Skip to content

Commit

Permalink
Fix the graph view, make item fields nullable and make the item card …
Browse files Browse the repository at this point in the history
…resize correctly
  • Loading branch information
ysbrandB committed Jun 13, 2024
1 parent 0a778bf commit 281dcdc
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 42 deletions.
40 changes: 40 additions & 0 deletions app/Console/Commands/fixJsonItems.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Console\Commands;

use App\Models\Item;
use Illuminate\Console\Command;

class fixJsonItems extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:fix-json-items';

/**
* The console command description.
*
* @var string
*/
protected $description = 'get all of the items and remove the 0 values from the json_items column.';

/**
* Execute the console command.
*/
public function handle()
{
$items = Item::query()->without('attributes')->select('id', 'json_items')->get();
foreach ($items as $item){
if($item->json_items){
$new = array_values(array_filter($item->json_items, function ($value){
return $value!==0;
}));
$item->json_items = $new;
$item->save();
}
}
}
}
12 changes: 8 additions & 4 deletions app/Http/Controllers/ItemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace App\Http\Controllers;

use App\Http\Requests\StoreItemRequest;
use App\Models\Attribute;
use App\Models\AttributeType;
use App\Models\Item;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -57,7 +55,10 @@ public function store(Request $request)
$wiringPhoto?->storeAs('photos/' . $photo->hashName(), ['disk' => 'public']);
$item = new Item();
$item->fill($request->except('attributes', 'photo', 'wiring_photo', 'json_items'));
$item->json_items = array_map('intval', explode(',', $request->input('edges')));
$json_items = explode(',', $request->input('edges'));
if ($json_items[0] !== "") {
$item->json_items = array_map('intval',$json_items);
}
$item->photo = $photo?->hashName();
$item->wiring_photo = $wiringPhoto?->hashName();
$item->save();
Expand Down Expand Up @@ -130,7 +131,10 @@ public function update(Request $request, int $id)
}

$item->fill($request->except('attributes', 'photo', 'wiring_photo', 'json_items'));
$item->json_items = array_map('intval', explode(',', $request->input('edges')));
$json_items = explode(',', $request->input('edges'));
if ($json_items[0] !== "") {
$item->json_items = array_map('intval',$json_items);
}
$item->save();
$string = explode(',', $request->input('attributes'));
$item->attributes()->sync($string[0] === "" ? [] : $string);
Expand Down
6 changes: 6 additions & 0 deletions app/Models/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,17 @@ public function edges(): HasMany

public function getPhotoUrlAttribute(): string
{
if(!$this->photo){
return '';
}
return asset('storage/photos/' . $this->photo);
}

public function getWiringPhotoUrlAttribute(): string
{
if(!$this->wiring_photo){
return '';
}
return asset('storage/photos/' . $this->wiring_photo);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('items', function ($table){
$table->text('description')->nullable()->change();
$table->text('card_description')->nullable()->change();
$table->text('pros')->nullable()->change();
$table->text('cons')->nullable()->change();
$table->text('hardware_considerations')->nullable()->change();
$table->text('software_considerations')->nullable()->change();
$table->text('wiring_instructions')->nullable()->change();
$table->text('example_code')->nullable()->change();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
//reverse up
Schema::table('items', function ($table){
$table->text('description')->change();
$table->text('card_description')->change();
$table->text('pros')->change();
$table->text('cons')->change();
$table->text('hardware_considerations')->change();
$table->text('software_considerations')->change();
$table->text('wiring_instructions')->change();
$table->text('example_code')->change();
});
}
};
1 change: 0 additions & 1 deletion resources/js/CustomComponents/MarkDownTextArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const emit = defineEmits<{
<template>
<div class="relative w-full min-w-[200px] mt-6">
<textarea
required
:value="description"
@input="$emit('updateMarkdown', (
//@ts-ignore
Expand Down
4 changes: 3 additions & 1 deletion resources/js/CustomComponents/Pill.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<script setup lang="ts">
const props = defineProps<{
color: string;
disableClasses?:boolean;
}>();
const standardClasses = "text-xs font-medium px-2.5 py-0.5 m-1 rounded-full h-min"
</script>
<template>
<span class="text-xs font-medium px-2.5 py-0.5 m-1 rounded-full h-min" :class="`bg-${color}-100 text-${color}-800 dark:bg-${color}-900 dark:text-${color}-300`"><slot/></span>
<span :class="[`bg-${color}-100 text-${color}-800 dark:bg-${color}-900 dark:text-${color}-300`, disableClasses?'':standardClasses]"><slot/></span>
</template>
41 changes: 21 additions & 20 deletions resources/js/Pages/Items/Show.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import 'highlight.js/styles/atom-one-dark.css';
import {marked} from 'marked';
const renderMarkdown = (markdown: string) => marked(markdown);
const renderMarkdown = (markdown: string|undefined) => marked(markdown??'');
</script>

Expand All @@ -47,36 +47,36 @@ const renderMarkdown = (markdown: string) => marked(markdown);
<div class="grid grid-cols-3 md:grid-cols-12">
<div class="col-span-3 md:col-span-9 mt-4">
<OpeningCard title="Description" :open="true">
<template #content>
<template #content v-if="item.description">
<div v-html="renderMarkdown(item.description)"></div>
</template>
</OpeningCard>

<OpeningCard title="Pros">
<OpeningCard title="Pros" v-if="item.pros">
<template #content>
<div v-html="renderMarkdown(item.pros)"></div>
</template>
</OpeningCard>

<OpeningCard title="Cons">
<OpeningCard title="Cons" v-if="item.cons">
<template #content>
<div v-html="renderMarkdown(item.cons)"></div>
</template>
</OpeningCard>

<OpeningCard title="Hardware considerations">
<OpeningCard title="Hardware considerations" v-if="item.hardware_considerations">
<template #content>
<div v-html="renderMarkdown(item.hardware_considerations)"></div>
</template>
</OpeningCard>

<OpeningCard title="Software considerations">
<OpeningCard title="Software considerations" v-if="item.software_considerations">
<template #content>
<div v-html="renderMarkdown(item.software_considerations)"></div>
</template>
</OpeningCard>

<OpeningCard title="Wiring">
<OpeningCard title="Wiring" v-if="item.wiring_instructions">
<template #content>
<div class="float-right mb-2 text-black italic dark:text-gray-100">
<img :src="item.wiring_photo_url" width="400" class="rounded-lg" alt="wiring diagram">
Expand All @@ -86,30 +86,31 @@ const renderMarkdown = (markdown: string) => marked(markdown);
</template>
</OpeningCard>

<OpeningCard title="Example code">
<OpeningCard title="Example code" v-if="item.example_code">
<template #content>
<v-highlightjs autodetect :code="item.example_code" class="w-full sm:text-sm"/>
<v-highlightjs autodetect :code="item.example_code??''" class="w-full sm:text-sm"/>
</template>
</OpeningCard>
</div>
<div class="col-span-3 md:pt-0 mt-4">
<div class="sticky top-8 max-w-7xl mx-auto sm:pr-6 lg:pr-4" id="wrapper">
<div
id="resizeCard"
class="p-8 bg-white dark:bg-gray-800 shadow-sm rounded-lg aspect-[63/88] overflow-hidden">
<div class="dark:text-gray-100 font-bold text-2xl mb-2">{{ item.title }}</div>
<img :src="item.photo_url" class="rounded-lg w-[75%] mx-auto" alt="item photo">
<div class="text-gray-600 text-sm my-2">{{ item.card_description }}</div>
<div class="sticky top-8 sm:px-6 lg:px-4 relative flex-col flex items-center justify-items-center" id="wrapper" style="font-size: 80%">
<div id="resizeCard" style="padding: 2em; width:23em; background-color: white; color: #1a202c; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 0.5em; aspect-ratio: 63/88; overflow: hidden;">
<div style="font-weight: bold; font-size: 2em; margin-bottom: 0.3em;">
{{ item.title }}
</div>
<img :src="item.photo_url" style="border-radius: 0.5em; max-width: 15em; display: block; margin: 0 auto;" alt="item photo">
<div style="color: #718096; font-size: 0.875em; margin: 1em 0;">
{{ item.card_description }}
</div>
<qrcode-vue
class="float-right max-w-[80px] max-h-[80px] dark:bg-gray-800 dark:text-gray-100 m-2"
style="float: right; max-width: 5em; max-height: 5em; background-color: #1a202c; color: #f7fafc; margin: 0.5em;"
:value="route('items.show', props.item.public_id)"
:margin="2"
:size="500"
level="Q"
render-as="canvas"/>
<div class="flex flex-wrap">
<pill v-for="attribute in item.attributes" :key="attribute.id"
:color="attribute.attribute_type?.color??''">
<div style="display: flex; flex-wrap: wrap;">
<pill v-for="attribute in item.attributes" :key="attribute.id" :color="attribute.attribute_type?.color??''" :disable-classes="true" style="font-size: 0.75em; font-weight: 500; padding: 0.125em 0.625em; margin: 0.25em; border-radius: 9999em; min-height: 0;">
{{ attribute.title }}
</pill>
</div>
Expand Down
45 changes: 39 additions & 6 deletions resources/js/Pages/Test.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import {Head, router} from '@inertiajs/vue3';
const props = defineProps<{
items: Item[],
python: Item
nodes: Item[]
python: Item,
log?: any
}>();
import {VNetworkGraph} from "v-network-graph"
if(props.log)
console.log(props.log);
import {Configs, Edges, VNetworkGraph} from "v-network-graph"
import "v-network-graph/lib/style.css"
import 'd3-force';
import {reactive} from "vue"
Expand Down Expand Up @@ -38,15 +42,26 @@ if(props.python) {
//@ts-ignore
nodes[`node${props.python.id}`] = {name: props.python.title, photo_url: props.python.photo_url, public_id: props.python.public_id}
}
props.items.forEach((item: Item) => {
//@ts-ignore
nodes[`node${item.id}`] = {name: item.title, photo_url: item.photo_url, public_id: props.python.public_id}
const addNode = (item: Item) =>{
const node: Node = {name: item.title, photo_url: item.photo_url, public_id: item.public_id};
//@ts-ignore
const list = [item.id, ...item.json_items, props.python.id]
nodes[`node${item.id}`] = node;
}
props.items.forEach((item: Item) => {
addNode(item)
const list = [item.id, ...item.json_items??[], props.python.id]
for(let i=0; i<list.length - 1; i++){
//@ts-ignore
myEdges.add({source: `node${list[i]}`, target: `node${list[i+1]}`})
}
})
props.nodes.forEach((item: Item) => {
addNode(item)
})
//filter out the myEdges where source is target and target is source from another item
Array.from(myEdges).forEach((edge: Edge, index: number) => {
if(!myEdges.has({source: edge.target, target: edge.source})){
Expand Down Expand Up @@ -99,6 +114,24 @@ const configs = reactive(
text: "name",
},
},
edge: {
summarize: ((edges: Edges, configs: Configs) => true),
summarized: { // configs for summarized edge
label: {
// * These fields can also be specified with the function as
// `(edges: Record<string, Edge>) => value`.
fontSize: 0, // font size. default: 10
color: "#4466cc" // font color. default: "#4466cc"
},
shape:{
width: 0,
height: 0,
},
stroke:{
width: 2,
}
}
},
})
)
</script>
Expand Down
16 changes: 8 additions & 8 deletions resources/js/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ export interface User {
export interface Item {
id: number;
title: string;
description: string;
card_description: string;
wiring_instructions: string;
pros: string;
cons: string;
hardware_considerations: string;
software_considerations: string;
example_code: string;
description?: string;
card_description?: string;
wiring_instructions?: string;
pros?: string;
cons?: string;
hardware_considerations?: string;
software_considerations?: string;
example_code?: string;
public_id: string;
photo_url?: string;
wiring_photo_url?: string;
Expand Down
19 changes: 17 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,24 @@
Route::resource('attribute_types', AttributeTypeController::class)->middleware('auth');
Route::resource('attributes', AttributeController::class);
Route::get('/test', function () {
$query = Item::query()
->select('json_items', 'id', 'title', 'photo')
->without('attributes');
$pythonItem = $query->clone()
->where('id', env('PYTHON_ID'))
->firstOrFail();
$items = $query->clone()
->whereNot('id', env('PYTHON_ID'))
->get();
$nodes = $query->clone()
->whereIn('id', $items->pluck('json_items')->flatten()->unique())
->whereNotIn('id', $items->pluck('id')->toArray())
->get();
return Inertia::render('Test', [
'items'=>Item::query()->whereNot('id', env('PYTHON_ID'))->select('json_items', 'id', 'title', 'photo')->without('attributes')->get(),
'python'=>Item::query()->where('id', env('PYTHON_ID'))->select('json_items', 'id', 'title', 'photo')->without('attributes')->firstOrFail()
'items'=> $items,
'python'=>$pythonItem,
'nodes' => $nodes,
'log'=>[$items->pluck('json_items')->flatten()->unique()]
]);
})->name('test');

Expand Down

0 comments on commit 281dcdc

Please sign in to comment.