feat: improve repo structure

This commit is contained in:
ndsboy 2025-02-23 18:54:08 +00:00
parent 9ac4a20119
commit 911bdc39a0
19 changed files with 5925 additions and 21596 deletions

View file

@ -1,9 +1,19 @@
{
"name": "swabsite",
"name": "swabdirectus",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node": {}
},
"containerUser": "vscode",
"runArgs": ["--userns=keep-id", "--security-opt=label=disable"]
"runArgs": [
"--userns=keep-id",
"--security-opt=label=disable"
],
"customizations": {
"vscode": {
"extensions": [
"Vue.volar"
]
}
}
}

View file

@ -2,5 +2,8 @@
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"editor.formatOnSave": true
"editor.formatOnSave": true,
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
}
}

30
.vscode/tasks.json vendored
View file

@ -2,18 +2,40 @@
"version": "2.0.0",
"tasks": [
{
"label": "start directus",
"command": "npx directus start",
"label": "install",
"command": "npm i",
"type": "shell",
"problemMatcher": []
},
{
"label": "build",
"command": "npm run build",
"type": "shell",
"problemMatcher": []
},
{
"label": "dev",
"command": "npm run dev",
"dependsOn": [
"dev directus",
"dev extension"
],
"problemMatcher": []
},
{
"label": "dev directus",
"command": "npx directus start",
"type": "shell",
"options": {
"cwd": "${workspaceFolder}/extensions/directus-extension-swablab"
"cwd": "${workspaceFolder}/directus"
},
"hide": true,
"problemMatcher": []
},
{
"label": "dev extension",
"command": "npm run dev",
"type": "shell",
"hide": true,
"problemMatcher": []
}
]

44
README.md Normal file
View file

@ -0,0 +1,44 @@
# Directus Plugins
Hier sind die selbst entwickelten Plugins für [Directus](https://directus.io).
Directus bietet für Plugins eine [Anleitung](https://docs.directus.io/extensions/introduction.html)
sowie vorgefertigte [Komponenten](https://components.directus.io).
Liste an Plugins:
- `tasks`: Ein Layout für die Task-Liste.
Diese soll die Übersicht der Aufgaben vereinfachen und funktioniert auch Mobil.
## Entwicklung
Um die Entwicklung einfach und einheitlich zu gestalten, benutzen wir
[Devcontainer](https://containers.dev) in
[VSCode](https://code.visualstudio.com). Wenn du das Repo in VSCode mit der
Devcontainer-Erweiterung öffnest, dann werden alle Tools und Erweiterungen für
die Entwicklung automatisch für dich installiert. Wenn du das nicht willst oder
kannst, musst du Node von Hand installieren.
Folgende VSCode-Tasks sind definiert:
- `install`: Installiert/Updated die Dependencies
- `dev`: Startet ein lokales Directus und überwacht auf Code-Änderungen
- `build`: Buildet das Plugin
Das lokale Directus ist unter `http://localhost:8055` erreichbar
und es sind bereits Testdaten angelegt (deshalb die DB im Repo).
Der Account ist `admin@example.com` mit dem Passwort `admin`.
## Änderungen
Wenn du etwas ändern willst oder du einen Fehler bemerkt hast, dann öffne gerne
ein [Issue](https://git.swablab.de/swablab/directus/issues) und beschreibe
möglichst genau dein Problem.
Alternativ kannst du die Änderung auch gerne selbst entwickeln und einen
[Pull Request](https://git.swablab.de/swablab/directus/pulls) stellen.
## Deployment
Wenn Änderungen den `main`-Branch erreichen, wird automatisch eine
[Pipeline](https://git.swablab.de/swablab/directus/actions) gestartet. Diese baut
die Erweiterung und fügt diese in das Directus-Image hinzu. Das Image wird dann als
[Package](https://git.swablab.de/swablab/directus/packages) gepuhst und dann
automatisch von Watchtower regelmäßig aktualisiert.

View file

Binary file not shown.

View file

@ -0,0 +1 @@
../../../dist

View file

@ -0,0 +1 @@
../../../package.json

8
directus/package.json Normal file
View file

@ -0,0 +1,8 @@
{
"name": "dist",
"private": true,
"dependencies": {
"directus": "^11.4.1",
"sqlite3": "^5.1.7"
}
}

View file

@ -1,3 +0,0 @@
.DS_Store
node_modules
dist

File diff suppressed because it is too large Load diff

View file

@ -1,35 +0,0 @@
{
"name": "swablab",
"version": "1.0.0",
"type": "module",
"files": [
"dist"
],
"directus:extension": {
"type": "bundle",
"path": {
"app": "dist/app.js",
"api": "dist/api.js"
},
"entries": [
{
"type": "layout",
"name": "tasks",
"source": "src/tasks/index.js"
}
],
"host": "^10.10.0"
},
"scripts": {
"build": "directus-extension build",
"dev": "directus-extension build -w --no-minify",
"link": "directus-extension link",
"add": "directus-extension add"
},
"devDependencies": {
"@directus/extensions-sdk": "13.0.1",
"@types/vue-router": "^2.0.0",
"typescript": "^5.7.3",
"vue": "^3.5.13"
}
}

View file

@ -1,79 +0,0 @@
<template>
<VListGroup v-if="!loading" class="swablab-tasks"
v-for="status in fields.find(f => f.field == 'status')?.meta?.options?.choices" open arrowPlacement="">
<template #activator>
<VListItem>
{{ status.text }}
</VListItem>
</template>
<VList v-for="item in items.filter(i => i.status == status.value)" :key="item.id">
<VListItem :clickable="true" @click="router.push(`${collection}/${item.id}`)">
<VListItemIcon>
<VIcon
:name="fields.find(f => f.field == 'category')?.meta?.options?.choices.find((c: any) => c.value == item.category).icon" />
</VListItemIcon>
<VListItemContent>
{{ item.title }}
</VListItemContent>
<VIcon v-if="item.responsibles.length == 0" name="person_search" color="green" />
<VIcon v-if="item.responsibles.find(x => x.directus_users_id == me)" name="account_circle" color="blue" />
<VChip v-if="item.date_due" :small="true">
<display-datetime format="short" :value="item.date_due" :use24="true" />
</VChip>
</VListItem>
</VList>
</VListGroup>
</template>
<style>
.swablab-tasks {
--v-list-padding: 12px;
}
.swablab-tasks .v-chip {
margin-left: 6px;
}
</style>
<script lang="ts">
import { Field } from '@directus/types';
import { defineComponent, PropType } from 'vue';
type Task = {
id: string
title: string
status: string
date_due?: string
priority: string
category: string
description: string
responsibles: {
directus_users_id: {
id: string
}
}[]
}
export default defineComponent({
inheritAttrs: false,
props: {
collection: String,
items: {
type: Array as PropType<Task[]>,
required: true,
},
loading: Boolean,
error: Array,
router: {
type: Object,
required: true,
},
fields: {
type: Array as PropType<Field[]>,
required: true,
},
me: Object,
}
})
</script>

21468
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,16 +1,37 @@
{
"name": "dist",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"directus": "^11.4.1",
"sqlite3": "^5.1.7"
}
}
"name": "swablab",
"version": "1.0.0",
"type": "module",
"files": [
"dist"
],
"directus:extension": {
"type": "bundle",
"path": {
"app": "dist/app.js",
"api": "dist/api.js"
},
"entries": [
{
"type": "layout",
"name": "tasks",
"source": "src/tasks/index.js"
}
],
"host": "^10.10.0"
},
"scripts": {
"build": "directus-extension build",
"dev": "directus-extension build -w --no-minify",
"link": "directus-extension link",
"add": "directus-extension add"
},
"devDependencies": {
"@directus/types": "^13.0.0",
"@directus/extensions-sdk": "13.0.1",
"@directus/extensions": "^3.0.1",
"typescript": "^5.7.3",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
}
}

View file

@ -7,7 +7,7 @@ import LayoutComponent from './layout.vue';
export default defineLayout({
id: 'tasks',
name: 'swablab tasks',
icon: 'box',
icon: 'task_alt',
component: LayoutComponent,
slots: {
options: () => null,

86
src/tasks/layout.vue Normal file
View file

@ -0,0 +1,86 @@
<template>
<VList class="swablab-tasks" v-if="!loading">
<VListGroup v-for="status in fields.find(f => f.field == 'status')?.meta?.options?.choices" :key="status.value" open
active arrowPlacement>
<template #activator>
<VListItem>
{{ status.text }} ({{items.filter(i => i.status == status.value).length}})
</VListItem>
</template>
<VListItem v-for="item in items.filter(i => i.status == status.value)" :key="item.id" clickable
@click="router.push(`${collection}/${item.id}`)">
<VListItemIcon>
<VIcon
:name="fields.find(f => f.field == 'category')?.meta?.options?.choices.find((c: any) => c.value == item.category).icon"
:color="item.priority == 'high' ? 'orange' : item.priority == 'low' ? 'dimgrey' : ''" />
</VListItemIcon>
<VListItemContent>
{{ item.title }}
</VListItemContent>
<VIcon v-if="item.responsibles.length == 0" name="person_search" color="green" />
<VIcon v-if="item.responsibles.find(x => x.directus_users_id == me)" name="person_pin_circle" color="blue" />
<VChip v-if="item.date_due" small>
<display-datetime format="short" :value="item.date_due" use24 />
</VChip>
</VListItem>
</VListGroup>
</VList>
</template>
<style>
.swablab-tasks {
--v-list-padding: 12px;
}
.swablab-tasks .v-list-group>.items {
padding: var(--v-list-padding);
}
.swablab-tasks .v-chip {
margin-left: 6px;
}
</style>
<script lang="ts">
import { Field } from '@directus/types';
import { defineComponent, PropType } from 'vue';
type Task = {
id: string
title: string
status: string
date_due?: string
priority: string
category: string
description: string
responsibles: {
directus_users_id: {
id: string
}
}[]
}
export default defineComponent({
inheritAttrs: false,
props: {
collection: String,
items: {
type: Array as PropType<Task[]>,
required: true,
},
loading: Boolean,
error: Array,
router: {
type: Object,
required: true,
},
fields: {
type: Array as PropType<Field[]>,
required: true,
},
me: Object,
}
})
</script>