Skip to content

Commit

Permalink
Update asset manager
Browse files Browse the repository at this point in the history
  • Loading branch information
austinkregel committed Aug 12, 2024
1 parent 2df388b commit 0b3fb17
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 27 deletions.
3 changes: 2 additions & 1 deletion app/Http/Controllers/Spork/AssetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Services\Development\DescribeTableService;
use Illuminate\Http\Request;
use Inertia\Inertia;

Expand All @@ -12,7 +13,7 @@ class AssetController extends Controller
public function index()
{
return Inertia::render('Assets/Index', [
''
'description' => (new DescribeTableService)->describe(new Asset),
]);
}

Expand Down
2 changes: 1 addition & 1 deletion app/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ protected function casts(): array

public static function fromFeedItem(ExternalRssFeed $feed, FeedItem $item): self
{
if ($post = self::firstWhere('external_guid', $item->getExternalId())) {
if ($post = self::firstWhere('external_guid', $item->getUuidIfExists())) {
return $post;
}

Expand Down
3 changes: 2 additions & 1 deletion app/Models/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Asset extends Model implements Crud
'id',
'name',
'type',
'group',
'location',
'description',
'acquired_at',
Expand All @@ -47,7 +48,7 @@ class Asset extends Model implements Crud
'meta' => 'array',
];

public function owner()
public function owner(): \Illuminate\Database\Eloquent\Relations\MorphTo
{
return $this->morphTo();
}
Expand Down
8 changes: 7 additions & 1 deletion app/Services/ConditionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ public function navigation()

// So we want to filter out any nav items
$navItems = Navigation::query()
->with('conditions', 'children')
->with(['conditions', 'children' => function ($builder) {
$builder->orderBy('order');
}])
->where('authentication_required', auth()->check())
->whereNull('parent_id')
->orderBy('order')
Expand All @@ -69,6 +71,10 @@ public function navigation()
->count() > 0
);

if ($item->children->isNotEmpty()) {
$item->children->sortDesc();
}

return $item;
});

Expand Down
94 changes: 84 additions & 10 deletions resources/js/Pages/Assets/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,78 @@ import { ref, computed } from 'vue';
import AppLayout from "@/Layouts/AppLayout.vue";
import {buildUrl} from "@kbco/query-builder";
import SporkTable from "@/Components/Spork/Atoms/SporkTable.vue";
const form = ref({
input: ''
import SporkButton from "@/Components/Spork/SporkButton.vue";
import SporkDynamicInput from "@/Components/Spork/SporkDynamicInput.vue";
import Modal from "@/Components/Modal.vue";
import {router} from "@inertiajs/vue3";
const { description } = defineProps({
description: Object
});
const DynamicFormToFillableArray = function (model) {
return Object.keys(model).map(key => ({
value: typeof (model[key] ?? '') === 'object' ? JSON.stringify(model[key]?? '') : (model[key] ?? null),
name: key,
}));
}
const FillableArrayToDynamicForm = function (fillable) {
return fillable.map(value => ({
value: null,
name: value,
}));
}
const form = ref(null);
const scannedInput = ref(null);
const data = ref(null);
const errors = ref(null);
const isNumber = computed(() => {
return isNaN(Number(form.value.input));
return isNaN(Number(scannedInput.value));
});
const decodedValue = computed(() => {
return !isNaN(Number(form.value.input)) ? Number(form.value.input) : atob(form.value.input);
return !isNaN(Number(scannedInput.value)) ? Number(scannedInput.value) : atob(scannedInput.value);
});
const search = () => {
axios.get(buildUrl('/api/crud/assets', {
filter: {
id: decodedValue.value
}
},
include: ['owner']
})).then(response => {
data.value = (response.data);
if (data.value.data.length === 1) {
form.value = DynamicFormToFillableArray(data.value.data[0])
}
});
}
const onSave = async (fo, toggle) => {
const data = fo.reduce((all, { name, value }) => ({ ...all, [name]: value }), {});
let url = '/api/crud/'+description.name;
if (data?.id) {
url += '/'+data.id;
}
axios[data?.id ? 'put' : 'post'](url, data).then(() => {
router.reload({
only: ['data', 'paginator'],
});
toggle();
}).catch((e) => {
toggle();
errors.value = e?.response?.data?.errors;
});
}
</script>
<template>
<AppLayout title="Assets">
<div id="printable" class="text-black px-8 py-2 rounded-lg ">
<input
autofocus
v-model="form.input"
v-model="scannedInput"
@keyup.enter="search"
class="dark:bg-stone-800 dark:text-white dark:border-stone-600"
type="text"
Expand All @@ -42,19 +85,50 @@ const search = () => {
<SporkTable
header="Asset Search"
description="Search for assets by ID or Asset ID"

:headers="[{
name: 'ID',
accessor: 'id'
}, {
name: 'Name',
accessor: 'name'
},
{
name: 'Owner',
accessor: item => item?.owner?.name
}
]"
v-if="data && data?.data"
v-if="!form && data && data?.data"
:items="data.data ?? []"

/>
<div>
<code><pre>{{ form }}</pre></code>
</div>
<Modal :show="form">
<div class="text-xl flex flex-col justify-between p-4">
<div v-for="(field, i) in form">
<SporkDynamicInput
:key="i+'.form-value'"
:autofocus="i === 1"
v-model="form[i]"
v-if="description.types[field.name]"
:type="description.types[field.name].type ?? 'text'"
:disabled-input="!description.fillable.includes(field.name)"
:editable-label="false"
:errors="errors?.[field.name]"
class="mt-4"
/>
</div>
<div class="mt-4">
<SporkButton xsmall plain @click="onSave(form, () => form = null)">
Apply
</SporkButton>
</div>
</div>
</Modal>
</AppLayout>
</template>
Expand Down
1 change: 0 additions & 1 deletion resources/js/Pages/Credentials.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
<spork-input v-model="form.name" type="text" name="name" id="name" />
</div>


<div class="col-span-6">
<label for="name" class="block text-sm font-medium">Type</label>
<spork-select v-model="form.type" type="text" name="refresh_token" id="refresh_token">
Expand Down
6 changes: 6 additions & 0 deletions resources/js/Pages/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ onMounted(() => {
timeInterval.value = setInterval(() => {
now.value = dayjs();
}, 1000)
console.log(MetricApiCard)
return () => {
clearInterval(timeInterval.value)
}
})
</script>

Expand Down
62 changes: 57 additions & 5 deletions resources/js/Pages/Development/Index.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<script setup>
import ContextMenuItem from "@/Components/ContextMenus/ContextMenuItem.vue";
import hljs from 'highlight.js';
import Manage from "@/Layouts/Manage.vue";
import AppLayout from "@/Layouts/AppLayout.vue";
import FileOrFolder from "@/Components/Spork/FileOrFolder.vue";
import ContextMenu from "@/Components/ContextMenus/ContextMenu.vue";
import {ref, watch} from "vue";
import CodeEditor from 'simple-code-editor';
import Button from "@/Components/Button.vue";
import SporkButton from "@/Components/Spork/SporkButton.vue";
import DynamicIcon from "@/Components/DynamicIcon.vue";
import { router } from '@inertiajs/vue3';
import { parse } from 'node-html-parser';
import Node from "node-html-parser/dist/nodes/node.js";
import hljsDefineVue from 'highlightjs-vue';
hljsDefineVue(hljs);
const { title, files } = defineProps({
title: String,
files: Array
Expand All @@ -28,6 +30,8 @@ watch(selectedContext, (value) => {
const file = ref('');
const openFile = ref(false);
const node = ref(null);
const openedFile = async (openedFile, component) => {
console.log('opened file', {...openedFile}, component)
Expand All @@ -43,10 +47,50 @@ const openedFile = async (openedFile, component) => {
file.value = data;
}
/**
* @param {Node} currentNode
* @param currentNode
* @returns {{children: {children: *, classes: *, name: *}[], classes: IterableIterator<string>, name: string}}
*/
function parseTheNode(currentNode) {
const name = currentNode.rawTagName;
const children = currentNode.childNodes.map((node) => {
return parseTheNode(node);
});
/**
* @var {Node} parentNode
* @var {Node[]} childNodes
* @var {DOMTokenList} classList
*/
let { parentNode, childNodes, ...rest } = currentNode;
return {
name,
children,
attr: rest.attributes,
// toString(){
// return currentNode.toString();
// },
// ...rest,
};
}
if (openedFile.name.endsWith('.vue')) {
const parsed = parse(data);
const nodesWeCareAbout = parsed.childNodes.filter((node) => node.nodeType === 1)
// When we parse a vue file, we could have a script, style, or template tag, or any combination of them. We need to handle each section separately.
const script = nodesWeCareAbout.find((node) => node.rawTagName === 'script');
const style = nodesWeCareAbout.find((node) => node.rawTagName === 'style');
const template = nodesWeCareAbout.find((node) => node.rawTagName === 'template');
node.value = parseTheNode(template);
}
openFile.value = openedFile;
}
const getLanguage = (lang) => {
return hljs.getLanguage(lang);
return hljs.getLanguage(lang) ?? 'vue';
}
const saveFile = () => {
console.log('saving file', { ... openFile.value }, file.value)
Expand All @@ -62,6 +106,14 @@ const saveFile = () => {
const cancelFile = () => {
openFile.value = null;
}
const recursiveMap = (n) => {
return n.children.map((node) => {
return {
name: node.name,
children: node.children?.length > 0 ? recursiveMap(node) : 0,
}
});
}
</script>
<template>
Expand Down Expand Up @@ -113,7 +165,7 @@ const cancelFile = () => {
:display-language="true"
@lang="getLanguage"
height="calc(100vh - 140px)"
:languages="[['php', 'PHP'], ['js', 'JavaScript'], ['html', 'HTML'], ['css', 'CSS'], ['json', 'JSON'], ['yaml', 'yml']]"
:languages="[['php', 'PHP'], ['js', 'JavaScript'],['vue', 'Vue SFC'], ['html', 'HTML'], ['css', 'CSS'], ['json', 'JSON'], ['yaml', 'yml']]"
/>
</div>
Expand Down
7 changes: 1 addition & 6 deletions resources/js/Pages/Manage/Index.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
<script setup>
import AppLayout from '@/Layouts/AppLayout.vue';
import Welcome from '@/Components/Welcome.vue';
import MetricCard from '@/Components/Spork/Atoms/MetricCard.vue';
import {usePage, Link, router} from '@inertiajs/vue3'
import { computed, ref } from 'vue';
import { ref } from 'vue';
import DynamicIcon from "@/Components/DynamicIcon.vue";
import SporkInput from "@/Components/Spork/SporkInput.vue";
import CrudView from "@/Components/Spork/CrudView.vue";
import { buildUrl } from '@kbco/query-builder';
import Manage from "@/Layouts/Manage.vue";
import SporkDynamicInput from "@/Components/Spork/SporkDynamicInput.vue";
import MetricApiCard from "@/Components/Spork/Molecules/MetricApiCard.vue";
const page = usePage()
const { title, data, description, paginator, link, plural, apiLink, singular, body, metrics } = defineProps({
data: Array,
title: String,
Expand Down
11 changes: 10 additions & 1 deletion resources/js/Pages/Servers/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,17 @@
{{server.services.map(s => s.service).join(', ')}}
<div class="flex-grow flex justify-between">
<div></div>
<div>
<div class="flex flex-col gap-2">
<Status :status="server.status" />

<div class="flex flex-wrap gap-2">
<DynamicIcon icon-name="ArrowPathIcon" class="text-white w-5 h-5" data-note="SSH connection test" />
<DynamicIcon icon-name="SignalSlashIcon" class="text-white w-5 h-5" data-note="No active connection to the server"/>
<DynamicIcon icon-name="SignalIcon" class="text-white w-5 h-5" data-note="Has active connection to the server"/>
<DynamicIcon icon-name="PuzzlePieceIcon" class="text-white w-5 h-5" data-note="This can be a button that takes you to install new software"/>
<DynamicIcon icon-name="CalendarDaysIcon" class="text-white w-5 h-5" data-note="The server crontab under root." />
<DynamicIcon icon-name="DocumentTextIcon" class="text-white w-5 h-5" data-note="Logs" />
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit 0b3fb17

Please sign in to comment.