From 5fc7cc96046ec04e3f498f6d042673242588690b Mon Sep 17 00:00:00 2001 From: florianfederspiel Date: Tue, 19 May 2026 12:47:51 +0200 Subject: [PATCH] =?UTF-8?q?Dateimodal=20=C3=BCberarbeiten=20und=20Dateityp?= =?UTF-8?q?en=20pflegen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0040_filetag_system_types.sql | 6 + backend/db/migrations/meta/_journal.json | 7 + backend/db/schema/filetags.ts | 2 + backend/src/modules/bootstrap.service.ts | 12 +- backend/src/routes/admin.ts | 6 + backend/src/routes/resources/main.ts | 8 + backend/src/utils/resource.config.ts | 25 +- frontend/components/DocumentDisplayModal.vue | 522 ++++++++---------- frontend/components/EntityEdit.vue | 8 +- frontend/components/MainNav.vue | 5 + frontend/composables/useFiles.ts | 14 +- .../pages/standardEntity/[type]/index.vue | 4 + frontend/stores/data.js | 60 ++ 13 files changed, 360 insertions(+), 319 deletions(-) create mode 100644 backend/db/migrations/0040_filetag_system_types.sql diff --git a/backend/db/migrations/0040_filetag_system_types.sql b/backend/db/migrations/0040_filetag_system_types.sql new file mode 100644 index 0000000..dd21344 --- /dev/null +++ b/backend/db/migrations/0040_filetag_system_types.sql @@ -0,0 +1,6 @@ +ALTER TABLE "filetags" ADD COLUMN "isSystemUsed" boolean DEFAULT false NOT NULL; + +UPDATE "filetags" +SET "isSystemUsed" = true +WHERE COALESCE("createddocumenttype", '') <> '' + OR COALESCE("incomingDocumentType", '') <> ''; diff --git a/backend/db/migrations/meta/_journal.json b/backend/db/migrations/meta/_journal.json index 00763b1..bc82b47 100644 --- a/backend/db/migrations/meta/_journal.json +++ b/backend/db/migrations/meta/_journal.json @@ -281,6 +281,13 @@ "when": 1779840000000, "tag": "0039_events_repeat_interval", "breakpoints": true + }, + { + "idx": 40, + "version": "7", + "when": 1779141600000, + "tag": "0040_filetag_system_types", + "breakpoints": true } ] } diff --git a/backend/db/schema/filetags.ts b/backend/db/schema/filetags.ts index 3dc47cf..19027bb 100644 --- a/backend/db/schema/filetags.ts +++ b/backend/db/schema/filetags.ts @@ -26,6 +26,8 @@ export const filetags = pgTable("filetags", { createdDocumentType: text("createddocumenttype").default(""), incomingDocumentType: text("incomingDocumentType"), + isSystemUsed: boolean("isSystemUsed").notNull().default(false), + archived: boolean("archived").notNull().default(false), }) diff --git a/backend/src/modules/bootstrap.service.ts b/backend/src/modules/bootstrap.service.ts index ee424e3..611577a 100644 --- a/backend/src/modules/bootstrap.service.ts +++ b/backend/src/modules/bootstrap.service.ts @@ -116,12 +116,12 @@ async function ensureTenantFileDefaults(server: FastifyInstance, tenantId: numbe const timestamp = new Date() const tagDefaults = [ - { name: "Rechnungen", color: "#16a34a", createdDocumentType: "invoices" }, - { name: "Angebote", color: "#2563eb", createdDocumentType: "quotes" }, - { name: "Auftragsbestätigungen", color: "#7c3aed", createdDocumentType: "confirmationOrders" }, - { name: "Lieferscheine", color: "#ea580c", createdDocumentType: "deliveryNotes" }, - { name: "Eingangsrechnungen", color: "#dc2626", incomingDocumentType: "invoices" }, - { name: "Mahnungen", color: "#b91c1c", incomingDocumentType: "reminders" }, + { name: "Rechnungen", color: "#16a34a", createdDocumentType: "invoices", isSystemUsed: true }, + { name: "Angebote", color: "#2563eb", createdDocumentType: "quotes", isSystemUsed: true }, + { name: "Auftragsbestätigungen", color: "#7c3aed", createdDocumentType: "confirmationOrders", isSystemUsed: true }, + { name: "Lieferscheine", color: "#ea580c", createdDocumentType: "deliveryNotes", isSystemUsed: true }, + { name: "Eingangsrechnungen", color: "#dc2626", incomingDocumentType: "invoices", isSystemUsed: true }, + { name: "Mahnungen", color: "#b91c1c", incomingDocumentType: "reminders", isSystemUsed: true }, ] for (const tag of tagDefaults) { diff --git a/backend/src/routes/admin.ts b/backend/src/routes/admin.ts index 3c7f52b..a35b3c2 100644 --- a/backend/src/routes/admin.ts +++ b/backend/src/routes/admin.ts @@ -45,36 +45,42 @@ export default async function adminRoutes(server: FastifyInstance) { name: "Rechnungen", color: "#16a34a", createdDocumentType: "invoices", + isSystemUsed: true, }, { tenant: tenantId, name: "Angebote", color: "#2563eb", createdDocumentType: "quotes", + isSystemUsed: true, }, { tenant: tenantId, name: "Auftragsbestätigungen", color: "#7c3aed", createdDocumentType: "confirmationOrders", + isSystemUsed: true, }, { tenant: tenantId, name: "Lieferscheine", color: "#ea580c", createdDocumentType: "deliveryNotes", + isSystemUsed: true, }, { tenant: tenantId, name: "Eingangsrechnungen", color: "#dc2626", incomingDocumentType: "invoices", + isSystemUsed: true, }, { tenant: tenantId, name: "Mahnungen", color: "#b91c1c", incomingDocumentType: "reminders", + isSystemUsed: true, }, ]) .returning({ diff --git a/backend/src/routes/resources/main.ts b/backend/src/routes/resources/main.ts index 2b1fcda..b7a5a7b 100644 --- a/backend/src/routes/resources/main.ts +++ b/backend/src/routes/resources/main.ts @@ -968,6 +968,14 @@ export default async function resourceRoutes(server: FastifyInstance) { //@ts-ignore delete data.updatedBy; delete data.updatedAt; + if (resource === "filetags") { + delete data.isSystemUsed + + if (oldRecord.isSystemUsed && data.archived === true) { + return reply.code(400).send({ error: "System-Dateitypen können nicht archiviert werden" }) + } + } + if (portalCustomerId) { data = { ...sanitizePortalCustomerUpdate(data), diff --git a/backend/src/utils/resource.config.ts b/backend/src/utils/resource.config.ts index aabdc7f..7c59fee 100644 --- a/backend/src/utils/resource.config.ts +++ b/backend/src/utils/resource.config.ts @@ -105,7 +105,22 @@ export const resourceConfig = { numberRangeHolder: "vendorNumber", }, files: { - table: files + table: files, + mtoLoad: [ + "project", + "customer", + "contract", + "vendor", + "incominginvoice", + "plant", + "createddocument", + "vehicle", + "product", + "check", + "inventoryitem", + "authProfile", + "type", + ], }, folders: { table: folders @@ -113,6 +128,9 @@ export const resourceConfig = { filetags: { table: filetags }, + type: { + table: filetags + }, inventoryitems: { table: inventoryitems, numberRangeHolder: "articleNumber", @@ -201,6 +219,11 @@ export const resourceConfig = { tenantKey: "tenant_id", searchColumns: ["first_name", "last_name", "full_name", "email", "employee_number"], }, + authProfile: { + table: authProfiles, + tenantKey: "tenant_id", + searchColumns: ["first_name", "last_name", "full_name", "email", "employee_number"], + }, letterheads: { table: letterheads, diff --git a/frontend/components/DocumentDisplayModal.vue b/frontend/components/DocumentDisplayModal.vue index 5d3798b..9b625fa 100644 --- a/frontend/components/DocumentDisplayModal.vue +++ b/frontend/components/DocumentDisplayModal.vue @@ -1,8 +1,7 @@ diff --git a/frontend/components/EntityEdit.vue b/frontend/components/EntityEdit.vue index 205da09..ac771bf 100644 --- a/frontend/components/EntityEdit.vue +++ b/frontend/components/EntityEdit.vue @@ -394,6 +394,12 @@ const getPostSaveRoute = () => { return null } +const canArchiveItem = computed(() => { + if (!item.value?.id) return false + if (dataType.canArchiveFunction) return dataType.canArchiveFunction(item.value) + return true +}) + const createItem = async () => { let ret = null @@ -461,7 +467,7 @@ const updateItem = async () => {