From c58aadef76b6091fdd48e83da4893b254fe9b11c Mon Sep 17 00:00:00 2001 From: &mile Date: Mon, 11 May 2026 18:51:13 +0200 Subject: [PATCH 01/14] feat(storage): move storage to org-level, add file date & non-nullable name - Move files/folders from year-scope to org-scope: new /storage route under $idOrganization, updated API routes and dashboard tree - Add optional 'date' field on file (content date, e.g. invoice date) with migration 0023_add_date_to_file.sql; exposed in updateOneFileForm and filePage - Make file 'name' NOT NULL across DB (migration 0024), Drizzle model, Valibot schema, and createOneFile route body - Default upload name derived without file extension (referenceFromFileName) - Add 'date' field to file entry/update form (entriesTable, entryPage, createOneEntry, updateOneEntry) - Entry table and entry page: file column now a clickable link to the file page, showing '${name} (${reference})' - Simplify file.name null-guards throughout website now that name is non-nullable --- .../$idOrganization/$idOrganizationRoutes.ts | 4 ++ .../src/routes/auth/$idYear/$idYearRoutes.ts | 4 -- .../files/$idFile/generateFileGetSignedUrl.ts | 9 +-- .../auth/$idYear/files/$idFile/ocrFile.ts | 19 ++---- .../auth/$idYear/files/$idFile/readOneFile.ts | 9 +-- .../$idYear/files/$idFile/updateOneFile.ts | 10 +-- .../auth/$idYear/files/createOneFile.ts | 1 - .../routes/auth/$idYear/files/readAllFiles.ts | 10 +-- .../folders/$idFolder/deleteOneFolder.ts | 3 +- .../folders/$idFolder/readOneFolder.ts | 3 +- .../folders/$idFolder/updateOneFolder.ts | 3 +- .../auth/$idYear/folders/createOneFolder.ts | 1 - .../auth/$idYear/folders/readAllFolders.ts | 4 +- .../agent/agentFile/createOneAgentFile.ts | 20 ++---- .../agentSession/updateOneAgentSession.ts | 12 +--- .../routes/auth/agent/searchReferenceable.ts | 1 - packages/api/src/utilities/ocr/processOcr.ts | 14 +--- packages/metadata/src/models/file.ts | 12 ++-- packages/metadata/src/models/folder.ts | 7 -- .../files/$idFile/generateFileGetSignedUrl.ts | 1 - .../years/$idYear/files/$idFile/ocrFile.ts | 1 - .../$idYear/files/$idFile/readOneFile.ts | 1 - .../$idYear/files/$idFile/updateOneFile.ts | 2 +- .../years/$idYear/files/createOneFile.ts | 3 +- .../years/$idYear/files/readAllFiles.ts | 6 +- .../folders/$idFolder/deleteOneFolder.ts | 1 - .../folders/$idFolder/readOneFolder.ts | 1 - .../folders/$idFolder/updateOneFolder.ts | 1 - .../years/$idYear/folders/createOneFolder.ts | 1 - .../years/$idYear/folders/readAllFolders.ts | 6 +- packages/metadata/src/schemas/file.ts | 7 +- packages/metadata/src/schemas/folder.ts | 2 - .../0022_move_storage_to_org_level.sql | 17 +++++ .../tools/drizzle/0023_add_date_to_file.sql | 2 + .../drizzle/0024_make_file_name_not_null.sql | 2 + .../$idOrganization/organizationLayout.tsx | 9 +++ .../$idYear/entries/$idEntry/entryPage.tsx | 17 +++-- .../entries/$idEntry/updateOneEntry.tsx | 4 +- .../$idYear/entries/createOneEntry.tsx | 4 +- .../$idYear/entries/entriesTable.tsx | 12 +++- .../$idYear/files/$idFile/deleteOneFile.tsx | 8 +-- .../$idYear/files/$idFile/fileData.tsx | 2 - .../$idYear/files/$idFile/fileFile.tsx | 1 - .../$idYear/files/$idFile/fileLayout.tsx | 15 ++--- .../$idYear/files/$idFile/fileMetadataTab.tsx | 3 +- .../$idYear/files/$idFile/filePage.tsx | 64 ++++++++++--------- .../files/$idFile/fileVisualisationTab.tsx | 3 +- .../files/$idFile/updateOneFileForm.tsx | 30 +++++++-- .../dashboard/$idYear/files/createOneFile.tsx | 12 +--- .../$idYear/files/createOneFolder.tsx | 7 +- .../$idYear/files/deleteFileWithSignedUrl.ts | 2 +- .../dashboard/$idYear/files/fileActions.tsx | 20 ++---- .../$idYear/files/fileContextMenu.tsx | 10 +-- .../dashboard/$idYear/files/fileSelect.tsx | 2 +- .../dashboard/$idYear/files/filesGrid.tsx | 20 ++---- .../dashboard/$idYear/files/filesPage.tsx | 19 ++---- .../$idYear/files/filesPageContent.tsx | 7 +- .../dashboard/$idYear/files/filesTable.tsx | 23 ++----- .../files/filesTableSelectionActions.tsx | 12 +--- .../dashboard/$idYear/files/folderActions.tsx | 6 +- .../$idYear/files/folderContextMenu.tsx | 6 +- .../$idYear/files/moveOneFileForm.tsx | 16 +---- .../$idYear/files/moveOneFolderForm.tsx | 10 +-- .../$idYear/files/updateOneFolderForm.tsx | 6 +- .../features/dashboard/$idYear/yearLayout.tsx | 11 +--- .../routes/root/dashboard/dashboardTree.ts | 28 ++++---- .../storage/$idFile/fileLayoutRoute.tsx | 14 ++++ .../storage/$idFile/fileMetadataRoute.tsx | 14 ++++ .../storage/$idFile/fileRoute.tsx | 14 ++++ .../$idFile/fileVisualisationRoute.tsx | 14 ++++ .../storage/storageLayoutRoute.tsx | 11 ++++ .../$idOrganization/storage/storageRoute.tsx | 17 +++++ 72 files changed, 309 insertions(+), 364 deletions(-) create mode 100644 packages/tools/drizzle/0022_move_storage_to_org_level.sql create mode 100644 packages/tools/drizzle/0023_add_date_to_file.sql create mode 100644 packages/tools/drizzle/0024_make_file_name_not_null.sql create mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx diff --git a/packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts b/packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts index cadfb675..35d6caac 100644 --- a/packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts +++ b/packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts @@ -1,3 +1,5 @@ +import { filesRoutes } from "../$idYear/files/filesRoutes.js" +import { foldersRoutes } from "../$idYear/folders/foldersRoutes.js" import { apiKeyRoutes } from "./apiKey/apiKeyRoutes.js" import { organizationPaymentsRoutes } from "./organizationPayment/organizationPaymentsRoutes.js" import { organizationSettingsRoutes } from "./organizationSettings/organizationSettingsRoutes.js" @@ -13,4 +15,6 @@ export const $idOrganizationRoutes = [ ...organizationSettingsRoutes, ...organizationPaymentsRoutes, ...apiKeyRoutes, + ...filesRoutes, + ...foldersRoutes, ] diff --git a/packages/api/src/routes/auth/$idYear/$idYearRoutes.ts b/packages/api/src/routes/auth/$idYear/$idYearRoutes.ts index 1606b7c4..40b134b0 100644 --- a/packages/api/src/routes/auth/$idYear/$idYearRoutes.ts +++ b/packages/api/src/routes/auth/$idYear/$idYearRoutes.ts @@ -1,6 +1,4 @@ import { entriesRoutes } from "./entries/entriesRoutes.js" -import { filesRoutes } from "./files/filesRoutes.js" -import { foldersRoutes } from "./folders/foldersRoutes.js" import { readOneYearRoute } from "./readOneYear.js" import { reportsRoutes } from "./reports/reportsRoutes.js" import { yearSettingsRoute } from "./yearSettings/yearSettingsRoute.js" @@ -9,8 +7,6 @@ export const $idYearRoutes = [ readOneYearRoute, ...entriesRoutes, - ...filesRoutes, - ...foldersRoutes, ...reportsRoutes, ...yearSettingsRoute, ] diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts b/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts index d2e23054..7413a045 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts +++ b/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts @@ -1,5 +1,5 @@ import { generateFileGetSignedUrlRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq, isNull } from "drizzle-orm" +import { and, eq } from "drizzle-orm" import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../../utilities/apiFactory.js" @@ -22,12 +22,7 @@ export const generateFileGetSignedUrlRoute = apiFactory const readOneFile = await selectOne({ database: c.var.clients.sql, table: models.file, - where: (table) => - and( - eq(table.idOrganization, idOrganization), - body.idYear !== null ? eq(table.idYear, body.idYear) : isNull(table.idYear), - eq(table.id, body.idFile), - ), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), }) if (readOneFile.storageKey === null) { diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts b/packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts index 96e77332..bc153ff3 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts +++ b/packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts @@ -1,5 +1,5 @@ import { generateId, models, ocrFileRouteDefinition } from "@arrhes/application-metadata" -import { and, eq, isNull, sql } from "drizzle-orm" +import { and, eq, sql } from "drizzle-orm" import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" @@ -45,12 +45,7 @@ export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.p const sourceFile = await selectOne({ database: c.var.clients.sql, table: models.file, - where: (table) => - and( - eq(table.idOrganization, idOrganization), - body.idYear !== null ? eq(table.idYear, body.idYear) : isNull(table.idYear), - eq(table.id, body.idFile), - ), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), }) if (sourceFile.storageKey === null) { @@ -166,10 +161,10 @@ export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.p const markdownBuffer = Buffer.from(normalizedMarkdownContent, "utf-8") const newFileId = generateId() - const originalName = sourceFile.name ?? sourceFile.reference ?? "document" + const originalName = sourceFile.name || sourceFile.reference || "document" const baseName = originalName.replace(/\.[^.]+$/, "") const markdownName = `${baseName}.md` - const storageKey = `organizations/${idOrganization}/${body.idYear}/files/${newFileId}` + const storageKey = `organizations/${idOrganization}/storage/${newFileId}` const newFile = await insertOne({ database: c.var.clients.sql, @@ -177,7 +172,6 @@ export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.p data: { id: newFileId, idOrganization: idOrganization, - idYear: body.idYear, idFolder: sourceFile.idFolder, reference: sourceFile.reference, name: markdownName, @@ -196,11 +190,6 @@ export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.p contentType: "text/markdown; charset=utf-8", metadata: { idOrganization: idOrganization, - ...(body.idYear !== null - ? { - idYear: body.idYear, - } - : {}), idUser: user.id, }, body: markdownBuffer, diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts b/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts index 29b39c0b..6e2c4294 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts +++ b/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts @@ -1,5 +1,5 @@ import { models, readOneFileRouteDefinition } from "@arrhes/application-metadata" -import { and, eq, isNull } from "drizzle-orm" +import { and, eq } from "drizzle-orm" import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../../utilities/apiFactory.js" @@ -18,12 +18,7 @@ export const readOneFileRoute = apiFactory.createApp().post(readOneFileRouteDefi const readOneFile = await selectOne({ database: c.var.clients.sql, table: models.file, - where: (table) => - and( - eq(table.idOrganization, idOrganization), - body.idYear !== null ? eq(table.idYear, body.idYear) : isNull(table.idYear), - eq(table.id, body.idFile), - ), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), }) return response({ diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts b/packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts index abe8090f..87de540a 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts +++ b/packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts @@ -1,5 +1,5 @@ import { models, updateOneFileRouteDefinition } from "@arrhes/application-metadata" -import { and, eq, isNull } from "drizzle-orm" +import { and, eq } from "drizzle-orm" import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../../utilities/apiFactory.js" @@ -21,16 +21,12 @@ export const updateOneFileRoute = apiFactory.createApp().post(updateOneFileRoute data: { reference: body.reference, name: body.name, + date: body.date, idFolder: body.idFolder, lastUpdatedAt: new Date().toISOString(), lastUpdatedBy: user.id, }, - where: (table) => - and( - eq(table.idOrganization, idOrganization), - body.idYear !== null ? eq(table.idYear, body.idYear) : isNull(table.idYear), - eq(table.id, body.idFile), - ), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), }) return response({ diff --git a/packages/api/src/routes/auth/$idYear/files/createOneFile.ts b/packages/api/src/routes/auth/$idYear/files/createOneFile.ts index 5d56faa9..68bfb902 100644 --- a/packages/api/src/routes/auth/$idYear/files/createOneFile.ts +++ b/packages/api/src/routes/auth/$idYear/files/createOneFile.ts @@ -20,7 +20,6 @@ export const createOneFileRoute = apiFactory.createApp().post(createOneFileRoute data: { id: generateId(), idOrganization: idOrganization, - idYear: body.idYear, idFolder: body.idFolder, reference: body.reference, name: body.name, diff --git a/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts b/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts index 6d3e6555..883c790f 100644 --- a/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts +++ b/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts @@ -1,5 +1,5 @@ import { models, readAllFilesRouteDefinition } from "@arrhes/application-metadata" -import { and, eq, isNull } from "drizzle-orm" +import { eq } from "drizzle-orm" import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" @@ -10,7 +10,7 @@ export const readAllFilesRoute = apiFactory.createApp().post(readAllFilesRouteDe const { idOrganization } = await checkUserSessionMiddleware({ context: c, }) - const body = await validateBodyMiddleware({ + await validateBodyMiddleware({ context: c, schema: readAllFilesRouteDefinition.schemas.body, }) @@ -18,11 +18,7 @@ export const readAllFilesRoute = apiFactory.createApp().post(readAllFilesRouteDe const readAllFiles = await selectMany({ database: c.var.clients.sql, table: models.file, - where: (table) => - and( - eq(table.idOrganization, idOrganization), - body.idYear !== null ? eq(table.idYear, body.idYear) : isNull(table.idYear), - ), + where: (table) => eq(table.idOrganization, idOrganization), }) return response({ diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts index f5e3033c..e63ae5e0 100644 --- a/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts +++ b/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts @@ -18,8 +18,7 @@ export const deleteOneFolderRoute = apiFactory.createApp().post(deleteOneFolderR const deleteOneFolder = await deleteOne({ database: c.var.clients.sql, table: models.folder, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idFolder)), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), }) return response({ diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts index 6be72567..d5f0be0e 100644 --- a/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts +++ b/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts @@ -18,8 +18,7 @@ export const readOneFolderRoute = apiFactory.createApp().post(readOneFolderRoute const readOneFolder = await selectOne({ database: c.var.clients.sql, table: models.folder, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idFolder)), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), }) return response({ diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts index fb4a006f..90576646 100644 --- a/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts +++ b/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts @@ -24,8 +24,7 @@ export const updateOneFolderRoute = apiFactory.createApp().post(updateOneFolderR lastUpdatedAt: new Date().toISOString(), lastUpdatedBy: user.id, }, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idFolder)), + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), }) return response({ diff --git a/packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts index fc924ac6..442c1b1e 100644 --- a/packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts +++ b/packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts @@ -20,7 +20,6 @@ export const createOneFolderRoute = apiFactory.createApp().post(createOneFolderR data: { id: generateId(), idOrganization: idOrganization, - idYear: body.idYear, idFolderParent: body.idFolderParent ?? null, name: body.name, createdAt: new Date().toISOString(), diff --git a/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts b/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts index a2d6c1c7..2d73d783 100644 --- a/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts +++ b/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts @@ -1,5 +1,5 @@ import { models, readAllFoldersRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" +import { eq } from "drizzle-orm" import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" @@ -18,7 +18,7 @@ export const readAllFoldersRoute = apiFactory.createApp().post(readAllFoldersRou const readAllFolders = await selectMany({ database: c.var.clients.sql, table: models.folder, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), + where: (table) => eq(table.idOrganization, idOrganization), }) return response({ diff --git a/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts b/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts index bafa2dd4..f4bd4009 100644 --- a/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts +++ b/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts @@ -67,19 +67,11 @@ export const createOneAgentFileRoute = apiFactory }) } - const idYear = session.idYear - - // Check for duplicate file by hash within the same organization and year + // Check for duplicate file by hash within the same organization const existingFiles = await c.var.clients.sql .select() .from(models.file) - .where( - and( - eq(models.file.idOrganization, idOrganization), - eq(models.file.idYear, idYear), - eq(models.file.hash, body.fileHash), - ), - ) + .where(and(eq(models.file.idOrganization, idOrganization), eq(models.file.hash, body.fileHash))) .limit(1) if (existingFiles.length > 0 && existingFiles[0]) { @@ -108,14 +100,13 @@ export const createOneAgentFileRoute = apiFactory }) } - // Find or create the ".agent" folder at the root of the year + // Find or create the ".agent" folder at the root const existingFolders = await c.var.clients.sql .select() .from(models.folder) .where( and( eq(models.folder.idOrganization, idOrganization), - eq(models.folder.idYear, idYear), eq(models.folder.name, ".agent"), isNull(models.folder.idFolderParent), ), @@ -133,7 +124,6 @@ export const createOneAgentFileRoute = apiFactory data: { id: generateId(), idOrganization: idOrganization, - idYear: idYear, idFolderParent: null, name: ".agent", createdAt: new Date().toISOString(), @@ -144,7 +134,7 @@ export const createOneAgentFileRoute = apiFactory } const newFileId = generateId() - const storageKey = `organizations/${idOrganization}/${idYear}/files/${newFileId}` + const storageKey = `organizations/${idOrganization}/storage/${newFileId}` const newFile = await insertOne({ database: c.var.clients.sql, @@ -152,7 +142,6 @@ export const createOneAgentFileRoute = apiFactory data: { id: newFileId, idOrganization: idOrganization, - idYear: idYear, idFolder: agentFolderId, reference: null, name: body.fileName, @@ -181,7 +170,6 @@ export const createOneAgentFileRoute = apiFactory contentType: body.fileType, metadata: { idOrganization: idOrganization, - idYear: idYear, idUser: user.id, }, }) diff --git a/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts b/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts index 17652f10..b14208f9 100644 --- a/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts +++ b/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts @@ -43,15 +43,6 @@ export const updateOneAgentSessionRoute = apiFactory if (body.fileIds === null || body.fileIds.length === 0) { data.attachedFiles = null } else { - const idYear = body.idYear !== undefined ? body.idYear : session.idYear - if (!idYear) { - throw new Exception({ - statusCode: 400, - internalMessage: "Agent session has no year for file import", - externalMessage: "Veuillez sélectionner un exercice fiscal pour importer des fichiers", - }) - } - await checkOrganizationSubscriptionSessionMiddleware({ context: c, idOrganization: session.idOrganization, @@ -64,7 +55,6 @@ export const updateOneAgentSessionRoute = apiFactory .where( and( eq(models.file.idOrganization, session.idOrganization), - eq(models.file.idYear, idYear), inArray(models.file.id, body.fileIds), ), ) @@ -119,7 +109,7 @@ export const updateOneAgentSessionRoute = apiFactory const { ocrFile } = await processOcr({ var: c.var, idOrganization: session.idOrganization, - idYear: idYear, + idYear: session.idYear ?? "", idUser: user.id, sourceFile: file, }) diff --git a/packages/api/src/routes/auth/agent/searchReferenceable.ts b/packages/api/src/routes/auth/agent/searchReferenceable.ts index 8fde2bdb..75660d6e 100644 --- a/packages/api/src/routes/auth/agent/searchReferenceable.ts +++ b/packages/api/src/routes/auth/agent/searchReferenceable.ts @@ -142,7 +142,6 @@ export const searchReferenceableRoute = apiFactory .where( and( eq(models.file.idOrganization, idOrganization), - idYear ? eq(models.file.idYear, idYear) : undefined, or( ilike(sql`COALESCE(${models.file.name}, '')`, pattern), ilike(sql`COALESCE(${models.file.reference}, '')`, pattern), diff --git a/packages/api/src/utilities/ocr/processOcr.ts b/packages/api/src/utilities/ocr/processOcr.ts index 4ab74d56..0625bf46 100644 --- a/packages/api/src/utilities/ocr/processOcr.ts +++ b/packages/api/src/utilities/ocr/processOcr.ts @@ -42,7 +42,7 @@ interface ProcessOcrResult { } export async function processOcr(params: ProcessOcrParams): Promise { - const { idOrganization, idYear, idUser, sourceFile } = params + const { idOrganization, idUser, sourceFile } = params console.log( `[processOcr] Starting OCR for file "${sourceFile.name}" (id=${sourceFile.id}, type=${sourceFile.type}, storageKey=${sourceFile.storageKey})`, @@ -175,13 +175,7 @@ export async function processOcr(params: ProcessOcrParams): Promise 0 && existingOcrFiles[0]) { @@ -208,7 +202,7 @@ export async function processOcr(params: ProcessOcrParams): Promise yearModel.id, { - onDelete: "cascade", - onUpdate: "cascade", - }), idFolder: idColumn("id_folder").references(() => folderModel.id, { onDelete: "set null", onUpdate: "cascade", @@ -31,11 +26,12 @@ export const fileModel = pgTable( }), name: varchar("name", { length: 256, - }), + }).notNull(), storageKey: text("storage_key"), type: text("type"), size: integer("size"), hash: text("hash"), + date: dateTimeColumn("date"), createdAt: dateTimeColumn("created_at").notNull(), lastUpdatedAt: dateTimeColumn("last_updated_at"), createdBy: idColumn("created_by").references((): AnyPgColumn => userModel.id, { @@ -48,8 +44,8 @@ export const fileModel = pgTable( }), }, (table) => [ - uniqueIndex("table_file_id_organization_id_year_hash_unique") - .on(table.idOrganization, table.idYear, table.hash) + uniqueIndex("table_file_id_organization_hash_unique") + .on(table.idOrganization, table.hash) .where(sql`${table.hash} IS NOT NULL`), ], ) diff --git a/packages/metadata/src/models/folder.ts b/packages/metadata/src/models/folder.ts index c2fff8b1..4fda51ae 100644 --- a/packages/metadata/src/models/folder.ts +++ b/packages/metadata/src/models/folder.ts @@ -3,7 +3,6 @@ import { dateTimeColumn } from "../components/models/dateTimeColumn.js" import { idColumn } from "../components/models/idColumn.js" import { organizationModel } from "./organization.js" import { userModel } from "./user.js" -import { yearModel } from "./year.js" // Model export const folderModel = pgTable("table_folder", { @@ -14,12 +13,6 @@ export const folderModel = pgTable("table_folder", { onUpdate: "cascade", }) .notNull(), - idYear: idColumn("id_year") - .references(() => yearModel.id, { - onDelete: "cascade", - onUpdate: "cascade", - }) - .notNull(), idFolderParent: idColumn("id_folder_parent").references((): AnyPgColumn => folderModel.id, { onDelete: "cascade", onUpdate: "cascade", diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts index 2664b685..6b907bad 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts @@ -9,7 +9,6 @@ export const generateFileGetSignedUrlRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFile: fileSchema.entries.id, - idYear: fileSchema.entries.idYear, }), return: v.object({ url: v.string(), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts index 8433d42d..b14f4924 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts @@ -9,7 +9,6 @@ export const ocrFileRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFile: fileSchema.entries.id, - idYear: fileSchema.entries.idYear, }), return: v.object({ file: fileSchemaReturn, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts index 2ab709ec..3df53d37 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts @@ -9,7 +9,6 @@ export const readOneFileRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFile: fileSchema.entries.id, - idYear: fileSchema.entries.idYear, }), return: fileSchemaReturn, }, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts index 10e79b21..b89eb7b8 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts @@ -9,9 +9,9 @@ export const updateOneFileRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFile: fileSchema.entries.id, - idYear: fileSchema.entries.idYear, reference: v.optional(fileSchema.entries.reference), name: v.optional(fileSchema.entries.name), + date: v.optional(fileSchema.entries.date), idFolder: v.optional(fileSchema.entries.idFolder), }), return: fileSchemaReturn, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts index 2411e3e3..7e9d07bf 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts @@ -8,10 +8,9 @@ export const createOneFileRouteDefinition = routeDefinition({ path: `${routePath.auth}/create-one-file`, schemas: { body: v.object({ - idYear: fileSchema.entries.idYear, idFolder: v.optional(fileSchema.entries.idFolder), reference: fileSchema.entries.reference, - name: v.optional(fileSchema.entries.name), + name: fileSchema.entries.name, hash: fileSchema.entries.hash, }), return: fileSchemaReturn, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts index 1ad5986d..f04a724d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts @@ -1,15 +1,13 @@ import * as v from "valibot" import { routePath } from "../../../../../../../../components/index.js" -import { fileSchema, fileSchemaReturn } from "../../../../../../../../schemas/file.js" +import { fileSchemaReturn } from "../../../../../../../../schemas/file.js" import { routeDefinition } from "../../../../../../../../utilities/routeDefinition.js" export const readAllFilesRouteDefinition = routeDefinition({ protocol: "http", path: `${routePath.auth}/read-all-files`, schemas: { - body: v.object({ - idYear: fileSchema.entries.idYear, - }), + body: v.object({}), return: v.array(fileSchemaReturn), }, }) diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts index 9203b787..024c33c6 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts @@ -9,7 +9,6 @@ export const deleteOneFolderRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFolder: folderSchema.entries.id, - idYear: folderSchema.entries.idYear, }), return: v.object({}), }, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts index 40d1af9d..df2083a4 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts @@ -9,7 +9,6 @@ export const readOneFolderRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFolder: folderSchema.entries.id, - idYear: folderSchema.entries.idYear, }), return: folderSchemaReturn, }, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts index 338ef137..ed1cfe74 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts @@ -9,7 +9,6 @@ export const updateOneFolderRouteDefinition = routeDefinition({ schemas: { body: v.object({ idFolder: folderSchema.entries.id, - idYear: folderSchema.entries.idYear, name: v.optional(folderSchema.entries.name), idFolderParent: v.optional(folderSchema.entries.idFolderParent), }), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts index 8b0b1a9a..f45afc32 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts @@ -8,7 +8,6 @@ export const createOneFolderRouteDefinition = routeDefinition({ path: `${routePath.auth}/create-one-folder`, schemas: { body: v.object({ - idYear: folderSchema.entries.idYear, idFolderParent: v.optional(folderSchema.entries.idFolderParent), name: folderSchema.entries.name, }), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts index 2ed2b7a0..9abcd579 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts @@ -1,15 +1,13 @@ import * as v from "valibot" import { routePath } from "../../../../../../../../components/index.js" -import { folderSchema, folderSchemaReturn } from "../../../../../../../../schemas/folder.js" +import { folderSchemaReturn } from "../../../../../../../../schemas/folder.js" import { routeDefinition } from "../../../../../../../../utilities/routeDefinition.js" export const readAllFoldersRouteDefinition = routeDefinition({ protocol: "http", path: `${routePath.auth}/read-all-folders`, schemas: { - body: v.object({ - idYear: folderSchema.entries.idYear, - }), + body: v.object({}), return: v.array(folderSchemaReturn), }, }) diff --git a/packages/metadata/src/schemas/file.ts b/packages/metadata/src/schemas/file.ts index 8f4dcc18..453b5ec1 100644 --- a/packages/metadata/src/schemas/file.ts +++ b/packages/metadata/src/schemas/file.ts @@ -7,22 +7,23 @@ import type { fileModel } from "../models/file.js" export const fileSchema = v.object({ id: v.nonNullable(idSchema, "Ce champ est requis"), idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), - idYear: v.nullable(idSchema), idFolder: v.nullable(idSchema), reference: v.nullable( varcharSchema({ maxLength: 256, }), ), - name: v.nullable( + name: v.nonNullable( varcharSchema({ maxLength: 256, }), + "Ce champ est requis", ), storageKey: v.nullable(stringSchema), type: v.nullable(stringSchema), size: v.nullable(integerSchema), hash: v.nullable(stringSchema), + date: v.nullable(dateTimeSchema), createdAt: v.nonNullable(dateTimeSchema, "Ce champ est requis"), lastUpdatedAt: v.nullable(dateTimeSchema), createdBy: v.nullable(idSchema), @@ -32,7 +33,6 @@ export const fileSchema = v.object({ export const fileSchemaReturn = v.pick(fileSchema, [ "id", "idOrganization", - "idYear", "idFolder", "reference", "name", @@ -42,6 +42,7 @@ export const fileSchemaReturn = v.pick(fileSchema, [ "createdAt", "lastUpdatedAt", "hash", + "date", "createdBy", "lastUpdatedBy", ]) diff --git a/packages/metadata/src/schemas/folder.ts b/packages/metadata/src/schemas/folder.ts index b4884784..12f0a4d2 100644 --- a/packages/metadata/src/schemas/folder.ts +++ b/packages/metadata/src/schemas/folder.ts @@ -7,7 +7,6 @@ import type { folderModel } from "../models/folder.js" export const folderSchema = v.object({ id: v.nonNullable(idSchema, "Ce champ est requis"), idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), - idYear: v.nonNullable(idSchema, "Ce champ est requis"), idFolderParent: v.nullable(idSchema), name: v.nonNullable( varcharSchema({ @@ -24,7 +23,6 @@ export const folderSchema = v.object({ export const folderSchemaReturn = v.pick(folderSchema, [ "id", "idOrganization", - "idYear", "idFolderParent", "name", "createdAt", diff --git a/packages/tools/drizzle/0022_move_storage_to_org_level.sql b/packages/tools/drizzle/0022_move_storage_to_org_level.sql new file mode 100644 index 00000000..c5afa3d3 --- /dev/null +++ b/packages/tools/drizzle/0022_move_storage_to_org_level.sql @@ -0,0 +1,17 @@ +-- Move file/folder storage from year-scoped to organization-level +-- 1. Drop id_year from table_file and table_folder +-- 2. Update deduplication index to org+hash scope + +-- Step 1: Drop id_year column from table_file +ALTER TABLE "table_file" DROP COLUMN IF EXISTS "id_year"; + +-- Step 2: Drop id_year column from table_folder +ALTER TABLE "table_folder" DROP COLUMN IF EXISTS "id_year"; + +-- Step 3: Drop old per-year deduplication index +DROP INDEX IF EXISTS "table_file_id_organization_id_year_hash_unique"; + +-- Step 4: Create new org-level deduplication index +CREATE UNIQUE INDEX IF NOT EXISTS "table_file_id_organization_hash_unique" +ON "table_file" ("id_organization", "hash") +WHERE "hash" IS NOT NULL; diff --git a/packages/tools/drizzle/0023_add_date_to_file.sql b/packages/tools/drizzle/0023_add_date_to_file.sql new file mode 100644 index 00000000..39330cf5 --- /dev/null +++ b/packages/tools/drizzle/0023_add_date_to_file.sql @@ -0,0 +1,2 @@ +-- Add optional content date to table_file (e.g. invoice date, distinct from createdAt) +ALTER TABLE "table_file" ADD COLUMN "date" TIMESTAMP WITH TIME ZONE; diff --git a/packages/tools/drizzle/0024_make_file_name_not_null.sql b/packages/tools/drizzle/0024_make_file_name_not_null.sql new file mode 100644 index 00000000..0e7aa717 --- /dev/null +++ b/packages/tools/drizzle/0024_make_file_name_not_null.sql @@ -0,0 +1,2 @@ +UPDATE "table_file" SET "name" = '' WHERE "name" IS NULL; +ALTER TABLE "table_file" ALTER COLUMN "name" SET NOT NULL; diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx index f061c4d5..f1d63477 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx @@ -1,5 +1,6 @@ import { IconCalendarEvent, + IconFolders, IconPlug, IconRobot, IconRosetteDiscountCheck, @@ -36,6 +37,14 @@ export function OrganizationLayout() { idOrganization: params.idOrganization, }, }, + { + label: "Stockage", + icon: , + to: "/dashboard/organisations/$idOrganization/stockage", + params: { + idOrganization: params.idOrganization, + }, + }, { label: "Membres", icon: , diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx index c2b0c3c1..af9e2962 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx @@ -1,11 +1,12 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { ButtonPlainContent, FormatDate, FormatNull, FormatPrice, FormatText } from "@arrhes/ui" +import { ButtonPlainContent, FormatDate, FormatNull, FormatPrice, FormatText, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import type * as v from "valibot" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" +import { LinkButton } from "../../../../../components/linkButton.tsx" import { entryLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" import type { YearDataKey } from "../../yearDataWrapper.tsx" import { YearDataWrapper } from "../../yearDataWrapper.tsx" @@ -115,12 +116,18 @@ function EntryInformationsTab(props: { )} - {props.entry.idFile === null ? ( + {props.entry.idFile === null || props.file === null ? ( - ) : props.file !== null ? ( - {props.file.reference} ) : ( - + + {props.file.name} + )} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx index 09ced696..18419321 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx @@ -173,7 +173,9 @@ export function UpdateOneEntry(props: { entry: v.InferOutput ({ key: file.id, - label: file.reference ?? "", + label: file.reference + ? `${file.name} (${file.reference})` + : file.name, })} /> diff --git a/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx index 645fd5c4..d1c3a360 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx @@ -235,7 +235,9 @@ export function CreateOneEntry(props: { placeholder="Sélectionner une pièce justificative" getOption={(file) => ({ key: file.id, - label: file.reference ?? "", + label: file.reference + ? `${file.name} (${file.reference})` + : file.name, })} /> diff --git a/packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx b/packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx index e311fc19..e750228a 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx @@ -187,7 +187,17 @@ export function EntriesTable(props: { if (row.original.idFile === null) return const file = filesMap.get(row.original.idFile) if (!file) return - return {file.reference} + return ( + + {file.name} + + ) }, filterFn: "includesString", }, diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx index eaf17c7e..e86a632a 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx @@ -15,7 +15,6 @@ export function DeleteOneFile(props: { async function onSubmit() { const isDeleted = await deleteFileWithSignedUrl({ idFile: props.file.id, - idYear: props.file.idYear, }) if (isDeleted === false) { @@ -28,9 +27,7 @@ export function DeleteOneFile(props: { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.file.idYear, - }, + body: {}, }) toast({ @@ -39,10 +36,9 @@ export function DeleteOneFile(props: { }) applicationRouter.navigate({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage", + to: "/dashboard/organisations/$idOrganization/stockage", params: { idOrganization: props.file.idOrganization, - idYear: props.file.idYear, }, search: { idFolder: undefined, diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileData.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileData.tsx index 997a0eb3..8e6492c0 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileData.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileData.tsx @@ -8,7 +8,6 @@ import { useDataFromAPI } from "../../../../../utilities/useHTTPData.ts" export function FileData(props: { idFile: v.InferOutput["id"] idOrganization: v.InferOutput["id"] - idYear: v.InferOutput["id"] children: ( data: v.InferOutput, ) => ReactElement | Array | null @@ -17,7 +16,6 @@ export function FileData(props: { routeDefinition: readOneFileRouteDefinition, body: { idFile: props.idFile, - idYear: props.idYear, }, }) diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileFile.tsx index 3d3181ef..ce6ad129 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileFile.tsx @@ -14,7 +14,6 @@ export function FileFile(props: { file: v.InferOutput {(file) => { @@ -37,10 +36,9 @@ export function FileLayout() { })} > , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage/$idFile", + to: "/dashboard/organisations/$idOrganization/stockage/$idFile", params: { idOrganization: params.idOrganization, - idYear: params.idYear, idFile: params.idFile, }, }, { label: "Métadonnées", icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage/$idFile/métadonnées", + to: "/dashboard/organisations/$idOrganization/stockage/$idFile/métadonnées", params: { idOrganization: params.idOrganization, - idYear: params.idYear, idFile: params.idFile, }, }, { label: "Visualisation", icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage/$idFile/visualisation", + to: "/dashboard/organisations/$idOrganization/stockage/$idFile/visualisation", params: { idOrganization: params.idOrganization, - idYear: params.idYear, idFile: params.idFile, }, }, diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx index f5a58b46..41082ed5 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx @@ -3,7 +3,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx" +import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" import { FileData } from "./fileData.tsx" export function FileMetadataTab() { @@ -14,7 +14,6 @@ export function FileMetadataTab() { return ( {(file) => { diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx index df7b80d2..d8518516 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx @@ -1,9 +1,9 @@ -import { FormatFileSize, FormatText } from "@arrhes/ui" +import { FormatDateTime, FormatFileSize, FormatNull, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx" +import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" import { FileData } from "./fileData.tsx" export function FilePage() { @@ -14,36 +14,40 @@ export function FilePage() { return ( - {(file) => { - return ( - - - - - - {file.reference} - - - {file.name} - - - {file.type?.split("/").at(1)} - - - - - - - - ) - }} + {(file) => ( + + + + + + {file.reference} + + + {file.name} + + + {file.date !== null && file.date !== undefined ? ( + + ) : ( + + )} + + + {file.type?.split("/").at(1)} + + + + + + + + )} ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx index 8aab9d90..0430b733 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx" +import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" import { FileData } from "./fileData.tsx" import { FileFile } from "./fileFile.tsx" @@ -13,7 +13,6 @@ export function FileVisualisationTab() { return ( {(file) => { diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx index c571c4d6..c7be3d8b 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx @@ -7,7 +7,7 @@ import { updateOneFileRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputFile, InputText, toast } from "@arrhes/ui" +import { InputDate, InputFile, InputText, toast } from "@arrhes/ui" import { IconPencil } from "@tabler/icons-react" import { Fragment } from "react/jsx-runtime" import * as v from "valibot" @@ -40,9 +40,9 @@ export function UpdateOneFileForm(props: { file: v.InferOutput )} /> + ( + + + + + + + + )} + /> )} diff --git a/packages/website/src/features/dashboard/$idYear/files/createOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/createOneFile.tsx index 61346a90..a945b735 100644 --- a/packages/website/src/features/dashboard/$idYear/files/createOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/createOneFile.tsx @@ -25,11 +25,10 @@ function referenceFromFileName(name: string): string { async function uploadOneFile(params: { idOrganization: string - idYear: string idFolder?: string | null file: File }): Promise<"added" | "duplicate" | "error"> { - const { file, idOrganization: _idOrganization, idYear, idFolder } = params + const { file, idOrganization: _idOrganization, idFolder } = params if (file.size > MAX_FILE_SIZE) { toast({ @@ -45,10 +44,9 @@ async function uploadOneFile(params: { const createResponse = await getResponseBodyFromAPI({ routeDefinition: createOneFileRouteDefinition, body: { - idYear, idFolder: idFolder ?? undefined, reference: referenceFromFileName(file.name), - name: file.name, + name: referenceFromFileName(file.name), hash: hash, }, }) @@ -117,7 +115,6 @@ async function uploadOneFile(params: { export function CreateOneFile(props: { idOrganization: v.InferOutput["id"] - idYear: v.InferOutput["id"] idFolder?: string | null children: JSX.Element }) { @@ -131,7 +128,6 @@ export function CreateOneFile(props: { fileArray.map((file) => uploadOneFile({ idOrganization: props.idOrganization, - idYear: props.idYear, idFolder: props.idFolder, file, }), @@ -145,9 +141,7 @@ export function CreateOneFile(props: { if (added > 0) { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) } diff --git a/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx b/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx index db6bab3e..219e89f0 100644 --- a/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx @@ -16,7 +16,6 @@ import { invalidateData } from "../../../../utilities/invalidateData.js" export function CreateOneFolder(props: { idOrganization: v.InferOutput["id"] - idYear: v.InferOutput["id"] idFolderParent?: string | null }) { const [open, setOpen] = useState(false) @@ -38,7 +37,6 @@ export function CreateOneFolder(props: { { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) setOpen(false) }} diff --git a/packages/website/src/features/dashboard/$idYear/files/deleteFileWithSignedUrl.ts b/packages/website/src/features/dashboard/$idYear/files/deleteFileWithSignedUrl.ts index 06284882..030f4d34 100644 --- a/packages/website/src/features/dashboard/$idYear/files/deleteFileWithSignedUrl.ts +++ b/packages/website/src/features/dashboard/$idYear/files/deleteFileWithSignedUrl.ts @@ -4,7 +4,7 @@ import { } from "@arrhes/application-metadata/routes" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" -export async function deleteFileWithSignedUrl(parameters: { idFile: string; idYear: string | null }) { +export async function deleteFileWithSignedUrl(parameters: { idFile: string }) { const signedDeleteUrlResponse = await getResponseBodyFromAPI({ routeDefinition: generateFileDeleteSignedUrlRouteDefinition, body: { diff --git a/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx b/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx index 7a852cb1..2e4193b4 100644 --- a/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx @@ -21,11 +21,7 @@ import { UpdateOneFileForm } from "./$idFile/updateOneFileForm.js" import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" import { MoveOneFileForm } from "./moveOneFileForm.js" -export function FileActions(props: { - file: v.InferOutput - idOrganization: string - idYear: string -}) { +export function FileActions(props: { file: v.InferOutput; idOrganization: string }) { const [editOpen, setEditOpen] = useState(false) const [moveOpen, setMoveOpen] = useState(false) const [deleteOpen, setDeleteOpen] = useState(false) @@ -42,7 +38,6 @@ export function FileActions(props: { async function handleDelete() { const isDeleted = await deleteFileWithSignedUrl({ idFile: props.file.id, - idYear: props.idYear, }) if (isDeleted === false) { @@ -55,9 +50,7 @@ export function FileActions(props: { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -72,7 +65,6 @@ export function FileActions(props: { routeDefinition: ocrFileRouteDefinition, body: { idFile: props.file.id, - idYear: props.idYear, }, hasToastMessage: true, }) @@ -84,9 +76,7 @@ export function FileActions(props: { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -115,10 +105,9 @@ export function FileActions(props: { > setMoveOpen(false)} /> diff --git a/packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx index 816cc676..7bcabcf6 100644 --- a/packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx @@ -18,7 +18,6 @@ import { MoveOneFileForm } from "./moveOneFileForm.js" export function FileContextMenu(props: { file: v.InferOutput idOrganization: string - idYear: string children: ReactElement }) { const [editOpen, setEditOpen] = useState(false) @@ -28,7 +27,6 @@ export function FileContextMenu(props: { async function handleDelete() { const isDeleted = await deleteFileWithSignedUrl({ idFile: props.file.id, - idYear: props.idYear, }) if (isDeleted === false) { @@ -41,9 +39,7 @@ export function FileContextMenu(props: { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -61,10 +57,9 @@ export function FileContextMenu(props: { leftIcon={} onSelect={() => { applicationRouter.navigate({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage/$idFile", + to: "/dashboard/organisations/$idOrganization/stockage/$idFile", params: { idOrganization: props.idOrganization, - idYear: props.idYear, idFile: props.file.id, }, }) @@ -126,7 +121,6 @@ export function FileContextMenu(props: { > setMoveOpen(false)} /> diff --git a/packages/website/src/features/dashboard/$idYear/files/fileSelect.tsx b/packages/website/src/features/dashboard/$idYear/files/fileSelect.tsx index d58304db..7fb2dee7 100644 --- a/packages/website/src/features/dashboard/$idYear/files/fileSelect.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/fileSelect.tsx @@ -29,7 +29,7 @@ export function FileSelect(props: { ? [] : filesResponse.data.map((file) => ({ key: file.id, - label: file.reference ?? "", + label: file.reference ? `${file.name} (${file.reference})` : file.name, })) } /> diff --git a/packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx b/packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx index 65bc9340..29f112a6 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx @@ -122,7 +122,6 @@ type DragPayload = export function FilesGrid(props: { idOrganization: v.InferOutput["id"] - idYear: v.InferOutput["id"] files: Array> folders: Array> currentFolderId: string | null @@ -211,7 +210,6 @@ export function FilesGrid(props: { routeDefinition: updateOneFileRouteDefinition, body: { idFile: payload.id, - idYear: props.idYear, idFolder: folderId, }, }) @@ -226,9 +224,7 @@ export function FilesGrid(props: { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -246,7 +242,6 @@ export function FilesGrid(props: { routeDefinition: updateOneFolderRouteDefinition, body: { idFolder: payload.id, - idYear: props.idYear, idFolderParent: folderId, }, }) @@ -261,9 +256,7 @@ export function FilesGrid(props: { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -386,7 +379,6 @@ export function FilesGrid(props: { key={folder.id} folder={folder} idOrganization={props.idOrganization} - idYear={props.idYear} >
- {file.name ?? file.reference} + {file.name} - {file.name && file.reference && ( + {file.reference && ( {(folders) => ( void params: { idOrganization: string - idYear: string } }) { const { @@ -119,9 +118,7 @@ export function FilesPageContent(props: { > {(files) => { const currentFiles = files.filter((f) => (f.idFolder ?? null) === currentFolderId) @@ -130,7 +127,6 @@ export function FilesPageContent(props: { return ( ["id"] - idYear: v.InferOutput["id"] files: Array> folders: Array> currentFolderId: string | null @@ -274,7 +273,6 @@ export function FilesTable(props: { routeDefinition: updateOneFileRouteDefinition, body: { idFile: payload.id, - idYear: props.idYear, idFolder: targetFolderId, }, }) @@ -289,9 +287,7 @@ export function FilesTable(props: { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -309,7 +305,6 @@ export function FilesTable(props: { routeDefinition: updateOneFolderRouteDefinition, body: { idFolder: payload.id, - idYear: props.idYear, idFolderParent: targetFolderId, }, }) @@ -324,9 +319,7 @@ export function FilesTable(props: { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ @@ -366,12 +359,7 @@ export function FilesTable(props: { enableRowSelection={(row) => row.original.kind !== "back"} getRowId={(row) => (row.kind === "back" ? "__back__" : row.data.id)} resetSelectionTrigger={props.currentFolderId} - selectionActions={(selectedRows) => ( - - )} + selectionActions={(selectedRows) => } emptyStateProps={{ icon: , title: "Aucun fichier", @@ -456,10 +444,9 @@ export function FilesTable(props: { return } applicationRouter.navigate({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage/$idFile", + to: "/dashboard/organisations/$idOrganization/stockage/$idFile", params: { idOrganization: props.idOrganization, - idYear: props.idYear, idFile: item.data.id, }, }) @@ -526,7 +513,6 @@ export function FilesTable(props: { ) @@ -535,7 +521,6 @@ export function FilesTable(props: { ) }, diff --git a/packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx index 8773d055..586b1e50 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx @@ -29,7 +29,7 @@ export type TableRow = data: v.InferOutput } -export function FilesTableSelectionActions(props: { selectedRows: Array>; idYear: string }) { +export function FilesTableSelectionActions(props: { selectedRows: Array> }) { const [deleteOpen, setDeleteOpen] = useState(false) const selectedFiles = props.selectedRows .filter((r) => r.original.kind === "file") @@ -63,7 +63,6 @@ export function FilesTableSelectionActions(props: { selectedRows: Array deleteFileWithSignedUrl({ idFile: file.id, - idYear: props.idYear, }).then((ok) => ({ ok, })), @@ -73,7 +72,6 @@ export function FilesTableSelectionActions(props: { selectedRows: Array r.ok === false)) { diff --git a/packages/website/src/features/dashboard/$idYear/files/folderActions.tsx b/packages/website/src/features/dashboard/$idYear/files/folderActions.tsx index ce6cb931..d96c1976 100644 --- a/packages/website/src/features/dashboard/$idYear/files/folderActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/folderActions.tsx @@ -17,7 +17,6 @@ import { UpdateOneFolderForm } from "./updateOneFolderForm.js" export function FolderActions(props: { folder: v.InferOutput idOrganization: string - idYear: string onFolderOpen: (folderId: string | null) => void }) { const [editOpen, setEditOpen] = useState(false) @@ -29,7 +28,6 @@ export function FolderActions(props: { routeDefinition: deleteOneFolderRouteDefinition, body: { idFolder: props.folder.id, - idYear: props.idYear, }, }) @@ -43,9 +41,7 @@ export function FolderActions(props: { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ diff --git a/packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx index 3759f7cf..0905ce58 100644 --- a/packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx @@ -17,7 +17,6 @@ import { UpdateOneFolderForm } from "./updateOneFolderForm.js" export function FolderContextMenu(props: { folder: v.InferOutput idOrganization: string - idYear: string children: ReactElement }) { const [editOpen, setEditOpen] = useState(false) @@ -29,7 +28,6 @@ export function FolderContextMenu(props: { routeDefinition: deleteOneFolderRouteDefinition, body: { idFolder: props.folder.id, - idYear: props.idYear, }, }) @@ -43,9 +41,7 @@ export function FolderContextMenu(props: { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) toast({ diff --git a/packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx b/packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx index 10fc4f6a..8e36b9cd 100644 --- a/packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx @@ -20,16 +20,10 @@ import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" const rootOptionKey = "__root__" -export function MoveOneFileForm(props: { - file: v.InferOutput - idYear: string - onSuccess?: () => void -}) { +export function MoveOneFileForm(props: { file: v.InferOutput; onSuccess?: () => void }) { const foldersResponse = useDataFromAPI({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) const folderOptions = useMemo( @@ -53,7 +47,6 @@ export function MoveOneFileForm(props: { schema={updateOneFileRouteDefinition.schemas.body} defaultValues={{ idFile: props.file.id, - idYear: props.idYear, idFolder: props.file.idFolder, }} submitButtonProps={{ @@ -65,7 +58,6 @@ export function MoveOneFileForm(props: { routeDefinition: updateOneFileRouteDefinition, body: { idFile: props.file.id, - idYear: data.idYear, idFolder: data.idFolder, }, }) @@ -88,9 +80,7 @@ export function MoveOneFileForm(props: { onSuccess={async () => { await invalidateData({ routeDefinition: readAllFilesRouteDefinition, - body: { - idYear: props.idYear, - }, + body: {}, }) props.onSuccess?.() diff --git a/packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx b/packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx index bc879fd7..c60310c1 100644 --- a/packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx @@ -59,9 +59,7 @@ export function MoveOneFolderForm(props: { }) { const foldersResponse = useDataFromAPI({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.folder.idYear, - }, + body: {}, }) const folderOptions = useMemo(() => { @@ -94,7 +92,6 @@ export function MoveOneFolderForm(props: { schema={updateOneFolderRouteDefinition.schemas.body} defaultValues={{ idFolder: props.folder.id, - idYear: props.folder.idYear, idFolderParent: props.folder.idFolderParent, }} submitButtonProps={{ @@ -106,7 +103,6 @@ export function MoveOneFolderForm(props: { routeDefinition: updateOneFolderRouteDefinition, body: { idFolder: props.folder.id, - idYear: data.idYear, idFolderParent: data.idFolderParent, }, }) @@ -129,9 +125,7 @@ export function MoveOneFolderForm(props: { onSuccess={async () => { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.folder.idYear, - }, + body: {}, }) props.onSuccess?.() diff --git a/packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx b/packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx index 91e9e8ee..3f96d19f 100644 --- a/packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx @@ -21,7 +21,6 @@ export function UpdateOneFolderForm(props: { schema={updateOneFolderRouteDefinition.schemas.body} defaultValues={{ idFolder: props.folder.id, - idYear: props.folder.idYear, name: props.folder.name, }} submitButtonProps={{ @@ -33,7 +32,6 @@ export function UpdateOneFolderForm(props: { routeDefinition: updateOneFolderRouteDefinition, body: { idFolder: props.folder.id, - idYear: data.idYear, name: data.name, }, }) @@ -54,9 +52,7 @@ export function UpdateOneFolderForm(props: { onSuccess={async () => { await invalidateData({ routeDefinition: readAllFoldersRouteDefinition, - body: { - idYear: props.folder.idYear, - }, + body: {}, }) props.onSuccess?.() }} diff --git a/packages/website/src/features/dashboard/$idYear/yearLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearLayout.tsx index d3548bed..829745d6 100644 --- a/packages/website/src/features/dashboard/$idYear/yearLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearLayout.tsx @@ -1,4 +1,4 @@ -import { IconFolders, IconPencil, IconReport, IconSettings } from "@tabler/icons-react" +import { IconPencil, IconReport, IconSettings } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" import { Fragment } from "react/jsx-runtime" import { PageNavigation } from "../../../components/layouts/page/pageNavigation.tsx" @@ -22,15 +22,6 @@ export function YearLayout() { idYear: params.idYear, }, }, - { - label: "Stockage", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/stockage", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, { label: "Documents comptables", icon: , diff --git a/packages/website/src/routes/root/dashboard/dashboardTree.ts b/packages/website/src/routes/root/dashboard/dashboardTree.ts index bfbc5d91..f6ae18ef 100644 --- a/packages/website/src/routes/root/dashboard/dashboardTree.ts +++ b/packages/website/src/routes/root/dashboard/dashboardTree.ts @@ -29,6 +29,12 @@ import { organizationSettingsLayoutRoute } from "./organizations/$idOrganization import { organizationSettingsRoute } from "./organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx" import { organizationUsersLayoutRoute } from "./organizations/$idOrganization/organizationUsers/organizationUsersLayoutRoute.tsx" import { organizationUsersRoute } from "./organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx" +import { fileLayoutRoute } from "./organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" +import { fileMetadataRoute } from "./organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx" +import { fileRoute } from "./organizations/$idOrganization/storage/$idFile/fileRoute.tsx" +import { fileVisualisationRoute } from "./organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx" +import { storageLayoutRoute } from "./organizations/$idOrganization/storage/storageLayoutRoute.tsx" +import { storageRoute } from "./organizations/$idOrganization/storage/storageRoute.tsx" import { entryLineLayoutRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx" import { entryLineMetadataRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx" import { entryLineRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx" @@ -39,12 +45,6 @@ import { entryMetadataRoute } from "./organizations/$idOrganization/years/$idYea import { entryRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx" import { entriesLayoutRoute } from "./organizations/$idOrganization/years/$idYear/entries/entriesLayoutRoute.tsx" import { entriesRoute } from "./organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx" -import { fileLayoutRoute } from "./organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx" -import { fileMetadataRoute } from "./organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx" -import { fileRoute } from "./organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx" -import { fileVisualisationRoute } from "./organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx" -import { filesLayoutRoute } from "./organizations/$idOrganization/years/$idYear/files/filesLayoutRoute.tsx" -import { filesRoute } from "./organizations/$idOrganization/years/$idYear/files/filesRoute.tsx" import { balanceReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx" import { balanceSheetReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx" import { incomeStatementReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx" @@ -152,6 +152,14 @@ export const dashboardTree: AnyRoute = dashboardLayoutRoute.addChildren([ agentSessionRoute, ]), ]), + storageLayoutRoute.addChildren([ + storageRoute, + fileLayoutRoute.addChildren([ + fileRoute, + fileMetadataRoute, + fileVisualisationRoute, + ]), + ]), ]), yearsPathRoute.addChildren([ yearPathRoute.addChildren([ @@ -170,14 +178,6 @@ export const dashboardTree: AnyRoute = dashboardLayoutRoute.addChildren([ entryLineMetadataRoute, ]), ]), - filesLayoutRoute.addChildren([ - filesRoute, - fileLayoutRoute.addChildren([ - fileRoute, - fileMetadataRoute, - fileVisualisationRoute, - ]), - ]), reportsLayoutRoute.addChildren([ reportsRoute, journalReportRoute, diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx new file mode 100644 index 00000000..9af10259 --- /dev/null +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx @@ -0,0 +1,14 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { storageLayoutRoute } from "../storageLayoutRoute.js" + +export const fileLayoutRoute = createRoute({ + getParentRoute: () => storageLayoutRoute, + path: "/$idFile", + beforeLoad: () => ({ + title: "Pièce justificative", + }), + component: lazyRouteComponent( + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/fileLayout.js"), + "FileLayout", + ), +}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx new file mode 100644 index 00000000..0b374f99 --- /dev/null +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx @@ -0,0 +1,14 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { fileLayoutRoute } from "./fileLayoutRoute.js" + +export const fileMetadataRoute = createRoute({ + getParentRoute: () => fileLayoutRoute, + path: "/métadonnées", + beforeLoad: () => ({ + title: "Métadonnées", + }), + component: lazyRouteComponent( + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/fileMetadataTab.js"), + "FileMetadataTab", + ), +}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx new file mode 100644 index 00000000..306eea9a --- /dev/null +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx @@ -0,0 +1,14 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { fileLayoutRoute } from "./fileLayoutRoute.js" + +export const fileRoute = createRoute({ + getParentRoute: () => fileLayoutRoute, + path: "/", + beforeLoad: () => ({ + title: undefined, + }), + component: lazyRouteComponent( + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/filePage.js"), + "FilePage", + ), +}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx new file mode 100644 index 00000000..eb84a4af --- /dev/null +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx @@ -0,0 +1,14 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { fileLayoutRoute } from "./fileLayoutRoute.js" + +export const fileVisualisationRoute = createRoute({ + getParentRoute: () => fileLayoutRoute, + path: "/visualisation", + beforeLoad: () => ({ + title: "Visualisation", + }), + component: lazyRouteComponent( + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/fileVisualisationTab.js"), + "FileVisualisationTab", + ), +}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx new file mode 100644 index 00000000..ab12ac7c --- /dev/null +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx @@ -0,0 +1,11 @@ +import { createRoute, Outlet } from "@tanstack/react-router" +import { organizationLayoutRoute } from "../organizationLayoutRoute.js" + +export const storageLayoutRoute = createRoute({ + getParentRoute: () => organizationLayoutRoute, + path: "/stockage", + beforeLoad: () => ({ + title: "Stockage", + }), + component: () => , +}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx new file mode 100644 index 00000000..7562b11f --- /dev/null +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx @@ -0,0 +1,17 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { storageLayoutRoute } from "./storageLayoutRoute.js" + +export const storageRoute = createRoute({ + getParentRoute: () => storageLayoutRoute, + path: "/", + validateSearch: (search: Record) => ({ + idFolder: typeof search.idFolder === "string" ? search.idFolder : undefined, + }), + beforeLoad: () => ({ + title: undefined, + }), + component: lazyRouteComponent( + () => import("../../../../../../features/dashboard/$idYear/files/filesPage.js"), + "FilesPage", + ), +}) From 15c9b9a09873964c83c21d9fbd5eb03abea7c886 Mon Sep 17 00:00:00 2001 From: &mile Date: Mon, 11 May 2026 20:44:19 +0200 Subject: [PATCH 02/14] feat(api): add DB schema drift check on startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New checkDatabaseSchema utility: bidirectional check between Drizzle models and information_schema.columns — detects missing/extra tables and columns in both directions - server.ts: run schema check before the restart loop; SCHEMA_CHECK_ONLY=1 exits immediately after check (used by start.sh pre-flight) - start.sh: run plain tsx (no watch) with SCHEMA_CHECK_ONLY=1 before launching tsx watch so a non-zero exit propagates to the shell - compose.yml: add healthcheck on the API container so docker compose --wait correctly surfaces startup failures - up.sh: use --wait flag and print logs of exited containers on failure - metadata/package.json: add 'source' export condition pointing to .ts files so tsx --conditions source skips the build step in dev - api/worker package.json dev scripts: add --conditions source - worker: fix runAgentSession — remove idYear from file query/insert, update storageKey to org-level path (organizations/$org/storage/$id) --- .workflows/dev/compose.yml | 6 ++ .workflows/dev/packages/api/start.sh | 13 ++-- .workflows/dev/up.sh | 31 +++++--- packages/api/package.json | 4 +- packages/api/src/server.ts | 22 +++++- .../api/src/utilities/checkDatabaseSchema.ts | 71 +++++++++++++++++++ packages/metadata/package.json | 9 ++- packages/worker/package.json | 4 +- .../jobs/runAgentSession/runAgentSession.ts | 4 +- 9 files changed, 141 insertions(+), 23 deletions(-) create mode 100644 packages/api/src/utilities/checkDatabaseSchema.ts diff --git a/.workflows/dev/compose.yml b/.workflows/dev/compose.yml index 3b34fe79..dbc24498 100644 --- a/.workflows/dev/compose.yml +++ b/.workflows/dev/compose.yml @@ -161,6 +161,12 @@ services: condition: service_healthy redis: condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "node -e \"require('http').get('http://localhost:' + process.env.PORT, r => process.exit(r.statusCode < 500 ? 0 : 1)).on('error', () => process.exit(1))\""] + interval: 10s + timeout: 5s + retries: 5 + start_period: 60s # Website - Frontend interface (React + Vite) website: diff --git a/.workflows/dev/packages/api/start.sh b/.workflows/dev/packages/api/start.sh index 6fcf9344..40870fd5 100644 --- a/.workflows/dev/packages/api/start.sh +++ b/.workflows/dev/packages/api/start.sh @@ -2,14 +2,17 @@ # ============================================================================== # Start API Server # ============================================================================== -# Starts the API development server with hot reload. -# Builds workspace dependencies first (tsc --build follows project references). +# 1. Runs a one-off schema drift check (plain tsx, no watch). +# If the DB is out of sync with the Drizzle models the script exits non-zero, +# the container stops, and `docker compose up --wait` surfaces the error. +# 2. Starts the API dev server with hot reload (tsx watch). +# tsx is started with --conditions source so that @arrhes/application-metadata +# resolves to ./src/index.ts directly — no build step needed in dev. # ============================================================================== set -e -echo "Building workspace dependencies..." -cd /workspace/packages/api -pnpm run build +echo "Checking database schema..." +SCHEMA_CHECK_ONLY=1 pnpm --filter="@arrhes/application-api" exec tsx --conditions source ./src/server.ts echo "Starting API dev server..." exec pnpm --filter="@arrhes/application-api" dev diff --git a/.workflows/dev/up.sh b/.workflows/dev/up.sh index 55c51d47..65563b50 100644 --- a/.workflows/dev/up.sh +++ b/.workflows/dev/up.sh @@ -84,15 +84,28 @@ POSTGRES_HOST_PORT=$postgres_host_port REDIS_HOST_PORT=$redis_host_port EOF -WEBSITE_HOST_PORT="$website_host_port" \ -API_HOST_PORT="$api_host_port" \ -STORAGE_HOST_PORT="$storage_host_port" \ -RUSTFS_UI_HOST_PORT="$rustfs_ui_host_port" \ -MAILPIT_UI_HOST_PORT="$mailpit_ui_host_port" \ -MAILPIT_SMTP_HOST_PORT="$mailpit_smtp_host_port" \ -POSTGRES_HOST_PORT="$postgres_host_port" \ -REDIS_HOST_PORT="$redis_host_port" \ - "${DC[@]}" up --detach --build --force-recreate +if ! WEBSITE_HOST_PORT="$website_host_port" \ + API_HOST_PORT="$api_host_port" \ + STORAGE_HOST_PORT="$storage_host_port" \ + RUSTFS_UI_HOST_PORT="$rustfs_ui_host_port" \ + MAILPIT_UI_HOST_PORT="$mailpit_ui_host_port" \ + MAILPIT_SMTP_HOST_PORT="$mailpit_smtp_host_port" \ + POSTGRES_HOST_PORT="$postgres_host_port" \ + REDIS_HOST_PORT="$redis_host_port" \ + "${DC[@]}" up --detach --build --force-recreate --wait; then + echo "" + echo "==============================================" + echo " ERROR: one or more services failed to start" + echo "==============================================" + echo "" + # Print logs for every exited container so the error is visible + for container in $("${DC[@]}" ps --all --filter status=exited --format '{{.Name}}' 2>/dev/null); do + echo "--- Logs for $container ---" + docker logs "$container" 2>&1 | tail -30 + echo "" + done + exit 1 +fi echo "" echo "==============================================" diff --git a/packages/api/package.json b/packages/api/package.json index ad6ba048..dcb95122 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -3,7 +3,7 @@ "type": "module", "private": false, "scripts": { - "dev": "tsx watch --env-file=.env ./src/server.ts", + "dev": "tsx watch --conditions source --env-file=.env ./src/server.ts", "build": "tsc --build", "start": "node --env-file=.env ./build/server.js", "test": "vitest run", @@ -36,4 +36,4 @@ "postgres": "3.4.9", "valibot": "1.4.0" } -} +} \ No newline at end of file diff --git a/packages/api/src/server.ts b/packages/api/src/server.ts index efb1deed..5776cc37 100644 --- a/packages/api/src/server.ts +++ b/packages/api/src/server.ts @@ -1,5 +1,6 @@ import { createServer } from "node:http" import { api } from "./api.js" +import { checkDatabaseSchema } from "./utilities/checkDatabaseSchema.js" import { getClients } from "./utilities/getClients.js" import { getEnv } from "./utilities/getEnv.js" import { ensureStorageBucket } from "./utilities/storage/ensureStorageBucket.js" @@ -15,6 +16,25 @@ async function startServer() { console.error("Unhandled Rejection:", reason) // Similar to uncaughtException handling }) + + // Schema check — runs on every startup. + // When SCHEMA_CHECK_ONLY=1, exit immediately after the check so that + // start.sh can use plain `tsx` (not watch) to get a real exit code + // before handing off to `tsx watch`. + try { + const env = getEnv() + const clients = await getClients(env) + await checkDatabaseSchema(clients.sql) + } catch (error: unknown) { + console.error("Database schema check failed — run migrations and restart:") + console.error(error instanceof Error ? error.message : error) + process.exit(1) + } + + if (process.env.SCHEMA_CHECK_ONLY === "1") { + process.exit(0) + } + while (true) { try { // Get variables and clients @@ -79,7 +99,7 @@ async function startServer() { }) // Wait indefinitely (prevents loop from restarting immediately) - await new Promise(() => {}) + await new Promise(() => { }) } catch (error: unknown) { if (error instanceof Error) { console.error( diff --git a/packages/api/src/utilities/checkDatabaseSchema.ts b/packages/api/src/utilities/checkDatabaseSchema.ts new file mode 100644 index 00000000..5071b7ab --- /dev/null +++ b/packages/api/src/utilities/checkDatabaseSchema.ts @@ -0,0 +1,71 @@ +import { models } from "@arrhes/application-metadata" +import { getTableColumns, getTableName, sql } from "drizzle-orm" +import type { sqlClient } from "../clients/sqlClient.js" + +type DbClient = ReturnType + +export async function checkDatabaseSchema(db: DbClient) { + // Collect expected tables and their columns from the Drizzle model definitions. + // `models` is a plain { key: pgTable } object — table instances only, no relations. + const expected = new Map>() // table_name -> Set + + for (const table of Object.values(models)) { + const tableName = getTableName(table) + const columns = getTableColumns(table) + const colNames = new Set(Object.values(columns).map((col) => col.name)) + expected.set(tableName, colNames) + } + + // Query all columns present in the public schema + const rows = await db.execute<{ table_name: string; column_name: string }>( + sql`SELECT table_name, column_name + FROM information_schema.columns + WHERE table_schema = 'public'`, + ) + + const actual = new Map>() + for (const row of rows) { + if (!actual.has(row.table_name)) { + actual.set(row.table_name, new Set()) + } + actual.get(row.table_name)!.add(row.column_name) + } + + const drift: string[] = [] + + // Model → DB: tables/columns expected by the code but absent from the DB + for (const [tableName, expectedCols] of expected) { + if (!actual.has(tableName)) { + drift.push(` Table '${tableName}' is missing from the database`) + continue + } + const actualCols = actual.get(tableName)! + for (const col of expectedCols) { + if (!actualCols.has(col)) { + drift.push(` Column '${tableName}.${col}' is missing from the database`) + } + } + } + + // DB → Model: tables/columns present in the DB but no longer in the code + for (const [tableName, actualCols] of actual) { + if (!expected.has(tableName)) { + drift.push(` Table '${tableName}' exists in the database but has no model`) + continue + } + const expectedCols = expected.get(tableName)! + for (const col of actualCols) { + if (!expectedCols.has(col)) { + drift.push(` Column '${tableName}.${col}' exists in the database but is not in the model`) + } + } + } + + if (drift.length > 0) { + throw new Error( + `Database schema is out of date — run migrations before starting the API:\n${drift.join("\n")}`, + ) + } + + console.info(`Database schema check passed (${expected.size} tables verified)`) +} diff --git a/packages/metadata/package.json b/packages/metadata/package.json index 52a3ae4d..addea8d2 100644 --- a/packages/metadata/package.json +++ b/packages/metadata/package.json @@ -17,32 +17,39 @@ }, "exports": { ".": { + "source": "./src/index.ts", "types": "./build/index.d.ts", "default": "./build/index.js" }, "./models": { + "source": "./src/models/index.ts", "types": "./build/models/index.d.ts", "default": "./build/models/index.js" }, "./components": { + "source": "./src/components/index.ts", "types": "./build/components/index.d.ts", "default": "./build/components/index.js" }, "./schemas": { + "source": "./src/schemas/index.ts", "types": "./build/schemas/index.d.ts", "default": "./build/schemas/index.js" }, "./routes": { + "source": "./src/routes/index.ts", "types": "./build/routes/index.d.ts", "default": "./build/routes/index.js" }, "./utilities": { + "source": "./src/utilities/index.ts", "types": "./build/utilities/index.d.ts", "default": "./build/utilities/index.js" }, "./entryTemplates": { + "source": "./src/entryTemplates/index.ts", "types": "./build/entryTemplates/index.d.ts", "default": "./build/entryTemplates/index.js" } } -} +} \ No newline at end of file diff --git a/packages/worker/package.json b/packages/worker/package.json index ac657459..d1496d5c 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -3,7 +3,7 @@ "type": "module", "private": true, "scripts": { - "dev": "tsx watch --env-file=.env ./src/main.ts", + "dev": "tsx watch --conditions source --env-file=.env ./src/main.ts", "build": "tsc --build", "start": "node --env-file=.env ./build/main.js" }, @@ -32,4 +32,4 @@ "imports": { "#src/*": "./build/*" } -} +} \ No newline at end of file diff --git a/packages/worker/src/jobs/runAgentSession/runAgentSession.ts b/packages/worker/src/jobs/runAgentSession/runAgentSession.ts index 9d12b24a..b4fa08e2 100644 --- a/packages/worker/src/jobs/runAgentSession/runAgentSession.ts +++ b/packages/worker/src/jobs/runAgentSession/runAgentSession.ts @@ -610,7 +610,6 @@ export async function runAgentSession(args: RunAgentSessionJobArgs): Promise Date: Mon, 11 May 2026 20:52:24 +0200 Subject: [PATCH 03/14] fix(worker): stop excessive logging that filled disk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove per-chunk console.log inside the LLM stream loop in runAgentSession — fired on every token, producing thousands of lines per agent session - Remove duplicate getJobCounts() log inside the Bull job processor callback (was logged once per job); keep only the startup log - Add Docker log rotation to the worker service in both compose files (max-size: 50m, max-file: 5 → 250 MB cap) as a safety net --- .workflows/build/compose.start.yml | 5 +++++ .workflows/dev/compose.yml | 5 +++++ packages/worker/src/jobs/runAgentSession/runAgentSession.ts | 1 - packages/worker/src/utilities/queue/processJobs.ts | 5 ++--- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.workflows/build/compose.start.yml b/.workflows/build/compose.start.yml index d735cf11..16f9469f 100644 --- a/.workflows/build/compose.start.yml +++ b/.workflows/build/compose.start.yml @@ -135,6 +135,11 @@ services: worker: container_name: arrhes-prod-worker image: arrhes-worker:${ARRHES_VERSION:-dev} + logging: + driver: json-file + options: + max-size: "50m" + max-file: "5" environment: ENV: development VERBOSE: "true" diff --git a/.workflows/dev/compose.yml b/.workflows/dev/compose.yml index dbc24498..eb7ac3e9 100644 --- a/.workflows/dev/compose.yml +++ b/.workflows/dev/compose.yml @@ -197,6 +197,11 @@ services: worker: container_name: arrhes-worker image: arrhes-dev-worker:latest + logging: + driver: json-file + options: + max-size: "50m" + max-file: "5" build: context: ../.. dockerfile: .workflows/dev/packages/worker/Dockerfile diff --git a/packages/worker/src/jobs/runAgentSession/runAgentSession.ts b/packages/worker/src/jobs/runAgentSession/runAgentSession.ts index b4fa08e2..8165d413 100644 --- a/packages/worker/src/jobs/runAgentSession/runAgentSession.ts +++ b/packages/worker/src/jobs/runAgentSession/runAgentSession.ts @@ -972,7 +972,6 @@ export async function runAgentSession(args: RunAgentSessionJobArgs): Promise Promise | unknow export async function processJobs() { try { - console.log(await ContextClients.queue.getJobCounts()) + console.log("Job counts:", await ContextClients.queue.getJobCounts()) ContextClients.queue.process(10, async (job) => { try { - console.log(await ContextClients.queue.getJobCounts()) - console.log(`process job : (${await job.getState()}) ${job.id}`) + console.log(`[processJobs] Processing job: (${await job.getState()}) ${job.id}`) const validatedJob = validate({ schema: jobSchema, data: job.data, From 06863cc7f08c1cd630396d4f5e6311e3c464d8f5 Mon Sep 17 00:00:00 2001 From: &mile Date: Mon, 11 May 2026 21:44:55 +0200 Subject: [PATCH 04/14] fix(api): sign-out now expires cookies (maxAge: 0) instead of resetting them --- packages/api/src/routes/public/signOut.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api/src/routes/public/signOut.ts b/packages/api/src/routes/public/signOut.ts index 43aeb898..b9e62188 100644 --- a/packages/api/src/routes/public/signOut.ts +++ b/packages/api/src/routes/public/signOut.ts @@ -9,7 +9,7 @@ import { unsignString } from "../../utilities/cookies/unsignString.js" import { Exception } from "../../utilities/exception.js" import { response } from "../../utilities/response.js" import { updateOne } from "../../utilities/sql/updateOne.js" -import { getCookieSecurityOptions, productName, userSessionCookieMaxAge } from "../../utilities/variables.js" +import { getCookieSecurityOptions, productName } from "../../utilities/variables.js" export const signOutRoute = apiFactory.createApp().post(signOutRouteDefinition.path, async (c) => { const _body = await validateBodyMiddleware({ @@ -57,7 +57,7 @@ export const signOutRoute = apiFactory.createApp().post(signOutRouteDefinition.p name: `${productName}_${"id_user_session"}`, value: "", options: { - maxAge: userSessionCookieMaxAge, + maxAge: 0, httpOnly: true, ...cookieSecurity, domain: cookieDomain, @@ -69,9 +69,9 @@ export const signOutRoute = apiFactory.createApp().post(signOutRouteDefinition.p "Set-Cookie", serializeCookie({ name: `${productName}_${"is_auth"}`, - value: String(false), + value: "", options: { - maxAge: userSessionCookieMaxAge, + maxAge: 0, httpOnly: false, ...cookieSecurity, domain: cookieDomain, From 375a99a0f57f3c925c972a289d0e3824608971f4 Mon Sep 17 00:00:00 2001 From: &mile Date: Wed, 13 May 2026 18:55:10 +0200 Subject: [PATCH 05/14] perf: fix year selector cookie, optimize entry page rendering and hash maps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix org cookie not updated when selecting org in header (YearContextSelect was firing readAllYears with stale cookie after DB reset) - Add idOrganization to readAllYears body so query key is org-scoped - Eliminate nested YearDataWrapper in EntryPage by passing pre-resolved data as props from EntryTabContent (removes double useQueries subscription) - Extract EntryRoutePage for standalone router route - Pre-build 12 index Maps (entryById, entryLinesByEntryId, journalById, etc.) inside YearDataWrapper with stable memoized references — Maps only rebuild when their specific data slice changes - Remove 6 redundant useMemo Map builders from EntriesTable (now receive maps from YearDataWrapper as stable props) - Replace O(n) .find()/.filter() in entryTabContent with O(1) Map lookups --- packages/api/package.json | 2 +- .../$idOrganization/years/readAllYears.ts | 8 + .../src/routes/auth/settings/updateUser.ts | 1 + packages/api/src/server.ts | 2 +- .../api/src/utilities/checkDatabaseSchema.ts | 9 +- packages/api/tsconfig.json | 10 +- packages/metadata/package.json | 2 +- packages/metadata/src/models/user.ts | 6 + .../$idOrganization/years/readAllYears.ts | 4 +- .../dashboard/auth/settings/updateUser.ts | 1 + packages/metadata/src/schemas/user.ts | 8 + .../drizzle/0025_add_user_dashboard_mode.sql | 1 + packages/tools/src/seed/seed.ts | 22 +- packages/tools/tsconfig.json | 12 +- packages/ui/src/components/layouts/kbd.tsx | 24 + packages/ui/src/index.ts | 1 + packages/ui/tsconfig.json | 6 +- packages/ui/tsconfig.panda.json | 4 + .../layouts/commandPalette/commandPalette.tsx | 505 +++++++++++++++ .../layouts/commandPalette/searchRoutes.ts | 120 ++++ .../src/components/layouts/subPageContent.tsx | 86 +++ .../src/components/layouts/tabBar/tabBar.tsx | 132 ++++ .../src/components/layouts/tabBar/tabLink.tsx | 53 ++ .../src/components/overlays/drawer/drawer.tsx | 13 - .../components/overlays/drawer/drawerBody.tsx | 20 - .../overlays/drawer/drawerContent.tsx | 136 ---- .../overlays/drawer/drawerHeader.tsx | 46 -- .../components/overlays/drawer/drawerRoot.tsx | 33 - .../overlays/drawer/drawerTrigger.tsx | 31 - .../src/contexts/tabs/tabDefinitions.ts | 289 +++++++++ .../website/src/contexts/tabs/tabsContext.tsx | 88 +++ .../src/contexts/tabs/tabsProvider.tsx | 581 +++++++++++++++++ .../website/src/contexts/tabs/tabsStorage.ts | 110 ++++ .../src/contexts/tabs/useOuterRouter.tsx | 16 + .../$idOrganization/agent/agentPage.tsx | 40 +- .../agent/agentSessionContent.tsx | 89 +-- .../$idOrganization/agent/agentTabContent.tsx | 329 ++++++++++ .../organizationApi/keys/createOneApiKey.tsx | 198 +++--- .../keys/organizationApiKeysPage.tsx | 14 +- .../organizationApiTabContent.tsx | 48 ++ .../invoices/InvoicesTable.tsx | 10 +- .../invoices/organizationInvoicesPage.tsx | 19 +- .../organizationBillingTabContent.tsx | 78 +++ .../organizationServicesPage.tsx | 126 ++-- .../organizationBilling/updateLicencePage.tsx | 178 +++++ .../updateLicenceSubscriptionDrawer.tsx | 170 ----- .../organizationBilling/updateOcrPage.tsx | 302 +++++++++ .../updateOcrSubscriptionDrawer.tsx | 316 --------- .../organizationBilling/updateStoragePage.tsx | 470 ++++++++++++++ .../updateStorageSubscriptionDrawer.tsx | 520 --------------- .../organizationBilling/updateTokensPage.tsx | 319 +++++++++ .../updateTokensSubscriptionDrawer.tsx | 327 ---------- .../wallet/WalletTopUpDrawer.tsx | 94 --- .../wallet/WalletWithdrawalDrawer.tsx | 127 ---- .../wallet/organizationWalletPage.tsx | 267 ++++---- .../wallet/walletTopUpPage.tsx | 89 +++ .../wallet/walletWithdrawalPage.tsx | 161 +++++ .../organizationSecurityPage.tsx | 12 +- .../organizationSettingsPage.tsx | 12 +- .../organizationSettingsTabContent.tsx | 48 ++ .../updateOneOrganization.tsx | 250 ++++---- .../organizationTabContent.tsx | 204 ++++++ .../updateOneOrganizationUser.tsx | 184 +++--- .../createOneOrganizationUser.tsx | 230 ++++--- .../organizationUsersPage.tsx | 14 +- .../$idOrganization/years/createOneYear.tsx | 294 +++++---- .../years/yearListTableRow.tsx | 46 +- .../$idOrganization/years/yearsListTable.tsx | 2 +- .../$idOrganization/years/yearsPage.tsx | 14 +- .../$idEntryLine/updateOneEntryLine.tsx | 597 ++++++++--------- .../entries/$idEntry/createOneEntryLine.tsx | 607 +++++++++--------- .../entries/$idEntry/entryCategoriesTab.tsx | 18 +- .../entries/$idEntry/entryLinesTab.tsx | 18 +- .../entries/$idEntry/entryMetadataTab.tsx | 16 +- .../$idYear/entries/$idEntry/entryPage.tsx | 76 ++- .../entries/$idEntry/entryTabContent.tsx | 245 +++++++ .../entries/$idEntry/updateManyEntryLines.tsx | 539 ++++++++-------- .../entries/$idEntry/updateOneEntry.tsx | 338 +++++----- .../$idYear/entries/createOneEntry.tsx | 525 +++++++-------- .../dashboard/$idYear/entries/entriesPage.tsx | 117 ++-- .../$idYear/entries/entriesTable.tsx | 141 ++-- .../$idYear/entries/exportEntryLines.tsx | 503 +++++++-------- .../$idYear/entries/exportFecFile.tsx | 191 +++--- .../$idYear/entries/importFecFile.tsx | 202 +++--- .../$idYear/files/$idFile/fileMetadataTab.tsx | 11 +- .../$idYear/files/$idFile/filePage.tsx | 11 +- .../$idYear/files/$idFile/fileTabContent.tsx | 105 +++ .../files/$idFile/fileVisualisationTab.tsx | 11 +- .../$idYear/files/$idFile/updateOneFile.tsx | 50 +- .../$idYear/files/createOneFolder.tsx | 166 ++--- .../dashboard/$idYear/files/fileActions.tsx | 57 +- .../$idYear/files/fileContextMenu.tsx | 39 +- .../dashboard/$idYear/files/folderActions.tsx | 38 +- .../$idYear/files/folderContextMenu.tsx | 39 +- .../balanceReport/balanceReportPage.tsx | 12 +- .../balanceSheetReportPage.tsx | 24 +- .../incomeStatementReportPage.tsx | 24 +- .../journalReport/journalReportPage.tsx | 12 +- .../reports/ledgerReport/ledgerReportPage.tsx | 12 +- .../$idYear/reports/reportsTabContent.tsx | 107 +++ .../dashboard/$idYear/yearDataWrapper.tsx | 212 +++++- .../accounts/$idAccount/updateOneAccount.tsx | 530 +++++++-------- .../yearSettings/accounts/accountsPage.tsx | 26 +- .../accounts/createOneAccount.tsx | 514 ++++++++------- .../$idBalanceSheet/updateOneBalanceSheet.tsx | 328 +++++----- .../balanceSheets/balanceSheetRow.tsx | 13 +- .../balanceSheets/balanceSheetsPage.tsx | 34 +- .../balanceSheets/createOneBalanceSheet.tsx | 308 ++++----- .../$idYear/yearSettings/deleteOneYear.tsx | 19 +- .../updateOneIncomeStatement.tsx | 288 +++++---- .../updateOneComputationIncomeStatement.tsx | 266 ++++---- .../createOneComputationIncomeStatement.tsx | 248 +++---- .../$idComputation/updateOneComputation.tsx | 230 ++++--- .../computations/createOneComputation.tsx | 210 +++--- .../createOneIncomeStatement.tsx | 266 ++++---- .../incomeStatements/incomeStatementRow.tsx | 13 +- .../incomeStatements/incomeStatementsPage.tsx | 34 +- .../journals/$idJournal/updateOneJournal.tsx | 230 ++++--- .../journals/createOneJournal.tsx | 210 +++--- .../journals/journalListTableRow.tsx | 13 +- .../yearSettings/journals/journalsPage.tsx | 26 +- .../yearSettings/tags/$idTag/updateOneTag.tsx | 190 +++--- .../yearSettings/tags/createOneTag.tsx | 170 ++--- .../yearSettings/tags/tagListTableRow.tsx | 13 +- .../$idYear/yearSettings/tags/tagsPage.tsx | 26 +- .../$idYear/yearSettings/updateOneYear.tsx | 290 +++++---- .../$idYear/yearSettings/yearSettingsPage.tsx | 21 +- .../yearSettings/yearSettingsTabContent.tsx | 143 +++++ .../dashboard/OrganizationContextSelect.tsx | 102 +++ .../features/dashboard/YearContextSelect.tsx | 116 ++++ .../$idTicket/adminTicketTabContent.tsx | 59 ++ .../admin/tickets/$idTicket/ticketPage.tsx | 14 +- .../dashboard/admin/tickets/ticketsPage.tsx | 121 ++-- .../dashboard/dashboardDefaultPage.tsx | 42 ++ .../features/dashboard/dashboardLayout.tsx | 237 +------ .../src/features/dashboard/dashboardShell.tsx | 391 +++++++++++ .../organizations/addNewOrganization.tsx | 310 ++++----- .../organizationListTableRow.tsx | 44 +- .../features/dashboard/profile/deleteUser.tsx | 162 ++--- .../dashboard/profile/updateUserEmail.tsx | 204 +++--- .../dashboard/profile/updateUserPassword.tsx | 228 ++++--- .../support/$idTicket/ticketPage.tsx | 16 +- .../support/$idTicket/ticketTabContent.tsx | 48 ++ .../dashboard/support/createOneTicket.tsx | 262 ++++---- .../dashboard/support/ticketListTableRow.tsx | 44 +- .../website/src/routes/applicationTree.ts | 4 +- .../root/dashboard/dashboardRootRoute.tsx | 21 +- .../dashboard/dashboardTabHistoryRoute.tsx | 9 + .../root/dashboard/dashboardTabRoute.tsx | 9 + .../routes/root/dashboard/dashboardTree.ts | 262 +------- .../root/dashboard/fullDashboardTree.ts | 13 + .../$idYear/entries/$idEntry/entryRoute.tsx | 2 +- packages/website/tsconfig.json | 5 +- packages/worker/package.json | 2 +- .../jobs/runAgentSession/runAgentSession.ts | 7 +- packages/worker/tsconfig.json | 9 +- 156 files changed, 12331 insertions(+), 8117 deletions(-) create mode 100644 packages/tools/drizzle/0025_add_user_dashboard_mode.sql create mode 100644 packages/ui/src/components/layouts/kbd.tsx create mode 100644 packages/ui/tsconfig.panda.json create mode 100644 packages/website/src/components/layouts/commandPalette/commandPalette.tsx create mode 100644 packages/website/src/components/layouts/commandPalette/searchRoutes.ts create mode 100644 packages/website/src/components/layouts/subPageContent.tsx create mode 100644 packages/website/src/components/layouts/tabBar/tabBar.tsx create mode 100644 packages/website/src/components/layouts/tabBar/tabLink.tsx delete mode 100644 packages/website/src/components/overlays/drawer/drawer.tsx delete mode 100644 packages/website/src/components/overlays/drawer/drawerBody.tsx delete mode 100644 packages/website/src/components/overlays/drawer/drawerContent.tsx delete mode 100644 packages/website/src/components/overlays/drawer/drawerHeader.tsx delete mode 100644 packages/website/src/components/overlays/drawer/drawerRoot.tsx delete mode 100644 packages/website/src/components/overlays/drawer/drawerTrigger.tsx create mode 100644 packages/website/src/contexts/tabs/tabDefinitions.ts create mode 100644 packages/website/src/contexts/tabs/tabsContext.tsx create mode 100644 packages/website/src/contexts/tabs/tabsProvider.tsx create mode 100644 packages/website/src/contexts/tabs/tabsStorage.ts create mode 100644 packages/website/src/contexts/tabs/useOuterRouter.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx delete mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicenceSubscriptionDrawer.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx delete mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrSubscriptionDrawer.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx delete mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStorageSubscriptionDrawer.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx delete mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensSubscriptionDrawer.tsx delete mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpDrawer.tsx delete mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalDrawer.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletTopUpPage.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idYear/files/$idFile/fileTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idYear/reports/reportsTabContent.tsx create mode 100644 packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx create mode 100644 packages/website/src/features/dashboard/OrganizationContextSelect.tsx create mode 100644 packages/website/src/features/dashboard/YearContextSelect.tsx create mode 100644 packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx create mode 100644 packages/website/src/features/dashboard/dashboardDefaultPage.tsx create mode 100644 packages/website/src/features/dashboard/dashboardShell.tsx create mode 100644 packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx create mode 100644 packages/website/src/routes/root/dashboard/dashboardTabHistoryRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/dashboardTabRoute.tsx create mode 100644 packages/website/src/routes/root/dashboard/fullDashboardTree.ts diff --git a/packages/api/package.json b/packages/api/package.json index dcb95122..08193c59 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -36,4 +36,4 @@ "postgres": "3.4.9", "valibot": "1.4.0" } -} \ No newline at end of file +} diff --git a/packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts b/packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts index 9076dae2..85aa48aa 100644 --- a/packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts +++ b/packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts @@ -3,6 +3,7 @@ import { and, eq } from "drizzle-orm" import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" +import { Exception } from "../../../../utilities/exception.js" import { response } from "../../../../utilities/response.js" import { selectMany } from "../../../../utilities/sql/selectMany.js" @@ -10,6 +11,13 @@ export const readAllYearsRoute = apiFactory.createApp().post(readAllYearsRouteDe const { idOrganization } = await checkUserSessionMiddleware({ context: c, }) + if (!idOrganization) { + throw new Exception({ + statusCode: 400, + internalMessage: "idOrganization is required for readAllYears", + externalMessage: "Organization identifier is required", + }) + } const _body = await validateBodyMiddleware({ context: c, schema: readAllYearsRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/settings/updateUser.ts b/packages/api/src/routes/auth/settings/updateUser.ts index 415add53..62d44369 100644 --- a/packages/api/src/routes/auth/settings/updateUser.ts +++ b/packages/api/src/routes/auth/settings/updateUser.ts @@ -20,6 +20,7 @@ export const updateUserRoute = apiFactory.createApp().post(updateUserRouteDefini table: models.user, data: { alias: body.alias, + dashboardMode: body.dashboardMode, lastUpdatedAt: new Date().toISOString(), }, where: (table) => eq(table.id, user.id), diff --git a/packages/api/src/server.ts b/packages/api/src/server.ts index 5776cc37..97febe55 100644 --- a/packages/api/src/server.ts +++ b/packages/api/src/server.ts @@ -99,7 +99,7 @@ async function startServer() { }) // Wait indefinitely (prevents loop from restarting immediately) - await new Promise(() => { }) + await new Promise(() => {}) } catch (error: unknown) { if (error instanceof Error) { console.error( diff --git a/packages/api/src/utilities/checkDatabaseSchema.ts b/packages/api/src/utilities/checkDatabaseSchema.ts index 5071b7ab..5ef07276 100644 --- a/packages/api/src/utilities/checkDatabaseSchema.ts +++ b/packages/api/src/utilities/checkDatabaseSchema.ts @@ -17,7 +17,10 @@ export async function checkDatabaseSchema(db: DbClient) { } // Query all columns present in the public schema - const rows = await db.execute<{ table_name: string; column_name: string }>( + const rows = await db.execute<{ + table_name: string + column_name: string + }>( sql`SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = 'public'`, @@ -62,9 +65,7 @@ export async function checkDatabaseSchema(db: DbClient) { } if (drift.length > 0) { - throw new Error( - `Database schema is out of date — run migrations before starting the API:\n${drift.join("\n")}`, - ) + throw new Error(`Database schema is out of date — run migrations before starting the API:\n${drift.join("\n")}`) } console.info(`Database schema check passed (${expected.size} tables verified)`) diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index db11ed04..ecff0485 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -20,9 +20,15 @@ "outDir": "./build", "paths": { "#/*": ["./src/*"] - } + }, + "incremental": true, + "tsBuildInfoFile": "./.tsbuildinfo" }, "exclude": ["./node_modules", "./build"], "include": ["./src"], - "references": [{ "path": "../metadata" }] + "references": [ + { + "path": "../metadata" + } + ] } diff --git a/packages/metadata/package.json b/packages/metadata/package.json index addea8d2..5666b809 100644 --- a/packages/metadata/package.json +++ b/packages/metadata/package.json @@ -52,4 +52,4 @@ "default": "./build/entryTemplates/index.js" } } -} \ No newline at end of file +} diff --git a/packages/metadata/src/models/user.ts b/packages/metadata/src/models/user.ts index 38303394..22d692a8 100644 --- a/packages/metadata/src/models/user.ts +++ b/packages/metadata/src/models/user.ts @@ -23,6 +23,12 @@ export const userModel = pgTable( passwordSalt: text("password_salt").notNull(), createdAt: dateTimeColumn("created_at").notNull(), lastUpdatedAt: dateTimeColumn("last_updated_at"), + dashboardMode: varchar("dashboard_mode", { + length: 16, + }) + .notNull() + .default("tabs") + .$type<"tabs" | "classic">(), }, (t) => [ index().on(t.emailToken), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts index 9c67f46c..97210379 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts @@ -7,7 +7,9 @@ export const readAllYearsRouteDefinition = routeDefinition({ protocol: "http", path: `${routePath.auth}/read-all-years`, schemas: { - body: v.object({}), + body: v.object({ + idOrganization: v.optional(v.string()), + }), return: v.array(yearSchemaReturn), }, }) diff --git a/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts b/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts index 608dd634..e6eb4a9f 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts @@ -9,6 +9,7 @@ export const updateUserRouteDefinition = routeDefinition({ schemas: { body: v.object({ alias: v.optional(userSchema.entries.alias), + dashboardMode: v.optional(userSchema.entries.dashboardMode), }), return: userSchemaReturn, }, diff --git a/packages/metadata/src/schemas/user.ts b/packages/metadata/src/schemas/user.ts index 8d5b5a5b..c8c11022 100644 --- a/packages/metadata/src/schemas/user.ts +++ b/packages/metadata/src/schemas/user.ts @@ -22,6 +22,13 @@ export const userSchema = v.object({ passwordSalt: v.nonNullable(stringSchema, "Ce champ est requis"), createdAt: v.nonNullable(dateTimeSchema, "Ce champ est requis"), lastUpdatedAt: v.nullable(dateTimeSchema), + dashboardMode: v.nonNullable( + v.picklist([ + "tabs", + "classic", + ]), + "Ce champ est requis", + ), }) satisfies v.GenericSchema export const userSchemaReturn = v.pick(userSchema, [ @@ -38,4 +45,5 @@ export const userSchemaReturn = v.pick(userSchema, [ "passwordSalt", "createdAt", "lastUpdatedAt", + "dashboardMode", ]) diff --git a/packages/tools/drizzle/0025_add_user_dashboard_mode.sql b/packages/tools/drizzle/0025_add_user_dashboard_mode.sql new file mode 100644 index 00000000..ba7cc659 --- /dev/null +++ b/packages/tools/drizzle/0025_add_user_dashboard_mode.sql @@ -0,0 +1 @@ +ALTER TABLE "table_user" ADD COLUMN "dashboard_mode" varchar(16) DEFAULT 'tabs' NOT NULL; diff --git a/packages/tools/src/seed/seed.ts b/packages/tools/src/seed/seed.ts index 276b315f..98cac5a0 100644 --- a/packages/tools/src/seed/seed.ts +++ b/packages/tools/src/seed/seed.ts @@ -63,13 +63,21 @@ async function triggerSeededMonthlyBilling() { return } - const response = await fetch(`${apiBaseUrl}${SEED_INTERNAL_API_PATH}`, { - method: "POST", - headers: { - "Content-Type": "application/json", - "x-internal-api-key": internalApiKey, - }, - }) + let response: Response + try { + response = await fetch(`${apiBaseUrl}${SEED_INTERNAL_API_PATH}`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-internal-api-key": internalApiKey, + }, + }) + } catch (err) { + console.warn( + `Skipping seeded monthly billing generation: API unreachable at ${apiBaseUrl} (${(err as Error).message}).`, + ) + return + } if (!response.ok) { const body = await response.text() diff --git a/packages/tools/tsconfig.json b/packages/tools/tsconfig.json index 18c124d4..a664e050 100644 --- a/packages/tools/tsconfig.json +++ b/packages/tools/tsconfig.json @@ -16,10 +16,16 @@ "declarationMap": true, "sourceMap": true, "verbatimModuleSyntax": false, - "rootDir": ".", - "outDir": "./build" + "rootDir": "./src", + "outDir": "./build", + "incremental": true, + "tsBuildInfoFile": "./.tsbuildinfo" }, "exclude": ["./node_modules", "./build"], "include": ["./src"], - "references": [{ "path": "../metadata" }] + "references": [ + { + "path": "../metadata" + } + ] } diff --git a/packages/ui/src/components/layouts/kbd.tsx b/packages/ui/src/components/layouts/kbd.tsx new file mode 100644 index 00000000..b70eeecc --- /dev/null +++ b/packages/ui/src/components/layouts/kbd.tsx @@ -0,0 +1,24 @@ +import type { ComponentProps } from "react" +import { css } from "../../utilities/cn.ts" + +export function Kbd(props: { children: ComponentProps<"kbd">["children"] }) { + return ( + + {props.children} + + ) +} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index efbb41dd..34c1948c 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -44,6 +44,7 @@ export { InputToggle } from "./components/inputs/inputToggle.js" export { Badge } from "./components/layouts/badge.js" export { Chip, type ChipColors } from "./components/layouts/chip.js" export { CircularLoader } from "./components/layouts/circularLoader.js" +export { Kbd } from "./components/layouts/kbd.js" export { Logo } from "./components/layouts/logo.js" export { PageNavigation } from "./components/layouts/pageNavigation.js" export { Separator } from "./components/layouts/separator.js" diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json index 3f14dfda..82783931 100644 --- a/packages/ui/tsconfig.json +++ b/packages/ui/tsconfig.json @@ -27,7 +27,9 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, "ignoreDeprecations": "6.0", - "baseUrl": "." + "baseUrl": ".", + "incremental": true, + "tsBuildInfoFile": "./.tsbuildinfo" }, - "include": ["panda.config.ts", "src", "styled-system"] + "include": ["panda.config.ts", "src"] } diff --git a/packages/ui/tsconfig.panda.json b/packages/ui/tsconfig.panda.json new file mode 100644 index 00000000..a9a85538 --- /dev/null +++ b/packages/ui/tsconfig.panda.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["panda.config.ts", "src", "styled-system"] +} diff --git a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx new file mode 100644 index 00000000..fdcc1510 --- /dev/null +++ b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx @@ -0,0 +1,505 @@ +import { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata/routes" +import { InputCombobox } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconBuilding, IconCalendar, IconLayoutGrid, IconSearch, IconUser } from "@tabler/icons-react" +import { useEffect, useMemo, useRef, useState } from "react" +import { createPortal } from "react-dom" +import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" +import { useTabs } from "../../../contexts/tabs/tabsContext.js" +import { levenshtein } from "../../../utilities/levenshtein.js" +import { useDataFromAPI } from "../../../utilities/useHTTPData.js" +import { + type OrgSearchRoute, + orgSearchRoutes, + type SearchRoute, + userSearchRoutes, + type YearSearchRoute, + yearSearchRoutes, +} from "./searchRoutes.js" + +// ─── Fuzzy filter ───────────────────────────────────────────────────────────── + +function scoreMatch(query: string, target: string): number { + const q = query.toLowerCase() + const t = target.toLowerCase() + if (t.includes(q)) return 0 + return levenshtein(q, t.slice(0, Math.max(t.length, q.length))) +} + +function filterRoutes< + T extends { + label: string + description?: string + }, +>(query: string, routes: T[]): T[] { + if (!query) return routes + return routes + .map((r) => ({ + ...r, + _score: Math.min(scoreMatch(query, r.label), r.description ? scoreMatch(query, r.description) : 99), + })) + .filter((r) => r._score <= 3) + .sort((a, b) => a._score - b._score) +} + +// ─── Component ──────────────────────────────────────────────────────────────── + +export function CommandPalette(props: { selectedOrgId: string | null; selectedYearId: string | null }) { + const { selectedOrgId, selectedYearId } = props + const [open, setOpen] = useState(false) + const [query, setQuery] = useState("") + const [selected, setSelected] = useState(0) + const { openTab } = useTabs() + const inputRef = useRef(null) + + const orgsData = useDataFromAPI({ + routeDefinition: getAllMyOrganizationsRouteDefinition, + body: {}, + }) + + // Reset on open + useEffect(() => { + if (open) { + setQuery("") + setSelected(0) + setTimeout(() => inputRef.current?.focus(), 50) + } + }, [ + open, + ]) + + // Open via custom DOM event + useEffect(() => { + function handleOpen() { + setOpen(true) + } + window.addEventListener("arrhes:open-palette", handleOpen) + return () => window.removeEventListener("arrhes:open-palette", handleOpen) + }, []) + + // Close when a tab is opened + useEffect(() => { + function handleTabOpened() { + setOpen(false) + } + window.addEventListener("arrhes:tab-opened", handleTabOpened) + return () => window.removeEventListener("arrhes:tab-opened", handleTabOpened) + }, []) + + // Ctrl/Cmd+K shortcut + useEffect(() => { + function handleKey(e: KeyboardEvent) { + if ((e.ctrlKey || e.metaKey) && e.key === "k") { + e.preventDefault() + setOpen(true) + } + } + document.addEventListener("keydown", handleKey) + return () => document.removeEventListener("keydown", handleKey) + }, []) + + // ─── Result computation ──────────────────────────────────────────────────── + + const allOrgs = orgsData.data ?? [] + + // User section: static pages + matching orgs (when no org selected) + const filteredUserPages = filterRoutes(query, userSearchRoutes) + + const filteredOrgItems: SearchRoute[] = useMemo(() => { + if (!selectedOrgId) { + // Show orgs as navigable items — open their exercices tab. + return filterRoutes( + query, + allOrgs.map((ou) => ({ + label: ou.organization.name, + description: "Organisation", + tabComponent: "exercices", + tabProps: { + idOrganization: ou.organization.id, + }, + })), + ) + } + // Show org-level sub-routes. + return filterRoutes( + query, + orgSearchRoutes.map( + (r: OrgSearchRoute): SearchRoute => ({ + label: r.label, + description: r.description, + tabComponent: r.tabComponent, + tabProps: { + idOrganization: selectedOrgId, + }, + }), + ), + ) + }, [ + query, + allOrgs, + selectedOrgId, + ]) + + const filteredYearItems: SearchRoute[] = useMemo(() => { + if (!selectedOrgId || !selectedYearId) return [] + return filterRoutes( + query, + yearSearchRoutes.map( + (r: YearSearchRoute): SearchRoute => ({ + label: r.label, + description: r.description, + tabComponent: r.tabComponent, + tabProps: { + idOrganization: selectedOrgId, + idYear: selectedYearId, + }, + }), + ), + ) + }, [ + query, + selectedOrgId, + selectedYearId, + ]) + + const allItems: SearchRoute[] = [ + ...filteredUserPages, + ...filteredOrgItems, + ...filteredYearItems, + ] + + function activate(item: SearchRoute) { + setOpen(false) + openTab({ + component: item.tabComponent, + props: item.tabProps, + } as OpenTabArgs) + } + + function handleKeyDown(e: React.KeyboardEvent) { + if (e.key === "ArrowDown") { + e.preventDefault() + setSelected((s) => Math.min(s + 1, allItems.length - 1)) + } else if (e.key === "ArrowUp") { + e.preventDefault() + setSelected((s) => Math.max(s - 1, 0)) + } else if (e.key === "Enter") { + e.preventDefault() + const item = allItems[selected] + if (item) activate(item) + } else if (e.key === "Escape") { + setOpen(false) + } + } + + // Keep selected index in bounds when filtered list changes + useEffect(() => { + setSelected(0) + }, [ + query, + selectedOrgId, + selectedYearId, + ]) + + if (!open) return null + + // Offset counters for multi-section active tracking + const userOffset = 0 + const orgOffset = filteredUserPages.length + const yearOffset = orgOffset + filteredOrgItems.length + + return createPortal( +
{ + if (e.target === e.currentTarget) setOpen(false) + }} + > +
+ {/* Search input */} +
+ + setQuery(e.target.value)} + placeholder="Rechercher des pages, organisations…" + className={css({ + flex: 1, + fontSize: "0.9375rem", + border: "none", + outline: "none", + background: "transparent", + color: "neutral/900", + _placeholder: { + color: "neutral/400", + }, + })} + /> +
+ + {/* Results */} +
+ {allItems.length === 0 && ( +

+ {query ? `Aucun résultat pour « ${query} »` : "Aucun résultat"} +

+ )} + + {filteredUserPages.length > 0 && ( +
} + > + {filteredUserPages.map((page, i) => ( + } + label={page.label} + description={page.description} + active={selected === userOffset + i} + onMouseEnter={() => setSelected(userOffset + i)} + onClick={() => activate(page)} + /> + ))} +
+ )} + + {filteredOrgItems.length > 0 && ( +
} + > + {filteredOrgItems.map((item, i) => ( + } + label={item.label} + description={item.description} + active={selected === orgOffset + i} + onMouseEnter={() => setSelected(orgOffset + i)} + onClick={() => activate(item)} + /> + ))} +
+ )} + + {filteredYearItems.length > 0 && ( +
} + > + {filteredYearItems.map((item, i) => ( + } + label={item.label} + description={item.description} + active={selected === yearOffset + i} + onMouseEnter={() => setSelected(yearOffset + i)} + onClick={() => activate(item)} + /> + ))} +
+ )} +
+
+
, + document.body, + ) +} + +// ─── ContextSelect ──────────────────────────────────────────────────────────── + +export function ContextSelect(props: { + placeholder: string + value: string | null + onChange: (v: string | null) => void + options: { + key: string + label: string + }[] + isLoading?: boolean +}) { + return ( + props.onChange(v ?? null)} + options={props.options} + isLoading={props.isLoading} + allowEmpty={true} + /> + ) +} + +// ─── Sub-components ─────────────────────────────────────────────────────────── + +function Section({ label, icon, children }: { label: string; icon?: React.ReactNode; children: React.ReactNode }) { + return ( +
+
+ {icon && ( + + {icon} + + )} +

+ {label} +

+
+ {children} +
+ ) +} + +function ResultRow(props: { + icon: React.ReactNode + label: string + description?: string + active: boolean + onMouseEnter: () => void + onClick: () => void +}) { + return ( + + ) +} diff --git a/packages/website/src/components/layouts/commandPalette/searchRoutes.ts b/packages/website/src/components/layouts/commandPalette/searchRoutes.ts new file mode 100644 index 00000000..74bafe38 --- /dev/null +++ b/packages/website/src/components/layouts/commandPalette/searchRoutes.ts @@ -0,0 +1,120 @@ +export type SearchRoute = { + label: string + description?: string + /** Registry key for openTab. */ + tabComponent: string + /** Props to pass alongside the component key. */ + tabProps: Record +} + +// ─── User-level routes (always visible) ────────────────────────────────────── + +export const userSearchRoutes: SearchRoute[] = [ + { + label: "Organisations", + description: "Liste de vos organisations", + tabComponent: "organisations", + tabProps: {}, + }, + { + label: "Agent IA", + description: "Assistant comptable intelligent", + tabComponent: "agent", + tabProps: {}, + }, + { + label: "Profil", + description: "Votre profil utilisateur", + tabComponent: "profil", + tabProps: {}, + }, + { + label: "Support", + description: "Centre d'aide et tickets", + tabComponent: "support", + tabProps: {}, + }, + { + label: "Paramètres", + description: "Paramètres de l'application", + tabComponent: "paramètres", + tabProps: {}, + }, +] + +// ─── Organisation-level routes (require idOrganization) ────────────────────── + +export type OrgSearchRoute = { + label: string + description?: string + /** Registry key — props will be augmented with `{ idOrganization }` at call time. */ + tabComponent: string +} + +export const orgSearchRoutes: OrgSearchRoute[] = [ + { + label: "Exercices", + description: "Années fiscales", + tabComponent: "exercices", + }, + { + label: "Membres", + description: "Utilisateurs de l'organisation", + tabComponent: "membres", + }, + { + label: "Stockage", + description: "Fichiers et documents de l'organisation", + tabComponent: "organisation-stockage", + }, + { + label: "Facturation", + description: "Abonnements et factures", + tabComponent: "organisation-facturation", + }, + { + label: "Paramètres de l'organisation", + description: "Configuration générale", + tabComponent: "organisation-paramètres", + }, + { + label: "Clés API", + description: "Accès API de l'organisation", + tabComponent: "organisation-api", + }, +] + +// ─── Year-level routes (require idOrganization + idYear) ───────────────────── + +export type YearSearchRoute = { + label: string + description?: string + /** Registry key — props will be augmented with `{ idOrganization, idYear }` at call time. */ + tabComponent: string +} + +export const yearSearchRoutes: YearSearchRoute[] = [ + { + label: "Écritures", + description: "Journal comptable de l'exercice", + tabComponent: "exercice-écritures", + }, + { + label: "Documents", + description: "Rapports, bilans et compte de résultat", + tabComponent: "exercice-documents", + }, + { + label: "Stockage de l'exercice", + description: "Fichiers attachés à l'exercice", + tabComponent: "exercice-stockage", + }, + { + label: "Paramètres de l'exercice", + description: "Journaux, catégories, plan comptable", + tabComponent: "exercice-paramètres", + }, +] + +/** @deprecated use userSearchRoutes */ +export const staticSearchRoutes = userSearchRoutes diff --git a/packages/website/src/components/layouts/subPageContent.tsx b/packages/website/src/components/layouts/subPageContent.tsx new file mode 100644 index 00000000..7fb03fce --- /dev/null +++ b/packages/website/src/components/layouts/subPageContent.tsx @@ -0,0 +1,86 @@ +import { Button, ButtonGhostContent } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import type { Icon, IconProps } from "@tabler/icons-react" +import { type ReactElement, type ReactNode, useState } from "react" + +type SectionItem = { + key: string + label: string + icon?: ReactElement> + content: ReactNode +} + +type Section = { + title?: string + icon?: ReactElement> + items: SectionItem[] +} + +type Props = { + sections: Record + defaultKey?: string +} + +/** State-based tab navigation — no TanStack Router required. */ +export function SubPageContent({ sections, defaultKey }: Props) { + const firstKey = defaultKey ?? Object.values(sections).flatMap((s) => s.items)[0]?.key ?? "" + const [activeKey, setActiveKey] = useState(firstKey) + + const allItems = Object.values(sections).flatMap((s) => s.items) + const activeContent = allItems.find((i) => i.key === activeKey)?.content ?? null + + return ( +
+ {/* Tab bar */} +
+ {allItems.map((item) => ( + + ))} +
+ + {/* Active tab content */} +
+ {activeContent} +
+
+ ) +} diff --git a/packages/website/src/components/layouts/tabBar/tabBar.tsx b/packages/website/src/components/layouts/tabBar/tabBar.tsx new file mode 100644 index 00000000..f4738cfc --- /dev/null +++ b/packages/website/src/components/layouts/tabBar/tabBar.tsx @@ -0,0 +1,132 @@ +import { Button, ButtonGhostContent } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconChevronLeft, IconChevronRight, IconPlus, IconX } from "@tabler/icons-react" +import { type ComponentTab, currentEntry, useTabs } from "../../../contexts/tabs/tabsContext.js" + +export function TabBar() { + const { tabs, activeTabId, activateTab, closeTab, navigateBack, navigateForward } = useTabs() + + return ( +
+ {tabs.map((tab) => { + const isActive = tab.id === activeTabId + const title = tab.type === "component" ? currentEntry(tab as ComponentTab).title : tab.title + const canGoBack = tab.type === "component" && (tab as ComponentTab).historyIndex > 0 + const canGoForward = + tab.type === "component" && + (tab as ComponentTab).historyIndex < (tab as ComponentTab).history.length - 1 + return ( +
activateTab(tab.id)} + > + {tab.type === "component" && ( + <> + + + + )} + + {title} + + +
+ ) + })} + + {/* New tab button */} +
+ +
+
+ ) +} diff --git a/packages/website/src/components/layouts/tabBar/tabLink.tsx b/packages/website/src/components/layouts/tabBar/tabLink.tsx new file mode 100644 index 00000000..ad28f031 --- /dev/null +++ b/packages/website/src/components/layouts/tabBar/tabLink.tsx @@ -0,0 +1,53 @@ +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconExternalLink } from "@tabler/icons-react" +import type { ReactNode } from "react" +import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" +import { useTabs } from "../../../contexts/tabs/tabsContext.js" +import { ContextMenu } from "../../overlays/contextMenu/contextMenu.js" + +type TabLinkProps = { + args: OpenTabArgs + children: ReactNode +} + +/** + * Wraps any clickable element with tab-navigation behaviour: + * - Left-click → navigate (replace current tab, or new tab if Ctrl/Meta held) + * - Right-click → context menu with "Ouvrir" / "Ouvrir dans un nouvel onglet" + * + * The child element should NOT have its own openTab onClick; TabLink provides it. + */ +export function TabLink({ args, children }: TabLinkProps) { + const { openTab } = useTabs() + + return ( + + openTab(args)} + > + {children} + + + } + onClick={() => openTab(args)} + > + Ouvrir + + } + onClick={() => + openTab(args, { + newTab: true, + }) + } + > + Ouvrir dans un nouvel onglet + + + + ) +} diff --git a/packages/website/src/components/overlays/drawer/drawer.tsx b/packages/website/src/components/overlays/drawer/drawer.tsx deleted file mode 100644 index 34b9d18a..00000000 --- a/packages/website/src/components/overlays/drawer/drawer.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { DrawerBody } from "./drawerBody.js" -import { DrawerContent } from "./drawerContent.js" -import { DrawerHeader } from "./drawerHeader.js" -import { DrawerRoot } from "./drawerRoot.js" -import { DrawerTrigger } from "./drawerTrigger.js" - -export const Drawer = { - Root: DrawerRoot, - Trigger: DrawerTrigger, - Content: DrawerContent, - Header: DrawerHeader, - Body: DrawerBody, -} diff --git a/packages/website/src/components/overlays/drawer/drawerBody.tsx b/packages/website/src/components/overlays/drawer/drawerBody.tsx deleted file mode 100644 index 80ff64f3..00000000 --- a/packages/website/src/components/overlays/drawer/drawerBody.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { css } from "@arrhes/ui/utilities/cn.js" -import type { JSX } from "react" - -export function DrawerBody(props: { children: JSX.Element }) { - return ( -
- {props.children} -
- ) -} diff --git a/packages/website/src/components/overlays/drawer/drawerContent.tsx b/packages/website/src/components/overlays/drawer/drawerContent.tsx deleted file mode 100644 index 7d476441..00000000 --- a/packages/website/src/components/overlays/drawer/drawerContent.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import { type JSX, useCallback, useEffect, useRef, useState } from "react" -import { createPortal } from "react-dom" -import { useDrawerContext } from "./drawerRoot.js" - -export function DrawerContent(props: { children: JSX.Element | JSX.Element[]; className?: string }) { - const { open, setOpen } = useDrawerContext() - const [mounted, setMounted] = useState(false) - const [visible, setVisible] = useState(false) - const contentRef = useRef(null) - - // Mount when open becomes true, then trigger visible for animations - useEffect(() => { - if (open) { - setMounted(true) - // Trigger animation on next frame after mount - requestAnimationFrame(() => { - requestAnimationFrame(() => { - setVisible(true) - }) - }) - } else { - setVisible(false) - const timer = setTimeout(() => { - setMounted(false) - }, 200) - return () => clearTimeout(timer) - } - }, [ - open, - ]) - - // Handle Escape key - const handleKeyDown = useCallback( - (e: KeyboardEvent) => { - if (e.key === "Escape") { - setOpen(false) - } - }, - [ - setOpen, - ], - ) - - useEffect(() => { - if (mounted) { - document.addEventListener("keydown", handleKeyDown) - // Prevent body scroll when drawer is open - const originalOverflow = document.body.style.overflow - document.body.style.overflow = "hidden" - return () => { - document.removeEventListener("keydown", handleKeyDown) - document.body.style.overflow = originalOverflow - } - } - }, [ - mounted, - handleKeyDown, - ]) - - if (!mounted) return null - - return createPortal( - <> - {/* Overlay */} -
setOpen(false)} - aria-hidden="true" - /> - {/* Content */} -
- {props.children} -
- , - document.body, - ) -} diff --git a/packages/website/src/components/overlays/drawer/drawerHeader.tsx b/packages/website/src/components/overlays/drawer/drawerHeader.tsx deleted file mode 100644 index 196dd060..00000000 --- a/packages/website/src/components/overlays/drawer/drawerHeader.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { Button, ButtonGhostContent } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconX } from "@tabler/icons-react" -import { useDrawerContext } from "./drawerRoot.js" - -export function DrawerHeader(props: { title: string | undefined }) { - const { setOpen } = useDrawerContext() - - return ( -
- - {props.title === undefined ? null : ( - - {props.title} - - )} - - -
- ) -} diff --git a/packages/website/src/components/overlays/drawer/drawerRoot.tsx b/packages/website/src/components/overlays/drawer/drawerRoot.tsx deleted file mode 100644 index 041867ed..00000000 --- a/packages/website/src/components/overlays/drawer/drawerRoot.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { createContext, type JSX, useContext } from "react" - -type DrawerContextType = { - open: boolean - setOpen: (open: boolean) => void -} - -const DrawerContext = createContext(null) - -export function useDrawerContext() { - const context = useContext(DrawerContext) - if (context === null) { - throw new Error("useDrawerContext must be used within a DrawerRoot") - } - return context -} - -export function DrawerRoot(props: { - open: boolean - onOpenChange: (open: boolean) => void - children: JSX.Element | JSX.Element[] -}) { - return ( - - {props.children} - - ) -} diff --git a/packages/website/src/components/overlays/drawer/drawerTrigger.tsx b/packages/website/src/components/overlays/drawer/drawerTrigger.tsx deleted file mode 100644 index 1dd70762..00000000 --- a/packages/website/src/components/overlays/drawer/drawerTrigger.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Button } from "@arrhes/ui" -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import type { JSX } from "react" -import { useDrawerContext } from "./drawerRoot.js" - -export function DrawerTrigger(props: { children: JSX.Element; className?: string }) { - const { setOpen } = useDrawerContext() - - return ( - - ) -} diff --git a/packages/website/src/contexts/tabs/tabDefinitions.ts b/packages/website/src/contexts/tabs/tabDefinitions.ts new file mode 100644 index 00000000..f905331c --- /dev/null +++ b/packages/website/src/contexts/tabs/tabDefinitions.ts @@ -0,0 +1,289 @@ +import { createElement } from "react" +import { AgentTabContent } from "../../features/dashboard/$idOrganization/agent/agentTabContent.js" +import { OrganizationApiTabContent } from "../../features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.js" +import { OrganizationBillingTabContent } from "../../features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.js" +import { UpdateLicencePage } from "../../features/dashboard/$idOrganization/organizationBilling/updateLicencePage.js" +import { UpdateOcrPage } from "../../features/dashboard/$idOrganization/organizationBilling/updateOcrPage.js" +import { UpdateStoragePage } from "../../features/dashboard/$idOrganization/organizationBilling/updateStoragePage.js" +import { UpdateTokensPage } from "../../features/dashboard/$idOrganization/organizationBilling/updateTokensPage.js" +import { WalletTopUpPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/walletTopUpPage.js" +import { WalletWithdrawalPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.js" +import { OrganizationSettingsTabContent } from "../../features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.js" +import { OrganizationTabContent } from "../../features/dashboard/$idOrganization/organizationTabContent.js" +import { OrganizationUsersPage } from "../../features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.js" +import { YearsPage } from "../../features/dashboard/$idOrganization/years/yearsPage.js" +import { EntryTabContent } from "../../features/dashboard/$idYear/entries/$idEntry/entryTabContent.js" +import { EntriesPage } from "../../features/dashboard/$idYear/entries/entriesPage.js" +import { FileTabContent } from "../../features/dashboard/$idYear/files/$idFile/fileTabContent.js" +import { FilesPage } from "../../features/dashboard/$idYear/files/filesPage.js" +import { ReportsTabContent } from "../../features/dashboard/$idYear/reports/reportsTabContent.js" +import { YearSettingsTabContent } from "../../features/dashboard/$idYear/yearSettings/yearSettingsTabContent.js" +import { AdminTicketTabContent } from "../../features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.js" +import { TicketsPage } from "../../features/dashboard/admin/tickets/ticketsPage.js" +import { OrganizationsPage } from "../../features/dashboard/organizations/organizationsPage.js" +import { UserProfilePage } from "../../features/dashboard/profile/userProfilePage.js" +import { SettingsPage } from "../../features/dashboard/settings/settingsPage.js" +import { TicketTabContent } from "../../features/dashboard/support/$idTicket/ticketTabContent.js" +import { SupportPage } from "../../features/dashboard/support/supportPage.js" + +// ─── Types ─────────────────────────────────────────────────────────────────── + +export type TabDefinition = { + id: string + title: string + description?: string + component: React.ReactNode +} + +// ─── Registry ──────────────────────────────────────────────────────────────── + +export const TAB_REGISTRY = { + // ─── No-prop tabs ────────────────────────────────────────────────────── + organisations: (_props: Record): TabDefinition => ({ + id: "organisations", + title: "Organisations", + description: "Liste de vos organisations", + component: createElement(OrganizationsPage), + }), + + profil: (_props: Record): TabDefinition => ({ + id: "profil", + title: "Profil", + description: "Votre profil utilisateur", + component: createElement(UserProfilePage), + }), + + support: (_props: Record): TabDefinition => ({ + id: "support", + title: "Support", + description: "Centre d'aide et tickets", + component: createElement(SupportPage), + }), + + "admin-tickets": (_props: Record): TabDefinition => ({ + id: "admin-tickets", + title: "Administration", + description: "Tickets d'administration", + component: createElement(TicketsPage), + }), + + paramètres: (_props: Record): TabDefinition => ({ + id: "paramètres", + title: "Paramètres", + description: "Paramètres de l'application", + component: createElement(SettingsPage), + }), + + // ─── Org-level tabs ──────────────────────────────────────────────────── + + organisation: (props: { idOrganization: string }): TabDefinition => ({ + id: `organisation-${props.idOrganization}`, + title: "Organisation", + description: "Vue d'ensemble de l'organisation", + component: createElement(OrganizationTabContent, { + idOrganization: props.idOrganization, + }), + }), + + exercices: (props: { idOrganization: string }): TabDefinition => ({ + id: `exercices-${props.idOrganization}`, + title: "Exercices", + description: "Années fiscales", + component: createElement(YearsPage, { + idOrganization: props.idOrganization, + }), + }), + + agent: (props: { idOrganization: string }): TabDefinition => ({ + id: `agent-${props.idOrganization}`, + title: "Agent IA", + description: "Assistant comptable intelligent", + component: createElement(AgentTabContent, { + idOrganization: props.idOrganization, + }), + }), + + membres: (props: { idOrganization: string }): TabDefinition => ({ + id: `membres-${props.idOrganization}`, + title: "Membres", + description: "Utilisateurs de l'organisation", + component: createElement(OrganizationUsersPage, { + idOrganization: props.idOrganization, + }), + }), + + "organisation-stockage": (props: { idOrganization: string }): TabDefinition => ({ + id: `organisation-stockage-${props.idOrganization}`, + title: "Stockage", + description: "Fichiers et documents de l'organisation", + component: createElement(FilesPage), + }), + + "organisation-facturation": (props: { idOrganization: string }): TabDefinition => ({ + id: `organisation-facturation-${props.idOrganization}`, + title: "Facturation", + description: "Abonnements et factures", + component: createElement(OrganizationBillingTabContent, { + idOrganization: props.idOrganization, + }), + }), + + "organisation-paramètres": (props: { idOrganization: string }): TabDefinition => ({ + id: `organisation-paramètres-${props.idOrganization}`, + title: "Paramètres de l'organisation", + description: "Configuration générale", + component: createElement(OrganizationSettingsTabContent, { + idOrganization: props.idOrganization, + }), + }), + + "organisation-api": (props: { idOrganization: string }): TabDefinition => ({ + id: `organisation-api-${props.idOrganization}`, + title: "API", + description: "Accès API de l'organisation", + component: createElement(OrganizationApiTabContent, { + idOrganization: props.idOrganization, + }), + }), + + // ─── Year-level tabs ─────────────────────────────────────────────────── + + "exercice-écritures": (props: { idOrganization: string; idYear: string }): TabDefinition => ({ + id: `exercice-écritures-${props.idOrganization}-${props.idYear}`, + title: "Écritures", + description: "Journal comptable de l'exercice", + component: createElement(EntriesPage, { + idOrganization: props.idOrganization, + idYear: props.idYear, + }), + }), + + "exercice-documents": (props: { idOrganization: string; idYear: string }): TabDefinition => ({ + id: `exercice-documents-${props.idOrganization}-${props.idYear}`, + title: "Documents", + description: "Rapports, bilans et compte de résultat", + component: createElement(ReportsTabContent, { + idOrganization: props.idOrganization, + idYear: props.idYear, + }), + }), + + "exercice-stockage": (props: { idOrganization: string; idYear: string }): TabDefinition => ({ + id: `exercice-stockage-${props.idOrganization}-${props.idYear}`, + title: "Stockage", + description: "Fichiers attachés à l'exercice", + component: createElement(FilesPage), + }), + + "exercice-paramètres": (props: { idOrganization: string; idYear: string }): TabDefinition => ({ + id: `exercice-paramètres-${props.idOrganization}-${props.idYear}`, + title: "Paramètres de l'exercice", + description: "Journaux, catégories, plan comptable", + component: createElement(YearSettingsTabContent, { + idOrganization: props.idOrganization, + idYear: props.idYear, + }), + }), + + // ─── Billing form tabs ───────────────────────────────────────────────── + + "facturation-licence": (props: { idOrganization: string }): TabDefinition => ({ + id: `facturation-licence-${props.idOrganization}`, + title: "Modifier la licence", + description: "Modifier le montant de la licence mensuelle", + component: createElement(UpdateLicencePage, { + idOrganization: props.idOrganization, + }), + }), + + "facturation-stockage": (props: { idOrganization: string }): TabDefinition => ({ + id: `facturation-stockage-${props.idOrganization}`, + title: "Modifier le stockage", + description: "Ajuster la capacité de stockage", + component: createElement(UpdateStoragePage, { + idOrganization: props.idOrganization, + }), + }), + + "facturation-tokens": (props: { idOrganization: string }): TabDefinition => ({ + id: `facturation-tokens-${props.idOrganization}`, + title: "Modifier les tokens IA", + description: "Acheter des tokens pour l'assistant IA", + component: createElement(UpdateTokensPage, { + idOrganization: props.idOrganization, + }), + }), + + "facturation-ocr": (props: { idOrganization: string }): TabDefinition => ({ + id: `facturation-ocr-${props.idOrganization}`, + title: "Ajouter des pages OCR", + description: "Acheter des pages OCR supplémentaires", + component: createElement(UpdateOcrPage, { + idOrganization: props.idOrganization, + }), + }), + + "facturation-recharge": (props: { idOrganization: string }): TabDefinition => ({ + id: `facturation-recharge-${props.idOrganization}`, + title: "Recharger le portefeuille", + description: "Ajouter des fonds au portefeuille", + component: createElement(WalletTopUpPage, { + idOrganization: props.idOrganization, + }), + }), + + "facturation-retrait": (props: { idOrganization: string }): TabDefinition => ({ + id: `facturation-retrait-${props.idOrganization}`, + title: "Retirer du portefeuille", + description: "Retirer des fonds du portefeuille", + component: createElement(WalletWithdrawalPage, { + idOrganization: props.idOrganization, + }), + }), + + // ─── Detail tabs ─────────────────────────────────────────────────────── + + écriture: (props: { idOrganization: string; idYear: string; idEntry: string }): TabDefinition => ({ + id: `écriture-${props.idOrganization}-${props.idYear}-${props.idEntry}`, + title: "Écriture", + component: createElement(EntryTabContent, { + idOrganization: props.idOrganization, + idYear: props.idYear, + idEntry: props.idEntry, + }), + }), + + ticket: (props: { idTicket: string }): TabDefinition => ({ + id: `ticket-${props.idTicket}`, + title: "Ticket", + component: createElement(TicketTabContent, { + idTicket: props.idTicket, + }), + }), + + "admin-ticket": (props: { idTicket: string }): TabDefinition => ({ + id: `admin-ticket-${props.idTicket}`, + title: "Ticket", + component: createElement(AdminTicketTabContent, { + idTicket: props.idTicket, + }), + }), + + fichier: (props: { idOrganization: string; idFile: string }): TabDefinition => ({ + id: `fichier-${props.idOrganization}-${props.idFile}`, + title: "Fichier", + component: createElement(FileTabContent, { + idOrganization: props.idOrganization, + idFile: props.idFile, + }), + }), +} + +// ─── Open tab args (discriminated union derived from registry) ──────────────── + +export type OpenTabArgs = { + [K in keyof typeof TAB_REGISTRY]: { + component: K + props: Parameters<(typeof TAB_REGISTRY)[K]>[0] + } +}[keyof typeof TAB_REGISTRY] diff --git a/packages/website/src/contexts/tabs/tabsContext.tsx b/packages/website/src/contexts/tabs/tabsContext.tsx new file mode 100644 index 00000000..f448ca97 --- /dev/null +++ b/packages/website/src/contexts/tabs/tabsContext.tsx @@ -0,0 +1,88 @@ +import { createContext, useContext } from "react" +import type { OpenTabArgs } from "./tabDefinitions.js" + +// ─── History ───────────────────────────────────────────────────────────────── + +/** + * One entry in a tab's back/forward history stack. + * `component` is null when the entry has never been visited (or was evicted) + * and will be (re)created from the registry on first access. + */ +export type HistoryEntry = { + /** Stable random ID for this entry, used to build the browser URL. */ + id: string + definitionKey: string + definitionProps: Record + title: string + description?: string + /** The rendered React node. null = not yet mounted or evicted. */ + component: React.ReactNode +} + +// ─── Tab Types ─────────────────────────────────────────────────────────────── + +export type ComponentTab = { + id: string + type: "component" + /** All visited (and future-accessible) entries for this tab. */ + history: HistoryEntry[] + /** Index into `history` that is currently visible. */ + historyIndex: number + /** + * Whether this tab's current history entry is mounted in the DOM. + * When false all `entry.component` values are null (LRU-evicted). + */ + isAlive: boolean +} + +export type PanelTab = { + id: string + type: "panel" + title: string + icon?: string + component: React.ReactNode // never serialized +} + +export type Tab = ComponentTab | PanelTab + +// ─── Helpers ───────────────────────────────────────────────────────────────── + +/** Returns the currently-active history entry of a ComponentTab. */ +export function currentEntry(tab: ComponentTab): HistoryEntry { + return tab.history[tab.historyIndex] +} + +// ─── Options ───────────────────────────────────────────────────────────────── + +export type OpenTabOptions = { + /** + * When true, always create (or activate an existing) separate tab + * instead of replacing the current tab's history. + * Also forced when the user holds Ctrl / Meta during the click. + */ + newTab?: boolean +} + +// ─── Actions ───────────────────────────────────────────────────────────────── + +export type TabsContextValue = { + tabs: Tab[] + activeTabId: string | null + openTab: (args: OpenTabArgs, options?: OpenTabOptions) => void + closeTab: (id: string) => void + activateTab: (id: string) => void + navigateBack: (tabId: string) => void + navigateForward: (tabId: string) => void + openPanelTab: (title: string, component: React.ReactNode, icon?: string) => string + updateTabTitle: (id: string, title: string) => void +} + +export const TabsContext = createContext(null) + +export function useTabs(): TabsContextValue { + const ctx = useContext(TabsContext) + if (ctx === null) { + throw new Error("useTabs must be used within a TabsProvider") + } + return ctx +} diff --git a/packages/website/src/contexts/tabs/tabsProvider.tsx b/packages/website/src/contexts/tabs/tabsProvider.tsx new file mode 100644 index 00000000..4353e314 --- /dev/null +++ b/packages/website/src/contexts/tabs/tabsProvider.tsx @@ -0,0 +1,581 @@ +import { generateId } from "@arrhes/application-metadata" +import { useCallback, useEffect, useMemo, useRef, useState } from "react" +import { applicationRouter } from "../../routes/applicationRouter.js" +import { setCookie } from "../../utilities/cookies/setCookie.js" +import { cookiePrefix } from "../../utilities/variables.js" +import { type OpenTabArgs, TAB_REGISTRY, type TabDefinition } from "./tabDefinitions.js" +import { + type ComponentTab, + currentEntry, + type HistoryEntry, + type OpenTabOptions, + type PanelTab, + type Tab, + TabsContext, + type TabsContextValue, +} from "./tabsContext.js" +import { loadPersistedTabs, normalisePersisted, type PersistedHistoryEntry, savePersistedTabs } from "./tabsStorage.js" +import { OuterRouterProvider } from "./useOuterRouter.js" + +// Maximum number of component tabs kept alive in React memory at any time. +const MAX_ALIVE_TABS = 5 + +// ─── Helpers ───────────────────────────────────────────────────────────────── + +function buildEntry(definitionKey: string, definitionProps: Record, id?: string): HistoryEntry { + const registry = TAB_REGISTRY as Record TabDefinition> + const def = registry[definitionKey]?.(definitionProps) + return { + id: id ?? generateId(), + definitionKey, + definitionProps, + title: def?.title ?? "", + description: def?.description, + component: def?.component ?? null, + } +} + +/** + * Returns a new tabs array where at most MAX_ALIVE_TABS component tabs have + * isAlive = true. The `newlyActivatedId` is guaranteed to stay alive; + * older tabs beyond the limit are evicted (isAlive = false, all history + * component nodes cleared). + */ +function applyLruEviction(tabs: Tab[], newlyActivatedId: string): Tab[] { + const aliveComponentTabs = tabs.filter((t): t is ComponentTab => t.type === "component" && t.isAlive) + + if (aliveComponentTabs.length <= MAX_ALIVE_TABS) return tabs + + const toEvict = aliveComponentTabs + .filter((t) => t.id !== newlyActivatedId) + .slice(0, aliveComponentTabs.length - MAX_ALIVE_TABS) + + const evictIds = new Set(toEvict.map((t) => t.id)) + + return tabs.map((t) => { + if (t.type === "component" && evictIds.has(t.id)) { + return { + ...t, + isAlive: false, + // Free all component nodes across history. + history: t.history.map((e) => ({ + ...e, + component: null, + })), + } + } + return t + }) +} + +// ─── Provider ──────────────────────────────────────────────────────────────── + +type Props = { + children: React.ReactNode +} + +export function TabsProvider({ children }: Props) { + const [tabs, setTabs] = useState(() => { + const raw = loadPersistedTabs() + const persisted = raw ? normalisePersisted(raw) : null + if (persisted && persisted.tabs.length > 0) { + return persisted.tabs.flatMap((t) => { + if (!t.history || t.history.length === 0) return [] + + const history: HistoryEntry[] = t.history.map((e, idx) => { + // Only build the component for the currently-visible entry. + if (idx === (t.historyIndex ?? 0)) { + return buildEntry(e.definitionKey, e.definitionProps ?? {}, e.id) + } + return { + id: e.id, + definitionKey: e.definitionKey, + definitionProps: e.definitionProps ?? {}, + title: e.title, + description: e.description, + component: null, + } + }) + + const tab: ComponentTab = { + id: t.id, + type: "component", + history, + historyIndex: t.historyIndex ?? 0, + isAlive: true, + } + return [ + tab, + ] + }) + } + return [] + }) + + const [activeTabId, setActiveTabId] = useState(() => { + const persisted = loadPersistedTabs() + if (persisted?.activeTabId) return persisted.activeTabId + return null + }) + + // Track whether Ctrl / Meta is currently held so openTab can decide + // whether to replace-in-place or create a new tab — without requiring + // every call site to pass a flag. + const ctrlKeyRef = useRef(false) + useEffect(() => { + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === "Control" || e.key === "Meta") ctrlKeyRef.current = true + } + const onKeyUp = (e: KeyboardEvent) => { + if (e.key === "Control" || e.key === "Meta") ctrlKeyRef.current = false + } + window.addEventListener("keydown", onKeyDown) + window.addEventListener("keyup", onKeyUp) + // Safety: reset if window loses focus. + window.addEventListener("blur", () => { + ctrlKeyRef.current = false + }) + return () => { + window.removeEventListener("keydown", onKeyDown) + window.removeEventListener("keyup", onKeyUp) + } + }, []) + + // After every state change, sync to sessionStorage. + useEffect(() => { + const componentTabs = tabs.filter((t): t is ComponentTab => t.type === "component") + savePersistedTabs({ + activeTabId, + tabs: componentTabs.map((t) => ({ + id: t.id, + type: "component" as const, + history: t.history.map( + (e): PersistedHistoryEntry => ({ + id: e.id, + definitionKey: e.definitionKey, + definitionProps: e.definitionProps, + title: e.title, + description: e.description, + }), + ), + historyIndex: t.historyIndex, + })), + }) + }, [ + tabs, + activeTabId, + ]) + + // Keep a synchronous ref so openTab can read current tabs without a stale closure. + const tabsRef = useRef(tabs) + tabsRef.current = tabs + + // Keep a synchronous ref for activeTabId too. + const activeTabIdRef = useRef(activeTabId) + activeTabIdRef.current = activeTabId + + // Whenever the active tab or its current history entry changes, sync the + // org cookie so that all API calls include the correct X-Organization-Id header. + // This mirrors what organizationPathRoute.beforeLoad did in the TanStack Router flow. + useEffect(() => { + if (activeTabId === null) return + const activeTab = tabs.find((t): t is ComponentTab => t.type === "component" && t.id === activeTabId) + if (!activeTab) return + const idOrganization = currentEntry(activeTab).definitionProps.idOrganization + if (typeof idOrganization === "string" && idOrganization) { + setCookie(`${cookiePrefix}_id_organization`, idOrganization) + } + }, [ + activeTabId, + tabs, + ]) + + // On mount: initialise the browser URL from persisted state so the correct + // /dashboard/:tabId/:historyIndex is shown immediately. + useEffect(() => { + if (activeTabId === null) { + window.history.replaceState({}, "", "/dashboard") + } else { + const tab = tabsRef.current.find((t): t is ComponentTab => t.type === "component" && t.id === activeTabId) + const entryId = tab ? currentEntry(tab).id : "0" + window.history.replaceState({ tabId: activeTabId, entryId }, "", `/dashboard/${activeTabId}/${entryId}`) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + // React to browser back/forward (mouse buttons, keyboard, browser UI). + // Parse the destination URL/state and update tab context accordingly. + useEffect(() => { + const onPopState = (e: PopStateEvent) => { + const state = e.state as { tabId?: string; entryId?: string } | null + let tabId: string | null = null + let entryId: string | null = null + if (state?.tabId !== undefined && state.entryId !== undefined) { + tabId = state.tabId + entryId = state.entryId + } else { + const m = window.location.pathname.match(/^\/dashboard\/([^/]+)\/([^/]+)$/) + if (m) { + tabId = m[1] + entryId = m[2] + } else { + const s = window.location.pathname.match(/^\/dashboard\/([^/]+)$/) + if (s) tabId = s[1] + } + } + if (tabId === null) return + setActiveTabId(tabId) + setTabs((prev) => + applyLruEviction( + prev.map((t) => { + if (t.type !== "component" || t.id !== tabId) return t + const historyIndex = entryId + ? t.history.findIndex((e) => e.id === entryId) + : t.historyIndex + if (historyIndex < 0) return t + const history = t.history.map((e, i) => { + if (i !== historyIndex || e.component !== null) return e + return buildEntry(e.definitionKey, e.definitionProps, e.id) + }) + return { ...t, history, historyIndex } + }), + tabId, + ), + ) + } + window.addEventListener("popstate", onPopState) + return () => window.removeEventListener("popstate", onPopState) + }, []) + + // ─── Actions ───────────────────────────────────────────────────────────── + + const openTab = useCallback((args: OpenTabArgs, options?: OpenTabOptions) => { + window.dispatchEvent(new CustomEvent("arrhes:tab-opened")) + + const forceNew = options?.newTab === true || ctrlKeyRef.current + + const registry = TAB_REGISTRY as Record TabDefinition> + const def = registry[args.component as string]?.(args.props as Record) + if (!def) return + + const definitionKey = args.component as string + const definitionProps = args.props as Record + + const current = tabsRef.current + const currentActiveId = activeTabIdRef.current + + if (!forceNew) { + // ── Replace mode: push into the current tab's history ─────────── + const activeTab = current.find((t): t is ComponentTab => t.type === "component" && t.id === currentActiveId) + + if (activeTab) { + // Check if the current history entry is already this exact definition + const ce = currentEntry(activeTab) + if ( + ce.definitionKey === definitionKey && + JSON.stringify(ce.definitionProps) === JSON.stringify(definitionProps) + ) { + // Already showing this — no-op. + return + } + + const entry = buildEntry(definitionKey, definitionProps) + const newHistory = [ + // Truncate any forward history. + ...activeTab.history.slice(0, activeTab.historyIndex + 1), + entry, + ] + const newIndex = newHistory.length - 1 + + setTabs((prev) => + applyLruEviction( + prev.map((t) => + t.id === activeTab.id + ? { + ...t, + history: newHistory, + historyIndex: newIndex, + } + : t, + ), + activeTab.id, + ), + ) + window.history.pushState( + { tabId: activeTab.id, entryId: entry.id }, + "", + `/dashboard/${activeTab.id}/${entry.id}`, + ) + // Active tab ID stays the same. + return + } + // No active tab — fall through to create a new one. + } + + // ── New tab mode ───────────────────────────────────────────────────── + // Dedup: find a tab whose current history entry matches. + const existing = current.find((t): t is ComponentTab => { + if (t.type !== "component") return false + const ce = currentEntry(t) + return ( + ce.definitionKey === definitionKey && + JSON.stringify(ce.definitionProps) === JSON.stringify(definitionProps) + ) + }) + + if (existing) { + // Revive if evicted. + setTabs((prev) => + applyLruEviction( + prev.map((t) => { + if (t.type === "component" && t.id === existing.id && !t.isAlive) { + const history = t.history.map((e, i) => + i === t.historyIndex ? buildEntry(e.definitionKey, e.definitionProps) : e, + ) + return { + ...t, + isAlive: true, + history, + } + } + return t + }), + existing.id, + ), + ) + setActiveTabId(existing.id) + window.history.replaceState( + { tabId: existing.id, entryId: currentEntry(existing).id }, + "", + `/dashboard/${existing.id}/${currentEntry(existing).id}`, + ) + return + } + + const entry = buildEntry(definitionKey, definitionProps) + const newTab: ComponentTab = { + id: generateId(), + type: "component", + history: [ + entry, + ], + historyIndex: 0, + isAlive: true, + } + setActiveTabId(newTab.id) + setTabs((prev) => + applyLruEviction( + [ + ...prev, + newTab, + ], + newTab.id, + ), + ) + window.history.replaceState({ tabId: newTab.id, entryId: entry.id }, "", `/dashboard/${newTab.id}/${entry.id}`) + }, []) + + const closeTab = useCallback((id: string) => { + const current = tabsRef.current + const idx = current.findIndex((t) => t.id === id) + if (idx === -1) return + const next = current.filter((t) => t.id !== id) + const currentActiveId = activeTabIdRef.current + let newActiveId: string | null + if (next.length === 0) { + newActiveId = null + } else if (currentActiveId !== id) { + newActiveId = currentActiveId + } else { + newActiveId = next[Math.min(idx, next.length - 1)].id + } + + setTabs((prev) => { + const i = prev.findIndex((t) => t.id === id) + if (i === -1) return prev + const n = prev.filter((t) => t.id !== id) + if (n.length === 0) { + setActiveTabId(null) + return [] + } + setActiveTabId((currentActive) => { + if (currentActive !== id) return currentActive + return n[Math.min(i, n.length - 1)].id + }) + return n + }) + + if (newActiveId === null) { + window.history.replaceState({}, "", "/dashboard") + } else { + const newActiveTab = next.find((t): t is ComponentTab => t.type === "component" && t.id === newActiveId) + const entryId = newActiveTab ? currentEntry(newActiveTab).id : "0" + window.history.replaceState( + { tabId: newActiveId, entryId }, + "", + `/dashboard/${newActiveId}/${entryId}`, + ) + } + }, []) + + const activateTab = useCallback((id: string) => { + setTabs((prev) => { + const revived = prev.map((t) => { + if (t.type === "component" && t.id === id && !t.isAlive) { + const history = t.history.map((e, i) => + i === t.historyIndex ? buildEntry(e.definitionKey, e.definitionProps) : e, + ) + return { + ...t, + isAlive: true, + history, + } + } + return t + }) + return applyLruEviction(revived, id) + }) + setActiveTabId(id) + const tab = tabsRef.current.find((t): t is ComponentTab => t.type === "component" && t.id === id) + const entryId = tab ? currentEntry(tab).id : "0" + window.history.replaceState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) + }, []) + + // Delegate to browser history — the popstate handler above updates React state. + const navigateBack = useCallback((_tabId: string) => { + window.history.back() + }, []) + + const navigateForward = useCallback((_tabId: string) => { + window.history.forward() + }, []) + + const openPanelTab = useCallback((title: string, component: React.ReactNode, icon?: string): string => { + const id = generateId() + const newTab: PanelTab = { + id, + type: "panel", + title, + icon, + component, + } + setTabs((prev) => [ + ...prev, + newTab, + ]) + setActiveTabId(id) + return id + }, []) + + const updateTabTitle = useCallback((id: string, title: string) => { + setTabs((prev) => + prev.map((t) => { + if (t.id !== id || t.type !== "component") return t + // Update the title of the current history entry. + const history = t.history.map((e, i) => + i === t.historyIndex + ? { + ...e, + title, + } + : e, + ) + return { + ...t, + history, + } + }), + ) + }, []) + + const value = useMemo( + () => ({ + tabs, + activeTabId, + openTab, + closeTab, + activateTab, + navigateBack, + navigateForward, + openPanelTab, + updateTabTitle, + }), + [ + tabs, + activeTabId, + openTab, + closeTab, + activateTab, + navigateBack, + navigateForward, + openPanelTab, + updateTabTitle, + ], + ) + + return ( + + {children} + + ) +} + +// ─── Pre-render each alive route tab so React keep-alive works ──────────────── +// For each alive ComponentTab we render ALL history entries in the DOM, +// hiding non-current ones with display:none — this preserves React state +// (scroll position, form values etc.) across back/forward navigation. + +type TabContentAreaProps = { + activeTabId: string | null + tabs: Tab[] +} + +export function TabContentArea({ activeTabId, tabs }: TabContentAreaProps) { + const visibleStyle: React.CSSProperties = { + flex: 1, + minHeight: 0, + display: "flex", + flexDirection: "column", + } + const hiddenStyle: React.CSSProperties = { + display: "none", + } + + return ( + <> + {tabs.map((tab) => { + const isActiveTab = tab.id === activeTabId + + if (tab.type === "panel") { + return ( +
+ {tab.component} +
+ ) + } + + // Component tab: only render if alive. + if (!tab.isAlive) return null + + return ( +
+ {tab.history.map((entry, idx) => ( +
+ {entry.component} +
+ ))} +
+ ) + })} + + ) +} diff --git a/packages/website/src/contexts/tabs/tabsStorage.ts b/packages/website/src/contexts/tabs/tabsStorage.ts new file mode 100644 index 00000000..ca64a0e7 --- /dev/null +++ b/packages/website/src/contexts/tabs/tabsStorage.ts @@ -0,0 +1,110 @@ +import { generateId } from "@arrhes/application-metadata" + +// ─── sessionStorage persistence ────────────────────────────────────────────── +// Only component tabs are persisted (panel tabs hold a ReactNode which can't be serialized). + +const STORAGE_KEY = "arrhes_tabs" + +export type PersistedHistoryEntry = { + id: string + definitionKey: string + definitionProps: Record + title: string + description?: string +} + +export type PersistedComponentTab = { + id: string + type: "component" + /** Full navigation history for this tab. */ + history: PersistedHistoryEntry[] + /** Currently-visible index into `history`. */ + historyIndex: number +} + +export type PersistedState = { + activeTabId: string | null + tabs: PersistedComponentTab[] +} + +// ─── Legacy shape (before history was introduced) ──────────────────────────── + +type LegacyPersistedTab = { + id: string + type: "component" + title: string + description?: string + icon?: string + definitionKey: string + definitionProps: Record + // no `history` field +} + +type LegacyPersistedState = { + activeTabId: string | null + tabs: LegacyPersistedTab[] +} + +function isLegacy(raw: unknown): raw is LegacyPersistedState { + if (typeof raw !== "object" || raw === null) return false + const obj = raw as Record + if (!Array.isArray(obj.tabs)) return false + const first = obj.tabs[0] + if (!first) return true // empty — either format + return !("history" in first) +} + +// ─── I/O ───────────────────────────────────────────────────────────────────── + +export function loadPersistedTabs(): PersistedState | null { + try { + const raw = sessionStorage.getItem(STORAGE_KEY) + if (raw === null) return null + const parsed: unknown = JSON.parse(raw) + + // Migrate legacy format that had a flat definitionKey/definitionProps/title. + if (isLegacy(parsed)) { + return { + activeTabId: parsed.activeTabId, + tabs: parsed.tabs.map((t) => ({ + id: t.id, + type: "component" as const, + history: [ + { + id: generateId(), + definitionKey: t.definitionKey, + definitionProps: t.definitionProps ?? {}, + title: t.title, + description: t.description, + }, + ], + historyIndex: 0, + })), + } + } + + return parsed as PersistedState + } catch { + return null + } +} + +/** Normalise a loaded state: assign IDs to any entries that are missing one + * (forward-compat for sessions saved before this field was added). */ +export function normalisePersisted(state: PersistedState): PersistedState { + return { + ...state, + tabs: state.tabs.map((t) => ({ + ...t, + history: t.history.map((e) => (e.id ? e : { ...e, id: generateId() })), + })), + } +} + +export function savePersistedTabs(state: PersistedState): void { + try { + sessionStorage.setItem(STORAGE_KEY, JSON.stringify(state)) + } catch { + // sessionStorage unavailable (private mode etc.) — silently ignore + } +} diff --git a/packages/website/src/contexts/tabs/useOuterRouter.tsx b/packages/website/src/contexts/tabs/useOuterRouter.tsx new file mode 100644 index 00000000..dfdb3299 --- /dev/null +++ b/packages/website/src/contexts/tabs/useOuterRouter.tsx @@ -0,0 +1,16 @@ +import { createContext, useContext } from "react" +import type { applicationRouter } from "../../routes/applicationRouter.js" + +type OuterRouter = typeof applicationRouter + +const OuterRouterContext = createContext(null) + +export const OuterRouterProvider = OuterRouterContext.Provider + +export function useOuterRouter(): OuterRouter { + const router = useContext(OuterRouterContext) + if (router === null) { + throw new Error("useOuterRouter must be used within an OuterRouterProvider") + } + return router +} diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentPage.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/agentPage.tsx index e0d8dd13..1c85eca3 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/agentPage.tsx @@ -14,7 +14,6 @@ import type { KeyboardEvent } from "react" import { useEffect, useRef, useState } from "react" import { Popover } from "../../../../components/overlays/popover/popover.tsx" import { dataClient } from "../../../../contexts/data/queryClient.js" -import { organizationPathRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { useDataFromAPI } from "../../../../utilities/useHTTPData.js" @@ -30,10 +29,19 @@ interface PendingFileItem { name: string } -export function AgentPage() { +export function AgentPage({ + idOrganization: idOrganizationProp, + onSessionCreated, +}: { + idOrganization?: string + onSessionCreated?: (id: string) => void +} = {}) { const params = useParams({ - from: organizationPathRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" const [input, setInput] = useState("") const [isLoading, setIsLoading] = useState(false) const navigate = useNavigate() @@ -81,7 +89,7 @@ export function AgentPage() { const agentSessionResponse = await getResponseBodyFromAPI({ routeDefinition: createOneAgentSessionRouteDefinition, body: { - idOrganization: params.idOrganization, + idOrganization: idOrganization, message: text.trim(), idYear: selectedYearId || null, customInstructions: customInstructions.trim() || null, @@ -108,7 +116,7 @@ export function AgentPage() { const createFileResponse = await getResponseBodyFromAPI({ routeDefinition: createOneAgentFileRouteDefinition, body: { - idOrganization: params.idOrganization, + idOrganization: idOrganization, idAgentSession: agentSessionResponse.data.id, fileName: pendingFile.name, fileType: file.type || "application/octet-stream", @@ -161,7 +169,7 @@ export function AgentPage() { const agentMessageResponse = await getResponseBodyFromAPI({ routeDefinition: createOneAgentMessageRouteDefinition, body: { - idOrganization: params.idOrganization, + idOrganization: idOrganization, idAgentSession: agentSessionResponse.data.id, message: text.trim(), }, @@ -183,13 +191,17 @@ export function AgentPage() { exact: false, }) - navigate({ - to: "/dashboard/organisations/$idOrganization/agent/sessions/$idAgentSession", - params: { - idOrganization: params.idOrganization, - idAgentSession: agentSessionResponse.data.id, - }, - }) + if (onSessionCreated) { + onSessionCreated(agentSessionResponse.data.id) + } else { + navigate({ + to: "/dashboard/organisations/$idOrganization/agent/sessions/$idAgentSession", + params: { + idOrganization: idOrganization, + idAgentSession: agentSessionResponse.data.id, + }, + }) + } } catch (error) { console.error("[createNewSession]", error) toast({ diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx index 967e2911..cad2f4fd 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx @@ -35,7 +35,6 @@ import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" import { Popover } from "../../../../components/overlays/popover/popover.tsx" import { dataClient } from "../../../../contexts/data/queryClient.ts" -import { agentSessionRoute } from "../../../../routes/root/dashboard/agent/agentSessionRoute.tsx" import { getCookie } from "../../../../utilities/cookies/getCookie.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -147,10 +146,23 @@ function ContextInitialiser(props: { return <>{props.children} } -export function AgentSessionContent() { +export function AgentSessionContent({ + idOrganization: idOrganizationProp, + idAgentSession: idAgentSessionProp, + onDeleteSession, +}: { + idOrganization?: string + idAgentSession?: string + onDeleteSession?: () => void +} = {}) { const params = useParams({ - from: agentSessionRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + idAgentSession?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" + const idAgentSession = idAgentSessionProp ?? params.idAgentSession ?? "" const [input, setInput] = useState(undefined) const [draftReferences, setDraftReferences] = useState([]) @@ -177,7 +189,7 @@ export function AgentSessionContent() { const result = await getResponseBodyFromAPI({ routeDefinition: updateOneAgentSessionRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, idYear: editYear || null, customInstructions: editInstructions?.trim() || null, }, @@ -190,7 +202,7 @@ export function AgentSessionContent() { await invalidateData({ routeDefinition: readOneAgentSessionRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, }) } else { @@ -203,13 +215,13 @@ export function AgentSessionContent() { setIsSavingContext(false) } }, [ - params.idAgentSession, + idAgentSession, editYear, editInstructions, ]) const handleDeleteSession = useCallback(async () => { - const sessionId = params.idAgentSession + const sessionId = idAgentSession setIsDeleting(true) try { await getResponseBodyFromAPI({ @@ -224,19 +236,24 @@ export function AgentSessionContent() { ], exact: false, }) - navigate({ - to: "/dashboard/organisations/$idOrganization/agent", - params: { - idOrganization: params.idOrganization, - }, - }) + if (onDeleteSession) { + onDeleteSession() + } else { + navigate({ + to: "/dashboard/organisations/$idOrganization/agent", + params: { + idOrganization: idOrganization, + }, + }) + } } finally { setIsDeleting(false) } }, [ navigate, - params.idAgentSession, - params.idOrganization, + idAgentSession, + idOrganization, + onDeleteSession, ]) // ── Streaming state ───────────────────────────────────────────────────────── @@ -278,7 +295,7 @@ export function AgentSessionContent() { const { data: messagesData } = useDataFromAPI({ routeDefinition: readAllAgentMessagesRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, }) @@ -334,7 +351,7 @@ export function AgentSessionContent() { await invalidateData({ routeDefinition: readAllAgentMessagesRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, }) setStreamingContent("") @@ -366,7 +383,7 @@ export function AgentSessionContent() { signal: controller.signal, headers, body: JSON.stringify({ - idOrganization: params.idOrganization, + idOrganization: idOrganization, idAgentMessage: streamMessageId, }), }) @@ -496,7 +513,7 @@ export function AgentSessionContent() { const result = await getResponseBodyFromAPI({ routeDefinition: readAllAgentMessagesRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, signal: controller.signal, }) @@ -518,8 +535,8 @@ export function AgentSessionContent() { } }, [ streamMessageId, - params.idAgentSession, - params.idOrganization, + idAgentSession, + idOrganization, ]) // ── Send message ──────────────────────────────────────────────────────────── @@ -561,8 +578,8 @@ export function AgentSessionContent() { const createFileResponse = await getResponseBodyFromAPI({ routeDefinition: createOneAgentFileRouteDefinition, body: { - idOrganization: params.idOrganization, - idAgentSession: params.idAgentSession, + idOrganization: idOrganization, + idAgentSession: idAgentSession, fileName: file.name, fileType: file.type || "application/octet-stream", fileSize: file.size, @@ -604,7 +621,7 @@ export function AgentSessionContent() { const attachResult = await getResponseBodyFromAPI({ routeDefinition: updateOneAgentSessionRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, fileIds: [ ...existingIds, ...newIds, @@ -623,7 +640,7 @@ export function AgentSessionContent() { await invalidateData({ routeDefinition: readOneAgentSessionRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, }) } @@ -634,8 +651,8 @@ export function AgentSessionContent() { const result = await getResponseBodyFromAPI({ routeDefinition: createOneAgentMessageRouteDefinition, body: { - idOrganization: params.idOrganization, - idAgentSession: params.idAgentSession, + idOrganization: idOrganization, + idAgentSession: idAgentSession, message: text.trim(), references: references && references.length > 0 ? references : null, }, @@ -656,7 +673,7 @@ export function AgentSessionContent() { await invalidateData({ routeDefinition: readAllAgentMessagesRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, }) scrollToBottom() @@ -674,8 +691,8 @@ export function AgentSessionContent() { }, [ isSending, - params.idOrganization, - params.idAgentSession, + idOrganization, + idAgentSession, pendingFiles, scrollToBottom, ], @@ -689,7 +706,7 @@ export function AgentSessionContent() { {(agentSession) => { @@ -714,7 +731,7 @@ export function AgentSessionContent() { {(agentMessages) => { @@ -817,7 +834,7 @@ export function AgentSessionContent() { setDraftReferences(references) }} disabled={isSubmitting} - idOrganization={params.idOrganization} + idOrganization={idOrganization} idYear={agentSession.idYear} /> f.idFile), }, }) @@ -917,7 +934,7 @@ export function AgentSessionContent() { routeDefinition: readOneAgentSessionRouteDefinition, body: { - idAgentSession: params.idAgentSession, + idAgentSession: idAgentSession, }, }) } diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx new file mode 100644 index 00000000..1e3f81f5 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx @@ -0,0 +1,329 @@ +import { + readAllAgentSessionsRouteDefinition, + readOrganizationBillingRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { Button, ButtonGhostContent, ButtonOutlineContent, formatDateTime } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconMenu, IconMessage, IconPlus } from "@tabler/icons-react" +import { lazy, Suspense, useState } from "react" +import { Banner } from "../../../../components/layouts/banner.tsx" +import { EmptyState } from "../../../../components/layouts/emptyState.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" +import { SearchBar } from "../../../../components/layouts/searchBar.tsx" +import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" +import { extractSnippet } from "./extractSnippet.ts" + +const AgentPage = lazy(() => + import("./agentPage.js").then((m) => ({ + default: m.AgentPage, + })), +) +const AgentSessionContent = lazy(() => + import("./agentSessionContent.js").then((m) => ({ + default: m.AgentSessionContent, + })), +) + +export function AgentTabContent({ idOrganization }: { idOrganization: string }) { + const [selectedSessionId, setSelectedSessionId] = useState(null) + const [isMenuOpen, setIsMenuOpen] = useState(false) + const [search, setSearch] = useState("") + + const subscription = useDataFromAPI({ + routeDefinition: readOrganizationBillingRouteDefinition, + body: {}, + }) + + const tokensTotalAvailable = subscription.data?.tokensTotalAvailable ?? 0 + const searchTrimmed = search.trim() + + const { data: sessions } = useDataFromAPI({ + routeDefinition: readAllAgentSessionsRouteDefinition, + body: searchTrimmed + ? { + idOrganization, + search: searchTrimmed, + } + : { + idOrganization, + }, + }) + + const displaySessions = sessions ?? [] + + const sidebarContent = ( +
+
+ + +
+
+
+ {displaySessions.length === 0 ? ( + } + title="Aucune session" + subtitle={undefined} + /> + ) : null} + {displaySessions.map((session) => { + const snippet = + searchTrimmed && session.matchedContent + ? extractSnippet(session.matchedContent, searchTrimmed) + : undefined + + return ( + + ) + })} +
+
+
+ ) + + if (subscription.isPending) { + return ( + + +
+ Chargement... +
+
+
+ ) + } + + return ( +
+ {sidebarContent} +
+
+ + {isMenuOpen && ( +
setIsMenuOpen(false)} + > + {sidebarContent} +
+ )} +
+
+ 0 ? "information" : "warning"} + title="Assistant IA" + > + {tokensTotalAvailable > 0 + ? `Tokens disponibles: ${tokensTotalAvailable.toLocaleString("fr-FR")}` + : "Aucun token disponible. Rechargez votre organisation pour continuer."} + +
+
+ + {selectedSessionId === null ? ( + setSelectedSessionId(id)} + /> + ) : ( + // key forces remount when switching sessions + setSelectedSessionId(null)} + /> + )} + +
+
+
+ ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx index 36760ea4..6b1b8bb8 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx @@ -1,6 +1,7 @@ import { createOneApiKeyRouteDefinition, readAllApiKeysRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { type JSX, useState } from "react" import { Fragment } from "react/jsx-runtime" @@ -11,103 +12,122 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" import { RawKeyDisplay } from "./rawKeyDisplay.tsx" -export function CreateOneApiKey(props: { - idOrganization: v.InferOutput["id"] - children: JSX.Element -}) { - const [open, setOpen] = useState(false) +function CreateOneApiKeyPanel(props: { onClose: () => void }) { const [rawKey, setRawKey] = useState(null) return ( - - { - setOpen(value) - setRawKey(null) - }} - > - {props.children} - - - - {rawKey !== null ? ( - setOpen(false)} - /> - ) : ( - , - text: "Créer la clé API", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: createOneApiKeyRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible de créer la clé API", - variant: "error", - }) - return false - } +
+ {rawKey !== null ? ( + + ) : ( + , + text: "Créer la clé API", + }} + onSubmit={async (data) => { + const response = await getResponseBodyFromAPI({ + routeDefinition: createOneApiKeyRouteDefinition, + body: data, + }) + if (!response.ok) { + toast({ + title: "Impossible de créer la clé API", + variant: "error", + }) + return false + } - setRawKey(response.data.rawKey) - toast({ - title: "Clé API créée avec succès", - variant: "success", - }) - return true - }} - onCancel={undefined} - onSuccess={async () => { - await invalidateData({ - routeDefinition: readAllApiKeysRouteDefinition, - body: {}, - }) - }} - > - {(form) => ( - - ( - - - - - - - - )} + setRawKey(response.data.rawKey) + toast({ + title: "Clé API créée avec succès", + variant: "success", + }) + return true + }} + onCancel={undefined} + onSuccess={async () => { + await invalidateData({ + routeDefinition: readAllApiKeysRouteDefinition, + body: {}, + }) + }} + > + {(form) => ( + + ( + + - + + + + + )} - - )} - - - - + /> + + )} + + )} +
+ ) +} + +export function CreateOneApiKey(props: { + idOrganization: v.InferOutput["id"] + children: JSX.Element +}) { + const { openPanelTab, closeTab } = useTabs() + + return ( + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx index 92205184..aea2865a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx @@ -3,14 +3,16 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { Page } from "../../../../../components/layouts/page/page.tsx" -import { organizationApiKeysRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx" import { ApiKeysListTable } from "./apiKeysListTable.tsx" import { CreateOneApiKey } from "./createOneApiKey.tsx" -export function OrganizationApiKeysPage() { +export function OrganizationApiKeysPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { const params = useParams({ - from: organizationApiKeysRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( @@ -23,14 +25,14 @@ export function OrganizationApiKeysPage() { alignItems: "center", })} > - + } text="Créer une clé API" />
- + ) diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx new file mode 100644 index 00000000..3b252dc3 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx @@ -0,0 +1,48 @@ +import { IconHome, IconKey } from "@tabler/icons-react" +import { lazy, Suspense } from "react" +import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" + +const OrganizationApiGeneralPage = lazy(() => + import("./organizationApiGeneralPage.js").then((m) => ({ + default: m.OrganizationApiGeneralPage, + })), +) +const OrganizationApiKeysPage = lazy(() => + import("./keys/organizationApiKeysPage.js").then((m) => ({ + default: m.OrganizationApiKeysPage, + })), +) + +export function OrganizationApiTabContent(props: { idOrganization: string }) { + return ( + , + content: ( + + + + ), + }, + { + key: "clés", + label: "Clés", + icon: , + content: ( + + + + ), + }, + ], + }, + }} + /> + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx index b5664fa8..e8e041c2 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx @@ -1,11 +1,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata" import { getAmountTTCFromHTInCents, getTaxAmountFromHTInCents } from "@arrhes/application-metadata/utilities" import { Chip, type ChipColors } from "@arrhes/ui" -import { useParams } from "@tanstack/react-router" import type { ColumnDef } from "@tanstack/react-table" import type * as v from "valibot" import { DataTable } from "../../../../../components/layouts/dataTable.tsx" -import { organizationInvoicesRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx" import { InvoiceActionsPopover } from "./InvoiceActionsPopover.tsx" const invoiceStatusLabel: Record = { @@ -39,11 +37,7 @@ function getInvoiceTotalAmountInCents(invoice: Invoice) { type Invoice = v.InferOutput -export function InvoicesTable(props: { invoices: Array }) { - const params = useParams({ - from: organizationInvoicesRoute.id, - }) - +export function InvoicesTable(props: { invoices: Array; idOrganization: string }) { const columns: Array> = [ { id: "period", @@ -93,7 +87,7 @@ export function InvoicesTable(props: { invoices: Array }) { header: " ", cell: (context) => ( ), diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx index 13a247e3..6f1cec0f 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx @@ -5,13 +5,15 @@ import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../../components/layouts/settingsSection/settingsSection.tsx" -import { organizationInvoicesRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx" import { InvoicesTable } from "./InvoicesTable.tsx" -export function OrganizationInvoicesPage() { - const _params = useParams({ - from: organizationInvoicesRoute.id, - }) +export function OrganizationInvoicesPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { + const params = useParams({ + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( @@ -33,7 +35,12 @@ export function OrganizationInvoicesPage() { ) } - return + return ( + + ) }}
diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx new file mode 100644 index 00000000..e917458a --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx @@ -0,0 +1,78 @@ +import { IconFileInvoice, IconPuzzle, IconReceipt, IconWallet } from "@tabler/icons-react" +import { lazy, Suspense } from "react" +import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" + +const OrganizationWalletPage = lazy(() => + import("./wallet/organizationWalletPage.js").then((m) => ({ + default: m.OrganizationWalletPage, + })), +) +const OrganizationServicesPage = lazy(() => + import("./organizationServicesPage.js").then((m) => ({ + default: m.OrganizationServicesPage, + })), +) +const OrganizationBillingHistoryPage = lazy(() => + import("./organizationBillingHistoryPage.js").then((m) => ({ + default: m.OrganizationBillingHistoryPage, + })), +) +const OrganizationInvoicesPage = lazy(() => + import("./invoices/organizationInvoicesPage.js").then((m) => ({ + default: m.OrganizationInvoicesPage, + })), +) + +export function OrganizationBillingTabContent(props: { idOrganization: string }) { + return ( + , + content: ( + + + + ), + }, + { + key: "services", + label: "Services", + icon: , + content: ( + + + + ), + }, + { + key: "paiements", + label: "Paiements", + icon: , + content: ( + + + + ), + }, + { + key: "factures", + label: "Factures", + icon: , + content: ( + + + + ), + }, + ], + }, + }} + /> + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx index f989e8a8..ecebd828 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx @@ -10,15 +10,11 @@ import { Button, ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconAlertTriangle, IconPencil } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { organizationServicesRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx" +import { useTabs } from "../../../../contexts/tabs/tabsContext.js" import { formatEuros } from "../../../../utilities/formatEuros.tsx" -import { UpdateLicenceSubscriptionDrawer } from "./updateLicenceSubscriptionDrawer.tsx" -import { UpdateOcrSubscriptionDrawer } from "./updateOcrSubscriptionDrawer.tsx" -import { UpdateStorageSubscriptionDrawer } from "./updateStorageSubscriptionDrawer.tsx" -import { UpdateTokensSubscriptionDrawer } from "./updateTokensSubscriptionDrawer.tsx" import { OrganizationBillingDisclaimerBanner } from "./wallet/OrganizationBillingDisclaimerBanner.tsx" function getStorageAddonQuantity(storageLimit: number) { @@ -290,20 +286,22 @@ function ServiceCard(props: { ) } -export function OrganizationServicesPage() { - const [refreshKey, setRefreshKey] = useState(0) +export function OrganizationServicesPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { + const { openTab } = useTabs() const params = useParams({ - from: organizationServicesRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( {(organization) => { @@ -332,7 +330,7 @@ export function OrganizationServicesPage() { gap: "1.25rem", })} > - + {isWalletInsufficient ? (
setRefreshKey((key) => key + 1)} + - + } + text="Modifier" + /> + } /> } action={ - setRefreshKey((key) => key + 1)} + - + } + text="Modifier" + /> + } /> setRefreshKey((key) => key + 1)} + - + } + text="Modifier" + /> + } /> setRefreshKey((key) => key + 1)} + - + } + text="Modifier" + /> + } />
diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx new file mode 100644 index 00000000..58958171 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx @@ -0,0 +1,178 @@ +import { + readOneOrganizationRouteDefinition, + updateLicenceSubscriptionRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { getAmountTTCFromHTInCents, SUPPORT_TIERS, VAT_PERCENT } from "@arrhes/application-metadata/utilities" +import { Button, ButtonOutlineContent, toast } from "@arrhes/ui" +import { InputCurrency } from "@arrhes/ui/components/inputs/inputCurrency.js" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconDeviceFloppy } from "@tabler/icons-react" +import { useState } from "react" +import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { formatEuros } from "../../../../utilities/formatEuros.tsx" +import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" +import { invalidateData } from "../../../../utilities/invalidateData.ts" + +function UpdateLicenceForm(props: { idOrganization: string; currentAmountInCents: number }) { + const [confirmOpen, setConfirmOpen] = useState(false) + const [value, setValue] = useState(props.currentAmountInCents) + const [isSaving, setIsSaving] = useState(false) + const valueTTCInCents = getAmountTTCFromHTInCents(value) + + async function handleSave() { + if (Number.isNaN(value) || value < 0) { + toast({ + title: "Montant invalide", + variant: "error", + }) + return + } + + setIsSaving(true) + const response = await getResponseBodyFromAPI({ + routeDefinition: updateLicenceSubscriptionRouteDefinition, + body: { + newAmountInCents: value, + }, + }) + setIsSaving(false) + + if (response.ok === false) { + toast({ + title: response.error?.cause ?? "Erreur lors de la mise à jour", + variant: "error", + }) + return + } + + toast({ + title: "Modification enregistrée, effective le 1er du mois prochain", + variant: "success", + }) + + await invalidateData({ + routeDefinition: readOneOrganizationRouteDefinition, + body: { + idOrganization: props.idOrganization, + }, + }) + } + + return ( +
+

+ La licence Arrhes est un montant mensuel libre, prélevé depuis le portefeuille le 1er de chaque mois. + Vous pouvez le laisser à 0,00€ ou contribuer librement au développement d'Arrhes et bénéficier d'un + support privilégié. Le montant est HT. +

+
+ { + setValue(v ?? 0) + }} + type="number" + placeholder="Montant mensuel en €" + /> +
+ {SUPPORT_TIERS.map((tier) => ( + + ))} +
+
+ + +
+ ) +} + +export function UpdateLicencePage({ idOrganization }: { idOrganization: string }) { + return ( + + + Modifier le montant de la licence + + + + {(organization) => ( + + )} + + + + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicenceSubscriptionDrawer.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicenceSubscriptionDrawer.tsx deleted file mode 100644 index 040c8501..00000000 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicenceSubscriptionDrawer.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { - readOneOrganizationRouteDefinition, - updateLicenceSubscriptionRouteDefinition, -} from "@arrhes/application-metadata/routes" -import { getAmountTTCFromHTInCents, SUPPORT_TIERS, VAT_PERCENT } from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, toast } from "@arrhes/ui" -import { InputCurrency } from "@arrhes/ui/components/inputs/inputCurrency.js" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconDeviceFloppy } from "@tabler/icons-react" -import { type JSX, useState } from "react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" -import { formatEuros } from "../../../../utilities/formatEuros.tsx" -import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" -import { invalidateData } from "../../../../utilities/invalidateData.ts" - -export function UpdateLicenceSubscriptionDrawer(props: { - children: JSX.Element - idOrganization: string - currentAmountInCents: number - onSuccess: () => void -}) { - const [open, setOpen] = useState(false) - const [confirmOpen, setConfirmOpen] = useState(false) - const [value, setValue] = useState(props.currentAmountInCents) - const [isSaving, setIsSaving] = useState(false) - const valueTTCInCents = getAmountTTCFromHTInCents(value) - - async function handleSaveSupport() { - if (Number.isNaN(value) || value < 0) { - toast({ - title: "Montant invalide", - variant: "error", - }) - return - } - - setIsSaving(true) - const response = await getResponseBodyFromAPI({ - routeDefinition: updateLicenceSubscriptionRouteDefinition, - body: { - newAmountInCents: value, - }, - }) - setIsSaving(false) - - if (response.ok === false) { - toast({ - title: response.error?.cause ?? "Erreur lors de la mise à jour", - variant: "error", - }) - return - } - - toast({ - title: "Modification enregistrée, effective le 1er du mois prochain", - variant: "success", - }) - - await invalidateData({ - routeDefinition: readOneOrganizationRouteDefinition, - body: { - idOrganization: props.idOrganization, - }, - }) - setOpen(false) - props.onSuccess() - } - - return ( - - {props.children} - - - -
-

- La licence Arrhes est un montant mensuel libre, prélevé depuis le portefeuille le 1er de - chaque mois. Vous pouvez le laisser à 0,00€ ou contribuer librement au développement - d'Arrhes et bénéficier d'un support privilégié. Le montant est HT. -

-
- { - setValue(value ?? 0) - }} - type="number" - placeholder="Montant mensuel en €" - /> -
- {SUPPORT_TIERS.map((tier) => ( - - ))} -
-
- - -
-
-
-
- ) -} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx new file mode 100644 index 00000000..e363e475 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx @@ -0,0 +1,302 @@ +import { + readOneOrganizationRouteDefinition, + updateOcrSubscriptionRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { + getAmountTTCFromHTInCents, + INCLUDED_OCR_PAGES, + OCR_PAGE_PRICE_IN_CENTS, + OCR_PAGE_TIERS, + VAT_PERCENT, +} from "@arrhes/application-metadata/utilities" +import { Button, ButtonOutlineContent, ButtonPlainContent, InputNumber, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconCreditCard, IconX } from "@tabler/icons-react" +import { type ReactNode, useEffect, useState } from "react" +import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { formatEuros } from "../../../../utilities/formatEuros.tsx" +import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" +import { invalidateData } from "../../../../utilities/invalidateData.ts" + +function formatPageDelta(quantityDelta: number) { + if (quantityDelta === 0) { + return "Aucun ajout" + } + + return `${quantityDelta.toLocaleString("fr-FR")} page${quantityDelta > 1 ? "s" : ""}` +} + +function FormSection(props: { title: string; description?: string; children: ReactNode }) { + return ( +
+
+

+ {props.title} +

+ {props.description ? ( +

+ {props.description} +

+ ) : null} +
+ {props.children} +
+ ) +} + +function UpdateOcrForm(props: { idOrganization: string; currentQuantity: number; currentPagesLeft: number }) { + const [confirmOpen, setConfirmOpen] = useState(false) + const [quantityDelta, setQuantityDelta] = useState(0) + const nextQuantity = props.currentQuantity + quantityDelta + const deltaAmountInCents = quantityDelta * OCR_PAGE_PRICE_IN_CENTS + const deltaAmountTTCInCents = getAmountTTCFromHTInCents(deltaAmountInCents) + const nextPagesLeft = props.currentPagesLeft + quantityDelta + + useEffect(() => { + setQuantityDelta(0) + }, []) + + async function handleSave() { + const response = await getResponseBodyFromAPI({ + routeDefinition: updateOcrSubscriptionRouteDefinition, + body: { + newQuantity: nextQuantity, + }, + }) + + if (response.ok === false) { + toast({ + title: response.error?.cause ?? "Erreur lors de la mise à jour", + variant: "error", + }) + return + } + + toast({ + title: "Pages OCR mises à jour", + variant: "success", + }) + + await invalidateData({ + routeDefinition: readOneOrganizationRouteDefinition, + body: { + idOrganization: props.idOrganization, + }, + }) + } + + return ( +
+

+ Chaque page supplémentaire est débitée 0,01€ (HT) une seule fois depuis le portefeuille. Les pages + achetées restent disponibles tant qu'elles ne sont pas consommées. +

+ +
+ +
+ {OCR_PAGE_TIERS.map((tier) => ( + + ))} +
+
+
+ +
+ {[ + { + label: "Quota actuel", + value: `${props.currentPagesLeft.toLocaleString("fr-FR")} pages`, + bg: "neutral/1", + }, + { + label: "Nouveau quota", + value: `${nextPagesLeft.toLocaleString("fr-FR")} pages`, + bg: deltaAmountInCents > 0 ? "warning/5" : "neutral/1", + }, + { + label: "Débité du portefeuille", + value: `${formatEuros(deltaAmountTTCInCents)} TTC`, + bg: "neutral/1", + }, + ].map((item) => ( +
+ + {item.label} + + + {item.value} + +
+ ))} +
+
+
+ + +
+ +
+ ) +} + +export function UpdateOcrPage({ idOrganization }: { idOrganization: string }) { + return ( + + + Ajouter des pages OCR + + + + {(organization) => ( + + )} + + + + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrSubscriptionDrawer.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrSubscriptionDrawer.tsx deleted file mode 100644 index 3dffe674..00000000 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrSubscriptionDrawer.tsx +++ /dev/null @@ -1,316 +0,0 @@ -import { updateOcrSubscriptionRouteDefinition } from "@arrhes/application-metadata/routes" -import { - getAmountTTCFromHTInCents, - OCR_PAGE_PRICE_IN_CENTS, - OCR_PAGE_TIERS, - VAT_PERCENT, -} from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, ButtonPlainContent, InputNumber, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconCreditCard, IconX } from "@tabler/icons-react" -import { type JSX, type ReactNode, useEffect, useState } from "react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" -import { formatEuros } from "../../../../utilities/formatEuros.tsx" -import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" - -function formatPageDelta(quantityDelta: number) { - if (quantityDelta === 0) { - return "Aucun ajout" - } - - return `${quantityDelta.toLocaleString("fr-FR")} page${quantityDelta > 1 ? "s" : ""}` -} - -function DrawerSection(props: { title: string; description?: string; children: ReactNode }) { - return ( -
-
-

- {props.title} -

- {props.description ? ( -

- {props.description} -

- ) : null} -
- {props.children} -
- ) -} - -export function UpdateOcrSubscriptionDrawer(props: { - children: JSX.Element - currentQuantity: number - currentPagesLeft: number - onSuccess: () => void -}) { - const [open, setOpen] = useState(false) - const [confirmOpen, setConfirmOpen] = useState(false) - const [quantityDelta, setQuantityDelta] = useState(0) - const nextQuantity = props.currentQuantity + quantityDelta - const deltaAmountInCents = quantityDelta * OCR_PAGE_PRICE_IN_CENTS - const deltaAmountTTCInCents = getAmountTTCFromHTInCents(deltaAmountInCents) - const nextPagesLeft = props.currentPagesLeft + quantityDelta - - useEffect(() => { - if (open) { - setQuantityDelta(0) - } - }, [ - open, - ]) - - async function handleSave() { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateOcrSubscriptionRouteDefinition, - body: { - newQuantity: nextQuantity, - }, - }) - - if (response.ok === false) { - toast({ - title: response.error?.cause ?? "Erreur lors de la mise à jour", - variant: "error", - }) - return - } - toast({ - title: "Pages OCR mises à jour", - variant: "success", - }) - setOpen(false) - props.onSuccess() - } - - return ( - - {props.children} - - - -
-

- Chaque page supplémentaire est débitée 0,01€ (HT) une seule fois depuis le portefeuille. Les - pages achetées restent disponibles tant qu'elles ne sont pas consommées. -

- -
- -
- {OCR_PAGE_TIERS.map((tier) => ( - - ))} -
-
-
- -
-
- - Quota actuel - - - {props.currentPagesLeft.toLocaleString("fr-FR")} pages - -
-
0 ? "warning/5" : "neutral/1", - })} - > - - Nouveau quota - - - {nextPagesLeft.toLocaleString("fr-FR")} pages - -
-
- - Débité du portefeuille - - - {formatEuros(deltaAmountTTCInCents)} TTC - -
-
-
-
- - -
- -
-
-
-
- ) -} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx new file mode 100644 index 00000000..1f031c41 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx @@ -0,0 +1,470 @@ +import { + readOneOrganizationRouteDefinition, + updateStorageSubscriptionRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { + FREE_STORAGE_BYTES, + getAmountTTCFromHTInCents, + STORAGE_PRICE_PER_GB_IN_CENTS, + VAT_PERCENT, +} from "@arrhes/application-metadata/utilities" +import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconMinus, IconPlus } from "@tabler/icons-react" +import { type ReactNode, useEffect, useState } from "react" +import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { formatEuros } from "../../../../utilities/formatEuros.tsx" +import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" +import { invalidateData } from "../../../../utilities/invalidateData.ts" + +function formatBytes(bytes: number): string { + if (bytes >= 1_073_741_824) { + return `${(bytes / 1_073_741_824).toFixed(2)} Go` + } + + if (bytes >= 1_048_576) { + return `${(bytes / 1_048_576).toFixed(2)} Mo` + } + + if (bytes >= 1024) { + return `${(bytes / 1024).toFixed(2)} Ko` + } + + return `${bytes} o` +} + +function getStorageLimitFromQuantity(quantity: number): number { + return FREE_STORAGE_BYTES + quantity * FREE_STORAGE_BYTES +} + +function getMinimumStorageQuantityFromUsage(storageCurrentUsage: number): number { + return Math.max(Math.ceil(storageCurrentUsage / FREE_STORAGE_BYTES) - 1, 0) +} + +function formatStorageDelta(quantityDelta: number): string { + if (quantityDelta === 0) { + return "Aucun changement" + } + + if (quantityDelta > 0) { + return `Ajouter ${quantityDelta} Go` + } + + return `Retirer ${Math.abs(quantityDelta)} Go` +} + +function getProRataFraction(): number { + const now = new Date() + const daysInMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 0)).getUTCDate() + const remainingDays = daysInMonth - now.getUTCDate() + 1 + return remainingDays / daysInMonth +} + +function FormSection(props: { title: string; description?: string; children: ReactNode }) { + return ( +
+
+

+ {props.title} +

+ {props.description ? ( +

+ {props.description} +

+ ) : null} +
+ {props.children} +
+ ) +} + +function UpdateStorageForm(props: { + idOrganization: string + currentQuantity: number + currentUsageInBytes: number + currentMaxUsageInBytes: number +}) { + const [confirmOpen, setConfirmOpen] = useState(false) + const [quantityDelta, setQuantityDelta] = useState(0) + const [isLoading, setIsLoading] = useState(false) + const minimumQuantity = getMinimumStorageQuantityFromUsage(props.currentUsageInBytes) + const nextQuantity = props.currentQuantity + quantityDelta + const currentAmountInCents = props.currentQuantity * STORAGE_PRICE_PER_GB_IN_CENTS + const nextAmountInCents = nextQuantity * STORAGE_PRICE_PER_GB_IN_CENTS + const deltaAmountInCents = nextAmountInCents - currentAmountInCents + const proRataAmountInCents = Math.round(deltaAmountInCents * getProRataFraction()) + const proRataAmountTTCInCents = getAmountTTCFromHTInCents(proRataAmountInCents) + const nextStorageLimitInBytes = getStorageLimitFromQuantity(nextQuantity) + + useEffect(() => { + setQuantityDelta(0) + }, []) + + async function handleSave() { + setIsLoading(true) + const response = await getResponseBodyFromAPI({ + routeDefinition: updateStorageSubscriptionRouteDefinition, + body: { + newQuantity: nextQuantity, + }, + }) + setIsLoading(false) + + if (response.ok === false) { + toast({ + title: response.error?.cause ?? "Erreur lors de la mise à jour", + variant: "error", + }) + return + } + + toast({ + title: + quantityDelta > 0 + ? "Stockage augmenté immédiatement" + : "Réduction enregistrée, effective le 1er du mois prochain", + variant: "success", + }) + + await invalidateData({ + routeDefinition: readOneOrganizationRouteDefinition, + body: { + idOrganization: props.idOrganization, + }, + }) + } + + return ( +
+

+ {quantityDelta > 0 + ? `Augmenter le stockage est immédiat : le montant prorata du mois est débité du portefeuille. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` + : quantityDelta < 0 + ? `Réduire le stockage est effectif le 1er du mois prochain. Aucun remboursement n'est appliqué. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` + : `Ajustez le stockage disponible pour l'organisation. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).`} +

+ +
+ {[ + { + label: "Utilisation actuelle", + value: formatBytes(props.currentUsageInBytes), + }, + { + label: "Capacité actuelle", + value: formatBytes(props.currentMaxUsageInBytes), + }, + { + label: "Go supplémentaires actifs", + value: + props.currentQuantity === 0 + ? "Aucun supplément" + : `${props.currentQuantity} Go supplémentaires`, + }, + { + label: "Montant actuel", + value: `${formatEuros(currentAmountInCents)} HT / mois`, + }, + ].map((item) => ( +
+ + {item.label} + + + {item.value} + +
+ ))} +
+
+ +
+ + + Le minimum autorisé est calé sur l'usage actuel: {formatBytes(props.currentUsageInBytes)}. + +
+
+ +
+
+ + Capacité après modification + + + {formatBytes(nextStorageLimitInBytes)} + +
+
0 + ? "warning/5" + : deltaAmountInCents < 0 + ? "success/5" + : "neutral/1", + })} + > + + {deltaAmountInCents > 0 + ? "Débité maintenant (prorata)" + : deltaAmountInCents < 0 + ? "Effectif le 1er du mois" + : "Ajustement portefeuille"} + + + {deltaAmountInCents > 0 + ? `≈\u2009${formatEuros(proRataAmountTTCInCents)} TTC` + : formatEuros(Math.abs(deltaAmountInCents))} + +
+
+ + Nouveau montant mensuel + + + {formatEuros(nextAmountInCents)} HT / mois + +
+
+ + Nouvelle capacité totale + + + {formatStorageDelta(quantityDelta) === "Aucun changement" + ? formatBytes(props.currentMaxUsageInBytes) + : formatBytes(nextStorageLimitInBytes)} + +
+
+
+ + 0 + ? `${formatBytes(nextStorageLimitInBytes)} de stockage. ≈\u2009${formatEuros(proRataAmountTTCInCents)} TTC seront débités du portefeuille (prorata du mois en cours).` + : `Le stockage sera réduit à ${formatBytes(nextStorageLimitInBytes)}, effectif le 1er du mois prochain.` + } + submitButtonProps={{ + text: "Confirmer", + }} + onSubmit={handleSave} + /> +
+ ) +} + +export function UpdateStoragePage({ idOrganization }: { idOrganization: string }) { + return ( + + + Modifier le stockage + + + + {(organization) => ( + + )} + + + + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStorageSubscriptionDrawer.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStorageSubscriptionDrawer.tsx deleted file mode 100644 index 3f224467..00000000 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStorageSubscriptionDrawer.tsx +++ /dev/null @@ -1,520 +0,0 @@ -import { - readOneOrganizationRouteDefinition, - updateStorageSubscriptionRouteDefinition, -} from "@arrhes/application-metadata/routes" -import { - FREE_STORAGE_BYTES, - getAmountTTCFromHTInCents, - STORAGE_PRICE_PER_GB_IN_CENTS, - VAT_PERCENT, -} from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconMinus, IconPlus } from "@tabler/icons-react" -import { type JSX, type ReactNode, useEffect, useState } from "react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" -import { formatEuros } from "../../../../utilities/formatEuros.tsx" -import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" -import { invalidateData } from "../../../../utilities/invalidateData.ts" - -function formatBytes(bytes: number): string { - if (bytes >= 1_073_741_824) { - return `${(bytes / 1_073_741_824).toFixed(2)} Go` - } - - if (bytes >= 1_048_576) { - return `${(bytes / 1_048_576).toFixed(2)} Mo` - } - - if (bytes >= 1024) { - return `${(bytes / 1024).toFixed(2)} Ko` - } - - return `${bytes} o` -} - -function getStorageLimitFromQuantity(quantity: number): number { - return FREE_STORAGE_BYTES + quantity * FREE_STORAGE_BYTES -} - -function getMinimumStorageQuantityFromUsage(storageCurrentUsage: number): number { - return Math.max(Math.ceil(storageCurrentUsage / FREE_STORAGE_BYTES) - 1, 0) -} - -function formatStorageSelection(quantity: number): string { - return `${quantity + 1} Go disponibles` -} - -function getProRataFraction(): number { - const now = new Date() - const daysInMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 0)).getUTCDate() - const remainingDays = daysInMonth - now.getUTCDate() + 1 - return remainingDays / daysInMonth -} - -function formatStorageDelta(quantityDelta: number): string { - if (quantityDelta === 0) { - return "Aucun changement" - } - - if (quantityDelta > 0) { - return `Ajouter ${quantityDelta} Go` - } - - return `Retirer ${Math.abs(quantityDelta)} Go` -} - -function DrawerSection(props: { title: string; description?: string; children: ReactNode }) { - return ( -
-
-

- {props.title} -

- {props.description ? ( -

- {props.description} -

- ) : null} -
- {props.children} -
- ) -} - -export function UpdateStorageSubscriptionDrawer(props: { - children: JSX.Element - idOrganization: string - currentQuantity: number - currentUsageInBytes: number - currentMaxUsageInBytes: number - onSuccess: () => void -}) { - const [open, setOpen] = useState(false) - const [confirmOpen, setConfirmOpen] = useState(false) - const [quantityDelta, setQuantityDelta] = useState(0) - const [isLoading, setIsLoading] = useState(false) - const minimumQuantity = getMinimumStorageQuantityFromUsage(props.currentUsageInBytes) - const nextQuantity = props.currentQuantity + quantityDelta - const currentAmountInCents = props.currentQuantity * STORAGE_PRICE_PER_GB_IN_CENTS - const nextAmountInCents = nextQuantity * STORAGE_PRICE_PER_GB_IN_CENTS - const deltaAmountInCents = nextAmountInCents - currentAmountInCents - const proRataAmountInCents = Math.round(deltaAmountInCents * getProRataFraction()) - const proRataAmountTTCInCents = getAmountTTCFromHTInCents(proRataAmountInCents) - const nextStorageLimitInBytes = getStorageLimitFromQuantity(nextQuantity) - - useEffect(() => { - if (open) { - setQuantityDelta(0) - } - }, [ - open, - ]) - - async function handleSave() { - setIsLoading(true) - const response = await getResponseBodyFromAPI({ - routeDefinition: updateStorageSubscriptionRouteDefinition, - body: { - newQuantity: nextQuantity, - }, - }) - setIsLoading(false) - - if (response.ok === false) { - toast({ - title: response.error?.cause ?? "Erreur lors de la mise à jour", - variant: "error", - }) - return - } - toast({ - title: - quantityDelta > 0 - ? "Stockage augmenté immédiatement" - : "Réduction enregistrée, effective le 1er du mois prochain", - variant: "success", - }) - - await invalidateData({ - routeDefinition: readOneOrganizationRouteDefinition, - body: { - idOrganization: props.idOrganization, - }, - }) - - setOpen(false) - props.onSuccess() - } - - return ( - - {props.children} - - - -
-

- {quantityDelta > 0 - ? `Augmenter le stockage est immédiat : le montant prorata du mois est débité du portefeuille. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` - : quantityDelta < 0 - ? `Réduire le stockage est effectif le 1er du mois prochain. Aucun remboursement n'est appliqué. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` - : `Ajustez le stockage disponible pour l'organisation. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).`} -

- -
-
- - Utilisation actuelle - - - {formatBytes(props.currentUsageInBytes)} - -
-
- - Capacité actuelle - - - {formatBytes(props.currentMaxUsageInBytes)} - -
-
- - Go supplémentaires actifs - - - {props.currentQuantity === 0 - ? "Aucun supplément" - : `${props.currentQuantity} Go supplémentaires`} - -
-
- - Montant actuel - - - {formatEuros(currentAmountInCents)} HT / mois - -
-
-
- -
- - - Le minimum autorisé est calé sur l'usage actuel:{" "} - {formatBytes(props.currentUsageInBytes)}. - -
-
- -
-
- - Capacité après modification - - - {formatBytes(nextStorageLimitInBytes)} - -
-
0 - ? "warning/5" - : deltaAmountInCents < 0 - ? "success/5" - : "neutral/1", - })} - > - - {deltaAmountInCents > 0 - ? "Débité maintenant (prorata)" - : deltaAmountInCents < 0 - ? "Effectif le 1er du mois" - : "Ajustement portefeuille"} - - - {deltaAmountInCents > 0 - ? `≈\u2009${formatEuros(proRataAmountTTCInCents)} TTC` - : formatEuros(Math.abs(deltaAmountInCents))} - -
-
- - Nouveau montant mensuel - - - {formatEuros(nextAmountInCents)} HT / mois - -
-
- - Nouvelle capacité totale - - - {formatStorageSelection(nextQuantity)} - -
-
-
- - 0 - ? `${formatStorageDelta(quantityDelta)} sera appliqué immédiatement. ${formatEuros(proRataAmountTTCInCents)} TTC seront débités du portefeuille (${formatEuros(proRataAmountInCents)} HT + TVA ${VAT_PERCENT}%, prorata du mois).` - : `${formatStorageDelta(quantityDelta)} sera effectif le 1er du mois prochain. Aucun remboursement ne sera appliqué.` - } - submitButtonProps={{ - text: "Confirmer", - }} - onSubmit={handleSave} - /> -
-
-
-
- ) -} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx new file mode 100644 index 00000000..11d672cd --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx @@ -0,0 +1,319 @@ +import { + readOneOrganizationRouteDefinition, + updateTokensSubscriptionRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { + getAmountTTCFromHTInCents, + INCLUDED_AGENT_TOKENS, + TOKEN_PACK_PRICE_IN_CENTS, + TOKEN_TIERS, + TOKENS_PER_PACK, + VAT_PERCENT, +} from "@arrhes/application-metadata/utilities" +import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconPlus } from "@tabler/icons-react" +import { type ReactNode, useEffect, useState } from "react" +import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { formatEuros } from "../../../../utilities/formatEuros.tsx" +import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" +import { invalidateData } from "../../../../utilities/invalidateData.ts" + +function formatTokenValue(value: number) { + if (value >= 1_000_000) { + return `${(value / 1_000_000).toLocaleString("fr-FR", { + maximumFractionDigits: 1, + })} M` + } + + if (value >= 1_000) { + return `${(value / 1_000).toLocaleString("fr-FR", { + maximumFractionDigits: 0, + })} k` + } + + return value.toLocaleString("fr-FR") +} + +function formatTokenUnitDelta(quantityDelta: number) { + if (quantityDelta === 0) { + return "Aucun ajout" + } + + return `${quantityDelta} M tokens` +} + +function FormSection(props: { title: string; description?: string; children: ReactNode }) { + return ( +
+
+

+ {props.title} +

+ {props.description ? ( +

+ {props.description} +

+ ) : null} +
+ {props.children} +
+ ) +} + +function UpdateTokensForm(props: { idOrganization: string; currentQuantity: number; currentTokensLeft: number }) { + const [confirmOpen, setConfirmOpen] = useState(false) + const [quantityDelta, setQuantityDelta] = useState(0) + const nextQuantity = props.currentQuantity + quantityDelta + const deltaAmountInCents = quantityDelta * TOKEN_PACK_PRICE_IN_CENTS + const deltaAmountTTCInCents = getAmountTTCFromHTInCents(deltaAmountInCents) + const addedTokens = quantityDelta * TOKENS_PER_PACK + const nextTokensLeft = props.currentTokensLeft + addedTokens + + useEffect(() => { + setQuantityDelta(0) + }, []) + + async function handleSave() { + const response = await getResponseBodyFromAPI({ + routeDefinition: updateTokensSubscriptionRouteDefinition, + body: { + newQuantity: nextQuantity, + }, + }) + + if (response.ok === false) { + toast({ + title: response.error?.cause ?? "Erreur lors de la mise à jour", + variant: "error", + }) + return + } + + toast({ + title: "Tokens IA mis à jour", + variant: "success", + }) + + await invalidateData({ + routeDefinition: readOneOrganizationRouteDefinition, + body: { + idOrganization: props.idOrganization, + }, + }) + } + + return ( +
+

+ Chaque million de tokens supplémentaire est débité une seule fois depuis le portefeuille. Les tokens + achetés restent disponibles tant qu'ils n'ont pas été consommés. Montants en HT (TVA {VAT_PERCENT}%). +

+ +
+ +
+ {TOKEN_TIERS.map((tier) => ( + + ))} +
+
+
+ +
+ {[ + { + label: "Solde actuel", + value: `${formatTokenValue(props.currentTokensLeft)} tokens`, + bg: "neutral/1", + }, + { + label: "Nouveau solde", + value: `${formatTokenValue(nextTokensLeft)} tokens`, + bg: deltaAmountInCents > 0 ? "warning/5" : "neutral/1", + }, + { + label: "Débité du portefeuille", + value: `${formatEuros(deltaAmountTTCInCents)} TTC`, + bg: "neutral/1", + }, + ].map((item) => ( +
+ + {item.label} + + + {item.value} + +
+ ))} +
+
+ + +
+ ) +} + +export function UpdateTokensPage({ idOrganization }: { idOrganization: string }) { + return ( + + + Modifier les tokens Assistant IA + + + + {(organization) => ( + + )} + + + + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensSubscriptionDrawer.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensSubscriptionDrawer.tsx deleted file mode 100644 index 0cffd1f9..00000000 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensSubscriptionDrawer.tsx +++ /dev/null @@ -1,327 +0,0 @@ -import { updateTokensSubscriptionRouteDefinition } from "@arrhes/application-metadata/routes" -import { - getAmountTTCFromHTInCents, - TOKEN_PACK_PRICE_IN_CENTS, - TOKEN_TIERS, - TOKENS_PER_PACK, - VAT_PERCENT, -} from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconPlus } from "@tabler/icons-react" -import { type JSX, type ReactNode, useEffect, useState } from "react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" -import { formatEuros } from "../../../../utilities/formatEuros.tsx" -import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" - -function formatTokenValue(value: number) { - if (value >= 1_000_000) { - return `${(value / 1_000_000).toLocaleString("fr-FR", { - maximumFractionDigits: 1, - })} M` - } - - if (value >= 1_000) { - return `${(value / 1_000).toLocaleString("fr-FR", { - maximumFractionDigits: 0, - })} k` - } - - return value.toLocaleString("fr-FR") -} - -function formatTokenUnitDelta(quantityDelta: number) { - if (quantityDelta === 0) { - return "Aucun ajout" - } - - return `${quantityDelta} M tokens` -} - -function DrawerSection(props: { title: string; description?: string; children: ReactNode }) { - return ( -
-
-

- {props.title} -

- {props.description ? ( -

- {props.description} -

- ) : null} -
- {props.children} -
- ) -} - -export function UpdateTokensSubscriptionDrawer(props: { - children: JSX.Element - currentQuantity: number - currentTokensLeft: number - onSuccess: () => void -}) { - const [open, setOpen] = useState(false) - const [confirmOpen, setConfirmOpen] = useState(false) - const [quantityDelta, setQuantityDelta] = useState(0) - const nextQuantity = props.currentQuantity + quantityDelta - const deltaAmountInCents = quantityDelta * TOKEN_PACK_PRICE_IN_CENTS - const deltaAmountTTCInCents = getAmountTTCFromHTInCents(deltaAmountInCents) - const addedTokens = quantityDelta * TOKENS_PER_PACK - const nextTokensLeft = props.currentTokensLeft + addedTokens - - useEffect(() => { - if (open) { - setQuantityDelta(0) - } - }, [ - open, - ]) - - async function handleSave() { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateTokensSubscriptionRouteDefinition, - body: { - newQuantity: nextQuantity, - }, - }) - - if (response.ok === false) { - toast({ - title: response.error?.cause ?? "Erreur lors de la mise à jour", - variant: "error", - }) - return - } - toast({ - title: "Tokens IA mis à jour", - variant: "success", - }) - setOpen(false) - props.onSuccess() - } - - return ( - - {props.children} - - - -
-

- Chaque million de tokens supplémentaire est débité une seule fois depuis le portefeuille. - Les tokens achetés restent disponibles tant qu'ils n'ont pas été consommés. Montants en HT - (TVA {VAT_PERCENT}%). -

- -
- -
- {TOKEN_TIERS.map((tier) => ( - - ))} -
-
-
- -
-
- - Solde actuel - - - {formatTokenValue(props.currentTokensLeft)} tokens - -
-
0 ? "warning/5" : "neutral/1", - })} - > - - Nouveau solde - - - {formatTokenValue(nextTokensLeft)} tokens - -
-
- - Débité du portefeuille - - - {formatEuros(deltaAmountTTCInCents)} TTC - -
-
-
- - -
-
-
-
- ) -} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpDrawer.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpDrawer.tsx deleted file mode 100644 index ac8287b3..00000000 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpDrawer.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import { createWalletTopUpCheckoutRouteDefinition } from "@arrhes/application-metadata/routes" -import { Button, ButtonOutlineContent, InputText, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" -import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" -import { parseEuroAmountToCents } from "../../../../../utilities/parseEuroAmountToCents.ts" - -export function WalletTopUpDrawer(props: { children: JSX.Element; onSuccess: () => void }) { - const [open, setOpen] = useState(false) - const [amount, setAmount] = useState("25") - const [isLoading, setIsLoading] = useState(false) - - async function handleTopUp() { - const amountInCents = parseEuroAmountToCents(amount) - - if (Number.isNaN(amountInCents) || amountInCents <= 0) { - toast({ - title: "Montant invalide", - variant: "error", - }) - return - } - - setIsLoading(true) - const response = await getResponseBodyFromAPI({ - routeDefinition: createWalletTopUpCheckoutRouteDefinition, - body: { - amountInCents, - }, - }) - setIsLoading(false) - - if (response.ok === false) { - toast({ - title: "Impossible de démarrer le rechargement", - variant: "error", - }) - return - } - - props.onSuccess() - window.location.href = response.data.checkoutUrl - } - - return ( - - {props.children} - - - -
-

- Ajoutez un solde disponible immédiatement pour payer les achats ponctuels et les avances sur - abonnement. -

- setAmount(value ?? "")} - type="number" - placeholder="Montant en €" - /> - -
-
-
-
- ) -} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalDrawer.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalDrawer.tsx deleted file mode 100644 index 30d96d2b..00000000 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalDrawer.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { createWalletWithdrawalRouteDefinition } from "@arrhes/application-metadata/routes" -import { Button, ButtonOutlineContent, InputText, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconMinus } from "@tabler/icons-react" -import { type JSX, useEffect, useState } from "react" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" -import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" -import { parseEuroAmountToCents } from "../../../../../utilities/parseEuroAmountToCents.ts" - -export function WalletWithdrawalDrawer(props: { - children: JSX.Element - currentBalanceInCents: number - hasWithdrawalThisMonth: boolean - onSuccess: () => void -}) { - const [open, setOpen] = useState(false) - const [amount, setAmount] = useState("") - const [isLoading, setIsLoading] = useState(false) - - useEffect(() => { - if (open) { - setAmount((props.currentBalanceInCents / 100).toFixed(2).replace(".", ",")) - } - }, [ - open, - props.currentBalanceInCents, - ]) - - async function handleWithdrawal() { - const amountInCents = parseEuroAmountToCents(amount) - - if (Number.isNaN(amountInCents) || amountInCents <= 0) { - toast({ - title: "Montant invalide", - variant: "error", - }) - return - } - - setIsLoading(true) - const response = await getResponseBodyFromAPI({ - routeDefinition: createWalletWithdrawalRouteDefinition, - body: { - amountInCents, - }, - }) - setIsLoading(false) - - if (response.ok === false) { - toast({ - title: response.error?.cause ?? "Impossible d'initier le retrait", - variant: "error", - }) - return - } - - toast({ - title: "Retrait demandé", - variant: "success", - }) - setOpen(false) - props.onSuccess() - } - - return ( - - {props.children} - - - -
-

- Le retrait est effectué par remboursement Mollie depuis un rechargement compatible déjà - payé. -

-

- Un seul retrait portefeuille est autorisé par mois calendaire pour limiter les abus. -

- setAmount(value ?? "")} - type="number" - placeholder="Montant en €" - /> - -
-
-
-
- ) -} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx index 3f83d50c..f0b7dfa4 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx @@ -1,21 +1,15 @@ -import { - readAllOrganizationPaymentsRouteDefinition, - readOneOrganizationRouteDefinition, -} from "@arrhes/application-metadata/routes" +import { readOneOrganizationRouteDefinition } from "@arrhes/application-metadata/routes" import { FREE_STORAGE_BYTES, STORAGE_PRICE_PER_GB_IN_CENTS } from "@arrhes/application-metadata/utilities" import { Button, ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconAlertTriangle, IconCashMinus, IconPigMoney, IconPlus, IconWallet } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { useState } from "react" import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../../components/layouts/settingsSection/settingsSection.tsx" -import { organizationBillingRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.js" import { formatEuros } from "../../../../../utilities/formatEuros.tsx" import { OrganizationBillingDisclaimerBanner } from "./OrganizationBillingDisclaimerBanner.tsx" -import { WalletTopUpDrawer } from "./WalletTopUpDrawer.tsx" -import { WalletWithdrawalDrawer } from "./WalletWithdrawalDrawer.tsx" import { WalletCurrentMonth } from "./walletCurrentMonth.tsx" function getRecurringStorageAmountInCents(storageLimit: number) { @@ -29,39 +23,22 @@ function getNextMonthSubscriptionAmountInCents(organization: { licenceAmount: nu return organization.licenceAmount + getRecurringStorageAmountInCents(organization.storageLimit) } -function hasCurrentMonthWithdrawal( - payments: Array<{ - category: string - createdAt: string - status: string - }>, -) { - const now = new Date() - - return payments.some((payment) => { - if (payment.category !== "withdrawal" || payment.status === "failed") { - return false - } - - const createdAt = new Date(payment.createdAt) - return createdAt.getUTCFullYear() === now.getUTCFullYear() && createdAt.getUTCMonth() === now.getUTCMonth() - }) -} - -export function OrganizationWalletPage() { - const [refreshKey, setRefreshKey] = useState(0) +export function OrganizationWalletPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { + const { openTab } = useTabs() const params = useParams({ - from: organizationBillingRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( {(organization) => ( @@ -82,7 +59,7 @@ export function OrganizationWalletPage() { return ( <> - + {isWalletShortForNextMonth ? (
- setRefreshKey((key) => key + 1)}> - +
+ ) : null} + + +
+
+ - -
- ) : null} - - {(payments) => ( - - + +
+
- setRefreshKey((key) => key + 1)} - > - - - setRefreshKey((key) => key + 1)} + - - -
-
-
+ Montant disponible + + -
- - - Montant disponible - - - {formatEuros(organization.walletBalanceInCents)} - -
-
+ {formatEuros(organization.walletBalanceInCents)} +
- - )} - +
+ +
+ + Recharger le portefeuille + + +
+

+ Ajoutez un solde disponible immédiatement pour payer les achats ponctuels et les avances sur + abonnement. +

+ setAmount(value ?? "")} + type="number" + placeholder="Montant en €" + /> + +
+
+ + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx new file mode 100644 index 00000000..1e5e3147 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx @@ -0,0 +1,161 @@ +import { + createWalletWithdrawalRouteDefinition, + readAllOrganizationPaymentsRouteDefinition, + readOneOrganizationRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { Button, ButtonOutlineContent, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconMinus } from "@tabler/icons-react" +import { useEffect, useState } from "react" +import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" +import { Page } from "../../../../../components/layouts/page/page.tsx" +import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" +import { parseEuroAmountToCents } from "../../../../../utilities/parseEuroAmountToCents.ts" + +function hasCurrentMonthWithdrawal( + payments: Array<{ + category: string + createdAt: string + status: string + }>, +) { + const now = new Date() + + return payments.some((payment) => { + if (payment.category !== "withdrawal" || payment.status === "failed") { + return false + } + + const createdAt = new Date(payment.createdAt) + return createdAt.getUTCFullYear() === now.getUTCFullYear() && createdAt.getUTCMonth() === now.getUTCMonth() + }) +} + +function WalletWithdrawalForm(props: { currentBalanceInCents: number; hasWithdrawalThisMonth: boolean }) { + const [amount, setAmount] = useState("") + const [isLoading, setIsLoading] = useState(false) + + useEffect(() => { + setAmount((props.currentBalanceInCents / 100).toFixed(2).replace(".", ",")) + }, [ + props.currentBalanceInCents, + ]) + + async function handleWithdrawal() { + const amountInCents = parseEuroAmountToCents(amount) + + if (Number.isNaN(amountInCents) || amountInCents <= 0) { + toast({ + title: "Montant invalide", + variant: "error", + }) + return + } + + setIsLoading(true) + const response = await getResponseBodyFromAPI({ + routeDefinition: createWalletWithdrawalRouteDefinition, + body: { + amountInCents, + }, + }) + setIsLoading(false) + + if (response.ok === false) { + toast({ + title: response.error?.cause ?? "Impossible d'initier le retrait", + variant: "error", + }) + return + } + + toast({ + title: "Retrait demandé", + variant: "success", + }) + } + + return ( +
+

+ Le retrait est effectué par remboursement Mollie depuis un rechargement compatible déjà payé. +

+

+ Un seul retrait portefeuille est autorisé par mois calendaire pour limiter les abus. +

+ setAmount(value ?? "")} + type="number" + placeholder="Montant en €" + /> + +
+ ) +} + +export function WalletWithdrawalPage({ idOrganization }: { idOrganization: string }) { + return ( + + + Retirer du portefeuille + + + + {(organization) => ( + + {(payments) => ( + + )} + + )} + + + + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx index da7b2e66..0f282c8d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx @@ -5,13 +5,15 @@ import { useParams } from "@tanstack/react-router" import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { organizationSecurityRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx" import { DeleteOneOrganization } from "./deleteOneOrganization.tsx" -export function OrganizationSecurityPage() { +export function OrganizationSecurityPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { const params = useParams({ - from: organizationSecurityRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( @@ -19,7 +21,7 @@ export function OrganizationSecurityPage() { {(organization) => { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx index 3059a551..94327cf9 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx @@ -5,13 +5,15 @@ import { useParams } from "@tanstack/react-router" import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { organizationSettingsRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx" import { UpdateOneOrganization } from "./updateOneOrganization.tsx" -export function OrganizationSettingsPage() { +export function OrganizationSettingsPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { const params = useParams({ - from: organizationSettingsRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( @@ -19,7 +21,7 @@ export function OrganizationSettingsPage() { {(organization) => { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx new file mode 100644 index 00000000..38fabc30 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx @@ -0,0 +1,48 @@ +import { IconHome, IconLock } from "@tabler/icons-react" +import { lazy, Suspense } from "react" +import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" + +const OrganizationSettingsPage = lazy(() => + import("./organizationSettingsPage.js").then((m) => ({ + default: m.OrganizationSettingsPage, + })), +) +const OrganizationSecurityPage = lazy(() => + import("./organizationSecurityPage.js").then((m) => ({ + default: m.OrganizationSecurityPage, + })), +) + +export function OrganizationSettingsTabContent(props: { idOrganization: string }) { + return ( + , + content: ( + + + + ), + }, + { + key: "sécurité", + label: "Sécurité", + icon: , + content: ( + + + + ), + }, + ], + }, + }} + /> + ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx index 9311e3ec..5e0af0ac 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx @@ -3,9 +3,10 @@ import { updateOneOrganizationRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../components/forms/formControl.tsx" @@ -14,7 +15,7 @@ import { FormField } from "../../../../components/forms/formField.tsx" import { FormItem } from "../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -22,126 +23,143 @@ export function UpdateOneOrganization(props: { organization: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier l'organisation", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateOneOrganizationRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible de modifier l'organisation", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx new file mode 100644 index 00000000..608f7bd9 --- /dev/null +++ b/packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx @@ -0,0 +1,204 @@ +import { Button, ButtonGhostContent } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { + IconApi, + IconCalendar, + IconChevronRight, + IconCreditCard, + IconRobot, + IconSettings, + IconUsers, +} from "@tabler/icons-react" +import type { ReactNode } from "react" +import { TabLink } from "../../../components/layouts/tabBar/tabLink.js" +import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" + +type NavItem = { + label: string + description: string + icon: ReactNode + args: OpenTabArgs +} + +function NavCard({ item }: { item: NavItem }) { + return ( + + + + ) +} + +export function OrganizationTabContent(props: { idOrganization: string }) { + const items: NavItem[] = [ + { + label: "Exercices", + description: "Ann\u00e9es fiscales et \u00e9critures comptables", + icon: , + args: { + component: "exercices", + props: { + idOrganization: props.idOrganization, + }, + }, + }, + { + label: "Assistant", + description: "Assistant IA comptable", + icon: , + args: { + component: "agent", + props: { + idOrganization: props.idOrganization, + }, + }, + }, + { + label: "Membres", + description: "Utilisateurs et droits d\u2019acc\u00e8s", + icon: , + args: { + component: "membres", + props: { + idOrganization: props.idOrganization, + }, + }, + }, + { + label: "Facturation", + description: "Abonnements, services et paiements", + icon: , + args: { + component: "organisation-facturation", + props: { + idOrganization: props.idOrganization, + }, + }, + }, + { + label: "Param\u00e8tres", + description: "Configuration g\u00e9n\u00e9rale et s\u00e9curit\u00e9", + icon: , + args: { + component: "organisation-param\u00e8tres", + props: { + idOrganization: props.idOrganization, + }, + }, + }, + { + label: "API", + description: "Cl\u00e9s d\u2019acc\u00e8s et documentation", + icon: , + args: { + component: "organisation-api", + props: { + idOrganization: props.idOrganization, + }, + }, + }, + ] + + return ( +
+ {items.map((item) => ( +
+ +
+ ))} +
+ ) +} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx index fa22d598..97b328fd 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx @@ -3,9 +3,10 @@ import { updateOneOrganizationUserRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputToggle, toast } from "@arrhes/ui" +import { Button, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -14,7 +15,7 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -22,91 +23,108 @@ export function UpdateOneOrganizationUser(props: { organizationUser: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier l'utilisateur", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateOneOrganizationUserRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible de modifier l'utilisateur", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx index 8dea24b9..c3857000 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx @@ -3,9 +3,10 @@ import { readAllOrganizationUsersRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputText, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../components/forms/formControl.tsx" @@ -14,7 +15,7 @@ import { FormField } from "../../../../components/forms/formField.tsx" import { FormItem } from "../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -22,115 +23,132 @@ export function CreateOneOrganizationUser(props: { idOrganization: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter l'utilisateur", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: createOneOrganizationUserRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible d'ajouter l'utilisateur", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx index f4a06b2a..0b1360aa 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx @@ -3,14 +3,16 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconUserPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { Page } from "../../../../components/layouts/page/page.tsx" -import { organizationUsersRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx" import { CreateOneOrganizationUser } from "./createOneOrganizationUser.tsx" import { OrganizationUsersListTable } from "./organizationUsersListTable.tsx" -export function OrganizationUsersPage() { +export function OrganizationUsersPage({ idOrganization: idOrganizationProp }: { idOrganization?: string }) { const params = useParams({ - from: organizationUsersRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" return ( @@ -28,14 +30,14 @@ export function OrganizationUsersPage() { alignItems: "center", })} > - + } text="Inviter un collaborateur" /> - + ) diff --git a/packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx b/packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx index 64dce4c2..3c0ae34d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx @@ -1,8 +1,9 @@ import { createOneYearRouteDefinition, readAllYearsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputDate, InputText, toast } from "@arrhes/ui" +import { Button, InputDate, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../components/forms/formControl.tsx" @@ -11,7 +12,7 @@ import { FormField } from "../../../../components/forms/formField.tsx" import { FormItem } from "../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" import { YearSelect } from "./yearSelect.tsx" @@ -20,150 +21,167 @@ export function CreateOneYear(props: { idOrganization: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() const currentDate = new Date() return ( - - {props.children} - - - - , - text: "Ajouter l'exercice", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: createOneYearRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible de créer l'exercice", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/years/yearListTableRow.tsx b/packages/website/src/features/dashboard/$idOrganization/years/yearListTableRow.tsx index 5402bfd1..97f2ae60 100644 --- a/packages/website/src/features/dashboard/$idOrganization/years/yearListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/years/yearListTableRow.tsx @@ -1,9 +1,9 @@ import type { readAllYearsRouteDefinition } from "@arrhes/application-metadata/routes" -import { Chip, formatDate, LinkContent } from "@arrhes/ui" +import { Button, Chip, formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../../components/layouts/listTable/listTable.tsx" -import { LinkButton } from "../../../../components/linkButton.tsx" +import { TabLink } from "../../../../components/layouts/tabBar/tabLink.js" export function YearListTableRow(props: { year: v.InferOutput[number] @@ -38,27 +38,31 @@ export function YearListTableRow(props: { gap: "0.75rem", })} > - - - {props.year.label} - - + +
["id"] }) { +export function YearsListTable(props: { idOrganization: v.InferOutput["id"] }) { return ( @@ -28,14 +30,14 @@ export function YearsPage() { alignItems: "center", })} > - + } text="Ajouter un exercice" />
- +
) diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/updateOneEntryLine.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/updateOneEntryLine.tsx index 05ab7526..72298668 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/updateOneEntryLine.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/updateOneEntryLine.tsx @@ -5,10 +5,10 @@ import { updateOneEntryLineRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputPrice, InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputPrice, InputText, InputToggle, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../components/forms/formControl.tsx" @@ -18,7 +18,7 @@ import { FormItem } from "../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -26,145 +26,104 @@ export function UpdateOneEntryLine(props: { entryLine: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier le mouvement", - }} - onSubmit={async (data) => { - const updateEntryLineResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneEntryLineRouteDefinition, - body: data, - }) - if (updateEntryLineResponse.ok === false) { - toast({ - title: "Impossible de modifier le mouvement", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/createOneEntryLine.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/createOneEntryLine.tsx index f666a077..0bde8c7c 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/createOneEntryLine.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/createOneEntryLine.tsx @@ -5,10 +5,10 @@ import { readOneEntryRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputPrice, InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputPrice, InputText, InputToggle, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -18,7 +18,7 @@ import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -26,150 +26,109 @@ export function CreateOneEntryLine(props: { entry: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter le mouvement", - }} - onSubmit={async (data) => { - const createEntryLineResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneEntryLineRouteDefinition, - body: data, - }) - if (createEntryLineResponse.ok === false) { - toast({ - title: "Impossible d'ajouter le mouvement", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryCategoriesTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryCategoriesTab.tsx index 0da46d8a..55e5db02 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryCategoriesTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryCategoriesTab.tsx @@ -12,7 +12,6 @@ import { useState } from "react" import type * as v from "valibot" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { entryLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../../utilities/invalidateData.js" import type { YearDataKey } from "../../yearDataWrapper.tsx" @@ -24,18 +23,23 @@ const requiredKeys = [ "tags", ] as const satisfies readonly YearDataKey[] -export function EntryCategoriesTab() { +export function EntryCategoriesTab(props: { idYear?: string; idEntry?: string } = {}) { const params = useParams({ - from: entryLayoutRoute.id, - }) + strict: false, + }) as { + idYear?: string + idEntry?: string + } + const idYear = props.idYear ?? params.idYear ?? "" + const idEntry = props.idEntry ?? params.idEntry ?? "" return ( {({ entries, entryTags, tags }) => { - const entry = entries.find((r) => r.id === params.idEntry) + const entry = entries.find((r) => r.id === idEntry) if (entry === undefined) return null return ( @@ -43,7 +47,7 @@ export function EntryCategoriesTab() { entry={entry} entryTags={entryTags} tags={tags} - idYear={params.idYear} + idYear={idYear} /> ) }} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryLinesTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryLinesTab.tsx index 95146fdc..58bc72e0 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryLinesTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryLinesTab.tsx @@ -6,7 +6,6 @@ import { IconEdit, IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import type * as v from "valibot" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { entryLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" import type { YearDataKey } from "../../yearDataWrapper.tsx" import { YearDataWrapper } from "../../yearDataWrapper.tsx" import { CreateOneEntryLine } from "./createOneEntryLine.tsx" @@ -19,21 +18,26 @@ const requiredKeys = [ "accounts", ] as const satisfies readonly YearDataKey[] -export function EntryLinesTab() { +export function EntryLinesTab(props: { idYear?: string; idEntry?: string } = {}) { const params = useParams({ - from: entryLayoutRoute.id, - }) + strict: false, + }) as { + idYear?: string + idEntry?: string + } + const idYear = props.idYear ?? params.idYear ?? "" + const idEntry = props.idEntry ?? params.idEntry ?? "" return ( {({ entries, entryLines: allEntryLines, accounts }) => { - const entry = entries.find((r) => r.id === params.idEntry) + const entry = entries.find((r) => r.id === idEntry) if (entry === undefined) return null - const entryLines = allEntryLines.filter((row) => row.idEntry === params.idEntry) + const entryLines = allEntryLines.filter((row) => row.idEntry === idEntry) const accountsMap = new Map( accounts.map((account) => [ account.id, diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryMetadataTab.tsx index 8c51e84d..52fd0512 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryMetadataTab.tsx @@ -3,7 +3,6 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { entryLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" import type { YearDataKey } from "../../yearDataWrapper.tsx" import { YearDataWrapper } from "../../yearDataWrapper.tsx" @@ -11,18 +10,23 @@ const requiredKeys = [ "entries", ] as const satisfies readonly YearDataKey[] -export function EntryMetadataTab() { +export function EntryMetadataTab(props: { idYear?: string; idEntry?: string } = {}) { const params = useParams({ - from: entryLayoutRoute.id, - }) + strict: false, + }) as { + idYear?: string + idEntry?: string + } + const idYear = props.idYear ?? params.idYear ?? "" + const idEntry = props.idEntry ?? params.idEntry ?? "" return ( {({ entries }) => { - const entry = entries.find((r) => r.id === params.idEntry) + const entry = entries.find((r) => r.id === idEntry) if (entry === undefined) return null return ( diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx index af9e2962..cbd98d30 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx @@ -1,18 +1,51 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { ButtonPlainContent, FormatDate, FormatNull, FormatPrice, FormatText, LinkContent } from "@arrhes/ui" +import { Button, ButtonPlainContent, FormatDate, FormatNull, FormatPrice, FormatText, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import type * as v from "valibot" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { LinkButton } from "../../../../../components/linkButton.tsx" -import { entryLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import type { YearDataKey } from "../../yearDataWrapper.tsx" import { YearDataWrapper } from "../../yearDataWrapper.tsx" import { UpdateOneEntry } from "./updateOneEntry.tsx" -const requiredKeys = [ +export type EntryPageData = { + entry: v.InferOutput + journal: v.InferOutput | null + entryTagLabels: string[] + file: v.InferOutput | null + totalDebit: number + totalCredit: number +} + +// Used by the tab system — receives pre-resolved data from EntryTabContent's YearDataWrapper. +export function EntryPage(props: EntryPageData) { + const { openTab } = useTabs() + + return ( + + openTab({ + component: "fichier", + props: { + idOrganization, + idFile, + }, + }) + } + /> + ) +} + +const routeRequiredKeys = [ "entries", "entryLines", "entryTags", @@ -21,21 +54,23 @@ const requiredKeys = [ "files", ] as const satisfies readonly YearDataKey[] -export function EntryPage() { - const params = useParams({ - from: entryLayoutRoute.id, - }) +// Used by TanStack Router as a standalone route component — resolves data itself via YearDataWrapper. +export function EntryRoutePage() { + const params = useParams({ strict: false }) as { idYear?: string; idEntry?: string } + const idYear = params.idYear ?? "" + const idEntry = params.idEntry ?? "" + const { openTab } = useTabs() return ( {({ entries, entryLines: allEntryLines, entryTags, journals, tags, files }) => { - const entry = entries.find((r) => r.id === params.idEntry) + const entry = entries.find((r) => r.id === idEntry) if (entry === undefined) return null - const entryLines = allEntryLines.filter((row) => row.idEntry === params.idEntry) + const entryLines = allEntryLines.filter((row) => row.idEntry === idEntry) const journal = entry.idJournal !== null ? (journals.find((j) => j.id === entry.idJournal) ?? null) : null const entryTagIds = entryTags.filter((et) => et.idEntry === entry.id).map((et) => et.idTag) @@ -60,6 +95,12 @@ export function EntryPage() { file={file} totalDebit={totalDebit} totalCredit={totalCredit} + onFileClick={(idOrganization, idFile) => + openTab({ + component: "fichier", + props: { idOrganization, idFile }, + }) + } /> ) }} @@ -74,6 +115,7 @@ function EntryInformationsTab(props: { file: v.InferOutput | null totalDebit: number totalCredit: number + onFileClick: (idOrganization: string, idFile: string) => void }) { return ( ) : ( - + )} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx new file mode 100644 index 00000000..05b980ce --- /dev/null +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx @@ -0,0 +1,245 @@ +import { Button, ButtonGhostContent, ButtonOutlineContent, FormatError, formatPrice } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { + IconArrowBackUp, + IconCopyCheck, + IconDatabase, + IconDotsVertical, + IconInfoCircle, + IconList, + IconTag, + IconTrash, +} from "@tabler/icons-react" +import { Suspense, useState } from "react" +import { Banner } from "../../../../../components/layouts/banner.tsx" +import { Page } from "../../../../../components/layouts/page/page.tsx" +import { SubPageContent } from "../../../../../components/layouts/subPageContent.tsx" +import { Popover } from "../../../../../components/overlays/popover/popover.js" +import { compareAmounts } from "../../../../../utilities/compareAmounts.ts" +import type { YearDataKey } from "../../yearDataWrapper.tsx" +import { YearDataWrapper } from "../../yearDataWrapper.tsx" +import { ReverseOneEntry } from "../reverseOneEntry.tsx" +import { DeleteOneEntry } from "./deleteOneEntry.tsx" +import { DuplicateOneEntry } from "./duplicateOneEntry.tsx" +import { EntryCategoriesTab } from "./entryCategoriesTab.tsx" +import { EntryLinesTab } from "./entryLinesTab.tsx" +import { EntryMetadataTab } from "./entryMetadataTab.tsx" +import { EntryPage } from "./entryPage.tsx" +import { UpdateOneEntry } from "./updateOneEntry.tsx" + +const requiredKeys = [ + "entries", + "entryLines", + "entryTags", + "journals", + "tags", + "files", +] as const satisfies readonly YearDataKey[] + +export function EntryTabContent(props: { idOrganization: string; idYear: string; idEntry: string }) { + const [menuOpen, setMenuOpen] = useState(false) + + return ( + + {({ entries, entryLinesByEntryId, entryTagsByEntryId, journalById, tagById, fileById }) => { + const entry = entries.find((r) => r.id === props.idEntry) + + if (entry === undefined) { + return ( + + ) + } + + const entryLines = entryLinesByEntryId.get(props.idEntry) ?? [] + + let totalDebit = 0 + let totalCredit = 0 + + for (const entryLine of entryLines) { + totalDebit += Number(entryLine.debit) + totalCredit += Number(entryLine.credit) + } + + const journal = entry.idJournal !== null ? (journalById.get(entry.idJournal) ?? null) : null + const entryTagLabels = (entryTagsByEntryId.get(entry.id) ?? []) + .map((et) => tagById.get(et.idTag)) + .filter((t): t is NonNullable => t !== undefined) + .map((t) => t.label) + const file = entry.idFile !== null ? (fileById.get(entry.idFile) ?? null) : null + + return ( + + +
+ + } + text="Modifier" + /> + + + + + + + +
setMenuOpen(false)} + > + } + text="Extourner" + className={css({ + width: "100%", + justifyContent: "start", + })} + /> +
+
+ +
setMenuOpen(false)} + > + } + text="Dupliquer" + className={css({ + width: "100%", + justifyContent: "start", + })} + /> +
+
+
+
+ +
+ } + title="Supprimer" + color="danger" + /> +
+
+
+ {entry.idFile !== null ? null : ( + Il manque une pièce justificative. + )} + {compareAmounts({ + a: totalDebit, + b: totalCredit, + }) ? null : ( + + Les montants au débit et au crédit sont différents, veuillez corriger pour pouvoir + valider. ( + {formatPrice({ + price: totalDebit - totalCredit, + })} + ) + + )} + , + content: ( + + + + ), + }, + { + key: "mouvements", + label: "Mouvements", + icon: , + content: ( + + + + ), + }, + { + key: "catégories", + label: "Catégories", + icon: , + content: ( + + + + ), + }, + { + key: "métadonnées", + label: "Métadonnées", + icon: , + content: ( + + + + ), + }, + ], + }, + }} + /> +
+
+ ) + }} +
+ ) +} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx index 8d9dc177..208e1923 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx @@ -3,10 +3,10 @@ import { updateManyEntryLinesRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputText, InputToggle, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -15,7 +15,7 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -23,285 +23,302 @@ export function UpdateManyEntryLines(props: { entry: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier les mouvements", - }} - onSubmit={async (data) => { - const updateManyEntryLinesResponse = await getResponseBodyFromAPI({ - routeDefinition: updateManyEntryLinesRouteDefinition, - body: data, - }) - if (updateManyEntryLinesResponse.ok === false) { - toast({ - title: "Impossible de modifier les mouvements", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx index 18419321..6f91b6b3 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx @@ -6,9 +6,10 @@ import { updateOneEntryRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputDate, InputText, toast } from "@arrhes/ui" +import { Button, InputDate, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -18,176 +19,193 @@ import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" export function UpdateOneEntry(props: { entry: v.InferOutput; children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier l'écriture", - }} - onSubmit={async (data) => { - const updateEntryResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneEntryRouteDefinition, - body: data, - }) - if (updateEntryResponse.ok === false) { - toast({ - title: "Impossible de modifier l'écriture", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx index d1c3a360..3b08f92b 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx @@ -8,7 +8,7 @@ import { readAllTagsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputComboboxMultiple, InputDate, InputSelect, InputText, toast } from "@arrhes/ui" +import { Button, InputComboboxMultiple, InputDate, InputSelect, InputText, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { type JSX, useState } from "react" @@ -22,19 +22,18 @@ import { FormItem } from "../../../../components/forms/formItem.js" import { FormLabel } from "../../../../components/forms/formLabel.js" import { FormRoot } from "../../../../components/forms/formRoot.js" import { InputDataCombobox } from "../../../../components/inputDataCombobox.js" -import { Drawer } from "../../../../components/overlays/drawer/drawer.js" +import { useTabs } from "../../../../contexts/tabs/tabsContext.js" import { applicationRouter } from "../../../../routes/applicationRouter.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.js" import { type EntryTemplateKey, entryTemplates } from "./entryTemplates/entryTemplates.js" -export function CreateOneEntry(props: { +function CreateOneEntryPanel(props: { idOrganization: v.InferOutput["id"] idYear: v.InferOutput["id"] - children: JSX.Element + onClose: () => void }) { - const [open, setOpen] = useState(false) const [selectedTemplate, setSelectedTemplate] = useState("empty") const [isTemplateReady, setIsTemplateReady] = useState(false) const [selectedTags, setSelectedTags] = useState< @@ -55,267 +54,291 @@ export function CreateOneEntry(props: { const isSubmitDisabled = activeTemplate?.hasActionButton === true && isTemplateReady === false return ( - { - setOpen(value) - if (value === false) { - setSelectedTemplate("empty") - setIsTemplateReady(false) - setSelectedTags([]) - } - }} +
- {props.children} - - - - , - text: "Ajouter l'écriture", - isDisabled: isSubmitDisabled, - }} - onSubmit={async (data) => { - const createEntryResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneEntryFromTemplateRouteDefinition, - body: data, - }) - if (createEntryResponse.ok === false) { - toast({ - title: "Impossible d'ajouter l'écriture", - variant: "error", - }) - return false - } - - if (selectedTags.length > 0) { - await Promise.all( - selectedTags.map((tag) => - getResponseBodyFromAPI({ - routeDefinition: addOneEntryTagRouteDefinition, - body: { - idYear: props.idYear, - idEntry: createEntryResponse.data.id, - idTag: tag.key, - }, - }), - ), - ) - } + , + text: "Ajouter l'écriture", + isDisabled: isSubmitDisabled, + }} + onSubmit={async (data) => { + const createEntryResponse = await getResponseBodyFromAPI({ + routeDefinition: createOneEntryFromTemplateRouteDefinition, + body: data, + }) + if (createEntryResponse.ok === false) { + toast({ + title: "Impossible d'ajouter l'écriture", + variant: "error", + }) + return false + } - toast({ - title: "Écriture ajoutée avec succès", - variant: "success", - }) - applicationRouter.navigate({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/écritures/$idEntry", - params: { - idOrganization: props.idOrganization, - idYear: props.idYear, - idEntry: createEntryResponse.data.id, - }, - }) - return true - }} - onCancel={undefined} - onSuccess={async () => { - await Promise.all([ - invalidateData({ - routeDefinition: readAllEntriesRouteDefinition, + if (selectedTags.length > 0) { + await Promise.all( + selectedTags.map((tag) => + getResponseBodyFromAPI({ + routeDefinition: addOneEntryTagRouteDefinition, body: { idYear: props.idYear, + idEntry: createEntryResponse.data.id, + idTag: tag.key, }, }), - invalidateData({ - routeDefinition: readAllEntryTagsRouteDefinition, - body: { - idYear: props.idYear, - }, - }), - ]) + ), + ) + } - setOpen(false) - }} - > - {(form) => ( - - ( - - - - - - - - )} - /> - ( - - - - - - - - )} - /> - ( - - - - ({ - key: journal.id, - label: `(${journal.code}) ${journal.label}`, - })} - /> - - - - )} - /> - ( - - - - ({ - key: file.id, - label: file.reference - ? `${file.name} (${file.reference})` - : file.name, - })} - /> - - - - )} - /> + toast({ + title: "Écriture ajoutée avec succès", + variant: "success", + }) + applicationRouter.navigate({ + to: "/dashboard/organisations/$idOrganization/exercices/$idYear/écritures/$idEntry", + params: { + idOrganization: props.idOrganization, + idYear: props.idYear, + idEntry: createEntryResponse.data.id, + }, + }) + return true + }} + onCancel={undefined} + onSuccess={async () => { + await Promise.all([ + invalidateData({ + routeDefinition: readAllEntriesRouteDefinition, + body: { + idYear: props.idYear, + }, + }), + invalidateData({ + routeDefinition: readAllEntryTagsRouteDefinition, + body: { + idYear: props.idYear, + }, + }), + ]) + + props.onClose() + }} + > + {(form) => ( + + ( - ({ - key: tag.id, - label: tag.label, - })) - } - selectedOptions={selectedTags} - onChange={setSelectedTags} - loading={tagsResponse.isPending} + + + + + + )} + /> + ( + + + + + + - - - - Choisir un modèle - - { - const newValue = value ?? "empty" - setSelectedTemplate(newValue) - setIsTemplateReady(false) - form.setValue("entryLines", []) + )} + /> + ( + + + + ({ - key: template.key, - label: template.label, - }))} - placeholder="Sélectionner un modèle" - /> - - {activeTemplate === undefined || activeTemplate.key === "empty" ? null : ( -
({ + key: journal.id, + label: `(${journal.code}) ${journal.label}`, })} - > - {activeTemplate?.formComponent({ - form, - idOrganization: props.idOrganization, + /> + + + + )} + /> + ( + + + + ({ + key: file.id, + label: file.reference ? `${file.name} (${file.reference})` : file.name, })} -
- )} -
-
- )} -
-
-
- + /> + + + + )} + /> + + + ({ + key: tag.id, + label: tag.label, + })) + } + selectedOptions={selectedTags} + onChange={setSelectedTags} + loading={tagsResponse.isPending} + /> + + + + + Choisir un modèle + + { + const newValue = value ?? "empty" + setSelectedTemplate(newValue) + setIsTemplateReady(false) + form.setValue("entryLines", []) + }} + options={entryTemplates.map((template) => ({ + key: template.key, + label: template.label, + }))} + placeholder="Sélectionner un modèle" + /> + + {activeTemplate === undefined || activeTemplate.key === "empty" ? null : ( +
+ {activeTemplate?.formComponent({ + form, + idOrganization: props.idOrganization, + idYear: props.idYear, + onTemplateReadyChange: setIsTemplateReady, + })} +
+ )} +
+ + )} + +
+ ) +} + +export function CreateOneEntry(props: { + idOrganization: v.InferOutput["id"] + idYear: v.InferOutput["id"] + children: JSX.Element +}) { + const { openPanelTab, closeTab } = useTabs() + + return ( + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx index 0ffecbd4..6d7102cc 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx @@ -2,10 +2,10 @@ import { Button, ButtonGhostContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconDotsVertical, IconDownload, IconFileExport, IconFileImport, IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { Fragment, useState } from "react" +import { Fragment } from "react" import { Page } from "../../../../components/layouts/page/page.js" import { Popover } from "../../../../components/overlays/popover/popover.js" -import { entriesRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.js" +import { useTabs } from "../../../../contexts/tabs/tabsContext.js" import { YearDataWrapper } from "../yearDataWrapper.tsx" import { CreateOneEntry } from "./createOneEntry.js" import { EntriesTable } from "./entriesTable.js" @@ -13,19 +13,28 @@ import { ExportEntryLines } from "./exportEntryLines.js" import { ExportFecFile } from "./exportFecFile.js" import { ImportFecFile } from "./importFecFile.js" -export function EntriesPage() { +export function EntriesPage({ + idOrganization: idOrganizationProp, + idYear: idYearProp, +}: { + idOrganization?: string + idYear?: string +}) { const params = useParams({ - from: entriesRoute.id, - }) - const [exportOpen, setExportOpen] = useState(false) - const [fecOpen, setFecOpen] = useState(false) - const [importFecOpen, setImportFecOpen] = useState(false) + strict: false, + }) as { + idOrganization?: string + idYear?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" + const idYear = idYearProp ?? params.idYear ?? "" + const { openPanelTab, closeTab } = useTabs() return ( setExportOpen(true)} + onClick={() => { + const r = { + current: "", + } + r.current = openPanelTab( + "Exporter les mouvements", + closeTab(r.current)} + />, + ) + }} > } @@ -85,7 +108,21 @@ export function EntriesPage() { className={css({ width: "100%", })} - onClick={() => setFecOpen(true)} + onClick={() => { + const r = { + current: "", + } + r.current = openPanelTab( + "Exporter au format FEC", + closeTab(r.current)} + />, + ) + }} > } @@ -102,7 +139,20 @@ export function EntriesPage() { className={css({ width: "100%", })} - onClick={() => setImportFecOpen(true)} + onClick={() => { + const r = { + current: "", + } + r.current = openPanelTab( + "Importer un FEC", + closeTab(r.current)} + />, + ) + }} > } @@ -117,8 +167,8 @@ export function EntriesPage() { + ), filterFn: "includesString", }, @@ -188,15 +127,19 @@ export function EntriesTable(props: { const file = filesMap.get(row.original.idFile) if (!file) return return ( - - {file.name} - + + ) }, filterFn: "includesString", diff --git a/packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx b/packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx index 8b592d55..f13fe17b 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx @@ -6,6 +6,7 @@ import { } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { formatDate, formatPrice, InputDate, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconDownload } from "@tabler/icons-react" import { useMemo } from "react" import * as v from "valibot" @@ -17,7 +18,6 @@ import { FormItem } from "../../../../components/forms/formItem.js" import { FormLabel } from "../../../../components/forms/formLabel.js" import { FormRoot } from "../../../../components/forms/formRoot.js" import { InputDataCombobox } from "../../../../components/inputDataCombobox.js" -import { Drawer } from "../../../../components/overlays/drawer/drawer.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" export function ExportEntryLines(props: { @@ -25,8 +25,7 @@ export function ExportEntryLines(props: { idYear: v.InferOutput["id"] entries: v.InferOutput entryLines: v.InferOutput - open: boolean - onOpenChange: (open: boolean) => void + onClose: () => void }) { const entriesMap = useMemo(() => { return new Map( @@ -47,270 +46,266 @@ export function ExportEntryLines(props: { } return ( - - - - - , - text: "Exporter en CSV", - }} - onSubmit={async (data) => { - const filteredRows = props.entryLines.filter((row) => { - const entry = entriesMap.get(row.idEntry) - if (!entry) return false + , + text: "Exporter en CSV", + }} + onSubmit={async (data) => { + const filteredRows = props.entryLines.filter((row) => { + const entry = entriesMap.get(row.idEntry) + if (!entry) return false - if (data.idJournal && entry.idJournal !== data.idJournal) return false - if (data.idAccount && row.idAccount !== data.idAccount) return false - if (data.dateFrom && entry.date < data.dateFrom) return false - if (data.dateTo && entry.date > data.dateTo) return false + if (data.idJournal && entry.idJournal !== data.idJournal) return false + if (data.idAccount && row.idAccount !== data.idAccount) return false + if (data.dateFrom && entry.date < data.dateFrom) return false + if (data.dateTo && entry.date > data.dateTo) return false - return true - }) + return true + }) - if (filteredRows.length === 0) { - toast({ - title: "Aucun mouvement à exporter", - variant: "warning", - }) - return false - } + if (filteredRows.length === 0) { + toast({ + title: "Aucun mouvement à exporter", + variant: "warning", + }) + return false + } - const accountsResponse = await getResponseBodyFromAPI({ - routeDefinition: readAllAccountsRouteDefinition, - body: { - idYear: props.idYear, - }, - }) - const journalsResponse = await getResponseBodyFromAPI({ - routeDefinition: readAllJournalsRouteDefinition, - body: { - idYear: props.idYear, - }, - }) + const accountsResponse = await getResponseBodyFromAPI({ + routeDefinition: readAllAccountsRouteDefinition, + body: { + idYear: props.idYear, + }, + }) + const journalsResponse = await getResponseBodyFromAPI({ + routeDefinition: readAllJournalsRouteDefinition, + body: { + idYear: props.idYear, + }, + }) - if (!accountsResponse.ok || !journalsResponse.ok) { - toast({ - title: "Impossible de charger les données", - variant: "error", - }) - return false - } + if (!accountsResponse.ok || !journalsResponse.ok) { + toast({ + title: "Impossible de charger les données", + variant: "error", + }) + return false + } - const accountsMap = new Map( - accountsResponse.data.map((a) => [ - a.id, - { - number: a.number, - label: a.label, - }, - ]), - ) - const journalsMap = new Map( - journalsResponse.data.map((j) => [ - j.id, - { - code: j.code, - label: j.label, - }, - ]), - ) + const accountsMap = new Map( + accountsResponse.data.map((a) => [ + a.id, + { + number: a.number, + label: a.label, + }, + ]), + ) + const journalsMap = new Map( + journalsResponse.data.map((j) => [ + j.id, + { + code: j.code, + label: j.label, + }, + ]), + ) - const headers = [ - "Date", - "Code journal", - "Libellé journal", - "Libellé écriture", - "N° compte", - "Libellé compte", - "Libellé mouvement", - "Débit", - "Crédit", - ] + const headers = [ + "Date", + "Code journal", + "Libellé journal", + "Libellé écriture", + "N° compte", + "Libellé compte", + "Libellé mouvement", + "Débit", + "Crédit", + ] - const rows = filteredRows - .map((row) => { - const entry = entriesMap.get(row.idEntry) - if (!entry) return null + const rows = filteredRows + .map((row) => { + const entry = entriesMap.get(row.idEntry) + if (!entry) return null - const account = accountsMap.get(row.idAccount) - const journal = entry.idJournal ? journalsMap.get(entry.idJournal) : null + const account = accountsMap.get(row.idAccount) + const journal = entry.idJournal ? journalsMap.get(entry.idJournal) : null - return [ - formatDate(entry.date) ?? "", - journal?.code ?? "", - journal?.label ?? "", - entry.label, - account?.number ?? "", - account?.label ?? "", - row.label ?? "", - formatPrice({ - price: row.debit, - }), - formatPrice({ - price: row.credit, - }), - ].map(escapeCsvValue) - }) - .filter((row) => row !== null) + return [ + formatDate(entry.date) ?? "", + journal?.code ?? "", + journal?.label ?? "", + entry.label, + account?.number ?? "", + account?.label ?? "", + row.label ?? "", + formatPrice({ + price: row.debit, + }), + formatPrice({ + price: row.credit, + }), + ].map(escapeCsvValue) + }) + .filter((row) => row !== null) - const csvContent = [ - headers.map(escapeCsvValue).join(";"), - ...rows.map((r) => r.join(";")), - ].join("\n") + const csvContent = [ + headers.map(escapeCsvValue).join(";"), + ...rows.map((r) => r.join(";")), + ].join("\n") - const BOM = "\uFEFF" - const blob = new Blob( - [ - BOM + csvContent, - ], - { - type: "text/csv;charset=utf-8;", - }, - ) - const url = URL.createObjectURL(blob) - const link = document.createElement("a") - link.href = url - link.download = `ecritures-${new Date().toISOString().slice(0, 10)}.csv` - link.click() - URL.revokeObjectURL(url) + const BOM = "\uFEFF" + const blob = new Blob( + [ + BOM + csvContent, + ], + { + type: "text/csv;charset=utf-8;", + }, + ) + const url = URL.createObjectURL(blob) + const link = document.createElement("a") + link.href = url + link.download = `ecritures-${new Date().toISOString().slice(0, 10)}.csv` + link.click() + URL.revokeObjectURL(url) - toast({ - title: `${filteredRows.length} mouvements exportés`, - variant: "success", - }) - return true - }} - onCancel={undefined} - onSuccess={async () => { - props.onOpenChange(false) - }} - > - {(form) => ( - - ( - - - - ({ - key: journal.id, - label: `(${journal.code}) ${journal.label ?? ""}`, - })} - /> - - - - )} - /> - ( - - - - ({ - key: account.id, - label: `${account.number} - ${account.label}`, - })} - /> - - - - )} - /> - ( - - - - - - - - )} - /> - ( - - - - - - - - )} - /> - - )} - - - - + toast({ + title: `${filteredRows.length} mouvements exportés`, + variant: "success", + }) + return true + }} + onCancel={undefined} + onSuccess={async () => { + props.onClose() + }} + > + {(form) => ( + + ( + + + + ({ + key: journal.id, + label: `(${journal.code}) ${journal.label ?? ""}`, + })} + /> + + + + )} + /> + ( + + + + ({ + key: account.id, + label: `${account.number} - ${account.label}`, + })} + /> + + + + )} + /> + ( + + + + + + + + )} + /> + ( + + + + + + + + )} + /> + + )} +
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx b/packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx index 686a3380..3c6fc26f 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx @@ -12,8 +12,8 @@ import { IconFileExport } from "@tabler/icons-react" import { useEffect, useMemo, useState } from "react" import type * as v from "valibot" import { Banner } from "../../../../components/layouts/banner.js" -import { LinkButton } from "../../../../components/linkButton.js" -import { Drawer } from "../../../../components/overlays/drawer/drawer.js" +import { useTabs } from "../../../../contexts/tabs/tabsContext.js" + import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" /** @@ -63,13 +63,12 @@ export function ExportFecFile(props: { idYear: v.InferOutput["id"] entries: v.InferOutput entryLines: v.InferOutput - open: boolean - onOpenChange: (open: boolean) => void + onClose: () => void }) { const [siren, setSiren] = useState(null) + const { openTab } = useTabs() useEffect(() => { - if (!props.open) return getResponseBodyFromAPI({ routeDefinition: readOneOrganizationRouteDefinition, body: { @@ -82,7 +81,6 @@ export function ExportFecFile(props: { }) }, [ props.idOrganization, - props.open, ]) const entriesMap = useMemo(() => { @@ -240,106 +238,101 @@ export function ExportFecFile(props: { title: `${sortedRows.length} mouvements exportés au format FEC`, variant: "success", }) - props.onOpenChange(false) + props.onClose() } return ( - - - - -
+ Le Fichier des Écritures Comptables (FEC) est un export normé de toutes les écritures de l'exercice, au + format requis par l'administration fiscale. +

+

+ Nous avons créé également un outil de validation de conformité du FEC, disponible gratuitement en ligne + sur{" "} + + fec.arrhes.com + + . +

+ {siren === "" && ( + + Le numéro SIREN de l'organisation n'est pas renseigné. Le nom du fichier FEC ne sera pas conforme. + Vous pouvez l'ajouter dans les{" "} + -
-
-
-
+ paramètres de l'organisation + + + . + + )} +

+ {props.entries.length} écriture{props.entries.length > 1 ? "s" : ""} - {props.entryLines.length}{" "} + mouvement{props.entryLines.length > 1 ? "s" : ""} +

+ + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/importFecFile.tsx b/packages/website/src/features/dashboard/$idYear/entries/importFecFile.tsx index 002d80ed..3b79c4db 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/importFecFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/importFecFile.tsx @@ -13,7 +13,6 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconFileImport } from "@tabler/icons-react" import { useMemo, useState } from "react" import type * as v from "valibot" -import { Drawer } from "../../../../components/overlays/drawer/drawer.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" @@ -236,8 +235,7 @@ export function ImportFecFile(props: { idYear: v.InferOutput["id"] journals: v.InferOutput accounts: v.InferOutput - open: boolean - onOpenChange: (open: boolean) => void + onClose: () => void }) { const [selectedFile, setSelectedFile] = useState(null) @@ -429,115 +427,101 @@ export function ImportFecFile(props: { }) setSelectedFile(null) - props.onOpenChange(false) + props.onClose() } return ( - { - props.onOpenChange(open) - if (open === false) { - setSelectedFile(null) - } - }} +
- - - -
-

- Importez un FEC pour créer automatiquement les journaux, comptes, écritures et mouvements - manquants de l'exercice. -

-

- Nous avons créé également un outil de validation de conformité du FEC, disponible - gratuitement en ligne sur{" "} - - fec.arrhes.com - - . -

- { - if (file === undefined) { - setSelectedFile(null) - return - } - setSelectedFile(file) - }} - /> -

- Format supporté: fichier texte FEC avec séparateur tabulation ou "|". -

-

- {selectedFileLabel} -

- -

- Le contrôle de compatibilité vérifie les colonnes requises et l'équilibre débit/crédit de - chaque écriture. -

-
-
-
- +

+ Importez un FEC pour créer automatiquement les journaux, comptes, écritures et mouvements manquants de + l'exercice. +

+

+ Nous avons créé également un outil de validation de conformité du FEC, disponible gratuitement en ligne + sur{" "} + + fec.arrhes.com + + . +

+ { + if (file === undefined) { + setSelectedFile(null) + return + } + setSelectedFile(file) + }} + /> +

+ Format supporté: fichier texte FEC avec séparateur tabulation ou "|". +

+

+ {selectedFileLabel} +

+ +

+ Le contrôle de compatibilité vérifie les colonnes requises et l'équilibre débit/crédit de chaque + écriture. +

+
) } diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx index 41082ed5..27781d92 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx @@ -3,18 +3,19 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" import { FileData } from "./fileData.tsx" -export function FileMetadataTab() { +export function FileMetadataTab(props: { idOrganization?: string; idFile?: string } = {}) { const params = useParams({ - from: fileLayoutRoute.id, + strict: false, }) + const idOrganization = props.idOrganization ?? params.idOrganization ?? "" + const idFile = props.idFile ?? params.idFile ?? "" return ( {(file) => { return ( diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx index d8518516..1e1e7dfd 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx @@ -3,18 +3,19 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" import { FileData } from "./fileData.tsx" -export function FilePage() { +export function FilePage(props: { idOrganization?: string; idFile?: string } = {}) { const params = useParams({ - from: fileLayoutRoute.id, + strict: false, }) + const idOrganization = props.idOrganization ?? params.idOrganization ?? "" + const idFile = props.idFile ?? params.idFile ?? "" return ( {(file) => ( + + + {(file) => ( + <> +
+ +
+ } + text="Modifier" + /> +
+
+ +
+ } + title="Supprimer" + color="danger" + /> +
+
+
+ , + content: ( + + + + ), + }, + { + key: "métadonnées", + label: "Métadonnées", + icon: , + content: ( + + + + ), + }, + { + key: "visualisation", + label: "Visualisation", + icon: , + content: ( + + + + ), + }, + ], + }, + }} + /> + + )} +
+
+
+ ) +} diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx index 0430b733..d7fb6f99 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx @@ -1,19 +1,20 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" import { FileData } from "./fileData.tsx" import { FileFile } from "./fileFile.tsx" -export function FileVisualisationTab() { +export function FileVisualisationTab(props: { idOrganization?: string; idFile?: string } = {}) { const params = useParams({ - from: fileLayoutRoute.id, + strict: false, }) + const idOrganization = props.idOrganization ?? params.idOrganization ?? "" + const idFile = props.idFile ?? params.idFile ?? "" return ( {(file) => { return ( diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx index 8a092a21..eee1f021 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx @@ -1,27 +1,43 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { type JSX, useState } from "react" +import { Button } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import type { JSX } from "react" import type * as v from "valibot" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.js" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.js" import { UpdateOneFileForm } from "./updateOneFileForm.js" export function UpdateOneFile(props: { file: v.InferOutput; children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - { + const r = { + current: "", + } + r.current = openPanelTab( + "Modifier le fichier", +
+ closeTab(r.current)} + /> +
, + ) + }} > - {props.children} - - - - setOpen(false)} - /> - - -
+ {props.children} + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx b/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx index 219e89f0..2086d799 100644 --- a/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx @@ -1,8 +1,8 @@ import { createOneFolderRouteDefinition, readAllFoldersRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { Button, ButtonOutlineContent, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconFolderPlus } from "@tabler/icons-react" -import { useState } from "react" import type * as v from "valibot" import { FormControl } from "../../../../components/forms/formControl.js" import { FormError } from "../../../../components/forms/formError.js" @@ -10,7 +10,7 @@ import { FormField } from "../../../../components/forms/formField.js" import { FormItem } from "../../../../components/forms/formItem.js" import { FormLabel } from "../../../../components/forms/formLabel.js" import { FormRoot } from "../../../../components/forms/formRoot.js" -import { Drawer } from "../../../../components/overlays/drawer/drawer.js" +import { useTabs } from "../../../../contexts/tabs/tabsContext.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" @@ -18,87 +18,95 @@ export function CreateOneFolder(props: { idOrganization: v.InferOutput["id"] idFolderParent?: string | null }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - - - - - , - text: "Créer le dossier", - }} - onSubmit={async (data) => { - const createResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneFolderRouteDefinition, - body: { - idFolderParent: data.idFolderParent, - name: data.name, - }, - }) - if (createResponse.ok === false) { + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx b/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx index 2e4193b4..de98e7e7 100644 --- a/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx @@ -9,11 +9,10 @@ import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconFileText, IconPencil, IconTrash } from "@tabler/icons-react" import { useState } from "react" import type * as v from "valibot" -import { LinkButton } from "../../../../components/linkButton.js" import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" -import { Drawer } from "../../../../components/overlays/drawer/drawer.js" import { Popover } from "../../../../components/overlays/popover/popover.js" +import { useTabs } from "../../../../contexts/tabs/tabsContext.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" @@ -22,11 +21,11 @@ import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" import { MoveOneFileForm } from "./moveOneFileForm.js" export function FileActions(props: { file: v.InferOutput; idOrganization: string }) { - const [editOpen, setEditOpen] = useState(false) const [moveOpen, setMoveOpen] = useState(false) const [deleteOpen, setDeleteOpen] = useState(false) const [ocrLoading, setOcrLoading] = useState(false) const [ocrTooltipOpen, setOcrTooltipOpen] = useState(false) + const { openPanelTab, closeTab, openTab } = useTabs() const subscription = useDataFromAPI({ routeDefinition: readOrganizationBillingRouteDefinition, @@ -104,12 +103,16 @@ export function FileActions(props: { file: v.InferOutput - + openTab({ + component: "fichier", + props: { + idOrganization: props.idOrganization, + idFile: props.file.id, + }, + }) + } className={css({ width: "100%", })} @@ -122,14 +125,31 @@ export function FileActions(props: { file: v.InferOutput - + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx index 1a424e66..f0de7d46 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx @@ -6,14 +6,24 @@ import { useCallback, useState, useTransition } from "react" import { Box } from "../../../../../components/layouts/box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { accountsRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx" import { AccountsTable } from "./accountsTable.tsx" import { CreateOneAccount } from "./createOneAccount.tsx" -export function AccountsPage() { +export function AccountsPage({ + idOrganization: idOrganizationProp, + idYear: idYearProp, +}: { + idOrganization?: string + idYear?: string +} = {}) { const params = useParams({ - from: accountsRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + idYear?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" + const idYear = idYearProp ?? params.idYear ?? "" const [globalFilter, setGlobalFilter] = useState("") const [, startTransition] = useTransition() @@ -39,8 +49,8 @@ export function AccountsPage() { })} > } @@ -65,8 +75,8 @@ export function AccountsPage() { })} > diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx index d79d9f2c..1606c0e2 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx @@ -1,8 +1,9 @@ import { createOneAccountRouteDefinition, readAllAccountsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputText, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -11,7 +12,7 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" import { BalanceSheetsSelect } from "../balanceSheets/balanceSheetSelect.tsx" @@ -22,263 +23,280 @@ export function CreateOneAccount(props: { idYear: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter le compte", - }} - onSubmit={async (data) => { - const createAccountResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneAccountRouteDefinition, - body: data, - }) - if (createAccountResponse.ok === false) { - toast({ - title: "Impossible d'ajouter le compte", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx index 9827d01b..7d61245f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx @@ -4,9 +4,10 @@ import { updateOneBalanceSheetRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputText, InputToggle, toast } from "@arrhes/ui" +import { css, cx } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../components/forms/formControl.tsx" @@ -15,7 +16,7 @@ import { FormField } from "../../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" import { BalanceSheetsSelect } from "../balanceSheetSelect.tsx" @@ -23,164 +24,185 @@ import { BalanceSheetsSelect } from "../balanceSheetSelect.tsx" export function UpdateOneBalanceSheet(props: { balanceSheet: v.InferOutput children: JSX.Element + className?: string }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier la ligne de bilan", - }} - onSubmit={async (data) => { - const updateBalanceSheetResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneBalanceSheetRouteDefinition, - body: data, - }) - if (updateBalanceSheetResponse.ok === false) { - toast({ - title: "Impossible de modifier la ligne de bilan", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx index 1e879a3e..459853e2 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx @@ -2,8 +2,8 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { css } from "@arrhes/ui/utilities/cn.js" import type { ComponentProps } from "react" import type * as v from "valibot" -import { LinkButton } from "../../../../../components/linkButton.tsx" import { ACCOUNT_ITEM_HEIGHT, INDENT_PER_LEVEL } from "../accounts/accountItem.tsx" +import { UpdateOneBalanceSheet } from "./$idBalanceSheet/updateOneBalanceSheet.tsx" export function BalanceSheetRow(props: { idOrganization: v.InferOutput["id"] @@ -13,13 +13,8 @@ export function BalanceSheetRow(props: { className?: ComponentProps<"div">["className"] }) { return ( - - + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx index 7ccba1a3..bdf875f5 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx @@ -7,14 +7,24 @@ import { Box } from "../../../../../components/layouts/box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { balanceSheetsLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsLayoutRoute.tsx" import { BalanceSheetTable } from "./balanceSheetTable.tsx" import { CreateOneBalanceSheet } from "./createOneBalanceSheet.tsx" -export function BalanceSheetsPage() { +export function BalanceSheetsPage({ + idOrganization: idOrganizationProp, + idYear: idYearProp, +}: { + idOrganization?: string + idYear?: string +} = {}) { const params = useParams({ - from: balanceSheetsLayoutRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + idYear?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" + const idYear = idYearProp ?? params.idYear ?? "" const [globalFilter, setGlobalFilter] = useState("") const [, startTransition] = useTransition() const pathname = useRouterState({ @@ -40,8 +50,8 @@ export function BalanceSheetsPage() { icon: , to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/bilan/actif", params: { - idOrganization: params.idOrganization, - idYear: params.idYear, + idOrganization: idOrganization, + idYear: idYear, }, }, { @@ -49,8 +59,8 @@ export function BalanceSheetsPage() { icon: , to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/bilan/passif", params: { - idOrganization: params.idOrganization, - idYear: params.idYear, + idOrganization: idOrganization, + idYear: idYear, }, }, ]} @@ -68,8 +78,8 @@ export function BalanceSheetsPage() { })} > } @@ -97,8 +107,8 @@ export function BalanceSheetsPage() { })} > diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx index 8e032029..0986313c 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx @@ -3,9 +3,10 @@ import { readAllBalanceSheetsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputText, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -14,7 +15,7 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" import { BalanceSheetsSelect } from "./balanceSheetSelect.tsx" @@ -24,155 +25,172 @@ export function CreateOneBalanceSheet(props: { idYear: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter la ligne de bilan", - }} - onSubmit={async (data) => { - const createBalanceSheetResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneBalanceSheetRouteDefinition, - body: data, - }) - if (createBalanceSheetResponse.ok === false) { - toast({ - title: "Impossible d'ajouter la ligne de bilan", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx index dd44c2e1..81399896 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx @@ -4,7 +4,7 @@ import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" -import { applicationRouter } from "../../../../routes/applicationRouter.tsx" +import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -12,6 +12,8 @@ export function DeleteOneYear(props: { year: v.InferOutput children: ReactElement> }) { + const { openTab } = useTabs() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneYearRouteDefinition, @@ -38,12 +40,17 @@ export function DeleteOneYear(props: { variant: "success", }) - applicationRouter.navigate({ - to: "/dashboard/organisations/$idOrganization/exercices", - params: { - idOrganization: props.year.idOrganization, + openTab( + { + component: "exercices", + props: { + idOrganization: props.year.idOrganization, + }, }, - }) + { + newTab: true, + }, + ) } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx index a4b76782..93bcad62 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx @@ -4,9 +4,10 @@ import { updateOneIncomeStatementRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css, cx } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../components/forms/formControl.tsx" @@ -16,151 +17,172 @@ import { FormItem } from "../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" export function UpdateOneIncomeStatement(props: { incomeStatement: v.InferOutput children: JSX.Element + className?: string }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier la ligne de compte de résultat", - }} - onSubmit={async (data) => { - const updateIncomeStatementResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneIncomeStatementRouteDefinition, - body: data, - }) - if (updateIncomeStatementResponse.ok === false) { - toast({ - title: "Impossible de modifier la ligne de compte de résultat", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx index 4e08765c..b70fcef4 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx @@ -5,9 +5,10 @@ import { updateOneComputationIncomeStatementRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputToggle, toast } from "@arrhes/ui" +import { Button, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../../../../components/forms/formControl.tsx" @@ -17,7 +18,7 @@ import { FormItem } from "../../../../../../../../../components/forms/formItem.t import { FormLabel } from "../../../../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../../../utilities/invalidateData.ts" @@ -25,133 +26,150 @@ export function UpdateOneComputationIncomeStatement(props: { computationIncomeStatement: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier le terme du calcul", - }} - onSubmit={async (data) => { - const updateComputationIncomeStatementResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneComputationIncomeStatementRouteDefinition, - body: data, - }) - if (updateComputationIncomeStatementResponse.ok === false) { - toast({ - title: "Impossible de modifier le terme du calcul", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx index df4d71d7..f165f10d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx @@ -4,9 +4,10 @@ import { readAllIncomeStatementsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputToggle, toast } from "@arrhes/ui" +import { Button, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../../../components/forms/formControl.tsx" @@ -16,7 +17,7 @@ import { FormItem } from "../../../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../../utilities/invalidateData.ts" @@ -24,124 +25,141 @@ export function CreateOneComputationIncomeStatement(props: { computation: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter le terme du calcul", - }} - onSubmit={async (data) => { - const createComputationIncomeStatementResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneComputationIncomeStatementRouteDefinition, - body: data, - }) - if (createComputationIncomeStatementResponse.ok === false) { - toast({ - title: "Impossible d'ajouter le terme du calcul", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx index a67a457a..e728f3b1 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx @@ -4,9 +4,10 @@ import { updateOneComputationRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../../components/forms/formControl.tsx" @@ -15,7 +16,7 @@ import { FormField } from "../../../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../utilities/invalidateData.ts" @@ -23,115 +24,132 @@ export function UpdateOneComputation(props: { computation: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier la ligne de calcul", - }} - onSubmit={async (data) => { - const updateComputationResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneComputationRouteDefinition, - body: data, - }) - if (updateComputationResponse.ok === false) { - toast({ - title: "Impossible de modifier la ligne de calcul", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx index dfafe27f..ee4113fd 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx @@ -3,9 +3,10 @@ import { readAllComputationsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../components/forms/formControl.tsx" @@ -14,7 +15,7 @@ import { FormField } from "../../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -23,105 +24,122 @@ export function CreateOneComputation(props: { idYear: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter la ligne de calcul", - }} - onSubmit={async (data) => { - const createComputationResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneComputationRouteDefinition, - body: data, - }) - if (createComputationResponse.ok === false) { - toast({ - title: "Impossible d'ajouter la ligne de calcul", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx index 1c941156..085962ca 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx @@ -3,9 +3,10 @@ import { readAllIncomeStatementsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -15,7 +16,7 @@ import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" import { InputDataCombobox } from "../../../../../components/inputDataCombobox.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -24,134 +25,151 @@ export function CreateOneIncomeStatement(props: { idYear: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter la ligne de compte de résultat", - }} - onSubmit={async (data) => { - const createIncomeStatementResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneIncomeStatementRouteDefinition, - body: data, - }) - if (createIncomeStatementResponse.ok === false) { - toast({ - title: "Impossible d'ajouter la ligne de compte de résultat", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx index b67a95d2..3b3a2b8f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx @@ -2,8 +2,8 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { css } from "@arrhes/ui/utilities/cn.js" import type { ComponentProps } from "react" import type * as v from "valibot" -import { LinkButton } from "../../../../../components/linkButton.tsx" import { ACCOUNT_ITEM_HEIGHT, INDENT_PER_LEVEL } from "../accounts/accountItem.tsx" +import { UpdateOneIncomeStatement } from "./$idIncomeStatement/updateOneIncomeStatement.tsx" export function IncomeStatementRow(props: { idOrganization: v.InferOutput["id"] @@ -13,13 +13,8 @@ export function IncomeStatementRow(props: { className?: ComponentProps<"div">["className"] }) { return ( - - + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx index fb6196d0..2a584f8d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx @@ -6,14 +6,24 @@ import { useCallback, useState, useTransition } from "react" import { Box } from "../../../../../components/layouts/box.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { incomeStatementsLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx" import { CreateOneIncomeStatement } from "./createOneIncomeStatement.tsx" import { IncomeStatementsTable } from "./incomeStatementsTable.tsx" -export function IncomeStatementsPage() { +export function IncomeStatementsPage({ + idOrganization: idOrganizationProp, + idYear: idYearProp, +}: { + idOrganization?: string + idYear?: string +} = {}) { const params = useParams({ - from: incomeStatementsLayoutRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + idYear?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" + const idYear = idYearProp ?? params.idYear ?? "" const [globalFilter, setGlobalFilter] = useState("") const [, startTransition] = useTransition() @@ -33,8 +43,8 @@ export function IncomeStatementsPage() { icon: , to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/compte-de-résultat", params: { - idOrganization: params.idOrganization, - idYear: params.idYear, + idOrganization: idOrganization, + idYear: idYear, }, }, { @@ -42,8 +52,8 @@ export function IncomeStatementsPage() { icon: , to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/compte-de-résultat/calculs", params: { - idOrganization: params.idOrganization, - idYear: params.idYear, + idOrganization: idOrganization, + idYear: idYear, }, }, ]} @@ -61,8 +71,8 @@ export function IncomeStatementsPage() { })} > } @@ -88,8 +98,8 @@ export function IncomeStatementsPage() { })} > diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx index 43b5dd3a..bd53185c 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx @@ -4,9 +4,10 @@ import { updateOneJournalRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../components/forms/formControl.tsx" @@ -15,7 +16,7 @@ import { FormField } from "../../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -23,115 +24,132 @@ export function UpdateOneJournal(props: { journal: v.InferOutput children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier le journal", - }} - onSubmit={async (data) => { - const updateJournalResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneJournalRouteDefinition, - body: data, - }) - if (updateJournalResponse.ok === false) { - toast({ - title: "Impossible de modifier le journal", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx index 6aeecce4..8044972a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx @@ -1,8 +1,9 @@ import { createOneJournalRouteDefinition, readAllJournalsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -11,7 +12,7 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -20,105 +21,122 @@ export function CreateOneJournal(props: { idYear: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter le journal", - }} - onSubmit={async (data) => { - const createJournalResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneJournalRouteDefinition, - body: data, - }) - if (createJournalResponse.ok === false) { - toast({ - title: "Impossible d'ajouter le journal", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx index 622fe58a..c6c7f682 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx @@ -3,7 +3,7 @@ import { Chip, formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { LinkButton } from "../../../../../components/linkButton.tsx" +import { UpdateOneJournal } from "./$idJournal/updateOneJournal.tsx" export function JournalListTableRow(props: { journal: v.InferOutput }) { const createdAt = formatDate(props.journal.createdAt) @@ -35,14 +35,7 @@ export function JournalListTableRow(props: { journal: v.InferOutput - + {props.journal.label ?? undefined} - +
@@ -28,8 +38,8 @@ export function JournalsPage() { })} > } @@ -38,8 +48,8 @@ export function JournalsPage() {
diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx index 6d5efb55..4713150f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx @@ -4,9 +4,10 @@ import { updateOneTagRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../../components/forms/formControl.tsx" @@ -15,99 +16,116 @@ import { FormField } from "../../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" export function UpdateOneTag(props: { tag: v.InferOutput; children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier la catégorie", - }} - onSubmit={async (data) => { - const updateTagResponse = await getResponseBodyFromAPI({ - routeDefinition: updateOneTagRouteDefinition, - body: data, - }) - if (updateTagResponse.ok === false) { - toast({ - title: "Impossible de modifier la catégorie", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx index 8dfcdf41..44ea320b 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx @@ -1,8 +1,9 @@ import { createOneTagRouteDefinition, readAllTagsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputText, toast } from "@arrhes/ui" +import { Button, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../../components/forms/formControl.tsx" @@ -11,7 +12,7 @@ import { FormField } from "../../../../../components/forms/formField.tsx" import { FormItem } from "../../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -20,84 +21,101 @@ export function CreateOneTag(props: { idYear: v.InferOutput["id"] children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter la catégorie", - }} - onSubmit={async (data) => { - const createTagResponse = await getResponseBodyFromAPI({ - routeDefinition: createOneTagRouteDefinition, - body: data, - }) - if (createTagResponse.ok === false) { - toast({ - title: "Impossible d'ajouter la catégorie", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx index a549d1c8..95abda3a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx @@ -3,7 +3,7 @@ import { formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { LinkButton } from "../../../../../components/linkButton.tsx" +import { UpdateOneTag } from "./$idTag/updateOneTag.tsx" export function TagListTableRow(props: { tag: v.InferOutput }) { const createdAt = formatDate(props.tag.createdAt) @@ -35,14 +35,7 @@ export function TagListTableRow(props: { tag: v.InferOutput gap: "0.75rem", })} > - + > {props.tag.label ?? undefined} - +
@@ -28,8 +38,8 @@ export function TagsPage() { })} > } @@ -38,8 +48,8 @@ export function TagsPage() {
diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx index 3a1e1d51..c0169c2d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx @@ -1,8 +1,9 @@ import { readOneYearRouteDefinition, updateOneYearRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { InputDate, InputText, toast } from "@arrhes/ui" +import { Button, InputDate, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { FormControl } from "../../../../components/forms/formControl.tsx" @@ -11,153 +12,170 @@ import { FormField } from "../../../../components/forms/formField.tsx" import { FormItem } from "../../../../components/forms/formItem.tsx" import { FormLabel } from "../../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" import { YearSelect } from "../../$idOrganization/years/yearSelect.tsx" export function UpdateOneYear(props: { year: v.InferOutput; children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Modifier l'exercice", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateOneYearRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible de modifier l'exercice", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx index 8face1c0..671f92e0 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx @@ -6,14 +6,25 @@ import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { PageRoot } from "../../../../components/layouts/page/pageRoot.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { yearSettingsRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx" import { DeleteOneYear } from "./deleteOneYear.tsx" import { UpdateOneYear } from "./updateOneYear.tsx" -export function YearSettingsPage() { +export function YearSettingsPage({ + idOrganization: idOrganizationProp, + idYear: idYearProp, +}: { + idOrganization?: string + idYear?: string +} = {}) { const params = useParams({ - from: yearSettingsRoute.id, - }) + strict: false, + }) as { + idOrganization?: string + idYear?: string + } + const idOrganization = idOrganizationProp ?? params.idOrganization ?? "" + const idYear = idYearProp ?? params.idYear ?? "" + void idOrganization return ( @@ -21,7 +32,7 @@ export function YearSettingsPage() { {(year) => { diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx new file mode 100644 index 00000000..a46933e5 --- /dev/null +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx @@ -0,0 +1,143 @@ +import { + IconBook, + IconFileReport, + IconHome, + IconListNumbers, + IconReportMoney, + IconScale, + IconSettings, + IconTag, +} from "@tabler/icons-react" +import { lazy, Suspense } from "react" +import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" + +const YearSettingsPage = lazy(() => + import("./yearSettingsPage.js").then((m) => ({ + default: m.YearSettingsPage, + })), +) +const AccountsPage = lazy(() => + import("./accounts/accountsPage.js").then((m) => ({ + default: m.AccountsPage, + })), +) +const JournalsPage = lazy(() => + import("./journals/journalsPage.js").then((m) => ({ + default: m.JournalsPage, + })), +) +const TagsPage = lazy(() => + import("./tags/tagsPage.js").then((m) => ({ + default: m.TagsPage, + })), +) +const BalanceSheetsPage = lazy(() => + import("./balanceSheets/balanceSheetsPage.js").then((m) => ({ + default: m.BalanceSheetsPage, + })), +) +const IncomeStatementsPage = lazy(() => + import("./incomeStatements/incomeStatementsPage.js").then((m) => ({ + default: m.IncomeStatementsPage, + })), +) + +export function YearSettingsTabContent(props: { idOrganization: string; idYear: string }) { + return ( + , + items: [ + { + key: "général", + label: "Général", + icon: , + content: ( + + + + ), + }, + { + key: "comptes", + label: "Plan des comptes", + icon: , + content: ( + + + + ), + }, + { + key: "journaux", + label: "Journaux", + icon: , + content: ( + + + + ), + }, + { + key: "catégories", + label: "Catégories", + icon: , + content: ( + + + + ), + }, + ], + }, + documents: { + title: "Documents comptables", + icon: , + items: [ + { + key: "bilan", + label: "Bilan", + icon: , + content: ( + + + + ), + }, + { + key: "compte-de-résultat", + label: "Compte de résultat", + icon: , + content: ( + + + + ), + }, + ], + }, + }} + /> + ) +} diff --git a/packages/website/src/features/dashboard/OrganizationContextSelect.tsx b/packages/website/src/features/dashboard/OrganizationContextSelect.tsx new file mode 100644 index 00000000..c4d1edf8 --- /dev/null +++ b/packages/website/src/features/dashboard/OrganizationContextSelect.tsx @@ -0,0 +1,102 @@ +import { Button, ButtonGhostContent, ButtonPlainContent, Separator } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { getAllMyOrganizationsRouteDefinition } from "../../../../metadata/src/routes/dashboard/auth/index.js" +import { Popover } from "../../components/overlays/popover/popover.js" +import { useTabs } from "../../contexts/tabs/tabsContext.js" +import { useDataFromAPI } from "../../utilities/useHTTPData.js" + +export function OrganizationContextSelect(props: { value: string | null; onChange: (v: string | null) => void }) { + const { openTab } = useTabs() + + const organizationUsersData = useDataFromAPI({ + routeDefinition: getAllMyOrganizationsRouteDefinition, + body: {}, + }) + + const options = (organizationUsersData.data ?? []).map((organizationUser) => ({ + key: organizationUser.organization.id, + label: organizationUser.organization.name, + })) + const selectedLabel = options.find((option) => option.key === props.value)?.label + + if (options.length === 0) { + return ( + + ) + } + + return ( + + + + + + {options.map((option) => ( + + ))} + + + + + ) +} diff --git a/packages/website/src/features/dashboard/YearContextSelect.tsx b/packages/website/src/features/dashboard/YearContextSelect.tsx new file mode 100644 index 00000000..7f0df3ff --- /dev/null +++ b/packages/website/src/features/dashboard/YearContextSelect.tsx @@ -0,0 +1,116 @@ +import { readAllYearsRouteDefinition } from "@arrhes/application-metadata" +import { Button, ButtonGhostContent, ButtonPlainContent, Separator } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { Popover } from "../../components/overlays/popover/popover.js" +import { useTabs } from "../../contexts/tabs/tabsContext.js" +import { useDataFromAPI } from "../../utilities/useHTTPData.js" + +export function YearContextSelect(props: { + value: string | null + onChange: (v: string | null) => void + idOrganizationSelected: string | null +}) { + const { openTab } = useTabs() + + const yearsData = useDataFromAPI({ + routeDefinition: readAllYearsRouteDefinition, + body: { idOrganization: props.idOrganizationSelected ?? undefined }, + enabled: props.idOrganizationSelected !== null, + }) + + const options = (yearsData.data ?? []) + .filter((y) => y.idOrganization === props.idOrganizationSelected) + .map((y) => ({ + key: y.id, + label: y.label, + })) + + const selectedLabel = options.find((option) => option.key === props.value)?.label + + if (options.length === 0) { + return ( + + ) + } + + return ( + + + + + + {options.map((option) => ( + + ))} + + + + + ) +} diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx new file mode 100644 index 00000000..9f0198d1 --- /dev/null +++ b/packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx @@ -0,0 +1,59 @@ +import { adminReadOneTicketRouteDefinition } from "@arrhes/application-metadata/routes" +import { CircularLoader } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { useDataFromAPI } from "../../../../../utilities/useHTTPData.js" +import { StatusToggle } from "./statusToggle.js" +import { TicketPage } from "./ticketPage.js" + +export function AdminTicketTabContent(props: { idTicket: string }) { + const ticket = useDataFromAPI({ + routeDefinition: adminReadOneTicketRouteDefinition, + body: { + idTicket: props.idTicket, + }, + }) + + return ( +
+ {ticket.isPending && } + + {ticket.isError && ( + + Erreur lors de la recuperation du ticket. + + )} + + {ticket.data && ( +
+ +
+ )} + + +
+ ) +} diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx index b0bb9a68..af699a5b 100644 --- a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx @@ -7,7 +7,6 @@ import { Badge, CircularLoader, formatDate, Separator } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCheck } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { $idTicketLayoutRoute } from "../../../../../routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx" import { useDataFromAPI } from "../../../../../utilities/useHTTPData.js" import { CreateOneTicketMessage } from "./createOneTicketMessage.js" import { TicketMessageList } from "./ticketMessageList.js" @@ -24,22 +23,23 @@ const categoryLabels: Record = { other: "Autre", } -export function TicketPage() { +export function TicketPage(props: { idTicket?: string } = {}) { const params = useParams({ - from: $idTicketLayoutRoute.id, + strict: false, }) + const idTicket = props.idTicket ?? params.idTicket ?? "" const ticket = useDataFromAPI({ routeDefinition: adminReadOneTicketRouteDefinition, body: { - idTicket: params.idTicket, + idTicket: idTicket, }, }) const messages = useDataFromAPI({ routeDefinition: adminReadAllTicketMessagesRouteDefinition, body: { - idTicket: params.idTicket, + idTicket: idTicket, }, }) @@ -227,7 +227,7 @@ export function TicketPage() { {ticket.data && (ticket.data.status === "open" ? ( - + ) : (
) diff --git a/packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx b/packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx index 5c56fc4f..3367142c 100644 --- a/packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx @@ -1,9 +1,9 @@ import { adminReadAllTicketsRouteDefinition } from "@arrhes/application-metadata/routes" -import { Badge, CircularLoader, formatDate } from "@arrhes/ui" +import { Badge, Button, CircularLoader, formatDate } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconExternalLink } from "@tabler/icons-react" import type * as v from "valibot" -import { LinkButton } from "../../../../components/linkButton.js" +import { TabLink } from "../../../../components/layouts/tabBar/tabLink.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.js" const statusLabels: Record = { @@ -23,87 +23,92 @@ type Ticket = v.InferOutput<(typeof adminReadAllTicketsRouteDefinition)["schemas function TicketRow(props: { ticket: Ticket }) { const { ticket } = props return ( - -
+
+ + {ticket.id} + + {statusLabels[ticket.status] ?? ticket.status} + {categoryLabels[ticket.category] ?? ticket.category} +
- {ticket.id} + {`Cree le ${formatDate(ticket.createdAt, { + includeTime: true, + })}`} + {ticket.lastUpdatedAt + ? ` - Mis a jour le ${formatDate(ticket.lastUpdatedAt, { + includeTime: true, + })}` + : ""} - {statusLabels[ticket.status] ?? ticket.status} - {categoryLabels[ticket.category] ?? ticket.category}
- - {`Cree le ${formatDate(ticket.createdAt, { - includeTime: true, - })}`} - {ticket.lastUpdatedAt - ? ` - Mis a jour le ${formatDate(ticket.lastUpdatedAt, { - includeTime: true, - })}` - : ""} - + />
- -
-
+ + ) } diff --git a/packages/website/src/features/dashboard/dashboardDefaultPage.tsx b/packages/website/src/features/dashboard/dashboardDefaultPage.tsx new file mode 100644 index 00000000..879d9e18 --- /dev/null +++ b/packages/website/src/features/dashboard/dashboardDefaultPage.tsx @@ -0,0 +1,42 @@ +import { Button, ButtonGhostContent, ButtonOutlineContent, Kbd, LinkButton, LinkContent } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconBook, IconPlus } from "@tabler/icons-react" +import { Link } from "@tanstack/react-router" + +export function DashboardDefaultPage() { + return ( +
+

+ Aucun onglet ouvert +

+

+ Ouvrez un nouvel onglet avec le raccourci clavier Ctrl+K ou la barre de recherche en haut de + la page. +

+
+ ) +} diff --git a/packages/website/src/features/dashboard/dashboardLayout.tsx b/packages/website/src/features/dashboard/dashboardLayout.tsx index 57e7275e..ad748527 100644 --- a/packages/website/src/features/dashboard/dashboardLayout.tsx +++ b/packages/website/src/features/dashboard/dashboardLayout.tsx @@ -1,237 +1,10 @@ -import { readUserSessionRouteDefinition, signOutRouteDefinition } from "@arrhes/application-metadata/routes" -import { Button, ButtonGhostContent, ButtonOutlineContent, Logo, Separator, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { - IconBook2, - IconBuildings, - IconLifebuoy, - IconLogout, - IconSettings, - IconShield, - IconUser, -} from "@tabler/icons-react" -import { Outlet, useRouterState } from "@tanstack/react-router" -import { LinkButton } from "../../components/linkButton.js" -import { Popover } from "../../components/overlays/popover/popover.js" -import { applicationRouter } from "../../routes/applicationRouter.js" -import { deleteCookies } from "../../utilities/cookies/deleteCookies.js" -import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" -import { useDataFromAPI } from "../../utilities/useHTTPData.js" -import { Breadcrumbs } from "../breadcrumbs.js" +import { TabsProvider } from "../../contexts/tabs/tabsProvider.js" +import { DashboardShell } from "./dashboardShell.js" export function DashboardLayout() { - const pathname = useRouterState({ - select: (state) => state.location.pathname, - }) - const isAdminPath = pathname.startsWith("/dashboard/admin") - - const userSession = useDataFromAPI({ - routeDefinition: readUserSessionRouteDefinition, - body: {}, - }) - return ( -
- {/* Header */} -
-
-
- - } - text={isAdminPath ? "Admin" : undefined} - /> - - -
- -
-
- - {/* Main content */} -
-
- -
-
-
+ + + ) } diff --git a/packages/website/src/features/dashboard/dashboardShell.tsx b/packages/website/src/features/dashboard/dashboardShell.tsx new file mode 100644 index 00000000..f3f6ffac --- /dev/null +++ b/packages/website/src/features/dashboard/dashboardShell.tsx @@ -0,0 +1,391 @@ +import { readUserSessionRouteDefinition, signOutRouteDefinition } from "@arrhes/application-metadata/routes" +import { Button, ButtonGhostContent, ButtonOutlineContent, Logo, Separator, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { + IconBook2, + IconLifebuoy, + IconLogout, + IconSearch, + IconSettings, + IconShield, + IconTicket, + IconUser, +} from "@tabler/icons-react" +import { Outlet } from "@tanstack/react-router" +import { useEffect, useState } from "react" +import { CommandPalette } from "../../components/layouts/commandPalette/commandPalette.js" +import { TabBar } from "../../components/layouts/tabBar/tabBar.js" +import { Popover } from "../../components/overlays/popover/popover.js" +import { type ComponentTab, currentEntry, useTabs } from "../../contexts/tabs/tabsContext.js" +import { TabContentArea } from "../../contexts/tabs/tabsProvider.js" +import { useOuterRouter } from "../../contexts/tabs/useOuterRouter.js" +import { deleteCookies } from "../../utilities/cookies/deleteCookies.js" +import { setCookie } from "../../utilities/cookies/setCookie.js" +import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" +import { cookiePrefix } from "../../utilities/variables.js" +import { useDataFromAPI } from "../../utilities/useHTTPData.js" +import { OrganizationContextSelect } from "./OrganizationContextSelect.js" +import { YearContextSelect } from "./YearContextSelect.js" + +const SELECTED_ORG_KEY = "arrhes:context-org" +const SELECTED_YEAR_KEY = "arrhes:context-year" + +// ─── Inner shell — rendered inside TabsProvider ────────────────────────────── + +export function DashboardShell() { + const { tabs, activeTabId, openTab } = useTabs() + const applicationRouter = useOuterRouter() + const [selectedOrgId, setSelectedOrgId] = useState(() => { + try { + const id = localStorage.getItem(SELECTED_ORG_KEY) ?? null + if (id !== null) setCookie(`${cookiePrefix}_id_organization`, id) + return id + } catch { + return null + } + }) + const [selectedYearId, setSelectedYearId] = useState(() => { + try { + return localStorage.getItem(SELECTED_YEAR_KEY) ?? null + } catch { + return null + } + }) + + // Update browser title when active tab changes. + useEffect(() => { + const activeTab = tabs.find((t) => t.id === activeTabId) + if (activeTab) { + const title = + activeTab.type === "component" ? currentEntry(activeTab as ComponentTab).title : activeTab.title + document.title = `${title} — Arrhes` + // Update meta description. + const meta = document.querySelector("meta[name='description']") + if (meta && activeTab.type === "component") { + const entry = currentEntry(activeTab as ComponentTab) + if (entry.description) meta.content = entry.description + } + } else { + document.title = "Arrhes" + } + }, [ + tabs, + activeTabId, + ]) + + function handleOrgChange(id: string | null) { + setSelectedOrgId(id) + try { + if (id !== null) localStorage.setItem(SELECTED_ORG_KEY, id) + else localStorage.removeItem(SELECTED_ORG_KEY) + } catch {} + if (id !== null) setCookie(`${cookiePrefix}_id_organization`, id) + setSelectedYearId(null) + try { + localStorage.removeItem(SELECTED_YEAR_KEY) + } catch {} + } + + function handleYearChange(id: string | null) { + setSelectedYearId(id) + try { + if (id !== null) localStorage.setItem(SELECTED_YEAR_KEY, id) + else localStorage.removeItem(SELECTED_YEAR_KEY) + } catch {} + } + + const userSession = useDataFromAPI({ + routeDefinition: readUserSessionRouteDefinition, + body: {}, + }) + + return ( +
+ {/* Header */} +
+ {/* Breadcrumb: Logo / Org / Year */} +
+ + + / + + + {selectedOrgId !== null && ( + <> + + / + + + + )} +
+ + {/* Search */} + + + {/* Right: nav actions */} + +
+ + {/* Tab bar */} + + + {/* Tab content area */} +
+ + +
+ + {/* Command palette / search */} + +
+ ) +} diff --git a/packages/website/src/features/dashboard/organizations/addNewOrganization.tsx b/packages/website/src/features/dashboard/organizations/addNewOrganization.tsx index 8ecfe228..8e044306 100644 --- a/packages/website/src/features/dashboard/organizations/addNewOrganization.tsx +++ b/packages/website/src/features/dashboard/organizations/addNewOrganization.tsx @@ -2,9 +2,10 @@ import { addNewOrganizationRouteDefinition, getAllMyOrganizationsRouteDefinition, } from "@arrhes/application-metadata/routes" -import { InputText, InputToggle, toast } from "@arrhes/ui" +import { Button, InputText, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import { FormControl } from "../../../components/forms/formControl.tsx" import { FormError } from "../../../components/forms/formError.tsx" @@ -12,162 +13,179 @@ import { FormField } from "../../../components/forms/formField.tsx" import { FormItem } from "../../../components/forms/formItem.tsx" import { FormLabel } from "../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../utilities/invalidateData.ts" export function AddNewOrganization(props: { children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Ajouter l'organisation", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: addNewOrganizationRouteDefinition, - body: data, - }) - if (!response.ok) { - toast({ - title: "Impossible d'ajouter l'organisation", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx b/packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx index 255101c8..9b2f1fdf 100644 --- a/packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx +++ b/packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx @@ -1,9 +1,9 @@ import type { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata/routes" -import { Chip, LinkContent } from "@arrhes/ui" +import { Button, Chip, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../components/layouts/listTable/listTable.tsx" -import { LinkButton } from "../../../components/linkButton.tsx" +import { TabLink } from "../../../components/layouts/tabBar/tabLink.js" export function OrganizationListTableRow(props: { organizationUser: v.InferOutput[number] @@ -32,26 +32,30 @@ export function OrganizationListTableRow(props: { gap: "1rem", })} > - - - {organization.name} - - + +
- {props.children} - - - - , - text: "Supprimer mon compte", - color: "danger", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: deleteUserRouteDefinition, - body: data, - }) - if (response.ok === false) { + ) } diff --git a/packages/website/src/features/dashboard/profile/updateUserEmail.tsx b/packages/website/src/features/dashboard/profile/updateUserEmail.tsx index 91c0f739..df91cf3f 100644 --- a/packages/website/src/features/dashboard/profile/updateUserEmail.tsx +++ b/packages/website/src/features/dashboard/profile/updateUserEmail.tsx @@ -1,7 +1,8 @@ import { readUserSessionRouteDefinition, updateUserEmailRouteDefinition } from "@arrhes/application-metadata/routes" -import { InputPassword, InputText, toast } from "@arrhes/ui" +import { Button, InputPassword, InputText, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconDeviceFloppy } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import { FormControl } from "../../../components/forms/formControl.tsx" import { FormError } from "../../../components/forms/formError.tsx" @@ -9,106 +10,123 @@ import { FormField } from "../../../components/forms/formField.tsx" import { FormItem } from "../../../components/forms/formItem.tsx" import { FormLabel } from "../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../utilities/invalidateData.ts" export function UpdateUserEmail(props: { children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Mettre à jour l'email", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateUserEmailRouteDefinition, - body: data, - }) - if (response.ok === false) { + ) } diff --git a/packages/website/src/features/dashboard/profile/updateUserPassword.tsx b/packages/website/src/features/dashboard/profile/updateUserPassword.tsx index 740277cb..447a9ce6 100644 --- a/packages/website/src/features/dashboard/profile/updateUserPassword.tsx +++ b/packages/website/src/features/dashboard/profile/updateUserPassword.tsx @@ -1,7 +1,8 @@ import { updateUserPasswordRouteDefinition } from "@arrhes/application-metadata/routes" -import { InputPassword, toast } from "@arrhes/ui" +import { Button, InputPassword, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconDeviceFloppy } from "@tabler/icons-react" -import { type JSX, useState } from "react" +import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import { FormControl } from "../../../components/forms/formControl.tsx" import { FormError } from "../../../components/forms/formError.tsx" @@ -9,118 +10,135 @@ import { FormField } from "../../../components/forms/formField.tsx" import { FormItem } from "../../../components/forms/formItem.tsx" import { FormLabel } from "../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" export function UpdateUserPassword(props: { children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() return ( - - {props.children} - - - - , - text: "Mettre à jour le mot de passe", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: updateUserPasswordRouteDefinition, - body: data, - }) - if (response.ok === false) { + ) } diff --git a/packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx b/packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx index 25cbd54e..d54fdb8e 100644 --- a/packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx +++ b/packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx @@ -5,7 +5,6 @@ import { useParams } from "@tanstack/react-router" import { Banner } from "../../../../components/layouts/banner.tsx" import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" import { Section } from "../../../../components/layouts/section/section.tsx" -import { ticketLayoutRoute } from "../../../../routes/root/dashboard/support/ticketLayoutRoute.tsx" import { CreateOneTicketMessage } from "./createOneTicketMessage.tsx" import { TicketMessageList } from "./ticketMessageList.tsx" @@ -33,10 +32,11 @@ const statusLabels: Record< }, } -export function TicketPage() { +export function TicketPage(props: { idTicket?: string } = {}) { const params = useParams({ - from: ticketLayoutRoute.id, + strict: false, }) + const idTicket = props.idTicket ?? params.idTicket ?? "" return ( {(ticket) => { @@ -169,7 +169,7 @@ export function TicketPage() { {(messages) => { @@ -222,12 +222,12 @@ export function TicketPage() { {(ticket) => ticket.status === "open" ? ( - + ) : ( {(messages) => } diff --git a/packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx b/packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx new file mode 100644 index 00000000..e46254be --- /dev/null +++ b/packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx @@ -0,0 +1,48 @@ +import { readOneTicketRouteDefinition } from "@arrhes/application-metadata/routes" +import { css } from "@arrhes/ui/utilities/cn.js" +import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" +import { Section } from "../../../../components/layouts/section/section.tsx" +import { StatusToggle } from "./statusToggle.tsx" +import { TicketPage } from "./ticketPage.tsx" + +export function TicketTabContent(props: { idTicket: string }) { + return ( + + + + + + {(ticket) => ( +
+ +
+ )} +
+
+
+ +
+
+ ) +} diff --git a/packages/website/src/features/dashboard/support/createOneTicket.tsx b/packages/website/src/features/dashboard/support/createOneTicket.tsx index d3ba8778..9712c3ec 100644 --- a/packages/website/src/features/dashboard/support/createOneTicket.tsx +++ b/packages/website/src/features/dashboard/support/createOneTicket.tsx @@ -1,7 +1,8 @@ import { createOneTicketRouteDefinition, readAllTicketsRouteDefinition } from "@arrhes/application-metadata/routes" -import { InputTextArea, InputToggle, toast } from "@arrhes/ui" +import { Button, InputTextArea, InputToggle, toast } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type JSX, useRef, useState } from "react" +import { type JSX, useRef } from "react" import { Fragment } from "react/jsx-runtime" import { FormControl } from "../../../components/forms/formControl.tsx" import { FormError } from "../../../components/forms/formError.tsx" @@ -9,139 +10,156 @@ import { FormField } from "../../../components/forms/formField.tsx" import { FormItem } from "../../../components/forms/formItem.tsx" import { FormLabel } from "../../../components/forms/formLabel.tsx" import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { Drawer } from "../../../components/overlays/drawer/drawer.tsx" +import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" import { applicationRouter } from "../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../utilities/invalidateData.ts" export function CreateOneTicket(props: { children: JSX.Element }) { - const [open, setOpen] = useState(false) + const { openPanelTab, closeTab } = useTabs() const createdTicketIdRef = useRef(undefined) return ( - - {props.children} - - - - , - text: "Créer le ticket", - }} - onSubmit={async (data) => { - const response = await getResponseBodyFromAPI({ - routeDefinition: createOneTicketRouteDefinition, - body: data, - }) - if (response.ok === false) { - toast({ - title: "Impossible de créer le ticket", - variant: "error", + ) } diff --git a/packages/website/src/features/dashboard/support/ticketListTableRow.tsx b/packages/website/src/features/dashboard/support/ticketListTableRow.tsx index ed213eec..6a9418a1 100644 --- a/packages/website/src/features/dashboard/support/ticketListTableRow.tsx +++ b/packages/website/src/features/dashboard/support/ticketListTableRow.tsx @@ -1,9 +1,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Chip, formatDate, LinkContent } from "@arrhes/ui" +import { Button, Chip, formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../components/layouts/listTable/listTable.tsx" -import { LinkButton } from "../../../components/linkButton.tsx" +import { TabLink } from "../../../components/layouts/tabBar/tabLink.js" const categoryLabels: Record = { bug: "Erreur", @@ -64,26 +64,30 @@ export function TicketListTableRow(props: { ticket: v.InferOutput - - - {`Ticket - ${categoryLabel}`} - - + +
dashboardLayoutRoute, path: "/", - beforeLoad: () => { - const storedOrganizationId = getCookie(`${cookiePrefix}_id_organization`) - if (storedOrganizationId) { - throw redirect({ - to: "/dashboard/organisations/$idOrganization", - params: { - idOrganization: storedOrganizationId, - }, - }) - } - throw redirect({ - to: "/dashboard/organisations", - }) - }, - component: () => {}, + component: DashboardDefaultPage, }) diff --git a/packages/website/src/routes/root/dashboard/dashboardTabHistoryRoute.tsx b/packages/website/src/routes/root/dashboard/dashboardTabHistoryRoute.tsx new file mode 100644 index 00000000..7b423ab8 --- /dev/null +++ b/packages/website/src/routes/root/dashboard/dashboardTabHistoryRoute.tsx @@ -0,0 +1,9 @@ +import { createRoute } from "@tanstack/react-router" +import { dashboardLayoutRoute } from "./dashboardLayoutRoute.tsx" + +// Matches /dashboard/:tabId/:historyIndex — pushed by the tab system on each +// in-tab navigation step so browser back/forward traverses tab history. +export const dashboardTabHistoryRoute = createRoute({ + getParentRoute: () => dashboardLayoutRoute, + path: "/$tabId/$historyIndex", +}) diff --git a/packages/website/src/routes/root/dashboard/dashboardTabRoute.tsx b/packages/website/src/routes/root/dashboard/dashboardTabRoute.tsx new file mode 100644 index 00000000..de0ccfec --- /dev/null +++ b/packages/website/src/routes/root/dashboard/dashboardTabRoute.tsx @@ -0,0 +1,9 @@ +import { createRoute } from "@tanstack/react-router" +import { dashboardLayoutRoute } from "./dashboardLayoutRoute.tsx" + +// This route exists so that /dashboard/:tabId URLs are valid in the outer router. +// The DashboardLayout (parent) handles all rendering — no component needed here. +export const dashboardTabRoute = createRoute({ + getParentRoute: () => dashboardLayoutRoute, + path: "/$tabId", +}) diff --git a/packages/website/src/routes/root/dashboard/dashboardTree.ts b/packages/website/src/routes/root/dashboard/dashboardTree.ts index f6ae18ef..0f1bcb7e 100644 --- a/packages/website/src/routes/root/dashboard/dashboardTree.ts +++ b/packages/website/src/routes/root/dashboard/dashboardTree.ts @@ -1,263 +1,9 @@ import type { AnyRoute } from "@tanstack/react-router" -import { adminLayoutRoute } from "./admin/adminLayoutRoute.tsx" -import { adminRoute } from "./admin/adminRoute.tsx" -import { $idTicketLayoutRoute } from "./admin/tickets/$idTicket/$idTicketLayoutRoute.tsx" -import { $idTicketRoute } from "./admin/tickets/$idTicket/$idTicketRoute.tsx" -import { adminTicketsLayoutRoute } from "./admin/tickets/ticketsLayoutRoute.tsx" -import { adminTicketsRoute } from "./admin/tickets/ticketsRoute.tsx" -import { agentLayoutRoute } from "./agent/agentLayoutRoute.tsx" -import { agentRoute } from "./agent/agentRoute.tsx" -import { agentSessionRoute } from "./agent/agentSessionRoute.tsx" -import { agentSessionsLayoutRoute } from "./agent/agentSessionsLayoutRoute.tsx" -import { dashboardCatchRoute } from "./dashboardCatchRoute.tsx" import { dashboardLayoutRoute } from "./dashboardLayoutRoute.tsx" -import { dashboardRootRoute } from "./dashboardRootRoute.tsx" -import { organizationApiKeysRoute } from "./organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx" -import { organizationApiLayoutRoute } from "./organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx" -import { organizationApiRoute } from "./organizations/$idOrganization/organizationApi/organizationApiRoute.tsx" -import { organizationBillingHistoryRoute } from "./organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx" -import { organizationBillingLayoutRoute } from "./organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx" -import { organizationBillingRoute } from "./organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx" -import { organizationServicesRoute } from "./organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx" -import { organizationInvoicesRoute } from "./organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx" -import { organizationInvoiceUblRoute } from "./organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx" -import { organizationLayoutRoute } from "./organizations/$idOrganization/organizationLayoutRoute.tsx" -import { organizationPathRoute } from "./organizations/$idOrganization/organizationPathRoute.tsx" -import { organizationRoute } from "./organizations/$idOrganization/organizationRoute.tsx" -import { organizationSecurityRoute } from "./organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx" -import { organizationSettingsLayoutRoute } from "./organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx" -import { organizationSettingsRoute } from "./organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx" -import { organizationUsersLayoutRoute } from "./organizations/$idOrganization/organizationUsers/organizationUsersLayoutRoute.tsx" -import { organizationUsersRoute } from "./organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx" -import { fileLayoutRoute } from "./organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" -import { fileMetadataRoute } from "./organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx" -import { fileRoute } from "./organizations/$idOrganization/storage/$idFile/fileRoute.tsx" -import { fileVisualisationRoute } from "./organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx" -import { storageLayoutRoute } from "./organizations/$idOrganization/storage/storageLayoutRoute.tsx" -import { storageRoute } from "./organizations/$idOrganization/storage/storageRoute.tsx" -import { entryLineLayoutRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx" -import { entryLineMetadataRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx" -import { entryLineRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx" -import { entryCategoriesRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx" -import { entryLayoutRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" -import { entryLinesRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx" -import { entryMetadataRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx" -import { entryRoute } from "./organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx" -import { entriesLayoutRoute } from "./organizations/$idOrganization/years/$idYear/entries/entriesLayoutRoute.tsx" -import { entriesRoute } from "./organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx" -import { balanceReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx" -import { balanceSheetReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx" -import { incomeStatementReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx" -import { journalReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx" -import { ledgerReportRoute } from "./organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx" -import { reportsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx" -import { reportsRoute } from "./organizations/$idOrganization/years/$idYear/reports/reportsRoute.tsx" -import { yearLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx" -import { yearPathRoute } from "./organizations/$idOrganization/years/$idYear/yearPathRoute.tsx" -import { yearRoute } from "./organizations/$idOrganization/years/$idYear/yearRoute.tsx" -import { accountLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx" -import { accountMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx" -import { accountRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx" -import { accountsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsLayoutRoute.tsx" -import { accountsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx" -import { balanceSheetLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx" -import { balanceSheetMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx" -import { balanceSheetRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx" -import { actifLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifLayoutRoute.tsx" -import { actifRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx" -import { balanceSheetsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsLayoutRoute.tsx" -import { balanceSheetsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoute.tsx" -import { passifLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifLayoutRoute.tsx" -import { passifRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx" -import { incomeStatementLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx" -import { incomeStatementMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx" -import { incomeStatementRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx" -import { computationIncomeStatementLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx" -import { computationIncomeStatementMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx" -import { computationIncomeStatementRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx" -import { computationLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx" -import { computationMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx" -import { computationPostesRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx" -import { computationRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx" -import { computationsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsLayoutRoute.tsx" -import { computationsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx" -import { incomeStatementsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx" -import { incomeStatementsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx" -import { journalLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx" -import { journalMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx" -import { journalRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx" -import { journalsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsLayoutRoute.tsx" -import { journalsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx" -import { tagLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx" -import { tagMetadataRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx" -import { tagRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx" -import { tagsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsLayoutRoute.tsx" -import { tagsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx" -import { yearSettingsLayoutRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx" -import { yearSettingsRoute } from "./organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx" -import { yearsLayoutRoute } from "./organizations/$idOrganization/years/yearsLayoutRoute.tsx" -import { yearsPathRoute } from "./organizations/$idOrganization/years/yearsPathRoute.tsx" -import { yearsRoute } from "./organizations/$idOrganization/years/yearsRoute.tsx" -import { organizationsLayoutRoute } from "./organizations/organizationsLayoutRoute.tsx" -import { organizationsRoute } from "./organizations/organizationsRoute.tsx" -import { userProfileLayoutRoute } from "./profile/userProfileLayoutRoute.tsx" -import { userProfileRoute } from "./profile/userProfileRoute.tsx" -import { settingsLayoutRoute } from "./settings/settingsLayoutRoute.tsx" -import { settingsRoute } from "./settings/settingsRoute.tsx" -import { supportLayoutRoute } from "./support/supportLayoutRoute.tsx" -import { supportRoute } from "./support/supportRoute.tsx" -import { ticketLayoutRoute } from "./support/ticketLayoutRoute.tsx" -import { ticketRoute } from "./support/ticketRoute.tsx" +import { dashboardTabRoute } from "./dashboardTabRoute.tsx" +// The dashboard tab shell handles all internal routing via per-tab memory routers. +// dashboardTabRoute (/$tabId) ensures /dashboard/:id URLs don't fall through to the catch route. export const dashboardTree: AnyRoute = dashboardLayoutRoute.addChildren([ - dashboardRootRoute, - adminLayoutRoute.addChildren([ - adminRoute, - adminTicketsLayoutRoute.addChildren([ - adminTicketsRoute, - $idTicketLayoutRoute.addChildren([ - $idTicketRoute, - ]), - ]), - ]), - organizationsLayoutRoute.addChildren([ - organizationsRoute, - organizationPathRoute.addChildren([ - organizationLayoutRoute.addChildren([ - organizationRoute, - yearsLayoutRoute.addChildren([ - yearsRoute, - ]), - organizationUsersLayoutRoute.addChildren([ - organizationUsersRoute, - ]), - organizationApiLayoutRoute.addChildren([ - organizationApiRoute, - organizationApiKeysRoute, - ]), - organizationBillingLayoutRoute.addChildren([ - organizationBillingRoute, - organizationServicesRoute, - organizationBillingHistoryRoute, - organizationInvoicesRoute, - organizationInvoiceUblRoute, - ]), - organizationSettingsLayoutRoute.addChildren([ - organizationSettingsRoute, - organizationSecurityRoute, - ]), - agentLayoutRoute.addChildren([ - agentRoute, - agentSessionsLayoutRoute.addChildren([ - agentSessionRoute, - ]), - ]), - storageLayoutRoute.addChildren([ - storageRoute, - fileLayoutRoute.addChildren([ - fileRoute, - fileMetadataRoute, - fileVisualisationRoute, - ]), - ]), - ]), - yearsPathRoute.addChildren([ - yearPathRoute.addChildren([ - yearLayoutRoute.addChildren([ - yearRoute, - entriesLayoutRoute.addChildren([ - entriesRoute, - entryLayoutRoute.addChildren([ - entryRoute, - entryLinesRoute, - entryCategoriesRoute, - entryMetadataRoute, - ]), - entryLineLayoutRoute.addChildren([ - entryLineRoute, - entryLineMetadataRoute, - ]), - ]), - reportsLayoutRoute.addChildren([ - reportsRoute, - journalReportRoute, - ledgerReportRoute, - balanceReportRoute, - balanceSheetReportRoute, - incomeStatementReportRoute, - ]), - yearSettingsLayoutRoute.addChildren([ - yearSettingsRoute, - accountsLayoutRoute.addChildren([ - accountsRoute, - accountLayoutRoute.addChildren([ - accountRoute, - accountMetadataRoute, - ]), - ]), - journalsLayoutRoute.addChildren([ - journalsRoute, - journalLayoutRoute.addChildren([ - journalRoute, - journalMetadataRoute, - ]), - ]), - tagsLayoutRoute.addChildren([ - tagsRoute, - tagLayoutRoute.addChildren([ - tagRoute, - tagMetadataRoute, - ]), - ]), - balanceSheetsLayoutRoute.addChildren([ - balanceSheetsRoute, - actifLayoutRoute.addChildren([ - actifRoute, - ]), - passifLayoutRoute.addChildren([ - passifRoute, - ]), - balanceSheetLayoutRoute.addChildren([ - balanceSheetRoute, - balanceSheetMetadataRoute, - ]), - ]), - incomeStatementsLayoutRoute.addChildren([ - incomeStatementsRoute, - incomeStatementLayoutRoute.addChildren([ - incomeStatementRoute, - incomeStatementMetadataRoute, - ]), - computationsLayoutRoute.addChildren([ - computationsRoute, - computationLayoutRoute.addChildren([ - computationRoute, - computationPostesRoute, - computationMetadataRoute, - ]), - computationIncomeStatementLayoutRoute.addChildren([ - computationIncomeStatementRoute, - computationIncomeStatementMetadataRoute, - ]), - ]), - ]), - ]), - ]), - ]), - ]), - ]), - ]), - userProfileLayoutRoute.addChildren([ - userProfileRoute, - ]), - settingsLayoutRoute.addChildren([ - settingsRoute, - ]), - supportLayoutRoute.addChildren([ - supportRoute, - ticketLayoutRoute.addChildren([ - ticketRoute, - ]), - ]), - dashboardCatchRoute, + dashboardTabRoute, ]) diff --git a/packages/website/src/routes/root/dashboard/fullDashboardTree.ts b/packages/website/src/routes/root/dashboard/fullDashboardTree.ts new file mode 100644 index 00000000..b5969e60 --- /dev/null +++ b/packages/website/src/routes/root/dashboard/fullDashboardTree.ts @@ -0,0 +1,13 @@ +import type { AnyRoute } from "@tanstack/react-router" +import { dashboardLayoutRoute } from "./dashboardLayoutRoute.js" +import { dashboardRootRoute } from "./dashboardRootRoute.js" +import { dashboardTabHistoryRoute } from "./dashboardTabHistoryRoute.js" +import { dashboardTabRoute } from "./dashboardTabRoute.js" + +// Only the tab-based URL pattern is needed. The inner per-tab memory routers +// handle all content routing. Classic mode has been removed. +export const fullDashboardTree: AnyRoute = dashboardLayoutRoute.addChildren([ + dashboardRootRoute, + dashboardTabRoute, + dashboardTabHistoryRoute, +]) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx index 5973be7c..bd41339c 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx @@ -9,6 +9,6 @@ export const entryRoute = createRoute({ }), component: lazyRouteComponent( () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/entryPage.js"), - "EntryPage", + "EntryRoutePage", ), }) diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json index c7d0a1fa..2eb77bf8 100644 --- a/packages/website/tsconfig.json +++ b/packages/website/tsconfig.json @@ -26,9 +26,12 @@ "noFallthroughCasesInSwitch": true, /* Path aliases */ "ignoreDeprecations": "6.0", - "baseUrl": "." + "baseUrl": ".", + "incremental": true, + "tsBuildInfoFile": "./.tsbuildinfo" }, "include": ["src"], + "exclude": ["styled-system", "build", "node_modules"], "references": [ { "path": "../metadata" diff --git a/packages/worker/package.json b/packages/worker/package.json index d1496d5c..42deb979 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -32,4 +32,4 @@ "imports": { "#src/*": "./build/*" } -} \ No newline at end of file +} diff --git a/packages/worker/src/jobs/runAgentSession/runAgentSession.ts b/packages/worker/src/jobs/runAgentSession/runAgentSession.ts index 8165d413..93d9069a 100644 --- a/packages/worker/src/jobs/runAgentSession/runAgentSession.ts +++ b/packages/worker/src/jobs/runAgentSession/runAgentSession.ts @@ -607,12 +607,7 @@ export async function runAgentSession(args: RunAgentSessionJobArgs): Promise Date: Thu, 14 May 2026 21:33:22 +0200 Subject: [PATCH 06/14] feat(dashboard): split-panel tab management with drag-and-drop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add split panel view: right-click tab → 'Ouvrir en vue divisée', or drag a tab outside the bar to create a new panel automatically - Resizable panels with drag handle (20–80% range); dragging no longer selects text (userSelect toggled on body during resize) - SplitTabBar for the right panel with back/forward navigation buttons, drag-to-reorder and drag-to-transfer between panels - Closing the last tab in a panel closes both the tab and the panel - Auto-close split view when the left panel would have no tabs remaining - Right-click on empty tab bar area shows context menu: 'Fusionner les panneaux' (only visible in split mode) - Replaced Popover-based tab context menu with Radix ContextMenu (single root, capture/bubble trick for tab vs bar distinction) - ContextMenu.Item highlighted state matches hover style (no focus ring) - reorderTabs added to TabsContext for global tab reordering --- .../layouts/commandPalette/commandPalette.tsx | 13 +- .../src/components/layouts/subPageContent.tsx | 327 +++++++++++++++- .../components/layouts/tabBar/splitTabBar.tsx | 179 +++++++++ .../src/components/layouts/tabBar/tabBar.tsx | 362 ++++++++++++------ .../overlays/contextMenu/contextMenuItem.tsx | 4 + .../website/src/contexts/tabs/tabsContext.tsx | 1 + .../src/contexts/tabs/tabsProvider.tsx | 14 + .../src/features/dashboard/dashboardShell.tsx | 250 +++++++++++- 8 files changed, 1004 insertions(+), 146 deletions(-) create mode 100644 packages/website/src/components/layouts/tabBar/splitTabBar.tsx diff --git a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx index fdcc1510..f772efc3 100644 --- a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx +++ b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx @@ -170,10 +170,15 @@ export function CommandPalette(props: { selectedOrgId: string | null; selectedYe function activate(item: SearchRoute) { setOpen(false) - openTab({ - component: item.tabComponent, - props: item.tabProps, - } as OpenTabArgs) + openTab( + { + component: item.tabComponent, + props: item.tabProps, + } as OpenTabArgs, + { + newTab: true, + }, + ) } function handleKeyDown(e: React.KeyboardEvent) { diff --git a/packages/website/src/components/layouts/subPageContent.tsx b/packages/website/src/components/layouts/subPageContent.tsx index 7fb03fce..e8fcda8a 100644 --- a/packages/website/src/components/layouts/subPageContent.tsx +++ b/packages/website/src/components/layouts/subPageContent.tsx @@ -1,7 +1,10 @@ import { Button, ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" +import * as PopoverPrimitive from "@radix-ui/react-popover" import type { Icon, IconProps } from "@tabler/icons-react" -import { type ReactElement, type ReactNode, useState } from "react" +import { IconLayoutColumns, IconX } from "@tabler/icons-react" +import { type ReactElement, type ReactNode, useCallback, useEffect, useRef, useState } from "react" +import { Popover } from "../overlays/popover/popover.js" type SectionItem = { key: string @@ -21,22 +24,41 @@ type Props = { defaultKey?: string } -/** State-based tab navigation — no TanStack Router required. */ -export function SubPageContent({ sections, defaultKey }: Props) { - const firstKey = defaultKey ?? Object.values(sections).flatMap((s) => s.items)[0]?.key ?? "" - const [activeKey, setActiveKey] = useState(firstKey) +type PanelProps = { + allItems: SectionItem[] + activeKey: string + setActiveKey: (key: string) => void + onOpenInSplit?: (key: string) => void + rightSlot?: ReactNode +} - const allItems = Object.values(sections).flatMap((s) => s.items) +function Panel({ allItems, activeKey, setActiveKey, onOpenInSplit, rightSlot }: PanelProps) { const activeContent = allItems.find((i) => i.key === activeKey)?.content ?? null + const [contextMenuKey, setContextMenuKey] = useState(null) + + // Capture phase fires before the browser decides to show the native context menu. + useEffect(() => { + function suppressBrowserMenu(e: MouseEvent) { + if ((e.target as HTMLElement | null)?.closest?.("[data-tab-context]")) { + e.preventDefault() + } + } + document.addEventListener("contextmenu", suppressBrowserMenu, { + capture: true, + }) + return () => + document.removeEventListener("contextmenu", suppressBrowserMenu, { + capture: true, + }) + }, []) return (
{/* Tab bar */} @@ -56,17 +78,97 @@ export function SubPageContent({ sections, defaultKey }: Props) { })} > {allItems.map((item) => ( - + + { + e.preventDefault() + setContextMenuKey(item.key) + }} + > + + + + + + {onOpenInSplit && ( + + )} + + ))} + {rightSlot && ( +
+ {rightSlot} +
+ )}
{/* Active tab content */} @@ -84,3 +186,194 @@ export function SubPageContent({ sections, defaultKey }: Props) {
) } + +/** State-based tab navigation — no TanStack Router required. */ +export function SubPageContent({ sections, defaultKey }: Props) { + const allItems = Object.values(sections).flatMap((s) => s.items) + const firstKey = defaultKey ?? allItems[0]?.key ?? "" + + const [activeKey, setActiveKey] = useState(firstKey) + const [splitEnabled, setSplitEnabled] = useState(false) + const [splitPosition, setSplitPosition] = useState(50) + + const defaultRightKey = allItems.find((i) => i.key !== firstKey)?.key ?? firstKey + const [activeKeyRight, setActiveKeyRight] = useState(defaultRightKey) + + const containerRef = useRef(null) + const isDragging = useRef(false) + const dragStartX = useRef(0) + const dragStartPosition = useRef(50) + + const handleMouseMove = useCallback((e: MouseEvent) => { + if (!isDragging.current || !containerRef.current) return + const rect = containerRef.current.getBoundingClientRect() + const deltaX = e.clientX - dragStartX.current + const deltaPct = (deltaX / rect.width) * 100 + const newPct = Math.min(80, Math.max(20, dragStartPosition.current + deltaPct)) + setSplitPosition(newPct) + }, []) + + const handleMouseUp = useCallback(() => { + isDragging.current = false + window.removeEventListener("mousemove", handleMouseMove) + window.removeEventListener("mouseup", handleMouseUp) + document.body.style.cursor = "" + document.body.style.userSelect = "" + }, [ + handleMouseMove, + ]) + + const handleDragStart = useCallback( + (e: React.MouseEvent) => { + e.preventDefault() + isDragging.current = true + dragStartX.current = e.clientX + dragStartPosition.current = splitPosition + document.body.style.cursor = "col-resize" + document.body.style.userSelect = "none" + window.addEventListener("mousemove", handleMouseMove) + window.addEventListener("mouseup", handleMouseUp) + }, + [ + splitPosition, + handleMouseMove, + handleMouseUp, + ], + ) + + // Clean up listeners on unmount + useEffect( + () => () => { + window.removeEventListener("mousemove", handleMouseMove) + window.removeEventListener("mouseup", handleMouseUp) + }, + [ + handleMouseMove, + handleMouseUp, + ], + ) + + const closeSplit = useCallback(() => { + setSplitEnabled(false) + setSplitPosition(50) + }, []) + + const handleOpenInSplit = useCallback((key: string) => { + setActiveKeyRight(key) + setSplitEnabled(true) + }, []) + + if (!splitEnabled) { + return ( +
+ 1 ? handleOpenInSplit : undefined} + rightSlot={ + allItems.length > 1 ? ( + + ) : undefined + } + /> +
+ ) + } + + return ( +
+ {/* Left panel */} +
+ setSplitEnabled(false)}> + } + text="" + isCurrent={true} + /> + + } + /> +
+ + {/* Drag handle */} +
+ + {/* Right panel */} +
+ + } + text="" + /> + + } + /> +
+
+ ) +} diff --git a/packages/website/src/components/layouts/tabBar/splitTabBar.tsx b/packages/website/src/components/layouts/tabBar/splitTabBar.tsx new file mode 100644 index 00000000..04d5f395 --- /dev/null +++ b/packages/website/src/components/layouts/tabBar/splitTabBar.tsx @@ -0,0 +1,179 @@ +import { Button, ButtonGhostContent } from "@arrhes/ui" +import { css } from "@arrhes/ui/utilities/cn.js" +import { IconChevronLeft, IconChevronRight, IconX } from "@tabler/icons-react" +import { useState } from "react" +import { type ComponentTab, currentEntry, useTabs } from "../../../contexts/tabs/tabsContext.js" + +type Props = { + tabIds: string[] + activeTabId: string + onActivate: (tabId: string) => void + onRemove: (tabId: string) => void + onReorder: (tabId: string, insertBeforeTabId: string | null) => void + onDropFromLeft: (tabId: string, insertBeforeTabId: string | null) => void +} + +export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReorder, onDropFromLeft }: Props) { + const { tabs, navigateBack, navigateForward } = useTabs() + const [dragOverTabId, setDragOverTabId] = useState(null) + const panelTabs = tabIds.flatMap((id) => { + const t = tabs.find((x) => x.id === id) + return t ? [t] : [] + }) + + function handleDrop(e: React.DragEvent, insertBeforeTabId: string | null) { + e.preventDefault() + e.stopPropagation() + setDragOverTabId(null) + const fromLeft = e.dataTransfer.types.includes("application/arrhes-left-tab") + const draggedId = fromLeft + ? e.dataTransfer.getData("application/arrhes-left-tab") + : e.dataTransfer.getData("application/arrhes-right-tab") + if (!draggedId) return + if (fromLeft) onDropFromLeft(draggedId, insertBeforeTabId) + else onReorder(draggedId, insertBeforeTabId) + } + + return ( +
{ + if ( + e.dataTransfer.types.includes("application/arrhes-left-tab") || + e.dataTransfer.types.includes("application/arrhes-right-tab") + ) + e.preventDefault() + }} + onDrop={(e) => handleDrop(e, null)} + > + {panelTabs.map((tab) => { + const isActive = tab.id === activeTabId + const title = + tab.type === "component" + ? currentEntry(tab as ComponentTab).title + : ( + tab as { + title: string + } + ).title + return ( +
{ + e.dataTransfer.setData("application/arrhes-right-tab", tab.id) + e.dataTransfer.effectAllowed = "move" + }} + onDragEnd={() => setDragOverTabId(null)} + onDragOver={(e) => { + if ( + e.dataTransfer.types.includes("application/arrhes-left-tab") || + e.dataTransfer.types.includes("application/arrhes-right-tab") + ) { + e.preventDefault() + e.stopPropagation() + setDragOverTabId(tab.id) + } + }} + onDragLeave={(e) => { + if (!e.currentTarget.contains(e.relatedTarget as Node | null)) + setDragOverTabId(null) + }} + onDrop={(e) => handleDrop(e, tab.id)} + onClick={() => onActivate(tab.id)} + > + {tab.type === "component" && ( + <> + + + + )} + + {title} + + +
+ ) + })} + +
+ ) +} diff --git a/packages/website/src/components/layouts/tabBar/tabBar.tsx b/packages/website/src/components/layouts/tabBar/tabBar.tsx index f4738cfc..272810bb 100644 --- a/packages/website/src/components/layouts/tabBar/tabBar.tsx +++ b/packages/website/src/components/layouts/tabBar/tabBar.tsx @@ -1,132 +1,270 @@ import { Button, ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import { IconChevronLeft, IconChevronRight, IconPlus, IconX } from "@tabler/icons-react" +import { IconChevronLeft, IconChevronRight, IconLayoutColumns, IconPlus, IconX } from "@tabler/icons-react" +import { type ReactNode, useState } from "react" import { type ComponentTab, currentEntry, useTabs } from "../../../contexts/tabs/tabsContext.js" +import { ContextMenu } from "../../overlays/contextMenu/contextMenu.js" -export function TabBar() { - const { tabs, activeTabId, activateTab, closeTab, navigateBack, navigateForward } = useTabs() +type TabBarProps = { + excludeTabIds?: string[] + rightSlot?: ReactNode + onDropFromRight?: (tabId: string, insertBeforeTabId: string | null) => void + onMergePanels?: () => void +} + +export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanels }: TabBarProps = {}) { + const { tabs: allTabs, activeTabId, activateTab, closeTab, navigateBack, navigateForward, reorderTabs } = useTabs() + const tabs = allTabs.filter((t) => !excludeTabIds?.includes(t.id)) + const [dragOverTabId, setDragOverTabId] = useState(null) + const [contextMenuTabId, setContextMenuTabId] = useState(null) + const contextTab = contextMenuTabId !== null ? (tabs.find((t) => t.id === contextMenuTabId) ?? null) : null return ( -
- {tabs.map((tab) => { - const isActive = tab.id === activeTabId - const title = tab.type === "component" ? currentEntry(tab as ComponentTab).title : tab.title - const canGoBack = tab.type === "component" && (tab as ComponentTab).historyIndex > 0 - const canGoForward = - tab.type === "component" && - (tab as ComponentTab).historyIndex < (tab as ComponentTab).history.length - 1 - return ( -
activateTab(tab.id)} - > - {tab.type === "component" && ( - <> - + + + )} + - } /> - + {title} + - - )} - - {title} - +
+ ) + })} + + {/* New tab button */} +
- ) - })} - {/* New tab button */} -
- -
-
+ {rightSlot && ( +
+ {rightSlot} +
+ )} +
+ + + {contextTab ? ( + <> + } + onSelect={() => + window.dispatchEvent( + new CustomEvent("arrhes:split-tab", { + detail: { tabId: contextTab.id }, + }), + ) + } + > + Ouvrir en vue divisée + + } + onSelect={() => closeTab(contextTab.id)} + > + Fermer l'onglet + + {tabs.length > 1 && ( + { + for (const t of tabs) { + if (t.id !== contextTab.id) closeTab(t.id) + } + }} + > + Fermer les autres onglets + + )} + + ) : onMergePanels ? ( + } + onSelect={onMergePanels} + > + Fusionner les panneaux + + ) : null} + + ) } diff --git a/packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx b/packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx index 841da4ac..81b6c310 100644 --- a/packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx +++ b/packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx @@ -28,6 +28,10 @@ export function ContextMenuItem( _hover: { backgroundColor: "neutral/5", }, + "&[data-highlighted]": { + backgroundColor: "neutral/5", + outline: "none", + }, }), color === "danger" ? css({ diff --git a/packages/website/src/contexts/tabs/tabsContext.tsx b/packages/website/src/contexts/tabs/tabsContext.tsx index f448ca97..22785b4c 100644 --- a/packages/website/src/contexts/tabs/tabsContext.tsx +++ b/packages/website/src/contexts/tabs/tabsContext.tsx @@ -75,6 +75,7 @@ export type TabsContextValue = { navigateForward: (tabId: string) => void openPanelTab: (title: string, component: React.ReactNode, icon?: string) => string updateTabTitle: (id: string, title: string) => void + reorderTabs: (tabId: string, beforeTabId: string | null) => void } export const TabsContext = createContext(null) diff --git a/packages/website/src/contexts/tabs/tabsProvider.tsx b/packages/website/src/contexts/tabs/tabsProvider.tsx index 4353e314..307ebcd5 100644 --- a/packages/website/src/contexts/tabs/tabsProvider.tsx +++ b/packages/website/src/contexts/tabs/tabsProvider.tsx @@ -488,6 +488,18 @@ export function TabsProvider({ children }: Props) { ) }, []) + const reorderTabs = useCallback((tabId: string, beforeTabId: string | null) => { + setTabs((prev) => { + const tab = prev.find((t) => t.id === tabId) + if (!tab) return prev + const without = prev.filter((t) => t.id !== tabId) + if (beforeTabId === null) return [...without, tab] + const idx = without.findIndex((t) => t.id === beforeTabId) + if (idx === -1) return [...without, tab] + return [...without.slice(0, idx), tab, ...without.slice(idx)] + }) + }, []) + const value = useMemo( () => ({ tabs, @@ -499,6 +511,7 @@ export function TabsProvider({ children }: Props) { navigateForward, openPanelTab, updateTabTitle, + reorderTabs, }), [ tabs, @@ -510,6 +523,7 @@ export function TabsProvider({ children }: Props) { navigateForward, openPanelTab, updateTabTitle, + reorderTabs, ], ) diff --git a/packages/website/src/features/dashboard/dashboardShell.tsx b/packages/website/src/features/dashboard/dashboardShell.tsx index f3f6ffac..bbf3c5f3 100644 --- a/packages/website/src/features/dashboard/dashboardShell.tsx +++ b/packages/website/src/features/dashboard/dashboardShell.tsx @@ -12,8 +12,9 @@ import { IconUser, } from "@tabler/icons-react" import { Outlet } from "@tanstack/react-router" -import { useEffect, useState } from "react" +import { useCallback, useEffect, useRef, useState } from "react" import { CommandPalette } from "../../components/layouts/commandPalette/commandPalette.js" +import { SplitTabBar } from "../../components/layouts/tabBar/splitTabBar.js" import { TabBar } from "../../components/layouts/tabBar/tabBar.js" import { Popover } from "../../components/overlays/popover/popover.js" import { type ComponentTab, currentEntry, useTabs } from "../../contexts/tabs/tabsContext.js" @@ -22,8 +23,8 @@ import { useOuterRouter } from "../../contexts/tabs/useOuterRouter.js" import { deleteCookies } from "../../utilities/cookies/deleteCookies.js" import { setCookie } from "../../utilities/cookies/setCookie.js" import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" -import { cookiePrefix } from "../../utilities/variables.js" import { useDataFromAPI } from "../../utilities/useHTTPData.js" +import { cookiePrefix } from "../../utilities/variables.js" import { OrganizationContextSelect } from "./OrganizationContextSelect.js" import { YearContextSelect } from "./YearContextSelect.js" @@ -33,8 +34,56 @@ const SELECTED_YEAR_KEY = "arrhes:context-year" // ─── Inner shell — rendered inside TabsProvider ────────────────────────────── export function DashboardShell() { - const { tabs, activeTabId, openTab } = useTabs() + const { tabs, activeTabId, activateTab, openTab, reorderTabs, closeTab } = useTabs() const applicationRouter = useOuterRouter() + const [splitPosition, setSplitPosition] = useState(50) + const containerRef = useRef(null) + const isDragging = useRef(false) + const dragStartX = useRef(0) + const dragStartPosition = useRef(50) + + const handleMouseMove = useCallback((e: MouseEvent) => { + if (!isDragging.current || !containerRef.current) return + const rect = containerRef.current.getBoundingClientRect() + const deltaX = e.clientX - dragStartX.current + const deltaPct = (deltaX / rect.width) * 100 + const newPct = Math.min(80, Math.max(20, dragStartPosition.current + deltaPct)) + setSplitPosition(newPct) + }, []) + + const handleMouseUp = useCallback(() => { + isDragging.current = false + window.removeEventListener("mousemove", handleMouseMove) + window.removeEventListener("mouseup", handleMouseUp) + document.body.style.cursor = "" + document.body.style.userSelect = "" + }, [handleMouseMove]) + + const handleDragStart = useCallback( + (e: React.MouseEvent) => { + isDragging.current = true + dragStartX.current = e.clientX + dragStartPosition.current = splitPosition + document.body.style.cursor = "col-resize" + document.body.style.userSelect = "none" + window.addEventListener("mousemove", handleMouseMove) + window.addEventListener("mouseup", handleMouseUp) + }, + [splitPosition, handleMouseMove, handleMouseUp], + ) + + useEffect( + () => () => { + window.removeEventListener("mousemove", handleMouseMove) + window.removeEventListener("mouseup", handleMouseUp) + }, + [handleMouseMove, handleMouseUp], + ) + + const [rightPanel, setRightPanel] = useState<{ + tabIds: string[] + activeTabId: string + } | null>(null) const [selectedOrgId, setSelectedOrgId] = useState(() => { try { const id = localStorage.getItem(SELECTED_ORG_KEY) ?? null @@ -52,6 +101,62 @@ export function DashboardShell() { } }) + // Listen for split-tab events dispatched from the tab bar context menu. + const handleSplitTab = useCallback( + (e: Event) => { + const tabId = (e as CustomEvent<{ tabId: string }>).detail.tabId + setRightPanel((prev) => { + if (!prev) return { tabIds: [tabId], activeTabId: tabId } + if (prev.tabIds.includes(tabId)) return { ...prev, activeTabId: tabId } + return { tabIds: [...prev.tabIds, tabId], activeTabId: tabId } + }) + // If the tab was active in the left panel, switch to another left-panel tab. + if (tabId === activeTabId) { + const rightIds = new Set(rightPanel?.tabIds ?? []) + rightIds.add(tabId) + const remaining = tabs.filter((t) => !rightIds.has(t.id)) + if (remaining.length > 0) activateTab(remaining[remaining.length - 1].id) + } + }, + [activeTabId, tabs, rightPanel, activateTab], + ) + + useEffect(() => { + window.addEventListener("arrhes:split-tab", handleSplitTab) + return () => window.removeEventListener("arrhes:split-tab", handleSplitTab) + }, [handleSplitTab]) + + // Remove closed tabs from right panel. + useEffect(() => { + if (!rightPanel) return + const existingIds = new Set(tabs.map((t) => t.id)) + const filtered = rightPanel.tabIds.filter((id) => existingIds.has(id)) + if (filtered.length === rightPanel.tabIds.length) return + if (filtered.length === 0) { + setRightPanel(null) + } else { + const newActive = filtered.includes(rightPanel.activeTabId) + ? rightPanel.activeTabId + : filtered[filtered.length - 1] + setRightPanel({ + tabIds: filtered, + activeTabId: newActive, + }) + } + }, [ + tabs, + rightPanel, + ]) + + // Auto-close split view when the left panel would have no tabs. + useEffect(() => { + if (!rightPanel) return + const rightSet = new Set(rightPanel.tabIds) + if (tabs.filter((t) => !rightSet.has(t.id)).length === 0) { + setRightPanel(null) + } + }, [tabs, rightPanel]) + // Update browser title when active tab changes. useEffect(() => { const activeTab = tabs.find((t) => t.id === activeTabId) @@ -359,26 +464,145 @@ export function DashboardShell() { - {/* Tab bar */} - - - {/* Tab content area */} + {/* Tab bar + content area — panels side by side when split */}
- - + {/* Main / left panel — has its own tab bar */} +
+ setRightPanel(null) : undefined} + onDropFromRight={(tabId, insertBeforeTabId) => { + setRightPanel((prev) => { + if (!prev) return null + const next = prev.tabIds.filter((id) => id !== tabId) + return next.length === 0 + ? null + : { + tabIds: next, + activeTabId: next.includes(prev.activeTabId) + ? prev.activeTabId + : next[next.length - 1], + } + }) + reorderTabs(tabId, insertBeforeTabId) + activateTab(tabId) + }} + /> + + !rightPanel?.tabIds.includes(t.id))} + /> +
+ + {/* Split / right panel */} + {rightPanel && ( + <> + {/* Drag handle */} +
+ {/* Right panel */} +
+ + setRightPanel( + (prev) => + prev && { + ...prev, + activeTabId: tabId, + }, + ) + } + onRemove={(tabId) => { + setRightPanel((prev) => { + if (!prev) return null + const next = prev.tabIds.filter((id) => id !== tabId) + if (next.length === 0) { + closeTab(tabId) + return null + } + const newActive = + prev.activeTabId === tabId ? next[next.length - 1] : prev.activeTabId + return { + tabIds: next, + activeTabId: newActive, + } + }) + }} + onReorder={(tabId, insertBeforeTabId) => + setRightPanel((prev) => { + if (!prev) return null + const without = prev.tabIds.filter((id) => id !== tabId) + if (insertBeforeTabId === null) + return { ...prev, tabIds: [...without, tabId] } + const idx = without.indexOf(insertBeforeTabId) + const tabIds = + idx === -1 + ? [...without, tabId] + : [...without.slice(0, idx), tabId, ...without.slice(idx)] + return { ...prev, tabIds } + }) + } + onDropFromLeft={(tabId, insertBeforeTabId) => + setRightPanel((prev) => { + const existing = prev?.tabIds.filter((id) => id !== tabId) ?? [] + if (insertBeforeTabId === null) + return { tabIds: [...existing, tabId], activeTabId: tabId } + const idx = existing.indexOf(insertBeforeTabId) + const tabIds = + idx === -1 + ? [...existing, tabId] + : [...existing.slice(0, idx), tabId, ...existing.slice(idx)] + return { tabIds, activeTabId: tabId } + }) + } + /> + rightPanel.tabIds.includes(t.id))} + /> +
+ + )}
{/* Command palette / search */} From 22ca2cac2b1da16f032731835f9abaa750dc80a8 Mon Sep 17 00:00:00 2001 From: &mile Date: Fri, 15 May 2026 18:50:30 +0200 Subject: [PATCH 07/14] refactor: rename tsx files to PascalCase and fix import paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename ~440 .tsx component files from camelCase to PascalCase - Update all import paths across website, api, worker, and ui packages - Fix API email template import casing mismatches - Merge SplitTabBar into TabBar via panel? prop - Add tab description subtitle from HistoryEntry - Add label prop to écriture tab definition - Update dashboard docs with 5 interface sections --- packages/tools/src/schemas.ts | 2 +- packages/ui/src/components/buttons/Button.tsx | 95 ++++ ...hostContent.tsx => ButtonGhostContent.tsx} | 2 +- ...neContent.tsx => ButtonOutlineContent.tsx} | 2 +- ...lainContent.tsx => ButtonPlainContent.tsx} | 2 +- .../{linkButton.tsx => LinkButton.tsx} | 0 .../{linkContent.tsx => LinkContent.tsx} | 0 packages/ui/src/components/buttons/button.tsx | 11 +- .../src/components/buttons/buttonContent.tsx | 2 +- .../components/buttons/useButtonLoading.tsx | 10 + .../{formatBase.tsx => FormatBase.tsx} | 0 .../{formatError.tsx => FormatError.tsx} | 2 +- .../{formatLink.tsx => FormatLink.tsx} | 6 +- .../{formatNull.tsx => FormatNull.tsx} | 0 .../{formatText.tsx => FormatText.tsx} | 2 +- .../formats/display/FormatBoolean.tsx | 18 + .../components/formats/display/FormatDate.tsx | 25 + .../formats/display/FormatDateTime.tsx | 44 ++ .../formats/display/FormatFileSize.tsx | 30 ++ .../formats/display/FormatPrice.tsx | 38 ++ .../formats/display/FormatSelect.tsx | 26 + .../src/components/formats/formatBoolean.tsx | 19 - .../ui/src/components/formats/formatDate.tsx | 25 - .../src/components/formats/formatDateTime.tsx | 46 -- .../src/components/formats/formatFileSize.tsx | 32 -- .../ui/src/components/formats/formatPrice.tsx | 38 -- .../src/components/formats/formatSelect.tsx | 28 - .../{inputCheckbox.tsx => InputCheckbox.tsx} | 0 .../{inputCombobox.tsx => InputCombobox.tsx} | 14 +- ...Multiple.tsx => InputComboboxMultiple.tsx} | 14 +- .../{inputCurrency.tsx => InputCurrency.tsx} | 0 .../inputs/{inputDate.tsx => InputDate.tsx} | 0 ...{inputDebounced.tsx => InputDebounced.tsx} | 0 .../{inputDisabled.tsx => InputDisabled.tsx} | 0 .../inputs/{inputFile.tsx => InputFile.tsx} | 2 +- .../{inputNumber.tsx => InputNumber.tsx} | 4 +- .../{inputPassword.tsx => InputPassword.tsx} | 2 +- .../inputs/{inputPrice.tsx => InputPrice.tsx} | 0 .../{inputRating.tsx => InputRating.tsx} | 0 .../{inputSelect.tsx => InputSelect.tsx} | 10 +- .../{inputSwitch.tsx => InputSwitch.tsx} | 0 .../inputs/{inputText.tsx => InputText.tsx} | 0 .../{inputTextArea.tsx => InputTextArea.tsx} | 0 .../{inputToggle.tsx => InputToggle.tsx} | 4 +- .../layouts/{badge.tsx => Badge.tsx} | 0 .../components/layouts/{chip.tsx => Chip.tsx} | 0 ...{circularLoader.tsx => CircularLoader.tsx} | 0 .../components/layouts/{kbd.tsx => Kbd.tsx} | 0 .../components/layouts/{logo.tsx => Logo.tsx} | 0 ...{pageNavigation.tsx => PageNavigation.tsx} | 4 +- .../layouts/{separator.tsx => Separator.tsx} | 0 .../{virtualizer.tsx => Virtualizer.tsx} | 0 ...{popoverContent.tsx => PopoverContent.tsx} | 0 .../components/overlays/popover/popover.tsx | 2 +- .../toast/{toastItem.tsx => ToastItem.tsx} | 4 +- .../{toastViewport.tsx => ToastViewport.tsx} | 0 ...{toastProvider.tsx => ToasterProvider.tsx} | 0 .../src/components/overlays/toast/toast.tsx | 4 +- packages/ui/src/index.ts | 95 ++-- ...DataCombobox.tsx => InputDataCombobox.tsx} | 0 .../{linkButton.tsx => LinkButton.tsx} | 0 .../{docDefinition.tsx => DocDefinition.tsx} | 2 +- .../{docExample.tsx => DocExample.tsx} | 2 +- ...GlossaryEntry.tsx => DocGlossaryEntry.tsx} | 2 +- .../document/{docHeader.tsx => DocHeader.tsx} | 0 .../{docIndexLink.tsx => DocIndexLink.tsx} | 2 +- .../{docLastUpdate.tsx => DocLastUpdate.tsx} | 0 .../document/{docLink.tsx => DocLink.tsx} | 2 +- .../{docLinkCard.tsx => DocLinkCard.tsx} | 2 +- .../document/{docList.tsx => DocList.tsx} | 0 .../{docNextPage.tsx => DocNextPage.tsx} | 2 +- .../{docParagraph.tsx => DocParagraph.tsx} | 0 .../document/{docRoot.tsx => DocRoot.tsx} | 0 ...ocRouteRequest.tsx => DocRouteRequest.tsx} | 0 .../{docSection.tsx => DocSection.tsx} | 0 ...{docSectionCard.tsx => DocSectionCard.tsx} | 2 +- .../{docSourceRef.tsx => DocSourceRef.tsx} | 0 .../{docSources.tsx => DocSources.tsx} | 0 .../document/{docTable.tsx => DocTable.tsx} | 0 ...{docTextSection.tsx => DocTextSection.tsx} | 0 .../document/{docTip.tsx => DocTip.tsx} | 0 .../{formControl.tsx => FormControl.tsx} | 0 .../forms/{formError.tsx => FormError.tsx} | 0 .../forms/{formField.tsx => FormField.tsx} | 0 .../forms/{formGroup.tsx => FormGroup.tsx} | 0 .../forms/{formItem.tsx => FormItem.tsx} | 0 .../forms/{formLabel.tsx => FormLabel.tsx} | 0 .../forms/{formRoot.tsx => FormRoot.tsx} | 0 .../forms/{formSubmit.tsx => FormSubmit.tsx} | 0 .../layouts/{banner.tsx => Banner.tsx} | 0 .../components/layouts/{box.tsx => Box.tsx} | 0 ...opover.tsx => ColumnVisibilityPopover.tsx} | 0 .../layouts/{dataTable.tsx => DataTable.tsx} | 10 +- .../{dataWrapper.tsx => DataWrapper.tsx} | 0 .../{emptyState.tsx => EmptyState.tsx} | 0 .../{filterPopover.tsx => FilterPopover.tsx} | 0 .../components/layouts/{logo.tsx => Logo.tsx} | 0 .../layouts/{searchBar.tsx => SearchBar.tsx} | 0 .../{sortPopover.tsx => SortPopover.tsx} | 0 ...{subPageContent.tsx => SubPageContent.tsx} | 0 .../{subPageLayout.tsx => SubPageLayout.tsx} | 2 +- .../layouts/{title.tsx => TitleComponent.tsx} | 0 .../{virtualizer.tsx => Virtualizer.tsx} | 0 .../card/{cardContent.tsx => CardContent.tsx} | 0 .../card/{cardHeader.tsx => CardHeader.tsx} | 0 .../card/{cardRoot.tsx => CardRoot.tsx} | 0 .../src/components/layouts/card/card.tsx | 6 +- .../layouts/commandPalette/CommandPalette.tsx | 494 ++++++++++++++++++ .../layouts/commandPalette/ContextSelect.tsx | 23 + .../layouts/commandPalette/commandPalette.tsx | 27 +- .../layouts/commandPalette/searchRoutes.ts | 18 +- ...aBlockContent.tsx => DataBlockContent.tsx} | 0 ...ataBlockHeader.tsx => DataBlockHeader.tsx} | 0 .../{dataBlockItem.tsx => DataBlockItem.tsx} | 0 .../{dataBlockRoot.tsx => DataBlockRoot.tsx} | 0 .../layouts/dataBlock/dataBlock.tsx | 8 +- ...Filterable.tsx => ListTableFilterable.tsx} | 4 +- .../{listTableRoot.tsx => ListTableRoot.tsx} | 0 .../{listTableRow.tsx => ListTableRow.tsx} | 0 .../layouts/listTable/listTable.tsx | 8 +- .../page/{pageContent.tsx => PageContent.tsx} | 0 ...ageDescription.tsx => PageDescription.tsx} | 0 .../page/{pageHeader.tsx => PageHeader.tsx} | 0 ...{pageNavigation.tsx => PageNavigation.tsx} | 0 .../page/{pageRoot.tsx => PageRoot.tsx} | 0 .../{pageSeparator.tsx => PageSeparator.tsx} | 0 .../page/{pageTitle.tsx => PageTitle.tsx} | 0 .../src/components/layouts/page/page.tsx | 14 +- .../{sectionItem.tsx => SectionItem.tsx} | 0 .../{sectionRoot.tsx => SectionRoot.tsx} | 0 .../components/layouts/section/section.tsx | 4 +- ...onHeader.tsx => SettingsSectionHeader.tsx} | 0 ...ectionRoot.tsx => SettingsSectionRoot.tsx} | 0 ...sSectionRow.tsx => SettingsSectionRow.tsx} | 0 .../settingsSection/settingsSection.tsx | 6 +- .../layouts/tab/{tabRoot.tsx => TabRoot.tsx} | 2 +- .../src/components/layouts/tab/tab.tsx | 2 +- .../{splitTabBar.tsx => SplitTabBar.tsx} | 84 ++- .../src/components/layouts/tabBar/TabBar.tsx | 347 ++++++++++++ .../tabBar/{tabLink.tsx => TabLink.tsx} | 2 +- .../src/components/layouts/tabBar/tabBar.tsx | 270 ---------- .../table/{tableRoot.tsx => TableRoot.tsx} | 0 .../src/components/layouts/table/table.tsx | 16 +- .../{tableBodyCell.tsx => TableBodyCell.tsx} | 0 .../{tableBodyRow.tsx => TableBodyRow.tsx} | 0 ...ableHeaderCell.tsx => TableHeaderCell.tsx} | 0 ...ableHeaderRoot.tsx => TableHeaderRoot.tsx} | 0 ...{tableHeaderRow.tsx => TableHeaderRow.tsx} | 0 ...MenuContent.tsx => ContextMenuContent.tsx} | 0 ...ontextMenuItem.tsx => ContextMenuItem.tsx} | 19 +- ...ontextMenuRoot.tsx => ContextMenuRoot.tsx} | 0 ...Separator.tsx => ContextMenuSeparator.tsx} | 0 ...MenuTrigger.tsx => ContextMenuTrigger.tsx} | 0 .../overlays/contextMenu/contextMenu.tsx | 10 +- ...rmationModal.tsx => ConfirmationModal.tsx} | 0 .../dialog/{dialogBody.tsx => DialogBody.tsx} | 0 .../{dialogContent.tsx => DialogContent.tsx} | 2 +- ...gDescription.tsx => DialogDescription.tsx} | 0 .../{dialogFooter.tsx => DialogFooter.tsx} | 0 .../{dialogHeader.tsx => DialogHeader.tsx} | 0 .../{dialogOverlay.tsx => DialogOverlay.tsx} | 0 .../dialog/{dialogRoot.tsx => DialogRoot.tsx} | 0 .../{dialogTitle.tsx => DialogTitle.tsx} | 0 .../src/components/overlays/dialog/dialog.tsx | 16 +- ...{popoverContent.tsx => PopoverContent.tsx} | 0 .../components/overlays/popover/popover.tsx | 2 +- ...{tooltipContent.tsx => TooltipContent.tsx} | 0 .../components/overlays/tooltip/tooltip.tsx | 2 +- .../{rootProvider.tsx => RootProvider.tsx} | 4 +- .../dashboard/DashboardContextProvider.tsx | 52 ++ .../contexts/dashboard/dashboardContext.tsx | 16 + .../{dataProvider.tsx => DataProvider.tsx} | 0 ...{routerProvider.tsx => RouterProvider.tsx} | 0 .../src/contexts/tabs/TabContentArea.tsx | 56 ++ .../src/contexts/tabs/tabDefinitions.ts | 55 +- .../website/src/contexts/tabs/tabsContext.tsx | 10 +- .../src/contexts/tabs/tabsProvider.tsx | 147 +++--- .../website/src/contexts/tabs/useTabs.tsx | 10 + .../{breadcrumbs.tsx => Breadcrumbs.tsx} | 2 +- .../{rootLayout.tsx => RootLayout.tsx} | 0 ...ationLayout.tsx => OrganizationLayout.tsx} | 2 +- ...Content.tsx => OrganizationTabContent.tsx} | 2 +- .../{agentLayout.tsx => AgentLayout.tsx} | 6 +- .../{agentMessage.tsx => AgentMessage.tsx} | 2 +- ...ntMessagePart.tsx => AgentMessagePart.tsx} | 0 .../agent/{agentPage.tsx => AgentPage.tsx} | 0 ...ionContent.tsx => AgentSessionContent.tsx} | 8 +- ...ntSessionPage.tsx => AgentSessionPage.tsx} | 2 +- ...gentTabContent.tsx => AgentTabContent.tsx} | 10 +- .../{mentionInput.tsx => MentionInput.tsx} | 0 ...age.tsx => OrganizationApiGeneralPage.tsx} | 2 +- ...piLayout.tsx => OrganizationApiLayout.tsx} | 2 +- ...tent.tsx => OrganizationApiTabContent.tsx} | 6 +- ...istTableRow.tsx => ApiKeyListTableRow.tsx} | 2 +- ...KeysListTable.tsx => ApiKeysListTable.tsx} | 6 +- ...reateOneApiKey.tsx => CreateOneApiKey.tsx} | 16 +- ...eleteOneApiKey.tsx => DeleteOneApiKey.tsx} | 2 +- ...ysPage.tsx => OrganizationApiKeysPage.tsx} | 4 +- .../{rawKeyDisplay.tsx => RawKeyDisplay.tsx} | 0 ...ubscription.tsx => CancelSubscription.tsx} | 2 +- ...tsx => OrganizationBillingHistoryPage.tsx} | 6 +- ...yout.tsx => OrganizationBillingLayout.tsx} | 2 +- ....tsx => OrganizationBillingTabContent.tsx} | 10 +- ...sPage.tsx => OrganizationServicesPage.tsx} | 4 +- ...ubscription.tsx => ResumeSubscription.tsx} | 2 +- ...eLicencePage.tsx => UpdateLicencePage.tsx} | 6 +- .../{updateOcrPage.tsx => UpdateOcrPage.tsx} | 4 +- ...eStoragePage.tsx => UpdateStoragePage.tsx} | 4 +- ...ateTokensPage.tsx => UpdateTokensPage.tsx} | 4 +- .../invoices/InvoiceActionsPopover.tsx | 2 +- .../invoices/InvoicePaymentsTable.tsx | 2 +- .../invoices/InvoicesTable.tsx | 2 +- ...cePage.tsx => OrganizationInvoicePage.tsx} | 4 +- ...sPage.tsx => OrganizationInvoicesPage.tsx} | 4 +- .../OrganizationBillingDisclaimerBanner.tsx | 4 +- ...letPage.tsx => OrganizationWalletPage.tsx} | 6 +- ...urrentMonth.tsx => WalletCurrentMonth.tsx} | 2 +- ...alletTopUpPage.tsx => WalletTopUpPage.tsx} | 0 ...rawalPage.tsx => WalletWithdrawalPage.tsx} | 2 +- ...nization.tsx => DeleteOneOrganization.tsx} | 2 +- ...yPage.tsx => OrganizationSecurityPage.tsx} | 4 +- ...out.tsx => OrganizationSettingsLayout.tsx} | 2 +- ...sPage.tsx => OrganizationSettingsPage.tsx} | 4 +- ...tsx => OrganizationSettingsTabContent.tsx} | 6 +- ...nization.tsx => UpdateOneOrganization.tsx} | 14 +- ...User.tsx => DeleteOneOrganizationUser.tsx} | 2 +- ...User.tsx => UpdateOneOrganizationUser.tsx} | 14 +- ...User.tsx => CreateOneOrganizationUser.tsx} | 14 +- ...w.tsx => OrganizationUserListTableRow.tsx} | 4 +- ...ble.tsx => OrganizationUsersListTable.tsx} | 6 +- ...sersPage.tsx => OrganizationUsersPage.tsx} | 4 +- .../{createOneYear.tsx => CreateOneYear.tsx} | 36 +- ...rListTableRow.tsx => YearListTableRow.tsx} | 2 +- .../years/{yearSelect.tsx => YearSelect.tsx} | 0 ...{yearsListTable.tsx => YearsListTable.tsx} | 6 +- .../years/{yearsPage.tsx => YearsPage.tsx} | 4 +- .../dashboard/$idYear/YearDataProvider.tsx | 148 ++++++ ...earDataWrapper.tsx => YearDataWrapper.tsx} | 0 .../{yearLayout.tsx => YearLayout.tsx} | 2 +- ...neEntryLine.tsx => DeleteOneEntryLine.tsx} | 2 +- ...ntryLineLayout.tsx => EntryLineLayout.tsx} | 8 +- ...tadataTab.tsx => EntryLineMetadataTab.tsx} | 2 +- .../{entryLinePage.tsx => EntryLinePage.tsx} | 2 +- ...neEntryLine.tsx => UpdateOneEntryLine.tsx} | 16 +- ...neEntryLine.tsx => CreateOneEntryLine.tsx} | 16 +- ...{deleteOneEntry.tsx => DeleteOneEntry.tsx} | 2 +- ...cateOneEntry.tsx => DuplicateOneEntry.tsx} | 0 ...tegoriesTab.tsx => EntryCategoriesTab.tsx} | 4 +- .../{entryLayout.tsx => EntryLayout.tsx} | 14 +- .../{entryLinesTab.tsx => EntryLinesTab.tsx} | 10 +- ...ntryLinesTable.tsx => EntryLinesTable.tsx} | 6 +- ...ryMetadataTab.tsx => EntryMetadataTab.tsx} | 4 +- .../$idYear/entries/$idEntry/EntryPage.tsx | 118 +++++ .../entries/$idEntry/EntryRoutePage.tsx | 60 +++ ...ntryTabContent.tsx => EntryTabContent.tsx} | 24 +- ...ntryLines.tsx => UpdateManyEntryLines.tsx} | 14 +- ...{updateOneEntry.tsx => UpdateOneEntry.tsx} | 16 +- .../$idYear/entries/$idEntry/entryPage.tsx | 70 +-- ...{createOneEntry.tsx => CreateOneEntry.tsx} | 18 +- .../{entriesPage.tsx => EntriesPage.tsx} | 14 +- .../{entriesTable.tsx => EntriesTable.tsx} | 9 +- ...s.tsx => EntriesTableSelectionActions.tsx} | 2 +- ...ortEntryLines.tsx => ExportEntryLines.tsx} | 16 +- .../{exportFecFile.tsx => ExportFecFile.tsx} | 4 +- .../{importFecFile.tsx => ImportFecFile.tsx} | 0 ...everseOneEntry.tsx => ReverseOneEntry.tsx} | 2 +- ...plate.tsx => AmortizationTemplateForm.tsx} | 12 +- .../entries/entryTemplates/entryTemplates.tsx | 2 +- .../{deleteOneFile.tsx => DeleteOneFile.tsx} | 2 +- .../$idFile/{fileData.tsx => FileData.tsx} | 0 .../$idFile/{fileFile.tsx => FileFile.tsx} | 0 .../{fileLayout.tsx => FileLayout.tsx} | 8 +- ...ileMetadataTab.tsx => FileMetadataTab.tsx} | 2 +- .../$idFile/{filePage.tsx => FilePage.tsx} | 2 +- ...{fileTabContent.tsx => FileTabContent.tsx} | 14 +- ...sationTab.tsx => FileVisualisationTab.tsx} | 4 +- .../{updateOneFile.tsx => UpdateOneFile.tsx} | 4 +- ...eOneFileForm.tsx => UpdateOneFileForm.tsx} | 12 +- .../{createOneFile.tsx => CreateOneFile.tsx} | 0 ...reateOneFolder.tsx => CreateOneFolder.tsx} | 14 +- .../{fileActions.tsx => FileActions.tsx} | 8 +- ...ileContextMenu.tsx => FileContextMenu.tsx} | 8 +- .../files/{fileSelect.tsx => FileSelect.tsx} | 0 .../files/{filesGrid.tsx => FilesGrid.tsx} | 6 +- .../files/{filesPage.tsx => FilesPage.tsx} | 8 +- ...esPageContent.tsx => FilesPageContent.tsx} | 6 +- .../files/{filesTable.tsx => FilesTable.tsx} | 10 +- ...ons.tsx => FilesTableSelectionActions.tsx} | 2 +- .../{folderActions.tsx => FolderActions.tsx} | 8 +- ...rContextMenu.tsx => FolderContextMenu.tsx} | 8 +- ...oveOneFileForm.tsx => MoveOneFileForm.tsx} | 12 +- ...neFolderForm.tsx => MoveOneFolderForm.tsx} | 12 +- ...FolderForm.tsx => UpdateOneFolderForm.tsx} | 12 +- ...terPopover.tsx => ReportFilterPopover.tsx} | 0 .../{reportsLayout.tsx => ReportsLayout.tsx} | 2 +- ...tsTabContent.tsx => ReportsTabContent.tsx} | 12 +- ...ceReportPage.tsx => BalanceReportPage.tsx} | 10 +- ...ReportTable.tsx => BalanceReportTable.tsx} | 0 ...ortPage.tsx => BalanceSheetReportPage.tsx} | 14 +- ...eportPdf.tsx => BalanceSheetReportPdf.tsx} | 0 ...ort.tsx => DownloadBalanceSheetReport.tsx} | 2 +- ...m.tsx => BalanceSheetAssetsReportItem.tsx} | 2 +- ...ow.tsx => BalanceSheetAssetsReportRow.tsx} | 0 ....tsx => BalanceSheetAssetsReportTable.tsx} | 4 +- ... => BalanceSheetLiabilitiesReportItem.tsx} | 2 +- ...x => BalanceSheetLiabilitiesReportRow.tsx} | 0 ...=> BalanceSheetLiabilitiesReportTable.tsx} | 4 +- ....tsx => DownloadIncomeStatementReport.tsx} | 2 +- ...Item.tsx => IncomeStatementReportItem.tsx} | 2 +- ...Page.tsx => IncomeStatementReportPage.tsx} | 12 +- ...rtPdf.tsx => IncomeStatementReportPdf.tsx} | 0 ...rtRow.tsx => IncomeStatementReportRow.tsx} | 0 ...le.tsx => IncomeStatementsReportTable.tsx} | 2 +- ...alReportPage.tsx => JournalReportPage.tsx} | 10 +- ...ReportTable.tsx => JournalReportTable.tsx} | 0 ...gerReportPage.tsx => LedgerReportPage.tsx} | 10 +- ...rReportTable.tsx => LedgerReportTable.tsx} | 0 .../dashboard/$idYear/useYearData.tsx | 10 + .../dashboard/$idYear/yearDataContext.tsx | 18 +- .../{deleteOneYear.tsx => DeleteOneYear.tsx} | 4 +- .../{updateOneYear.tsx => UpdateOneYear.tsx} | 16 +- ...tingsLayout.tsx => YearSettingsLayout.tsx} | 2 +- ...rSettingsPage.tsx => YearSettingsPage.tsx} | 8 +- ...Content.tsx => YearSettingsTabContent.tsx} | 14 +- .../{accountLayout.tsx => AccountLayout.tsx} | 8 +- ...MetadataTab.tsx => AccountMetadataTab.tsx} | 2 +- .../{accountPage.tsx => AccountPage.tsx} | 2 +- ...eteOneAccount.tsx => DeleteOneAccount.tsx} | 2 +- ...ateOneAccount.tsx => UpdateOneAccount.tsx} | 18 +- .../{accountSelect.tsx => AccountSelect.tsx} | 0 .../{accountsPage.tsx => AccountsPage.tsx} | 6 +- .../{accountsTable.tsx => AccountsTable.tsx} | 4 +- ...ateOneAccount.tsx => CreateOneAccount.tsx} | 18 +- ...SheetLayout.tsx => BalanceSheetLayout.tsx} | 8 +- ...ataTab.tsx => BalanceSheetMetadataTab.tsx} | 2 +- ...anceSheetPage.tsx => BalanceSheetPage.tsx} | 2 +- ...nceSheet.tsx => DeleteOneBalanceSheet.tsx} | 2 +- ...nceSheet.tsx => UpdateOneBalanceSheet.tsx} | 16 +- ...anceSheetItem.tsx => BalanceSheetItem.tsx} | 2 +- ...alanceSheetRow.tsx => BalanceSheetRow.tsx} | 2 +- ...ceSheetTable.tsx => BalanceSheetTable.tsx} | 6 +- ...ceSheetsPage.tsx => BalanceSheetsPage.tsx} | 6 +- ...heetSelect.tsx => BalanceSheetsSelect.tsx} | 0 ...nceSheet.tsx => CreateOneBalanceSheet.tsx} | 16 +- ...ement.tsx => DeleteOneIncomeStatement.tsx} | 2 +- ...ntLayout.tsx => IncomeStatementLayout.tsx} | 8 +- ...Tab.tsx => IncomeStatementMetadataTab.tsx} | 2 +- ...tementPage.tsx => IncomeStatementPage.tsx} | 2 +- ...ement.tsx => UpdateOneIncomeStatement.tsx} | 16 +- ...ement.tsx => CreateOneIncomeStatement.tsx} | 16 +- ...tementItem.tsx => IncomeStatementItem.tsx} | 2 +- ...tatementRow.tsx => IncomeStatementRow.tsx} | 2 +- ...mentsPage.tsx => IncomeStatementsPage.tsx} | 6 +- ...ntsTable.tsx => IncomeStatementsTable.tsx} | 6 +- ...tationLayout.tsx => ComputationLayout.tsx} | 8 +- ...dataTab.tsx => ComputationMetadataTab.tsx} | 2 +- ...omputationPage.tsx => ComputationPage.tsx} | 2 +- ...PostesTab.tsx => ComputationPostesTab.tsx} | 6 +- ...mputation.tsx => DeleteOneComputation.tsx} | 2 +- ...mputation.tsx => UpdateOneComputation.tsx} | 14 +- ...x => ComputationIncomeStatementLayout.tsx} | 8 +- ...ComputationIncomeStatementMetadataTab.tsx} | 2 +- ...tsx => ComputationIncomeStatementPage.tsx} | 2 +- ...> DeleteOneComputationIncomeStatement.tsx} | 2 +- ...> UpdateOneComputationIncomeStatement.tsx} | 16 +- ...x => ComputationIncomeStatementsTable.tsx} | 6 +- ...> CreateOneComputationIncomeStatement.tsx} | 16 +- ...putationsPage.tsx => ComputationsPage.tsx} | 6 +- ...tationsTable.tsx => ComputationsTable.tsx} | 6 +- ...mputation.tsx => CreateOneComputation.tsx} | 14 +- ...eteOneJournal.tsx => DeleteOneJournal.tsx} | 2 +- .../{journalLayout.tsx => JournalLayout.tsx} | 8 +- ...MetadataTab.tsx => JournalMetadataTab.tsx} | 2 +- .../{journalPage.tsx => JournalPage.tsx} | 2 +- ...ateOneJournal.tsx => UpdateOneJournal.tsx} | 14 +- ...ateOneJournal.tsx => CreateOneJournal.tsx} | 14 +- ...stTableRow.tsx => JournalListTableRow.tsx} | 2 +- .../{journalSelect.tsx => JournalSelect.tsx} | 0 ...alsListTable.tsx => JournalsListTable.tsx} | 6 +- .../{journalsPage.tsx => JournalsPage.tsx} | 4 +- .../{deleteOneTag.tsx => DeleteOneTag.tsx} | 2 +- .../$idTag/{tagLayout.tsx => TagLayout.tsx} | 8 +- ...{tagMetadataTab.tsx => TagMetadataTab.tsx} | 2 +- .../tags/$idTag/{tagPage.tsx => TagPage.tsx} | 2 +- .../{updateOneTag.tsx => UpdateOneTag.tsx} | 14 +- .../{createOneTag.tsx => CreateOneTag.tsx} | 14 +- ...agListTableRow.tsx => TagListTableRow.tsx} | 2 +- .../tags/{tagSelect.tsx => TagSelect.tsx} | 0 .../{tagsListTable.tsx => TagsListTable.tsx} | 6 +- .../tags/{tagsPage.tsx => TagsPage.tsx} | 4 +- ...faultPage.tsx => DashboardDefaultPage.tsx} | 0 ...oundPage.tsx => DashboardNotFoundPage.tsx} | 4 +- .../dashboard/OrganizationContextSelect.tsx | 57 +- .../features/dashboard/YearContextSelect.tsx | 73 ++- ...inPanelLayout.tsx => AdminPanelLayout.tsx} | 0 ...bContent.tsx => AdminTicketTabContent.tsx} | 4 +- ...Message.tsx => CreateOneTicketMessage.tsx} | 0 .../{statusToggle.tsx => StatusToggle.tsx} | 0 .../{ticketLayout.tsx => TicketLayout.tsx} | 4 +- ...tMessageList.tsx => TicketMessageList.tsx} | 0 .../{ticketPage.tsx => TicketPage.tsx} | 4 +- .../{ticketsPage.tsx => TicketsPage.tsx} | 127 ++--- .../features/dashboard/dashboardLayout.tsx | 10 - .../dashboardLayout/DashboardLayout.tsx | 14 + .../DashboardShell.tsx} | 182 +++---- ...rganization.tsx => AddNewOrganization.tsx} | 35 +- ...leRow.tsx => OrganizationListTableRow.tsx} | 2 +- ...stTable.tsx => OrganizationsListTable.tsx} | 6 +- ...izationsPage.tsx => OrganizationsPage.tsx} | 4 +- .../{deleteUser.tsx => DeleteUser.tsx} | 14 +- ...pdateUserEmail.tsx => UpdateUserEmail.tsx} | 14 +- ...serPassword.tsx => UpdateUserPassword.tsx} | 14 +- ...serProfilePage.tsx => UserProfilePage.tsx} | 10 +- ...ateUserEmail.tsx => ValidateUserEmail.tsx} | 0 .../{settingsPage.tsx => SettingsPage.tsx} | 0 ...Message.tsx => CreateOneTicketMessage.tsx} | 12 +- .../{statusToggle.tsx => StatusToggle.tsx} | 0 .../{ticketLayout.tsx => TicketLayout.tsx} | 6 +- ...tMessageList.tsx => TicketMessageList.tsx} | 0 .../{ticketPage.tsx => TicketPage.tsx} | 8 +- ...ketTabContent.tsx => TicketTabContent.tsx} | 6 +- ...reateOneTicket.tsx => CreateOneTicket.tsx} | 14 +- .../{supportPage.tsx => SupportPage.tsx} | 8 +- ...istTableRow.tsx => TicketListTableRow.tsx} | 2 +- ...ketsListTable.tsx => TicketsListTable.tsx} | 6 +- .../docs/{docsLayout.tsx => DocsLayout.tsx} | 8 +- .../docs/{docsSearch.tsx => DocsSearch.tsx} | 0 .../docs/{sectionTab.tsx => SectionTab.tsx} | 2 +- ...arNavigation.tsx => SidebarNavigation.tsx} | 2 +- ...Page.tsx => AccountsAccountingDocPage.tsx} | 26 +- ...cPage.tsx => ClassesAccountingDocPage.tsx} | 16 +- ...e.tsx => DoubleEntryAccountingDocPage.tsx} | 24 +- ...cPage.tsx => EntriesAccountingDocPage.tsx} | 26 +- ....tsx => IntroductionAccountingDocPage.tsx} | 20 +- ...gDocPage.tsx => RootAccountingDocPage.tsx} | 14 +- ...cPage.tsx => BalanceAccountingDocPage.tsx} | 26 +- ....tsx => BalanceSheetAccountingDocPage.tsx} | 26 +- ...ngDocPage.tsx => FecAccountingDocPage.tsx} | 26 +- ...x => IncomeStatementAccountingDocPage.tsx} | 24 +- ...cPage.tsx => JournalAccountingDocPage.tsx} | 26 +- ...ocPage.tsx => LedgerAccountingDocPage.tsx} | 26 +- ...DocPage.tsx => NotesAccountingDocPage.tsx} | 24 +- ...cPage.tsx => ReportsAccountingDocPage.tsx} | 22 +- ... => AccountResourcesAccountingDocPage.tsx} | 18 +- ...=> AccountsResourcesAccountingDocPage.tsx} | 12 +- ...ccountInfoCard.tsx => AccountInfoCard.tsx} | 2 +- ...ccountNotFound.tsx => AccountNotFound.tsx} | 6 +- ...ection.tsx => AccountScenariosSection.tsx} | 4 +- ...istSection.tsx => ChildrenListSection.tsx} | 4 +- ...editSection.tsx => DebitCreditSection.tsx} | 4 +- .../components/{infoRow.tsx => InfoRow.tsx} | 0 ...yExamples.tsx => JournalEntryExamples.tsx} | 6 +- ...ntSection.tsx => ParentAccountSection.tsx} | 4 +- ...untBanner.tsx => SummaryAccountBanner.tsx} | 2 +- ...ssaryListItem.tsx => GlossaryListItem.tsx} | 2 +- ...=> GlossaryResourcesAccountingDocPage.tsx} | 12 +- ...lossaryTermResourcesAccountingDocPage.tsx} | 16 +- ...=> ScenarioResourcesAccountingDocPage.tsx} | 12 +- ...> ScenariosResourcesAccountingDocPage.tsx} | 10 +- ...odelsAiDocPage.tsx => ModelsAiDocPage.tsx} | 16 +- .../ai/{ocrAiDocPage.tsx => OcrAiDocPage.tsx} | 14 +- .../{rootAiDocPage.tsx => RootAiDocPage.tsx} | 16 +- ...{toolsAiDocPage.tsx => ToolsAiDocPage.tsx} | 12 +- ...cPage.tsx => AuthenticationApiDocPage.tsx} | 16 +- ...ilesApiDocPage.tsx => FilesApiDocPage.tsx} | 12 +- ...DocPage.tsx => IntroductionApiDocPage.tsx} | 18 +- ...DocPage.tsx => OrganizationApiDocPage.tsx} | 14 +- ...{rootApiDocPage.tsx => RootApiDocPage.tsx} | 10 +- ...{yearApiDocPage.tsx => YearApiDocPage.tsx} | 14 +- .../features/docs/components/DataError.tsx | 2 +- .../dashboard/BillingDashboardDocPage.tsx | 12 +- ...ocPage.tsx => EntriesDashboardDocPage.tsx} | 18 +- ...dDocPage.tsx => FilesDashboardDocPage.tsx} | 18 +- .../GettingStartedDashboardDocPage.tsx | 191 +++++++ ....tsx => OrganizationsDashboardDocPage.tsx} | 18 +- ...ocPage.tsx => ReportsDashboardDocPage.tsx} | 16 +- ...rdDocPage.tsx => RootDashboardDocPage.tsx} | 10 +- .../dashboard/UpdatesDashboardDocPage.tsx | 8 +- ...dDocPage.tsx => YearsDashboardDocPage.tsx} | 16 +- .../gettingStartedDashboardDocPage.tsx | 110 ---- .../website/src/features/docs/docSections.tsx | 2 +- ...ralDocPage.tsx => LegalGeneralDocPage.tsx} | 8 +- ...lDocPage.tsx => PrivacyGeneralDocPage.tsx} | 8 +- ...eralDocPage.tsx => RootGeneralDocPage.tsx} | 6 +- ...lDocPage.tsx => SupportGeneralDocPage.tsx} | 6 +- ...ralDocPage.tsx => TermsGeneralDocPage.tsx} | 6 +- ...cPage.tsx => WhitepaperGeneralDocPage.tsx} | 6 +- .../{featureCard.tsx => FeatureCard.tsx} | 0 ...DocPage.tsx => FeaturesGeneralDocPage.tsx} | 4 +- .../pricing/{faqItem.tsx => FaqItem.tsx} | 0 ...lDocPage.tsx => PricingGeneralDocPage.tsx} | 6 +- .../error/{errorPage.tsx => ErrorPage.tsx} | 0 ...InvoiceViewer.tsx => UblInvoiceViewer.tsx} | 0 ...tionBanner.tsx => DocumentationBanner.tsx} | 2 +- .../home/{featureItem.tsx => FeatureItem.tsx} | 0 ...oIllustration.tsx => HeroIllustration.tsx} | 0 .../home/{homePage.tsx => HomePage.tsx} | 6 +- ...ionsBanner.tsx => OrganizationsBanner.tsx} | 4 +- .../home/{pricing.tsx => Pricing.tsx} | 4 +- .../{notFoundPage.tsx => NotFoundPage.tsx} | 4 +- ...ceXmlPage.tsx => PublicInvoiceXmlPage.tsx} | 0 ...PasswordPage.tsx => ResetPasswordPage.tsx} | 14 +- .../signIn/{signInPage.tsx => SignInPage.tsx} | 14 +- .../signUp/{signUpPage.tsx => SignUpPage.tsx} | 14 +- packages/website/src/root.tsx | 2 +- packages/website/src/routes/catchRoute.tsx | 2 +- .../root/dashboard/admin/adminLayoutRoute.tsx | 2 +- .../$idTicket/$idTicketLayoutRoute.tsx | 2 +- .../tickets/$idTicket/$idTicketRoute.tsx | 2 +- .../dashboard/admin/tickets/ticketsRoute.tsx | 2 +- .../root/dashboard/agent/agentLayoutRoute.tsx | 2 +- .../root/dashboard/agent/agentRoute.tsx | 2 +- .../dashboard/agent/agentSessionRoute.tsx | 2 +- .../root/dashboard/dashboardCatchRoute.tsx | 2 +- .../root/dashboard/dashboardLayoutRoute.tsx | 2 +- .../root/dashboard/dashboardRootRoute.tsx | 2 +- .../organizationApiKeysRoute.tsx | 2 +- .../organizationApiLayoutRoute.tsx | 2 +- .../organizationApi/organizationApiRoute.tsx | 2 +- .../organizationBillingHistoryRoute.tsx | 2 +- .../organizationBillingLayoutRoute.tsx | 2 +- .../organizationBillingRoute.tsx | 2 +- .../organizationBillingsRoute.tsx | 2 +- .../organizationInvoiceUblRoute.tsx | 2 +- .../organizationInvoicesRoute.tsx | 2 +- .../organizationLayoutRoute.tsx | 2 +- .../organizationSecurityRoute.tsx | 2 +- .../organizationSettingsLayoutRoute.tsx | 2 +- .../organizationSettingsRoute.tsx | 2 +- .../organizationUsersRoute.tsx | 2 +- .../storage/$idFile/fileLayoutRoute.tsx | 2 +- .../storage/$idFile/fileMetadataRoute.tsx | 2 +- .../storage/$idFile/fileRoute.tsx | 2 +- .../$idFile/fileVisualisationRoute.tsx | 2 +- .../$idOrganization/storage/storageRoute.tsx | 2 +- .../$idEntryLine/entryLineLayoutRoute.tsx | 2 +- .../$idEntryLine/entryLineMetadataRoute.tsx | 2 +- .../$idEntry/$idEntryLine/entryLineRoute.tsx | 2 +- .../entries/$idEntry/entryCategoriesRoute.tsx | 2 +- .../entries/$idEntry/entryLayoutRoute.tsx | 2 +- .../entries/$idEntry/entryLinesRoute.tsx | 2 +- .../entries/$idEntry/entryMetadataRoute.tsx | 2 +- .../$idYear/entries/$idEntry/entryRoute.tsx | 2 +- .../years/$idYear/entries/entriesRoute.tsx | 2 +- .../$idYear/files/$idFile/fileLayoutRoute.tsx | 2 +- .../files/$idFile/fileMetadataRoute.tsx | 2 +- .../years/$idYear/files/$idFile/fileRoute.tsx | 2 +- .../files/$idFile/fileVisualisationRoute.tsx | 2 +- .../years/$idYear/files/filesRoute.tsx | 2 +- .../$idYear/reports/balanceReportRoute.tsx | 2 +- .../reports/balanceSheetReportRoute.tsx | 2 +- .../reports/incomeStatementReportRoute.tsx | 2 +- .../$idYear/reports/journalReportRoute.tsx | 2 +- .../$idYear/reports/ledgerReportRoute.tsx | 2 +- .../$idYear/reports/reportsLayoutRoute.tsx | 2 +- .../years/$idYear/yearLayoutRoute.tsx | 2 +- .../$idAccount/accountLayoutRoute.tsx | 2 +- .../$idAccount/accountMetadataRoute.tsx | 2 +- .../accounts/$idAccount/accountRoute.tsx | 2 +- .../yearSettings/accounts/accountsRoute.tsx | 2 +- .../balanceSheetLayoutRoute.tsx | 2 +- .../balanceSheetMetadataRoute.tsx | 2 +- .../$idBalanceSheet/balanceSheetRoute.tsx | 2 +- .../balanceSheets/actif/actifRoute.tsx | 2 +- .../balanceSheets/passif/passifRoute.tsx | 2 +- .../incomeStatementLayoutRoute.tsx | 2 +- .../incomeStatementMetadataRoute.tsx | 2 +- .../incomeStatementRoute.tsx | 2 +- .../computationIncomeStatementLayoutRoute.tsx | 2 +- ...omputationIncomeStatementMetadataRoute.tsx | 2 +- .../computationIncomeStatementRoute.tsx | 2 +- .../$idComputation/computationLayoutRoute.tsx | 2 +- .../computationMetadataRoute.tsx | 2 +- .../$idComputation/computationPostesRoute.tsx | 2 +- .../$idComputation/computationRoute.tsx | 2 +- .../computations/computationsRoute.tsx | 2 +- .../incomeStatementsRoute.tsx | 2 +- .../$idJournal/journalLayoutRoute.tsx | 2 +- .../$idJournal/journalMetadataRoute.tsx | 2 +- .../journals/$idJournal/journalRoute.tsx | 2 +- .../yearSettings/journals/journalsRoute.tsx | 2 +- .../tags/$idTag/tagLayoutRoute.tsx | 2 +- .../tags/$idTag/tagMetadataRoute.tsx | 2 +- .../yearSettings/tags/$idTag/tagRoute.tsx | 2 +- .../$idYear/yearSettings/tags/tagsRoute.tsx | 2 +- .../yearSettings/yearSettingsLayoutRoute.tsx | 2 +- .../yearSettings/yearSettingsRoute.tsx | 2 +- .../$idOrganization/years/yearsRoute.tsx | 2 +- .../organizations/organizationsRoute.tsx | 2 +- .../dashboard/profile/userProfileRoute.tsx | 2 +- .../root/dashboard/settings/settingsRoute.tsx | 2 +- .../root/dashboard/support/supportRoute.tsx | 2 +- .../dashboard/support/ticketLayoutRoute.tsx | 2 +- .../root/dashboard/support/ticketRoute.tsx | 2 +- .../accountsAccountingDocRoute.tsx | 2 +- .../classesAccountingDocRoute.tsx | 2 +- .../doubleEntryAccountingDocRoute.tsx | 2 +- .../entriesAccountingDocRoute.tsx | 2 +- .../introductionAccountingDocRoute.tsx | 2 +- .../reports/balanceAccountingDocRoute.tsx | 2 +- .../balanceSheetAccountingDocRoute.tsx | 2 +- .../reports/fecAccountingDocRoute.tsx | 2 +- .../incomeStatementAccountingDocRoute.tsx | 2 +- .../reports/journalAccountingDocRoute.tsx | 2 +- .../reports/ledgerAccountingDocRoute.tsx | 2 +- .../reports/notesAccountingDocRoute.tsx | 2 +- .../reports/reportsAccountingDocRoute.tsx | 2 +- .../accounts/accountAccountingDocRoute.tsx | 2 +- .../accounts/accountsAccountingDocRoute.tsx | 2 +- .../glossary/glossaryAccountingDocRoute.tsx | 2 +- .../glossaryTermAccountingDocRoute.tsx | 2 +- .../scenarios/scenarioAccountingDocRoute.tsx | 2 +- .../scenarios/scenariosAccountingDocRoute.tsx | 2 +- .../accounting/rootAccountingDocRoute.tsx | 2 +- .../routes/root/docs/ai/modelsAiDocRoute.tsx | 2 +- .../src/routes/root/docs/ai/ocrAiDocRoute.tsx | 2 +- .../routes/root/docs/ai/rootAiDocRoute.tsx | 2 +- .../routes/root/docs/ai/toolsAiDocRoute.tsx | 2 +- .../docs/api/authenticationApiDocRoute.tsx | 2 +- .../routes/root/docs/api/filesApiDocRoute.tsx | 2 +- .../root/docs/api/introductionApiDocRoute.tsx | 2 +- .../root/docs/api/organizationApiDocRoute.tsx | 2 +- .../routes/root/docs/api/rootApiDocRoute.tsx | 2 +- .../routes/root/docs/api/yearApiDocRoute.tsx | 2 +- .../dashboard/entriesDashboardDocRoute.tsx | 2 +- .../docs/dashboard/filesDashboardDocRoute.tsx | 2 +- .../gettingStartedDashboardDocRoute.tsx | 2 +- .../organizationsDashboardDocRoute.tsx | 2 +- .../dashboard/reportsDashboardDocRoute.tsx | 2 +- .../docs/dashboard/rootDashboardDocRoute.tsx | 2 +- .../docs/dashboard/yearsDashboardDocRoute.tsx | 2 +- .../src/routes/root/docs/docsLayoutRoute.tsx | 2 +- .../docs/root/featuresGeneralDocRoute.tsx | 2 +- .../root/docs/root/legalGeneralDocRoute.tsx | 2 +- .../root/docs/root/pricingGeneralDocRoute.tsx | 2 +- .../root/docs/root/privacyGeneralDocRoute.tsx | 2 +- .../root/docs/root/rootGeneralDocRoute.tsx | 2 +- .../root/docs/root/supportGeneralDocRoute.tsx | 2 +- .../root/docs/root/termsGeneralDocRoute.tsx | 2 +- .../docs/root/whitepaperGeneralDocRoute.tsx | 2 +- .../website/src/routes/root/errorRoute.tsx | 2 +- .../src/routes/root/home/homeRootRoute.tsx | 2 +- .../src/routes/root/publicInvoiceXmlRoute.tsx | 2 +- .../routes/root/signIn/resetPasswordRoute.tsx | 2 +- .../src/routes/root/signIn/signInRoute.tsx | 2 +- .../src/routes/root/signUp/signUpRoute.tsx | 2 +- .../website/src/routes/rootLayoutRoute.tsx | 2 +- 647 files changed, 3612 insertions(+), 2484 deletions(-) create mode 100644 packages/ui/src/components/buttons/Button.tsx rename packages/ui/src/components/buttons/{buttonGhostContent.tsx => ButtonGhostContent.tsx} (98%) rename packages/ui/src/components/buttons/{buttonOutlineContent.tsx => ButtonOutlineContent.tsx} (98%) rename packages/ui/src/components/buttons/{buttonPlainContent.tsx => ButtonPlainContent.tsx} (98%) rename packages/ui/src/components/buttons/{linkButton.tsx => LinkButton.tsx} (100%) rename packages/ui/src/components/buttons/{linkContent.tsx => LinkContent.tsx} (100%) create mode 100644 packages/ui/src/components/buttons/useButtonLoading.tsx rename packages/ui/src/components/formats/{formatBase.tsx => FormatBase.tsx} (100%) rename packages/ui/src/components/formats/{formatError.tsx => FormatError.tsx} (94%) rename packages/ui/src/components/formats/{formatLink.tsx => FormatLink.tsx} (91%) rename packages/ui/src/components/formats/{formatNull.tsx => FormatNull.tsx} (100%) rename packages/ui/src/components/formats/{formatText.tsx => FormatText.tsx} (94%) create mode 100644 packages/ui/src/components/formats/display/FormatBoolean.tsx create mode 100644 packages/ui/src/components/formats/display/FormatDate.tsx create mode 100644 packages/ui/src/components/formats/display/FormatDateTime.tsx create mode 100644 packages/ui/src/components/formats/display/FormatFileSize.tsx create mode 100644 packages/ui/src/components/formats/display/FormatPrice.tsx create mode 100644 packages/ui/src/components/formats/display/FormatSelect.tsx rename packages/ui/src/components/inputs/{inputCheckbox.tsx => InputCheckbox.tsx} (100%) rename packages/ui/src/components/inputs/{inputCombobox.tsx => InputCombobox.tsx} (95%) rename packages/ui/src/components/inputs/{inputComboboxMultiple.tsx => InputComboboxMultiple.tsx} (95%) rename packages/ui/src/components/inputs/{inputCurrency.tsx => InputCurrency.tsx} (100%) rename packages/ui/src/components/inputs/{inputDate.tsx => InputDate.tsx} (100%) rename packages/ui/src/components/inputs/{inputDebounced.tsx => InputDebounced.tsx} (100%) rename packages/ui/src/components/inputs/{inputDisabled.tsx => InputDisabled.tsx} (100%) rename packages/ui/src/components/inputs/{inputFile.tsx => InputFile.tsx} (98%) rename packages/ui/src/components/inputs/{inputNumber.tsx => InputNumber.tsx} (95%) rename packages/ui/src/components/inputs/{inputPassword.tsx => InputPassword.tsx} (98%) rename packages/ui/src/components/inputs/{inputPrice.tsx => InputPrice.tsx} (100%) rename packages/ui/src/components/inputs/{inputRating.tsx => InputRating.tsx} (100%) rename packages/ui/src/components/inputs/{inputSelect.tsx => InputSelect.tsx} (95%) rename packages/ui/src/components/inputs/{inputSwitch.tsx => InputSwitch.tsx} (100%) rename packages/ui/src/components/inputs/{inputText.tsx => InputText.tsx} (100%) rename packages/ui/src/components/inputs/{inputTextArea.tsx => InputTextArea.tsx} (100%) rename packages/ui/src/components/inputs/{inputToggle.tsx => InputToggle.tsx} (96%) rename packages/ui/src/components/layouts/{badge.tsx => Badge.tsx} (100%) rename packages/ui/src/components/layouts/{chip.tsx => Chip.tsx} (100%) rename packages/ui/src/components/layouts/{circularLoader.tsx => CircularLoader.tsx} (100%) rename packages/ui/src/components/layouts/{kbd.tsx => Kbd.tsx} (100%) rename packages/ui/src/components/layouts/{logo.tsx => Logo.tsx} (100%) rename packages/ui/src/components/layouts/{pageNavigation.tsx => PageNavigation.tsx} (95%) rename packages/ui/src/components/layouts/{separator.tsx => Separator.tsx} (100%) rename packages/ui/src/components/layouts/{virtualizer.tsx => Virtualizer.tsx} (100%) rename packages/ui/src/components/overlays/popover/{popoverContent.tsx => PopoverContent.tsx} (100%) rename packages/ui/src/components/overlays/toast/{toastItem.tsx => ToastItem.tsx} (96%) rename packages/ui/src/components/overlays/toast/{toastViewport.tsx => ToastViewport.tsx} (100%) rename packages/ui/src/components/overlays/toast/{toastProvider.tsx => ToasterProvider.tsx} (100%) rename packages/website/src/components/{inputDataCombobox.tsx => InputDataCombobox.tsx} (100%) rename packages/website/src/components/{linkButton.tsx => LinkButton.tsx} (100%) rename packages/website/src/components/document/{docDefinition.tsx => DocDefinition.tsx} (97%) rename packages/website/src/components/document/{docExample.tsx => DocExample.tsx} (90%) rename packages/website/src/components/document/{docGlossaryEntry.tsx => DocGlossaryEntry.tsx} (89%) rename packages/website/src/components/document/{docHeader.tsx => DocHeader.tsx} (100%) rename packages/website/src/components/document/{docIndexLink.tsx => DocIndexLink.tsx} (95%) rename packages/website/src/components/document/{docLastUpdate.tsx => DocLastUpdate.tsx} (100%) rename packages/website/src/components/document/{docLink.tsx => DocLink.tsx} (94%) rename packages/website/src/components/document/{docLinkCard.tsx => DocLinkCard.tsx} (98%) rename packages/website/src/components/document/{docList.tsx => DocList.tsx} (100%) rename packages/website/src/components/document/{docNextPage.tsx => DocNextPage.tsx} (97%) rename packages/website/src/components/document/{docParagraph.tsx => DocParagraph.tsx} (100%) rename packages/website/src/components/document/{docRoot.tsx => DocRoot.tsx} (100%) rename packages/website/src/components/document/{docRouteRequest.tsx => DocRouteRequest.tsx} (100%) rename packages/website/src/components/document/{docSection.tsx => DocSection.tsx} (100%) rename packages/website/src/components/document/{docSectionCard.tsx => DocSectionCard.tsx} (99%) rename packages/website/src/components/document/{docSourceRef.tsx => DocSourceRef.tsx} (100%) rename packages/website/src/components/document/{docSources.tsx => DocSources.tsx} (100%) rename packages/website/src/components/document/{docTable.tsx => DocTable.tsx} (100%) rename packages/website/src/components/document/{docTextSection.tsx => DocTextSection.tsx} (100%) rename packages/website/src/components/document/{docTip.tsx => DocTip.tsx} (100%) rename packages/website/src/components/forms/{formControl.tsx => FormControl.tsx} (100%) rename packages/website/src/components/forms/{formError.tsx => FormError.tsx} (100%) rename packages/website/src/components/forms/{formField.tsx => FormField.tsx} (100%) rename packages/website/src/components/forms/{formGroup.tsx => FormGroup.tsx} (100%) rename packages/website/src/components/forms/{formItem.tsx => FormItem.tsx} (100%) rename packages/website/src/components/forms/{formLabel.tsx => FormLabel.tsx} (100%) rename packages/website/src/components/forms/{formRoot.tsx => FormRoot.tsx} (100%) rename packages/website/src/components/forms/{formSubmit.tsx => FormSubmit.tsx} (100%) rename packages/website/src/components/layouts/{banner.tsx => Banner.tsx} (100%) rename packages/website/src/components/layouts/{box.tsx => Box.tsx} (100%) rename packages/website/src/components/layouts/{columnVisibilityPopover.tsx => ColumnVisibilityPopover.tsx} (100%) rename packages/website/src/components/layouts/{dataTable.tsx => DataTable.tsx} (99%) rename packages/website/src/components/layouts/{dataWrapper.tsx => DataWrapper.tsx} (100%) rename packages/website/src/components/layouts/{emptyState.tsx => EmptyState.tsx} (100%) rename packages/website/src/components/layouts/{filterPopover.tsx => FilterPopover.tsx} (100%) rename packages/website/src/components/layouts/{logo.tsx => Logo.tsx} (100%) rename packages/website/src/components/layouts/{searchBar.tsx => SearchBar.tsx} (100%) rename packages/website/src/components/layouts/{sortPopover.tsx => SortPopover.tsx} (100%) rename packages/website/src/components/layouts/{subPageContent.tsx => SubPageContent.tsx} (100%) rename packages/website/src/components/layouts/{subPageLayout.tsx => SubPageLayout.tsx} (99%) rename packages/website/src/components/layouts/{title.tsx => TitleComponent.tsx} (100%) rename packages/website/src/components/layouts/{virtualizer.tsx => Virtualizer.tsx} (100%) rename packages/website/src/components/layouts/card/{cardContent.tsx => CardContent.tsx} (100%) rename packages/website/src/components/layouts/card/{cardHeader.tsx => CardHeader.tsx} (100%) rename packages/website/src/components/layouts/card/{cardRoot.tsx => CardRoot.tsx} (100%) create mode 100644 packages/website/src/components/layouts/commandPalette/CommandPalette.tsx create mode 100644 packages/website/src/components/layouts/commandPalette/ContextSelect.tsx rename packages/website/src/components/layouts/dataBlock/{dataBlockContent.tsx => DataBlockContent.tsx} (100%) rename packages/website/src/components/layouts/dataBlock/{dataBlockHeader.tsx => DataBlockHeader.tsx} (100%) rename packages/website/src/components/layouts/dataBlock/{dataBlockItem.tsx => DataBlockItem.tsx} (100%) rename packages/website/src/components/layouts/dataBlock/{dataBlockRoot.tsx => DataBlockRoot.tsx} (100%) rename packages/website/src/components/layouts/listTable/{listTableFilterable.tsx => ListTableFilterable.tsx} (97%) rename packages/website/src/components/layouts/listTable/{listTableRoot.tsx => ListTableRoot.tsx} (100%) rename packages/website/src/components/layouts/listTable/{listTableRow.tsx => ListTableRow.tsx} (100%) rename packages/website/src/components/layouts/page/{pageContent.tsx => PageContent.tsx} (100%) rename packages/website/src/components/layouts/page/{pageDescription.tsx => PageDescription.tsx} (100%) rename packages/website/src/components/layouts/page/{pageHeader.tsx => PageHeader.tsx} (100%) rename packages/website/src/components/layouts/page/{pageNavigation.tsx => PageNavigation.tsx} (100%) rename packages/website/src/components/layouts/page/{pageRoot.tsx => PageRoot.tsx} (100%) rename packages/website/src/components/layouts/page/{pageSeparator.tsx => PageSeparator.tsx} (100%) rename packages/website/src/components/layouts/page/{pageTitle.tsx => PageTitle.tsx} (100%) rename packages/website/src/components/layouts/section/{sectionItem.tsx => SectionItem.tsx} (100%) rename packages/website/src/components/layouts/section/{sectionRoot.tsx => SectionRoot.tsx} (100%) rename packages/website/src/components/layouts/settingsSection/{settingsSectionHeader.tsx => SettingsSectionHeader.tsx} (100%) rename packages/website/src/components/layouts/settingsSection/{settingsSectionRoot.tsx => SettingsSectionRoot.tsx} (100%) rename packages/website/src/components/layouts/settingsSection/{settingsSectionRow.tsx => SettingsSectionRow.tsx} (100%) rename packages/website/src/components/layouts/tab/{tabRoot.tsx => TabRoot.tsx} (97%) rename packages/website/src/components/layouts/tabBar/{splitTabBar.tsx => SplitTabBar.tsx} (67%) create mode 100644 packages/website/src/components/layouts/tabBar/TabBar.tsx rename packages/website/src/components/layouts/tabBar/{tabLink.tsx => TabLink.tsx} (96%) delete mode 100644 packages/website/src/components/layouts/tabBar/tabBar.tsx rename packages/website/src/components/layouts/table/{tableRoot.tsx => TableRoot.tsx} (100%) rename packages/website/src/components/layouts/table/tableBody/{tableBodyCell.tsx => TableBodyCell.tsx} (100%) rename packages/website/src/components/layouts/table/tableBody/{tableBodyRow.tsx => TableBodyRow.tsx} (100%) rename packages/website/src/components/layouts/table/tableHeader/{tableHeaderCell.tsx => TableHeaderCell.tsx} (100%) rename packages/website/src/components/layouts/table/tableHeader/{tableHeaderRoot.tsx => TableHeaderRoot.tsx} (100%) rename packages/website/src/components/layouts/table/tableHeader/{tableHeaderRow.tsx => TableHeaderRow.tsx} (100%) rename packages/website/src/components/overlays/contextMenu/{contextMenuContent.tsx => ContextMenuContent.tsx} (100%) rename packages/website/src/components/overlays/contextMenu/{contextMenuItem.tsx => ContextMenuItem.tsx} (80%) rename packages/website/src/components/overlays/contextMenu/{contextMenuRoot.tsx => ContextMenuRoot.tsx} (100%) rename packages/website/src/components/overlays/contextMenu/{contextMenuSeparator.tsx => ContextMenuSeparator.tsx} (100%) rename packages/website/src/components/overlays/contextMenu/{contextMenuTrigger.tsx => ContextMenuTrigger.tsx} (100%) rename packages/website/src/components/overlays/dialog/{confirmationModal.tsx => ConfirmationModal.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogBody.tsx => DialogBody.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogContent.tsx => DialogContent.tsx} (97%) rename packages/website/src/components/overlays/dialog/{dialogDescription.tsx => DialogDescription.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogFooter.tsx => DialogFooter.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogHeader.tsx => DialogHeader.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogOverlay.tsx => DialogOverlay.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogRoot.tsx => DialogRoot.tsx} (100%) rename packages/website/src/components/overlays/dialog/{dialogTitle.tsx => DialogTitle.tsx} (100%) rename packages/website/src/components/overlays/popover/{popoverContent.tsx => PopoverContent.tsx} (100%) rename packages/website/src/components/overlays/tooltip/{tooltipContent.tsx => TooltipContent.tsx} (100%) rename packages/website/src/contexts/{rootProvider.tsx => RootProvider.tsx} (79%) create mode 100644 packages/website/src/contexts/dashboard/DashboardContextProvider.tsx create mode 100644 packages/website/src/contexts/dashboard/dashboardContext.tsx rename packages/website/src/contexts/data/{dataProvider.tsx => DataProvider.tsx} (100%) rename packages/website/src/contexts/router/{routerProvider.tsx => RouterProvider.tsx} (100%) create mode 100644 packages/website/src/contexts/tabs/TabContentArea.tsx create mode 100644 packages/website/src/contexts/tabs/useTabs.tsx rename packages/website/src/features/{breadcrumbs.tsx => Breadcrumbs.tsx} (98%) rename packages/website/src/features/{rootLayout.tsx => RootLayout.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/{organizationLayout.tsx => OrganizationLayout.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/{organizationTabContent.tsx => OrganizationTabContent.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentLayout.tsx => AgentLayout.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentMessage.tsx => AgentMessage.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentMessagePart.tsx => AgentMessagePart.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentPage.tsx => AgentPage.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentSessionContent.tsx => AgentSessionContent.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentSessionPage.tsx => AgentSessionPage.tsx} (84%) rename packages/website/src/features/dashboard/$idOrganization/agent/{agentTabContent.tsx => AgentTabContent.tsx} (97%) rename packages/website/src/features/dashboard/$idOrganization/agent/{mentionInput.tsx => MentionInput.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/{organizationApiGeneralPage.tsx => OrganizationApiGeneralPage.tsx} (95%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/{organizationApiLayout.tsx => OrganizationApiLayout.tsx} (95%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/{organizationApiTabContent.tsx => OrganizationApiTabContent.tsx} (88%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/{apiKeyListTableRow.tsx => ApiKeyListTableRow.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/{apiKeysListTable.tsx => ApiKeysListTable.tsx} (87%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/{createOneApiKey.tsx => CreateOneApiKey.tsx} (90%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/{deleteOneApiKey.tsx => DeleteOneApiKey.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/{organizationApiKeysPage.tsx => OrganizationApiKeysPage.tsx} (92%) rename packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/{rawKeyDisplay.tsx => RawKeyDisplay.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{cancelSubscription.tsx => CancelSubscription.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{organizationBillingHistoryPage.tsx => OrganizationBillingHistoryPage.tsx} (96%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{organizationBillingLayout.tsx => OrganizationBillingLayout.tsx} (97%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{organizationBillingTabContent.tsx => OrganizationBillingTabContent.tsx} (89%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{organizationServicesPage.tsx => OrganizationServicesPage.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{resumeSubscription.tsx => ResumeSubscription.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{updateLicencePage.tsx => UpdateLicencePage.tsx} (97%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{updateOcrPage.tsx => UpdateOcrPage.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{updateStoragePage.tsx => UpdateStoragePage.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/{updateTokensPage.tsx => UpdateTokensPage.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/{organizationInvoicePage.tsx => OrganizationInvoicePage.tsx} (97%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/{organizationInvoicesPage.tsx => OrganizationInvoicesPage.tsx} (94%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/{organizationWalletPage.tsx => OrganizationWalletPage.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/{walletCurrentMonth.tsx => WalletCurrentMonth.tsx} (99%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/{walletTopUpPage.tsx => WalletTopUpPage.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/{walletWithdrawalPage.tsx => WalletWithdrawalPage.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationSettings/{deleteOneOrganization.tsx => DeleteOneOrganization.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationSettings/{organizationSecurityPage.tsx => OrganizationSecurityPage.tsx} (94%) rename packages/website/src/features/dashboard/$idOrganization/organizationSettings/{organizationSettingsLayout.tsx => OrganizationSettingsLayout.tsx} (95%) rename packages/website/src/features/dashboard/$idOrganization/organizationSettings/{organizationSettingsPage.tsx => OrganizationSettingsPage.tsx} (94%) rename packages/website/src/features/dashboard/$idOrganization/organizationSettings/{organizationSettingsTabContent.tsx => OrganizationSettingsTabContent.tsx} (89%) rename packages/website/src/features/dashboard/$idOrganization/organizationSettings/{updateOneOrganization.tsx => UpdateOneOrganization.tsx} (94%) rename packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/{deleteOneOrganizationUser.tsx => DeleteOneOrganizationUser.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/{updateOneOrganizationUser.tsx => UpdateOneOrganizationUser.tsx} (92%) rename packages/website/src/features/dashboard/$idOrganization/organizationUsers/{createOneOrganizationUser.tsx => CreateOneOrganizationUser.tsx} (94%) rename packages/website/src/features/dashboard/$idOrganization/organizationUsers/{organizationUserListTableRow.tsx => OrganizationUserListTableRow.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/organizationUsers/{organizationUsersListTable.tsx => OrganizationUsersListTable.tsx} (88%) rename packages/website/src/features/dashboard/$idOrganization/organizationUsers/{organizationUsersPage.tsx => OrganizationUsersPage.tsx} (92%) rename packages/website/src/features/dashboard/$idOrganization/years/{createOneYear.tsx => CreateOneYear.tsx} (90%) rename packages/website/src/features/dashboard/$idOrganization/years/{yearListTableRow.tsx => YearListTableRow.tsx} (98%) rename packages/website/src/features/dashboard/$idOrganization/years/{yearSelect.tsx => YearSelect.tsx} (100%) rename packages/website/src/features/dashboard/$idOrganization/years/{yearsListTable.tsx => YearsListTable.tsx} (87%) rename packages/website/src/features/dashboard/$idOrganization/years/{yearsPage.tsx => YearsPage.tsx} (93%) create mode 100644 packages/website/src/features/dashboard/$idYear/YearDataProvider.tsx rename packages/website/src/features/dashboard/$idYear/{yearDataWrapper.tsx => YearDataWrapper.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/{yearLayout.tsx => YearLayout.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/{deleteOneEntryLine.tsx => DeleteOneEntryLine.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/{entryLineLayout.tsx => EntryLineLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/{entryLineMetadataTab.tsx => EntryLineMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/{entryLinePage.tsx => EntryLinePage.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/{updateOneEntryLine.tsx => UpdateOneEntryLine.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{createOneEntryLine.tsx => CreateOneEntryLine.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{deleteOneEntry.tsx => DeleteOneEntry.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{duplicateOneEntry.tsx => DuplicateOneEntry.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{entryCategoriesTab.tsx => EntryCategoriesTab.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{entryLayout.tsx => EntryLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{entryLinesTab.tsx => EntryLinesTab.tsx} (91%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{entryLinesTable.tsx => EntryLinesTable.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{entryMetadataTab.tsx => EntryMetadataTab.tsx} (94%) create mode 100644 packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryPage.tsx create mode 100644 packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{entryTabContent.tsx => EntryTabContent.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{updateManyEntryLines.tsx => UpdateManyEntryLines.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{updateOneEntry.tsx => UpdateOneEntry.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/entries/{createOneEntry.tsx => CreateOneEntry.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/entries/{entriesPage.tsx => EntriesPage.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/entries/{entriesTable.tsx => EntriesTable.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/entries/{entriesTableSelectionActions.tsx => EntriesTableSelectionActions.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/entries/{exportEntryLines.tsx => ExportEntryLines.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/entries/{exportFecFile.tsx => ExportFecFile.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/{importFecFile.tsx => ImportFecFile.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/entries/{reverseOneEntry.tsx => ReverseOneEntry.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/entries/entryTemplates/{amortizationTemplate.tsx => AmortizationTemplateForm.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{deleteOneFile.tsx => DeleteOneFile.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{fileData.tsx => FileData.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{fileFile.tsx => FileFile.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{fileLayout.tsx => FileLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{fileMetadataTab.tsx => FileMetadataTab.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{filePage.tsx => FilePage.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{fileTabContent.tsx => FileTabContent.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{fileVisualisationTab.tsx => FileVisualisationTab.tsx} (91%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{updateOneFile.tsx => UpdateOneFile.tsx} (91%) rename packages/website/src/features/dashboard/$idYear/files/$idFile/{updateOneFileForm.tsx => UpdateOneFileForm.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/files/{createOneFile.tsx => CreateOneFile.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/files/{createOneFolder.tsx => CreateOneFolder.tsx} (91%) rename packages/website/src/features/dashboard/$idYear/files/{fileActions.tsx => FileActions.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/files/{fileContextMenu.tsx => FileContextMenu.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/files/{fileSelect.tsx => FileSelect.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/files/{filesGrid.tsx => FilesGrid.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/files/{filesPage.tsx => FilesPage.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/files/{filesPageContent.tsx => FilesPageContent.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/files/{filesTable.tsx => FilesTable.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/files/{filesTableSelectionActions.tsx => FilesTableSelectionActions.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/files/{folderActions.tsx => FolderActions.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/files/{folderContextMenu.tsx => FolderContextMenu.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/files/{moveOneFileForm.tsx => MoveOneFileForm.tsx} (91%) rename packages/website/src/features/dashboard/$idYear/files/{moveOneFolderForm.tsx => MoveOneFolderForm.tsx} (93%) rename packages/website/src/features/dashboard/$idYear/files/{updateOneFolderForm.tsx => UpdateOneFolderForm.tsx} (88%) rename packages/website/src/features/dashboard/$idYear/reports/{reportFilterPopover.tsx => ReportFilterPopover.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/{reportsLayout.tsx => ReportsLayout.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/reports/{reportsTabContent.tsx => ReportsTabContent.tsx} (90%) rename packages/website/src/features/dashboard/$idYear/reports/balanceReport/{balanceReportPage.tsx => BalanceReportPage.tsx} (93%) rename packages/website/src/features/dashboard/$idYear/reports/balanceReport/{balanceReportTable.tsx => BalanceReportTable.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/{balanceSheetReportPage.tsx => BalanceSheetReportPage.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/{balanceSheetReportPdf.tsx => BalanceSheetReportPdf.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/{downloadBalanceSheetReport.tsx => DownloadBalanceSheetReport.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/{balanceSheetAssetsReportItem.tsx => BalanceSheetAssetsReportItem.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/{balanceSheetAssetsReportRow.tsx => BalanceSheetAssetsReportRow.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/{balanceSheetAssetsReportTable.tsx => BalanceSheetAssetsReportTable.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/{balanceSheetLiabilitiesReportItem.tsx => BalanceSheetLiabilitiesReportItem.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/{balanceSheetLiabilityiesReportRow.tsx => BalanceSheetLiabilitiesReportRow.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/{balanceSheetLiabilitiesReportTable.tsx => BalanceSheetLiabilitiesReportTable.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/{downloadIncomeStatementReport.tsx => DownloadIncomeStatementReport.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/{incomeStatementReportItem.tsx => IncomeStatementReportItem.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/{incomeStatementReportPage.tsx => IncomeStatementReportPage.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/{incomeStatementReportPdf.tsx => IncomeStatementReportPdf.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/{incomeStatementReportRow.tsx => IncomeStatementReportRow.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/{incomeStatementsReportTable.tsx => IncomeStatementsReportTable.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/reports/journalReport/{journalReportPage.tsx => JournalReportPage.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/reports/journalReport/{journalReportTable.tsx => JournalReportTable.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/reports/ledgerReport/{ledgerReportPage.tsx => LedgerReportPage.tsx} (93%) rename packages/website/src/features/dashboard/$idYear/reports/ledgerReport/{ledgerReportTable.tsx => LedgerReportTable.tsx} (100%) create mode 100644 packages/website/src/features/dashboard/$idYear/useYearData.tsx rename packages/website/src/features/dashboard/$idYear/yearSettings/{deleteOneYear.tsx => DeleteOneYear.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/{updateOneYear.tsx => UpdateOneYear.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/{yearSettingsLayout.tsx => YearSettingsLayout.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/{yearSettingsPage.tsx => YearSettingsPage.tsx} (93%) rename packages/website/src/features/dashboard/$idYear/yearSettings/{yearSettingsTabContent.tsx => YearSettingsTabContent.tsx} (92%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/{accountLayout.tsx => AccountLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/{accountMetadataTab.tsx => AccountMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/{accountPage.tsx => AccountPage.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/{deleteOneAccount.tsx => DeleteOneAccount.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/{updateOneAccount.tsx => UpdateOneAccount.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/{accountSelect.tsx => AccountSelect.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/{accountsPage.tsx => AccountsPage.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/{accountsTable.tsx => AccountsTable.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/accounts/{createOneAccount.tsx => CreateOneAccount.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/{balanceSheetLayout.tsx => BalanceSheetLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/{balanceSheetMetadataTab.tsx => BalanceSheetMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/{balanceSheetPage.tsx => BalanceSheetPage.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/{deleteOneBalanceSheet.tsx => DeleteOneBalanceSheet.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/{updateOneBalanceSheet.tsx => UpdateOneBalanceSheet.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/{balanceSheetItem.tsx => BalanceSheetItem.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/{balanceSheetRow.tsx => BalanceSheetRow.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/{balanceSheetTable.tsx => BalanceSheetTable.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/{balanceSheetsPage.tsx => BalanceSheetsPage.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/{balanceSheetSelect.tsx => BalanceSheetsSelect.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/{createOneBalanceSheet.tsx => CreateOneBalanceSheet.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/{deleteOneIncomeStatement.tsx => DeleteOneIncomeStatement.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/{incomeStatementLayout.tsx => IncomeStatementLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/{incomeStatementMetadataTab.tsx => IncomeStatementMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/{incomeStatementPage.tsx => IncomeStatementPage.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/{updateOneIncomeStatement.tsx => UpdateOneIncomeStatement.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/{createOneIncomeStatement.tsx => CreateOneIncomeStatement.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/{incomeStatementItem.tsx => IncomeStatementItem.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/{incomeStatementRow.tsx => IncomeStatementRow.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/{incomeStatementsPage.tsx => IncomeStatementsPage.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/{incomeStatementsTable.tsx => IncomeStatementsTable.tsx} (95%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/{computationLayout.tsx => ComputationLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/{computationMetadataTab.tsx => ComputationMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/{computationPage.tsx => ComputationPage.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/{computationPostesTab.tsx => ComputationPostesTab.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/{deleteOneComputation.tsx => DeleteOneComputation.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/{updateOneComputation.tsx => UpdateOneComputation.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/{computationIncomeStatementLayout.tsx => ComputationIncomeStatementLayout.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/{computationIncomeStatementMetadataTab.tsx => ComputationIncomeStatementMetadataTab.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/{computationIncomeStatementPage.tsx => ComputationIncomeStatementPage.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/{deleteOneComputationIncomeStatement.tsx => DeleteOneComputationIncomeStatement.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/{updateOneComputationIncomeStatement.tsx => UpdateOneComputationIncomeStatement.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/{computationIncomeStatementTable.tsx => ComputationIncomeStatementsTable.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/{createOneComputationIncomeStatement.tsx => CreateOneComputationIncomeStatement.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/{computationsPage.tsx => ComputationsPage.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/{computationsTable.tsx => ComputationsTable.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/{createOneComputation.tsx => CreateOneComputation.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/{deleteOneJournal.tsx => DeleteOneJournal.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/{journalLayout.tsx => JournalLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/{journalMetadataTab.tsx => JournalMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/{journalPage.tsx => JournalPage.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/{updateOneJournal.tsx => UpdateOneJournal.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/{createOneJournal.tsx => CreateOneJournal.tsx} (93%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/{journalListTableRow.tsx => JournalListTableRow.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/{journalSelect.tsx => JournalSelect.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/{journalsListTable.tsx => JournalsListTable.tsx} (89%) rename packages/website/src/features/dashboard/$idYear/yearSettings/journals/{journalsPage.tsx => JournalsPage.tsx} (94%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/{deleteOneTag.tsx => DeleteOneTag.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/{tagLayout.tsx => TagLayout.tsx} (96%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/{tagMetadataTab.tsx => TagMetadataTab.tsx} (99%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/{tagPage.tsx => TagPage.tsx} (98%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/{updateOneTag.tsx => UpdateOneTag.tsx} (93%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/{createOneTag.tsx => CreateOneTag.tsx} (91%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/{tagListTableRow.tsx => TagListTableRow.tsx} (97%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/{tagSelect.tsx => TagSelect.tsx} (100%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/{tagsListTable.tsx => TagsListTable.tsx} (89%) rename packages/website/src/features/dashboard/$idYear/yearSettings/tags/{tagsPage.tsx => TagsPage.tsx} (95%) rename packages/website/src/features/dashboard/{dashboardDefaultPage.tsx => DashboardDefaultPage.tsx} (100%) rename packages/website/src/features/dashboard/{dashboardNotFoundPage.tsx => DashboardNotFoundPage.tsx} (96%) rename packages/website/src/features/dashboard/admin/{adminPanelLayout.tsx => AdminPanelLayout.tsx} (100%) rename packages/website/src/features/dashboard/admin/tickets/$idTicket/{adminTicketTabContent.tsx => AdminTicketTabContent.tsx} (94%) rename packages/website/src/features/dashboard/admin/tickets/$idTicket/{createOneTicketMessage.tsx => CreateOneTicketMessage.tsx} (100%) rename packages/website/src/features/dashboard/admin/tickets/$idTicket/{statusToggle.tsx => StatusToggle.tsx} (100%) rename packages/website/src/features/dashboard/admin/tickets/$idTicket/{ticketLayout.tsx => TicketLayout.tsx} (95%) rename packages/website/src/features/dashboard/admin/tickets/$idTicket/{ticketMessageList.tsx => TicketMessageList.tsx} (100%) rename packages/website/src/features/dashboard/admin/tickets/$idTicket/{ticketPage.tsx => TicketPage.tsx} (98%) rename packages/website/src/features/dashboard/admin/tickets/{ticketsPage.tsx => TicketsPage.tsx} (65%) delete mode 100644 packages/website/src/features/dashboard/dashboardLayout.tsx create mode 100644 packages/website/src/features/dashboard/dashboardLayout/DashboardLayout.tsx rename packages/website/src/features/dashboard/{dashboardShell.tsx => dashboardLayout/DashboardShell.tsx} (77%) rename packages/website/src/features/dashboard/organizations/{addNewOrganization.tsx => AddNewOrganization.tsx} (91%) rename packages/website/src/features/dashboard/organizations/{organizationListTableRow.tsx => OrganizationListTableRow.tsx} (98%) rename packages/website/src/features/dashboard/organizations/{organizationsListTable.tsx => OrganizationsListTable.tsx} (87%) rename packages/website/src/features/dashboard/organizations/{organizationsPage.tsx => OrganizationsPage.tsx} (90%) rename packages/website/src/features/dashboard/profile/{deleteUser.tsx => DeleteUser.tsx} (91%) rename packages/website/src/features/dashboard/profile/{updateUserEmail.tsx => UpdateUserEmail.tsx} (93%) rename packages/website/src/features/dashboard/profile/{updateUserPassword.tsx => UpdateUserPassword.tsx} (93%) rename packages/website/src/features/dashboard/profile/{userProfilePage.tsx => UserProfilePage.tsx} (93%) rename packages/website/src/features/dashboard/profile/{validateUserEmail.tsx => ValidateUserEmail.tsx} (100%) rename packages/website/src/features/dashboard/settings/{settingsPage.tsx => SettingsPage.tsx} (100%) rename packages/website/src/features/dashboard/support/$idTicket/{createOneTicketMessage.tsx => CreateOneTicketMessage.tsx} (89%) rename packages/website/src/features/dashboard/support/$idTicket/{statusToggle.tsx => StatusToggle.tsx} (100%) rename packages/website/src/features/dashboard/support/$idTicket/{ticketLayout.tsx => TicketLayout.tsx} (94%) rename packages/website/src/features/dashboard/support/$idTicket/{ticketMessageList.tsx => TicketMessageList.tsx} (100%) rename packages/website/src/features/dashboard/support/$idTicket/{ticketPage.tsx => TicketPage.tsx} (97%) rename packages/website/src/features/dashboard/support/$idTicket/{ticketTabContent.tsx => TicketTabContent.tsx} (92%) rename packages/website/src/features/dashboard/support/{createOneTicket.tsx => CreateOneTicket.tsx} (94%) rename packages/website/src/features/dashboard/support/{supportPage.tsx => SupportPage.tsx} (94%) rename packages/website/src/features/dashboard/support/{ticketListTableRow.tsx => TicketListTableRow.tsx} (98%) rename packages/website/src/features/dashboard/support/{ticketsListTable.tsx => TicketsListTable.tsx} (87%) rename packages/website/src/features/docs/{docsLayout.tsx => DocsLayout.tsx} (98%) rename packages/website/src/features/docs/{docsSearch.tsx => DocsSearch.tsx} (100%) rename packages/website/src/features/docs/{sectionTab.tsx => SectionTab.tsx} (94%) rename packages/website/src/features/docs/{sidebarNavigation.tsx => SidebarNavigation.tsx} (98%) rename packages/website/src/features/docs/accounting/introduction/{accountsAccountingDocPage.tsx => AccountsAccountingDocPage.tsx} (95%) rename packages/website/src/features/docs/accounting/introduction/{classesAccountingDocPage.tsx => ClassesAccountingDocPage.tsx} (95%) rename packages/website/src/features/docs/accounting/introduction/{doubleEntryAccountingDocPage.tsx => DoubleEntryAccountingDocPage.tsx} (95%) rename packages/website/src/features/docs/accounting/introduction/{entriesAccountingDocPage.tsx => EntriesAccountingDocPage.tsx} (96%) rename packages/website/src/features/docs/accounting/introduction/{introductionAccountingDocPage.tsx => IntroductionAccountingDocPage.tsx} (92%) rename packages/website/src/features/docs/accounting/introduction/{rootAccountingDocPage.tsx => RootAccountingDocPage.tsx} (83%) rename packages/website/src/features/docs/accounting/reports/{balanceAccountingDocPage.tsx => BalanceAccountingDocPage.tsx} (93%) rename packages/website/src/features/docs/accounting/reports/{balanceSheetAccountingDocPage.tsx => BalanceSheetAccountingDocPage.tsx} (96%) rename packages/website/src/features/docs/accounting/reports/{fecAccountingDocPage.tsx => FecAccountingDocPage.tsx} (93%) rename packages/website/src/features/docs/accounting/reports/{incomeStatementAccountingDocPage.tsx => IncomeStatementAccountingDocPage.tsx} (96%) rename packages/website/src/features/docs/accounting/reports/{journalAccountingDocPage.tsx => JournalAccountingDocPage.tsx} (95%) rename packages/website/src/features/docs/accounting/reports/{ledgerAccountingDocPage.tsx => LedgerAccountingDocPage.tsx} (93%) rename packages/website/src/features/docs/accounting/reports/{notesAccountingDocPage.tsx => NotesAccountingDocPage.tsx} (93%) rename packages/website/src/features/docs/accounting/reports/{reportsAccountingDocPage.tsx => ReportsAccountingDocPage.tsx} (92%) rename packages/website/src/features/docs/accounting/resources/accounts/{accountResourcesAccountingDocPage.tsx => AccountResourcesAccountingDocPage.tsx} (77%) rename packages/website/src/features/docs/accounting/resources/accounts/{accountsResourcesAccountingDocPage.tsx => AccountsResourcesAccountingDocPage.tsx} (97%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{accountInfoCard.tsx => AccountInfoCard.tsx} (98%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{accountNotFound.tsx => AccountNotFound.tsx} (82%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{accountScenariosSection.tsx => AccountScenariosSection.tsx} (95%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{childrenListSection.tsx => ChildrenListSection.tsx} (97%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{debitCreditSection.tsx => DebitCreditSection.tsx} (96%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{infoRow.tsx => InfoRow.tsx} (100%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{journalEntryExamples.tsx => JournalEntryExamples.tsx} (97%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{parentAccountSection.tsx => ParentAccountSection.tsx} (96%) rename packages/website/src/features/docs/accounting/resources/accounts/components/{summaryAccountBanner.tsx => SummaryAccountBanner.tsx} (97%) rename packages/website/src/features/docs/accounting/resources/glossary/{glossaryListItem.tsx => GlossaryListItem.tsx} (97%) rename packages/website/src/features/docs/accounting/resources/glossary/{glossaryResourcesAccountingDocPage.tsx => GlossaryResourcesAccountingDocPage.tsx} (95%) rename packages/website/src/features/docs/accounting/resources/glossary/{glossaryTermResourcesAccountingDocPage.tsx => GlossaryTermResourcesAccountingDocPage.tsx} (92%) rename packages/website/src/features/docs/accounting/resources/scenarios/{scenarioResourcesAccountingDocPage.tsx => ScenarioResourcesAccountingDocPage.tsx} (91%) rename packages/website/src/features/docs/accounting/resources/scenarios/{scenariosResourcesAccountingDocPage.tsx => ScenariosResourcesAccountingDocPage.tsx} (96%) rename packages/website/src/features/docs/ai/{modelsAiDocPage.tsx => ModelsAiDocPage.tsx} (88%) rename packages/website/src/features/docs/ai/{ocrAiDocPage.tsx => OcrAiDocPage.tsx} (81%) rename packages/website/src/features/docs/ai/{rootAiDocPage.tsx => RootAiDocPage.tsx} (90%) rename packages/website/src/features/docs/ai/{toolsAiDocPage.tsx => ToolsAiDocPage.tsx} (96%) rename packages/website/src/features/docs/api/{authenticationApiDocPage.tsx => AuthenticationApiDocPage.tsx} (92%) rename packages/website/src/features/docs/api/{filesApiDocPage.tsx => FilesApiDocPage.tsx} (91%) rename packages/website/src/features/docs/api/{introductionApiDocPage.tsx => IntroductionApiDocPage.tsx} (93%) rename packages/website/src/features/docs/api/{organizationApiDocPage.tsx => OrganizationApiDocPage.tsx} (92%) rename packages/website/src/features/docs/api/{rootApiDocPage.tsx => RootApiDocPage.tsx} (88%) rename packages/website/src/features/docs/api/{yearApiDocPage.tsx => YearApiDocPage.tsx} (96%) rename packages/website/src/features/docs/dashboard/{entriesDashboardDocPage.tsx => EntriesDashboardDocPage.tsx} (93%) rename packages/website/src/features/docs/dashboard/{filesDashboardDocPage.tsx => FilesDashboardDocPage.tsx} (88%) create mode 100644 packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx rename packages/website/src/features/docs/dashboard/{organizationsDashboardDocPage.tsx => OrganizationsDashboardDocPage.tsx} (88%) rename packages/website/src/features/docs/dashboard/{reportsDashboardDocPage.tsx => ReportsDashboardDocPage.tsx} (94%) rename packages/website/src/features/docs/dashboard/{rootDashboardDocPage.tsx => RootDashboardDocPage.tsx} (89%) rename packages/website/src/features/docs/dashboard/{yearsDashboardDocPage.tsx => YearsDashboardDocPage.tsx} (86%) delete mode 100644 packages/website/src/features/docs/dashboard/gettingStartedDashboardDocPage.tsx rename packages/website/src/features/docs/general/{legalGeneralDocPage.tsx => LegalGeneralDocPage.tsx} (95%) rename packages/website/src/features/docs/general/{privacyGeneralDocPage.tsx => PrivacyGeneralDocPage.tsx} (97%) rename packages/website/src/features/docs/general/{rootGeneralDocPage.tsx => RootGeneralDocPage.tsx} (91%) rename packages/website/src/features/docs/general/{supportGeneralDocPage.tsx => SupportGeneralDocPage.tsx} (98%) rename packages/website/src/features/docs/general/{termsGeneralDocPage.tsx => TermsGeneralDocPage.tsx} (97%) rename packages/website/src/features/docs/general/{whitepaperGeneralDocPage.tsx => WhitepaperGeneralDocPage.tsx} (96%) rename packages/website/src/features/docs/general/features/{featureCard.tsx => FeatureCard.tsx} (100%) rename packages/website/src/features/docs/general/features/{featuresGeneralDocPage.tsx => FeaturesGeneralDocPage.tsx} (98%) rename packages/website/src/features/docs/general/pricing/{faqItem.tsx => FaqItem.tsx} (100%) rename packages/website/src/features/docs/general/pricing/{pricingGeneralDocPage.tsx => PricingGeneralDocPage.tsx} (95%) rename packages/website/src/features/error/{errorPage.tsx => ErrorPage.tsx} (100%) rename packages/website/src/features/facturation/{ublInvoiceViewer.tsx => UblInvoiceViewer.tsx} (100%) rename packages/website/src/features/home/{documentationBanner.tsx => DocumentationBanner.tsx} (96%) rename packages/website/src/features/home/{featureItem.tsx => FeatureItem.tsx} (100%) rename packages/website/src/features/home/{heroIllustration.tsx => HeroIllustration.tsx} (100%) rename packages/website/src/features/home/{homePage.tsx => HomePage.tsx} (98%) rename packages/website/src/features/home/{organizationsBanner.tsx => OrganizationsBanner.tsx} (92%) rename packages/website/src/features/home/{pricing.tsx => Pricing.tsx} (98%) rename packages/website/src/features/notFound/{notFoundPage.tsx => NotFoundPage.tsx} (97%) rename packages/website/src/features/public/invoiceXml/{publicInvoiceXmlPage.tsx => PublicInvoiceXmlPage.tsx} (100%) rename packages/website/src/features/signIn/{resetPasswordPage.tsx => ResetPasswordPage.tsx} (94%) rename packages/website/src/features/signIn/{signInPage.tsx => SignInPage.tsx} (95%) rename packages/website/src/features/signUp/{signUpPage.tsx => SignUpPage.tsx} (96%) diff --git a/packages/tools/src/schemas.ts b/packages/tools/src/schemas.ts index e1e2c6af..f9f1feb3 100644 --- a/packages/tools/src/schemas.ts +++ b/packages/tools/src/schemas.ts @@ -17,7 +17,7 @@ export { agentMessageModel, agentMessageRelations, agentMessageStateEnum, -} from "../../metadata/src/models/agentMessage.ts" +} from "../../metadata/src/models/AgentMessage.ts" export { agentSessionModel, agentSessionRelations } from "../../metadata/src/models/agentSession.ts" export { apiKeyModel, apiKeyRelations } from "../../metadata/src/models/apiKey.ts" export { balanceSheetModel, balanceSheetRelations } from "../../metadata/src/models/balanceSheet.ts" diff --git a/packages/ui/src/components/buttons/Button.tsx b/packages/ui/src/components/buttons/Button.tsx new file mode 100644 index 00000000..5d289f3c --- /dev/null +++ b/packages/ui/src/components/buttons/Button.tsx @@ -0,0 +1,95 @@ +import { + type ComponentProps, + createContext, + type MouseEvent, + type ReactNode, + useRef, + useState, +} from "react" +import { css, cx } from "../../utilities/cn.ts" +import { sleep } from "../../utilities/sleep.ts" + +/** + * Context for passing loading state from Button to ButtonContent + */ +export const ButtonLoadingContext = createContext(false) + +/** + * Button component - a neutral container for clickable elements + * Handles click events, loading state, and disabled state + * Use composition with ButtonContent for styled button content + * + * @example + * + */ +export function Button( + props: Omit, "children" | "disabled"> & { + hasLoader?: boolean + children: ReactNode + title?: string + isDisabled?: boolean + }, +) { + const [isLoading, setIsLoading] = useState(false) + const isLoadingRef = useRef(false) + + async function handleClick(e: MouseEvent) { + if (props.onClick === undefined) return + if (!props.hasLoader) { + props.onClick(e) + return + } + + if (isLoadingRef.current) return + isLoadingRef.current = true + setIsLoading(true) + + try { + await Promise.all([ + sleep(100), + props.onClick(e), + ]) + } finally { + isLoadingRef.current = false + setIsLoading(false) + } + } + + const { hasLoader, className, isDisabled, title, children, onClick: _onClick, ...buttonProps } = props + + return ( + + + + ) +} diff --git a/packages/ui/src/components/buttons/buttonGhostContent.tsx b/packages/ui/src/components/buttons/ButtonGhostContent.tsx similarity index 98% rename from packages/ui/src/components/buttons/buttonGhostContent.tsx rename to packages/ui/src/components/buttons/ButtonGhostContent.tsx index 4236d9b9..447b0e5b 100644 --- a/packages/ui/src/components/buttons/buttonGhostContent.tsx +++ b/packages/ui/src/components/buttons/ButtonGhostContent.tsx @@ -1,5 +1,5 @@ import { sva } from "@arrhes/ui/css" -import { useButtonLoading } from "./button" +import { useButtonLoading } from "./useButtonLoading" import { type ButtonContentProps, renderButtonContent } from "./buttonContent" const ghostRecipe = sva({ diff --git a/packages/ui/src/components/buttons/buttonOutlineContent.tsx b/packages/ui/src/components/buttons/ButtonOutlineContent.tsx similarity index 98% rename from packages/ui/src/components/buttons/buttonOutlineContent.tsx rename to packages/ui/src/components/buttons/ButtonOutlineContent.tsx index 5f136c39..89bfd443 100644 --- a/packages/ui/src/components/buttons/buttonOutlineContent.tsx +++ b/packages/ui/src/components/buttons/ButtonOutlineContent.tsx @@ -1,5 +1,5 @@ import { sva } from "@arrhes/ui/css" -import { useButtonLoading } from "./button" +import { useButtonLoading } from "./useButtonLoading" import { type ButtonContentProps, renderButtonContent } from "./buttonContent" const outlineRecipe = sva({ diff --git a/packages/ui/src/components/buttons/buttonPlainContent.tsx b/packages/ui/src/components/buttons/ButtonPlainContent.tsx similarity index 98% rename from packages/ui/src/components/buttons/buttonPlainContent.tsx rename to packages/ui/src/components/buttons/ButtonPlainContent.tsx index 71b9da81..6fa30be2 100644 --- a/packages/ui/src/components/buttons/buttonPlainContent.tsx +++ b/packages/ui/src/components/buttons/ButtonPlainContent.tsx @@ -1,5 +1,5 @@ import { sva } from "@arrhes/ui/css" -import { useButtonLoading } from "./button" +import { useButtonLoading } from "./useButtonLoading" import { type ButtonContentProps, renderButtonContent } from "./buttonContent" const plainRecipe = sva({ diff --git a/packages/ui/src/components/buttons/linkButton.tsx b/packages/ui/src/components/buttons/LinkButton.tsx similarity index 100% rename from packages/ui/src/components/buttons/linkButton.tsx rename to packages/ui/src/components/buttons/LinkButton.tsx diff --git a/packages/ui/src/components/buttons/linkContent.tsx b/packages/ui/src/components/buttons/LinkContent.tsx similarity index 100% rename from packages/ui/src/components/buttons/linkContent.tsx rename to packages/ui/src/components/buttons/LinkContent.tsx diff --git a/packages/ui/src/components/buttons/button.tsx b/packages/ui/src/components/buttons/button.tsx index 027ee552..5d289f3c 100644 --- a/packages/ui/src/components/buttons/button.tsx +++ b/packages/ui/src/components/buttons/button.tsx @@ -3,7 +3,6 @@ import { createContext, type MouseEvent, type ReactNode, - useContext, useRef, useState, } from "react" @@ -13,15 +12,7 @@ import { sleep } from "../../utilities/sleep.ts" /** * Context for passing loading state from Button to ButtonContent */ -const ButtonLoadingContext = createContext(false) - -/** - * Hook to access the loading state from a parent Button - * Returns false if not within a Button context - */ -export function useButtonLoading() { - return useContext(ButtonLoadingContext) -} +export const ButtonLoadingContext = createContext(false) /** * Button component - a neutral container for clickable elements diff --git a/packages/ui/src/components/buttons/buttonContent.tsx b/packages/ui/src/components/buttons/buttonContent.tsx index 2dbe6344..991657cd 100644 --- a/packages/ui/src/components/buttons/buttonContent.tsx +++ b/packages/ui/src/components/buttons/buttonContent.tsx @@ -1,7 +1,7 @@ import type { Icon, IconProps, ReactNode } from "@tabler/icons-react" import { cloneElement, type ReactElement } from "react" import { css, cx } from "../../utilities/cn.ts" -import { CircularLoader } from "../layouts/circularLoader" +import { CircularLoader } from "../layouts/CircularLoader" export type ButtonColor = "default" | "neutral" | "danger" | "success" diff --git a/packages/ui/src/components/buttons/useButtonLoading.tsx b/packages/ui/src/components/buttons/useButtonLoading.tsx new file mode 100644 index 00000000..3f94a6b2 --- /dev/null +++ b/packages/ui/src/components/buttons/useButtonLoading.tsx @@ -0,0 +1,10 @@ +import { useContext } from "react" +import { ButtonLoadingContext } from "./Button.js" + +/** + * Hook to access the loading state from a parent Button + * Returns false if not within a Button context + */ +export function useButtonLoading() { + return useContext(ButtonLoadingContext) +} diff --git a/packages/ui/src/components/formats/formatBase.tsx b/packages/ui/src/components/formats/FormatBase.tsx similarity index 100% rename from packages/ui/src/components/formats/formatBase.tsx rename to packages/ui/src/components/formats/FormatBase.tsx diff --git a/packages/ui/src/components/formats/formatError.tsx b/packages/ui/src/components/formats/FormatError.tsx similarity index 94% rename from packages/ui/src/components/formats/formatError.tsx rename to packages/ui/src/components/formats/FormatError.tsx index afc9a906..41ff039e 100644 --- a/packages/ui/src/components/formats/formatError.tsx +++ b/packages/ui/src/components/formats/FormatError.tsx @@ -1,6 +1,6 @@ import type { ComponentProps } from "react" import { css } from "../../utilities/cn.js" -import { FormatBase } from "./formatBase.js" +import { FormatBase } from "./FormatBase.js" export function FormatError(props: { text: string; className?: ComponentProps<"div">["className"] }) { return ( diff --git a/packages/ui/src/components/formats/formatLink.tsx b/packages/ui/src/components/formats/FormatLink.tsx similarity index 91% rename from packages/ui/src/components/formats/formatLink.tsx rename to packages/ui/src/components/formats/FormatLink.tsx index 9310e82d..b7633d01 100644 --- a/packages/ui/src/components/formats/formatLink.tsx +++ b/packages/ui/src/components/formats/FormatLink.tsx @@ -1,9 +1,9 @@ import type { ComponentProps } from "react" import { css } from "../../utilities/cn.js" -import { Button } from "../buttons/button.js" +import { Button } from "../buttons/Button.js" import { toast } from "../overlays/toast/useToast.js" -import { FormatBase } from "./formatBase.js" -import { FormatNull } from "./formatNull.js" +import { FormatBase } from "./FormatBase.js" +import { FormatNull } from "./FormatNull.js" type FormatLinkProps = { text: string | null diff --git a/packages/ui/src/components/formats/formatNull.tsx b/packages/ui/src/components/formats/FormatNull.tsx similarity index 100% rename from packages/ui/src/components/formats/formatNull.tsx rename to packages/ui/src/components/formats/FormatNull.tsx diff --git a/packages/ui/src/components/formats/formatText.tsx b/packages/ui/src/components/formats/FormatText.tsx similarity index 94% rename from packages/ui/src/components/formats/formatText.tsx rename to packages/ui/src/components/formats/FormatText.tsx index 9561caf5..f61ac86d 100644 --- a/packages/ui/src/components/formats/formatText.tsx +++ b/packages/ui/src/components/formats/FormatText.tsx @@ -1,6 +1,6 @@ import type { ComponentProps, ReactNode } from "react" import { css, cx } from "../../utilities/cn.js" -import { FormatNull } from "./formatNull.js" +import { FormatNull } from "./FormatNull.js" export function FormatText(props: { wrap?: boolean diff --git a/packages/ui/src/components/formats/display/FormatBoolean.tsx b/packages/ui/src/components/formats/display/FormatBoolean.tsx new file mode 100644 index 00000000..ee64eb37 --- /dev/null +++ b/packages/ui/src/components/formats/display/FormatBoolean.tsx @@ -0,0 +1,18 @@ +import type { ComponentProps } from "react" +import { Chip } from "../../layouts/Chip.js" +import { FormatBase } from "../FormatBase.js" + +export function FormatBoolean(props: { + boolean?: boolean | null + text?: string + className?: ComponentProps<"div">["className"] +}) { + return ( + + + + ) +} diff --git a/packages/ui/src/components/formats/display/FormatDate.tsx b/packages/ui/src/components/formats/display/FormatDate.tsx new file mode 100644 index 00000000..fdc0cec7 --- /dev/null +++ b/packages/ui/src/components/formats/display/FormatDate.tsx @@ -0,0 +1,25 @@ +import type { ComponentProps } from "react" +import { css, cx } from "../../../utilities/cn.js" +import { FormatNull } from "../FormatNull.js" +import { FormatText } from "../FormatText.js" +import { formatDate } from "../formatDate.js" + +export function FormatDate(props: { + date?: string | Date | undefined | null + className?: ComponentProps<"div">["className"] +}) { + if (!props.date) return + if (String(new Date(props.date)) === "Invalid Date") return + return ( + + {formatDate(props.date)} + + ) +} diff --git a/packages/ui/src/components/formats/display/FormatDateTime.tsx b/packages/ui/src/components/formats/display/FormatDateTime.tsx new file mode 100644 index 00000000..048c87d9 --- /dev/null +++ b/packages/ui/src/components/formats/display/FormatDateTime.tsx @@ -0,0 +1,44 @@ +import type { ComponentProps } from "react" +import { css } from "../../../utilities/cn.js" +import { FormatNull } from "../FormatNull.js" +import { formatDateTime } from "../formatDateTime.js" + +export function FormatDateTime(props: { + date?: string | Date | undefined | null + className?: ComponentProps<"div">["className"] +}) { + const formatted = formatDateTime(props.date) + if (!formatted) return + + const [datePart, timePart] = formatted.split(" ") + + return ( +
+ + {datePart} + + + {timePart} + +
+ ) +} diff --git a/packages/ui/src/components/formats/display/FormatFileSize.tsx b/packages/ui/src/components/formats/display/FormatFileSize.tsx new file mode 100644 index 00000000..bfe2dabb --- /dev/null +++ b/packages/ui/src/components/formats/display/FormatFileSize.tsx @@ -0,0 +1,30 @@ +import type { ComponentProps } from "react" +import { css } from "../../../utilities/cn.js" +import { FormatBase } from "../FormatBase.js" +import { FormatNull } from "../FormatNull.js" +import { formatFileSize } from "../formatFileSize.js" + +export function FormatFileSize(props: { + size?: number | null + className?: ComponentProps<"div">["className"] +}) { + if (props.size === undefined || props.size === null) return + return ( + + + {formatFileSize(props.size)} + + + ) +} diff --git a/packages/ui/src/components/formats/display/FormatPrice.tsx b/packages/ui/src/components/formats/display/FormatPrice.tsx new file mode 100644 index 00000000..4bbca95f --- /dev/null +++ b/packages/ui/src/components/formats/display/FormatPrice.tsx @@ -0,0 +1,38 @@ +import type { ComponentProps } from "react" +import { css, cx } from "../../../utilities/cn.js" +import { FormatNull } from "../FormatNull.js" +import { formatPrice } from "../formatPrice.js" + +export function FormatPrice(props: { price?: number | null | string; className?: ComponentProps<"div">["className"] }) { + if (props.price === undefined || props.price === null) { + return + } + const price = Number(props.price) + const processedPrice = Math.abs(price) < 0.009 ? 0 : price + return ( + + {processedPrice < 0 + ? `-${formatPrice({ + price: Math.abs(processedPrice), + })}` + : formatPrice({ + price: Math.abs(processedPrice), + })} + + ) +} diff --git a/packages/ui/src/components/formats/display/FormatSelect.tsx b/packages/ui/src/components/formats/display/FormatSelect.tsx new file mode 100644 index 00000000..ff8cc2cb --- /dev/null +++ b/packages/ui/src/components/formats/display/FormatSelect.tsx @@ -0,0 +1,26 @@ +import type { ComponentProps } from "react" +import { Chip, type ChipColors } from "../../layouts/Chip.js" +import { FormatBase } from "../FormatBase.js" +import { FormatNull } from "../FormatNull.js" +import { formatSelect } from "../formatSelect.js" + +export function FormatSelect(props: { + option?: string | null + options: Array<{ + key: string + label: string + }> + color?: ChipColors + className?: ComponentProps<"div">["className"] +}) { + const option = formatSelect(props.option, props.options) + if (!option) return + return ( + + + + ) +} diff --git a/packages/ui/src/components/formats/formatBoolean.tsx b/packages/ui/src/components/formats/formatBoolean.tsx index db306454..35e97a80 100644 --- a/packages/ui/src/components/formats/formatBoolean.tsx +++ b/packages/ui/src/components/formats/formatBoolean.tsx @@ -1,23 +1,4 @@ -import type { ComponentProps } from "react" -import { Chip } from "../layouts/chip.js" -import { FormatBase } from "./formatBase.js" - export function formatBoolean(boolean?: boolean | null) { if (!boolean) return "Non" return "Oui" } - -export function FormatBoolean(props: { - boolean?: boolean | null - text?: string - className?: ComponentProps<"div">["className"] -}) { - return ( - - - - ) -} diff --git a/packages/ui/src/components/formats/formatDate.tsx b/packages/ui/src/components/formats/formatDate.tsx index 58c99e7c..fa047689 100644 --- a/packages/ui/src/components/formats/formatDate.tsx +++ b/packages/ui/src/components/formats/formatDate.tsx @@ -1,8 +1,3 @@ -import type { ComponentProps } from "react" -import { css, cx } from "../../utilities/cn.js" -import { FormatNull } from "./formatNull.js" -import { FormatText } from "./formatText.js" - export function formatDate( rawDate?: string | Date | undefined | null, options?: { @@ -35,23 +30,3 @@ export function formatDate( return dateStr } - -export function FormatDate(props: { - date?: string | Date | undefined | null - className?: ComponentProps<"div">["className"] -}) { - if (!props.date) return - if (String(new Date(props.date)) === "Invalid Date") return - return ( - - {formatDate(props.date)} - - ) -} diff --git a/packages/ui/src/components/formats/formatDateTime.tsx b/packages/ui/src/components/formats/formatDateTime.tsx index 78400e1c..937b32b7 100644 --- a/packages/ui/src/components/formats/formatDateTime.tsx +++ b/packages/ui/src/components/formats/formatDateTime.tsx @@ -1,7 +1,3 @@ -import type { ComponentProps } from "react" -import { css } from "../../utilities/cn.js" -import { FormatNull } from "./formatNull.js" - export function formatDateTime(rawDate?: string | Date | undefined | null) { if (!rawDate || String(new Date(rawDate)) === "Invalid Date") return undefined @@ -26,45 +22,3 @@ export function formatDateTime(rawDate?: string | Date | undefined | null) { minute, ].join(":")}` } - -type FormatDateTime = { - date?: string | Date | undefined | null - className?: ComponentProps<"div">["className"] -} - -export function FormatDateTime(props: FormatDateTime) { - const formatted = formatDateTime(props.date) - if (!formatted) return - - const [datePart, timePart] = formatted.split(" ") - - return ( -
- - {datePart} - - - {timePart} - -
- ) -} diff --git a/packages/ui/src/components/formats/formatFileSize.tsx b/packages/ui/src/components/formats/formatFileSize.tsx index e90c23a8..12c6a4ab 100644 --- a/packages/ui/src/components/formats/formatFileSize.tsx +++ b/packages/ui/src/components/formats/formatFileSize.tsx @@ -1,8 +1,3 @@ -import type { ComponentProps } from "react" -import { css } from "../../utilities/cn.js" -import { FormatBase } from "./formatBase.js" -import { FormatNull } from "./formatNull.js" - const sizes = [ "o", "ko", @@ -18,30 +13,3 @@ export function formatFileSize(size?: number | null) { const i = Math.floor(Math.log(size) / Math.log(1000)) return `${parseFloat((size / 1000 ** i).toFixed(2))} ${sizes.at(i)}` } - -type FormatFileSize = { - size?: number | null - className?: ComponentProps<"div">["className"] -} - -export function FormatFileSize(props: FormatFileSize) { - if (props.size === undefined || props.size === null) return - return ( - - - {formatFileSize(props.size)} - - - ) -} diff --git a/packages/ui/src/components/formats/formatPrice.tsx b/packages/ui/src/components/formats/formatPrice.tsx index 86f51d2a..c1d951fa 100644 --- a/packages/ui/src/components/formats/formatPrice.tsx +++ b/packages/ui/src/components/formats/formatPrice.tsx @@ -1,7 +1,3 @@ -import type { ComponentProps } from "react" -import { css, cx } from "../../utilities/cn.js" -import { FormatNull } from "./formatNull.js" - export function formatPrice(parameters: { price?: number | null | string }) { if (parameters.price === undefined || parameters.price === null) return "/" const price = Number(parameters.price) @@ -15,37 +11,3 @@ export function formatPrice(parameters: { price?: number | null | string }) { .format(processedPrice) .replace(/,/g, ".") } - -export function FormatPrice(props: { price?: number | null | string; className?: ComponentProps<"div">["className"] }) { - if (props.price === undefined || props.price === null) { - return - } - const price = Number(props.price) - const processedPrice = Math.abs(price) < 0.009 ? 0 : price - return ( - - {processedPrice < 0 - ? `-${formatPrice({ - price: Math.abs(processedPrice), - })}` - : formatPrice({ - price: Math.abs(processedPrice), - })} - - ) -} diff --git a/packages/ui/src/components/formats/formatSelect.tsx b/packages/ui/src/components/formats/formatSelect.tsx index 3fb9d505..793e5aba 100644 --- a/packages/ui/src/components/formats/formatSelect.tsx +++ b/packages/ui/src/components/formats/formatSelect.tsx @@ -1,8 +1,3 @@ -import type { ComponentProps } from "react" -import { Chip, type ChipColors } from "../layouts/chip.js" -import { FormatBase } from "./formatBase.js" -import { FormatNull } from "./formatNull.js" - export function formatSelect( key: string | null | undefined, options: { @@ -12,26 +7,3 @@ export function formatSelect( ) { return options.find((x) => x.key === key)?.label ?? "" } - -type FormatSelect = { - option?: string | null - options: Array<{ - key: string - label: string - }> - color?: ChipColors - className?: ComponentProps<"div">["className"] -} - -export function FormatSelect(props: FormatSelect) { - const option = formatSelect(props.option, props.options) - if (!option) return - return ( - - - - ) -} diff --git a/packages/ui/src/components/inputs/inputCheckbox.tsx b/packages/ui/src/components/inputs/InputCheckbox.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputCheckbox.tsx rename to packages/ui/src/components/inputs/InputCheckbox.tsx diff --git a/packages/ui/src/components/inputs/inputCombobox.tsx b/packages/ui/src/components/inputs/InputCombobox.tsx similarity index 95% rename from packages/ui/src/components/inputs/inputCombobox.tsx rename to packages/ui/src/components/inputs/InputCombobox.tsx index a21b19a1..f76ddb4c 100644 --- a/packages/ui/src/components/inputs/inputCombobox.tsx +++ b/packages/ui/src/components/inputs/InputCombobox.tsx @@ -3,14 +3,14 @@ import { type ComponentProps, useEffect, useState } from "react" import type { FieldError } from "react-hook-form" import { css, cx } from "../../utilities/cn.js" import { debounce } from "../../utilities/debounce.js" -import { Button } from "../buttons/button.js" -import { ButtonGhostContent } from "../buttons/buttonGhostContent.js" -import { ButtonOutlineContent } from "../buttons/buttonOutlineContent.js" -import { FormatNull } from "../formats/formatNull.js" -import { CircularLoader } from "../layouts/circularLoader.js" -import { Virtualizer } from "../layouts/virtualizer.js" +import { Button } from "../buttons/Button.js" +import { ButtonGhostContent } from "../buttons/ButtonGhostContent.js" +import { ButtonOutlineContent } from "../buttons/ButtonOutlineContent.js" +import { FormatNull } from "../formats/FormatNull.js" +import { CircularLoader } from "../layouts/CircularLoader.js" +import { Virtualizer } from "../layouts/Virtualizer.js" import { Popover } from "../overlays/popover/popover.js" -import { InputText } from "./inputText.js" +import { InputText } from "./InputText.js" export function InputCombobox(props: { error?: FieldError diff --git a/packages/ui/src/components/inputs/inputComboboxMultiple.tsx b/packages/ui/src/components/inputs/InputComboboxMultiple.tsx similarity index 95% rename from packages/ui/src/components/inputs/inputComboboxMultiple.tsx rename to packages/ui/src/components/inputs/InputComboboxMultiple.tsx index 75f575f8..f6de7d69 100644 --- a/packages/ui/src/components/inputs/inputComboboxMultiple.tsx +++ b/packages/ui/src/components/inputs/InputComboboxMultiple.tsx @@ -2,14 +2,14 @@ import { IconChevronDown, IconX } from "@tabler/icons-react" import { useEffect, useState } from "react" import { css, cx } from "../../utilities/cn.js" import { debounce } from "../../utilities/debounce.js" -import { Button } from "../buttons/button.js" -import { ButtonGhostContent } from "../buttons/buttonGhostContent.js" -import { ButtonOutlineContent } from "../buttons/buttonOutlineContent.js" -import { FormatNull } from "../formats/formatNull.js" -import { CircularLoader } from "../layouts/circularLoader.js" -import { Virtualizer } from "../layouts/virtualizer.js" +import { Button } from "../buttons/Button.js" +import { ButtonGhostContent } from "../buttons/ButtonGhostContent.js" +import { ButtonOutlineContent } from "../buttons/ButtonOutlineContent.js" +import { FormatNull } from "../formats/FormatNull.js" +import { CircularLoader } from "../layouts/CircularLoader.js" +import { Virtualizer } from "../layouts/Virtualizer.js" import { Popover } from "../overlays/popover/popover.js" -import { InputText } from "./inputText.js" +import { InputText } from "./InputText.js" type InputComboboxMultiple = { placeholder: string diff --git a/packages/ui/src/components/inputs/inputCurrency.tsx b/packages/ui/src/components/inputs/InputCurrency.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputCurrency.tsx rename to packages/ui/src/components/inputs/InputCurrency.tsx diff --git a/packages/ui/src/components/inputs/inputDate.tsx b/packages/ui/src/components/inputs/InputDate.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputDate.tsx rename to packages/ui/src/components/inputs/InputDate.tsx diff --git a/packages/ui/src/components/inputs/inputDebounced.tsx b/packages/ui/src/components/inputs/InputDebounced.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputDebounced.tsx rename to packages/ui/src/components/inputs/InputDebounced.tsx diff --git a/packages/ui/src/components/inputs/inputDisabled.tsx b/packages/ui/src/components/inputs/InputDisabled.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputDisabled.tsx rename to packages/ui/src/components/inputs/InputDisabled.tsx diff --git a/packages/ui/src/components/inputs/inputFile.tsx b/packages/ui/src/components/inputs/InputFile.tsx similarity index 98% rename from packages/ui/src/components/inputs/inputFile.tsx rename to packages/ui/src/components/inputs/InputFile.tsx index 7ef7c167..c499c267 100644 --- a/packages/ui/src/components/inputs/inputFile.tsx +++ b/packages/ui/src/components/inputs/InputFile.tsx @@ -1,7 +1,7 @@ import { type InputHTMLAttributes, useEffect, useRef, useState } from "react" import type { FieldError } from "react-hook-form" import { css } from "../../utilities/cn.js" -import { Button } from "../buttons/button.js" +import { Button } from "../buttons/Button.js" export function InputFile( props: Omit, "value" | "onChange"> & { diff --git a/packages/ui/src/components/inputs/inputNumber.tsx b/packages/ui/src/components/inputs/InputNumber.tsx similarity index 95% rename from packages/ui/src/components/inputs/inputNumber.tsx rename to packages/ui/src/components/inputs/InputNumber.tsx index 6da54289..fa0fc747 100644 --- a/packages/ui/src/components/inputs/inputNumber.tsx +++ b/packages/ui/src/components/inputs/InputNumber.tsx @@ -1,7 +1,7 @@ import { IconMinus, IconPlus } from "@tabler/icons-react" import { css } from "../../utilities/cn.js" -import { Button } from "../buttons/button.js" -import { ButtonOutlineContent } from "../buttons/buttonOutlineContent.js" +import { Button } from "../buttons/Button.js" +import { ButtonOutlineContent } from "../buttons/ButtonOutlineContent.js" export function InputNumber(props: { value: number; onChange: (value: number) => void; min?: number; label?: string }) { const min = props.min ?? 0 diff --git a/packages/ui/src/components/inputs/inputPassword.tsx b/packages/ui/src/components/inputs/InputPassword.tsx similarity index 98% rename from packages/ui/src/components/inputs/inputPassword.tsx rename to packages/ui/src/components/inputs/InputPassword.tsx index fa3decb4..2aadd24f 100644 --- a/packages/ui/src/components/inputs/inputPassword.tsx +++ b/packages/ui/src/components/inputs/InputPassword.tsx @@ -3,7 +3,7 @@ import type { InputHTMLAttributes } from "react" import { useState } from "react" import type { FieldError } from "react-hook-form" import { css, cx } from "../../utilities/cn.js" -import { Button } from "../buttons/button.js" +import { Button } from "../buttons/Button.js" export function InputPassword( props: Omit, "value" | "onChange"> & { diff --git a/packages/ui/src/components/inputs/inputPrice.tsx b/packages/ui/src/components/inputs/InputPrice.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputPrice.tsx rename to packages/ui/src/components/inputs/InputPrice.tsx diff --git a/packages/ui/src/components/inputs/inputRating.tsx b/packages/ui/src/components/inputs/InputRating.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputRating.tsx rename to packages/ui/src/components/inputs/InputRating.tsx diff --git a/packages/ui/src/components/inputs/inputSelect.tsx b/packages/ui/src/components/inputs/InputSelect.tsx similarity index 95% rename from packages/ui/src/components/inputs/inputSelect.tsx rename to packages/ui/src/components/inputs/InputSelect.tsx index a5135f7d..87127bce 100644 --- a/packages/ui/src/components/inputs/inputSelect.tsx +++ b/packages/ui/src/components/inputs/InputSelect.tsx @@ -2,11 +2,11 @@ import { IconCheck, IconChevronDown } from "@tabler/icons-react" import { type InputHTMLAttributes, useState } from "react" import type { FieldError } from "react-hook-form" import { css, cx } from "../../utilities/cn.js" -import { Button } from "../buttons/button.js" -import { ButtonGhostContent } from "../buttons/buttonGhostContent.js" -import { ButtonOutlineContent } from "../buttons/buttonOutlineContent.js" -import { FormatNull } from "../formats/formatNull.js" -import { CircularLoader } from "../layouts/circularLoader.js" +import { Button } from "../buttons/Button.js" +import { ButtonGhostContent } from "../buttons/ButtonGhostContent.js" +import { ButtonOutlineContent } from "../buttons/ButtonOutlineContent.js" +import { FormatNull } from "../formats/FormatNull.js" +import { CircularLoader } from "../layouts/CircularLoader.js" import { Popover } from "../overlays/popover/popover.js" export function InputSelect( diff --git a/packages/ui/src/components/inputs/inputSwitch.tsx b/packages/ui/src/components/inputs/InputSwitch.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputSwitch.tsx rename to packages/ui/src/components/inputs/InputSwitch.tsx diff --git a/packages/ui/src/components/inputs/inputText.tsx b/packages/ui/src/components/inputs/InputText.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputText.tsx rename to packages/ui/src/components/inputs/InputText.tsx diff --git a/packages/ui/src/components/inputs/inputTextArea.tsx b/packages/ui/src/components/inputs/InputTextArea.tsx similarity index 100% rename from packages/ui/src/components/inputs/inputTextArea.tsx rename to packages/ui/src/components/inputs/InputTextArea.tsx diff --git a/packages/ui/src/components/inputs/inputToggle.tsx b/packages/ui/src/components/inputs/InputToggle.tsx similarity index 96% rename from packages/ui/src/components/inputs/inputToggle.tsx rename to packages/ui/src/components/inputs/InputToggle.tsx index 5331cc2c..f1670a83 100644 --- a/packages/ui/src/components/inputs/inputToggle.tsx +++ b/packages/ui/src/components/inputs/InputToggle.tsx @@ -1,8 +1,8 @@ import type * as SwitchPrimitives from "@radix-ui/react-switch" import type { ComponentProps, JSX } from "react" import { css, cx } from "../../utilities/cn.js" -import { Button } from "../buttons/button.js" -import { ButtonGhostContent } from "../buttons/buttonGhostContent.js" +import { Button } from "../buttons/Button.js" +import { ButtonGhostContent } from "../buttons/ButtonGhostContent.js" export function InputToggle( props: Omit, "value" | "onChange"> & { diff --git a/packages/ui/src/components/layouts/badge.tsx b/packages/ui/src/components/layouts/Badge.tsx similarity index 100% rename from packages/ui/src/components/layouts/badge.tsx rename to packages/ui/src/components/layouts/Badge.tsx diff --git a/packages/ui/src/components/layouts/chip.tsx b/packages/ui/src/components/layouts/Chip.tsx similarity index 100% rename from packages/ui/src/components/layouts/chip.tsx rename to packages/ui/src/components/layouts/Chip.tsx diff --git a/packages/ui/src/components/layouts/circularLoader.tsx b/packages/ui/src/components/layouts/CircularLoader.tsx similarity index 100% rename from packages/ui/src/components/layouts/circularLoader.tsx rename to packages/ui/src/components/layouts/CircularLoader.tsx diff --git a/packages/ui/src/components/layouts/kbd.tsx b/packages/ui/src/components/layouts/Kbd.tsx similarity index 100% rename from packages/ui/src/components/layouts/kbd.tsx rename to packages/ui/src/components/layouts/Kbd.tsx diff --git a/packages/ui/src/components/layouts/logo.tsx b/packages/ui/src/components/layouts/Logo.tsx similarity index 100% rename from packages/ui/src/components/layouts/logo.tsx rename to packages/ui/src/components/layouts/Logo.tsx diff --git a/packages/ui/src/components/layouts/pageNavigation.tsx b/packages/ui/src/components/layouts/PageNavigation.tsx similarity index 95% rename from packages/ui/src/components/layouts/pageNavigation.tsx rename to packages/ui/src/components/layouts/PageNavigation.tsx index bdb013ca..535a43d3 100644 --- a/packages/ui/src/components/layouts/pageNavigation.tsx +++ b/packages/ui/src/components/layouts/PageNavigation.tsx @@ -1,8 +1,8 @@ import { useMatches, useRouterState } from "@tanstack/react-router" import type { JSX } from "react" import { css } from "../../utilities/cn.js" -import { ButtonGhostContent } from "../buttons/buttonGhostContent.js" -import { LinkButton } from "../buttons/linkButton.js" +import { ButtonGhostContent } from "../buttons/ButtonGhostContent.js" +import { LinkButton } from "../buttons/LinkButton.js" export function PageNavigation(props: { tabs: diff --git a/packages/ui/src/components/layouts/separator.tsx b/packages/ui/src/components/layouts/Separator.tsx similarity index 100% rename from packages/ui/src/components/layouts/separator.tsx rename to packages/ui/src/components/layouts/Separator.tsx diff --git a/packages/ui/src/components/layouts/virtualizer.tsx b/packages/ui/src/components/layouts/Virtualizer.tsx similarity index 100% rename from packages/ui/src/components/layouts/virtualizer.tsx rename to packages/ui/src/components/layouts/Virtualizer.tsx diff --git a/packages/ui/src/components/overlays/popover/popoverContent.tsx b/packages/ui/src/components/overlays/popover/PopoverContent.tsx similarity index 100% rename from packages/ui/src/components/overlays/popover/popoverContent.tsx rename to packages/ui/src/components/overlays/popover/PopoverContent.tsx diff --git a/packages/ui/src/components/overlays/popover/popover.tsx b/packages/ui/src/components/overlays/popover/popover.tsx index 7135b96e..1d1b8fa8 100644 --- a/packages/ui/src/components/overlays/popover/popover.tsx +++ b/packages/ui/src/components/overlays/popover/popover.tsx @@ -1,5 +1,5 @@ import { PopoverClose } from "./popoverClose.js" -import { PopoverContent } from "./popoverContent.js" +import { PopoverContent } from "./PopoverContent.js" import { PopoverRoot } from "./popoverRoot.js" import { PopoverTrigger } from "./popoverTrigger.js" diff --git a/packages/ui/src/components/overlays/toast/toastItem.tsx b/packages/ui/src/components/overlays/toast/ToastItem.tsx similarity index 96% rename from packages/ui/src/components/overlays/toast/toastItem.tsx rename to packages/ui/src/components/overlays/toast/ToastItem.tsx index 22e9b65c..9f43aa63 100644 --- a/packages/ui/src/components/overlays/toast/toastItem.tsx +++ b/packages/ui/src/components/overlays/toast/ToastItem.tsx @@ -8,8 +8,8 @@ import { } from "@tabler/icons-react" import type { ReactElement } from "react" import { css } from "../../../utilities/cn.js" -import { Button } from "../../buttons/button.js" -import { ButtonGhostContent } from "../../buttons/buttonGhostContent.js" +import { Button } from "../../buttons/Button.js" +import { ButtonGhostContent } from "../../buttons/ButtonGhostContent.js" import type { ToasterToast, ToastVariant } from "./useToast.js" const toastIcons: Record>> = { diff --git a/packages/ui/src/components/overlays/toast/toastViewport.tsx b/packages/ui/src/components/overlays/toast/ToastViewport.tsx similarity index 100% rename from packages/ui/src/components/overlays/toast/toastViewport.tsx rename to packages/ui/src/components/overlays/toast/ToastViewport.tsx diff --git a/packages/ui/src/components/overlays/toast/toastProvider.tsx b/packages/ui/src/components/overlays/toast/ToasterProvider.tsx similarity index 100% rename from packages/ui/src/components/overlays/toast/toastProvider.tsx rename to packages/ui/src/components/overlays/toast/ToasterProvider.tsx diff --git a/packages/ui/src/components/overlays/toast/toast.tsx b/packages/ui/src/components/overlays/toast/toast.tsx index ceaeb818..453154b8 100644 --- a/packages/ui/src/components/overlays/toast/toast.tsx +++ b/packages/ui/src/components/overlays/toast/toast.tsx @@ -1,5 +1,5 @@ -import { ToastItem } from "./toastItem.js" -import { ToastViewport } from "./toastViewport.js" +import { ToastItem } from "./ToastItem.js" +import { ToastViewport } from "./ToastViewport.js" export const Toast = { Item: ToastItem, diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 34c1948c..dc8d34db 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,58 +1,65 @@ // Utilities // Components - Buttons -export { Button, useButtonLoading } from "./components/buttons/button.js" +export { Button } from "./components/buttons/Button.js" +export { useButtonLoading } from "./components/buttons/useButtonLoading.js" export type { ButtonColor, ButtonContentProps } from "./components/buttons/buttonContent.js" export { renderButtonContent } from "./components/buttons/buttonContent.js" -export { ButtonGhostContent } from "./components/buttons/buttonGhostContent.js" -export { ButtonOutlineContent } from "./components/buttons/buttonOutlineContent.js" -export { ButtonPlainContent } from "./components/buttons/buttonPlainContent.js" -export { LinkButton } from "./components/buttons/linkButton.js" -export type { LinkContentProps } from "./components/buttons/linkContent.js" -export { LinkContent } from "./components/buttons/linkContent.js" +export { ButtonGhostContent } from "./components/buttons/ButtonGhostContent.js" +export { ButtonOutlineContent } from "./components/buttons/ButtonOutlineContent.js" +export { ButtonPlainContent } from "./components/buttons/ButtonPlainContent.js" +export { LinkButton } from "./components/buttons/LinkButton.js" +export type { LinkContentProps } from "./components/buttons/LinkContent.js" +export { LinkContent } from "./components/buttons/LinkContent.js" // Components - Formats -export { FormatBase } from "./components/formats/formatBase.js" -export { FormatBoolean, formatBoolean } from "./components/formats/formatBoolean.js" -export { FormatDate, formatDate } from "./components/formats/formatDate.js" -export { FormatDateTime, formatDateTime } from "./components/formats/formatDateTime.js" -export { FormatError } from "./components/formats/formatError.js" -export { FormatFileSize, formatFileSize } from "./components/formats/formatFileSize.js" -export { FormatLink } from "./components/formats/formatLink.js" -export { FormatNull } from "./components/formats/formatNull.js" -export { FormatPrice, formatPrice } from "./components/formats/formatPrice.js" -export { FormatSelect, formatSelect } from "./components/formats/formatSelect.js" -export { FormatText } from "./components/formats/formatText.js" -export { InputCheckbox } from "./components/inputs/inputCheckbox.js" -export { InputCombobox } from "./components/inputs/inputCombobox.js" -export { InputComboboxMultiple } from "./components/inputs/inputComboboxMultiple.js" -export { InputCurrency } from "./components/inputs/inputCurrency.js" -export { InputDate } from "./components/inputs/inputDate.js" -export { InputDebounced } from "./components/inputs/inputDebounced.js" -export { InputDisabled } from "./components/inputs/inputDisabled.js" -export { InputFile } from "./components/inputs/inputFile.js" -export { InputNumber } from "./components/inputs/inputNumber.js" -export { InputPassword } from "./components/inputs/inputPassword.js" -export { InputPrice } from "./components/inputs/inputPrice.js" -export { InputRating } from "./components/inputs/inputRating.js" -export { InputSelect } from "./components/inputs/inputSelect.js" -export { InputSwitch } from "./components/inputs/inputSwitch.js" +export { FormatBase } from "./components/formats/FormatBase.js" +export { formatBoolean } from "./components/formats/formatBoolean.js" +export { FormatBoolean } from "./components/formats/display/FormatBoolean.js" +export { formatDate } from "./components/formats/formatDate.js" +export { FormatDate } from "./components/formats/display/FormatDate.js" +export { formatDateTime } from "./components/formats/formatDateTime.js" +export { FormatDateTime } from "./components/formats/display/FormatDateTime.js" +export { FormatError } from "./components/formats/FormatError.js" +export { formatFileSize } from "./components/formats/formatFileSize.js" +export { FormatFileSize } from "./components/formats/display/FormatFileSize.js" +export { FormatLink } from "./components/formats/FormatLink.js" +export { FormatNull } from "./components/formats/FormatNull.js" +export { formatPrice } from "./components/formats/formatPrice.js" +export { FormatPrice } from "./components/formats/display/FormatPrice.js" +export { formatSelect } from "./components/formats/formatSelect.js" +export { FormatSelect } from "./components/formats/display/FormatSelect.js" +export { FormatText } from "./components/formats/FormatText.js" +export { InputCheckbox } from "./components/inputs/InputCheckbox.js" +export { InputCombobox } from "./components/inputs/InputCombobox.js" +export { InputComboboxMultiple } from "./components/inputs/InputComboboxMultiple.js" +export { InputCurrency } from "./components/inputs/InputCurrency.js" +export { InputDate } from "./components/inputs/InputDate.js" +export { InputDebounced } from "./components/inputs/InputDebounced.js" +export { InputDisabled } from "./components/inputs/InputDisabled.js" +export { InputFile } from "./components/inputs/InputFile.js" +export { InputNumber } from "./components/inputs/InputNumber.js" +export { InputPassword } from "./components/inputs/InputPassword.js" +export { InputPrice } from "./components/inputs/InputPrice.js" +export { InputRating } from "./components/inputs/InputRating.js" +export { InputSelect } from "./components/inputs/InputSelect.js" +export { InputSwitch } from "./components/inputs/InputSwitch.js" // Components - Inputs -export { InputText } from "./components/inputs/inputText.js" -export { InputTextArea } from "./components/inputs/inputTextArea.js" -export { InputToggle } from "./components/inputs/inputToggle.js" +export { InputText } from "./components/inputs/InputText.js" +export { InputTextArea } from "./components/inputs/InputTextArea.js" +export { InputToggle } from "./components/inputs/InputToggle.js" // Components - Layouts -export { Badge } from "./components/layouts/badge.js" -export { Chip, type ChipColors } from "./components/layouts/chip.js" -export { CircularLoader } from "./components/layouts/circularLoader.js" -export { Kbd } from "./components/layouts/kbd.js" -export { Logo } from "./components/layouts/logo.js" -export { PageNavigation } from "./components/layouts/pageNavigation.js" -export { Separator } from "./components/layouts/separator.js" -export { Virtualizer } from "./components/layouts/virtualizer.js" +export { Badge } from "./components/layouts/Badge.js" +export { Chip, type ChipColors } from "./components/layouts/Chip.js" +export { CircularLoader } from "./components/layouts/CircularLoader.js" +export { Kbd } from "./components/layouts/Kbd.js" +export { Logo } from "./components/layouts/Logo.js" +export { PageNavigation } from "./components/layouts/PageNavigation.js" +export { Separator } from "./components/layouts/Separator.js" +export { Virtualizer } from "./components/layouts/Virtualizer.js" // Components - Overlays export { Popover } from "./components/overlays/popover/popover.js" export { Toast } from "./components/overlays/toast/toast.js" -export { ToasterProvider } from "./components/overlays/toast/toastProvider.js" +export { ToasterProvider } from "./components/overlays/toast/ToasterProvider.js" export type { ToasterToast, ToastVariant } from "./components/overlays/toast/useToast.js" export { toast, useToast } from "./components/overlays/toast/useToast.js" // Utilities diff --git a/packages/website/src/components/inputDataCombobox.tsx b/packages/website/src/components/InputDataCombobox.tsx similarity index 100% rename from packages/website/src/components/inputDataCombobox.tsx rename to packages/website/src/components/InputDataCombobox.tsx diff --git a/packages/website/src/components/linkButton.tsx b/packages/website/src/components/LinkButton.tsx similarity index 100% rename from packages/website/src/components/linkButton.tsx rename to packages/website/src/components/LinkButton.tsx diff --git a/packages/website/src/components/document/docDefinition.tsx b/packages/website/src/components/document/DocDefinition.tsx similarity index 97% rename from packages/website/src/components/document/docDefinition.tsx rename to packages/website/src/components/document/DocDefinition.tsx index 4255dadd..ac20ca80 100644 --- a/packages/website/src/components/document/docDefinition.tsx +++ b/packages/website/src/components/document/DocDefinition.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconBookmark } from "@tabler/icons-react" import type { ReactNode } from "react" -import { DocTip } from "./docTip.js" +import { DocTip } from "./DocTip.js" export function DocDefinition(props: { term?: string; children: ReactNode }) { return ( diff --git a/packages/website/src/components/document/docExample.tsx b/packages/website/src/components/document/DocExample.tsx similarity index 90% rename from packages/website/src/components/document/docExample.tsx rename to packages/website/src/components/document/DocExample.tsx index 8b2433c8..7ebc8f46 100644 --- a/packages/website/src/components/document/docExample.tsx +++ b/packages/website/src/components/document/DocExample.tsx @@ -1,5 +1,5 @@ import { IconInfoCircle } from "@tabler/icons-react" -import { DocTip } from "./docTip.js" +import { DocTip } from "./DocTip.js" export function DocExample(props: { title?: string; children: React.ReactNode }) { return ( diff --git a/packages/website/src/components/document/docGlossaryEntry.tsx b/packages/website/src/components/document/DocGlossaryEntry.tsx similarity index 89% rename from packages/website/src/components/document/docGlossaryEntry.tsx rename to packages/website/src/components/document/DocGlossaryEntry.tsx index 7612bb1b..3e79823e 100644 --- a/packages/website/src/components/document/docGlossaryEntry.tsx +++ b/packages/website/src/components/document/DocGlossaryEntry.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from "react" -import { DocDefinition } from "./docDefinition.js" +import { DocDefinition } from "./DocDefinition.js" export function DocGlossaryEntry(props: { term: string; children: ReactNode }) { const id = props.term diff --git a/packages/website/src/components/document/docHeader.tsx b/packages/website/src/components/document/DocHeader.tsx similarity index 100% rename from packages/website/src/components/document/docHeader.tsx rename to packages/website/src/components/document/DocHeader.tsx diff --git a/packages/website/src/components/document/docIndexLink.tsx b/packages/website/src/components/document/DocIndexLink.tsx similarity index 95% rename from packages/website/src/components/document/docIndexLink.tsx rename to packages/website/src/components/document/DocIndexLink.tsx index 4d749e33..8d4a01f8 100644 --- a/packages/website/src/components/document/docIndexLink.tsx +++ b/packages/website/src/components/document/DocIndexLink.tsx @@ -1,6 +1,6 @@ import { css } from "@arrhes/ui/utilities/cn.js" import type { ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../linkButton.js" +import { LinkButton } from "../LinkButton.js" export function DocIndexLink(props: { to: ValidRoutes; label: string }) { return ( diff --git a/packages/website/src/components/document/docLastUpdate.tsx b/packages/website/src/components/document/DocLastUpdate.tsx similarity index 100% rename from packages/website/src/components/document/docLastUpdate.tsx rename to packages/website/src/components/document/DocLastUpdate.tsx diff --git a/packages/website/src/components/document/docLink.tsx b/packages/website/src/components/document/DocLink.tsx similarity index 94% rename from packages/website/src/components/document/docLink.tsx rename to packages/website/src/components/document/DocLink.tsx index 67b26399..8ecd957f 100644 --- a/packages/website/src/components/document/docLink.tsx +++ b/packages/website/src/components/document/DocLink.tsx @@ -1,6 +1,6 @@ import { css } from "@arrhes/ui/utilities/cn.js" import type { ValidParams, ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../linkButton.js" +import { LinkButton } from "../LinkButton.js" export function DocLink(props: { to: ValidRoutes; params?: ValidParams; hash?: string; children: React.ReactNode }) { return ( diff --git a/packages/website/src/components/document/docLinkCard.tsx b/packages/website/src/components/document/DocLinkCard.tsx similarity index 98% rename from packages/website/src/components/document/docLinkCard.tsx rename to packages/website/src/components/document/DocLinkCard.tsx index 60dc102d..41ae89e4 100644 --- a/packages/website/src/components/document/docLinkCard.tsx +++ b/packages/website/src/components/document/DocLinkCard.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import type { ReactNode } from "react" import type { ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../linkButton.js" +import { LinkButton } from "../LinkButton.js" export type DocLinkCardColor = "information" | "success" | "primary" | "warning" diff --git a/packages/website/src/components/document/docList.tsx b/packages/website/src/components/document/DocList.tsx similarity index 100% rename from packages/website/src/components/document/docList.tsx rename to packages/website/src/components/document/DocList.tsx diff --git a/packages/website/src/components/document/docNextPage.tsx b/packages/website/src/components/document/DocNextPage.tsx similarity index 97% rename from packages/website/src/components/document/docNextPage.tsx rename to packages/website/src/components/document/DocNextPage.tsx index f6fc2987..34cc52db 100644 --- a/packages/website/src/components/document/docNextPage.tsx +++ b/packages/website/src/components/document/DocNextPage.tsx @@ -2,7 +2,7 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" import type { ValidParams, ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../linkButton.js" +import { LinkButton } from "../LinkButton.js" export function DocNextPage(props: { to: ValidRoutes; params?: ValidParams; label: string; description?: string }) { return ( diff --git a/packages/website/src/components/document/docParagraph.tsx b/packages/website/src/components/document/DocParagraph.tsx similarity index 100% rename from packages/website/src/components/document/docParagraph.tsx rename to packages/website/src/components/document/DocParagraph.tsx diff --git a/packages/website/src/components/document/docRoot.tsx b/packages/website/src/components/document/DocRoot.tsx similarity index 100% rename from packages/website/src/components/document/docRoot.tsx rename to packages/website/src/components/document/DocRoot.tsx diff --git a/packages/website/src/components/document/docRouteRequest.tsx b/packages/website/src/components/document/DocRouteRequest.tsx similarity index 100% rename from packages/website/src/components/document/docRouteRequest.tsx rename to packages/website/src/components/document/DocRouteRequest.tsx diff --git a/packages/website/src/components/document/docSection.tsx b/packages/website/src/components/document/DocSection.tsx similarity index 100% rename from packages/website/src/components/document/docSection.tsx rename to packages/website/src/components/document/DocSection.tsx diff --git a/packages/website/src/components/document/docSectionCard.tsx b/packages/website/src/components/document/DocSectionCard.tsx similarity index 99% rename from packages/website/src/components/document/docSectionCard.tsx rename to packages/website/src/components/document/DocSectionCard.tsx index d93f00d2..1477e34c 100644 --- a/packages/website/src/components/document/docSectionCard.tsx +++ b/packages/website/src/components/document/DocSectionCard.tsx @@ -3,7 +3,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" import type { ReactNode } from "react" import type { ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../linkButton.js" +import { LinkButton } from "../LinkButton.js" export type DocSectionCardColor = "information" | "success" | "primary" | "warning" diff --git a/packages/website/src/components/document/docSourceRef.tsx b/packages/website/src/components/document/DocSourceRef.tsx similarity index 100% rename from packages/website/src/components/document/docSourceRef.tsx rename to packages/website/src/components/document/DocSourceRef.tsx diff --git a/packages/website/src/components/document/docSources.tsx b/packages/website/src/components/document/DocSources.tsx similarity index 100% rename from packages/website/src/components/document/docSources.tsx rename to packages/website/src/components/document/DocSources.tsx diff --git a/packages/website/src/components/document/docTable.tsx b/packages/website/src/components/document/DocTable.tsx similarity index 100% rename from packages/website/src/components/document/docTable.tsx rename to packages/website/src/components/document/DocTable.tsx diff --git a/packages/website/src/components/document/docTextSection.tsx b/packages/website/src/components/document/DocTextSection.tsx similarity index 100% rename from packages/website/src/components/document/docTextSection.tsx rename to packages/website/src/components/document/DocTextSection.tsx diff --git a/packages/website/src/components/document/docTip.tsx b/packages/website/src/components/document/DocTip.tsx similarity index 100% rename from packages/website/src/components/document/docTip.tsx rename to packages/website/src/components/document/DocTip.tsx diff --git a/packages/website/src/components/forms/formControl.tsx b/packages/website/src/components/forms/FormControl.tsx similarity index 100% rename from packages/website/src/components/forms/formControl.tsx rename to packages/website/src/components/forms/FormControl.tsx diff --git a/packages/website/src/components/forms/formError.tsx b/packages/website/src/components/forms/FormError.tsx similarity index 100% rename from packages/website/src/components/forms/formError.tsx rename to packages/website/src/components/forms/FormError.tsx diff --git a/packages/website/src/components/forms/formField.tsx b/packages/website/src/components/forms/FormField.tsx similarity index 100% rename from packages/website/src/components/forms/formField.tsx rename to packages/website/src/components/forms/FormField.tsx diff --git a/packages/website/src/components/forms/formGroup.tsx b/packages/website/src/components/forms/FormGroup.tsx similarity index 100% rename from packages/website/src/components/forms/formGroup.tsx rename to packages/website/src/components/forms/FormGroup.tsx diff --git a/packages/website/src/components/forms/formItem.tsx b/packages/website/src/components/forms/FormItem.tsx similarity index 100% rename from packages/website/src/components/forms/formItem.tsx rename to packages/website/src/components/forms/FormItem.tsx diff --git a/packages/website/src/components/forms/formLabel.tsx b/packages/website/src/components/forms/FormLabel.tsx similarity index 100% rename from packages/website/src/components/forms/formLabel.tsx rename to packages/website/src/components/forms/FormLabel.tsx diff --git a/packages/website/src/components/forms/formRoot.tsx b/packages/website/src/components/forms/FormRoot.tsx similarity index 100% rename from packages/website/src/components/forms/formRoot.tsx rename to packages/website/src/components/forms/FormRoot.tsx diff --git a/packages/website/src/components/forms/formSubmit.tsx b/packages/website/src/components/forms/FormSubmit.tsx similarity index 100% rename from packages/website/src/components/forms/formSubmit.tsx rename to packages/website/src/components/forms/FormSubmit.tsx diff --git a/packages/website/src/components/layouts/banner.tsx b/packages/website/src/components/layouts/Banner.tsx similarity index 100% rename from packages/website/src/components/layouts/banner.tsx rename to packages/website/src/components/layouts/Banner.tsx diff --git a/packages/website/src/components/layouts/box.tsx b/packages/website/src/components/layouts/Box.tsx similarity index 100% rename from packages/website/src/components/layouts/box.tsx rename to packages/website/src/components/layouts/Box.tsx diff --git a/packages/website/src/components/layouts/columnVisibilityPopover.tsx b/packages/website/src/components/layouts/ColumnVisibilityPopover.tsx similarity index 100% rename from packages/website/src/components/layouts/columnVisibilityPopover.tsx rename to packages/website/src/components/layouts/ColumnVisibilityPopover.tsx diff --git a/packages/website/src/components/layouts/dataTable.tsx b/packages/website/src/components/layouts/DataTable.tsx similarity index 99% rename from packages/website/src/components/layouts/dataTable.tsx rename to packages/website/src/components/layouts/DataTable.tsx index a66a3b96..fcd14878 100644 --- a/packages/website/src/components/layouts/dataTable.tsx +++ b/packages/website/src/components/layouts/DataTable.tsx @@ -26,11 +26,11 @@ import { type VisibilityState, } from "@tanstack/react-table" import { type ComponentProps, Fragment, type ReactElement, useMemo, useRef, useState } from "react" -import { ColumnVisibilityPopover, type VisibilityColumn } from "./columnVisibilityPopover.js" -import { EmptyState } from "./emptyState.js" -import { type FilterColumn, FilterPopover } from "./filterPopover.js" -import { SearchBar } from "./searchBar.js" -import { type SortDirection, SortPopover } from "./sortPopover.js" +import { ColumnVisibilityPopover, type VisibilityColumn } from "./ColumnVisibilityPopover.js" +import { EmptyState } from "./EmptyState.js" +import { type FilterColumn, FilterPopover } from "./FilterPopover.js" +import { SearchBar } from "./SearchBar.js" +import { type SortDirection, SortPopover } from "./SortPopover.js" declare module "@tanstack/react-table" { interface ColumnMeta { diff --git a/packages/website/src/components/layouts/dataWrapper.tsx b/packages/website/src/components/layouts/DataWrapper.tsx similarity index 100% rename from packages/website/src/components/layouts/dataWrapper.tsx rename to packages/website/src/components/layouts/DataWrapper.tsx diff --git a/packages/website/src/components/layouts/emptyState.tsx b/packages/website/src/components/layouts/EmptyState.tsx similarity index 100% rename from packages/website/src/components/layouts/emptyState.tsx rename to packages/website/src/components/layouts/EmptyState.tsx diff --git a/packages/website/src/components/layouts/filterPopover.tsx b/packages/website/src/components/layouts/FilterPopover.tsx similarity index 100% rename from packages/website/src/components/layouts/filterPopover.tsx rename to packages/website/src/components/layouts/FilterPopover.tsx diff --git a/packages/website/src/components/layouts/logo.tsx b/packages/website/src/components/layouts/Logo.tsx similarity index 100% rename from packages/website/src/components/layouts/logo.tsx rename to packages/website/src/components/layouts/Logo.tsx diff --git a/packages/website/src/components/layouts/searchBar.tsx b/packages/website/src/components/layouts/SearchBar.tsx similarity index 100% rename from packages/website/src/components/layouts/searchBar.tsx rename to packages/website/src/components/layouts/SearchBar.tsx diff --git a/packages/website/src/components/layouts/sortPopover.tsx b/packages/website/src/components/layouts/SortPopover.tsx similarity index 100% rename from packages/website/src/components/layouts/sortPopover.tsx rename to packages/website/src/components/layouts/SortPopover.tsx diff --git a/packages/website/src/components/layouts/subPageContent.tsx b/packages/website/src/components/layouts/SubPageContent.tsx similarity index 100% rename from packages/website/src/components/layouts/subPageContent.tsx rename to packages/website/src/components/layouts/SubPageContent.tsx diff --git a/packages/website/src/components/layouts/subPageLayout.tsx b/packages/website/src/components/layouts/SubPageLayout.tsx similarity index 99% rename from packages/website/src/components/layouts/subPageLayout.tsx rename to packages/website/src/components/layouts/SubPageLayout.tsx index ebf96b3c..4da8c2a8 100644 --- a/packages/website/src/components/layouts/subPageLayout.tsx +++ b/packages/website/src/components/layouts/SubPageLayout.tsx @@ -4,7 +4,7 @@ import { type Icon, IconMenu, type IconProps } from "@tabler/icons-react" import { Outlet, useMatches, useRouterState } from "@tanstack/react-router" import { cloneElement, type ReactElement, useState } from "react" import type { ValidParams, ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../linkButton.js" +import { LinkButton } from "../LinkButton.js" export function SubPageLayout(props: { sections: Record< diff --git a/packages/website/src/components/layouts/title.tsx b/packages/website/src/components/layouts/TitleComponent.tsx similarity index 100% rename from packages/website/src/components/layouts/title.tsx rename to packages/website/src/components/layouts/TitleComponent.tsx diff --git a/packages/website/src/components/layouts/virtualizer.tsx b/packages/website/src/components/layouts/Virtualizer.tsx similarity index 100% rename from packages/website/src/components/layouts/virtualizer.tsx rename to packages/website/src/components/layouts/Virtualizer.tsx diff --git a/packages/website/src/components/layouts/card/cardContent.tsx b/packages/website/src/components/layouts/card/CardContent.tsx similarity index 100% rename from packages/website/src/components/layouts/card/cardContent.tsx rename to packages/website/src/components/layouts/card/CardContent.tsx diff --git a/packages/website/src/components/layouts/card/cardHeader.tsx b/packages/website/src/components/layouts/card/CardHeader.tsx similarity index 100% rename from packages/website/src/components/layouts/card/cardHeader.tsx rename to packages/website/src/components/layouts/card/CardHeader.tsx diff --git a/packages/website/src/components/layouts/card/cardRoot.tsx b/packages/website/src/components/layouts/card/CardRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/card/cardRoot.tsx rename to packages/website/src/components/layouts/card/CardRoot.tsx diff --git a/packages/website/src/components/layouts/card/card.tsx b/packages/website/src/components/layouts/card/card.tsx index 5a782166..02981b9b 100644 --- a/packages/website/src/components/layouts/card/card.tsx +++ b/packages/website/src/components/layouts/card/card.tsx @@ -1,6 +1,6 @@ -import { CardContent } from "./cardContent.js" -import { CardHeader } from "./cardHeader.js" -import { CardRoot } from "./cardRoot.js" +import { CardContent } from "./CardContent.js" +import { CardHeader } from "./CardHeader.js" +import { CardRoot } from "./CardRoot.js" export const Card = { Root: CardRoot, diff --git a/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx b/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx new file mode 100644 index 00000000..8a794faf --- /dev/null +++ b/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx @@ -0,0 +1,494 @@ +import { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata/routes" +import { css, cx } from "@arrhes/ui/utilities/cn.js" +import { IconBuilding, IconCalendar, IconSearch, IconUser } from "@tabler/icons-react" +import { cloneElement, useEffect, useMemo, useRef, useState } from "react" +import { createPortal } from "react-dom" +import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" +import { useTabs } from "../../../contexts/tabs/useTabs.js" +import { levenshtein } from "../../../utilities/levenshtein.js" +import { useDataFromAPI } from "../../../utilities/useHTTPData.js" +import { + type OrgSearchRoute, + orgSearchRoutes, + type SearchRoute, + userSearchRoutes, + type YearSearchRoute, + yearSearchRoutes, +} from "./searchRoutes.js" + +// ─── Fuzzy filter ───────────────────────────────────────────────────────────── + +function scoreMatch(query: string, target: string): number { + const q = query.toLowerCase() + const t = target.toLowerCase() + if (t.includes(q)) return 0 + return levenshtein(q, t.slice(0, Math.max(t.length, q.length))) +} + +function filterRoutes< + T extends { + label: string + description?: string + }, +>(query: string, routes: T[], groupLabel?: string): T[] { + if (!query) return routes + const groupScore = groupLabel ? scoreMatch(query, groupLabel) : 99 + return routes + .map((r) => ({ + ...r, + _score: Math.min( + scoreMatch(query, r.label), + r.description ? scoreMatch(query, r.description) : 99, + groupScore, + ), + })) + .filter((r) => r._score <= 3) + .sort((a, b) => a._score - b._score) +} + +// ─── Component ──────────────────────────────────────────────────────────────── + +export function CommandPalette(props: { selectedOrgId: string | null; selectedYearId: string | null }) { + const { selectedOrgId, selectedYearId } = props + const [open, setOpen] = useState(false) + const [query, setQuery] = useState("") + const [selected, setSelected] = useState(0) + const [groupFilter, setGroupFilter] = useState<"user" | "org" | "year" | null>(null) + const { openTab } = useTabs() + const inputRef = useRef(null) + + const orgsData = useDataFromAPI({ + routeDefinition: getAllMyOrganizationsRouteDefinition, + body: {}, + }) + + // Reset on open + useEffect(() => { + if (open) { + setQuery("") + setSelected(0) + setGroupFilter(null) + setTimeout(() => inputRef.current?.focus(), 50) + } + }, [ + open, + ]) + + // Open via custom DOM event + useEffect(() => { + function handleOpen() { + setOpen(true) + } + window.addEventListener("arrhes:open-palette", handleOpen) + return () => window.removeEventListener("arrhes:open-palette", handleOpen) + }, []) + + // Close when a tab is opened + useEffect(() => { + function handleTabOpened() { + setOpen(false) + } + window.addEventListener("arrhes:tab-opened", handleTabOpened) + return () => window.removeEventListener("arrhes:tab-opened", handleTabOpened) + }, []) + + // Ctrl/Cmd+K shortcut + useEffect(() => { + function handleKey(e: KeyboardEvent) { + if ((e.ctrlKey || e.metaKey) && e.key === "k") { + e.preventDefault() + setOpen(true) + } + } + document.addEventListener("keydown", handleKey) + return () => document.removeEventListener("keydown", handleKey) + }, []) + + // ─── Result computation ──────────────────────────────────────────────────── + + const allOrgs = orgsData.data ?? [] + + // User section: static pages + matching orgs (when no org selected) + const filteredUserPages = filterRoutes(query, userSearchRoutes, "Utilisateur") + + const filteredOrgItems: SearchRoute[] = useMemo(() => { + if (!selectedOrgId) { + // Show orgs as navigable items — open their exercices tab. + return filterRoutes( + query, + allOrgs.map((ou) => ({ + label: ou.organization.name, + description: "Organisation", + tabComponent: "exercices", + tabProps: { + idOrganization: ou.organization.id, + }, + })), + "Organisations", + ) + } + // Show org-level sub-routes. + return filterRoutes( + query, + orgSearchRoutes.map( + (r: OrgSearchRoute): SearchRoute => ({ + label: r.label, + description: r.description, + tabComponent: r.tabComponent, + tabProps: { + idOrganization: selectedOrgId, + }, + }), + ), + "Organisation", + ) + }, [ + query, + allOrgs, + selectedOrgId, + ]) + + const filteredYearItems: SearchRoute[] = useMemo(() => { + if (!selectedOrgId || !selectedYearId) return [] + return filterRoutes( + query, + yearSearchRoutes.map( + (r: YearSearchRoute): SearchRoute => ({ + label: r.label, + description: r.description, + tabComponent: r.tabComponent, + tabProps: { + idOrganization: selectedOrgId, + idYear: selectedYearId, + }, + }), + ), + "Exercice", + ) + }, [ + query, + selectedOrgId, + selectedYearId, + ]) + + const orgLabel = selectedOrgId ? "Organisation" : "Organisations" + + const allItems: Array = [ + ...(groupFilter === null || groupFilter === "user" + ? filteredUserPages.map((r) => ({ ...r, group: "Utilisateur" })) + : []), + ...(groupFilter === null || groupFilter === "org" + ? filteredOrgItems.map((r) => ({ ...r, group: orgLabel })) + : []), + ...(groupFilter === null || groupFilter === "year" + ? filteredYearItems.map((r) => ({ ...r, group: "Exercice" })) + : []), + ] + + function activate(item: SearchRoute) { + setOpen(false) + openTab( + { + component: item.tabComponent, + props: item.tabProps, + } as OpenTabArgs, + { + newTab: true, + }, + ) + } + + function handleKeyDown(e: React.KeyboardEvent) { + if (e.key === "ArrowDown") { + e.preventDefault() + setSelected((s) => Math.min(s + 1, allItems.length - 1)) + } else if (e.key === "ArrowUp") { + e.preventDefault() + setSelected((s) => Math.max(s - 1, 0)) + } else if (e.key === "Enter") { + e.preventDefault() + const item = allItems[selected] + if (item) activate(item) + } else if (e.key === "Escape") { + setOpen(false) + } + } + + // Keep selected index in bounds when filtered list changes + useEffect(() => { + setSelected(0) + }, [ + query, + selectedOrgId, + selectedYearId, + ]) + + if (!open) return null + + return createPortal( +
{ + if (e.target === e.currentTarget) setOpen(false) + }} + > +
+ {/* Search input */} +
+ + setQuery(e.target.value)} + placeholder="Rechercher des pages, organisations…" + className={css({ + flex: 1, + fontSize: "0.9375rem", + border: "none", + outline: "none", + background: "transparent", + color: "neutral/900", + _placeholder: { + color: "neutral/400", + }, + })} + /> +
+ + {/* Group filter bar */} +
+ {( + [ + { key: null, label: "Tout", icon: null }, + { key: "user" as const, label: "Utilisateur", icon: }, + { + key: "org" as const, + label: selectedOrgId ? "Organisation" : "Organisations", + icon: , + }, + ...(selectedOrgId && selectedYearId + ? [{ key: "year" as const, label: "Exercice", icon: }] + : []), + ] as const + ).map((group) => { + const isActive = groupFilter === group.key + return ( + + ) + })} +
+ + {/* Results */} +
+ {allItems.length === 0 && ( +

+ {query ? `Aucun résultat pour « ${query} »` : "Aucun résultat"} +

+ )} + + {allItems.map((item, i) => ( + setSelected(i)} + onClick={() => activate(item)} + /> + ))} +
+
+
, + document.body, + ) +} + +// ─── Sub-components ─────────────────────────────────────────────────────────── + +function ResultRow(props: { + group: string + label: string + description?: string + active: boolean + onMouseEnter: () => void + onClick: () => void +}) { + return ( + + ) +} diff --git a/packages/website/src/components/layouts/commandPalette/ContextSelect.tsx b/packages/website/src/components/layouts/commandPalette/ContextSelect.tsx new file mode 100644 index 00000000..31b26069 --- /dev/null +++ b/packages/website/src/components/layouts/commandPalette/ContextSelect.tsx @@ -0,0 +1,23 @@ +import { InputCombobox } from "@arrhes/ui" + +export function ContextSelect(props: { + placeholder: string + value: string | null + onChange: (v: string | null) => void + options: { + key: string + label: string + }[] + isLoading?: boolean +}) { + return ( + props.onChange(v ?? null)} + options={props.options} + isLoading={props.isLoading} + allowEmpty={true} + /> + ) +} diff --git a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx index f772efc3..7d356665 100644 --- a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx +++ b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx @@ -1,11 +1,10 @@ import { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata/routes" -import { InputCombobox } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBuilding, IconCalendar, IconLayoutGrid, IconSearch, IconUser } from "@tabler/icons-react" import { useEffect, useMemo, useRef, useState } from "react" import { createPortal } from "react-dom" import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" -import { useTabs } from "../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../contexts/tabs/useTabs.js" import { levenshtein } from "../../../utilities/levenshtein.js" import { useDataFromAPI } from "../../../utilities/useHTTPData.js" import { @@ -370,30 +369,6 @@ export function CommandPalette(props: { selectedOrgId: string | null; selectedYe ) } -// ─── ContextSelect ──────────────────────────────────────────────────────────── - -export function ContextSelect(props: { - placeholder: string - value: string | null - onChange: (v: string | null) => void - options: { - key: string - label: string - }[] - isLoading?: boolean -}) { - return ( - props.onChange(v ?? null)} - options={props.options} - isLoading={props.isLoading} - allowEmpty={true} - /> - ) -} - // ─── Sub-components ─────────────────────────────────────────────────────────── function Section({ label, icon, children }: { label: string; icon?: React.ReactNode; children: React.ReactNode }) { diff --git a/packages/website/src/components/layouts/commandPalette/searchRoutes.ts b/packages/website/src/components/layouts/commandPalette/searchRoutes.ts index 74bafe38..e5fc2d40 100644 --- a/packages/website/src/components/layouts/commandPalette/searchRoutes.ts +++ b/packages/website/src/components/layouts/commandPalette/searchRoutes.ts @@ -16,12 +16,6 @@ export const userSearchRoutes: SearchRoute[] = [ tabComponent: "organisations", tabProps: {}, }, - { - label: "Agent IA", - description: "Assistant comptable intelligent", - tabComponent: "agent", - tabProps: {}, - }, { label: "Profil", description: "Votre profil utilisateur", @@ -52,6 +46,11 @@ export type OrgSearchRoute = { } export const orgSearchRoutes: OrgSearchRoute[] = [ + { + label: "Agent IA", + description: "Assistant comptable intelligent", + tabComponent: "agent", + }, { label: "Exercices", description: "Années fiscales", @@ -78,7 +77,7 @@ export const orgSearchRoutes: OrgSearchRoute[] = [ tabComponent: "organisation-paramètres", }, { - label: "Clés API", + label: "API", description: "Accès API de l'organisation", tabComponent: "organisation-api", }, @@ -104,11 +103,6 @@ export const yearSearchRoutes: YearSearchRoute[] = [ description: "Rapports, bilans et compte de résultat", tabComponent: "exercice-documents", }, - { - label: "Stockage de l'exercice", - description: "Fichiers attachés à l'exercice", - tabComponent: "exercice-stockage", - }, { label: "Paramètres de l'exercice", description: "Journaux, catégories, plan comptable", diff --git a/packages/website/src/components/layouts/dataBlock/dataBlockContent.tsx b/packages/website/src/components/layouts/dataBlock/DataBlockContent.tsx similarity index 100% rename from packages/website/src/components/layouts/dataBlock/dataBlockContent.tsx rename to packages/website/src/components/layouts/dataBlock/DataBlockContent.tsx diff --git a/packages/website/src/components/layouts/dataBlock/dataBlockHeader.tsx b/packages/website/src/components/layouts/dataBlock/DataBlockHeader.tsx similarity index 100% rename from packages/website/src/components/layouts/dataBlock/dataBlockHeader.tsx rename to packages/website/src/components/layouts/dataBlock/DataBlockHeader.tsx diff --git a/packages/website/src/components/layouts/dataBlock/dataBlockItem.tsx b/packages/website/src/components/layouts/dataBlock/DataBlockItem.tsx similarity index 100% rename from packages/website/src/components/layouts/dataBlock/dataBlockItem.tsx rename to packages/website/src/components/layouts/dataBlock/DataBlockItem.tsx diff --git a/packages/website/src/components/layouts/dataBlock/dataBlockRoot.tsx b/packages/website/src/components/layouts/dataBlock/DataBlockRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/dataBlock/dataBlockRoot.tsx rename to packages/website/src/components/layouts/dataBlock/DataBlockRoot.tsx diff --git a/packages/website/src/components/layouts/dataBlock/dataBlock.tsx b/packages/website/src/components/layouts/dataBlock/dataBlock.tsx index 1a080372..1e86a9ff 100644 --- a/packages/website/src/components/layouts/dataBlock/dataBlock.tsx +++ b/packages/website/src/components/layouts/dataBlock/dataBlock.tsx @@ -1,7 +1,7 @@ -import { DataBlockContent } from "./dataBlockContent.js" -import { DataBlockHeader } from "./dataBlockHeader.js" -import { DataBlockItem } from "./dataBlockItem.js" -import { DataBlockRoot } from "./dataBlockRoot.js" +import { DataBlockContent } from "./DataBlockContent.js" +import { DataBlockHeader } from "./DataBlockHeader.js" +import { DataBlockItem } from "./DataBlockItem.js" +import { DataBlockRoot } from "./DataBlockRoot.js" export const DataBlock = { Root: DataBlockRoot, diff --git a/packages/website/src/components/layouts/listTable/listTableFilterable.tsx b/packages/website/src/components/layouts/listTable/ListTableFilterable.tsx similarity index 97% rename from packages/website/src/components/layouts/listTable/listTableFilterable.tsx rename to packages/website/src/components/layouts/listTable/ListTableFilterable.tsx index 78d42546..63ca1743 100644 --- a/packages/website/src/components/layouts/listTable/listTableFilterable.tsx +++ b/packages/website/src/components/layouts/listTable/ListTableFilterable.tsx @@ -1,8 +1,8 @@ import { InputDebounced, InputText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { type ReactElement, useMemo, useState } from "react" -import { type FilterColumn, FilterPopover } from "../filterPopover.js" -import { type SortDirection, SortPopover } from "../sortPopover.js" +import { type FilterColumn, FilterPopover } from "../FilterPopover.js" +import { type SortDirection, SortPopover } from "../SortPopover.js" export type ListTableColumn = FilterColumn & { id: string diff --git a/packages/website/src/components/layouts/listTable/listTableRoot.tsx b/packages/website/src/components/layouts/listTable/ListTableRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/listTable/listTableRoot.tsx rename to packages/website/src/components/layouts/listTable/ListTableRoot.tsx diff --git a/packages/website/src/components/layouts/listTable/listTableRow.tsx b/packages/website/src/components/layouts/listTable/ListTableRow.tsx similarity index 100% rename from packages/website/src/components/layouts/listTable/listTableRow.tsx rename to packages/website/src/components/layouts/listTable/ListTableRow.tsx diff --git a/packages/website/src/components/layouts/listTable/listTable.tsx b/packages/website/src/components/layouts/listTable/listTable.tsx index badfc9f5..bc77d62a 100644 --- a/packages/website/src/components/layouts/listTable/listTable.tsx +++ b/packages/website/src/components/layouts/listTable/listTable.tsx @@ -1,6 +1,6 @@ -import { ListTableFilterable } from "./listTableFilterable.js" -import { ListTableRoot } from "./listTableRoot.js" -import { ListTableRow } from "./listTableRow.js" +import { ListTableFilterable } from "./ListTableFilterable.js" +import { ListTableRoot } from "./ListTableRoot.js" +import { ListTableRow } from "./ListTableRow.js" export const ListTable = { Root: ListTableRoot, @@ -8,4 +8,4 @@ export const ListTable = { Filterable: ListTableFilterable, } -export type { ListTableColumn } from "./listTableFilterable.js" +export type { ListTableColumn } from "./ListTableFilterable.js" diff --git a/packages/website/src/components/layouts/page/pageContent.tsx b/packages/website/src/components/layouts/page/PageContent.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageContent.tsx rename to packages/website/src/components/layouts/page/PageContent.tsx diff --git a/packages/website/src/components/layouts/page/pageDescription.tsx b/packages/website/src/components/layouts/page/PageDescription.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageDescription.tsx rename to packages/website/src/components/layouts/page/PageDescription.tsx diff --git a/packages/website/src/components/layouts/page/pageHeader.tsx b/packages/website/src/components/layouts/page/PageHeader.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageHeader.tsx rename to packages/website/src/components/layouts/page/PageHeader.tsx diff --git a/packages/website/src/components/layouts/page/pageNavigation.tsx b/packages/website/src/components/layouts/page/PageNavigation.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageNavigation.tsx rename to packages/website/src/components/layouts/page/PageNavigation.tsx diff --git a/packages/website/src/components/layouts/page/pageRoot.tsx b/packages/website/src/components/layouts/page/PageRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageRoot.tsx rename to packages/website/src/components/layouts/page/PageRoot.tsx diff --git a/packages/website/src/components/layouts/page/pageSeparator.tsx b/packages/website/src/components/layouts/page/PageSeparator.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageSeparator.tsx rename to packages/website/src/components/layouts/page/PageSeparator.tsx diff --git a/packages/website/src/components/layouts/page/pageTitle.tsx b/packages/website/src/components/layouts/page/PageTitle.tsx similarity index 100% rename from packages/website/src/components/layouts/page/pageTitle.tsx rename to packages/website/src/components/layouts/page/PageTitle.tsx diff --git a/packages/website/src/components/layouts/page/page.tsx b/packages/website/src/components/layouts/page/page.tsx index cd791793..4c9d6d2a 100644 --- a/packages/website/src/components/layouts/page/page.tsx +++ b/packages/website/src/components/layouts/page/page.tsx @@ -1,10 +1,10 @@ -import { PageContent } from "./pageContent.js" -import { PageDescription } from "./pageDescription.js" -import { PageHeader } from "./pageHeader.js" -import { PageNavigation } from "./pageNavigation.js" -import { PageRoot } from "./pageRoot.js" -import { PageSeparator } from "./pageSeparator.js" -import { PageTitle } from "./pageTitle.js" +import { PageContent } from "./PageContent.js" +import { PageDescription } from "./PageDescription.js" +import { PageHeader } from "./PageHeader.js" +import { PageNavigation } from "./PageNavigation.js" +import { PageRoot } from "./PageRoot.js" +import { PageSeparator } from "./PageSeparator.js" +import { PageTitle } from "./PageTitle.js" export const Page = { Root: PageRoot, diff --git a/packages/website/src/components/layouts/section/sectionItem.tsx b/packages/website/src/components/layouts/section/SectionItem.tsx similarity index 100% rename from packages/website/src/components/layouts/section/sectionItem.tsx rename to packages/website/src/components/layouts/section/SectionItem.tsx diff --git a/packages/website/src/components/layouts/section/sectionRoot.tsx b/packages/website/src/components/layouts/section/SectionRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/section/sectionRoot.tsx rename to packages/website/src/components/layouts/section/SectionRoot.tsx diff --git a/packages/website/src/components/layouts/section/section.tsx b/packages/website/src/components/layouts/section/section.tsx index 4177c020..c510c236 100644 --- a/packages/website/src/components/layouts/section/section.tsx +++ b/packages/website/src/components/layouts/section/section.tsx @@ -1,5 +1,5 @@ -import { SectionItem } from "./sectionItem.js" -import { SectionRoot } from "./sectionRoot.js" +import { SectionItem } from "./SectionItem.js" +import { SectionRoot } from "./SectionRoot.js" export const Section = { Root: SectionRoot, diff --git a/packages/website/src/components/layouts/settingsSection/settingsSectionHeader.tsx b/packages/website/src/components/layouts/settingsSection/SettingsSectionHeader.tsx similarity index 100% rename from packages/website/src/components/layouts/settingsSection/settingsSectionHeader.tsx rename to packages/website/src/components/layouts/settingsSection/SettingsSectionHeader.tsx diff --git a/packages/website/src/components/layouts/settingsSection/settingsSectionRoot.tsx b/packages/website/src/components/layouts/settingsSection/SettingsSectionRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/settingsSection/settingsSectionRoot.tsx rename to packages/website/src/components/layouts/settingsSection/SettingsSectionRoot.tsx diff --git a/packages/website/src/components/layouts/settingsSection/settingsSectionRow.tsx b/packages/website/src/components/layouts/settingsSection/SettingsSectionRow.tsx similarity index 100% rename from packages/website/src/components/layouts/settingsSection/settingsSectionRow.tsx rename to packages/website/src/components/layouts/settingsSection/SettingsSectionRow.tsx diff --git a/packages/website/src/components/layouts/settingsSection/settingsSection.tsx b/packages/website/src/components/layouts/settingsSection/settingsSection.tsx index 2437db58..9a5462ae 100644 --- a/packages/website/src/components/layouts/settingsSection/settingsSection.tsx +++ b/packages/website/src/components/layouts/settingsSection/settingsSection.tsx @@ -1,6 +1,6 @@ -import { SettingsSectionHeader } from "./settingsSectionHeader.js" -import { SettingsSectionRoot } from "./settingsSectionRoot.js" -import { SettingsSectionRow } from "./settingsSectionRow.js" +import { SettingsSectionHeader } from "./SettingsSectionHeader.js" +import { SettingsSectionRoot } from "./SettingsSectionRoot.js" +import { SettingsSectionRow } from "./SettingsSectionRow.js" export const SettingsSection = { Root: SettingsSectionRoot, diff --git a/packages/website/src/components/layouts/tab/tabRoot.tsx b/packages/website/src/components/layouts/tab/TabRoot.tsx similarity index 97% rename from packages/website/src/components/layouts/tab/tabRoot.tsx rename to packages/website/src/components/layouts/tab/TabRoot.tsx index 8f55589a..cd5ad068 100644 --- a/packages/website/src/components/layouts/tab/tabRoot.tsx +++ b/packages/website/src/components/layouts/tab/TabRoot.tsx @@ -4,7 +4,7 @@ import type { Icon, IconProps } from "@tabler/icons-react" import { useMatches, useRouterState } from "@tanstack/react-router" import type { ReactElement } from "react" import type { ValidParams, ValidRoutes } from "../../../routes/applicationRouter.js" -import { LinkButton } from "../../linkButton.js" +import { LinkButton } from "../../LinkButton.js" export function TabRoot(props: { tabs: Array<{ diff --git a/packages/website/src/components/layouts/tab/tab.tsx b/packages/website/src/components/layouts/tab/tab.tsx index ad0c864e..15db2ca9 100644 --- a/packages/website/src/components/layouts/tab/tab.tsx +++ b/packages/website/src/components/layouts/tab/tab.tsx @@ -1,4 +1,4 @@ -import { TabRoot } from "./tabRoot.js" +import { TabRoot } from "./TabRoot.js" export const Tab = { Root: TabRoot, diff --git a/packages/website/src/components/layouts/tabBar/splitTabBar.tsx b/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx similarity index 67% rename from packages/website/src/components/layouts/tabBar/splitTabBar.tsx rename to packages/website/src/components/layouts/tabBar/SplitTabBar.tsx index 04d5f395..367bbf1b 100644 --- a/packages/website/src/components/layouts/tabBar/splitTabBar.tsx +++ b/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx @@ -2,7 +2,8 @@ import { Button, ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconChevronRight, IconX } from "@tabler/icons-react" import { useState } from "react" -import { type ComponentTab, currentEntry, useTabs } from "../../../contexts/tabs/tabsContext.js" +import { type ComponentTab, currentEntry } from "../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../contexts/tabs/useTabs.js" type Props = { tabIds: string[] @@ -62,16 +63,17 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord }} onDrop={(e) => handleDrop(e, null)} > - {panelTabs.map((tab) => { + {panelTabs.map((tab, index) => { const isActive = tab.id === activeTabId - const title = - tab.type === "component" - ? currentEntry(tab as ComponentTab).title - : ( - tab as { - title: string - } - ).title + const entry = tab.type === "component" ? currentEntry(tab as ComponentTab) : null + const title = entry + ? entry.title + : ( + tab as { + title: string + } + ).title + const description = entry?.description return (
{ e.dataTransfer.setData("application/arrhes-right-tab", tab.id) @@ -109,14 +116,26 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord ) { e.preventDefault() e.stopPropagation() - setDragOverTabId(tab.id) + const rect = e.currentTarget.getBoundingClientRect() + const insertBeforeTabId = + e.clientX < rect.left + rect.width / 2 + ? tab.id + : (panelTabs[index + 1]?.id ?? null) + setDragOverTabId(insertBeforeTabId) } }} onDragLeave={(e) => { if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setDragOverTabId(null) }} - onDrop={(e) => handleDrop(e, tab.id)} + onDrop={(e) => { + const rect = e.currentTarget.getBoundingClientRect() + const insertBeforeTabId = + e.clientX < rect.left + rect.width / 2 + ? tab.id + : (panelTabs[index + 1]?.id ?? null) + handleDrop(e, insertBeforeTabId) + }} onClick={() => onActivate(tab.id)} > {tab.type === "component" && ( @@ -150,16 +169,37 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord className={css({ paddingLeft: "0.5rem", flex: 1, - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap", - fontSize: "0.8125rem", - fontWeight: isActive ? "600" : "400", - color: isActive ? "primary/800" : "neutral/600", + display: "flex", + flexDirection: "column", + minWidth: 0, })} - title={title} + title={description ? `${title} — ${description}` : title} > - {title} + + {title} + + {description && ( + + {description} + + )} +
+ ) + })} + + {!isRightPanel && ( +
+ +
+ )} + + {rightSlot && ( +
+ {rightSlot} +
+ )} +
+ + + {contextTab ? ( + <> + } + disabled={!contextTabCanGoBack} + onSelect={() => navigateBack(contextTab.id)} + > + Retour + + } + disabled={!contextTabCanGoForward} + onSelect={() => navigateForward(contextTab.id)} + > + Suivant + + + {!isRightPanel && ( + } + onSelect={() => + window.dispatchEvent( + new CustomEvent("arrhes:split-tab", { + detail: { tabId: contextTab.id }, + }), + ) + } + > + Ouvrir en vue divisée + + )} + } + onSelect={() => onCloseTab(contextTab.id)} + > + Fermer l'onglet + + + ) : ( + <> + {tabs.length > 1 && ( + { + const keepId = activeTabId + for (const t of tabs) { + if (t.id !== keepId) onCloseTab(t.id) + } + }} + > + Fermer les autres onglets + + )} + {onMergePanels && ( + } + onSelect={onMergePanels} + > + Fusionner les panneaux + + )} + + )} + + + ) +} diff --git a/packages/website/src/components/layouts/tabBar/tabLink.tsx b/packages/website/src/components/layouts/tabBar/TabLink.tsx similarity index 96% rename from packages/website/src/components/layouts/tabBar/tabLink.tsx rename to packages/website/src/components/layouts/tabBar/TabLink.tsx index ad28f031..daa89ded 100644 --- a/packages/website/src/components/layouts/tabBar/tabLink.tsx +++ b/packages/website/src/components/layouts/tabBar/TabLink.tsx @@ -2,7 +2,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconExternalLink } from "@tabler/icons-react" import type { ReactNode } from "react" import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" -import { useTabs } from "../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../contexts/tabs/useTabs.js" import { ContextMenu } from "../../overlays/contextMenu/contextMenu.js" type TabLinkProps = { diff --git a/packages/website/src/components/layouts/tabBar/tabBar.tsx b/packages/website/src/components/layouts/tabBar/tabBar.tsx deleted file mode 100644 index 272810bb..00000000 --- a/packages/website/src/components/layouts/tabBar/tabBar.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import { Button, ButtonGhostContent } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconChevronLeft, IconChevronRight, IconLayoutColumns, IconPlus, IconX } from "@tabler/icons-react" -import { type ReactNode, useState } from "react" -import { type ComponentTab, currentEntry, useTabs } from "../../../contexts/tabs/tabsContext.js" -import { ContextMenu } from "../../overlays/contextMenu/contextMenu.js" - -type TabBarProps = { - excludeTabIds?: string[] - rightSlot?: ReactNode - onDropFromRight?: (tabId: string, insertBeforeTabId: string | null) => void - onMergePanels?: () => void -} - -export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanels }: TabBarProps = {}) { - const { tabs: allTabs, activeTabId, activateTab, closeTab, navigateBack, navigateForward, reorderTabs } = useTabs() - const tabs = allTabs.filter((t) => !excludeTabIds?.includes(t.id)) - const [dragOverTabId, setDragOverTabId] = useState(null) - const [contextMenuTabId, setContextMenuTabId] = useState(null) - const contextTab = contextMenuTabId !== null ? (tabs.find((t) => t.id === contextMenuTabId) ?? null) : null - - return ( - { if (!open) setContextMenuTabId(null) }}> - -
setContextMenuTabId(null)} - onDragOver={(e) => { - if ( - e.dataTransfer.types.includes("application/arrhes-left-tab") || - e.dataTransfer.types.includes("application/arrhes-right-tab") - ) - e.preventDefault() - }} - onDrop={(e) => { - const fromLeft = e.dataTransfer.types.includes("application/arrhes-left-tab") - const draggedTabId = fromLeft - ? e.dataTransfer.getData("application/arrhes-left-tab") - : e.dataTransfer.getData("application/arrhes-right-tab") - if (!draggedTabId) return - setDragOverTabId(null) - if (fromLeft) reorderTabs(draggedTabId, null) - else onDropFromRight?.(draggedTabId, null) - }} - > - {tabs.map((tab) => { - const isActive = tab.id === activeTabId - const title = - tab.type === "component" ? currentEntry(tab as ComponentTab).title : tab.title - const canGoBack = tab.type === "component" && (tab as ComponentTab).historyIndex > 0 - const canGoForward = - tab.type === "component" && - (tab as ComponentTab).historyIndex < (tab as ComponentTab).history.length - 1 - return ( -
{ - e.dataTransfer.setData("application/arrhes-left-tab", tab.id) - e.dataTransfer.effectAllowed = "move" - }} - onDragEnd={(e) => { - setDragOverTabId(null) - if (e.dataTransfer.dropEffect === "none") { - window.dispatchEvent( - new CustomEvent("arrhes:split-tab", { - detail: { tabId: tab.id }, - }), - ) - } - }} - onDragOver={(e) => { - if ( - e.dataTransfer.types.includes("application/arrhes-left-tab") || - e.dataTransfer.types.includes("application/arrhes-right-tab") - ) { - e.preventDefault() - e.stopPropagation() - setDragOverTabId(tab.id) - } - }} - onDragLeave={(e) => { - if (!e.currentTarget.contains(e.relatedTarget as Node | null)) - setDragOverTabId(null) - }} - onDrop={(e) => { - e.preventDefault() - e.stopPropagation() - setDragOverTabId(null) - const fromLeft = e.dataTransfer.types.includes( - "application/arrhes-left-tab", - ) - const draggedTabId = fromLeft - ? e.dataTransfer.getData("application/arrhes-left-tab") - : e.dataTransfer.getData("application/arrhes-right-tab") - if (!draggedTabId) return - if (fromLeft) reorderTabs(draggedTabId, tab.id) - else onDropFromRight?.(draggedTabId, tab.id) - }} - onClick={() => activateTab(tab.id)} - onContextMenu={() => setContextMenuTabId(tab.id)} - > - {tab.type === "component" && ( - <> - - - - )} - - {title} - - -
- ) - })} - - {/* New tab button */} -
- -
- - {rightSlot && ( -
- {rightSlot} -
- )} -
-
- - {contextTab ? ( - <> - } - onSelect={() => - window.dispatchEvent( - new CustomEvent("arrhes:split-tab", { - detail: { tabId: contextTab.id }, - }), - ) - } - > - Ouvrir en vue divisée - - } - onSelect={() => closeTab(contextTab.id)} - > - Fermer l'onglet - - {tabs.length > 1 && ( - { - for (const t of tabs) { - if (t.id !== contextTab.id) closeTab(t.id) - } - }} - > - Fermer les autres onglets - - )} - - ) : onMergePanels ? ( - } - onSelect={onMergePanels} - > - Fusionner les panneaux - - ) : null} - -
- ) -} diff --git a/packages/website/src/components/layouts/table/tableRoot.tsx b/packages/website/src/components/layouts/table/TableRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/table/tableRoot.tsx rename to packages/website/src/components/layouts/table/TableRoot.tsx diff --git a/packages/website/src/components/layouts/table/table.tsx b/packages/website/src/components/layouts/table/table.tsx index aab6594b..02d03349 100644 --- a/packages/website/src/components/layouts/table/table.tsx +++ b/packages/website/src/components/layouts/table/table.tsx @@ -1,12 +1,12 @@ -import { FilterPopover } from "../filterPopover.js" -import { SortPopover } from "../sortPopover.js" -import { TableBodyCell } from "./tableBody/tableBodyCell.js" +import { FilterPopover } from "../FilterPopover.js" +import { SortPopover } from "../SortPopover.js" +import { TableBodyCell } from "./tableBody/TableBodyCell.js" import { TableBodyRoot } from "./tableBody/tableBodyRoot.js" -import { TableBodyRow } from "./tableBody/tableBodyRow.js" -import { TableHeaderCell } from "./tableHeader/tableHeaderCell.js" -import { TableHeaderRoot } from "./tableHeader/tableHeaderRoot.js" -import { TableHeaderRow } from "./tableHeader/tableHeaderRow.js" -import { TableRoot } from "./tableRoot.js" +import { TableBodyRow } from "./tableBody/TableBodyRow.js" +import { TableHeaderCell } from "./tableHeader/TableHeaderCell.js" +import { TableHeaderRoot } from "./tableHeader/TableHeaderRoot.js" +import { TableHeaderRow } from "./tableHeader/TableHeaderRow.js" +import { TableRoot } from "./TableRoot.js" export const Table = { Root: TableRoot, diff --git a/packages/website/src/components/layouts/table/tableBody/tableBodyCell.tsx b/packages/website/src/components/layouts/table/tableBody/TableBodyCell.tsx similarity index 100% rename from packages/website/src/components/layouts/table/tableBody/tableBodyCell.tsx rename to packages/website/src/components/layouts/table/tableBody/TableBodyCell.tsx diff --git a/packages/website/src/components/layouts/table/tableBody/tableBodyRow.tsx b/packages/website/src/components/layouts/table/tableBody/TableBodyRow.tsx similarity index 100% rename from packages/website/src/components/layouts/table/tableBody/tableBodyRow.tsx rename to packages/website/src/components/layouts/table/tableBody/TableBodyRow.tsx diff --git a/packages/website/src/components/layouts/table/tableHeader/tableHeaderCell.tsx b/packages/website/src/components/layouts/table/tableHeader/TableHeaderCell.tsx similarity index 100% rename from packages/website/src/components/layouts/table/tableHeader/tableHeaderCell.tsx rename to packages/website/src/components/layouts/table/tableHeader/TableHeaderCell.tsx diff --git a/packages/website/src/components/layouts/table/tableHeader/tableHeaderRoot.tsx b/packages/website/src/components/layouts/table/tableHeader/TableHeaderRoot.tsx similarity index 100% rename from packages/website/src/components/layouts/table/tableHeader/tableHeaderRoot.tsx rename to packages/website/src/components/layouts/table/tableHeader/TableHeaderRoot.tsx diff --git a/packages/website/src/components/layouts/table/tableHeader/tableHeaderRow.tsx b/packages/website/src/components/layouts/table/tableHeader/TableHeaderRow.tsx similarity index 100% rename from packages/website/src/components/layouts/table/tableHeader/tableHeaderRow.tsx rename to packages/website/src/components/layouts/table/tableHeader/TableHeaderRow.tsx diff --git a/packages/website/src/components/overlays/contextMenu/contextMenuContent.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx similarity index 100% rename from packages/website/src/components/overlays/contextMenu/contextMenuContent.tsx rename to packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx diff --git a/packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx similarity index 80% rename from packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx rename to packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx index 81b6c310..9c05ffa5 100644 --- a/packages/website/src/components/overlays/contextMenu/contextMenuItem.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx @@ -32,17 +32,22 @@ export function ContextMenuItem( backgroundColor: "neutral/5", outline: "none", }, + "&[data-disabled]": { + opacity: 0.4, + cursor: "default", + pointerEvents: "none", + }, }), color === "danger" ? css({ - color: "error", - _hover: { - backgroundColor: "red.50", - }, - }) + color: "error", + _hover: { + backgroundColor: "red.50", + }, + }) : css({ - color: "neutral", - }), + color: "neutral", + }), props.className, )} > diff --git a/packages/website/src/components/overlays/contextMenu/contextMenuRoot.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuRoot.tsx similarity index 100% rename from packages/website/src/components/overlays/contextMenu/contextMenuRoot.tsx rename to packages/website/src/components/overlays/contextMenu/ContextMenuRoot.tsx diff --git a/packages/website/src/components/overlays/contextMenu/contextMenuSeparator.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuSeparator.tsx similarity index 100% rename from packages/website/src/components/overlays/contextMenu/contextMenuSeparator.tsx rename to packages/website/src/components/overlays/contextMenu/ContextMenuSeparator.tsx diff --git a/packages/website/src/components/overlays/contextMenu/contextMenuTrigger.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuTrigger.tsx similarity index 100% rename from packages/website/src/components/overlays/contextMenu/contextMenuTrigger.tsx rename to packages/website/src/components/overlays/contextMenu/ContextMenuTrigger.tsx diff --git a/packages/website/src/components/overlays/contextMenu/contextMenu.tsx b/packages/website/src/components/overlays/contextMenu/contextMenu.tsx index 5ed73f8d..34c7ee0f 100644 --- a/packages/website/src/components/overlays/contextMenu/contextMenu.tsx +++ b/packages/website/src/components/overlays/contextMenu/contextMenu.tsx @@ -1,8 +1,8 @@ -import { ContextMenuContent } from "./contextMenuContent.js" -import { ContextMenuItem } from "./contextMenuItem.js" -import { ContextMenuRoot } from "./contextMenuRoot.js" -import { ContextMenuSeparator } from "./contextMenuSeparator.js" -import { ContextMenuTrigger } from "./contextMenuTrigger.js" +import { ContextMenuContent } from "./ContextMenuContent.js" +import { ContextMenuItem } from "./ContextMenuItem.js" +import { ContextMenuRoot } from "./ContextMenuRoot.js" +import { ContextMenuSeparator } from "./ContextMenuSeparator.js" +import { ContextMenuTrigger } from "./ContextMenuTrigger.js" export const ContextMenu = { Root: ContextMenuRoot, diff --git a/packages/website/src/components/overlays/dialog/confirmationModal.tsx b/packages/website/src/components/overlays/dialog/ConfirmationModal.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/confirmationModal.tsx rename to packages/website/src/components/overlays/dialog/ConfirmationModal.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogBody.tsx b/packages/website/src/components/overlays/dialog/DialogBody.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogBody.tsx rename to packages/website/src/components/overlays/dialog/DialogBody.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogContent.tsx b/packages/website/src/components/overlays/dialog/DialogContent.tsx similarity index 97% rename from packages/website/src/components/overlays/dialog/dialogContent.tsx rename to packages/website/src/components/overlays/dialog/DialogContent.tsx index 341d8113..acec089e 100644 --- a/packages/website/src/components/overlays/dialog/dialogContent.tsx +++ b/packages/website/src/components/overlays/dialog/DialogContent.tsx @@ -1,7 +1,7 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" import * as DialogPrimitive from "@radix-ui/react-dialog" import type { ComponentPropsWithRef } from "react" -import { DialogOverlay } from "./dialogOverlay.js" +import { DialogOverlay } from "./DialogOverlay.js" import { DialogPortal } from "./dialogPortal.js" export function DialogContent(props: ComponentPropsWithRef) { diff --git a/packages/website/src/components/overlays/dialog/dialogDescription.tsx b/packages/website/src/components/overlays/dialog/DialogDescription.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogDescription.tsx rename to packages/website/src/components/overlays/dialog/DialogDescription.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogFooter.tsx b/packages/website/src/components/overlays/dialog/DialogFooter.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogFooter.tsx rename to packages/website/src/components/overlays/dialog/DialogFooter.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogHeader.tsx b/packages/website/src/components/overlays/dialog/DialogHeader.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogHeader.tsx rename to packages/website/src/components/overlays/dialog/DialogHeader.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogOverlay.tsx b/packages/website/src/components/overlays/dialog/DialogOverlay.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogOverlay.tsx rename to packages/website/src/components/overlays/dialog/DialogOverlay.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogRoot.tsx b/packages/website/src/components/overlays/dialog/DialogRoot.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogRoot.tsx rename to packages/website/src/components/overlays/dialog/DialogRoot.tsx diff --git a/packages/website/src/components/overlays/dialog/dialogTitle.tsx b/packages/website/src/components/overlays/dialog/DialogTitle.tsx similarity index 100% rename from packages/website/src/components/overlays/dialog/dialogTitle.tsx rename to packages/website/src/components/overlays/dialog/DialogTitle.tsx diff --git a/packages/website/src/components/overlays/dialog/dialog.tsx b/packages/website/src/components/overlays/dialog/dialog.tsx index 7ee93196..2127e763 100644 --- a/packages/website/src/components/overlays/dialog/dialog.tsx +++ b/packages/website/src/components/overlays/dialog/dialog.tsx @@ -1,12 +1,12 @@ -import { DialogBody } from "./dialogBody.js" -import { DialogContent } from "./dialogContent.js" -import { DialogDescription } from "./dialogDescription.js" -import { DialogFooter } from "./dialogFooter.js" -import { DialogHeader } from "./dialogHeader.js" -import { DialogOverlay } from "./dialogOverlay.js" +import { DialogBody } from "./DialogBody.js" +import { DialogContent } from "./DialogContent.js" +import { DialogDescription } from "./DialogDescription.js" +import { DialogFooter } from "./DialogFooter.js" +import { DialogHeader } from "./DialogHeader.js" +import { DialogOverlay } from "./DialogOverlay.js" import { DialogPortal } from "./dialogPortal.js" -import { DialogRoot } from "./dialogRoot.js" -import { DialogTitle } from "./dialogTitle.js" +import { DialogRoot } from "./DialogRoot.js" +import { DialogTitle } from "./DialogTitle.js" import { DialogTrigger } from "./dialogTrigger.js" export const Dialog = { diff --git a/packages/website/src/components/overlays/popover/popoverContent.tsx b/packages/website/src/components/overlays/popover/PopoverContent.tsx similarity index 100% rename from packages/website/src/components/overlays/popover/popoverContent.tsx rename to packages/website/src/components/overlays/popover/PopoverContent.tsx diff --git a/packages/website/src/components/overlays/popover/popover.tsx b/packages/website/src/components/overlays/popover/popover.tsx index 7135b96e..1d1b8fa8 100644 --- a/packages/website/src/components/overlays/popover/popover.tsx +++ b/packages/website/src/components/overlays/popover/popover.tsx @@ -1,5 +1,5 @@ import { PopoverClose } from "./popoverClose.js" -import { PopoverContent } from "./popoverContent.js" +import { PopoverContent } from "./PopoverContent.js" import { PopoverRoot } from "./popoverRoot.js" import { PopoverTrigger } from "./popoverTrigger.js" diff --git a/packages/website/src/components/overlays/tooltip/tooltipContent.tsx b/packages/website/src/components/overlays/tooltip/TooltipContent.tsx similarity index 100% rename from packages/website/src/components/overlays/tooltip/tooltipContent.tsx rename to packages/website/src/components/overlays/tooltip/TooltipContent.tsx diff --git a/packages/website/src/components/overlays/tooltip/tooltip.tsx b/packages/website/src/components/overlays/tooltip/tooltip.tsx index 42f8b55e..3e5a2af9 100644 --- a/packages/website/src/components/overlays/tooltip/tooltip.tsx +++ b/packages/website/src/components/overlays/tooltip/tooltip.tsx @@ -1,4 +1,4 @@ -import { TooltipContent } from "./tooltipContent.js" +import { TooltipContent } from "./TooltipContent.js" import { TooltipPortal } from "./tooltipPortal.js" import { TooltipProvider } from "./tooltipProvider.js" import { TooltipRoot } from "./tooltipRoot.js" diff --git a/packages/website/src/contexts/rootProvider.tsx b/packages/website/src/contexts/RootProvider.tsx similarity index 79% rename from packages/website/src/contexts/rootProvider.tsx rename to packages/website/src/contexts/RootProvider.tsx index 3b0371b3..dc9109e3 100644 --- a/packages/website/src/contexts/rootProvider.tsx +++ b/packages/website/src/contexts/RootProvider.tsx @@ -1,7 +1,7 @@ import { CircularLoader, ToasterProvider } from "@arrhes/ui" import { Fragment, Suspense } from "react" -import { DataProvider } from "./data/dataProvider.js" -import { RouterProvider } from "./router/routerProvider.js" +import { DataProvider } from "./data/DataProvider.js" +import { RouterProvider } from "./router/RouterProvider.js" export function RootProvider() { return ( diff --git a/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx b/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx new file mode 100644 index 00000000..2deb4ed8 --- /dev/null +++ b/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx @@ -0,0 +1,52 @@ +import type { ReactNode } from "react" +import { useCallback, useState } from "react" +import { setCookie } from "../../utilities/cookies/setCookie.js" +import { cookiePrefix } from "../../utilities/variables.js" +import { DashboardContext } from "./dashboardContext.js" + +const SELECTED_ORG_KEY = "arrhes:context-org" +const SELECTED_YEAR_KEY = "arrhes:context-year" + +function readStorage(key: string): string | null { + try { + return localStorage.getItem(key) + } catch { + return null + } +} + +function writeStorage(key: string, value: string | null): void { + try { + if (value !== null) localStorage.setItem(key, value) + else localStorage.removeItem(key) + } catch { } +} + +export function DashboardContextProvider(props: { children: ReactNode }) { + const [selectedOrgId, setSelectedOrgId] = useState(() => { + const id = readStorage(SELECTED_ORG_KEY) + if (id !== null) setCookie(`${cookiePrefix}_id_organization`, id) + return id + }) + + const [selectedYearId, setSelectedYearId] = useState(() => readStorage(SELECTED_YEAR_KEY)) + + const setOrg = useCallback((id: string | null) => { + setSelectedOrgId(id) + writeStorage(SELECTED_ORG_KEY, id) + if (id !== null) setCookie(`${cookiePrefix}_id_organization`, id) + setSelectedYearId(null) + writeStorage(SELECTED_YEAR_KEY, null) + }, []) + + const setYear = useCallback((id: string | null) => { + setSelectedYearId(id) + writeStorage(SELECTED_YEAR_KEY, id) + }, []) + + return ( + + {props.children} + + ) +} diff --git a/packages/website/src/contexts/dashboard/dashboardContext.tsx b/packages/website/src/contexts/dashboard/dashboardContext.tsx new file mode 100644 index 00000000..fda650c0 --- /dev/null +++ b/packages/website/src/contexts/dashboard/dashboardContext.tsx @@ -0,0 +1,16 @@ +import { createContext, useContext } from "react" + +export type DashboardContextValue = { + selectedOrgId: string | null + selectedYearId: string | null + setOrg: (id: string | null) => void + setYear: (id: string | null) => void +} + +export const DashboardContext = createContext(null) + +export function useDashboardContext(): DashboardContextValue { + const ctx = useContext(DashboardContext) + if (ctx === null) throw new Error("useDashboardContext must be used inside DashboardContextProvider") + return ctx +} diff --git a/packages/website/src/contexts/data/dataProvider.tsx b/packages/website/src/contexts/data/DataProvider.tsx similarity index 100% rename from packages/website/src/contexts/data/dataProvider.tsx rename to packages/website/src/contexts/data/DataProvider.tsx diff --git a/packages/website/src/contexts/router/routerProvider.tsx b/packages/website/src/contexts/router/RouterProvider.tsx similarity index 100% rename from packages/website/src/contexts/router/routerProvider.tsx rename to packages/website/src/contexts/router/RouterProvider.tsx diff --git a/packages/website/src/contexts/tabs/TabContentArea.tsx b/packages/website/src/contexts/tabs/TabContentArea.tsx new file mode 100644 index 00000000..4ddc5f27 --- /dev/null +++ b/packages/website/src/contexts/tabs/TabContentArea.tsx @@ -0,0 +1,56 @@ +import type { Tab } from "./tabsContext.js" + +type TabContentAreaProps = { + activeTabId: string | null + tabs: Tab[] +} + +export function TabContentArea({ activeTabId, tabs }: TabContentAreaProps) { + const visibleStyle: React.CSSProperties = { + flex: 1, + minHeight: 0, + display: "flex", + flexDirection: "column", + } + const hiddenStyle: React.CSSProperties = { + display: "none", + } + + return ( + <> + {tabs.map((tab) => { + const isActiveTab = tab.id === activeTabId + + if (tab.type === "panel") { + return ( +
+ {tab.component} +
+ ) + } + + // Component tab: only render if alive. + if (!tab.isAlive) return null + + return ( +
+ {tab.history.map((entry, idx) => ( +
+ {entry.component} +
+ ))} +
+ ) + })} + + ) +} diff --git a/packages/website/src/contexts/tabs/tabDefinitions.ts b/packages/website/src/contexts/tabs/tabDefinitions.ts index f905331c..07b5345e 100644 --- a/packages/website/src/contexts/tabs/tabDefinitions.ts +++ b/packages/website/src/contexts/tabs/tabDefinitions.ts @@ -1,30 +1,30 @@ import { createElement } from "react" -import { AgentTabContent } from "../../features/dashboard/$idOrganization/agent/agentTabContent.js" -import { OrganizationApiTabContent } from "../../features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.js" -import { OrganizationBillingTabContent } from "../../features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.js" -import { UpdateLicencePage } from "../../features/dashboard/$idOrganization/organizationBilling/updateLicencePage.js" -import { UpdateOcrPage } from "../../features/dashboard/$idOrganization/organizationBilling/updateOcrPage.js" -import { UpdateStoragePage } from "../../features/dashboard/$idOrganization/organizationBilling/updateStoragePage.js" -import { UpdateTokensPage } from "../../features/dashboard/$idOrganization/organizationBilling/updateTokensPage.js" -import { WalletTopUpPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/walletTopUpPage.js" -import { WalletWithdrawalPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.js" -import { OrganizationSettingsTabContent } from "../../features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.js" -import { OrganizationTabContent } from "../../features/dashboard/$idOrganization/organizationTabContent.js" -import { OrganizationUsersPage } from "../../features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.js" -import { YearsPage } from "../../features/dashboard/$idOrganization/years/yearsPage.js" -import { EntryTabContent } from "../../features/dashboard/$idYear/entries/$idEntry/entryTabContent.js" -import { EntriesPage } from "../../features/dashboard/$idYear/entries/entriesPage.js" -import { FileTabContent } from "../../features/dashboard/$idYear/files/$idFile/fileTabContent.js" -import { FilesPage } from "../../features/dashboard/$idYear/files/filesPage.js" -import { ReportsTabContent } from "../../features/dashboard/$idYear/reports/reportsTabContent.js" -import { YearSettingsTabContent } from "../../features/dashboard/$idYear/yearSettings/yearSettingsTabContent.js" -import { AdminTicketTabContent } from "../../features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.js" -import { TicketsPage } from "../../features/dashboard/admin/tickets/ticketsPage.js" -import { OrganizationsPage } from "../../features/dashboard/organizations/organizationsPage.js" -import { UserProfilePage } from "../../features/dashboard/profile/userProfilePage.js" -import { SettingsPage } from "../../features/dashboard/settings/settingsPage.js" -import { TicketTabContent } from "../../features/dashboard/support/$idTicket/ticketTabContent.js" -import { SupportPage } from "../../features/dashboard/support/supportPage.js" +import { AgentTabContent } from "../../features/dashboard/$idOrganization/agent/AgentTabContent.js" +import { OrganizationApiTabContent } from "../../features/dashboard/$idOrganization/organizationApi/OrganizationApiTabContent.js" +import { OrganizationBillingTabContent } from "../../features/dashboard/$idOrganization/organizationBilling/OrganizationBillingTabContent.js" +import { UpdateLicencePage } from "../../features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.js" +import { UpdateOcrPage } from "../../features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.js" +import { UpdateStoragePage } from "../../features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.js" +import { UpdateTokensPage } from "../../features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.js" +import { WalletTopUpPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpPage.js" +import { WalletWithdrawalPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalPage.js" +import { OrganizationSettingsTabContent } from "../../features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsTabContent.js" +import { OrganizationTabContent } from "../../features/dashboard/$idOrganization/OrganizationTabContent.js" +import { OrganizationUsersPage } from "../../features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.js" +import { YearsPage } from "../../features/dashboard/$idOrganization/years/YearsPage.js" +import { EntryTabContent } from "../../features/dashboard/$idYear/entries/$idEntry/EntryTabContent.js" +import { EntriesPage } from "../../features/dashboard/$idYear/entries/EntriesPage.js" +import { FileTabContent } from "../../features/dashboard/$idYear/files/$idFile/FileTabContent.js" +import { FilesPage } from "../../features/dashboard/$idYear/files/FilesPage.js" +import { ReportsTabContent } from "../../features/dashboard/$idYear/reports/ReportsTabContent.js" +import { YearSettingsTabContent } from "../../features/dashboard/$idYear/yearSettings/YearSettingsTabContent.js" +import { AdminTicketTabContent } from "../../features/dashboard/admin/tickets/$idTicket/AdminTicketTabContent.js" +import { TicketsPage } from "../../features/dashboard/admin/tickets/TicketsPage.js" +import { OrganizationsPage } from "../../features/dashboard/organizations/OrganizationsPage.js" +import { UserProfilePage } from "../../features/dashboard/profile/UserProfilePage.js" +import { SettingsPage } from "../../features/dashboard/settings/SettingsPage.js" +import { TicketTabContent } from "../../features/dashboard/support/$idTicket/TicketTabContent.js" +import { SupportPage } from "../../features/dashboard/support/SupportPage.js" // ─── Types ─────────────────────────────────────────────────────────────────── @@ -243,9 +243,10 @@ export const TAB_REGISTRY = { // ─── Detail tabs ─────────────────────────────────────────────────────── - écriture: (props: { idOrganization: string; idYear: string; idEntry: string }): TabDefinition => ({ + écriture: (props: { idOrganization: string; idYear: string; idEntry: string; label?: string }): TabDefinition => ({ id: `écriture-${props.idOrganization}-${props.idYear}-${props.idEntry}`, title: "Écriture", + description: props.label, component: createElement(EntryTabContent, { idOrganization: props.idOrganization, idYear: props.idYear, diff --git a/packages/website/src/contexts/tabs/tabsContext.tsx b/packages/website/src/contexts/tabs/tabsContext.tsx index 22785b4c..df46c95e 100644 --- a/packages/website/src/contexts/tabs/tabsContext.tsx +++ b/packages/website/src/contexts/tabs/tabsContext.tsx @@ -1,4 +1,4 @@ -import { createContext, useContext } from "react" +import { createContext } from "react" import type { OpenTabArgs } from "./tabDefinitions.js" // ─── History ───────────────────────────────────────────────────────────────── @@ -79,11 +79,3 @@ export type TabsContextValue = { } export const TabsContext = createContext(null) - -export function useTabs(): TabsContextValue { - const ctx = useContext(TabsContext) - if (ctx === null) { - throw new Error("useTabs must be used within a TabsProvider") - } - return ctx -} diff --git a/packages/website/src/contexts/tabs/tabsProvider.tsx b/packages/website/src/contexts/tabs/tabsProvider.tsx index 307ebcd5..04025b4d 100644 --- a/packages/website/src/contexts/tabs/tabsProvider.tsx +++ b/packages/website/src/contexts/tabs/tabsProvider.tsx @@ -118,6 +118,10 @@ export function TabsProvider({ children }: Props) { return null }) + // Ordered list of recently focused tab IDs (most recent last). + // Used to determine which tab to activate after closing the active one. + const focusHistoryRef = useRef([]) + // Track whether Ctrl / Meta is currently held so openTab can decide // whether to replace-in-place or create a new tab — without requiring // every call site to pass a flag. @@ -200,7 +204,7 @@ export function TabsProvider({ children }: Props) { const entryId = tab ? currentEntry(tab).id : "0" window.history.replaceState({ tabId: activeTabId, entryId }, "", `/dashboard/${activeTabId}/${entryId}`) } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) // React to browser back/forward (mouse buttons, keyboard, browser UI). @@ -292,10 +296,10 @@ export function TabsProvider({ children }: Props) { prev.map((t) => t.id === activeTab.id ? { - ...t, - history: newHistory, - historyIndex: newIndex, - } + ...t, + history: newHistory, + historyIndex: newIndex, + } : t, ), activeTab.id, @@ -381,13 +385,20 @@ export function TabsProvider({ children }: Props) { if (idx === -1) return const next = current.filter((t) => t.id !== id) const currentActiveId = activeTabIdRef.current + + // Remove closed tab from focus history. + focusHistoryRef.current = focusHistoryRef.current.filter((fid) => fid !== id) + let newActiveId: string | null if (next.length === 0) { newActiveId = null } else if (currentActiveId !== id) { newActiveId = currentActiveId } else { - newActiveId = next[Math.min(idx, next.length - 1)].id + // Find the most recently focused tab that still exists. + const existingIds = new Set(next.map((t) => t.id)) + const lastFocused = [...focusHistoryRef.current].reverse().find((fid) => existingIds.has(fid)) + newActiveId = lastFocused ?? next[Math.min(idx, next.length - 1)].id } setTabs((prev) => { @@ -400,7 +411,9 @@ export function TabsProvider({ children }: Props) { } setActiveTabId((currentActive) => { if (currentActive !== id) return currentActive - return n[Math.min(i, n.length - 1)].id + const existingIds = new Set(n.map((t) => t.id)) + const lastFocused = [...focusHistoryRef.current].reverse().find((fid) => existingIds.has(fid)) + return lastFocused ?? n[Math.min(i, n.length - 1)].id }) return n }) @@ -419,6 +432,9 @@ export function TabsProvider({ children }: Props) { }, []) const activateTab = useCallback((id: string) => { + // Record in focus history (append, deduplicate from earlier positions). + focusHistoryRef.current = [...focusHistoryRef.current.filter((fid) => fid !== id), id] + setTabs((prev) => { const revived = prev.map((t) => { if (t.type === "component" && t.id === id && !t.isAlive) { @@ -441,13 +457,55 @@ export function TabsProvider({ children }: Props) { window.history.replaceState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) }, []) - // Delegate to browser history — the popstate handler above updates React state. - const navigateBack = useCallback((_tabId: string) => { - window.history.back() + // Navigate within the tab's own history stack (does not add browser history entries). + const navigateBack = useCallback((tabId: string) => { + const tab = tabsRef.current.find((t): t is ComponentTab => t.type === "component" && t.id === tabId) + if (!tab || tab.historyIndex <= 0) return + const newIndex = tab.historyIndex - 1 + const targetEntry = tab.history[newIndex] + setTabs((prev) => { + const t = prev.find((pt): pt is ComponentTab => pt.type === "component" && pt.id === tabId) + if (!t || t.historyIndex <= 0) return prev + const idx = t.historyIndex - 1 + const history = t.history.map((e, i) => { + if (i !== idx || e.component !== null) return e + return buildEntry(e.definitionKey, e.definitionProps, e.id) + }) + return applyLruEviction( + prev.map((pt) => (pt.id === tabId ? { ...t, history, historyIndex: idx } : pt)), + tabId, + ) + }) + window.history.replaceState( + { tabId, entryId: targetEntry.id }, + "", + `/dashboard/${tabId}/${targetEntry.id}`, + ) }, []) - const navigateForward = useCallback((_tabId: string) => { - window.history.forward() + const navigateForward = useCallback((tabId: string) => { + const tab = tabsRef.current.find((t): t is ComponentTab => t.type === "component" && t.id === tabId) + if (!tab || tab.historyIndex >= tab.history.length - 1) return + const newIndex = tab.historyIndex + 1 + const targetEntry = tab.history[newIndex] + setTabs((prev) => { + const t = prev.find((pt): pt is ComponentTab => pt.type === "component" && pt.id === tabId) + if (!t || t.historyIndex >= t.history.length - 1) return prev + const idx = t.historyIndex + 1 + const history = t.history.map((e, i) => { + if (i !== idx || e.component !== null) return e + return buildEntry(e.definitionKey, e.definitionProps, e.id) + }) + return applyLruEviction( + prev.map((pt) => (pt.id === tabId ? { ...t, history, historyIndex: idx } : pt)), + tabId, + ) + }) + window.history.replaceState( + { tabId, entryId: targetEntry.id }, + "", + `/dashboard/${tabId}/${targetEntry.id}`, + ) }, []) const openPanelTab = useCallback((title: string, component: React.ReactNode, icon?: string): string => { @@ -475,9 +533,9 @@ export function TabsProvider({ children }: Props) { const history = t.history.map((e, i) => i === t.historyIndex ? { - ...e, - title, - } + ...e, + title, + } : e, ) return { @@ -534,62 +592,3 @@ export function TabsProvider({ children }: Props) { ) } -// ─── Pre-render each alive route tab so React keep-alive works ──────────────── -// For each alive ComponentTab we render ALL history entries in the DOM, -// hiding non-current ones with display:none — this preserves React state -// (scroll position, form values etc.) across back/forward navigation. - -type TabContentAreaProps = { - activeTabId: string | null - tabs: Tab[] -} - -export function TabContentArea({ activeTabId, tabs }: TabContentAreaProps) { - const visibleStyle: React.CSSProperties = { - flex: 1, - minHeight: 0, - display: "flex", - flexDirection: "column", - } - const hiddenStyle: React.CSSProperties = { - display: "none", - } - - return ( - <> - {tabs.map((tab) => { - const isActiveTab = tab.id === activeTabId - - if (tab.type === "panel") { - return ( -
- {tab.component} -
- ) - } - - // Component tab: only render if alive. - if (!tab.isAlive) return null - - return ( -
- {tab.history.map((entry, idx) => ( -
- {entry.component} -
- ))} -
- ) - })} - - ) -} diff --git a/packages/website/src/contexts/tabs/useTabs.tsx b/packages/website/src/contexts/tabs/useTabs.tsx new file mode 100644 index 00000000..91823fd9 --- /dev/null +++ b/packages/website/src/contexts/tabs/useTabs.tsx @@ -0,0 +1,10 @@ +import { useContext } from "react" +import { TabsContext, type TabsContextValue } from "./tabsContext.js" + +export function useTabs(): TabsContextValue { + const ctx = useContext(TabsContext) + if (ctx === null) { + throw new Error("useTabs must be used within a TabsProvider") + } + return ctx +} diff --git a/packages/website/src/features/breadcrumbs.tsx b/packages/website/src/features/Breadcrumbs.tsx similarity index 98% rename from packages/website/src/features/breadcrumbs.tsx rename to packages/website/src/features/Breadcrumbs.tsx index 63106f66..11bb9d68 100644 --- a/packages/website/src/features/breadcrumbs.tsx +++ b/packages/website/src/features/Breadcrumbs.tsx @@ -3,7 +3,7 @@ import { ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useRouterState } from "@tanstack/react-router" import { Fragment } from "react/jsx-runtime" -import { LinkButton } from "../components/linkButton.js" +import { LinkButton } from "../components/LinkButton.js" import { useDataFromAPI } from "../utilities/useHTTPData.js" export function Breadcrumbs() { diff --git a/packages/website/src/features/rootLayout.tsx b/packages/website/src/features/RootLayout.tsx similarity index 100% rename from packages/website/src/features/rootLayout.tsx rename to packages/website/src/features/RootLayout.tsx diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx rename to packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx index f1d63477..f1147597 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx @@ -9,7 +9,7 @@ import { } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" import { Fragment } from "react/jsx-runtime" -import { PageNavigation } from "../../../components/layouts/page/pageNavigation.tsx" +import { PageNavigation } from "../../../components/layouts/page/PageNavigation.tsx" import { organizationLayoutRoute } from "../../../routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx" export function OrganizationLayout() { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx rename to packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx index 608f7bd9..04884ca1 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationTabContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx @@ -10,7 +10,7 @@ import { IconUsers, } from "@tabler/icons-react" import type { ReactNode } from "react" -import { TabLink } from "../../../components/layouts/tabBar/tabLink.js" +import { TabLink } from "../../../components/layouts/tabBar/TabLink.js" import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" type NavItem = { diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentLayout.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx index ceb1b958..13736060 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx @@ -7,10 +7,10 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconMenu, IconMessage, IconPlus } from "@tabler/icons-react" import { Outlet, useNavigate, useParams } from "@tanstack/react-router" import { useState } from "react" -import { Banner } from "../../../../components/layouts/banner.tsx" -import { EmptyState } from "../../../../components/layouts/emptyState.tsx" +import { Banner } from "../../../../components/layouts/Banner.tsx" +import { EmptyState } from "../../../../components/layouts/EmptyState.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { SearchBar } from "../../../../components/layouts/searchBar.tsx" +import { SearchBar } from "../../../../components/layouts/SearchBar.tsx" import { organizationPathRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.tsx" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" import { extractSnippet } from "./extractSnippet.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentMessage.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentMessage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentMessage.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentMessage.tsx index 457c5036..344caf24 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentMessage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentMessage.tsx @@ -3,7 +3,7 @@ import { formatDateTime } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCalculator, IconFile, IconFileText, IconNotebook, IconPaperclip, IconTag } from "@tabler/icons-react" import type { InferOutput } from "valibot" -import { AgentMessagePart } from "./agentMessagePart.tsx" +import { AgentMessagePart } from "./AgentMessagePart.tsx" import { getAgentMessageParts } from "./getAgentMessageParts.ts" const referenceTypeIcons: Record = { diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentMessagePart.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentMessagePart.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentMessagePart.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentMessagePart.tsx diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentPage.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentPage.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentPage.tsx diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx index cad2f4fd..0c116ac2 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx @@ -31,8 +31,8 @@ import { } from "@tabler/icons-react" import { useNavigate, useParams } from "@tanstack/react-router" import { useCallback, useEffect, useRef, useState } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { Popover } from "../../../../components/overlays/popover/popover.tsx" import { dataClient } from "../../../../contexts/data/queryClient.ts" import { getCookie } from "../../../../utilities/cookies/getCookie.js" @@ -41,9 +41,9 @@ import { invalidateData } from "../../../../utilities/invalidateData.ts" import { resolveApiBaseUrl } from "../../../../utilities/resolveApiBaseUrl.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" import { cookiePrefix } from "../../../../utilities/variables.js" -import { AgentMessage } from "./agentMessage.tsx" +import { AgentMessage } from "./AgentMessage.tsx" import { isHealthyStreamResponse } from "./isStreamResponseUnavailable.ts" -import { MentionInput, type MentionReference } from "./mentionInput.tsx" +import { MentionInput, type MentionReference } from "./MentionInput.tsx" const subagentLabels: Record = { data_analyst: "Analyste de données", diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionPage.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionPage.tsx similarity index 84% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentSessionPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionPage.tsx index 470c47dc..f94342fa 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentSessionPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionPage.tsx @@ -1,5 +1,5 @@ import { css } from "@arrhes/ui/css" -import { AgentSessionContent } from "./agentSessionContent.tsx" +import { AgentSessionContent } from "./AgentSessionContent.tsx" export function AgentSessionPage() { return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentTabContent.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/AgentTabContent.tsx index 1e3f81f5..96f45e9a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/agentTabContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentTabContent.tsx @@ -6,20 +6,20 @@ import { Button, ButtonGhostContent, ButtonOutlineContent, formatDateTime } from import { css } from "@arrhes/ui/utilities/cn.js" import { IconMenu, IconMessage, IconPlus } from "@tabler/icons-react" import { lazy, Suspense, useState } from "react" -import { Banner } from "../../../../components/layouts/banner.tsx" -import { EmptyState } from "../../../../components/layouts/emptyState.tsx" +import { Banner } from "../../../../components/layouts/Banner.tsx" +import { EmptyState } from "../../../../components/layouts/EmptyState.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { SearchBar } from "../../../../components/layouts/searchBar.tsx" +import { SearchBar } from "../../../../components/layouts/SearchBar.tsx" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" import { extractSnippet } from "./extractSnippet.ts" const AgentPage = lazy(() => - import("./agentPage.js").then((m) => ({ + import("./AgentPage.js").then((m) => ({ default: m.AgentPage, })), ) const AgentSessionContent = lazy(() => - import("./agentSessionContent.js").then((m) => ({ + import("./AgentSessionContent.js").then((m) => ({ default: m.AgentSessionContent, })), ) diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/mentionInput.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/MentionInput.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idOrganization/agent/mentionInput.tsx rename to packages/website/src/features/dashboard/$idOrganization/agent/MentionInput.tsx diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiGeneralPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiGeneralPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx index a9b6a5b9..3ce5f766 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiGeneralPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx @@ -2,7 +2,7 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { IconBook2 } from "@tabler/icons-react" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { LinkButton } from "../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../components/LinkButton.tsx" export function OrganizationApiGeneralPage() { return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiLayout.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx index f47d516c..b2790f97 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx @@ -1,6 +1,6 @@ import { IconHome, IconKey } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/subPageLayout.tsx" +import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" import { organizationApiLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx" export function OrganizationApiLayout() { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiTabContent.tsx similarity index 88% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiTabContent.tsx index 3b252dc3..68de1e75 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/organizationApiTabContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiTabContent.tsx @@ -1,14 +1,14 @@ import { IconHome, IconKey } from "@tabler/icons-react" import { lazy, Suspense } from "react" -import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" +import { SubPageContent } from "../../../../components/layouts/SubPageContent.tsx" const OrganizationApiGeneralPage = lazy(() => - import("./organizationApiGeneralPage.js").then((m) => ({ + import("./OrganizationApiGeneralPage.js").then((m) => ({ default: m.OrganizationApiGeneralPage, })), ) const OrganizationApiKeysPage = lazy(() => - import("./keys/organizationApiKeysPage.js").then((m) => ({ + import("./keys/OrganizationApiKeysPage.js").then((m) => ({ default: m.OrganizationApiKeysPage, })), ) diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/apiKeyListTableRow.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/ApiKeyListTableRow.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/apiKeyListTableRow.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/ApiKeyListTableRow.tsx index 00915fe9..6db0c494 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/apiKeyListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/ApiKeyListTableRow.tsx @@ -4,7 +4,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconTrash } from "@tabler/icons-react" import type * as v from "valibot" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { DeleteOneApiKey } from "./deleteOneApiKey.tsx" +import { DeleteOneApiKey } from "./DeleteOneApiKey.tsx" export function ApiKeyListTableRow(props: { apiKey: v.InferOutput[number] diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/apiKeysListTable.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/ApiKeysListTable.tsx similarity index 87% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/apiKeysListTable.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/ApiKeysListTable.tsx index 7d65774b..e7641890 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/apiKeysListTable.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/ApiKeysListTable.tsx @@ -2,10 +2,10 @@ import { readAllApiKeysRouteDefinition } from "@arrhes/application-metadata/rout import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { IconKey } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { ApiKeyListTableRow } from "./apiKeyListTableRow.tsx" +import { ApiKeyListTableRow } from "./ApiKeyListTableRow.tsx" export function ApiKeysListTable(_props: { idOrganization: v.InferOutput["id"] }) { return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/CreateOneApiKey.tsx similarity index 90% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/CreateOneApiKey.tsx index 6b1b8bb8..cb5e3845 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/createOneApiKey.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/CreateOneApiKey.tsx @@ -6,16 +6,16 @@ import { IconPlus } from "@tabler/icons-react" import { type JSX, useState } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" -import { RawKeyDisplay } from "./rawKeyDisplay.tsx" +import { RawKeyDisplay } from "./RawKeyDisplay.tsx" function CreateOneApiKeyPanel(props: { onClose: () => void }) { const [rawKey, setRawKey] = useState(null) diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/deleteOneApiKey.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/deleteOneApiKey.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx index e0426f7b..099abeca 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/deleteOneApiKey.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx @@ -3,7 +3,7 @@ import { deleteOneApiKeyRouteDefinition, readAllApiKeysRouteDefinition } from "@ import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/OrganizationApiKeysPage.tsx similarity index 92% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/OrganizationApiKeysPage.tsx index aea2865a..ac308c0f 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/OrganizationApiKeysPage.tsx @@ -3,8 +3,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { Page } from "../../../../../components/layouts/page/page.tsx" -import { ApiKeysListTable } from "./apiKeysListTable.tsx" -import { CreateOneApiKey } from "./createOneApiKey.tsx" +import { ApiKeysListTable } from "./ApiKeysListTable.tsx" +import { CreateOneApiKey } from "./CreateOneApiKey.tsx" export function OrganizationApiKeysPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/rawKeyDisplay.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/RawKeyDisplay.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/rawKeyDisplay.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/RawKeyDisplay.tsx diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/cancelSubscription.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/cancelSubscription.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx index bee5f575..5dd62ad7 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/cancelSubscription.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx @@ -4,7 +4,7 @@ import { } from "@arrhes/application-metadata/routes" import { ButtonOutlineContent, toast } from "@arrhes/ui" import { IconPlayerPause } from "@tabler/icons-react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingHistoryPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingHistoryPage.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingHistoryPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingHistoryPage.tsx index 40733c56..c5434ee2 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingHistoryPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingHistoryPage.tsx @@ -2,9 +2,9 @@ import { readAllOrganizationPaymentsRouteDefinition } from "@arrhes/application- import { Chip, type ChipColors, FormatPrice, formatDate } from "@arrhes/ui" import { IconReceipt } from "@tabler/icons-react" import type { ColumnDef } from "@tanstack/react-table" -import { DataTable } from "../../../../components/layouts/dataTable.tsx" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../components/layouts/emptyState.tsx" +import { DataTable } from "../../../../components/layouts/DataTable.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../components/layouts/EmptyState.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingLayout.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx index fe1f8646..e1d66910 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx @@ -1,6 +1,6 @@ import { IconFileInvoice, IconPuzzle, IconReceipt, IconWallet } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/subPageLayout.tsx" +import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" import { organizationBillingLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx" export function OrganizationBillingLayout() { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingTabContent.tsx similarity index 89% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingTabContent.tsx index e917458a..f62cb03d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationBillingTabContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingTabContent.tsx @@ -1,24 +1,24 @@ import { IconFileInvoice, IconPuzzle, IconReceipt, IconWallet } from "@tabler/icons-react" import { lazy, Suspense } from "react" -import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" +import { SubPageContent } from "../../../../components/layouts/SubPageContent.tsx" const OrganizationWalletPage = lazy(() => - import("./wallet/organizationWalletPage.js").then((m) => ({ + import("./wallet/OrganizationWalletPage.js").then((m) => ({ default: m.OrganizationWalletPage, })), ) const OrganizationServicesPage = lazy(() => - import("./organizationServicesPage.js").then((m) => ({ + import("./OrganizationServicesPage.js").then((m) => ({ default: m.OrganizationServicesPage, })), ) const OrganizationBillingHistoryPage = lazy(() => - import("./organizationBillingHistoryPage.js").then((m) => ({ + import("./OrganizationBillingHistoryPage.js").then((m) => ({ default: m.OrganizationBillingHistoryPage, })), ) const OrganizationInvoicesPage = lazy(() => - import("./invoices/organizationInvoicesPage.js").then((m) => ({ + import("./invoices/OrganizationInvoicesPage.js").then((m) => ({ default: m.OrganizationInvoicesPage, })), ) diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx index ecebd828..3f178cb1 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx @@ -11,9 +11,9 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconAlertTriangle, IconPencil } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import type { JSX } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { OrganizationBillingDisclaimerBanner } from "./wallet/OrganizationBillingDisclaimerBanner.tsx" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/resumeSubscription.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/resumeSubscription.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx index 6a8435e9..dbbf20f7 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/resumeSubscription.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx @@ -4,7 +4,7 @@ import { } from "@arrhes/application-metadata/routes" import { ButtonOutlineContent, toast } from "@arrhes/ui" import { IconPlayerPlay } from "@tabler/icons-react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx index 58958171..936893b5 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateLicencePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx @@ -4,13 +4,13 @@ import { } from "@arrhes/application-metadata/routes" import { getAmountTTCFromHTInCents, SUPPORT_TIERS, VAT_PERCENT } from "@arrhes/application-metadata/utilities" import { Button, ButtonOutlineContent, toast } from "@arrhes/ui" -import { InputCurrency } from "@arrhes/ui/components/inputs/inputCurrency.js" +import { InputCurrency } from "@arrhes/ui/components/inputs/InputCurrency.js" import { css } from "@arrhes/ui/utilities/cn.js" import { IconDeviceFloppy } from "@tabler/icons-react" import { useState } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx index e363e475..c9029a85 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateOcrPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx @@ -13,9 +13,9 @@ import { Button, ButtonOutlineContent, ButtonPlainContent, InputNumber, toast } import { css } from "@arrhes/ui/utilities/cn.js" import { IconCreditCard, IconX } from "@tabler/icons-react" import { type ReactNode, useEffect, useState } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx index 1f031c41..8e5861d7 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateStoragePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx @@ -12,9 +12,9 @@ import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconMinus, IconPlus } from "@tabler/icons-react" import { type ReactNode, useEffect, useState } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx index 11d672cd..d8edff9d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/updateTokensPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx @@ -14,9 +14,9 @@ import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { type ReactNode, useEffect, useState } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoiceActionsPopover.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoiceActionsPopover.tsx index 1b8d7edf..b5564579 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoiceActionsPopover.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoiceActionsPopover.tsx @@ -3,7 +3,7 @@ import { Button, ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconDotsVertical, IconDownload, IconEye } from "@tabler/icons-react" import type * as v from "valibot" -import { LinkButton } from "../../../../../components/linkButton.js" +import { LinkButton } from "../../../../../components/LinkButton.js" import { Popover } from "../../../../../components/overlays/popover/popover.js" import { DownloadInvoiceAsPDFButton } from "./DownloadInvoiceAsPDFButton.tsx" import { DownloadInvoiceAsXMLButton } from "./DownloadInvoiceAsXMLButton.tsx" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicePaymentsTable.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicePaymentsTable.tsx index beb7b9d2..c822330b 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicePaymentsTable.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicePaymentsTable.tsx @@ -2,7 +2,7 @@ import { readAllOrganizationPaymentsRouteDefinition } from "@arrhes/application- import { getTaxAmountFromHTInCents, OCR_PAGE_PRICE_IN_CENTS } from "@arrhes/application-metadata/utilities" import { FormatDateTime, FormatPrice } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" function getPaymentServiceLabel(serviceType: string | null) { if (serviceType === "support") return "Licence" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx index e8e041c2..c6d55a3c 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/InvoicesTable.tsx @@ -3,7 +3,7 @@ import { getAmountTTCFromHTInCents, getTaxAmountFromHTInCents } from "@arrhes/ap import { Chip, type ChipColors } from "@arrhes/ui" import type { ColumnDef } from "@tanstack/react-table" import type * as v from "valibot" -import { DataTable } from "../../../../../components/layouts/dataTable.tsx" +import { DataTable } from "../../../../../components/layouts/DataTable.tsx" import { InvoiceActionsPopover } from "./InvoiceActionsPopover.tsx" const invoiceStatusLabel: Record = { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicePage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx index d505726e..0d9161ba 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx @@ -4,8 +4,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { useState } from "react" import type * as v from "valibot" -import { Banner } from "../../../../../components/layouts/banner.tsx" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" +import { Banner } from "../../../../../components/layouts/Banner.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../../components/layouts/settingsSection/settingsSection.tsx" import { organizationInvoiceUblRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.js" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicesPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicesPage.tsx index 6f1cec0f..6965996a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicesPage.tsx @@ -1,8 +1,8 @@ import { readAllInvoicesRouteDefinition } from "@arrhes/application-metadata/routes" import { IconFileInvoice } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../../components/layouts/settingsSection/settingsSection.tsx" import { InvoicesTable } from "./InvoicesTable.tsx" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationBillingDisclaimerBanner.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationBillingDisclaimerBanner.tsx index 7fa07050..c2dd1a6d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationBillingDisclaimerBanner.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationBillingDisclaimerBanner.tsx @@ -7,8 +7,8 @@ import { Button, ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconAlertTriangle, IconPencil } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { UpdateOneOrganization } from "../../organizationSettings/updateOneOrganization.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { UpdateOneOrganization } from "../../organizationSettings/UpdateOneOrganization.tsx" export type SubscriptionFeatureType = "storage_gb" | "agent_tokens_million" | "ocr_pages_hundred" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationWalletPage.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationWalletPage.tsx index f0b7dfa4..7022d7a8 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationWalletPage.tsx @@ -4,13 +4,13 @@ import { Button, ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconAlertTriangle, IconCashMinus, IconPigMoney, IconPlus, IconWallet } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../../components/layouts/settingsSection/settingsSection.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../../../contexts/tabs/useTabs.js" import { formatEuros } from "../../../../../utilities/formatEuros.tsx" import { OrganizationBillingDisclaimerBanner } from "./OrganizationBillingDisclaimerBanner.tsx" -import { WalletCurrentMonth } from "./walletCurrentMonth.tsx" +import { WalletCurrentMonth } from "./WalletCurrentMonth.tsx" function getRecurringStorageAmountInCents(storageLimit: number) { return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletCurrentMonth.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletCurrentMonth.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletCurrentMonth.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletCurrentMonth.tsx index ead0f903..279bf8e3 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletCurrentMonth.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletCurrentMonth.tsx @@ -5,7 +5,7 @@ import { } from "@arrhes/application-metadata/routes" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" import { formatEuros } from "../../../../../utilities/formatEuros.tsx" function getPaymentLineType(payment: { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletTopUpPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpPage.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletTopUpPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpPage.tsx diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalPage.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalPage.tsx index 1e5e3147..d142d259 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/walletWithdrawalPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalPage.tsx @@ -7,7 +7,7 @@ import { Button, ButtonOutlineContent, InputText, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconMinus } from "@tabler/icons-react" import { useEffect, useState } from "react" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { parseEuroAmountToCents } from "../../../../../utilities/parseEuroAmountToCents.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/deleteOneOrganization.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationSettings/deleteOneOrganization.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx index 7b9611c3..a1a4c49c 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/deleteOneOrganization.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx @@ -6,7 +6,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSecurityPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSecurityPage.tsx index 0f282c8d..14e99ed4 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSecurityPage.tsx @@ -2,10 +2,10 @@ import { readOneOrganizationRouteDefinition } from "@arrhes/application-metadata import { ButtonOutlineContent } from "@arrhes/ui" import { IconTrash } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { DeleteOneOrganization } from "./deleteOneOrganization.tsx" +import { DeleteOneOrganization } from "./DeleteOneOrganization.tsx" export function OrganizationSecurityPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsLayout.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx index 4708b614..31ad324a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx @@ -1,6 +1,6 @@ import { IconHome, IconLock } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/subPageLayout.tsx" +import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" import { organizationSettingsLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx" export function OrganizationSettingsLayout() { diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsPage.tsx index 94327cf9..6bb53812 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsPage.tsx @@ -2,10 +2,10 @@ import { readOneOrganizationRouteDefinition } from "@arrhes/application-metadata import { ButtonOutlineContent } from "@arrhes/ui" import { IconPencil } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { UpdateOneOrganization } from "./updateOneOrganization.tsx" +import { UpdateOneOrganization } from "./UpdateOneOrganization.tsx" export function OrganizationSettingsPage({ idOrganization: idOrganizationProp }: { idOrganization?: string } = {}) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsTabContent.tsx similarity index 89% rename from packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsTabContent.tsx index 38fabc30..d39a3dc3 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/organizationSettingsTabContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsTabContent.tsx @@ -1,14 +1,14 @@ import { IconHome, IconLock } from "@tabler/icons-react" import { lazy, Suspense } from "react" -import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" +import { SubPageContent } from "../../../../components/layouts/SubPageContent.tsx" const OrganizationSettingsPage = lazy(() => - import("./organizationSettingsPage.js").then((m) => ({ + import("./OrganizationSettingsPage.js").then((m) => ({ default: m.OrganizationSettingsPage, })), ) const OrganizationSecurityPage = lazy(() => - import("./organizationSecurityPage.js").then((m) => ({ + import("./OrganizationSecurityPage.js").then((m) => ({ default: m.OrganizationSecurityPage, })), ) diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/UpdateOneOrganization.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationSettings/UpdateOneOrganization.tsx index 5e0af0ac..3541fc92 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/updateOneOrganization.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/UpdateOneOrganization.tsx @@ -9,13 +9,13 @@ import { IconPencil } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../components/forms/formError.tsx" -import { FormField } from "../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/deleteOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/deleteOneOrganizationUser.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx index 4127322f..ed13e08a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/deleteOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx @@ -6,7 +6,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/UpdateOneOrganizationUser.tsx similarity index 92% rename from packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/UpdateOneOrganizationUser.tsx index 97b328fd..90aac602 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/updateOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/UpdateOneOrganizationUser.tsx @@ -9,13 +9,13 @@ import { IconPencil } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/CreateOneOrganizationUser.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationUsers/CreateOneOrganizationUser.tsx index c3857000..65d7174b 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/createOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/CreateOneOrganizationUser.tsx @@ -9,13 +9,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../components/forms/formError.tsx" -import { FormField } from "../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUserListTableRow.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUserListTableRow.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUserListTableRow.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUserListTableRow.tsx index 4f3d382f..4c0236b0 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUserListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUserListTableRow.tsx @@ -4,8 +4,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconUserEdit, IconUserX } from "@tabler/icons-react" import type * as v from "valibot" import { ListTable } from "../../../../components/layouts/listTable/listTable.tsx" -import { DeleteOneOrganizationUser } from "./$idOrganizationUser/deleteOneOrganizationUser.tsx" -import { UpdateOneOrganizationUser } from "./$idOrganizationUser/updateOneOrganizationUser.tsx" +import { DeleteOneOrganizationUser } from "./$idOrganizationUser/DeleteOneOrganizationUser.tsx" +import { UpdateOneOrganizationUser } from "./$idOrganizationUser/UpdateOneOrganizationUser.tsx" export function OrganizationUserListTableRow(props: { organizationUser: v.InferOutput[number] diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersListTable.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUsersListTable.tsx similarity index 88% rename from packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersListTable.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUsersListTable.tsx index f7247ca4..753daeeb 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersListTable.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUsersListTable.tsx @@ -2,10 +2,10 @@ import { readAllOrganizationUsersRouteDefinition } from "@arrhes/application-met import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { IconUsers } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../../components/layouts/listTable/listTable.tsx" -import { OrganizationUserListTableRow } from "./organizationUserListTableRow.tsx" +import { OrganizationUserListTableRow } from "./OrganizationUserListTableRow.tsx" export function OrganizationUsersListTable(_props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.tsx similarity index 92% rename from packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx rename to packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.tsx index 0b1360aa..0b88b667 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.tsx @@ -3,8 +3,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconUserPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { Page } from "../../../../components/layouts/page/page.tsx" -import { CreateOneOrganizationUser } from "./createOneOrganizationUser.tsx" -import { OrganizationUsersListTable } from "./organizationUsersListTable.tsx" +import { CreateOneOrganizationUser } from "./CreateOneOrganizationUser.tsx" +import { OrganizationUsersListTable } from "./OrganizationUsersListTable.tsx" export function OrganizationUsersPage({ idOrganization: idOrganizationProp }: { idOrganization?: string }) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx b/packages/website/src/features/dashboard/$idOrganization/years/CreateOneYear.tsx similarity index 90% rename from packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx rename to packages/website/src/features/dashboard/$idOrganization/years/CreateOneYear.tsx index 3c0ae34d..fb660003 100644 --- a/packages/website/src/features/dashboard/$idOrganization/years/createOneYear.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/years/CreateOneYear.tsx @@ -1,38 +1,42 @@ import { createOneYearRouteDefinition, readAllYearsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { Button, InputDate, InputText, toast } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" +import { css, cx } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../components/forms/formError.tsx" -import { FormField } from "../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" -import { YearSelect } from "./yearSelect.tsx" +import { YearSelect } from "./YearSelect.tsx" export function CreateOneYear(props: { idOrganization: v.InferOutput["id"] children: JSX.Element + className?: string }) { const { openPanelTab, closeTab } = useTabs() const currentDate = new Date() return ( + )} + + + + + + + + + + + + + + + + ) +} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx new file mode 100644 index 00000000..9ced18f3 --- /dev/null +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx @@ -0,0 +1,60 @@ +import { useParams } from "@tanstack/react-router" +import type { YearDataKey } from "../../YearDataWrapper.js" +import { YearDataWrapper } from "../../YearDataWrapper.js" +import { EntryPage } from "./EntryPage.js" + +const routeRequiredKeys = [ + "entries", + "entryLines", + "entryTags", + "journals", + "tags", + "files", +] as const satisfies readonly YearDataKey[] + +// Used by TanStack Router as a standalone route component — resolves data itself via YearDataWrapper. +export function EntryRoutePage() { + const params = useParams({ strict: false }) as { idYear?: string; idEntry?: string } + const idYear = params.idYear ?? "" + const idEntry = params.idEntry ?? "" + + return ( + + {({ entries, entryLines: allEntryLines, entryTags, journals, tags, files }) => { + const entry = entries.find((r) => r.id === idEntry) + if (entry === undefined) return null + + const entryLines = allEntryLines.filter((row) => row.idEntry === idEntry) + const journal = + entry.idJournal !== null ? (journals.find((j) => j.id === entry.idJournal) ?? null) : null + const entryTagIds = entryTags.filter((et) => et.idEntry === entry.id).map((et) => et.idTag) + const entryTagLabels = entryTagIds + .map((id) => tags.find((t) => t.id === id)) + .filter((t): t is NonNullable => Boolean(t)) + .map((t) => t.label) + const file = entry.idFile !== null ? (files.find((f) => f.id === entry.idFile) ?? null) : null + + let totalDebit = 0 + let totalCredit = 0 + for (const entryLine of entryLines) { + totalDebit += Number(entryLine.debit) + totalCredit += Number(entryLine.credit) + } + + return ( + + ) + }} + + ) +} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryTabContent.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx rename to packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryTabContent.tsx index 05b980ce..a43270a7 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryTabContent.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryTabContent.tsx @@ -11,21 +11,21 @@ import { IconTrash, } from "@tabler/icons-react" import { Suspense, useState } from "react" -import { Banner } from "../../../../../components/layouts/banner.tsx" +import { Banner } from "../../../../../components/layouts/Banner.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" -import { SubPageContent } from "../../../../../components/layouts/subPageContent.tsx" +import { SubPageContent } from "../../../../../components/layouts/SubPageContent.tsx" import { Popover } from "../../../../../components/overlays/popover/popover.js" import { compareAmounts } from "../../../../../utilities/compareAmounts.ts" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { ReverseOneEntry } from "../reverseOneEntry.tsx" -import { DeleteOneEntry } from "./deleteOneEntry.tsx" -import { DuplicateOneEntry } from "./duplicateOneEntry.tsx" -import { EntryCategoriesTab } from "./entryCategoriesTab.tsx" -import { EntryLinesTab } from "./entryLinesTab.tsx" -import { EntryMetadataTab } from "./entryMetadataTab.tsx" -import { EntryPage } from "./entryPage.tsx" -import { UpdateOneEntry } from "./updateOneEntry.tsx" +import type { YearDataKey } from "../../YearDataWrapper.tsx" +import { YearDataWrapper } from "../../YearDataWrapper.tsx" +import { ReverseOneEntry } from "../ReverseOneEntry.tsx" +import { DeleteOneEntry } from "./DeleteOneEntry.tsx" +import { DuplicateOneEntry } from "./DuplicateOneEntry.tsx" +import { EntryCategoriesTab } from "./EntryCategoriesTab.tsx" +import { EntryLinesTab } from "./EntryLinesTab.tsx" +import { EntryMetadataTab } from "./EntryMetadataTab.tsx" +import { EntryPage } from "./EntryPage.tsx" +import { UpdateOneEntry } from "./UpdateOneEntry.tsx" const requiredKeys = [ "entries", diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx rename to packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx index 208e1923..9c609ac3 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateManyEntryLines.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx @@ -9,13 +9,13 @@ import { IconPencil } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx rename to packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx index 6f91b6b3..953317b5 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/updateOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx @@ -12,14 +12,14 @@ import { IconPencil } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { InputDataCombobox } from "../../../../../components/inputDataCombobox.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { InputDataCombobox } from "../../../../../components/InputDataCombobox.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx index cbd98d30..220d7090 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx @@ -2,14 +2,11 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { Button, ButtonPlainContent, FormatDate, FormatNull, FormatPrice, FormatText, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" import type * as v from "valibot" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { UpdateOneEntry } from "./updateOneEntry.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" +import { UpdateOneEntry } from "./UpdateOneEntry.tsx" export type EntryPageData = { entry: v.InferOutput @@ -45,69 +42,6 @@ export function EntryPage(props: EntryPageData) { ) } -const routeRequiredKeys = [ - "entries", - "entryLines", - "entryTags", - "journals", - "tags", - "files", -] as const satisfies readonly YearDataKey[] - -// Used by TanStack Router as a standalone route component — resolves data itself via YearDataWrapper. -export function EntryRoutePage() { - const params = useParams({ strict: false }) as { idYear?: string; idEntry?: string } - const idYear = params.idYear ?? "" - const idEntry = params.idEntry ?? "" - const { openTab } = useTabs() - - return ( - - {({ entries, entryLines: allEntryLines, entryTags, journals, tags, files }) => { - const entry = entries.find((r) => r.id === idEntry) - if (entry === undefined) return null - - const entryLines = allEntryLines.filter((row) => row.idEntry === idEntry) - const journal = - entry.idJournal !== null ? (journals.find((j) => j.id === entry.idJournal) ?? null) : null - const entryTagIds = entryTags.filter((et) => et.idEntry === entry.id).map((et) => et.idTag) - const entryTagLabels = entryTagIds - .map((id) => tags.find((t) => t.id === id)) - .filter((t): t is NonNullable => Boolean(t)) - .map((t) => t.label) - const file = entry.idFile !== null ? (files.find((f) => f.id === entry.idFile) ?? null) : null - - let totalDebit = 0 - let totalCredit = 0 - for (const entryLine of entryLines) { - totalDebit += Number(entryLine.debit) - totalCredit += Number(entryLine.credit) - } - - return ( - - openTab({ - component: "fichier", - props: { idOrganization, idFile }, - }) - } - /> - ) - }} - - ) -} - function EntryInformationsTab(props: { entry: v.InferOutput journal: v.InferOutput | null diff --git a/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/CreateOneEntry.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx rename to packages/website/src/features/dashboard/$idYear/entries/CreateOneEntry.tsx index 3b08f92b..06c4d12d 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/createOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/CreateOneEntry.tsx @@ -14,15 +14,15 @@ import { IconPlus } from "@tabler/icons-react" import { type JSX, useState } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.js" -import { FormError } from "../../../../components/forms/formError.js" -import { FormField } from "../../../../components/forms/formField.js" -import { FormGroup } from "../../../../components/forms/formGroup.js" -import { FormItem } from "../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../components/forms/formRoot.js" -import { InputDataCombobox } from "../../../../components/inputDataCombobox.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { FormControl } from "../../../../components/forms/FormControl.js" +import { FormError } from "../../../../components/forms/FormError.js" +import { FormField } from "../../../../components/forms/FormField.js" +import { FormGroup } from "../../../../components/forms/FormGroup.js" +import { FormItem } from "../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../components/forms/FormRoot.js" +import { InputDataCombobox } from "../../../../components/InputDataCombobox.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { applicationRouter } from "../../../../routes/applicationRouter.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" diff --git a/packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/EntriesPage.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx rename to packages/website/src/features/dashboard/$idYear/entries/EntriesPage.tsx index 6d7102cc..580c24b3 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entriesPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/EntriesPage.tsx @@ -5,13 +5,13 @@ import { useParams } from "@tanstack/react-router" import { Fragment } from "react" import { Page } from "../../../../components/layouts/page/page.js" import { Popover } from "../../../../components/overlays/popover/popover.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" -import { YearDataWrapper } from "../yearDataWrapper.tsx" -import { CreateOneEntry } from "./createOneEntry.js" -import { EntriesTable } from "./entriesTable.js" -import { ExportEntryLines } from "./exportEntryLines.js" -import { ExportFecFile } from "./exportFecFile.js" -import { ImportFecFile } from "./importFecFile.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" +import { YearDataWrapper } from "../YearDataWrapper.tsx" +import { CreateOneEntry } from "./CreateOneEntry.js" +import { EntriesTable } from "./EntriesTable.js" +import { ExportEntryLines } from "./ExportEntryLines.js" +import { ExportFecFile } from "./ExportFecFile.js" +import { ImportFecFile } from "./ImportFecFile.js" export function EntriesPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx b/packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx rename to packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx index e364e027..ae06a27e 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entriesTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx @@ -8,10 +8,10 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPencil } from "@tabler/icons-react" import { useMemo } from "react" import type * as v from "valibot" -import { DataTable } from "../../../../components/layouts/dataTable.js" -import { TabLink } from "../../../../components/layouts/tabBar/tabLink.js" -import type { YearDataMaps } from "../yearDataWrapper.tsx" -import { EntriesTableSelectionActions } from "./entriesTableSelectionActions.js" +import { DataTable } from "../../../../components/layouts/DataTable.js" +import { TabLink } from "../../../../components/layouts/tabBar/TabLink.js" +import type { YearDataMaps } from "../YearDataWrapper.tsx" +import { EntriesTableSelectionActions } from "./EntriesTableSelectionActions.js" export function EntriesTable(props: { idOrganization: v.InferOutput["id"] @@ -76,6 +76,7 @@ export function EntriesTable(props: { idOrganization: row.original.idOrganization, idYear: row.original.idYear, idEntry: row.original.id, + label: row.original.label, }, }} > diff --git a/packages/website/src/features/dashboard/$idYear/entries/entriesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/entries/entriesTableSelectionActions.tsx rename to packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx index 5e87272f..38673c74 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entriesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx @@ -5,7 +5,7 @@ import { IconChevronDown, IconTrash } from "@tabler/icons-react" import type { Row } from "@tanstack/react-table" import { useState } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Popover } from "../../../../components/overlays/popover/popover.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" diff --git a/packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx b/packages/website/src/features/dashboard/$idYear/entries/ExportEntryLines.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx rename to packages/website/src/features/dashboard/$idYear/entries/ExportEntryLines.tsx index f13fe17b..1797cda9 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/exportEntryLines.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/ExportEntryLines.tsx @@ -10,14 +10,14 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconDownload } from "@tabler/icons-react" import { useMemo } from "react" import * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.js" -import { FormError } from "../../../../components/forms/formError.js" -import { FormField } from "../../../../components/forms/formField.js" -import { FormGroup } from "../../../../components/forms/formGroup.js" -import { FormItem } from "../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../components/forms/formRoot.js" -import { InputDataCombobox } from "../../../../components/inputDataCombobox.js" +import { FormControl } from "../../../../components/forms/FormControl.js" +import { FormError } from "../../../../components/forms/FormError.js" +import { FormField } from "../../../../components/forms/FormField.js" +import { FormGroup } from "../../../../components/forms/FormGroup.js" +import { FormItem } from "../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../components/forms/FormRoot.js" +import { InputDataCombobox } from "../../../../components/InputDataCombobox.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" export function ExportEntryLines(props: { diff --git a/packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx b/packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx rename to packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx index 3c6fc26f..7847527c 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/exportFecFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx @@ -11,8 +11,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconFileExport } from "@tabler/icons-react" import { useEffect, useMemo, useState } from "react" import type * as v from "valibot" -import { Banner } from "../../../../components/layouts/banner.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { Banner } from "../../../../components/layouts/Banner.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" diff --git a/packages/website/src/features/dashboard/$idYear/entries/importFecFile.tsx b/packages/website/src/features/dashboard/$idYear/entries/ImportFecFile.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/entries/importFecFile.tsx rename to packages/website/src/features/dashboard/$idYear/entries/ImportFecFile.tsx diff --git a/packages/website/src/features/dashboard/$idYear/entries/reverseOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/entries/reverseOneEntry.tsx rename to packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx index 41cde234..70cd279c 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/reverseOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx @@ -8,7 +8,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/amortizationTemplate.tsx b/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/AmortizationTemplateForm.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/entries/entryTemplates/amortizationTemplate.tsx rename to packages/website/src/features/dashboard/$idYear/entries/entryTemplates/AmortizationTemplateForm.tsx index 805849a7..7f8e2047 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/amortizationTemplate.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/AmortizationTemplateForm.tsx @@ -7,12 +7,12 @@ import { IconCalculator } from "@tabler/icons-react" import { useEffect, useRef } from "react" import { FormProvider, useForm } from "react-hook-form" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { InputDataCombobox } from "../../../../../components/inputDataCombobox.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { InputDataCombobox } from "../../../../../components/InputDataCombobox.tsx" import { useDataFromAPI } from "../../../../../utilities/useHTTPData.ts" import type { EntryTemplateFormProps } from "./entryTemplates.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/entryTemplates.tsx b/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/entryTemplates.tsx index 70d32a54..7e22c260 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/entryTemplates.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/entryTemplates/entryTemplates.tsx @@ -1,6 +1,6 @@ import type { ReactElement } from "react" import type { UseFormReturn } from "react-hook-form" -import { AmortizationTemplateForm } from "./amortizationTemplate.tsx" +import { AmortizationTemplateForm } from "./AmortizationTemplateForm.tsx" export type EntryTemplateKey = "empty" | "amortization" diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx index e86a632a..d3d92b92 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/deleteOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx @@ -3,7 +3,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../routes/applicationRouter.tsx" import { invalidateData } from "../../../../../utilities/invalidateData.ts" import { deleteFileWithSignedUrl } from "../deleteFileWithSignedUrl.ts" diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileData.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileData.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/fileData.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FileData.tsx diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileFile.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/fileFile.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FileFile.tsx diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileLayout.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/fileLayout.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx index e23b5f2d..2e16fb6e 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx @@ -5,11 +5,11 @@ import { Outlet, useParams } from "@tanstack/react-router" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../components/LinkButton.tsx" import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" -import { DeleteOneFile } from "./deleteOneFile.tsx" -import { FileData } from "./fileData.tsx" -import { UpdateOneFile } from "./updateOneFile.tsx" +import { DeleteOneFile } from "./DeleteOneFile.tsx" +import { FileData } from "./FileData.tsx" +import { UpdateOneFile } from "./UpdateOneFile.tsx" export function FileLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileMetadataTab.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FileMetadataTab.tsx index 27781d92..10265888 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileMetadataTab.tsx @@ -3,7 +3,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { FileData } from "./fileData.tsx" +import { FileData } from "./FileData.tsx" export function FileMetadataTab(props: { idOrganization?: string; idFile?: string } = {}) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FilePage.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FilePage.tsx index 1e1e7dfd..d973e0a6 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/filePage.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FilePage.tsx @@ -3,7 +3,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { FileData } from "./fileData.tsx" +import { FileData } from "./FileData.tsx" export function FilePage(props: { idOrganization?: string; idFile?: string } = {}) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileTabContent.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileTabContent.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/fileTabContent.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FileTabContent.tsx index bd6d6a00..096ae891 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileTabContent.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileTabContent.tsx @@ -3,13 +3,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconDatabase, IconEye, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Suspense } from "react" import { Page } from "../../../../../components/layouts/page/page.tsx" -import { SubPageContent } from "../../../../../components/layouts/subPageContent.tsx" -import { DeleteOneFile } from "./deleteOneFile.tsx" -import { FileData } from "./fileData.tsx" -import { FileMetadataTab } from "./fileMetadataTab.tsx" -import { FilePage } from "./filePage.tsx" -import { FileVisualisationTab } from "./fileVisualisationTab.tsx" -import { UpdateOneFile } from "./updateOneFile.tsx" +import { SubPageContent } from "../../../../../components/layouts/SubPageContent.tsx" +import { DeleteOneFile } from "./DeleteOneFile.tsx" +import { FileData } from "./FileData.tsx" +import { FileMetadataTab } from "./FileMetadataTab.tsx" +import { FilePage } from "./FilePage.tsx" +import { FileVisualisationTab } from "./FileVisualisationTab.tsx" +import { UpdateOneFile } from "./UpdateOneFile.tsx" export function FileTabContent(props: { idOrganization: string; idFile: string }) { return ( diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileVisualisationTab.tsx similarity index 91% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/FileVisualisationTab.tsx index d7fb6f99..04d6616e 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/fileVisualisationTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileVisualisationTab.tsx @@ -1,8 +1,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { FileData } from "./fileData.tsx" -import { FileFile } from "./fileFile.tsx" +import { FileData } from "./FileData.tsx" +import { FileFile } from "./FileFile.tsx" export function FileVisualisationTab(props: { idOrganization?: string; idFile?: string } = {}) { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx similarity index 91% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx index eee1f021..a752020d 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx @@ -3,8 +3,8 @@ import { Button } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type { JSX } from "react" import type * as v from "valibot" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.js" -import { UpdateOneFileForm } from "./updateOneFileForm.js" +import { useTabs } from "../../../../../contexts/tabs/useTabs.js" +import { UpdateOneFileForm } from "./UpdateOneFileForm.js" export function UpdateOneFile(props: { file: v.InferOutput; children: JSX.Element }) { const { openPanelTab, closeTab } = useTabs() diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFileForm.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx rename to packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFileForm.tsx index c7be3d8b..def9d57b 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/updateOneFileForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFileForm.tsx @@ -11,12 +11,12 @@ import { InputDate, InputFile, InputText, toast } from "@arrhes/ui" import { IconPencil } from "@tabler/icons-react" import { Fragment } from "react/jsx-runtime" import * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.js" -import { FormError } from "../../../../../components/forms/formError.js" -import { FormField } from "../../../../../components/forms/formField.js" -import { FormItem } from "../../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../../components/forms/formRoot.js" +import { FormControl } from "../../../../../components/forms/FormControl.js" +import { FormError } from "../../../../../components/forms/FormError.js" +import { FormField } from "../../../../../components/forms/FormField.js" +import { FormItem } from "../../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../../components/forms/FormRoot.js" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../../utilities/invalidateData.js" diff --git a/packages/website/src/features/dashboard/$idYear/files/createOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/CreateOneFile.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/files/createOneFile.tsx rename to packages/website/src/features/dashboard/$idYear/files/CreateOneFile.tsx diff --git a/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx b/packages/website/src/features/dashboard/$idYear/files/CreateOneFolder.tsx similarity index 91% rename from packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx rename to packages/website/src/features/dashboard/$idYear/files/CreateOneFolder.tsx index 2086d799..bf915850 100644 --- a/packages/website/src/features/dashboard/$idYear/files/createOneFolder.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/CreateOneFolder.tsx @@ -4,13 +4,13 @@ import { Button, ButtonOutlineContent, InputText, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconFolderPlus } from "@tabler/icons-react" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.js" -import { FormError } from "../../../../components/forms/formError.js" -import { FormField } from "../../../../components/forms/formField.js" -import { FormItem } from "../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../components/forms/formRoot.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { FormControl } from "../../../../components/forms/FormControl.js" +import { FormError } from "../../../../components/forms/FormError.js" +import { FormField } from "../../../../components/forms/FormField.js" +import { FormItem } from "../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../components/forms/FormRoot.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" diff --git a/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/files/fileActions.tsx rename to packages/website/src/features/dashboard/$idYear/files/FileActions.tsx index de98e7e7..31b276bb 100644 --- a/packages/website/src/features/dashboard/$idYear/files/fileActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx @@ -9,16 +9,16 @@ import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconFileText, IconPencil, IconTrash } from "@tabler/icons-react" import { useState } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" import { Popover } from "../../../../components/overlays/popover/popover.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" -import { UpdateOneFileForm } from "./$idFile/updateOneFileForm.js" +import { UpdateOneFileForm } from "./$idFile/UpdateOneFileForm.js" import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" -import { MoveOneFileForm } from "./moveOneFileForm.js" +import { MoveOneFileForm } from "./MoveOneFileForm.js" export function FileActions(props: { file: v.InferOutput; idOrganization: string }) { const [moveOpen, setMoveOpen] = useState(false) diff --git a/packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx rename to packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx index 24fe1ed8..9d6c254a 100644 --- a/packages/website/src/features/dashboard/$idYear/files/fileContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx @@ -6,14 +6,14 @@ import { IconArrowsMove, IconEye, IconPencil, IconTrash } from "@tabler/icons-re import { type ReactElement, useState } from "react" import type * as v from "valibot" import { ContextMenu } from "../../../../components/overlays/contextMenu/contextMenu.js" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { applicationRouter } from "../../../../routes/applicationRouter.js" import { invalidateData } from "../../../../utilities/invalidateData.js" -import { UpdateOneFileForm } from "./$idFile/updateOneFileForm.js" +import { UpdateOneFileForm } from "./$idFile/UpdateOneFileForm.js" import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" -import { MoveOneFileForm } from "./moveOneFileForm.js" +import { MoveOneFileForm } from "./MoveOneFileForm.js" export function FileContextMenu(props: { file: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/files/fileSelect.tsx b/packages/website/src/features/dashboard/$idYear/files/FileSelect.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/files/fileSelect.tsx rename to packages/website/src/features/dashboard/$idYear/files/FileSelect.tsx diff --git a/packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesGrid.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx rename to packages/website/src/features/dashboard/$idYear/files/FilesGrid.tsx index 29f112a6..e704d30f 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesGrid.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesGrid.tsx @@ -10,12 +10,12 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" import { IconArrowUp, IconFile, IconFileTypePdf, IconFolder, IconPhoto } from "@tabler/icons-react" import { type DragEvent, useRef, useState } from "react" import type * as v from "valibot" -import { EmptyState } from "../../../../components/layouts/emptyState.js" +import { EmptyState } from "../../../../components/layouts/EmptyState.js" import { applicationRouter } from "../../../../routes/applicationRouter.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" -import { FileContextMenu } from "./fileContextMenu.js" -import { FolderContextMenu } from "./folderContextMenu.js" +import { FileContextMenu } from "./FileContextMenu.js" +import { FolderContextMenu } from "./FolderContextMenu.js" function getFileIcon(type: string | null) { if (!type) return diff --git a/packages/website/src/features/dashboard/$idYear/files/filesPage.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/files/filesPage.tsx rename to packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx index 47d759c6..34bab188 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx @@ -8,15 +8,15 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { useNavigate, useParams, useSearch } from "@tanstack/react-router" import { type DragEvent, useState } from "react" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.js" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.js" import { Page } from "../../../../components/layouts/page/page.js" import { storageLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.js" import { storageRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" -import { CreateOneFile } from "./createOneFile.js" -import { CreateOneFolder } from "./createOneFolder.js" -import { FilesPageContent } from "./filesPageContent.js" +import { CreateOneFile } from "./CreateOneFile.js" +import { CreateOneFolder } from "./CreateOneFolder.js" +import { FilesPageContent } from "./FilesPageContent.js" export function FilesPage() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/files/filesPageContent.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesPageContent.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/files/filesPageContent.tsx rename to packages/website/src/features/dashboard/$idYear/files/FilesPageContent.tsx index b77699b9..855ce619 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesPageContent.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesPageContent.tsx @@ -2,9 +2,9 @@ import { readAllFilesRouteDefinition, type readAllFoldersRouteDefinition } from import { css } from "@arrhes/ui/utilities/cn.js" import { type DragEvent, useMemo, useState } from "react" import type * as v from "valibot" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.js" -import { FilesGrid } from "./filesGrid.js" -import { FilesTable } from "./filesTable.js" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.js" +import { FilesGrid } from "./FilesGrid.js" +import { FilesTable } from "./FilesTable.js" type ViewMode = "grid" | "list" diff --git a/packages/website/src/features/dashboard/$idYear/files/filesTable.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesTable.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/files/filesTable.tsx rename to packages/website/src/features/dashboard/$idYear/files/FilesTable.tsx index 3e462b5e..a576145e 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesTable.tsx @@ -10,14 +10,14 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" import { IconArrowLeft, IconFile, IconFileTypePdf, IconFolder } from "@tabler/icons-react" import { type DragEvent, type MouseEvent, type ReactElement, useEffect, useRef, useState } from "react" import type * as v from "valibot" -import { DataTable } from "../../../../components/layouts/dataTable.js" +import { DataTable } from "../../../../components/layouts/DataTable.js" import { applicationRouter } from "../../../../routes/applicationRouter.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" -import { FileActions } from "./fileActions.js" -import type { TableRow } from "./filesTableSelectionActions.js" -import { FilesTableSelectionActions } from "./filesTableSelectionActions.js" -import { FolderActions } from "./folderActions.js" +import { FileActions } from "./FileActions.js" +import type { TableRow } from "./FilesTableSelectionActions.js" +import { FilesTableSelectionActions } from "./FilesTableSelectionActions.js" +import { FolderActions } from "./FolderActions.js" type DragPayload = | { diff --git a/packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx rename to packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx index 586b1e50..4327bba2 100644 --- a/packages/website/src/features/dashboard/$idYear/files/filesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx @@ -10,7 +10,7 @@ import { IconChevronDown, IconTrash } from "@tabler/icons-react" import type { Row } from "@tanstack/react-table" import { useState } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Popover } from "../../../../components/overlays/popover/popover.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" diff --git a/packages/website/src/features/dashboard/$idYear/files/folderActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/files/folderActions.tsx rename to packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx index e24bd8fa..a3ec32e2 100644 --- a/packages/website/src/features/dashboard/$idYear/files/folderActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx @@ -5,14 +5,14 @@ import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconPencil, IconTrash } from "@tabler/icons-react" import { useState } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" import { Popover } from "../../../../components/overlays/popover/popover.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" -import { MoveOneFolderForm } from "./moveOneFolderForm.js" -import { UpdateOneFolderForm } from "./updateOneFolderForm.js" +import { MoveOneFolderForm } from "./MoveOneFolderForm.js" +import { UpdateOneFolderForm } from "./UpdateOneFolderForm.js" export function FolderActions(props: { folder: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx rename to packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx index 2d5cf7a1..1505976c 100644 --- a/packages/website/src/features/dashboard/$idYear/files/folderContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx @@ -6,13 +6,13 @@ import { IconArrowsMove, IconPencil, IconTrash } from "@tabler/icons-react" import { type ReactElement, useState } from "react" import type * as v from "valibot" import { ContextMenu } from "../../../../components/overlays/contextMenu/contextMenu.js" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.js" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" -import { useTabs } from "../../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" -import { MoveOneFolderForm } from "./moveOneFolderForm.js" -import { UpdateOneFolderForm } from "./updateOneFolderForm.js" +import { MoveOneFolderForm } from "./MoveOneFolderForm.js" +import { UpdateOneFolderForm } from "./UpdateOneFolderForm.js" export function FolderContextMenu(props: { folder: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx b/packages/website/src/features/dashboard/$idYear/files/MoveOneFileForm.tsx similarity index 91% rename from packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx rename to packages/website/src/features/dashboard/$idYear/files/MoveOneFileForm.tsx index 8e36b9cd..afc96d10 100644 --- a/packages/website/src/features/dashboard/$idYear/files/moveOneFileForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/MoveOneFileForm.tsx @@ -8,12 +8,12 @@ import { InputSelect, toast } from "@arrhes/ui" import { IconArrowsMove } from "@tabler/icons-react" import { useMemo } from "react" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.js" -import { FormError } from "../../../../components/forms/formError.js" -import { FormField } from "../../../../components/forms/formField.js" -import { FormItem } from "../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../components/forms/formRoot.js" +import { FormControl } from "../../../../components/forms/FormControl.js" +import { FormError } from "../../../../components/forms/FormError.js" +import { FormField } from "../../../../components/forms/FormField.js" +import { FormItem } from "../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../components/forms/FormRoot.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx b/packages/website/src/features/dashboard/$idYear/files/MoveOneFolderForm.tsx similarity index 93% rename from packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx rename to packages/website/src/features/dashboard/$idYear/files/MoveOneFolderForm.tsx index c60310c1..cee45d0f 100644 --- a/packages/website/src/features/dashboard/$idYear/files/moveOneFolderForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/MoveOneFolderForm.tsx @@ -4,12 +4,12 @@ import { InputSelect, toast } from "@arrhes/ui" import { IconArrowsMove } from "@tabler/icons-react" import { useMemo } from "react" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.js" -import { FormError } from "../../../../components/forms/formError.js" -import { FormField } from "../../../../components/forms/formField.js" -import { FormItem } from "../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../components/forms/formRoot.js" +import { FormControl } from "../../../../components/forms/FormControl.js" +import { FormError } from "../../../../components/forms/FormError.js" +import { FormField } from "../../../../components/forms/FormField.js" +import { FormItem } from "../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../components/forms/FormRoot.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx b/packages/website/src/features/dashboard/$idYear/files/UpdateOneFolderForm.tsx similarity index 88% rename from packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx rename to packages/website/src/features/dashboard/$idYear/files/UpdateOneFolderForm.tsx index 3f96d19f..1d872bfa 100644 --- a/packages/website/src/features/dashboard/$idYear/files/updateOneFolderForm.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/UpdateOneFolderForm.tsx @@ -3,12 +3,12 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { InputText, toast } from "@arrhes/ui" import { IconPencil } from "@tabler/icons-react" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.js" -import { FormError } from "../../../../components/forms/formError.js" -import { FormField } from "../../../../components/forms/formField.js" -import { FormItem } from "../../../../components/forms/formItem.js" -import { FormLabel } from "../../../../components/forms/formLabel.js" -import { FormRoot } from "../../../../components/forms/formRoot.js" +import { FormControl } from "../../../../components/forms/FormControl.js" +import { FormError } from "../../../../components/forms/FormError.js" +import { FormField } from "../../../../components/forms/FormField.js" +import { FormItem } from "../../../../components/forms/FormItem.js" +import { FormLabel } from "../../../../components/forms/FormLabel.js" +import { FormRoot } from "../../../../components/forms/FormRoot.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" diff --git a/packages/website/src/features/dashboard/$idYear/reports/reportFilterPopover.tsx b/packages/website/src/features/dashboard/$idYear/reports/ReportFilterPopover.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/reportFilterPopover.tsx rename to packages/website/src/features/dashboard/$idYear/reports/ReportFilterPopover.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/reportsLayout.tsx b/packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/reports/reportsLayout.tsx rename to packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx index 4677091f..c3efcf66 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/reportsLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx @@ -1,6 +1,6 @@ import { IconBook, IconBook2, IconChartBar, IconReport, IconReportMoney, IconScale } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/subPageLayout.js" +import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.js" import { reportsLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.js" export function ReportsLayout() { diff --git a/packages/website/src/features/dashboard/$idYear/reports/reportsTabContent.tsx b/packages/website/src/features/dashboard/$idYear/reports/ReportsTabContent.tsx similarity index 90% rename from packages/website/src/features/dashboard/$idYear/reports/reportsTabContent.tsx rename to packages/website/src/features/dashboard/$idYear/reports/ReportsTabContent.tsx index 801ac776..f310e727 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/reportsTabContent.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/ReportsTabContent.tsx @@ -1,29 +1,29 @@ import { IconBook, IconBook2, IconChartBar, IconReport, IconReportMoney, IconScale } from "@tabler/icons-react" import { lazy, Suspense } from "react" -import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" +import { SubPageContent } from "../../../../components/layouts/SubPageContent.tsx" const JournalReportPage = lazy(() => - import("./journalReport/journalReportPage.js").then((m) => ({ + import("./journalReport/JournalReportPage.js").then((m) => ({ default: m.JournalReportPage, })), ) const LedgerReportPage = lazy(() => - import("./ledgerReport/ledgerReportPage.js").then((m) => ({ + import("./ledgerReport/LedgerReportPage.js").then((m) => ({ default: m.LedgerReportPage, })), ) const BalanceReportPage = lazy(() => - import("./balanceReport/balanceReportPage.js").then((m) => ({ + import("./balanceReport/BalanceReportPage.js").then((m) => ({ default: m.BalanceReportPage, })), ) const BalanceSheetReportPage = lazy(() => - import("./balanceSheetReport/balanceSheetReportPage.js").then((m) => ({ + import("./balanceSheetReport/BalanceSheetReportPage.js").then((m) => ({ default: m.BalanceSheetReportPage, })), ) const IncomeStatementReportPage = lazy(() => - import("./incomeStatementReport/incomeStatementReportPage.js").then((m) => ({ + import("./incomeStatementReport/IncomeStatementReportPage.js").then((m) => ({ default: m.IncomeStatementReportPage, })), ) diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceReport/balanceReportPage.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceReport/BalanceReportPage.tsx similarity index 93% rename from packages/website/src/features/dashboard/$idYear/reports/balanceReport/balanceReportPage.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceReport/BalanceReportPage.tsx index f2fd1f7d..b565a17d 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceReport/balanceReportPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceReport/BalanceReportPage.tsx @@ -1,13 +1,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { useState } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { ReportFilterPopover } from "../reportFilterPopover.tsx" -import { BalanceReportTable } from "./balanceReportTable.tsx" +import type { YearDataKey } from "../../YearDataWrapper.tsx" +import { YearDataWrapper } from "../../YearDataWrapper.tsx" +import { ReportFilterPopover } from "../ReportFilterPopover.tsx" +import { BalanceReportTable } from "./BalanceReportTable.tsx" const requiredKeys = [ "accounts", diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceReport/balanceReportTable.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceReport/BalanceReportTable.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/balanceReport/balanceReportTable.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceReport/BalanceReportTable.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetReportPage.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPage.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetReportPage.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPage.tsx index 170866c6..698bb29b 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetReportPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPage.tsx @@ -2,15 +2,15 @@ import { Button, ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { useState } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { ReportFilterPopover } from "../reportFilterPopover.tsx" -import { BalanceSheetAssetsReportTable } from "./balanceSheetAsset/balanceSheetAssetsReportTable.tsx" -import { BalanceSheetLiabilitiesReportTable } from "./balanceSheetLiability/balanceSheetLiabilitiesReportTable.tsx" -import { DownloadBalanceSheetReport } from "./downloadBalanceSheetReport.tsx" +import type { YearDataKey } from "../../YearDataWrapper.tsx" +import { YearDataWrapper } from "../../YearDataWrapper.tsx" +import { ReportFilterPopover } from "../ReportFilterPopover.tsx" +import { BalanceSheetAssetsReportTable } from "./balanceSheetAsset/BalanceSheetAssetsReportTable.tsx" +import { BalanceSheetLiabilitiesReportTable } from "./balanceSheetLiability/BalanceSheetLiabilitiesReportTable.tsx" +import { DownloadBalanceSheetReport } from "./DownloadBalanceSheetReport.tsx" const requiredKeys = [ "accounts", diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetReportPdf.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPdf.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetReportPdf.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPdf.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/downloadBalanceSheetReport.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/DownloadBalanceSheetReport.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/downloadBalanceSheetReport.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/DownloadBalanceSheetReport.tsx index 8bda96e9..fb262803 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/downloadBalanceSheetReport.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/DownloadBalanceSheetReport.tsx @@ -7,7 +7,7 @@ import { IconDownload, IconFileTypePdf, IconFileTypeXml } from "@tabler/icons-re import type * as v from "valibot" import { Popover } from "../../../../../components/overlays/popover/popover.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" -import { BalanceSheetReportPdf } from "./balanceSheetReportPdf.tsx" +import { BalanceSheetReportPdf } from "./BalanceSheetReportPdf.tsx" export function DownloadBalanceSheetReport(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportItem.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportItem.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportItem.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportItem.tsx index 26d836dc..b64c94b9 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportItem.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportItem.tsx @@ -3,7 +3,7 @@ import { type ComponentProps, Fragment } from "react" import type * as v from "valibot" import { toRoman } from "../../../../../../utilities/toRoman.ts" import { getBalanceSheetChildren } from "../../../yearSettings/balanceSheets/getBalanceSheetChildren.tsx" -import { BalanceSheetAssetsReportRow } from "./balanceSheetAssetsReportRow.tsx" +import { BalanceSheetAssetsReportRow } from "./BalanceSheetAssetsReportRow.tsx" export function BalanceSheetAssetsReportItem(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportRow.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportRow.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportRow.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportRow.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportTable.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportTable.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportTable.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportTable.tsx index 19d11592..2ee02c80 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/balanceSheetAssetsReportTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetAsset/BalanceSheetAssetsReportTable.tsx @@ -5,8 +5,8 @@ import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { Table } from "../../../../../../components/layouts/table/table.tsx" import { getBalanceSheetChildren } from "../../../yearSettings/balanceSheets/getBalanceSheetChildren.tsx" -import { BalanceSheetAssetsReportItem } from "./balanceSheetAssetsReportItem.tsx" -import { BalanceSheetAssetsReportRow } from "./balanceSheetAssetsReportRow.tsx" +import { BalanceSheetAssetsReportItem } from "./BalanceSheetAssetsReportItem.tsx" +import { BalanceSheetAssetsReportRow } from "./BalanceSheetAssetsReportRow.tsx" export function BalanceSheetAssetsReportTable(props: { balanceSheets: Array> diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilitiesReportItem.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportItem.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilitiesReportItem.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportItem.tsx index a6ccd2a8..e9759d9d 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilitiesReportItem.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportItem.tsx @@ -3,7 +3,7 @@ import { type ComponentProps, Fragment } from "react" import type * as v from "valibot" import { toRoman } from "../../../../../../utilities/toRoman.ts" import { getBalanceSheetChildren } from "../../../yearSettings/balanceSheets/getBalanceSheetChildren.tsx" -import { BalanceSheetLiabilitiesReportRow } from "./balanceSheetLiabilityiesReportRow.tsx" +import { BalanceSheetLiabilitiesReportRow } from "./BalanceSheetLiabilitiesReportRow.tsx" export function BalanceSheetLiabilitiesReportItem(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilityiesReportRow.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportRow.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilityiesReportRow.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportRow.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilitiesReportTable.tsx b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportTable.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilitiesReportTable.tsx rename to packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportTable.tsx index 1f8b315f..2fa249af 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/balanceSheetLiabilitiesReportTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetLiability/BalanceSheetLiabilitiesReportTable.tsx @@ -5,8 +5,8 @@ import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" import { Table } from "../../../../../../components/layouts/table/table.tsx" import { getBalanceSheetChildren } from "../../../yearSettings/balanceSheets/getBalanceSheetChildren.tsx" -import { BalanceSheetLiabilitiesReportItem } from "./balanceSheetLiabilitiesReportItem.tsx" -import { BalanceSheetLiabilitiesReportRow } from "./balanceSheetLiabilityiesReportRow.tsx" +import { BalanceSheetLiabilitiesReportItem } from "./BalanceSheetLiabilitiesReportItem.tsx" +import { BalanceSheetLiabilitiesReportRow } from "./BalanceSheetLiabilitiesReportRow.tsx" export function BalanceSheetLiabilitiesReportTable(props: { balanceSheets: Array> diff --git a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/downloadIncomeStatementReport.tsx b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/DownloadIncomeStatementReport.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/downloadIncomeStatementReport.tsx rename to packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/DownloadIncomeStatementReport.tsx index fc21a670..179b9393 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/downloadIncomeStatementReport.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/DownloadIncomeStatementReport.tsx @@ -7,7 +7,7 @@ import { IconDownload, IconFileTypePdf, IconFileTypeXml } from "@tabler/icons-re import type * as v from "valibot" import { Popover } from "../../../../../components/overlays/popover/popover.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" -import { IncomeStatementReportPdf } from "./incomeStatementReportPdf.tsx" +import { IncomeStatementReportPdf } from "./IncomeStatementReportPdf.tsx" export function DownloadIncomeStatementReport(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportItem.tsx b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportItem.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportItem.tsx rename to packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportItem.tsx index 380b6a48..4b2dd4d5 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportItem.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportItem.tsx @@ -3,7 +3,7 @@ import { type ComponentProps, Fragment } from "react" import type * as v from "valibot" import { toRoman } from "../../../../../utilities/toRoman.ts" import { getIncomeStatementChildren } from "../../yearSettings/incomeStatements/getIncomeStatementChildren.tsx" -import { IncomeStatementReportRow } from "./incomeStatementReportRow.tsx" +import { IncomeStatementReportRow } from "./IncomeStatementReportRow.tsx" export function IncomeStatementReportItem(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportPage.tsx b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportPage.tsx rename to packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPage.tsx index 90698d43..f4515283 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPage.tsx @@ -1,14 +1,14 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { useState } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { ReportFilterPopover } from "../reportFilterPopover.tsx" -import { DownloadIncomeStatementReport } from "./downloadIncomeStatementReport.tsx" -import { IncomeStatementsReportTable } from "./incomeStatementsReportTable.tsx" +import type { YearDataKey } from "../../YearDataWrapper.tsx" +import { YearDataWrapper } from "../../YearDataWrapper.tsx" +import { ReportFilterPopover } from "../ReportFilterPopover.tsx" +import { DownloadIncomeStatementReport } from "./DownloadIncomeStatementReport.tsx" +import { IncomeStatementsReportTable } from "./IncomeStatementsReportTable.tsx" const requiredKeys = [ "accounts", diff --git a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportPdf.tsx b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPdf.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportPdf.tsx rename to packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPdf.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportRow.tsx b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportRow.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportRow.tsx rename to packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportRow.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementsReportTable.tsx b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementsReportTable.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementsReportTable.tsx rename to packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementsReportTable.tsx index 11446376..8eff22b0 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementsReportTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementsReportTable.tsx @@ -5,7 +5,7 @@ import type * as v from "valibot" import { Table } from "../../../../../components/layouts/table/table.tsx" import { toRoman } from "../../../../../utilities/toRoman.ts" import { getIncomeStatementChildren } from "../../yearSettings/incomeStatements/getIncomeStatementChildren.tsx" -import { IncomeStatementReportItem } from "./incomeStatementReportItem.tsx" +import { IncomeStatementReportItem } from "./IncomeStatementReportItem.tsx" export function IncomeStatementsReportTable(props: { incomeStatements: Array> diff --git a/packages/website/src/features/dashboard/$idYear/reports/journalReport/journalReportPage.tsx b/packages/website/src/features/dashboard/$idYear/reports/journalReport/JournalReportPage.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/reports/journalReport/journalReportPage.tsx rename to packages/website/src/features/dashboard/$idYear/reports/journalReport/JournalReportPage.tsx index 8f44f058..259d25e6 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/journalReport/journalReportPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/journalReport/JournalReportPage.tsx @@ -3,13 +3,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { useState } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { ReportFilterPopover } from "../reportFilterPopover.tsx" -import { JournalReportTable } from "./journalReportTable.tsx" +import type { YearDataKey } from "../../YearDataWrapper.tsx" +import { YearDataWrapper } from "../../YearDataWrapper.tsx" +import { ReportFilterPopover } from "../ReportFilterPopover.tsx" +import { JournalReportTable } from "./JournalReportTable.tsx" const PAGE_SIZE = 20 diff --git a/packages/website/src/features/dashboard/$idYear/reports/journalReport/journalReportTable.tsx b/packages/website/src/features/dashboard/$idYear/reports/journalReport/JournalReportTable.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/journalReport/journalReportTable.tsx rename to packages/website/src/features/dashboard/$idYear/reports/journalReport/JournalReportTable.tsx diff --git a/packages/website/src/features/dashboard/$idYear/reports/ledgerReport/ledgerReportPage.tsx b/packages/website/src/features/dashboard/$idYear/reports/ledgerReport/LedgerReportPage.tsx similarity index 93% rename from packages/website/src/features/dashboard/$idYear/reports/ledgerReport/ledgerReportPage.tsx rename to packages/website/src/features/dashboard/$idYear/reports/ledgerReport/LedgerReportPage.tsx index ea9f0d2f..d0fc147b 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/ledgerReport/ledgerReportPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/ledgerReport/LedgerReportPage.tsx @@ -1,13 +1,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { useState } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import type { YearDataKey } from "../../yearDataWrapper.tsx" -import { YearDataWrapper } from "../../yearDataWrapper.tsx" -import { ReportFilterPopover } from "../reportFilterPopover.tsx" -import { LedgerReportTable } from "./ledgerReportTable.tsx" +import type { YearDataKey } from "../../YearDataWrapper.tsx" +import { YearDataWrapper } from "../../YearDataWrapper.tsx" +import { ReportFilterPopover } from "../ReportFilterPopover.tsx" +import { LedgerReportTable } from "./LedgerReportTable.tsx" const requiredKeys = [ "accounts", diff --git a/packages/website/src/features/dashboard/$idYear/reports/ledgerReport/ledgerReportTable.tsx b/packages/website/src/features/dashboard/$idYear/reports/ledgerReport/LedgerReportTable.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/reports/ledgerReport/ledgerReportTable.tsx rename to packages/website/src/features/dashboard/$idYear/reports/ledgerReport/LedgerReportTable.tsx diff --git a/packages/website/src/features/dashboard/$idYear/useYearData.tsx b/packages/website/src/features/dashboard/$idYear/useYearData.tsx new file mode 100644 index 00000000..520f40bf --- /dev/null +++ b/packages/website/src/features/dashboard/$idYear/useYearData.tsx @@ -0,0 +1,10 @@ +import { useContext } from "react" +import { YearDataContext, type YearDataContextValue } from "./YearDataProvider.js" + +export function useYearData(): YearDataContextValue { + const context = useContext(YearDataContext) + if (context === null) { + throw new Error("useYearData must be used within a YearDataProvider") + } + return context +} diff --git a/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx b/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx index c4524f27..aecf0cfc 100644 --- a/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx @@ -13,7 +13,7 @@ import { readAllTagsRouteDefinition, } from "@arrhes/application-metadata/routes" import { type UseQueryResult, useQuery } from "@tanstack/react-query" -import { createContext, type ReactNode, useContext, useMemo } from "react" +import { createContext, type ReactNode, useMemo } from "react" import type * as v from "valibot" import { ClientError } from "../../../utilities/clientError.ts" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" @@ -46,16 +46,16 @@ type YearScopedRouteDefinition = { schemas: { body: v.ObjectSchema return: - | v.ObjectSchema - | v.ArraySchema, undefined> + | v.ObjectSchema + | v.ArraySchema, undefined> } } -type YearDataContextValue = { +export type YearDataContextValue = { [K in YearDataKey]: UseQueryResult } -const YearDataContext = createContext(null) +export const YearDataContext = createContext(null) function useYearQuery( key: K, @@ -145,10 +145,4 @@ export function YearDataProvider(props: { idYear: string; children: ReactNode }) return {props.children} } -export function useYearData(): YearDataContextValue { - const context = useContext(YearDataContext) - if (context === null) { - throw new Error("useYearData must be used within a YearDataProvider") - } - return context -} + diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx index 81399896..7a4015ee 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/deleteOneYear.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx @@ -3,8 +3,8 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/confirmationModal.tsx" -import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" +import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" +import { useTabs } from "../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/UpdateOneYear.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/UpdateOneYear.tsx index c0169c2d..d013706c 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/updateOneYear.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/UpdateOneYear.tsx @@ -6,16 +6,16 @@ import { IconPencil } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../components/forms/formError.tsx" -import { FormField } from "../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" -import { YearSelect } from "../../$idOrganization/years/yearSelect.tsx" +import { YearSelect } from "../../$idOrganization/years/YearSelect.tsx" export function UpdateOneYear(props: { year: v.InferOutput; children: JSX.Element }) { const { openPanelTab, closeTab } = useTabs() diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx index d7da14b2..d07eaa22 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx @@ -9,7 +9,7 @@ import { IconTag, } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/subPageLayout.tsx" +import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" import { yearSettingsLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx" export function YearSettingsLayout() { diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx similarity index 93% rename from packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx index 671f92e0..93502704 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx @@ -2,12 +2,12 @@ import { readOneYearRouteDefinition } from "@arrhes/application-metadata/routes" import { ButtonOutlineContent } from "@arrhes/ui" import { IconPencil, IconTrash } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { PageRoot } from "../../../../components/layouts/page/pageRoot.tsx" +import { PageRoot } from "../../../../components/layouts/page/PageRoot.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { DeleteOneYear } from "./deleteOneYear.tsx" -import { UpdateOneYear } from "./updateOneYear.tsx" +import { DeleteOneYear } from "./DeleteOneYear.tsx" +import { UpdateOneYear } from "./UpdateOneYear.tsx" export function YearSettingsPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsTabContent.tsx similarity index 92% rename from packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsTabContent.tsx index a46933e5..fb8e544e 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/yearSettingsTabContent.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsTabContent.tsx @@ -9,35 +9,35 @@ import { IconTag, } from "@tabler/icons-react" import { lazy, Suspense } from "react" -import { SubPageContent } from "../../../../components/layouts/subPageContent.tsx" +import { SubPageContent } from "../../../../components/layouts/SubPageContent.tsx" const YearSettingsPage = lazy(() => - import("./yearSettingsPage.js").then((m) => ({ + import("./YearSettingsPage.js").then((m) => ({ default: m.YearSettingsPage, })), ) const AccountsPage = lazy(() => - import("./accounts/accountsPage.js").then((m) => ({ + import("./accounts/AccountsPage.js").then((m) => ({ default: m.AccountsPage, })), ) const JournalsPage = lazy(() => - import("./journals/journalsPage.js").then((m) => ({ + import("./journals/JournalsPage.js").then((m) => ({ default: m.JournalsPage, })), ) const TagsPage = lazy(() => - import("./tags/tagsPage.js").then((m) => ({ + import("./tags/TagsPage.js").then((m) => ({ default: m.TagsPage, })), ) const BalanceSheetsPage = lazy(() => - import("./balanceSheets/balanceSheetsPage.js").then((m) => ({ + import("./balanceSheets/BalanceSheetsPage.js").then((m) => ({ default: m.BalanceSheetsPage, })), ) const IncomeStatementsPage = lazy(() => - import("./incomeStatements/incomeStatementsPage.js").then((m) => ({ + import("./incomeStatements/IncomeStatementsPage.js").then((m) => ({ default: m.IncomeStatementsPage, })), ) diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx index aa069281..3286d2df 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { accountLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx" -import { DeleteOneAccount } from "./deleteOneAccount.tsx" -import { UpdateOneAccount } from "./updateOneAccount.tsx" +import { DeleteOneAccount } from "./DeleteOneAccount.tsx" +import { UpdateOneAccount } from "./UpdateOneAccount.tsx" export function AccountLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx index ce20df4b..c054f50e 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { accountLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountPage.tsx index 1321e2e5..ca3d868a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountPage.tsx @@ -3,7 +3,7 @@ import { FormatBoolean, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { accountLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/DeleteOneAccount.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/DeleteOneAccount.tsx index 65b104b4..f611a86d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/DeleteOneAccount.tsx @@ -4,7 +4,7 @@ import { toast } from "@arrhes/ui" import { IconTrash } from "@tabler/icons-react" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx index 28f6f980..13895992 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx @@ -10,17 +10,17 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" -import { BalanceSheetsSelect } from "../../balanceSheets/balanceSheetSelect.tsx" -import { AccountSelect } from "../accountSelect.tsx" +import { BalanceSheetsSelect } from "../../balanceSheets/BalanceSheetsSelect.tsx" +import { AccountSelect } from "../AccountSelect.tsx" export function UpdateOneAccount(props: { account: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountSelect.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountSelect.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountSelect.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountSelect.tsx diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountsPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountsPage.tsx index f0de7d46..a3250f7d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountsPage.tsx @@ -3,11 +3,11 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { useCallback, useState, useTransition } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { AccountsTable } from "./accountsTable.tsx" -import { CreateOneAccount } from "./createOneAccount.tsx" +import { AccountsTable } from "./AccountsTable.tsx" +import { CreateOneAccount } from "./CreateOneAccount.tsx" export function AccountsPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountsTable.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountsTable.tsx index fa27a4d0..0d581e0f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/accountsTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/AccountsTable.tsx @@ -4,8 +4,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconListNumbers } from "@tabler/icons-react" import { useNavigate } from "@tanstack/react-router" import { type MouseEvent, useCallback, useMemo } from "react" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" -import { Virtualizer } from "../../../../../components/layouts/virtualizer.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" +import { Virtualizer } from "../../../../../components/layouts/Virtualizer.tsx" import { useDataFromAPI } from "../../../../../utilities/useHTTPData.ts" import { ACCOUNT_ITEM_HEIGHT, AccountItem } from "./accountItem.tsx" import { sortAccounts } from "./sortAccounts.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/CreateOneAccount.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/accounts/CreateOneAccount.tsx index 1606c0e2..fd3156c4 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/createOneAccount.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/CreateOneAccount.tsx @@ -6,17 +6,17 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" -import { BalanceSheetsSelect } from "../balanceSheets/balanceSheetSelect.tsx" -import { AccountSelect } from "./accountSelect.tsx" +import { BalanceSheetsSelect } from "../balanceSheets/BalanceSheetsSelect.tsx" +import { AccountSelect } from "./AccountSelect.tsx" export function CreateOneAccount(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx index 794ecba5..e6703772 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { balanceSheetLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx" -import { DeleteOneBalanceSheet } from "./deleteOneBalanceSheet.tsx" -import { UpdateOneBalanceSheet } from "./updateOneBalanceSheet.tsx" +import { DeleteOneBalanceSheet } from "./DeleteOneBalanceSheet.tsx" +import { UpdateOneBalanceSheet } from "./UpdateOneBalanceSheet.tsx" export function BalanceSheetLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx index 4c734497..9c375ee8 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { balanceSheetLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetPage.tsx index 3112b94d..1dbbdfe8 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetPage.tsx @@ -3,7 +3,7 @@ import { FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { balanceSheetLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/DeleteOneBalanceSheet.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/DeleteOneBalanceSheet.tsx index 278170f9..d5a502e9 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/DeleteOneBalanceSheet.tsx @@ -6,7 +6,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/UpdateOneBalanceSheet.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/UpdateOneBalanceSheet.tsx index 7d61245f..75dfa238 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/UpdateOneBalanceSheet.tsx @@ -10,16 +10,16 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" -import { BalanceSheetsSelect } from "../balanceSheetSelect.tsx" +import { BalanceSheetsSelect } from "../BalanceSheetsSelect.tsx" export function UpdateOneBalanceSheet(props: { balanceSheet: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetItem.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetItem.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetItem.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetItem.tsx index 80dcb70a..0c69a138 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetItem.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetItem.tsx @@ -1,7 +1,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { type ComponentProps, Fragment } from "react" import type * as v from "valibot" -import { BalanceSheetRow } from "./balanceSheetRow.tsx" +import { BalanceSheetRow } from "./BalanceSheetRow.tsx" import { getBalanceSheetChildren } from "./getBalanceSheetChildren.tsx" export function BalanceSheetItem(props: { diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetRow.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetRow.tsx index 459853e2..929ffda9 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetRow.tsx @@ -3,7 +3,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import type { ComponentProps } from "react" import type * as v from "valibot" import { ACCOUNT_ITEM_HEIGHT, INDENT_PER_LEVEL } from "../accounts/accountItem.tsx" -import { UpdateOneBalanceSheet } from "./$idBalanceSheet/updateOneBalanceSheet.tsx" +import { UpdateOneBalanceSheet } from "./$idBalanceSheet/UpdateOneBalanceSheet.tsx" export function BalanceSheetRow(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetTable.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetTable.tsx index 5e4a96e0..b54e5004 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetTable.tsx @@ -3,9 +3,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { css } from "@arrhes/ui/utilities/cn.js" import { IconScale } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" -import { BalanceSheetItem } from "./balanceSheetItem.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" +import { BalanceSheetItem } from "./BalanceSheetItem.tsx" import { getBalanceSheetChildren } from "./getBalanceSheetChildren.tsx" export function BalanceSheetTable(props: { diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.tsx index bdf875f5..64557d15 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.tsx @@ -3,12 +3,12 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus, IconScale } from "@tabler/icons-react" import { useParams, useRouterState } from "@tanstack/react-router" import { useCallback, useState, useTransition } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { BalanceSheetTable } from "./balanceSheetTable.tsx" -import { CreateOneBalanceSheet } from "./createOneBalanceSheet.tsx" +import { BalanceSheetTable } from "./BalanceSheetTable.tsx" +import { CreateOneBalanceSheet } from "./CreateOneBalanceSheet.tsx" export function BalanceSheetsPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetSelect.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsSelect.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetSelect.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsSelect.tsx diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/CreateOneBalanceSheet.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/CreateOneBalanceSheet.tsx index 0986313c..a6afae1a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/CreateOneBalanceSheet.tsx @@ -9,16 +9,16 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" -import { BalanceSheetsSelect } from "./balanceSheetSelect.tsx" +import { BalanceSheetsSelect } from "./BalanceSheetsSelect.tsx" export function CreateOneBalanceSheet(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx index cc696511..f9a25a71 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx @@ -6,7 +6,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx index c20a6212..ccda40f0 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { incomeStatementLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx" -import { DeleteOneIncomeStatement } from "./deleteOneIncomeStatement.tsx" -import { UpdateOneIncomeStatement } from "./updateOneIncomeStatement.tsx" +import { DeleteOneIncomeStatement } from "./DeleteOneIncomeStatement.tsx" +import { UpdateOneIncomeStatement } from "./UpdateOneIncomeStatement.tsx" export function IncomeStatementLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx index f73eae8a..d184436c 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { incomeStatementLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementPage.tsx index f5469c89..deb8776f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementPage.tsx @@ -3,7 +3,7 @@ import { FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { incomeStatementLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/UpdateOneIncomeStatement.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/UpdateOneIncomeStatement.tsx index 93bcad62..8628af9d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/UpdateOneIncomeStatement.tsx @@ -10,14 +10,14 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { InputDataCombobox } from "../../../../../../components/inputDataCombobox.tsx" -import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../components/forms/FormRoot.tsx" +import { InputDataCombobox } from "../../../../../../components/InputDataCombobox.tsx" +import { useTabs } from "../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/CreateOneIncomeStatement.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/CreateOneIncomeStatement.tsx index 085962ca..558e65f2 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/CreateOneIncomeStatement.tsx @@ -9,14 +9,14 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { InputDataCombobox } from "../../../../../components/inputDataCombobox.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { InputDataCombobox } from "../../../../../components/InputDataCombobox.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementItem.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementItem.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementItem.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementItem.tsx index 62d07e43..e607f1ba 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementItem.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementItem.tsx @@ -2,7 +2,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { type ComponentProps, Fragment } from "react" import type * as v from "valibot" import { getIncomeStatementChildren } from "./getIncomeStatementChildren.tsx" -import { IncomeStatementRow } from "./incomeStatementRow.tsx" +import { IncomeStatementRow } from "./IncomeStatementRow.tsx" export function IncomeStatementItem(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementRow.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementRow.tsx index 3b3a2b8f..83506a4e 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementRow.tsx @@ -3,7 +3,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import type { ComponentProps } from "react" import type * as v from "valibot" import { ACCOUNT_ITEM_HEIGHT, INDENT_PER_LEVEL } from "../accounts/accountItem.tsx" -import { UpdateOneIncomeStatement } from "./$idIncomeStatement/updateOneIncomeStatement.tsx" +import { UpdateOneIncomeStatement } from "./$idIncomeStatement/UpdateOneIncomeStatement.tsx" export function IncomeStatementRow(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsPage.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsPage.tsx index 2a584f8d..bf1c5c63 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsPage.tsx @@ -3,11 +3,11 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconCalculator, IconPlus, IconReportMoney } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { useCallback, useState, useTransition } from "react" -import { Box } from "../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../components/layouts/Box.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { CreateOneIncomeStatement } from "./createOneIncomeStatement.tsx" -import { IncomeStatementsTable } from "./incomeStatementsTable.tsx" +import { CreateOneIncomeStatement } from "./CreateOneIncomeStatement.tsx" +import { IncomeStatementsTable } from "./IncomeStatementsTable.tsx" export function IncomeStatementsPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsTable.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsTable.tsx index 7bb46afe..efd036a6 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsTable.tsx @@ -3,10 +3,10 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { css } from "@arrhes/ui/utilities/cn.js" import { IconReportMoney } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" import { getIncomeStatementChildren } from "./getIncomeStatementChildren.tsx" -import { IncomeStatementItem } from "./incomeStatementItem.tsx" +import { IncomeStatementItem } from "./IncomeStatementItem.tsx" export function IncomeStatementsTable(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationLayout.tsx index 1b6025e2..84b1c6d2 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconList, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../../components/LinkButton.tsx" import { computationLayoutRoute } from "../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx" -import { DeleteOneComputation } from "./deleteOneComputation.tsx" -import { UpdateOneComputation } from "./updateOneComputation.tsx" +import { DeleteOneComputation } from "./DeleteOneComputation.tsx" +import { UpdateOneComputation } from "./UpdateOneComputation.tsx" export function ComputationLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx index 7ee9628c..1133680f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../components/layouts/section/section.tsx" import { computationLayoutRoute } from "../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPage.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPage.tsx index 386e470b..a19bc9dd 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPage.tsx @@ -3,7 +3,7 @@ import { FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../components/layouts/section/section.tsx" import { computationLayoutRoute } from "../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPostesTab.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPostesTab.tsx index b34577bd..2c949490 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPostesTab.tsx @@ -3,11 +3,11 @@ import { ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../components/layouts/section/section.tsx" import { computationLayoutRoute } from "../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx" -import { ComputationIncomeStatementsTable } from "./computationIncomeStatements/computationIncomeStatementTable.tsx" -import { CreateOneComputationIncomeStatement } from "./computationIncomeStatements/createOneComputationIncomeStatement.tsx" +import { ComputationIncomeStatementsTable } from "./computationIncomeStatements/ComputationIncomeStatementsTable.tsx" +import { CreateOneComputationIncomeStatement } from "./computationIncomeStatements/CreateOneComputationIncomeStatement.tsx" export function ComputationPostesTab() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/deleteOneComputation.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/DeleteOneComputation.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/deleteOneComputation.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/DeleteOneComputation.tsx index e95244ea..5d96f17a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/deleteOneComputation.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/DeleteOneComputation.tsx @@ -6,7 +6,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/UpdateOneComputation.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/UpdateOneComputation.tsx index e728f3b1..742836f0 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/updateOneComputation.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/UpdateOneComputation.tsx @@ -10,13 +10,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx index 92e635f2..0971a5c7 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../../../../components/LinkButton.tsx" import { computationIncomeStatementLayoutRoute } from "../../../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx" -import { DeleteOneComputationIncomeStatement } from "./deleteOneComputationIncomeStatement.tsx" -import { UpdateOneComputationIncomeStatement } from "./updateOneComputationIncomeStatement.tsx" +import { DeleteOneComputationIncomeStatement } from "./DeleteOneComputationIncomeStatement.tsx" +import { UpdateOneComputationIncomeStatement } from "./UpdateOneComputationIncomeStatement.tsx" export function ComputationIncomeStatementLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx index 3030133a..0a1e4b3a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" import { computationIncomeStatementLayoutRoute } from "../../../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementPage.tsx index 4d6c5033..901267d9 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementPage.tsx @@ -6,7 +6,7 @@ import { Chip, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" import { computationIncomeStatementLayoutRoute } from "../../../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/DeleteOneComputationIncomeStatement.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/DeleteOneComputationIncomeStatement.tsx index b1cb1579..38975da3 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/DeleteOneComputationIncomeStatement.tsx @@ -6,7 +6,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/UpdateOneComputationIncomeStatement.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/UpdateOneComputationIncomeStatement.tsx index b70fcef4..ab0d0b14 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/UpdateOneComputationIncomeStatement.tsx @@ -11,14 +11,14 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../../../../components/forms/formRoot.tsx" -import { InputDataCombobox } from "../../../../../../../../../components/inputDataCombobox.tsx" -import { useTabs } from "../../../../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../../../../components/forms/FormRoot.tsx" +import { InputDataCombobox } from "../../../../../../../../../components/InputDataCombobox.tsx" +import { useTabs } from "../../../../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/computationIncomeStatementTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/computationIncomeStatementTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx index 58fe6999..f1c1cb22 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/computationIncomeStatementTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx @@ -6,9 +6,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { ButtonGhostContent, Chip, FormatDateTime, FormatText } from "@arrhes/ui" import { IconEye } from "@tabler/icons-react" import type * as v from "valibot" -import { DataTable } from "../../../../../../../../components/layouts/dataTable.tsx" -import { DataWrapper } from "../../../../../../../../components/layouts/dataWrapper.tsx" -import { LinkButton } from "../../../../../../../../components/linkButton.tsx" +import { DataTable } from "../../../../../../../../components/layouts/DataTable.tsx" +import { DataWrapper } from "../../../../../../../../components/layouts/DataWrapper.tsx" +import { LinkButton } from "../../../../../../../../components/LinkButton.tsx" export function ComputationIncomeStatementsTable(props: { computation: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/CreateOneComputationIncomeStatement.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/CreateOneComputationIncomeStatement.tsx index f165f10d..95cdd103 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/CreateOneComputationIncomeStatement.tsx @@ -10,14 +10,14 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../../../components/forms/formRoot.tsx" -import { InputDataCombobox } from "../../../../../../../../components/inputDataCombobox.tsx" -import { useTabs } from "../../../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../../../components/forms/FormRoot.tsx" +import { InputDataCombobox } from "../../../../../../../../components/InputDataCombobox.tsx" +import { useTabs } from "../../../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx index deb912b6..34409adc 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx @@ -2,12 +2,12 @@ import { ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCalculator, IconPlus, IconReportMoney } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { Box } from "../../../../../../components/layouts/box.tsx" +import { Box } from "../../../../../../components/layouts/Box.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { incomeStatementsLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx" -import { ComputationsTable } from "./computationsTable.tsx" -import { CreateOneComputation } from "./createOneComputation.tsx" +import { ComputationsTable } from "./ComputationsTable.tsx" +import { CreateOneComputation } from "./CreateOneComputation.tsx" export function ComputationsPage() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx index e5ef855a..5e01d433 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx @@ -3,9 +3,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCalculator } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../../components/layouts/emptyState.tsx" -import { LinkButton } from "../../../../../../components/linkButton.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../../components/layouts/EmptyState.tsx" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" export function ComputationsTable(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/CreateOneComputation.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/CreateOneComputation.tsx index ee4113fd..8de86bc8 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/createOneComputation.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/CreateOneComputation.tsx @@ -9,13 +9,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx index a4d03994..6b2bf3e3 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx @@ -3,7 +3,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx index 07dfe2fc..94063fe3 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { journalLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx" -import { DeleteOneJournal } from "./deleteOneJournal.tsx" -import { UpdateOneJournal } from "./updateOneJournal.tsx" +import { DeleteOneJournal } from "./DeleteOneJournal.tsx" +import { UpdateOneJournal } from "./UpdateOneJournal.tsx" export function JournalLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx index 9ba1d079..b02f0635 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { journalLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalPage.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalPage.tsx index aa7fea66..75ebfd19 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/journalPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalPage.tsx @@ -3,7 +3,7 @@ import { FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { journalLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/UpdateOneJournal.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/UpdateOneJournal.tsx index bd53185c..c3f8ee4b 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/updateOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/UpdateOneJournal.tsx @@ -10,13 +10,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/CreateOneJournal.tsx similarity index 93% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/CreateOneJournal.tsx index 8044972a..8020cc48 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/createOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/CreateOneJournal.tsx @@ -6,13 +6,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalListTableRow.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalListTableRow.tsx index c6c7f682..041fef62 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalListTableRow.tsx @@ -3,7 +3,7 @@ import { Chip, formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { UpdateOneJournal } from "./$idJournal/updateOneJournal.tsx" +import { UpdateOneJournal } from "./$idJournal/UpdateOneJournal.tsx" export function JournalListTableRow(props: { journal: v.InferOutput }) { const createdAt = formatDate(props.journal.createdAt) diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalSelect.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalSelect.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalSelect.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalSelect.tsx diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalsListTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalsListTable.tsx similarity index 89% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalsListTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalsListTable.tsx index 9418c8ed..41745445 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalsListTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalsListTable.tsx @@ -2,10 +2,10 @@ import { readAllJournalsRouteDefinition } from "@arrhes/application-metadata/rou import type { schemas } from "@arrhes/application-metadata/schemas" import { IconBook } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { JournalListTableRow } from "./journalListTableRow.tsx" +import { JournalListTableRow } from "./JournalListTableRow.tsx" export function JournalsListTable(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalsPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalsPage.tsx index 5180c751..d77b6c91 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/journalsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/JournalsPage.tsx @@ -4,8 +4,8 @@ import { IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { CreateOneJournal } from "./createOneJournal.tsx" -import { JournalsListTable } from "./journalsListTable.tsx" +import { CreateOneJournal } from "./CreateOneJournal.tsx" +import { JournalsListTable } from "./JournalsListTable.tsx" export function JournalsPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/deleteOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/deleteOneTag.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx index f31113b0..c73c4755 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/deleteOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx @@ -3,7 +3,7 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { toast } from "@arrhes/ui" import type { ComponentPropsWithRef, ReactElement } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/confirmationModal.tsx" +import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx similarity index 96% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagLayout.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx index 7a16b0f3..237d6c47 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx @@ -3,13 +3,13 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { tagLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx" -import { DeleteOneTag } from "./deleteOneTag.tsx" -import { UpdateOneTag } from "./updateOneTag.tsx" +import { DeleteOneTag } from "./DeleteOneTag.tsx" +import { UpdateOneTag } from "./UpdateOneTag.tsx" export function TagLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx similarity index 99% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagMetadataTab.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx index c7c6c4ad..71af086d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx @@ -3,7 +3,7 @@ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { tagLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagPage.tsx similarity index 98% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagPage.tsx index f729a8aa..07e30f57 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/tagPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagPage.tsx @@ -3,7 +3,7 @@ import { FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { DataWrapper } from "../../../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { tagLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/UpdateOneTag.tsx similarity index 93% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/UpdateOneTag.tsx index 4713150f..a4ccf075 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/updateOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/UpdateOneTag.tsx @@ -10,13 +10,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/CreateOneTag.tsx similarity index 91% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/CreateOneTag.tsx index 44ea320b..60fcb433 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/createOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/CreateOneTag.tsx @@ -6,13 +6,13 @@ import { IconPlus } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../../components/forms/formError.tsx" -import { FormField } from "../../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagListTableRow.tsx similarity index 97% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagListTableRow.tsx index 95abda3a..cc1867bf 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagListTableRow.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagListTableRow.tsx @@ -3,7 +3,7 @@ import { formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { UpdateOneTag } from "./$idTag/updateOneTag.tsx" +import { UpdateOneTag } from "./$idTag/UpdateOneTag.tsx" export function TagListTableRow(props: { tag: v.InferOutput }) { const createdAt = formatDate(props.tag.createdAt) diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagSelect.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagSelect.tsx similarity index 100% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagSelect.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagSelect.tsx diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagsListTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagsListTable.tsx similarity index 89% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagsListTable.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagsListTable.tsx index 65983af2..8e3e50a3 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagsListTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagsListTable.tsx @@ -2,10 +2,10 @@ import { readAllTagsRouteDefinition } from "@arrhes/application-metadata/routes" import type { schemas } from "@arrhes/application-metadata/schemas" import { IconTag } from "@tabler/icons-react" import type * as v from "valibot" -import { DataWrapper } from "../../../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../../../components/layouts/listTable/listTable.tsx" -import { TagListTableRow } from "./tagListTableRow.tsx" +import { TagListTableRow } from "./TagListTableRow.tsx" export function TagsListTable(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagsPage.tsx similarity index 95% rename from packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagsPage.tsx rename to packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagsPage.tsx index 0c499821..81cbfebf 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/tagsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/TagsPage.tsx @@ -4,8 +4,8 @@ import { IconPlus } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { CreateOneTag } from "./createOneTag.tsx" -import { TagsListTable } from "./tagsListTable.tsx" +import { CreateOneTag } from "./CreateOneTag.tsx" +import { TagsListTable } from "./TagsListTable.tsx" export function TagsPage({ idOrganization: idOrganizationProp, diff --git a/packages/website/src/features/dashboard/dashboardDefaultPage.tsx b/packages/website/src/features/dashboard/DashboardDefaultPage.tsx similarity index 100% rename from packages/website/src/features/dashboard/dashboardDefaultPage.tsx rename to packages/website/src/features/dashboard/DashboardDefaultPage.tsx diff --git a/packages/website/src/features/dashboard/dashboardNotFoundPage.tsx b/packages/website/src/features/dashboard/DashboardNotFoundPage.tsx similarity index 96% rename from packages/website/src/features/dashboard/dashboardNotFoundPage.tsx rename to packages/website/src/features/dashboard/DashboardNotFoundPage.tsx index 2d52a83e..49407951 100644 --- a/packages/website/src/features/dashboard/dashboardNotFoundPage.tsx +++ b/packages/website/src/features/dashboard/DashboardNotFoundPage.tsx @@ -1,7 +1,7 @@ -import { ButtonOutlineContent } from "@arrhes/ui/components/buttons/buttonOutlineContent.js" +import { ButtonOutlineContent } from "@arrhes/ui/components/buttons/ButtonOutlineContent.js" import { css } from "@arrhes/ui/utilities/cn.js" import { IconHome } from "@tabler/icons-react" -import { LinkButton } from "../../components/linkButton.js" +import { LinkButton } from "../../components/LinkButton.js" export function DashboardNotFoundPage() { return ( diff --git a/packages/website/src/features/dashboard/OrganizationContextSelect.tsx b/packages/website/src/features/dashboard/OrganizationContextSelect.tsx index c4d1edf8..d299360f 100644 --- a/packages/website/src/features/dashboard/OrganizationContextSelect.tsx +++ b/packages/website/src/features/dashboard/OrganizationContextSelect.tsx @@ -1,13 +1,14 @@ import { Button, ButtonGhostContent, ButtonPlainContent, Separator } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" +import { IconChevronDown } from "@tabler/icons-react" import { getAllMyOrganizationsRouteDefinition } from "../../../../metadata/src/routes/dashboard/auth/index.js" import { Popover } from "../../components/overlays/popover/popover.js" -import { useTabs } from "../../contexts/tabs/tabsContext.js" import { useDataFromAPI } from "../../utilities/useHTTPData.js" +import { useState } from "react" +import { AddNewOrganization } from "./organizations/AddNewOrganization.js" export function OrganizationContextSelect(props: { value: string | null; onChange: (v: string | null) => void }) { - const { openTab } = useTabs() - + const [open, setOpen] = useState(false) const organizationUsersData = useDataFromAPI({ routeDefinition: getAllMyOrganizationsRouteDefinition, body: {}, @@ -21,26 +22,20 @@ export function OrganizationContextSelect(props: { value: string | null; onChang if (options.length === 0) { return ( - + ) } return ( - + @@ -57,11 +52,13 @@ export function OrganizationContextSelect(props: { value: string | null; onChang {options.map((option) => ( + > + + + ) diff --git a/packages/website/src/features/dashboard/YearContextSelect.tsx b/packages/website/src/features/dashboard/YearContextSelect.tsx index 7f0df3ff..da1580e2 100644 --- a/packages/website/src/features/dashboard/YearContextSelect.tsx +++ b/packages/website/src/features/dashboard/YearContextSelect.tsx @@ -1,17 +1,18 @@ import { readAllYearsRouteDefinition } from "@arrhes/application-metadata" import { Button, ButtonGhostContent, ButtonPlainContent, Separator } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" +import { IconChevronDown } from "@tabler/icons-react" +import { useState } from "react" import { Popover } from "../../components/overlays/popover/popover.js" -import { useTabs } from "../../contexts/tabs/tabsContext.js" import { useDataFromAPI } from "../../utilities/useHTTPData.js" +import { CreateOneYear } from "./$idOrganization/years/CreateOneYear.js" export function YearContextSelect(props: { value: string | null onChange: (v: string | null) => void idOrganizationSelected: string | null }) { - const { openTab } = useTabs() - + const [open, setOpen] = useState(false) const yearsData = useDataFromAPI({ routeDefinition: readAllYearsRouteDefinition, body: { idOrganization: props.idOrganizationSelected ?? undefined }, @@ -28,30 +29,22 @@ export function YearContextSelect(props: { const selectedLabel = options.find((option) => option.key === props.value)?.label if (options.length === 0) { + if (!props.idOrganizationSelected) return null return ( - + ) } return ( - + @@ -68,11 +61,13 @@ export function YearContextSelect(props: { {options.map((option) => ( + {props.idOrganizationSelected !== null && ( +
setOpen(false)}> + + + +
+ )}
) diff --git a/packages/website/src/features/dashboard/admin/adminPanelLayout.tsx b/packages/website/src/features/dashboard/admin/AdminPanelLayout.tsx similarity index 100% rename from packages/website/src/features/dashboard/admin/adminPanelLayout.tsx rename to packages/website/src/features/dashboard/admin/AdminPanelLayout.tsx diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/AdminTicketTabContent.tsx similarity index 94% rename from packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx rename to packages/website/src/features/dashboard/admin/tickets/$idTicket/AdminTicketTabContent.tsx index 9f0198d1..1a5de001 100644 --- a/packages/website/src/features/dashboard/admin/tickets/$idTicket/adminTicketTabContent.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/$idTicket/AdminTicketTabContent.tsx @@ -2,8 +2,8 @@ import { adminReadOneTicketRouteDefinition } from "@arrhes/application-metadata/ import { CircularLoader } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useDataFromAPI } from "../../../../../utilities/useHTTPData.js" -import { StatusToggle } from "./statusToggle.js" -import { TicketPage } from "./ticketPage.js" +import { StatusToggle } from "./StatusToggle.js" +import { TicketPage } from "./TicketPage.js" export function AdminTicketTabContent(props: { idTicket: string }) { const ticket = useDataFromAPI({ diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/createOneTicketMessage.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/CreateOneTicketMessage.tsx similarity index 100% rename from packages/website/src/features/dashboard/admin/tickets/$idTicket/createOneTicketMessage.tsx rename to packages/website/src/features/dashboard/admin/tickets/$idTicket/CreateOneTicketMessage.tsx diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/statusToggle.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/StatusToggle.tsx similarity index 100% rename from packages/website/src/features/dashboard/admin/tickets/$idTicket/statusToggle.tsx rename to packages/website/src/features/dashboard/admin/tickets/$idTicket/StatusToggle.tsx diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketLayout.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx similarity index 95% rename from packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketLayout.tsx rename to packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx index f0be3365..1bc29268 100644 --- a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketLayout.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx @@ -3,10 +3,10 @@ import { ButtonGhostContent, CircularLoader } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconArrowLeft } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { LinkButton } from "../../../../../components/linkButton.js" +import { LinkButton } from "../../../../../components/LinkButton.js" import { $idTicketLayoutRoute } from "../../../../../routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx" import { useDataFromAPI } from "../../../../../utilities/useHTTPData.js" -import { StatusToggle } from "./statusToggle.js" +import { StatusToggle } from "./StatusToggle.js" export function TicketLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketMessageList.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketMessageList.tsx similarity index 100% rename from packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketMessageList.tsx rename to packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketMessageList.tsx diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketPage.tsx similarity index 98% rename from packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx rename to packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketPage.tsx index af699a5b..fe8043f0 100644 --- a/packages/website/src/features/dashboard/admin/tickets/$idTicket/ticketPage.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketPage.tsx @@ -8,8 +8,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconCheck } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { useDataFromAPI } from "../../../../../utilities/useHTTPData.js" -import { CreateOneTicketMessage } from "./createOneTicketMessage.js" -import { TicketMessageList } from "./ticketMessageList.js" +import { CreateOneTicketMessage } from "./CreateOneTicketMessage.js" +import { TicketMessageList } from "./TicketMessageList.js" const statusLabels: Record = { open: "Ouvert", diff --git a/packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx b/packages/website/src/features/dashboard/admin/tickets/TicketsPage.tsx similarity index 65% rename from packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx rename to packages/website/src/features/dashboard/admin/tickets/TicketsPage.tsx index 3367142c..a871ba8e 100644 --- a/packages/website/src/features/dashboard/admin/tickets/ticketsPage.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/TicketsPage.tsx @@ -3,7 +3,8 @@ import { Badge, Button, CircularLoader, formatDate } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconExternalLink } from "@tabler/icons-react" import type * as v from "valibot" -import { TabLink } from "../../../../components/layouts/tabBar/tabLink.js" +import { Page } from "../../../../components/layouts/page/page.js" +import { TabLink } from "../../../../components/layouts/tabBar/TabLink.js" import { useDataFromAPI } from "../../../../utilities/useHTTPData.js" const statusLabels: Record = { @@ -94,8 +95,8 @@ function TicketRow(props: { ticket: Ticket }) { })}`} {ticket.lastUpdatedAt ? ` - Mis a jour le ${formatDate(ticket.lastUpdatedAt, { - includeTime: true, - })}` + includeTime: true, + })}` : ""} @@ -119,80 +120,68 @@ export function TicketsPage() { }) return ( -
-

- Tickets -

+ + + Tickets + + + {tickets.isPending && } - {tickets.isPending && } + {tickets.isError && ( +
+ + Erreur lors de la recuperation des tickets. + +
+ )} - {tickets.isError && ( -
+ {tickets.data && tickets.data.length === 0 && ( - Erreur lors de la recuperation des tickets. + Aucun ticket pour le moment. -
- )} - - {tickets.data && tickets.data.length === 0 && ( - - Aucun ticket pour le moment. - - )} + )} - {tickets.data && tickets.data.length > 0 && ( -
- {[ - ...tickets.data, - ] - .sort((a, b) => b.createdAt.localeCompare(a.createdAt)) - .map((ticket) => ( - - ))} -
- )} -
+ {tickets.data && tickets.data.length > 0 && ( +
+ {[ + ...tickets.data, + ] + .sort((a, b) => b.createdAt.localeCompare(a.createdAt)) + .map((ticket) => ( + + ))} +
+ )} + + ) } diff --git a/packages/website/src/features/dashboard/dashboardLayout.tsx b/packages/website/src/features/dashboard/dashboardLayout.tsx deleted file mode 100644 index ad748527..00000000 --- a/packages/website/src/features/dashboard/dashboardLayout.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { TabsProvider } from "../../contexts/tabs/tabsProvider.js" -import { DashboardShell } from "./dashboardShell.js" - -export function DashboardLayout() { - return ( - - - - ) -} diff --git a/packages/website/src/features/dashboard/dashboardLayout/DashboardLayout.tsx b/packages/website/src/features/dashboard/dashboardLayout/DashboardLayout.tsx new file mode 100644 index 00000000..39dbddc0 --- /dev/null +++ b/packages/website/src/features/dashboard/dashboardLayout/DashboardLayout.tsx @@ -0,0 +1,14 @@ +import { DashboardContextProvider } from "../../../contexts/dashboard/DashboardContextProvider.js" +import { TabsProvider } from "../../../contexts/tabs/tabsProvider.tsx" +import { DashboardShell } from "./DashboardShell.tsx" + + +export function DashboardLayout() { + return ( + + + + + + ) +} diff --git a/packages/website/src/features/dashboard/dashboardShell.tsx b/packages/website/src/features/dashboard/dashboardLayout/DashboardShell.tsx similarity index 77% rename from packages/website/src/features/dashboard/dashboardShell.tsx rename to packages/website/src/features/dashboard/dashboardLayout/DashboardShell.tsx index bbf3c5f3..f2bdd05c 100644 --- a/packages/website/src/features/dashboard/dashboardShell.tsx +++ b/packages/website/src/features/dashboard/dashboardLayout/DashboardShell.tsx @@ -1,6 +1,7 @@ import { readUserSessionRouteDefinition, signOutRouteDefinition } from "@arrhes/application-metadata/routes" import { Button, ButtonGhostContent, ButtonOutlineContent, Logo, Separator, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" +import { useDashboardContext } from "../../../contexts/dashboard/dashboardContext.js" import { IconBook2, IconLifebuoy, @@ -13,29 +14,25 @@ import { } from "@tabler/icons-react" import { Outlet } from "@tanstack/react-router" import { useCallback, useEffect, useRef, useState } from "react" -import { CommandPalette } from "../../components/layouts/commandPalette/commandPalette.js" -import { SplitTabBar } from "../../components/layouts/tabBar/splitTabBar.js" -import { TabBar } from "../../components/layouts/tabBar/tabBar.js" -import { Popover } from "../../components/overlays/popover/popover.js" -import { type ComponentTab, currentEntry, useTabs } from "../../contexts/tabs/tabsContext.js" -import { TabContentArea } from "../../contexts/tabs/tabsProvider.js" -import { useOuterRouter } from "../../contexts/tabs/useOuterRouter.js" -import { deleteCookies } from "../../utilities/cookies/deleteCookies.js" -import { setCookie } from "../../utilities/cookies/setCookie.js" -import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" -import { useDataFromAPI } from "../../utilities/useHTTPData.js" -import { cookiePrefix } from "../../utilities/variables.js" -import { OrganizationContextSelect } from "./OrganizationContextSelect.js" -import { YearContextSelect } from "./YearContextSelect.js" - -const SELECTED_ORG_KEY = "arrhes:context-org" -const SELECTED_YEAR_KEY = "arrhes:context-year" +import { CommandPalette } from "../../../components/layouts/commandPalette/CommandPalette.js" +import { TabBar } from "../../../components/layouts/tabBar/TabBar.js" +import { Popover } from "../../../components/overlays/popover/popover.js" +import { type ComponentTab, currentEntry } from "../../../contexts/tabs/tabsContext.js" +import { useTabs } from "../../../contexts/tabs/useTabs.js" +import { TabContentArea } from "../../../contexts/tabs/TabContentArea.js" +import { useOuterRouter } from "../../../contexts/tabs/useOuterRouter.js" +import { deleteCookies } from "../../../utilities/cookies/deleteCookies.js" +import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.js" +import { useDataFromAPI } from "../../../utilities/useHTTPData.js" +import { OrganizationContextSelect } from "../OrganizationContextSelect.js" +import { YearContextSelect } from "../YearContextSelect.js" // ─── Inner shell — rendered inside TabsProvider ────────────────────────────── export function DashboardShell() { const { tabs, activeTabId, activateTab, openTab, reorderTabs, closeTab } = useTabs() const applicationRouter = useOuterRouter() + const { selectedOrgId, selectedYearId, setOrg, setYear } = useDashboardContext() const [splitPosition, setSplitPosition] = useState(50) const containerRef = useRef(null) const isDragging = useRef(false) @@ -84,22 +81,6 @@ export function DashboardShell() { tabIds: string[] activeTabId: string } | null>(null) - const [selectedOrgId, setSelectedOrgId] = useState(() => { - try { - const id = localStorage.getItem(SELECTED_ORG_KEY) ?? null - if (id !== null) setCookie(`${cookiePrefix}_id_organization`, id) - return id - } catch { - return null - } - }) - const [selectedYearId, setSelectedYearId] = useState(() => { - try { - return localStorage.getItem(SELECTED_YEAR_KEY) ?? null - } catch { - return null - } - }) // Listen for split-tab events dispatched from the tab bar context menu. const handleSplitTab = useCallback( @@ -179,24 +160,11 @@ export function DashboardShell() { ]) function handleOrgChange(id: string | null) { - setSelectedOrgId(id) - try { - if (id !== null) localStorage.setItem(SELECTED_ORG_KEY, id) - else localStorage.removeItem(SELECTED_ORG_KEY) - } catch {} - if (id !== null) setCookie(`${cookiePrefix}_id_organization`, id) - setSelectedYearId(null) - try { - localStorage.removeItem(SELECTED_YEAR_KEY) - } catch {} + setOrg(id) } function handleYearChange(id: string | null) { - setSelectedYearId(id) - try { - if (id !== null) localStorage.setItem(SELECTED_YEAR_KEY, id) - else localStorage.removeItem(SELECTED_YEAR_KEY) - } catch {} + setYear(id) } const userSession = useDataFromAPI({ @@ -497,11 +465,11 @@ export function DashboardShell() { return next.length === 0 ? null : { - tabIds: next, - activeTabId: next.includes(prev.activeTabId) - ? prev.activeTabId - : next[next.length - 1], - } + tabIds: next, + activeTabId: next.includes(prev.activeTabId) + ? prev.activeTabId + : next[next.length - 1], + } }) reorderTabs(tabId, insertBeforeTabId) activateTab(tabId) @@ -540,61 +508,61 @@ export function DashboardShell() { overflow: "hidden", }} > - - setRightPanel( - (prev) => - prev && { - ...prev, - activeTabId: tabId, - }, - ) - } - onRemove={(tabId) => { - setRightPanel((prev) => { - if (!prev) return null - const next = prev.tabIds.filter((id) => id !== tabId) - if (next.length === 0) { - closeTab(tabId) - return null - } - const newActive = - prev.activeTabId === tabId ? next[next.length - 1] : prev.activeTabId - return { - tabIds: next, - activeTabId: newActive, - } - }) + setRightPanel(null)} + panel={{ + tabIds: rightPanel.tabIds, + activeTabId: rightPanel.activeTabId, + onActivate: (tabId) => + setRightPanel( + (prev) => + prev && { + ...prev, + activeTabId: tabId, + }, + ), + onRemove: (tabId) => { + setRightPanel((prev) => { + if (!prev) return null + const next = prev.tabIds.filter((id) => id !== tabId) + if (next.length === 0) { + closeTab(tabId) + return null + } + const newActive = + prev.activeTabId === tabId ? next[next.length - 1] : prev.activeTabId + return { + tabIds: next, + activeTabId: newActive, + } + }) + }, + onReorder: (tabId, insertBeforeTabId) => + setRightPanel((prev) => { + if (!prev) return null + const without = prev.tabIds.filter((id) => id !== tabId) + if (insertBeforeTabId === null) + return { ...prev, tabIds: [...without, tabId] } + const idx = without.indexOf(insertBeforeTabId) + const tabIds = + idx === -1 + ? [...without, tabId] + : [...without.slice(0, idx), tabId, ...without.slice(idx)] + return { ...prev, tabIds } + }), + onDropFromLeft: (tabId, insertBeforeTabId) => + setRightPanel((prev) => { + const existing = prev?.tabIds.filter((id) => id !== tabId) ?? [] + if (insertBeforeTabId === null) + return { tabIds: [...existing, tabId], activeTabId: tabId } + const idx = existing.indexOf(insertBeforeTabId) + const tabIds = + idx === -1 + ? [...existing, tabId] + : [...existing.slice(0, idx), tabId, ...existing.slice(idx)] + return { tabIds, activeTabId: tabId } + }), }} - onReorder={(tabId, insertBeforeTabId) => - setRightPanel((prev) => { - if (!prev) return null - const without = prev.tabIds.filter((id) => id !== tabId) - if (insertBeforeTabId === null) - return { ...prev, tabIds: [...without, tabId] } - const idx = without.indexOf(insertBeforeTabId) - const tabIds = - idx === -1 - ? [...without, tabId] - : [...without.slice(0, idx), tabId, ...without.slice(idx)] - return { ...prev, tabIds } - }) - } - onDropFromLeft={(tabId, insertBeforeTabId) => - setRightPanel((prev) => { - const existing = prev?.tabIds.filter((id) => id !== tabId) ?? [] - if (insertBeforeTabId === null) - return { tabIds: [...existing, tabId], activeTabId: tabId } - const idx = existing.indexOf(insertBeforeTabId) - const tabIds = - idx === -1 - ? [...existing, tabId] - : [...existing.slice(0, idx), tabId, ...existing.slice(idx)] - return { tabIds, activeTabId: tabId } - }) - } /> { const r = { current: "", diff --git a/packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx b/packages/website/src/features/dashboard/organizations/OrganizationListTableRow.tsx similarity index 98% rename from packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx rename to packages/website/src/features/dashboard/organizations/OrganizationListTableRow.tsx index 9b2f1fdf..4d730450 100644 --- a/packages/website/src/features/dashboard/organizations/organizationListTableRow.tsx +++ b/packages/website/src/features/dashboard/organizations/OrganizationListTableRow.tsx @@ -3,7 +3,7 @@ import { Button, Chip, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../components/layouts/listTable/listTable.tsx" -import { TabLink } from "../../../components/layouts/tabBar/tabLink.js" +import { TabLink } from "../../../components/layouts/tabBar/TabLink.js" export function OrganizationListTableRow(props: { organizationUser: v.InferOutput[number] diff --git a/packages/website/src/features/dashboard/organizations/organizationsListTable.tsx b/packages/website/src/features/dashboard/organizations/OrganizationsListTable.tsx similarity index 87% rename from packages/website/src/features/dashboard/organizations/organizationsListTable.tsx rename to packages/website/src/features/dashboard/organizations/OrganizationsListTable.tsx index aed037fe..65eca163 100644 --- a/packages/website/src/features/dashboard/organizations/organizationsListTable.tsx +++ b/packages/website/src/features/dashboard/organizations/OrganizationsListTable.tsx @@ -1,9 +1,9 @@ import { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata/routes" import { IconBuilding } from "@tabler/icons-react" -import { DataWrapper } from "../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../components/layouts/listTable/listTable.tsx" -import { OrganizationListTableRow } from "./organizationListTableRow.tsx" +import { OrganizationListTableRow } from "./OrganizationListTableRow.tsx" export function OrganizationsListTable() { return ( diff --git a/packages/website/src/features/dashboard/organizations/organizationsPage.tsx b/packages/website/src/features/dashboard/organizations/OrganizationsPage.tsx similarity index 90% rename from packages/website/src/features/dashboard/organizations/organizationsPage.tsx rename to packages/website/src/features/dashboard/organizations/OrganizationsPage.tsx index 78cf69ae..8124833c 100644 --- a/packages/website/src/features/dashboard/organizations/organizationsPage.tsx +++ b/packages/website/src/features/dashboard/organizations/OrganizationsPage.tsx @@ -2,8 +2,8 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBuildingPlus } from "@tabler/icons-react" import { Page } from "../../../components/layouts/page/page.tsx" -import { AddNewOrganization } from "./addNewOrganization.tsx" -import { OrganizationsListTable } from "./organizationsListTable.tsx" +import { AddNewOrganization } from "./AddNewOrganization.tsx" +import { OrganizationsListTable } from "./OrganizationsListTable.tsx" export function OrganizationsPage() { return ( diff --git a/packages/website/src/features/dashboard/profile/deleteUser.tsx b/packages/website/src/features/dashboard/profile/DeleteUser.tsx similarity index 91% rename from packages/website/src/features/dashboard/profile/deleteUser.tsx rename to packages/website/src/features/dashboard/profile/DeleteUser.tsx index 257928c4..dcb13609 100644 --- a/packages/website/src/features/dashboard/profile/deleteUser.tsx +++ b/packages/website/src/features/dashboard/profile/DeleteUser.tsx @@ -3,13 +3,13 @@ import { Button, InputPassword, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconTrash } from "@tabler/icons-react" import type { JSX } from "react" -import { FormControl } from "../../../components/forms/formControl.tsx" -import { FormError } from "../../../components/forms/formError.tsx" -import { FormField } from "../../../components/forms/formField.tsx" -import { FormItem } from "../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../components/forms/FormControl.tsx" +import { FormError } from "../../../components/forms/FormError.tsx" +import { FormField } from "../../../components/forms/FormField.tsx" +import { FormItem } from "../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../contexts/tabs/useTabs.tsx" import { applicationRouter } from "../../../routes/applicationRouter.tsx" import { deleteCookies } from "../../../utilities/cookies/deleteCookies.ts" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" diff --git a/packages/website/src/features/dashboard/profile/updateUserEmail.tsx b/packages/website/src/features/dashboard/profile/UpdateUserEmail.tsx similarity index 93% rename from packages/website/src/features/dashboard/profile/updateUserEmail.tsx rename to packages/website/src/features/dashboard/profile/UpdateUserEmail.tsx index df91cf3f..02ecec2e 100644 --- a/packages/website/src/features/dashboard/profile/updateUserEmail.tsx +++ b/packages/website/src/features/dashboard/profile/UpdateUserEmail.tsx @@ -4,13 +4,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconDeviceFloppy } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" -import { FormControl } from "../../../components/forms/formControl.tsx" -import { FormError } from "../../../components/forms/formError.tsx" -import { FormField } from "../../../components/forms/formField.tsx" -import { FormItem } from "../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../components/forms/FormControl.tsx" +import { FormError } from "../../../components/forms/FormError.tsx" +import { FormField } from "../../../components/forms/FormField.tsx" +import { FormItem } from "../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/profile/updateUserPassword.tsx b/packages/website/src/features/dashboard/profile/UpdateUserPassword.tsx similarity index 93% rename from packages/website/src/features/dashboard/profile/updateUserPassword.tsx rename to packages/website/src/features/dashboard/profile/UpdateUserPassword.tsx index 447a9ce6..fc4a38e6 100644 --- a/packages/website/src/features/dashboard/profile/updateUserPassword.tsx +++ b/packages/website/src/features/dashboard/profile/UpdateUserPassword.tsx @@ -4,13 +4,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconDeviceFloppy } from "@tabler/icons-react" import type { JSX } from "react" import { Fragment } from "react/jsx-runtime" -import { FormControl } from "../../../components/forms/formControl.tsx" -import { FormError } from "../../../components/forms/formError.tsx" -import { FormField } from "../../../components/forms/formField.tsx" -import { FormItem } from "../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../components/forms/FormControl.tsx" +import { FormError } from "../../../components/forms/FormError.tsx" +import { FormField } from "../../../components/forms/FormField.tsx" +import { FormItem } from "../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" export function UpdateUserPassword(props: { children: JSX.Element }) { diff --git a/packages/website/src/features/dashboard/profile/userProfilePage.tsx b/packages/website/src/features/dashboard/profile/UserProfilePage.tsx similarity index 93% rename from packages/website/src/features/dashboard/profile/userProfilePage.tsx rename to packages/website/src/features/dashboard/profile/UserProfilePage.tsx index 1febdd47..21d53235 100644 --- a/packages/website/src/features/dashboard/profile/userProfilePage.tsx +++ b/packages/website/src/features/dashboard/profile/UserProfilePage.tsx @@ -1,13 +1,13 @@ import { readUserSessionRouteDefinition } from "@arrhes/application-metadata/routes" import { Button, ButtonOutlineContent } from "@arrhes/ui" import { IconKey, IconMail, IconTrash } from "@tabler/icons-react" -import { DataWrapper } from "../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../components/layouts/page/page.js" import { SettingsSection } from "../../../components/layouts/settingsSection/settingsSection.tsx" -import { DeleteUser } from "./deleteUser.tsx" -import { UpdateUserEmail } from "./updateUserEmail.tsx" -import { UpdateUserPassword } from "./updateUserPassword.tsx" -import { ValidateUserEmail } from "./validateUserEmail.tsx" +import { DeleteUser } from "./DeleteUser.tsx" +import { UpdateUserEmail } from "./UpdateUserEmail.tsx" +import { UpdateUserPassword } from "./UpdateUserPassword.tsx" +import { ValidateUserEmail } from "./ValidateUserEmail.tsx" export function UserProfilePage() { return ( diff --git a/packages/website/src/features/dashboard/profile/validateUserEmail.tsx b/packages/website/src/features/dashboard/profile/ValidateUserEmail.tsx similarity index 100% rename from packages/website/src/features/dashboard/profile/validateUserEmail.tsx rename to packages/website/src/features/dashboard/profile/ValidateUserEmail.tsx diff --git a/packages/website/src/features/dashboard/settings/settingsPage.tsx b/packages/website/src/features/dashboard/settings/SettingsPage.tsx similarity index 100% rename from packages/website/src/features/dashboard/settings/settingsPage.tsx rename to packages/website/src/features/dashboard/settings/SettingsPage.tsx diff --git a/packages/website/src/features/dashboard/support/$idTicket/createOneTicketMessage.tsx b/packages/website/src/features/dashboard/support/$idTicket/CreateOneTicketMessage.tsx similarity index 89% rename from packages/website/src/features/dashboard/support/$idTicket/createOneTicketMessage.tsx rename to packages/website/src/features/dashboard/support/$idTicket/CreateOneTicketMessage.tsx index 1c986e15..358cd7be 100644 --- a/packages/website/src/features/dashboard/support/$idTicket/createOneTicketMessage.tsx +++ b/packages/website/src/features/dashboard/support/$idTicket/CreateOneTicketMessage.tsx @@ -7,12 +7,12 @@ import { InputTextArea, toast } from "@arrhes/ui" import { IconSend } from "@tabler/icons-react" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { FormControl } from "../../../../components/forms/formControl.tsx" -import { FormError } from "../../../../components/forms/formError.tsx" -import { FormField } from "../../../../components/forms/formField.tsx" -import { FormItem } from "../../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../../components/forms/formRoot.tsx" +import { FormControl } from "../../../../components/forms/FormControl.tsx" +import { FormError } from "../../../../components/forms/FormError.tsx" +import { FormField } from "../../../../components/forms/FormField.tsx" +import { FormItem } from "../../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../../components/forms/FormRoot.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/support/$idTicket/statusToggle.tsx b/packages/website/src/features/dashboard/support/$idTicket/StatusToggle.tsx similarity index 100% rename from packages/website/src/features/dashboard/support/$idTicket/statusToggle.tsx rename to packages/website/src/features/dashboard/support/$idTicket/StatusToggle.tsx diff --git a/packages/website/src/features/dashboard/support/$idTicket/ticketLayout.tsx b/packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx similarity index 94% rename from packages/website/src/features/dashboard/support/$idTicket/ticketLayout.tsx rename to packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx index 9f4ca7ce..88e5a6b7 100644 --- a/packages/website/src/features/dashboard/support/$idTicket/ticketLayout.tsx +++ b/packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx @@ -3,12 +3,12 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { Section } from "../../../../components/layouts/section/section.tsx" -import { LinkButton } from "../../../../components/linkButton.tsx" +import { LinkButton } from "../../../../components/LinkButton.tsx" import { ticketLayoutRoute } from "../../../../routes/root/dashboard/support/ticketLayoutRoute.tsx" -import { StatusToggle } from "./statusToggle.tsx" +import { StatusToggle } from "./StatusToggle.tsx" export function TicketLayout() { const params = useParams({ diff --git a/packages/website/src/features/dashboard/support/$idTicket/ticketMessageList.tsx b/packages/website/src/features/dashboard/support/$idTicket/TicketMessageList.tsx similarity index 100% rename from packages/website/src/features/dashboard/support/$idTicket/ticketMessageList.tsx rename to packages/website/src/features/dashboard/support/$idTicket/TicketMessageList.tsx diff --git a/packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx b/packages/website/src/features/dashboard/support/$idTicket/TicketPage.tsx similarity index 97% rename from packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx rename to packages/website/src/features/dashboard/support/$idTicket/TicketPage.tsx index d54fdb8e..7348d32d 100644 --- a/packages/website/src/features/dashboard/support/$idTicket/ticketPage.tsx +++ b/packages/website/src/features/dashboard/support/$idTicket/TicketPage.tsx @@ -2,11 +2,11 @@ import { readAllTicketMessagesRouteDefinition, readOneTicketRouteDefinition } fr import { Chip, formatDate, Separator } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { Banner } from "../../../../components/layouts/banner.tsx" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { Banner } from "../../../../components/layouts/Banner.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../components/layouts/section/section.tsx" -import { CreateOneTicketMessage } from "./createOneTicketMessage.tsx" -import { TicketMessageList } from "./ticketMessageList.tsx" +import { CreateOneTicketMessage } from "./CreateOneTicketMessage.tsx" +import { TicketMessageList } from "./TicketMessageList.tsx" const categoryLabels: Record = { bug: "Erreur", diff --git a/packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx b/packages/website/src/features/dashboard/support/$idTicket/TicketTabContent.tsx similarity index 92% rename from packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx rename to packages/website/src/features/dashboard/support/$idTicket/TicketTabContent.tsx index e46254be..17f35820 100644 --- a/packages/website/src/features/dashboard/support/$idTicket/ticketTabContent.tsx +++ b/packages/website/src/features/dashboard/support/$idTicket/TicketTabContent.tsx @@ -1,10 +1,10 @@ import { readOneTicketRouteDefinition } from "@arrhes/application-metadata/routes" import { css } from "@arrhes/ui/utilities/cn.js" -import { DataWrapper } from "../../../../components/layouts/dataWrapper.tsx" +import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { Section } from "../../../../components/layouts/section/section.tsx" -import { StatusToggle } from "./statusToggle.tsx" -import { TicketPage } from "./ticketPage.tsx" +import { StatusToggle } from "./StatusToggle.tsx" +import { TicketPage } from "./TicketPage.tsx" export function TicketTabContent(props: { idTicket: string }) { return ( diff --git a/packages/website/src/features/dashboard/support/createOneTicket.tsx b/packages/website/src/features/dashboard/support/CreateOneTicket.tsx similarity index 94% rename from packages/website/src/features/dashboard/support/createOneTicket.tsx rename to packages/website/src/features/dashboard/support/CreateOneTicket.tsx index 9712c3ec..80f4e48d 100644 --- a/packages/website/src/features/dashboard/support/createOneTicket.tsx +++ b/packages/website/src/features/dashboard/support/CreateOneTicket.tsx @@ -4,13 +4,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" import { type JSX, useRef } from "react" import { Fragment } from "react/jsx-runtime" -import { FormControl } from "../../../components/forms/formControl.tsx" -import { FormError } from "../../../components/forms/formError.tsx" -import { FormField } from "../../../components/forms/formField.tsx" -import { FormItem } from "../../../components/forms/formItem.tsx" -import { FormLabel } from "../../../components/forms/formLabel.tsx" -import { FormRoot } from "../../../components/forms/formRoot.tsx" -import { useTabs } from "../../../contexts/tabs/tabsContext.tsx" +import { FormControl } from "../../../components/forms/FormControl.tsx" +import { FormError } from "../../../components/forms/FormError.tsx" +import { FormField } from "../../../components/forms/FormField.tsx" +import { FormItem } from "../../../components/forms/FormItem.tsx" +import { FormLabel } from "../../../components/forms/FormLabel.tsx" +import { FormRoot } from "../../../components/forms/FormRoot.tsx" +import { useTabs } from "../../../contexts/tabs/useTabs.tsx" import { applicationRouter } from "../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../utilities/invalidateData.ts" diff --git a/packages/website/src/features/dashboard/support/supportPage.tsx b/packages/website/src/features/dashboard/support/SupportPage.tsx similarity index 94% rename from packages/website/src/features/dashboard/support/supportPage.tsx rename to packages/website/src/features/dashboard/support/SupportPage.tsx index 54b129aa..1d9e2807 100644 --- a/packages/website/src/features/dashboard/support/supportPage.tsx +++ b/packages/website/src/features/dashboard/support/SupportPage.tsx @@ -2,15 +2,15 @@ import { readOrganizationBillingRouteDefinition } from "@arrhes/application-meta import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBrandGithub, IconBrandLinkedin, IconMail, IconPlus } from "@tabler/icons-react" -import { Banner } from "../../../components/layouts/banner.tsx" -import { Box } from "../../../components/layouts/box.tsx" +import { Banner } from "../../../components/layouts/Banner.tsx" +import { Box } from "../../../components/layouts/Box.tsx" import { Page } from "../../../components/layouts/page/page.tsx" import { Section } from "../../../components/layouts/section/section.tsx" import { getCookie } from "../../../utilities/cookies/getCookie.ts" import { useDataFromAPI } from "../../../utilities/useHTTPData.ts" import { cookiePrefix } from "../../../utilities/variables.ts" -import { CreateOneTicket } from "./createOneTicket.tsx" -import { TicketsListTable } from "./ticketsListTable.tsx" +import { CreateOneTicket } from "./CreateOneTicket.tsx" +import { TicketsListTable } from "./TicketsListTable.tsx" function SupportBanner() { const hasOrganization = !!getCookie(`${cookiePrefix}_id_organization`) diff --git a/packages/website/src/features/dashboard/support/ticketListTableRow.tsx b/packages/website/src/features/dashboard/support/TicketListTableRow.tsx similarity index 98% rename from packages/website/src/features/dashboard/support/ticketListTableRow.tsx rename to packages/website/src/features/dashboard/support/TicketListTableRow.tsx index 6a9418a1..c5cfc0b2 100644 --- a/packages/website/src/features/dashboard/support/ticketListTableRow.tsx +++ b/packages/website/src/features/dashboard/support/TicketListTableRow.tsx @@ -3,7 +3,7 @@ import { Button, Chip, formatDate, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type * as v from "valibot" import { ListTable } from "../../../components/layouts/listTable/listTable.tsx" -import { TabLink } from "../../../components/layouts/tabBar/tabLink.js" +import { TabLink } from "../../../components/layouts/tabBar/TabLink.js" const categoryLabels: Record = { bug: "Erreur", diff --git a/packages/website/src/features/dashboard/support/ticketsListTable.tsx b/packages/website/src/features/dashboard/support/TicketsListTable.tsx similarity index 87% rename from packages/website/src/features/dashboard/support/ticketsListTable.tsx rename to packages/website/src/features/dashboard/support/TicketsListTable.tsx index be3e63a4..097d908e 100644 --- a/packages/website/src/features/dashboard/support/ticketsListTable.tsx +++ b/packages/website/src/features/dashboard/support/TicketsListTable.tsx @@ -1,9 +1,9 @@ import { readAllTicketsRouteDefinition } from "@arrhes/application-metadata/routes" import { IconTicket } from "@tabler/icons-react" -import { DataWrapper } from "../../../components/layouts/dataWrapper.tsx" -import { EmptyState } from "../../../components/layouts/emptyState.tsx" +import { DataWrapper } from "../../../components/layouts/DataWrapper.tsx" +import { EmptyState } from "../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../components/layouts/listTable/listTable.tsx" -import { TicketListTableRow } from "./ticketListTableRow.tsx" +import { TicketListTableRow } from "./TicketListTableRow.tsx" export function TicketsListTable() { return ( diff --git a/packages/website/src/features/docs/docsLayout.tsx b/packages/website/src/features/docs/DocsLayout.tsx similarity index 98% rename from packages/website/src/features/docs/docsLayout.tsx rename to packages/website/src/features/docs/DocsLayout.tsx index 844a1fb9..05364064 100644 --- a/packages/website/src/features/docs/docsLayout.tsx +++ b/packages/website/src/features/docs/DocsLayout.tsx @@ -3,11 +3,11 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" import { IconBook2, IconBrandGithub, IconMenu } from "@tabler/icons-react" import { Outlet, useRouterState } from "@tanstack/react-router" import { useState } from "react" -import { LinkButton } from "../../components/linkButton.js" +import { LinkButton } from "../../components/LinkButton.js" import { docSections } from "./docSections.js" -import { DocsSearch } from "./docsSearch.js" -import { SectionTab } from "./sectionTab.js" -import { SidebarNavigation } from "./sidebarNavigation.js" +import { DocsSearch } from "./DocsSearch.js" +import { SectionTab } from "./SectionTab.js" +import { SidebarNavigation } from "./SidebarNavigation.js" type DocSectionId = keyof typeof docSections diff --git a/packages/website/src/features/docs/docsSearch.tsx b/packages/website/src/features/docs/DocsSearch.tsx similarity index 100% rename from packages/website/src/features/docs/docsSearch.tsx rename to packages/website/src/features/docs/DocsSearch.tsx diff --git a/packages/website/src/features/docs/sectionTab.tsx b/packages/website/src/features/docs/SectionTab.tsx similarity index 94% rename from packages/website/src/features/docs/sectionTab.tsx rename to packages/website/src/features/docs/SectionTab.tsx index e70ab3bc..cc933eb8 100644 --- a/packages/website/src/features/docs/sectionTab.tsx +++ b/packages/website/src/features/docs/SectionTab.tsx @@ -1,7 +1,7 @@ import { ButtonGhostContent } from "@arrhes/ui" import type { Icon, IconProps } from "@tabler/icons-react" import type { ReactElement } from "react" -import { LinkButton } from "../../components/linkButton.tsx" +import { LinkButton } from "../../components/LinkButton.tsx" export interface DocSection { id: string diff --git a/packages/website/src/features/docs/sidebarNavigation.tsx b/packages/website/src/features/docs/SidebarNavigation.tsx similarity index 98% rename from packages/website/src/features/docs/sidebarNavigation.tsx rename to packages/website/src/features/docs/SidebarNavigation.tsx index 40210762..2f6e1729 100644 --- a/packages/website/src/features/docs/sidebarNavigation.tsx +++ b/packages/website/src/features/docs/SidebarNavigation.tsx @@ -2,7 +2,7 @@ import { ButtonGhostContent, Chip, type ChipColors } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import type { Icon, IconProps } from "@tabler/icons-react" import { cloneElement, type ReactElement } from "react" -import { LinkButton } from "../../components/linkButton.tsx" +import { LinkButton } from "../../components/LinkButton.tsx" export interface NavigationSection { title?: string diff --git a/packages/website/src/features/docs/accounting/introduction/accountsAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/accounting/introduction/accountsAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx index 4ad7682d..b5a0dbf7 100644 --- a/packages/website/src/features/docs/accounting/introduction/accountsAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTable } from "../../../../components/document/docTable.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" import { accountClasses } from "../resources/accounts/accountsData.js" export function AccountsAccountingDocPage() { diff --git a/packages/website/src/features/docs/accounting/introduction/classesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/ClassesAccountingDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/accounting/introduction/classesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/introduction/ClassesAccountingDocPage.tsx index b09341e5..a98de2c7 100644 --- a/packages/website/src/features/docs/accounting/introduction/classesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/ClassesAccountingDocPage.tsx @@ -1,11 +1,11 @@ -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTip } from "../../../../components/document/DocTip.js" import { accountClasses } from "../resources/accounts/accountsData.js" // ── Class descriptions & tips ────────────────────────────────────────────── diff --git a/packages/website/src/features/docs/accounting/introduction/doubleEntryAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/DoubleEntryAccountingDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/accounting/introduction/doubleEntryAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/introduction/DoubleEntryAccountingDocPage.tsx index daa15f8f..16c2d35c 100644 --- a/packages/website/src/features/docs/accounting/introduction/doubleEntryAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/DoubleEntryAccountingDocPage.tsx @@ -1,16 +1,16 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.tsx" -import { DocExample } from "../../../../components/document/docExample.tsx" -import { DocHeader } from "../../../../components/document/docHeader.tsx" -import { DocLink } from "../../../../components/document/docLink.tsx" -import { DocNextPage } from "../../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../../components/document/docRoot.tsx" -import { DocSection } from "../../../../components/document/docSection.tsx" -import { DocSourceRef } from "../../../../components/document/docSourceRef.tsx" -import { DocSources } from "../../../../components/document/docSources.tsx" -import { DocTable } from "../../../../components/document/docTable.tsx" -import { DocTip } from "../../../../components/document/docTip.tsx" +import { DocDefinition } from "../../../../components/document/DocDefinition.tsx" +import { DocExample } from "../../../../components/document/DocExample.tsx" +import { DocHeader } from "../../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../../components/document/DocLink.tsx" +import { DocNextPage } from "../../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../../components/document/DocSection.tsx" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.tsx" +import { DocSources } from "../../../../components/document/DocSources.tsx" +import { DocTable } from "../../../../components/document/DocTable.tsx" +import { DocTip } from "../../../../components/document/DocTip.tsx" export function DoubleEntryAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/introduction/entriesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/EntriesAccountingDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/accounting/introduction/entriesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/introduction/EntriesAccountingDocPage.tsx index 26d4cf39..f2dda448 100644 --- a/packages/website/src/features/docs/accounting/introduction/entriesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/EntriesAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.tsx" -import { DocExample } from "../../../../components/document/docExample.tsx" -import { DocHeader } from "../../../../components/document/docHeader.tsx" -import { DocLink } from "../../../../components/document/docLink.tsx" -import { DocList } from "../../../../components/document/docList.tsx" -import { DocNextPage } from "../../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../../components/document/docRoot.tsx" -import { DocSection } from "../../../../components/document/docSection.tsx" -import { DocSourceRef } from "../../../../components/document/docSourceRef.tsx" -import { DocSources } from "../../../../components/document/docSources.tsx" -import { DocTable } from "../../../../components/document/docTable.tsx" -import { DocTip } from "../../../../components/document/docTip.tsx" +import { DocDefinition } from "../../../../components/document/DocDefinition.tsx" +import { DocExample } from "../../../../components/document/DocExample.tsx" +import { DocHeader } from "../../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../../components/document/DocLink.tsx" +import { DocList } from "../../../../components/document/DocList.tsx" +import { DocNextPage } from "../../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../../components/document/DocSection.tsx" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.tsx" +import { DocSources } from "../../../../components/document/DocSources.tsx" +import { DocTable } from "../../../../components/document/DocTable.tsx" +import { DocTip } from "../../../../components/document/DocTip.tsx" export function EntriesAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/introduction/introductionAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/IntroductionAccountingDocPage.tsx similarity index 92% rename from packages/website/src/features/docs/accounting/introduction/introductionAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/introduction/IntroductionAccountingDocPage.tsx index 0b1d4401..2ec15003 100644 --- a/packages/website/src/features/docs/accounting/introduction/introductionAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/IntroductionAccountingDocPage.tsx @@ -1,13 +1,13 @@ -import { DocHeader } from "../../../../components/document/docHeader.tsx" -import { DocLink } from "../../../../components/document/docLink.tsx" -import { DocList } from "../../../../components/document/docList.tsx" -import { DocNextPage } from "../../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../../components/document/docRoot.tsx" -import { DocSection } from "../../../../components/document/docSection.tsx" -import { DocSourceRef } from "../../../../components/document/docSourceRef.tsx" -import { DocSources } from "../../../../components/document/docSources.tsx" -import { DocTip } from "../../../../components/document/docTip.tsx" +import { DocHeader } from "../../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../../components/document/DocLink.tsx" +import { DocList } from "../../../../components/document/DocList.tsx" +import { DocNextPage } from "../../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../../components/document/DocSection.tsx" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.tsx" +import { DocSources } from "../../../../components/document/DocSources.tsx" +import { DocTip } from "../../../../components/document/DocTip.tsx" export function IntroductionAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/introduction/rootAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/RootAccountingDocPage.tsx similarity index 83% rename from packages/website/src/features/docs/accounting/introduction/rootAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/introduction/RootAccountingDocPage.tsx index ce5c3591..154a98fb 100644 --- a/packages/website/src/features/docs/accounting/introduction/rootAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/RootAccountingDocPage.tsx @@ -1,10 +1,10 @@ -import { DocHeader } from "../../../../components/document/docHeader.tsx" -import { DocLink } from "../../../../components/document/docLink.tsx" -import { DocList } from "../../../../components/document/docList.tsx" -import { DocNextPage } from "../../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../../components/document/docRoot.tsx" -import { DocSection } from "../../../../components/document/docSection.tsx" +import { DocHeader } from "../../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../../components/document/DocLink.tsx" +import { DocList } from "../../../../components/document/DocList.tsx" +import { DocNextPage } from "../../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../../components/document/DocSection.tsx" export function RootAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/balanceAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx similarity index 93% rename from packages/website/src/features/docs/accounting/reports/balanceAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx index 1cae6b37..48d0f9b6 100644 --- a/packages/website/src/features/docs/accounting/reports/balanceAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTable } from "../../../../components/document/docTable.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function BalanceAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/balanceSheetAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/BalanceSheetAccountingDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/accounting/reports/balanceSheetAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/BalanceSheetAccountingDocPage.tsx index f4558c94..d5223052 100644 --- a/packages/website/src/features/docs/accounting/reports/balanceSheetAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/BalanceSheetAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTable } from "../../../../components/document/docTable.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function BalanceSheetAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/fecAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/FecAccountingDocPage.tsx similarity index 93% rename from packages/website/src/features/docs/accounting/reports/fecAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/FecAccountingDocPage.tsx index c330950d..a186c592 100644 --- a/packages/website/src/features/docs/accounting/reports/fecAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/FecAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTable } from "../../../../components/document/docTable.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function FecAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/incomeStatementAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/IncomeStatementAccountingDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/accounting/reports/incomeStatementAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/IncomeStatementAccountingDocPage.tsx index 19b7a79d..9f099b43 100644 --- a/packages/website/src/features/docs/accounting/reports/incomeStatementAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/IncomeStatementAccountingDocPage.tsx @@ -1,16 +1,16 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function IncomeStatementAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/journalAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/JournalAccountingDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/accounting/reports/journalAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/JournalAccountingDocPage.tsx index ea30c4ae..2cc3d16b 100644 --- a/packages/website/src/features/docs/accounting/reports/journalAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/JournalAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTable } from "../../../../components/document/docTable.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function JournalAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/ledgerAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/LedgerAccountingDocPage.tsx similarity index 93% rename from packages/website/src/features/docs/accounting/reports/ledgerAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/LedgerAccountingDocPage.tsx index bc71db57..42b226fa 100644 --- a/packages/website/src/features/docs/accounting/reports/ledgerAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/LedgerAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTable } from "../../../../components/document/docTable.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function LedgerAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/notesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/NotesAccountingDocPage.tsx similarity index 93% rename from packages/website/src/features/docs/accounting/reports/notesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/NotesAccountingDocPage.tsx index ef66eb51..5b59bbdb 100644 --- a/packages/website/src/features/docs/accounting/reports/notesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/NotesAccountingDocPage.tsx @@ -1,16 +1,16 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocExample } from "../../../../components/document/docExample.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocExample } from "../../../../components/document/DocExample.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function NotesAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/reports/reportsAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/ReportsAccountingDocPage.tsx similarity index 92% rename from packages/website/src/features/docs/accounting/reports/reportsAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/reports/ReportsAccountingDocPage.tsx index 8d137d18..ea249d85 100644 --- a/packages/website/src/features/docs/accounting/reports/reportsAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/ReportsAccountingDocPage.tsx @@ -1,14 +1,14 @@ -import { DocDefinition } from "../../../../components/document/docDefinition.js" -import { DocHeader } from "../../../../components/document/docHeader.js" -import { DocLink } from "../../../../components/document/docLink.js" -import { DocList } from "../../../../components/document/docList.js" -import { DocNextPage } from "../../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { DocSection } from "../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../components/document/docSourceRef.js" -import { DocSources } from "../../../../components/document/docSources.js" -import { DocTip } from "../../../../components/document/docTip.js" +import { DocDefinition } from "../../../../components/document/DocDefinition.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../components/document/DocLink.js" +import { DocList } from "../../../../components/document/DocList.js" +import { DocNextPage } from "../../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../components/document/DocSourceRef.js" +import { DocSources } from "../../../../components/document/DocSources.js" +import { DocTip } from "../../../../components/document/DocTip.js" export function ReportsAccountingDocPage() { return ( diff --git a/packages/website/src/features/docs/accounting/resources/accounts/accountResourcesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/resources/accounts/AccountResourcesAccountingDocPage.tsx similarity index 77% rename from packages/website/src/features/docs/accounting/resources/accounts/accountResourcesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/AccountResourcesAccountingDocPage.tsx index 3435ec70..de0f5d79 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/accountResourcesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/AccountResourcesAccountingDocPage.tsx @@ -1,17 +1,17 @@ import { ButtonOutlineContent, LinkButton } from "@arrhes/ui" import { IconArrowLeft } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DocHeader } from "../../../../../components/document/docHeader.js" -import { DocRoot } from "../../../../../components/document/docRoot.js" +import { DocHeader } from "../../../../../components/document/DocHeader.js" +import { DocRoot } from "../../../../../components/document/DocRoot.js" import { DataError } from "../../../components/DataError.js" import { getAccount, getAccountBySlug, getDirectChildren } from "./accountsData.js" -import { AccountInfoCard } from "./components/accountInfoCard.js" -import { AccountNotFound } from "./components/accountNotFound.js" -import { AccountScenariosSection } from "./components/accountScenariosSection.js" -import { ChildrenListSection } from "./components/childrenListSection.js" -import { DebitCreditSection } from "./components/debitCreditSection.js" -import { ParentAccountSection } from "./components/parentAccountSection.js" -import { SummaryAccountBanner } from "./components/summaryAccountBanner.js" +import { AccountInfoCard } from "./components/AccountInfoCard.js" +import { AccountNotFound } from "./components/AccountNotFound.js" +import { AccountScenariosSection } from "./components/AccountScenariosSection.js" +import { ChildrenListSection } from "./components/ChildrenListSection.js" +import { DebitCreditSection } from "./components/DebitCreditSection.js" +import { ParentAccountSection } from "./components/ParentAccountSection.js" +import { SummaryAccountBanner } from "./components/SummaryAccountBanner.js" export function AccountResourcesAccountingDocPage() { const { account: slug } = useParams({ diff --git a/packages/website/src/features/docs/accounting/resources/accounts/accountsResourcesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/resources/accounts/AccountsResourcesAccountingDocPage.tsx similarity index 97% rename from packages/website/src/features/docs/accounting/resources/accounts/accountsResourcesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/AccountsResourcesAccountingDocPage.tsx index 36faa35d..86601a47 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/accountsResourcesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/AccountsResourcesAccountingDocPage.tsx @@ -2,12 +2,12 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconLoader2, IconSearch } from "@tabler/icons-react" import { useVirtualizer } from "@tanstack/react-virtual" import { useRef, useState, useTransition } from "react" -import { DocHeader } from "../../../../../components/document/docHeader.js" -import { DocParagraph } from "../../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../../components/document/docRoot.js" -import { DocSection } from "../../../../../components/document/docSection.js" -import { DocSourceRef } from "../../../../../components/document/docSourceRef.js" -import { LinkButton } from "../../../../../components/linkButton.js" +import { DocHeader } from "../../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../../components/document/DocSection.js" +import { DocSourceRef } from "../../../../../components/document/DocSourceRef.js" +import { LinkButton } from "../../../../../components/LinkButton.js" import { type AccountEntry, accountEntries, searchAccounts } from "./accountsData.js" // ── Account row ───────────────────────────────────────────────────────────── diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/accountInfoCard.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/AccountInfoCard.tsx similarity index 98% rename from packages/website/src/features/docs/accounting/resources/accounts/components/accountInfoCard.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/AccountInfoCard.tsx index e9ba81f4..fc69d565 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/accountInfoCard.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/AccountInfoCard.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconBookmark } from "@tabler/icons-react" import type { AccountEntry } from "../accountsData.js" -import { InfoRow } from "./infoRow.js" +import { InfoRow } from "./InfoRow.js" export function AccountInfoCard(props: { entry: AccountEntry }) { const { entry } = props diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/accountNotFound.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/AccountNotFound.tsx similarity index 82% rename from packages/website/src/features/docs/accounting/resources/accounts/components/accountNotFound.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/AccountNotFound.tsx index 9d4aedae..110e4238 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/accountNotFound.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/AccountNotFound.tsx @@ -1,8 +1,8 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { IconArrowLeft } from "@tabler/icons-react" -import { DocHeader } from "../../../../../../components/document/docHeader.js" -import { DocRoot } from "../../../../../../components/document/docRoot.js" -import { LinkButton } from "../../../../../../components/linkButton.js" +import { DocHeader } from "../../../../../../components/document/DocHeader.js" +import { DocRoot } from "../../../../../../components/document/DocRoot.js" +import { LinkButton } from "../../../../../../components/LinkButton.js" export function AccountNotFound() { return ( diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/accountScenariosSection.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/AccountScenariosSection.tsx similarity index 95% rename from packages/website/src/features/docs/accounting/resources/accounts/components/accountScenariosSection.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/AccountScenariosSection.tsx index 04ac08fc..08875cab 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/accountScenariosSection.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/AccountScenariosSection.tsx @@ -1,8 +1,8 @@ import { ButtonOutlineContent, FormatNull } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconMasksTheater } from "@tabler/icons-react" -import { DocSection } from "../../../../../../components/document/docSection.js" -import { LinkButton } from "../../../../../../components/linkButton.js" +import { DocSection } from "../../../../../../components/document/DocSection.js" +import { LinkButton } from "../../../../../../components/LinkButton.js" import { getScenariosByAccountNumber } from "../../scenarios/scenariosData.js" import type { AccountEntry } from "../accountsData.js" diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/childrenListSection.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/ChildrenListSection.tsx similarity index 97% rename from packages/website/src/features/docs/accounting/resources/accounts/components/childrenListSection.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/ChildrenListSection.tsx index 300160cb..1d6b712a 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/childrenListSection.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/ChildrenListSection.tsx @@ -1,8 +1,8 @@ import { ButtonOutlineContent, FormatNull } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCornerDownRight } from "@tabler/icons-react" -import { DocSection } from "../../../../../../components/document/docSection.js" -import { LinkButton } from "../../../../../../components/linkButton.js" +import { DocSection } from "../../../../../../components/document/DocSection.js" +import { LinkButton } from "../../../../../../components/LinkButton.js" import type { AccountEntry } from "../accountsData.js" export function ChildrenListSection(props: { children: AccountEntry[] }) { diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/debitCreditSection.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/DebitCreditSection.tsx similarity index 96% rename from packages/website/src/features/docs/accounting/resources/accounts/components/debitCreditSection.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/DebitCreditSection.tsx index f5745cf8..b588a442 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/debitCreditSection.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/DebitCreditSection.tsx @@ -1,5 +1,5 @@ -import { DocSection } from "../../../../../../components/document/docSection.js" -import { DocTable } from "../../../../../../components/document/docTable.js" +import { DocSection } from "../../../../../../components/document/DocSection.js" +import { DocTable } from "../../../../../../components/document/DocTable.js" import type { AccountEntry } from "../accountsData.js" export function DebitCreditSection(props: { entry: AccountEntry }) { diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/infoRow.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/InfoRow.tsx similarity index 100% rename from packages/website/src/features/docs/accounting/resources/accounts/components/infoRow.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/InfoRow.tsx diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/journalEntryExamples.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/JournalEntryExamples.tsx similarity index 97% rename from packages/website/src/features/docs/accounting/resources/accounts/components/journalEntryExamples.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/JournalEntryExamples.tsx index c92d3eee..0d2d8f58 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/journalEntryExamples.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/JournalEntryExamples.tsx @@ -1,8 +1,8 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconMasksTheater } from "@tabler/icons-react" -import { DocSection } from "../../../../../../components/document/docSection.js" -import { DocTable } from "../../../../../../components/document/docTable.js" -import { DocTip } from "../../../../../../components/document/docTip.js" +import { DocSection } from "../../../../../../components/document/DocSection.js" +import { DocTable } from "../../../../../../components/document/DocTable.js" +import { DocTip } from "../../../../../../components/document/DocTip.js" import { getScenariosByAccountNumber } from "../../scenarios/scenariosData.js" import type { AccountEntry } from "../accountsData.js" diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/parentAccountSection.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/ParentAccountSection.tsx similarity index 96% rename from packages/website/src/features/docs/accounting/resources/accounts/components/parentAccountSection.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/ParentAccountSection.tsx index b3e797ee..15c975b2 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/parentAccountSection.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/ParentAccountSection.tsx @@ -1,8 +1,8 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCornerUpLeft } from "@tabler/icons-react" -import { DocSection } from "../../../../../../components/document/docSection.js" -import { LinkButton } from "../../../../../../components/linkButton.js" +import { DocSection } from "../../../../../../components/document/DocSection.js" +import { LinkButton } from "../../../../../../components/LinkButton.js" import type { AccountEntry } from "../accountsData.js" export function ParentAccountSection(props: { parentAccount: AccountEntry }) { diff --git a/packages/website/src/features/docs/accounting/resources/accounts/components/summaryAccountBanner.tsx b/packages/website/src/features/docs/accounting/resources/accounts/components/SummaryAccountBanner.tsx similarity index 97% rename from packages/website/src/features/docs/accounting/resources/accounts/components/summaryAccountBanner.tsx rename to packages/website/src/features/docs/accounting/resources/accounts/components/SummaryAccountBanner.tsx index 3ff26b33..93eeb95f 100644 --- a/packages/website/src/features/docs/accounting/resources/accounts/components/summaryAccountBanner.tsx +++ b/packages/website/src/features/docs/accounting/resources/accounts/components/SummaryAccountBanner.tsx @@ -1,6 +1,6 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconInfoCircle } from "@tabler/icons-react" -import { DocLink } from "../../../../../../components/document/docLink.js" +import { DocLink } from "../../../../../../components/document/DocLink.js" import type { AccountEntry } from "../accountsData.js" export function SummaryAccountBanner(props: { entry: AccountEntry }) { diff --git a/packages/website/src/features/docs/accounting/resources/glossary/glossaryListItem.tsx b/packages/website/src/features/docs/accounting/resources/glossary/GlossaryListItem.tsx similarity index 97% rename from packages/website/src/features/docs/accounting/resources/glossary/glossaryListItem.tsx rename to packages/website/src/features/docs/accounting/resources/glossary/GlossaryListItem.tsx index 22241fc7..257148b2 100644 --- a/packages/website/src/features/docs/accounting/resources/glossary/glossaryListItem.tsx +++ b/packages/website/src/features/docs/accounting/resources/glossary/GlossaryListItem.tsx @@ -1,5 +1,5 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { LinkButton } from "../../../../../components/linkButton.js" +import { LinkButton } from "../../../../../components/LinkButton.js" export function GlossaryListItem(props: { term: string diff --git a/packages/website/src/features/docs/accounting/resources/glossary/glossaryResourcesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/resources/glossary/GlossaryResourcesAccountingDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/accounting/resources/glossary/glossaryResourcesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/resources/glossary/GlossaryResourcesAccountingDocPage.tsx index 90ad6815..ab4cc7b5 100644 --- a/packages/website/src/features/docs/accounting/resources/glossary/glossaryResourcesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/resources/glossary/GlossaryResourcesAccountingDocPage.tsx @@ -1,13 +1,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconSearch } from "@tabler/icons-react" import { useState } from "react" -import { DocHeader } from "../../../../../components/document/docHeader.js" -import { DocLink } from "../../../../../components/document/docLink.js" -import { DocParagraph } from "../../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../../components/document/docRoot.js" -import { DocTip } from "../../../../../components/document/docTip.js" +import { DocHeader } from "../../../../../components/document/DocHeader.js" +import { DocLink } from "../../../../../components/document/DocLink.js" +import { DocParagraph } from "../../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../../components/document/DocRoot.js" +import { DocTip } from "../../../../../components/document/DocTip.js" import { getGlossaryTermsByLetter, searchGlossaryTerms } from "./glossaryData.js" -import { GlossaryListItem } from "./glossaryListItem.js" +import { GlossaryListItem } from "./GlossaryListItem.js" export function GlossaryResourcesAccountingDocPage() { const [query, setQuery] = useState("") diff --git a/packages/website/src/features/docs/accounting/resources/glossary/glossaryTermResourcesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/resources/glossary/GlossaryTermResourcesAccountingDocPage.tsx similarity index 92% rename from packages/website/src/features/docs/accounting/resources/glossary/glossaryTermResourcesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/resources/glossary/GlossaryTermResourcesAccountingDocPage.tsx index 86f97ccd..4851095e 100644 --- a/packages/website/src/features/docs/accounting/resources/glossary/glossaryTermResourcesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/resources/glossary/GlossaryTermResourcesAccountingDocPage.tsx @@ -2,14 +2,14 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconArrowLeft, IconLanguage, IconLink } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DocDefinition } from "../../../../../components/document/docDefinition.js" -import { DocHeader } from "../../../../../components/document/docHeader.js" -import { DocParagraph } from "../../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../../components/document/docRoot.js" -import { DocSection } from "../../../../../components/document/docSection.js" -import { DocSources } from "../../../../../components/document/docSources.js" -import { DocTip } from "../../../../../components/document/docTip.js" -import { LinkButton } from "../../../../../components/linkButton.js" +import { DocDefinition } from "../../../../../components/document/DocDefinition.js" +import { DocHeader } from "../../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../../components/document/DocSection.js" +import { DocSources } from "../../../../../components/document/DocSources.js" +import { DocTip } from "../../../../../components/document/DocTip.js" +import { LinkButton } from "../../../../../components/LinkButton.js" import { getGlossaryTermBySlug, glossaryTerms } from "./glossaryData.js" export function GlossaryTermResourcesAccountingDocPage() { diff --git a/packages/website/src/features/docs/accounting/resources/scenarios/scenarioResourcesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/resources/scenarios/ScenarioResourcesAccountingDocPage.tsx similarity index 91% rename from packages/website/src/features/docs/accounting/resources/scenarios/scenarioResourcesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/resources/scenarios/ScenarioResourcesAccountingDocPage.tsx index be24fef3..5598633a 100644 --- a/packages/website/src/features/docs/accounting/resources/scenarios/scenarioResourcesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/resources/scenarios/ScenarioResourcesAccountingDocPage.tsx @@ -2,12 +2,12 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconArrowLeft, IconLink } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" -import { DocHeader } from "../../../../../components/document/docHeader.js" -import { DocParagraph } from "../../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../../components/document/docRoot.js" -import { DocSection } from "../../../../../components/document/docSection.js" -import { DocTable } from "../../../../../components/document/docTable.js" -import { LinkButton } from "../../../../../components/linkButton.js" +import { DocHeader } from "../../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../../components/document/DocSection.js" +import { DocTable } from "../../../../../components/document/DocTable.js" +import { LinkButton } from "../../../../../components/LinkButton.js" import { DataError } from "../../../components/DataError.js" import { getScenarioAccounts, getScenarioById } from "./scenariosData.js" diff --git a/packages/website/src/features/docs/accounting/resources/scenarios/scenariosResourcesAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/resources/scenarios/ScenariosResourcesAccountingDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/accounting/resources/scenarios/scenariosResourcesAccountingDocPage.tsx rename to packages/website/src/features/docs/accounting/resources/scenarios/ScenariosResourcesAccountingDocPage.tsx index 5c2469db..4c90e4dd 100644 --- a/packages/website/src/features/docs/accounting/resources/scenarios/scenariosResourcesAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/resources/scenarios/ScenariosResourcesAccountingDocPage.tsx @@ -3,11 +3,11 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconLoader2, IconSearch } from "@tabler/icons-react" import { useVirtualizer } from "@tanstack/react-virtual" import { useRef, useState, useTransition } from "react" -import { DocHeader } from "../../../../../components/document/docHeader.js" -import { DocParagraph } from "../../../../../components/document/docParagraph.js" -import { DocRoot } from "../../../../../components/document/docRoot.js" -import { DocSection } from "../../../../../components/document/docSection.js" -import { LinkButton } from "../../../../../components/linkButton.js" +import { DocHeader } from "../../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../../components/document/DocSection.js" +import { LinkButton } from "../../../../../components/LinkButton.js" import { type ScenarioEntry, scenarioEntries, searchScenarios } from "./scenariosData.js" const ROW_HEIGHT = 32 diff --git a/packages/website/src/features/docs/ai/modelsAiDocPage.tsx b/packages/website/src/features/docs/ai/ModelsAiDocPage.tsx similarity index 88% rename from packages/website/src/features/docs/ai/modelsAiDocPage.tsx rename to packages/website/src/features/docs/ai/ModelsAiDocPage.tsx index 50ef6049..94133414 100644 --- a/packages/website/src/features/docs/ai/modelsAiDocPage.tsx +++ b/packages/website/src/features/docs/ai/ModelsAiDocPage.tsx @@ -1,11 +1,11 @@ -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocList } from "../../../components/document/docList.tsx" -import { DocNextPage } from "../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTable } from "../../../components/document/docTable.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocList } from "../../../components/document/DocList.tsx" +import { DocNextPage } from "../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTable } from "../../../components/document/DocTable.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function ModelsAiDocPage() { return ( diff --git a/packages/website/src/features/docs/ai/ocrAiDocPage.tsx b/packages/website/src/features/docs/ai/OcrAiDocPage.tsx similarity index 81% rename from packages/website/src/features/docs/ai/ocrAiDocPage.tsx rename to packages/website/src/features/docs/ai/OcrAiDocPage.tsx index e6b3c860..9307ac36 100644 --- a/packages/website/src/features/docs/ai/ocrAiDocPage.tsx +++ b/packages/website/src/features/docs/ai/OcrAiDocPage.tsx @@ -1,10 +1,10 @@ -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocLink } from "../../../components/document/docLink.tsx" -import { DocList } from "../../../components/document/docList.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../components/document/DocLink.tsx" +import { DocList } from "../../../components/document/DocList.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function OcrAiDocPage() { return ( diff --git a/packages/website/src/features/docs/ai/rootAiDocPage.tsx b/packages/website/src/features/docs/ai/RootAiDocPage.tsx similarity index 90% rename from packages/website/src/features/docs/ai/rootAiDocPage.tsx rename to packages/website/src/features/docs/ai/RootAiDocPage.tsx index 830b9727..4f23a063 100644 --- a/packages/website/src/features/docs/ai/rootAiDocPage.tsx +++ b/packages/website/src/features/docs/ai/RootAiDocPage.tsx @@ -1,14 +1,14 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocLink } from "../../../components/document/docLink.tsx" -import { DocList } from "../../../components/document/docList.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" -import { LinkButton } from "../../../components/linkButton.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../components/document/DocLink.tsx" +import { DocList } from "../../../components/document/DocList.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" +import { LinkButton } from "../../../components/LinkButton.tsx" export function RootAiDocPage() { return ( diff --git a/packages/website/src/features/docs/ai/toolsAiDocPage.tsx b/packages/website/src/features/docs/ai/ToolsAiDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/ai/toolsAiDocPage.tsx rename to packages/website/src/features/docs/ai/ToolsAiDocPage.tsx index 86643702..ad82ead0 100644 --- a/packages/website/src/features/docs/ai/toolsAiDocPage.tsx +++ b/packages/website/src/features/docs/ai/ToolsAiDocPage.tsx @@ -1,11 +1,11 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { useMemo, useState } from "react" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocList } from "../../../components/document/docList.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocList } from "../../../components/document/DocList.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" import { type AgentToolDefinition, agentToolsCatalog } from "../../dashboard/$idOrganization/agent/agentToolsCatalog.ts" const categoryOrder = [ diff --git a/packages/website/src/features/docs/api/authenticationApiDocPage.tsx b/packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx similarity index 92% rename from packages/website/src/features/docs/api/authenticationApiDocPage.tsx rename to packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx index 8544ef13..de9f49d1 100644 --- a/packages/website/src/features/docs/api/authenticationApiDocPage.tsx +++ b/packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx @@ -1,11 +1,11 @@ -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocList } from "../../../components/document/docList.tsx" -import { DocNextPage } from "../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTable } from "../../../components/document/docTable.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocList } from "../../../components/document/DocList.tsx" +import { DocNextPage } from "../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTable } from "../../../components/document/DocTable.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function AuthenticationApiDocPage() { return ( diff --git a/packages/website/src/features/docs/api/filesApiDocPage.tsx b/packages/website/src/features/docs/api/FilesApiDocPage.tsx similarity index 91% rename from packages/website/src/features/docs/api/filesApiDocPage.tsx rename to packages/website/src/features/docs/api/FilesApiDocPage.tsx index fc937a97..012d953d 100644 --- a/packages/website/src/features/docs/api/filesApiDocPage.tsx +++ b/packages/website/src/features/docs/api/FilesApiDocPage.tsx @@ -15,12 +15,12 @@ import { updateOneFileRouteDefinition, updateOneFolderRouteDefinition, } from "@arrhes/application-metadata/routes" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocRouteRequest } from "../../../components/document/docRouteRequest.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function FilesApiDocPage() { return ( diff --git a/packages/website/src/features/docs/api/introductionApiDocPage.tsx b/packages/website/src/features/docs/api/IntroductionApiDocPage.tsx similarity index 93% rename from packages/website/src/features/docs/api/introductionApiDocPage.tsx rename to packages/website/src/features/docs/api/IntroductionApiDocPage.tsx index ab913571..4ff5128f 100644 --- a/packages/website/src/features/docs/api/introductionApiDocPage.tsx +++ b/packages/website/src/features/docs/api/IntroductionApiDocPage.tsx @@ -1,12 +1,12 @@ -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocLink } from "../../../components/document/docLink.tsx" -import { DocList } from "../../../components/document/docList.tsx" -import { DocNextPage } from "../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTable } from "../../../components/document/docTable.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../components/document/DocLink.tsx" +import { DocList } from "../../../components/document/DocList.tsx" +import { DocNextPage } from "../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTable } from "../../../components/document/DocTable.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function IntroductionApiDocPage() { return ( diff --git a/packages/website/src/features/docs/api/organizationApiDocPage.tsx b/packages/website/src/features/docs/api/OrganizationApiDocPage.tsx similarity index 92% rename from packages/website/src/features/docs/api/organizationApiDocPage.tsx rename to packages/website/src/features/docs/api/OrganizationApiDocPage.tsx index f97d38f5..c327ee53 100644 --- a/packages/website/src/features/docs/api/organizationApiDocPage.tsx +++ b/packages/website/src/features/docs/api/OrganizationApiDocPage.tsx @@ -17,13 +17,13 @@ import { updateOneOrganizationRouteDefinition, updateOneOrganizationUserRouteDefinition, } from "@arrhes/application-metadata/routes" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocNextPage } from "../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocRouteRequest } from "../../../components/document/docRouteRequest.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocNextPage } from "../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function OrganizationApiDocPage() { return ( diff --git a/packages/website/src/features/docs/api/rootApiDocPage.tsx b/packages/website/src/features/docs/api/RootApiDocPage.tsx similarity index 88% rename from packages/website/src/features/docs/api/rootApiDocPage.tsx rename to packages/website/src/features/docs/api/RootApiDocPage.tsx index ffa478a6..122f9a15 100644 --- a/packages/website/src/features/docs/api/rootApiDocPage.tsx +++ b/packages/website/src/features/docs/api/RootApiDocPage.tsx @@ -1,11 +1,11 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocLink } from "../../../components/document/docLink.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" -import { LinkButton } from "../../../components/linkButton.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../components/document/DocLink.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" +import { LinkButton } from "../../../components/LinkButton.tsx" export function RootApiDocPage() { return ( diff --git a/packages/website/src/features/docs/api/yearApiDocPage.tsx b/packages/website/src/features/docs/api/YearApiDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/api/yearApiDocPage.tsx rename to packages/website/src/features/docs/api/YearApiDocPage.tsx index 4f493ecb..2404255c 100644 --- a/packages/website/src/features/docs/api/yearApiDocPage.tsx +++ b/packages/website/src/features/docs/api/YearApiDocPage.tsx @@ -56,13 +56,13 @@ import { updateOneTagRouteDefinition, updateOneYearRouteDefinition, } from "@arrhes/application-metadata/routes" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocNextPage } from "../../../components/document/docNextPage.tsx" -import { DocParagraph } from "../../../components/document/docParagraph.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocRouteRequest } from "../../../components/document/docRouteRequest.tsx" -import { DocSection } from "../../../components/document/docSection.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocNextPage } from "../../../components/document/DocNextPage.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" export function YearApiDocPage() { return ( diff --git a/packages/website/src/features/docs/components/DataError.tsx b/packages/website/src/features/docs/components/DataError.tsx index 4ed20f08..805b704b 100644 --- a/packages/website/src/features/docs/components/DataError.tsx +++ b/packages/website/src/features/docs/components/DataError.tsx @@ -1,5 +1,5 @@ import { LinkContent } from "@arrhes/ui" -import { DocTip } from "../../../components/document/docTip.js" +import { DocTip } from "../../../components/document/DocTip.js" export function DataError() { return ( diff --git a/packages/website/src/features/docs/dashboard/BillingDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/BillingDashboardDocPage.tsx index 5e430999..41a4118b 100644 --- a/packages/website/src/features/docs/dashboard/BillingDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/BillingDashboardDocPage.tsx @@ -1,9 +1,9 @@ -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" export function BillingDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/entriesDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx similarity index 93% rename from packages/website/src/features/docs/dashboard/entriesDashboardDocPage.tsx rename to packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx index 2805eb09..11b9c968 100644 --- a/packages/website/src/features/docs/dashboard/entriesDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx @@ -1,13 +1,13 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocExample } from "../../../components/document/docExample.js" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocNextPage } from "../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" -import { DocTable } from "../../../components/document/docTable.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocNextPage } from "../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTable } from "../../../components/document/DocTable.js" export function EntriesDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/filesDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx similarity index 88% rename from packages/website/src/features/docs/dashboard/filesDashboardDocPage.tsx rename to packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx index d972f59e..0834fe80 100644 --- a/packages/website/src/features/docs/dashboard/filesDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx @@ -1,12 +1,12 @@ -import { DocExample } from "../../../components/document/docExample.js" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocNextPage } from "../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" -import { DocTip } from "../../../components/document/docTip.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocNextPage } from "../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTip } from "../../../components/document/DocTip.js" export function FilesDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx new file mode 100644 index 00000000..fab53a7c --- /dev/null +++ b/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx @@ -0,0 +1,191 @@ +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocNextPage } from "../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTip } from "../../../components/document/DocTip.js" + +export function GettingStartedDashboardDocPage() { + return ( + + + + + + Pour commencer à utiliser Arrhes, vous devez d'abord créer un compte utilisateur. Rendez-vous sur la + page d'inscription et renseignez votre adresse email et un mot de passe. + + + Un email de confirmation vous sera envoyé. Cliquez sur le lien pour activer votre compte. + + + + + + Une fois connecté, vous arrivez sur la page d'accueil. Si c'est votre première connexion, vous serez + invité à créer une organisation. + + + + + + Vous pouvez gérer plusieurs organisations depuis le même compte. Pratique si vous gérez une + entreprise et une association par exemple ! + + + + + + Après avoir créé votre organisation, vous devez définir un exercice comptable. L'exercice correspond + généralement à l'année civile (du 1er janvier au 31 décembre), mais vous pouvez choisir d'autres + dates. + + + + + + Le logiciel créera automatiquement un plan comptable adapté à votre type d'organisation. Vous + pourrez le personnaliser par la suite si nécessaire. + + + + + + Arrhes fonctionne comme un éditeur de code ou un navigateur : chaque vue s'ouvre dans un{" "} + onglet. Vous pouvez ainsi garder plusieurs contextes ouverts simultanément sans + perdre votre place. + + + + + + + + + + + + + + + + Vous pouvez naviguer dans l'historique d'un onglet avec les raccourcis clavier{" "} + Alt+Flèche gauche et Alt+Flèche droite, ou via le menu + contextuel. + + + + + + La palette de commandes est le moyen le plus rapide d'ouvrir n'importe quelle vue : organisations, + exercices, écritures, documents, paramètres… + + + + Appuyez sur Ctrl+K (ou ⌘+K sur Mac). + , + "Ou cliquez sur le bouton « Rechercher… » dans l'en-tête.", + "Ou cliquez sur le bouton « + » à droite de la barre d'onglets.", + ]} + /> + + + + + + + + + Arrhes permet d'afficher deux panneaux côte à côte pour comparer ou travailler sur deux vues en + même temps, par exemple consulter le journal pendant la saisie d'une écriture. + + + + + + + + + + + + Avant de commencer la saisie, assurez-vous de comprendre les bases de la comptabilité. Si vous + n'avez jamais fait de comptabilité, nous vous recommandons de lire notre{" "} + cours d'introduction. + + Les concepts clés à maîtriser sont : + + + + + + ) +} diff --git a/packages/website/src/features/docs/dashboard/organizationsDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx similarity index 88% rename from packages/website/src/features/docs/dashboard/organizationsDashboardDocPage.tsx rename to packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx index f6d3e398..24007ccb 100644 --- a/packages/website/src/features/docs/dashboard/organizationsDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx @@ -1,12 +1,12 @@ -import { DocDefinition } from "../../../components/document/docDefinition.js" -import { DocExample } from "../../../components/document/docExample.js" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocNextPage } from "../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" +import { DocDefinition } from "../../../components/document/DocDefinition.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocNextPage } from "../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" export function OrganizationsDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/reportsDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/ReportsDashboardDocPage.tsx similarity index 94% rename from packages/website/src/features/docs/dashboard/reportsDashboardDocPage.tsx rename to packages/website/src/features/docs/dashboard/ReportsDashboardDocPage.tsx index f17d0549..4c620ddb 100644 --- a/packages/website/src/features/docs/dashboard/reportsDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/ReportsDashboardDocPage.tsx @@ -1,11 +1,11 @@ -import { DocExample } from "../../../components/document/docExample.js" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" -import { DocTable } from "../../../components/document/docTable.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTable } from "../../../components/document/DocTable.js" export function ReportsDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/rootDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/RootDashboardDocPage.tsx similarity index 89% rename from packages/website/src/features/docs/dashboard/rootDashboardDocPage.tsx rename to packages/website/src/features/docs/dashboard/RootDashboardDocPage.tsx index 8b356079..8c59440e 100644 --- a/packages/website/src/features/docs/dashboard/rootDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/RootDashboardDocPage.tsx @@ -1,11 +1,11 @@ import { ButtonOutlineContent, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" -import { DocHeader } from "../../../components/document/docHeader.tsx" -import { DocLink } from "../../../components/document/docLink.tsx" -import { DocRoot } from "../../../components/document/docRoot.tsx" -import { DocTip } from "../../../components/document/docTip.tsx" -import { LinkButton } from "../../../components/linkButton.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocLink } from "../../../components/document/DocLink.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" +import { LinkButton } from "../../../components/LinkButton.tsx" export function RootDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/UpdatesDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/UpdatesDashboardDocPage.tsx index cb42dcd3..3b751079 100644 --- a/packages/website/src/features/docs/dashboard/UpdatesDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/UpdatesDashboardDocPage.tsx @@ -1,8 +1,8 @@ import { LinkContent } from "@arrhes/ui" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" export function UpdatesDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/yearsDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx similarity index 86% rename from packages/website/src/features/docs/dashboard/yearsDashboardDocPage.tsx rename to packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx index dba1838d..ee3576d7 100644 --- a/packages/website/src/features/docs/dashboard/yearsDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx @@ -1,11 +1,11 @@ -import { DocExample } from "../../../components/document/docExample.js" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocNextPage } from "../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocNextPage } from "../../../components/document/DocNextPage.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" export function YearsDashboardDocPage() { return ( diff --git a/packages/website/src/features/docs/dashboard/gettingStartedDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/gettingStartedDashboardDocPage.tsx deleted file mode 100644 index 5c579755..00000000 --- a/packages/website/src/features/docs/dashboard/gettingStartedDashboardDocPage.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import { DocExample } from "../../../components/document/docExample.js" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocLink } from "../../../components/document/docLink.js" -import { DocList } from "../../../components/document/docList.js" -import { DocNextPage } from "../../../components/document/docNextPage.js" -import { DocParagraph } from "../../../components/document/docParagraph.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocSection } from "../../../components/document/docSection.js" - -export function GettingStartedDashboardDocPage() { - return ( - - - - - - Pour commencer à utiliser Arrhes, vous devez d'abord créer un compte utilisateur. Rendez-vous sur la - page d'inscription et renseignez votre adresse email et un mot de passe. - - - Un email de confirmation vous sera envoyé. Cliquez sur le lien pour activer votre compte. - - - - - - Une fois connecté, vous arrivez sur la page d'accueil. Si c'est votre première connexion, vous serez - invité à créer une organisation. - - - - - - Vous pouvez gérer plusieurs organisations depuis le même compte. Pratique si vous gérez une - entreprise et une association par exemple ! - - - - - - Après avoir créé votre organisation, vous devez définir un exercice comptable. L'exercice correspond - généralement à l'année civile (du 1er janvier au 31 décembre), mais vous pouvez choisir d'autres - dates. - - - - - - Le logiciel créera automatiquement un plan comptable adapté à votre type d'organisation. Vous - pourrez le personnaliser par la suite si nécessaire. - - - - - L'interface d'Arrhes est organisée autour de plusieurs sections : - - - La navigation se fait via le menu upérieur. Chaque section est accessible en un clic depuis - n'importe quelle page. - - - - - - Avant de commencer la saisie, assurez-vous de comprendre les bases de la comptabilité. Si vous - n'avez jamais fait de comptabilité, nous vous recommandons de lire notre{" "} - cours d'introduction. - - Les concepts clés à maîtriser sont : - - - - - - ) -} diff --git a/packages/website/src/features/docs/docSections.tsx b/packages/website/src/features/docs/docSections.tsx index 0c4703bc..439335e0 100644 --- a/packages/website/src/features/docs/docSections.tsx +++ b/packages/website/src/features/docs/docSections.tsx @@ -10,7 +10,7 @@ import { IconRobot, IconStack, } from "@tabler/icons-react" -import type { DocSection } from "./sectionTab.tsx" +import type { DocSection } from "./SectionTab.tsx" // Documentation sections configuration export const docSections: Record = { diff --git a/packages/website/src/features/docs/general/legalGeneralDocPage.tsx b/packages/website/src/features/docs/general/LegalGeneralDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/general/legalGeneralDocPage.tsx rename to packages/website/src/features/docs/general/LegalGeneralDocPage.tsx index ff85926c..dc38d8c4 100644 --- a/packages/website/src/features/docs/general/legalGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/LegalGeneralDocPage.tsx @@ -1,9 +1,9 @@ import { LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import { DocLastUpdate } from "../../../components/document/docLastUpdate.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocTextSection } from "../../../components/document/docTextSection.js" -import { DocTip } from "../../../components/document/docTip.js" +import { DocLastUpdate } from "../../../components/document/DocLastUpdate.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocTextSection } from "../../../components/document/DocTextSection.js" +import { DocTip } from "../../../components/document/DocTip.js" export function LegalGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/privacyGeneralDocPage.tsx b/packages/website/src/features/docs/general/PrivacyGeneralDocPage.tsx similarity index 97% rename from packages/website/src/features/docs/general/privacyGeneralDocPage.tsx rename to packages/website/src/features/docs/general/PrivacyGeneralDocPage.tsx index 433aee88..480732ab 100644 --- a/packages/website/src/features/docs/general/privacyGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/PrivacyGeneralDocPage.tsx @@ -1,9 +1,9 @@ import { LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import { DocLastUpdate } from "../../../components/document/docLastUpdate.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocTextSection } from "../../../components/document/docTextSection.js" -import { LinkButton } from "../../../components/linkButton.js" +import { DocLastUpdate } from "../../../components/document/DocLastUpdate.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocTextSection } from "../../../components/document/DocTextSection.js" +import { LinkButton } from "../../../components/LinkButton.js" export function PrivacyGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/rootGeneralDocPage.tsx b/packages/website/src/features/docs/general/RootGeneralDocPage.tsx similarity index 91% rename from packages/website/src/features/docs/general/rootGeneralDocPage.tsx rename to packages/website/src/features/docs/general/RootGeneralDocPage.tsx index e8f03ee3..089eac0b 100644 --- a/packages/website/src/features/docs/general/rootGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/RootGeneralDocPage.tsx @@ -1,9 +1,9 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" -import { DocHeader } from "../../../components/document/docHeader.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { LinkButton } from "../../../components/linkButton.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { LinkButton } from "../../../components/LinkButton.js" export function RootGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/supportGeneralDocPage.tsx b/packages/website/src/features/docs/general/SupportGeneralDocPage.tsx similarity index 98% rename from packages/website/src/features/docs/general/supportGeneralDocPage.tsx rename to packages/website/src/features/docs/general/SupportGeneralDocPage.tsx index b8d5ab13..c4ce6c2b 100644 --- a/packages/website/src/features/docs/general/supportGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/SupportGeneralDocPage.tsx @@ -1,9 +1,9 @@ import { ButtonOutlineContent, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBrandGithub, IconBrandLinkedin, IconExternalLink, IconMail } from "@tabler/icons-react" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocTip } from "../../../components/document/docTip.js" -import { LinkButton } from "../../../components/linkButton.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocTip } from "../../../components/document/DocTip.js" +import { LinkButton } from "../../../components/LinkButton.js" export function SupportGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/termsGeneralDocPage.tsx b/packages/website/src/features/docs/general/TermsGeneralDocPage.tsx similarity index 97% rename from packages/website/src/features/docs/general/termsGeneralDocPage.tsx rename to packages/website/src/features/docs/general/TermsGeneralDocPage.tsx index 2ee83879..2f51cf5b 100644 --- a/packages/website/src/features/docs/general/termsGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/TermsGeneralDocPage.tsx @@ -1,8 +1,8 @@ import { LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import { DocLastUpdate } from "../../../components/document/docLastUpdate.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocTextSection } from "../../../components/document/docTextSection.js" +import { DocLastUpdate } from "../../../components/document/DocLastUpdate.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocTextSection } from "../../../components/document/DocTextSection.js" export function TermsGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/whitepaperGeneralDocPage.tsx b/packages/website/src/features/docs/general/WhitepaperGeneralDocPage.tsx similarity index 96% rename from packages/website/src/features/docs/general/whitepaperGeneralDocPage.tsx rename to packages/website/src/features/docs/general/WhitepaperGeneralDocPage.tsx index c8fef895..0ed7172c 100644 --- a/packages/website/src/features/docs/general/whitepaperGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/WhitepaperGeneralDocPage.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocLastUpdate } from "../../../components/document/docLastUpdate.js" -import { DocRoot } from "../../../components/document/docRoot.js" -import { DocTextSection } from "../../../components/document/docTextSection.js" +import { DocLastUpdate } from "../../../components/document/DocLastUpdate.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocTextSection } from "../../../components/document/DocTextSection.js" export function WhitepaperGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/features/featureCard.tsx b/packages/website/src/features/docs/general/features/FeatureCard.tsx similarity index 100% rename from packages/website/src/features/docs/general/features/featureCard.tsx rename to packages/website/src/features/docs/general/features/FeatureCard.tsx diff --git a/packages/website/src/features/docs/general/features/featuresGeneralDocPage.tsx b/packages/website/src/features/docs/general/features/FeaturesGeneralDocPage.tsx similarity index 98% rename from packages/website/src/features/docs/general/features/featuresGeneralDocPage.tsx rename to packages/website/src/features/docs/general/features/FeaturesGeneralDocPage.tsx index 8bee0815..5e6be66b 100644 --- a/packages/website/src/features/docs/general/features/featuresGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/features/FeaturesGeneralDocPage.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconBook, IconCode, IconFileText, IconLock, IconScan, IconSparkles, IconUsers } from "@tabler/icons-react" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { FeatureCard } from "./featureCard.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { FeatureCard } from "./FeatureCard.js" export function FeaturesGeneralDocPage() { return ( diff --git a/packages/website/src/features/docs/general/pricing/faqItem.tsx b/packages/website/src/features/docs/general/pricing/FaqItem.tsx similarity index 100% rename from packages/website/src/features/docs/general/pricing/faqItem.tsx rename to packages/website/src/features/docs/general/pricing/FaqItem.tsx diff --git a/packages/website/src/features/docs/general/pricing/pricingGeneralDocPage.tsx b/packages/website/src/features/docs/general/pricing/PricingGeneralDocPage.tsx similarity index 95% rename from packages/website/src/features/docs/general/pricing/pricingGeneralDocPage.tsx rename to packages/website/src/features/docs/general/pricing/PricingGeneralDocPage.tsx index c490bb81..12f1eb02 100644 --- a/packages/website/src/features/docs/general/pricing/pricingGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/pricing/PricingGeneralDocPage.tsx @@ -1,7 +1,7 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { DocRoot } from "../../../../components/document/docRoot.js" -import { Pricing } from "../../../home/pricing.js" -import { FaqItem } from "./faqItem.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { Pricing } from "../../../home/Pricing.js" +import { FaqItem } from "./FaqItem.js" export function PricingGeneralDocPage() { return ( diff --git a/packages/website/src/features/error/errorPage.tsx b/packages/website/src/features/error/ErrorPage.tsx similarity index 100% rename from packages/website/src/features/error/errorPage.tsx rename to packages/website/src/features/error/ErrorPage.tsx diff --git a/packages/website/src/features/facturation/ublInvoiceViewer.tsx b/packages/website/src/features/facturation/UblInvoiceViewer.tsx similarity index 100% rename from packages/website/src/features/facturation/ublInvoiceViewer.tsx rename to packages/website/src/features/facturation/UblInvoiceViewer.tsx diff --git a/packages/website/src/features/home/documentationBanner.tsx b/packages/website/src/features/home/DocumentationBanner.tsx similarity index 96% rename from packages/website/src/features/home/documentationBanner.tsx rename to packages/website/src/features/home/DocumentationBanner.tsx index c4bd4695..0301d562 100644 --- a/packages/website/src/features/home/documentationBanner.tsx +++ b/packages/website/src/features/home/DocumentationBanner.tsx @@ -1,7 +1,7 @@ import { ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconExternalLink } from "@tabler/icons-react" -import { Box } from "../../components/layouts/box.js" +import { Box } from "../../components/layouts/Box.js" export function DocumentationBanner() { return ( diff --git a/packages/website/src/features/home/featureItem.tsx b/packages/website/src/features/home/FeatureItem.tsx similarity index 100% rename from packages/website/src/features/home/featureItem.tsx rename to packages/website/src/features/home/FeatureItem.tsx diff --git a/packages/website/src/features/home/heroIllustration.tsx b/packages/website/src/features/home/HeroIllustration.tsx similarity index 100% rename from packages/website/src/features/home/heroIllustration.tsx rename to packages/website/src/features/home/HeroIllustration.tsx diff --git a/packages/website/src/features/home/homePage.tsx b/packages/website/src/features/home/HomePage.tsx similarity index 98% rename from packages/website/src/features/home/homePage.tsx rename to packages/website/src/features/home/HomePage.tsx index f15df78a..bb5061ec 100644 --- a/packages/website/src/features/home/homePage.tsx +++ b/packages/website/src/features/home/HomePage.tsx @@ -1,9 +1,9 @@ import { Badge, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Logo } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBook2, IconBrandGithub, IconBrandLinkedin, IconGavel, IconUser } from "@tabler/icons-react" -import { LinkButton } from "../../components/linkButton.js" -import { HeroIllustration } from "./heroIllustration.js" -import { Pricing } from "./pricing.js" +import { LinkButton } from "../../components/LinkButton.js" +import { HeroIllustration } from "./HeroIllustration.js" +import { Pricing } from "./Pricing.js" export function HomePage() { return ( diff --git a/packages/website/src/features/home/organizationsBanner.tsx b/packages/website/src/features/home/OrganizationsBanner.tsx similarity index 92% rename from packages/website/src/features/home/organizationsBanner.tsx rename to packages/website/src/features/home/OrganizationsBanner.tsx index 39308278..5bb694c6 100644 --- a/packages/website/src/features/home/organizationsBanner.tsx +++ b/packages/website/src/features/home/OrganizationsBanner.tsx @@ -1,8 +1,8 @@ import { ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBuilding } from "@tabler/icons-react" -import { Box } from "../../components/layouts/box.js" -import { LinkButton } from "../../components/linkButton.js" +import { Box } from "../../components/layouts/Box.js" +import { LinkButton } from "../../components/LinkButton.js" export function OrganizationsBanner() { return ( diff --git a/packages/website/src/features/home/pricing.tsx b/packages/website/src/features/home/Pricing.tsx similarity index 98% rename from packages/website/src/features/home/pricing.tsx rename to packages/website/src/features/home/Pricing.tsx index 773e14d4..c2722694 100644 --- a/packages/website/src/features/home/pricing.tsx +++ b/packages/website/src/features/home/Pricing.tsx @@ -14,8 +14,8 @@ import { IconUserPlus, IconUsers, } from "@tabler/icons-react" -import { LinkButton } from "../../components/linkButton.js" -import { FeatureItem } from "./featureItem.tsx" +import { LinkButton } from "../../components/LinkButton.js" +import { FeatureItem } from "./FeatureItem.tsx" export function Pricing() { return ( diff --git a/packages/website/src/features/notFound/notFoundPage.tsx b/packages/website/src/features/notFound/NotFoundPage.tsx similarity index 97% rename from packages/website/src/features/notFound/notFoundPage.tsx rename to packages/website/src/features/notFound/NotFoundPage.tsx index 07b5393e..f281bea8 100644 --- a/packages/website/src/features/notFound/notFoundPage.tsx +++ b/packages/website/src/features/notFound/NotFoundPage.tsx @@ -1,7 +1,7 @@ -import { ButtonOutlineContent } from "@arrhes/ui/components/buttons/buttonOutlineContent.js" +import { ButtonOutlineContent } from "@arrhes/ui/components/buttons/ButtonOutlineContent.js" import { css } from "@arrhes/ui/utilities/cn.js" import { IconBook2, IconHome } from "@tabler/icons-react" -import { LinkButton } from "../../components/linkButton.js" +import { LinkButton } from "../../components/LinkButton.js" export function NotFoundPage() { return ( diff --git a/packages/website/src/features/public/invoiceXml/publicInvoiceXmlPage.tsx b/packages/website/src/features/public/invoiceXml/PublicInvoiceXmlPage.tsx similarity index 100% rename from packages/website/src/features/public/invoiceXml/publicInvoiceXmlPage.tsx rename to packages/website/src/features/public/invoiceXml/PublicInvoiceXmlPage.tsx diff --git a/packages/website/src/features/signIn/resetPasswordPage.tsx b/packages/website/src/features/signIn/ResetPasswordPage.tsx similarity index 94% rename from packages/website/src/features/signIn/resetPasswordPage.tsx rename to packages/website/src/features/signIn/ResetPasswordPage.tsx index de40d9b8..e64276de 100644 --- a/packages/website/src/features/signIn/resetPasswordPage.tsx +++ b/packages/website/src/features/signIn/ResetPasswordPage.tsx @@ -2,13 +2,13 @@ import { resetPasswordRouteDefinition } from "@arrhes/application-metadata/route import { ButtonGhostContent, InputText, Logo, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconArrowLeft, IconBook2, IconMail } from "@tabler/icons-react" -import { FormControl } from "../../components/forms/formControl.js" -import { FormError } from "../../components/forms/formError.js" -import { FormField } from "../../components/forms/formField.js" -import { FormItem } from "../../components/forms/formItem.js" -import { FormLabel } from "../../components/forms/formLabel.js" -import { FormRoot } from "../../components/forms/formRoot.js" -import { LinkButton } from "../../components/linkButton.js" +import { FormControl } from "../../components/forms/FormControl.js" +import { FormError } from "../../components/forms/FormError.js" +import { FormField } from "../../components/forms/FormField.js" +import { FormItem } from "../../components/forms/FormItem.js" +import { FormLabel } from "../../components/forms/FormLabel.js" +import { FormRoot } from "../../components/forms/FormRoot.js" +import { LinkButton } from "../../components/LinkButton.js" import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" export function ResetPasswordPage() { diff --git a/packages/website/src/features/signIn/signInPage.tsx b/packages/website/src/features/signIn/SignInPage.tsx similarity index 95% rename from packages/website/src/features/signIn/signInPage.tsx rename to packages/website/src/features/signIn/SignInPage.tsx index 626fea5b..31522f3b 100644 --- a/packages/website/src/features/signIn/signInPage.tsx +++ b/packages/website/src/features/signIn/SignInPage.tsx @@ -3,13 +3,13 @@ import { ButtonGhostContent, ButtonOutlineContent, InputPassword, InputText, Log import { css } from "@arrhes/ui/utilities/cn.js" import { IconBook2, IconLogin2, IconUserPlus } from "@tabler/icons-react" import { Fragment } from "react/jsx-runtime" -import { FormControl } from "../../components/forms/formControl.js" -import { FormError } from "../../components/forms/formError.js" -import { FormField } from "../../components/forms/formField.js" -import { FormItem } from "../../components/forms/formItem.js" -import { FormLabel } from "../../components/forms/formLabel.js" -import { FormRoot } from "../../components/forms/formRoot.js" -import { LinkButton } from "../../components/linkButton.js" +import { FormControl } from "../../components/forms/FormControl.js" +import { FormError } from "../../components/forms/FormError.js" +import { FormField } from "../../components/forms/FormField.js" +import { FormItem } from "../../components/forms/FormItem.js" +import { FormLabel } from "../../components/forms/FormLabel.js" +import { FormRoot } from "../../components/forms/FormRoot.js" +import { LinkButton } from "../../components/LinkButton.js" import { setCookie } from "../../utilities/cookies/setCookie.js" import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" import { cookiePrefix } from "../../utilities/variables.js" diff --git a/packages/website/src/features/signUp/signUpPage.tsx b/packages/website/src/features/signUp/SignUpPage.tsx similarity index 96% rename from packages/website/src/features/signUp/signUpPage.tsx rename to packages/website/src/features/signUp/SignUpPage.tsx index 19195609..8ce03347 100644 --- a/packages/website/src/features/signUp/signUpPage.tsx +++ b/packages/website/src/features/signUp/SignUpPage.tsx @@ -3,13 +3,13 @@ import { ButtonGhostContent, ButtonOutlineContent, InputPassword, InputText, Log import { css } from "@arrhes/ui/utilities/cn.js" import { IconBook2, IconLogin2, IconUserPlus } from "@tabler/icons-react" import { Fragment } from "react/jsx-runtime" -import { FormControl } from "../../components/forms/formControl.js" -import { FormError } from "../../components/forms/formError.js" -import { FormField } from "../../components/forms/formField.js" -import { FormItem } from "../../components/forms/formItem.js" -import { FormLabel } from "../../components/forms/formLabel.js" -import { FormRoot } from "../../components/forms/formRoot.js" -import { LinkButton } from "../../components/linkButton.js" +import { FormControl } from "../../components/forms/FormControl.js" +import { FormError } from "../../components/forms/FormError.js" +import { FormField } from "../../components/forms/FormField.js" +import { FormItem } from "../../components/forms/FormItem.js" +import { FormLabel } from "../../components/forms/FormLabel.js" +import { FormRoot } from "../../components/forms/FormRoot.js" +import { LinkButton } from "../../components/LinkButton.js" import { setCookie } from "../../utilities/cookies/setCookie.js" import { getResponseBodyFromAPI } from "../../utilities/getResponseBodyFromAPI.js" import { cookiePrefix } from "../../utilities/variables.js" diff --git a/packages/website/src/root.tsx b/packages/website/src/root.tsx index c6007d0b..a723be78 100644 --- a/packages/website/src/root.tsx +++ b/packages/website/src/root.tsx @@ -1,7 +1,7 @@ import { StrictMode } from "react" import { createRoot } from "react-dom/client" import "./assets/css/root.css" -import { RootProvider } from "./contexts/rootProvider.js" +import { RootProvider } from "./contexts/RootProvider.js" const rootElement = document.getElementById("root")! if (!rootElement.innerHTML) { diff --git a/packages/website/src/routes/catchRoute.tsx b/packages/website/src/routes/catchRoute.tsx index dd421fac..6c95f28f 100644 --- a/packages/website/src/routes/catchRoute.tsx +++ b/packages/website/src/routes/catchRoute.tsx @@ -9,5 +9,5 @@ export const catchRoute = createRoute({ description: "La page que vous recherchez n'existe pas ou a été déplacée.", robots: "noindex", }), - component: lazyRouteComponent(() => import("../features/notFound/notFoundPage.js"), "NotFoundPage"), + component: lazyRouteComponent(() => import("../features/notFound/NotFoundPage.js"), "NotFoundPage"), }) diff --git a/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx index b4c40924..b6dbd41c 100644 --- a/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx @@ -18,7 +18,7 @@ export const adminLayoutRoute = createRoute({ } }, component: lazyRouteComponent( - () => import("../../../../features/dashboard/admin/adminPanelLayout.js"), + () => import("../../../../features/dashboard/admin/AdminPanelLayout.js"), "AdminPanelLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx index c4898cf3..3a882f48 100644 --- a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx @@ -10,7 +10,7 @@ export const $idTicketLayoutRoute = createRoute({ title: "Ticket", }), component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/admin/tickets/$idTicket/ticketLayout.js"), + () => import("../../../../../../features/dashboard/admin/tickets/$idTicket/TicketLayout.js"), "TicketLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx index 2e39cff3..341b3be3 100644 --- a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx +++ b/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx @@ -8,7 +8,7 @@ export const $idTicketRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/admin/tickets/$idTicket/ticketPage.js"), + () => import("../../../../../../features/dashboard/admin/tickets/$idTicket/TicketPage.js"), "TicketPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx index 4cb438d5..2b464e5d 100644 --- a/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx @@ -10,7 +10,7 @@ export const adminTicketsRoute = createRoute({ title: "Tickets", }), component: lazyRouteComponent( - () => import("../../../../../features/dashboard/admin/tickets/ticketsPage.js"), + () => import("../../../../../features/dashboard/admin/tickets/TicketsPage.js"), "TicketsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx index ed1a9aae..ad9f2d70 100644 --- a/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx @@ -8,7 +8,7 @@ export const agentLayoutRoute = createRoute({ title: "Assistant", }), component: lazyRouteComponent( - () => import("../../../../features/dashboard/$idOrganization/agent/agentLayout.js"), + () => import("../../../../features/dashboard/$idOrganization/agent/AgentLayout.js"), "AgentLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx index 069bf17b..c7fdc63e 100644 --- a/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx +++ b/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx @@ -8,7 +8,7 @@ export const agentRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../features/dashboard/$idOrganization/agent/agentPage.js"), + () => import("../../../../features/dashboard/$idOrganization/agent/AgentPage.js"), "AgentPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx index 8fdc75e0..eb2a103b 100644 --- a/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx +++ b/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx @@ -3,7 +3,7 @@ import { lazy, Suspense } from "react" import { agentSessionsLayoutRoute } from "./agentSessionsLayoutRoute.js" const AgentSessionPage = lazy(() => - import("../../../../features/dashboard/$idOrganization/agent/agentSessionPage.js").then((m) => ({ + import("../../../../features/dashboard/$idOrganization/agent/AgentSessionPage.js").then((m) => ({ default: m.AgentSessionPage, })), ) diff --git a/packages/website/src/routes/root/dashboard/dashboardCatchRoute.tsx b/packages/website/src/routes/root/dashboard/dashboardCatchRoute.tsx index 737ea11e..490ad689 100644 --- a/packages/website/src/routes/root/dashboard/dashboardCatchRoute.tsx +++ b/packages/website/src/routes/root/dashboard/dashboardCatchRoute.tsx @@ -8,7 +8,7 @@ export const dashboardCatchRoute = createRoute({ title: "Page introuvable", }), component: lazyRouteComponent( - () => import("../../../features/dashboard/dashboardNotFoundPage.js"), + () => import("../../../features/dashboard/DashboardNotFoundPage.js"), "DashboardNotFoundPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/dashboardLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/dashboardLayoutRoute.tsx index 170caf31..d3b19c1b 100644 --- a/packages/website/src/routes/root/dashboard/dashboardLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/dashboardLayoutRoute.tsx @@ -21,5 +21,5 @@ export const dashboardLayoutRoute = createRoute({ robots: "noindex, nofollow", } }, - component: lazyRouteComponent(() => import("../../../features/dashboard/dashboardLayout.js"), "DashboardLayout"), + component: lazyRouteComponent(() => import("../../../features/dashboard/dashboardLayout/DashboardLayout.js"), "DashboardLayout"), }) diff --git a/packages/website/src/routes/root/dashboard/dashboardRootRoute.tsx b/packages/website/src/routes/root/dashboard/dashboardRootRoute.tsx index afb76af7..b1abb5b6 100644 --- a/packages/website/src/routes/root/dashboard/dashboardRootRoute.tsx +++ b/packages/website/src/routes/root/dashboard/dashboardRootRoute.tsx @@ -1,5 +1,5 @@ import { createRoute } from "@tanstack/react-router" -import { DashboardDefaultPage } from "../../../features/dashboard/dashboardDefaultPage.js" +import { DashboardDefaultPage } from "../../../features/dashboard/DashboardDefaultPage.js" import { dashboardLayoutRoute } from "./dashboardLayoutRoute.js" export const dashboardRootRoute = createRoute({ diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx index 48e405e9..17de5917 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx @@ -10,7 +10,7 @@ export const organizationApiKeysRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationApi/keys/organizationApiKeysPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationApi/keys/OrganizationApiKeysPage.js" ), "OrganizationApiKeysPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx index 06abae39..13366fc2 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx @@ -8,7 +8,7 @@ export const organizationApiLayoutRoute = createRoute({ title: "API", }), component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idOrganization/organizationApi/organizationApiLayout.js"), + () => import("../../../../../../features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.js"), "OrganizationApiLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx index a50f7e1f..0acbf1f0 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx @@ -10,7 +10,7 @@ export const organizationApiRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationApi/organizationApiGeneralPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.js" ), "OrganizationApiGeneralPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx index fff4763c..13724bab 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx @@ -10,7 +10,7 @@ export const organizationBillingHistoryRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/organizationBillingHistoryPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationBilling/OrganizationBillingHistoryPage.js" ), "OrganizationBillingHistoryPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx index 785241a3..f2764f53 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx @@ -10,7 +10,7 @@ export const organizationBillingLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/organizationBillingLayout.js" + "../../../../../../features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.js" ), "OrganizationBillingLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx index 59cd923b..e2959e29 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx @@ -10,7 +10,7 @@ export const organizationBillingRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/wallet/organizationWalletPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationWalletPage.js" ), "OrganizationWalletPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx index b9997597..2118d6f0 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx @@ -10,7 +10,7 @@ export const organizationServicesRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/organizationServicesPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.js" ), "OrganizationServicesPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx index 522f8c81..6eabc5f1 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx @@ -10,7 +10,7 @@ export const organizationInvoiceUblRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicePage.js" + "../../../../../../features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.js" ), "OrganizationInvoicePage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx index f3a35bed..c83a6dce 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx @@ -10,7 +10,7 @@ export const organizationInvoicesRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/invoices/organizationInvoicesPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicesPage.js" ), "OrganizationInvoicesPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx index f58b22b3..ffd3db3d 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx @@ -8,7 +8,7 @@ export const organizationLayoutRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../features/dashboard/$idOrganization/organizationLayout.js"), + () => import("../../../../../features/dashboard/$idOrganization/OrganizationLayout.js"), "OrganizationLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx index 196f41f3..8267dde7 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx @@ -10,7 +10,7 @@ export const organizationSecurityRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationSettings/organizationSecurityPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationSettings/OrganizationSecurityPage.js" ), "OrganizationSecurityPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx index 0b39d8db..ce917e6a 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx @@ -10,7 +10,7 @@ export const organizationSettingsLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationSettings/organizationSettingsLayout.js" + "../../../../../../features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.js" ), "OrganizationSettingsLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx index d8490853..91c7dda1 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx @@ -10,7 +10,7 @@ export const organizationSettingsRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/dashboard/$idOrganization/organizationSettings/organizationSettingsPage.js" + "../../../../../../features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsPage.js" ), "OrganizationSettingsPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx index 3065da29..59d3a817 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx @@ -8,7 +8,7 @@ export const organizationUsersRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idOrganization/organizationUsers/organizationUsersPage.js"), + () => import("../../../../../../features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.js"), "OrganizationUsersPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx index 9af10259..b3262d2f 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx @@ -8,7 +8,7 @@ export const fileLayoutRoute = createRoute({ title: "Pièce justificative", }), component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/fileLayout.js"), + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FileLayout.js"), "FileLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx index 0b374f99..94dd299f 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx @@ -8,7 +8,7 @@ export const fileMetadataRoute = createRoute({ title: "Métadonnées", }), component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/fileMetadataTab.js"), + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FileMetadataTab.js"), "FileMetadataTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx index 306eea9a..e0130e18 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx @@ -8,7 +8,7 @@ export const fileRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/filePage.js"), + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FilePage.js"), "FilePage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx index eb84a4af..a8d7df33 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx @@ -8,7 +8,7 @@ export const fileVisualisationRoute = createRoute({ title: "Visualisation", }), component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/fileVisualisationTab.js"), + () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FileVisualisationTab.js"), "FileVisualisationTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx index 7562b11f..0057c6a8 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx @@ -11,7 +11,7 @@ export const storageRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idYear/files/filesPage.js"), + () => import("../../../../../../features/dashboard/$idYear/files/FilesPage.js"), "FilesPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx index 451fbcdf..f4892920 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx @@ -10,7 +10,7 @@ export const entryLineLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/entryLineLayout.js" + "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.js" ), "EntryLineLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx index 1a419175..dc534197 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx @@ -10,7 +10,7 @@ export const entryLineMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataTab.js" + "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.js" ), "EntryLineMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx index 9670772b..2f7580aa 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx @@ -10,7 +10,7 @@ export const entryLineRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/entryLinePage.js" + "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLinePage.js" ), "EntryLinePage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx index c0812003..80a48a67 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx @@ -8,7 +8,7 @@ export const entryCategoriesRoute = createRoute({ title: "Catégories", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/entryCategoriesTab.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryCategoriesTab.js"), "EntryCategoriesTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx index 7d61e80b..311ee4ee 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx @@ -8,7 +8,7 @@ export const entryLayoutRoute = createRoute({ title: "Écriture", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/entryLayout.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryLayout.js"), "EntryLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx index 26842d16..367f11cb 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx @@ -8,7 +8,7 @@ export const entryLinesRoute = createRoute({ title: "Mouvements", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/entryLinesTab.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.js"), "EntryLinesTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx index 1146223c..b9deb889 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx @@ -8,7 +8,7 @@ export const entryMetadataRoute = createRoute({ title: "Métadonnées", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/entryMetadataTab.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryMetadataTab.js"), "EntryMetadataTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx index bd41339c..4aed966d 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx @@ -8,7 +8,7 @@ export const entryRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/entryPage.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.js"), "EntryRoutePage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx index 0baf5388..0783bef0 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx @@ -8,7 +8,7 @@ export const entriesRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/entries/entriesPage.js"), + () => import("../../../../../../../../features/dashboard/$idYear/entries/EntriesPage.js"), "EntriesPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx index 500ae2a4..9354a48e 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx @@ -8,7 +8,7 @@ export const fileLayoutRoute = createRoute({ title: "Pièce justificative", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/fileLayout.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FileLayout.js"), "FileLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx index 27bd79c7..f6639906 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx @@ -8,7 +8,7 @@ export const fileMetadataRoute = createRoute({ title: "Métadonnées", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/fileMetadataTab.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FileMetadataTab.js"), "FileMetadataTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx index 8019018b..16cb84a3 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx @@ -8,7 +8,7 @@ export const fileRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/filePage.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FilePage.js"), "FilePage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx index 326a702e..e363ea44 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx @@ -8,7 +8,7 @@ export const fileVisualisationRoute = createRoute({ title: "Visualisation", }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/fileVisualisationTab.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FileVisualisationTab.js"), "FileVisualisationTab", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx index e73b18bb..21272fc1 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx @@ -11,7 +11,7 @@ export const filesRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/files/filesPage.js"), + () => import("../../../../../../../../features/dashboard/$idYear/files/FilesPage.js"), "FilesPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx index 3e3ba5f1..5bd88884 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx @@ -8,7 +8,7 @@ export const balanceReportRoute = createRoute({ title: "Balance", }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/balanceReport/balanceReportPage.js"), + () => import("../../../../../../../../features/dashboard/$idYear/reports/balanceReport/BalanceReportPage.js"), "BalanceReportPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx index 792574a3..b375a58c 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx @@ -10,7 +10,7 @@ export const balanceSheetReportRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../features/dashboard/$idYear/reports/balanceSheetReport/balanceSheetReportPage.js" + "../../../../../../../../features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPage.js" ), "BalanceSheetReportPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx index a376cd47..ff415f60 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx @@ -10,7 +10,7 @@ export const incomeStatementReportRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../features/dashboard/$idYear/reports/incomeStatementReport/incomeStatementReportPage.js" + "../../../../../../../../features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPage.js" ), "IncomeStatementReportPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx index 049d906e..32fed85c 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx @@ -8,7 +8,7 @@ export const journalReportRoute = createRoute({ title: "Livre-journal", }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/journalReport/journalReportPage.js"), + () => import("../../../../../../../../features/dashboard/$idYear/reports/journalReport/JournalReportPage.js"), "JournalReportPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx index 9d1af1d2..5340f371 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx @@ -8,7 +8,7 @@ export const ledgerReportRoute = createRoute({ title: "Grand livre", }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/ledgerReport/ledgerReportPage.js"), + () => import("../../../../../../../../features/dashboard/$idYear/reports/ledgerReport/LedgerReportPage.js"), "LedgerReportPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx index 1c7b065e..032338da 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx @@ -8,7 +8,7 @@ export const reportsLayoutRoute = createRoute({ title: "Documents comptables", }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/reportsLayout.js"), + () => import("../../../../../../../../features/dashboard/$idYear/reports/ReportsLayout.js"), "ReportsLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx index f22c2ada..e0698aec 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx @@ -24,7 +24,7 @@ export const yearLayoutRoute = createRoute({ } }, component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/yearLayout.js"), + () => import("../../../../../../../features/dashboard/$idYear/YearLayout.js"), "YearLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx index 5664678a..6d70fa86 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx @@ -10,7 +10,7 @@ export const accountLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountLayout.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.js" ), "AccountLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx index f75fbea4..b7832679 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx @@ -10,7 +10,7 @@ export const accountMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountMetadataTab.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.js" ), "AccountMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx index d0297bf0..ffe9ffa1 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx @@ -10,7 +10,7 @@ export const accountRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/accountPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountPage.js" ), "AccountPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx index a707ddd4..d846e1fc 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx @@ -8,7 +8,7 @@ export const accountsRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/accountsPage.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/AccountsPage.js"), "AccountsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx index 86015cd5..f02c11b6 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx @@ -10,7 +10,7 @@ export const balanceSheetLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayout.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.js" ), "BalanceSheetLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx index 2c1a094f..b16b3f7d 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx @@ -10,7 +10,7 @@ export const balanceSheetMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataTab.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.js" ), "BalanceSheetMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx index 9da00902..7eefd843 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx @@ -10,7 +10,7 @@ export const balanceSheetRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetPage.js" ), "BalanceSheetPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx index 02c8d768..a0b7710f 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx @@ -10,7 +10,7 @@ export const actifRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.js" ), "BalanceSheetsPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx index 609b4678..70667bc2 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx @@ -10,7 +10,7 @@ export const passifRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/balanceSheetsPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.js" ), "BalanceSheetsPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx index bf725a60..c6868a07 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx @@ -10,7 +10,7 @@ export const incomeStatementLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayout.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.js" ), "IncomeStatementLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx index 14356331..6f8bccbb 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx @@ -10,7 +10,7 @@ export const incomeStatementMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataTab.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.js" ), "IncomeStatementMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx index 81547666..1da41feb 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx @@ -10,7 +10,7 @@ export const incomeStatementRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementPage.js" ), "IncomeStatementPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx index 4b5dd152..d7e0f4d7 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx @@ -10,7 +10,7 @@ export const computationIncomeStatementLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementLayout.js" + "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.js" ), "ComputationIncomeStatementLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx index 519ed1a8..1e1ddc19 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx @@ -10,7 +10,7 @@ export const computationIncomeStatementMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementMetadataTab.js" + "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.js" ), "ComputationIncomeStatementMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx index a3cbb367..08eed31b 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx @@ -10,7 +10,7 @@ export const computationIncomeStatementRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/computationIncomeStatementPage.js" + "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementPage.js" ), "ComputationIncomeStatementPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx index c5d06932..8933ae74 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx @@ -10,7 +10,7 @@ export const computationLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayout.js" + "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationLayout.js" ), "ComputationLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx index 93d9634d..a4c2419d 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx @@ -10,7 +10,7 @@ export const computationMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataTab.js" + "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.js" ), "ComputationMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx index 126149dc..7d3b8ada 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx @@ -10,7 +10,7 @@ export const computationPostesRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesTab.js" + "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPostesTab.js" ), "ComputationPostesTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx index 9b808746..67910511 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx @@ -10,7 +10,7 @@ export const computationRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPage.js" + "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPage.js" ), "ComputationPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx index 4de88528..167b26c3 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx @@ -10,7 +10,7 @@ export const computationsRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/computationsPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.js" ), "ComputationsPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx index a198d0bc..97902f99 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx @@ -10,7 +10,7 @@ export const incomeStatementsRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/incomeStatementsPage.js" + "../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsPage.js" ), "IncomeStatementsPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx index db5d5d1b..b4187608 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx @@ -10,7 +10,7 @@ export const journalLayoutRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/journalLayout.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.js" ), "JournalLayout", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx index 1e30fece..760168d5 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx @@ -10,7 +10,7 @@ export const journalMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/journalMetadataTab.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.js" ), "JournalMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx index 4f1d2ccf..b1444341 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx @@ -10,7 +10,7 @@ export const journalRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/journalPage.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalPage.js" ), "JournalPage", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx index 51f3448c..ea59ddce 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx @@ -8,7 +8,7 @@ export const journalsRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/journalsPage.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/JournalsPage.js"), "JournalsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx index d71d98ef..5502bb75 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx @@ -8,7 +8,7 @@ export const tagLayoutRoute = createRoute({ title: "Catégorie", }), component: lazyRouteComponent( - () => import("../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/tagLayout.js"), + () => import("../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.js"), "TagLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx index d25d515a..8e694bcc 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx @@ -10,7 +10,7 @@ export const tagMetadataRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/tagMetadataTab.js" + "../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.js" ), "TagMetadataTab", ), diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx index 1161f058..d1d79bf9 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx @@ -8,7 +8,7 @@ export const tagRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/tagPage.js"), + () => import("../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/TagPage.js"), "TagPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx index 2c130a05..77eac6e2 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx @@ -8,7 +8,7 @@ export const tagsRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/tagsPage.js"), + () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/TagsPage.js"), "TagsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx index 2321bfb0..3f4d1c70 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx @@ -8,7 +8,7 @@ export const yearSettingsLayoutRoute = createRoute({ title: "Paramètres", }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/yearSettings/yearSettingsLayout.js"), + () => import("../../../../../../../../features/dashboard/$idYear/yearSettings/YearSettingsLayout.js"), "YearSettingsLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx index 505568e3..47ca8d97 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx @@ -8,7 +8,7 @@ export const yearSettingsRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/yearSettings/yearSettingsPage.js"), + () => import("../../../../../../../../features/dashboard/$idYear/yearSettings/YearSettingsPage.js"), "YearSettingsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx index dc254bf2..785d6851 100644 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx @@ -8,7 +8,7 @@ export const yearsRoute = createRoute({ title: "Exercices fiscaux", }), component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idOrganization/years/yearsPage.js"), + () => import("../../../../../../features/dashboard/$idOrganization/years/YearsPage.js"), "YearsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx index 551b0731..3e000230 100644 --- a/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx @@ -8,7 +8,7 @@ export const organizationsRoute = createRoute({ title: "Organisations", }), component: lazyRouteComponent( - () => import("../../../../features/dashboard/organizations/organizationsPage.js"), + () => import("../../../../features/dashboard/organizations/OrganizationsPage.js"), "OrganizationsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx b/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx index 1e346985..5c63304f 100644 --- a/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx +++ b/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx @@ -6,7 +6,7 @@ export const userProfileRoute = createRoute({ path: "/", beforeLoad: () => {}, component: lazyRouteComponent( - () => import("../../../../features/dashboard/profile/userProfilePage.js"), + () => import("../../../../features/dashboard/profile/UserProfilePage.js"), "UserProfilePage", ), }) diff --git a/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx b/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx index 59d1206e..e7429ff9 100644 --- a/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx +++ b/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx @@ -6,7 +6,7 @@ export const settingsRoute = createRoute({ path: "/", beforeLoad: () => {}, component: lazyRouteComponent( - () => import("../../../../features/dashboard/settings/settingsPage.js"), + () => import("../../../../features/dashboard/settings/SettingsPage.js"), "SettingsPage", ), }) diff --git a/packages/website/src/routes/root/dashboard/support/supportRoute.tsx b/packages/website/src/routes/root/dashboard/support/supportRoute.tsx index b5fd1ce9..da96efb9 100644 --- a/packages/website/src/routes/root/dashboard/support/supportRoute.tsx +++ b/packages/website/src/routes/root/dashboard/support/supportRoute.tsx @@ -7,5 +7,5 @@ export const supportRoute = createRoute({ beforeLoad: () => ({ title: undefined, }), - component: lazyRouteComponent(() => import("../../../../features/dashboard/support/supportPage.js"), "SupportPage"), + component: lazyRouteComponent(() => import("../../../../features/dashboard/support/SupportPage.js"), "SupportPage"), }) diff --git a/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx index 307ac2f6..dffd23fd 100644 --- a/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx +++ b/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx @@ -8,7 +8,7 @@ export const ticketLayoutRoute = createRoute({ title: "Ticket", }), component: lazyRouteComponent( - () => import("../../../../features/dashboard/support/$idTicket/ticketLayout.js"), + () => import("../../../../features/dashboard/support/$idTicket/TicketLayout.js"), "TicketLayout", ), }) diff --git a/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx b/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx index 73ee17c4..0387c5ee 100644 --- a/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx +++ b/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx @@ -8,7 +8,7 @@ export const ticketRoute = createRoute({ title: undefined, }), component: lazyRouteComponent( - () => import("../../../../features/dashboard/support/$idTicket/ticketPage.js"), + () => import("../../../../features/dashboard/support/$idTicket/TicketPage.js"), "TicketPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/introduction/accountsAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/introduction/accountsAccountingDocRoute.tsx index 7b40abc0..69ba10e4 100644 --- a/packages/website/src/routes/root/docs/accounting/introduction/accountsAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/introduction/accountsAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const accountsAccountingDocRoute = createRoute({ "Présentation des comptes comptables : structure, numérotation et fonctionnement du plan comptable général français.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/introduction/accountsAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/introduction/AccountsAccountingDocPage.tsx"), "AccountsAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/introduction/classesAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/introduction/classesAccountingDocRoute.tsx index 88634bd7..0fc170c7 100644 --- a/packages/website/src/routes/root/docs/accounting/introduction/classesAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/introduction/classesAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const classesAccountingDocRoute = createRoute({ "Les 8 classes du plan comptable général français : comptes de bilan (1 à 5) et comptes de gestion (6 et 7).", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/introduction/classesAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/introduction/ClassesAccountingDocPage.tsx"), "ClassesAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/introduction/doubleEntryAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/introduction/doubleEntryAccountingDocRoute.tsx index 05093534..0403b23d 100644 --- a/packages/website/src/routes/root/docs/accounting/introduction/doubleEntryAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/introduction/doubleEntryAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const doubleEntryAccountingDocRoute = createRoute({ "Comprendre le principe de la partie double en comptabilité : chaque opération génère au moins un débit et un crédit.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/introduction/doubleEntryAccountingDocPage.js"), + () => import("../../../../../features/docs/accounting/introduction/DoubleEntryAccountingDocPage.js"), "DoubleEntryAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/introduction/entriesAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/introduction/entriesAccountingDocRoute.tsx index 100f53f1..b0964385 100644 --- a/packages/website/src/routes/root/docs/accounting/introduction/entriesAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/introduction/entriesAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const entriesAccountingDocRoute = createRoute({ "Apprenez à passer des écritures comptables : lignes de débit et crédit, pièces justificatives et enregistrement des opérations.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/introduction/entriesAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/introduction/EntriesAccountingDocPage.tsx"), "EntriesAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/introduction/introductionAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/introduction/introductionAccountingDocRoute.tsx index efbcfd71..82179d53 100644 --- a/packages/website/src/routes/root/docs/accounting/introduction/introductionAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/introduction/introductionAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const introductionAccountingDocRoute = createRoute({ "Introduction aux fondamentaux de la comptabilité française : principes, obligations légales et concepts de base.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/introduction/introductionAccountingDocPage.js"), + () => import("../../../../../features/docs/accounting/introduction/IntroductionAccountingDocPage.js"), "IntroductionAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/balanceAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/balanceAccountingDocRoute.tsx index c4459ee7..7929d3e6 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/balanceAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/balanceAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const balanceAccountingDocRoute = createRoute({ "La balance comptable : tableau récapitulatif des soldes débiteurs et créditeurs de tous les comptes d'un exercice.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/balanceAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/BalanceAccountingDocPage.tsx"), "BalanceAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/balanceSheetAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/balanceSheetAccountingDocRoute.tsx index 1c9f4ddc..01bbee02 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/balanceSheetAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/balanceSheetAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const balanceSheetAccountingDocRoute = createRoute({ "Le bilan comptable : document de synthèse présentant le patrimoine de l'entreprise (actif et passif) à la clôture de l'exercice.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/balanceSheetAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/BalanceSheetAccountingDocPage.tsx"), "BalanceSheetAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/fecAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/fecAccountingDocRoute.tsx index ac6f49f6..9224667e 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/fecAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/fecAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const fecAccountingDocRoute = createRoute({ "Le FEC : fichier normé des écritures comptables requis par l'administration fiscale lors d'un contrôle.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/fecAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/FecAccountingDocPage.tsx"), "FecAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/incomeStatementAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/incomeStatementAccountingDocRoute.tsx index d7ff5df0..40e9a3ba 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/incomeStatementAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/incomeStatementAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const incomeStatementAccountingDocRoute = createRoute({ "Le compte de résultat : document de synthèse présentant les produits et charges de l'exercice pour déterminer le résultat net.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/incomeStatementAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/IncomeStatementAccountingDocPage.tsx"), "IncomeStatementAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/journalAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/journalAccountingDocRoute.tsx index 04d9f37d..e3ecd139 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/journalAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/journalAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const journalAccountingDocRoute = createRoute({ "Le journal comptable : document chronologique enregistrant toutes les opérations comptables de l'entreprise.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/journalAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/JournalAccountingDocPage.tsx"), "JournalAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/ledgerAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/ledgerAccountingDocRoute.tsx index 988290b4..75ed1ec4 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/ledgerAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/ledgerAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const ledgerAccountingDocRoute = createRoute({ "Le grand livre comptable : regroupement de toutes les écritures par compte, outil essentiel de suivi comptable.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/ledgerAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/LedgerAccountingDocPage.tsx"), "LedgerAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/notesAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/notesAccountingDocRoute.tsx index 41a36aac..e76a05d7 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/notesAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/notesAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const notesAccountingDocRoute = createRoute({ "L'annexe comptable : document complémentaire au bilan et au compte de résultat, fournissant des informations détaillées.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/notesAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/NotesAccountingDocPage.tsx"), "NotesAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/reports/reportsAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/reports/reportsAccountingDocRoute.tsx index 642d2bda..fe43e580 100644 --- a/packages/website/src/routes/root/docs/accounting/reports/reportsAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/reports/reportsAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const reportsAccountingDocRoute = createRoute({ "Les documents comptables obligatoires : journal, grand livre, balance, bilan, compte de résultat et annexe.", }), component: lazyRouteComponent( - () => import("../../../../../features/docs/accounting/reports/reportsAccountingDocPage.tsx"), + () => import("../../../../../features/docs/accounting/reports/ReportsAccountingDocPage.tsx"), "ReportsAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/accounting/resources/accounts/accountAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/resources/accounts/accountAccountingDocRoute.tsx index df7ddf54..87a12bbf 100644 --- a/packages/website/src/routes/root/docs/accounting/resources/accounts/accountAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/resources/accounts/accountAccountingDocRoute.tsx @@ -17,7 +17,7 @@ export const accountAccountingDocRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/docs/accounting/resources/accounts/accountResourcesAccountingDocPage.tsx" + "../../../../../../features/docs/accounting/resources/accounts/AccountResourcesAccountingDocPage.js" ), "AccountResourcesAccountingDocPage", ), diff --git a/packages/website/src/routes/root/docs/accounting/resources/accounts/accountsAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/resources/accounts/accountsAccountingDocRoute.tsx index 5d2b0956..885e948a 100644 --- a/packages/website/src/routes/root/docs/accounting/resources/accounts/accountsAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/resources/accounts/accountsAccountingDocRoute.tsx @@ -12,7 +12,7 @@ export const accountsAccountingDocRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/docs/accounting/resources/accounts/accountsResourcesAccountingDocPage.tsx" + "../../../../../../features/docs/accounting/resources/accounts/AccountsResourcesAccountingDocPage.js" ), "AccountsResourcesAccountingDocPage", ), diff --git a/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryAccountingDocRoute.tsx index ca665bc1..6ca8ab01 100644 --- a/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryAccountingDocRoute.tsx @@ -12,7 +12,7 @@ export const glossaryAccountingDocIndexRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/docs/accounting/resources/glossary/glossaryResourcesAccountingDocPage.tsx" + "../../../../../../features/docs/accounting/resources/glossary/GlossaryResourcesAccountingDocPage.js" ), "GlossaryResourcesAccountingDocPage", ), diff --git a/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryTermAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryTermAccountingDocRoute.tsx index 5f516b08..8bf10eba 100644 --- a/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryTermAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/resources/glossary/glossaryTermAccountingDocRoute.tsx @@ -17,7 +17,7 @@ export const glossaryTermAccountingDocRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/docs/accounting/resources/glossary/glossaryTermResourcesAccountingDocPage.tsx" + "../../../../../../features/docs/accounting/resources/glossary/GlossaryTermResourcesAccountingDocPage.js" ), "GlossaryTermResourcesAccountingDocPage", ), diff --git a/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenarioAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenarioAccountingDocRoute.tsx index d9acb253..247622fc 100644 --- a/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenarioAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenarioAccountingDocRoute.tsx @@ -16,7 +16,7 @@ export const scenarioAccountingDocRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/docs/accounting/resources/scenarios/scenarioResourcesAccountingDocPage.tsx" + "../../../../../../features/docs/accounting/resources/scenarios/ScenarioResourcesAccountingDocPage.js" ), "ScenarioResourcesAccountingDocPage", ), diff --git a/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenariosAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenariosAccountingDocRoute.tsx index fc8b2e93..818b5733 100644 --- a/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenariosAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/resources/scenarios/scenariosAccountingDocRoute.tsx @@ -11,7 +11,7 @@ export const scenariosAccountingDocIndexRoute = createRoute({ component: lazyRouteComponent( () => import( - "../../../../../../features/docs/accounting/resources/scenarios/scenariosResourcesAccountingDocPage.tsx" + "../../../../../../features/docs/accounting/resources/scenarios/ScenariosResourcesAccountingDocPage.js" ), "ScenariosResourcesAccountingDocPage", ), diff --git a/packages/website/src/routes/root/docs/accounting/rootAccountingDocRoute.tsx b/packages/website/src/routes/root/docs/accounting/rootAccountingDocRoute.tsx index e3706a58..80a32445 100644 --- a/packages/website/src/routes/root/docs/accounting/rootAccountingDocRoute.tsx +++ b/packages/website/src/routes/root/docs/accounting/rootAccountingDocRoute.tsx @@ -10,7 +10,7 @@ export const rootAccountingDocRoute = createRoute({ "Cours de comptabilité française complet : partie double, écritures, comptes, documents de synthèse et glossaire.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/accounting/introduction/rootAccountingDocPage.js"), + () => import("../../../../features/docs/accounting/introduction/RootAccountingDocPage.js"), "RootAccountingDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/ai/modelsAiDocRoute.tsx b/packages/website/src/routes/root/docs/ai/modelsAiDocRoute.tsx index 9fc0249c..93c1d633 100644 --- a/packages/website/src/routes/root/docs/ai/modelsAiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/ai/modelsAiDocRoute.tsx @@ -8,5 +8,5 @@ export const modelsAiDocRoute = createRoute({ title: "Modèles IA", description: "Les modèles de langage utilisés par l'assistant comptable d'Arrhes.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/ai/modelsAiDocPage.tsx"), "ModelsAiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/ai/ModelsAiDocPage.tsx"), "ModelsAiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/ai/ocrAiDocRoute.tsx b/packages/website/src/routes/root/docs/ai/ocrAiDocRoute.tsx index 4bd1d8ae..c84a7359 100644 --- a/packages/website/src/routes/root/docs/ai/ocrAiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/ai/ocrAiDocRoute.tsx @@ -8,5 +8,5 @@ export const ocrAiDocRoute = createRoute({ title: "OCR", description: "Reconnaissance optique de caractères pour l'extraction automatique de données comptables.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/ai/ocrAiDocPage.tsx"), "OcrAiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/ai/OcrAiDocPage.tsx"), "OcrAiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/ai/rootAiDocRoute.tsx b/packages/website/src/routes/root/docs/ai/rootAiDocRoute.tsx index fcaca6ab..bca31325 100644 --- a/packages/website/src/routes/root/docs/ai/rootAiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/ai/rootAiDocRoute.tsx @@ -9,5 +9,5 @@ export const rootAiDocRoute = createRoute({ description: "Documentation de l'assistant IA d'Arrhes : un assistant comptable intelligent pour gérer vos données.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/ai/rootAiDocPage.tsx"), "RootAiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/ai/RootAiDocPage.tsx"), "RootAiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/ai/toolsAiDocRoute.tsx b/packages/website/src/routes/root/docs/ai/toolsAiDocRoute.tsx index f7d0be60..01cec5ca 100644 --- a/packages/website/src/routes/root/docs/ai/toolsAiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/ai/toolsAiDocRoute.tsx @@ -8,5 +8,5 @@ export const toolsAiDocRoute = createRoute({ title: "Outils de l'assistant", description: "Liste complète des outils disponibles pour l'assistant comptable IA d'Arrhes.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/ai/toolsAiDocPage.tsx"), "ToolsAiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/ai/ToolsAiDocPage.tsx"), "ToolsAiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/api/authenticationApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/authenticationApiDocRoute.tsx index eccaae23..28ee2655 100644 --- a/packages/website/src/routes/root/docs/api/authenticationApiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/api/authenticationApiDocRoute.tsx @@ -10,7 +10,7 @@ export const authenticationApiDocRoute = createRoute({ "Authentification à l'API Arrhes : gestion des clés API, sessions utilisateurs et sécurité des requêtes.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/api/authenticationApiDocPage.tsx"), + () => import("../../../../features/docs/api/AuthenticationApiDocPage.tsx"), "AuthenticationApiDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/api/filesApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/filesApiDocRoute.tsx index bca7efb9..9c04ea55 100644 --- a/packages/website/src/routes/root/docs/api/filesApiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/api/filesApiDocRoute.tsx @@ -9,5 +9,5 @@ export const filesApiDocRoute = createRoute({ description: "Endpoints API pour la gestion des fichiers et documents : upload, téléchargement et association aux écritures.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/api/filesApiDocPage.tsx"), "FilesApiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/api/FilesApiDocPage.tsx"), "FilesApiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/api/introductionApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/introductionApiDocRoute.tsx index 9fffbe8f..79a791c2 100644 --- a/packages/website/src/routes/root/docs/api/introductionApiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/api/introductionApiDocRoute.tsx @@ -10,7 +10,7 @@ export const introductionApiDocRoute = createRoute({ "Introduction à l'API Arrhes : authentification, format des requêtes, gestion des erreurs et bonnes pratiques.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/api/introductionApiDocPage.tsx"), + () => import("../../../../features/docs/api/IntroductionApiDocPage.tsx"), "IntroductionApiDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/api/organizationApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/organizationApiDocRoute.tsx index 4ee4cd0e..ce7cc095 100644 --- a/packages/website/src/routes/root/docs/api/organizationApiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/api/organizationApiDocRoute.tsx @@ -10,7 +10,7 @@ export const organizationApiDocRoute = createRoute({ "Endpoints API pour la gestion des organisations Arrhes : création, lecture, mise à jour et suppression.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/api/organizationApiDocPage.tsx"), + () => import("../../../../features/docs/api/OrganizationApiDocPage.tsx"), "OrganizationApiDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/api/rootApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/rootApiDocRoute.tsx index bbf32b84..2f9cfc4e 100644 --- a/packages/website/src/routes/root/docs/api/rootApiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/api/rootApiDocRoute.tsx @@ -9,5 +9,5 @@ export const rootApiDocRoute = createRoute({ description: "Documentation de l'API Arrhes : endpoints REST pour intégrer la comptabilité dans vos applications.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/api/rootApiDocPage.tsx"), "RootApiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/api/RootApiDocPage.tsx"), "RootApiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/api/yearApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/yearApiDocRoute.tsx index 6eae9b1e..e2b43e6d 100644 --- a/packages/website/src/routes/root/docs/api/yearApiDocRoute.tsx +++ b/packages/website/src/routes/root/docs/api/yearApiDocRoute.tsx @@ -9,5 +9,5 @@ export const yearApiDocRoute = createRoute({ description: "Endpoints API pour la gestion des exercices comptables : création, ouverture, clôture et consultation.", }), - component: lazyRouteComponent(() => import("../../../../features/docs/api/yearApiDocPage.tsx"), "YearApiDocPage"), + component: lazyRouteComponent(() => import("../../../../features/docs/api/YearApiDocPage.tsx"), "YearApiDocPage"), }) diff --git a/packages/website/src/routes/root/docs/dashboard/entriesDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/entriesDashboardDocRoute.tsx index 19ecd97c..d4ee76e7 100644 --- a/packages/website/src/routes/root/docs/dashboard/entriesDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/entriesDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const entriesDashboardDocRoute = createRoute({ "Saisissez et gérez vos écritures comptables dans Arrhes : création, modification, suppression et recherche d'écritures.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/entriesDashboardDocPage.js"), + () => import("../../../../features/docs/dashboard/EntriesDashboardDocPage.js"), "EntriesDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/dashboard/filesDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/filesDashboardDocRoute.tsx index 02daf378..53b43ef5 100644 --- a/packages/website/src/routes/root/docs/dashboard/filesDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/filesDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const filesDashboardDocRoute = createRoute({ "Gérez vos pièces justificatives dans Arrhes : importation, association aux écritures et stockage sécurisé de vos documents.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/filesDashboardDocPage.js"), + () => import("../../../../features/docs/dashboard/FilesDashboardDocPage.js"), "FilesDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/dashboard/gettingStartedDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/gettingStartedDashboardDocRoute.tsx index b5b114fd..c07d3c16 100644 --- a/packages/website/src/routes/root/docs/dashboard/gettingStartedDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/gettingStartedDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const gettingStartedDashboardDocRoute = createRoute({ "Guide de démarrage rapide d'Arrhes : créez votre compte, configurez votre première organisation et commencez votre comptabilité.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/gettingStartedDashboardDocPage.tsx"), + () => import("../../../../features/docs/dashboard/GettingStartedDashboardDocPage.tsx"), "GettingStartedDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/dashboard/organizationsDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/organizationsDashboardDocRoute.tsx index e2c83d73..b1057ea9 100644 --- a/packages/website/src/routes/root/docs/dashboard/organizationsDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/organizationsDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const organizationsDashboardDocRoute = createRoute({ "Gérez vos organisations dans Arrhes : création, paramétrage, gestion des membres et des abonnements.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/organizationsDashboardDocPage.js"), + () => import("../../../../features/docs/dashboard/OrganizationsDashboardDocPage.js"), "OrganizationsDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/dashboard/reportsDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/reportsDashboardDocRoute.tsx index 1ef418be..c4731822 100644 --- a/packages/website/src/routes/root/docs/dashboard/reportsDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/reportsDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const reportsDashboardDocRoute = createRoute({ "Générez vos documents comptables de synthèse dans Arrhes : journal, grand livre, balance, bilan et compte de résultat.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/reportsDashboardDocPage.tsx"), + () => import("../../../../features/docs/dashboard/ReportsDashboardDocPage.tsx"), "ReportsDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/dashboard/rootDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/rootDashboardDocRoute.tsx index 15b48322..e7f347eb 100644 --- a/packages/website/src/routes/root/docs/dashboard/rootDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/rootDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const rootDashboardDocRoute = createRoute({ "Guide d'utilisation du dashboard Arrhes : créez vos organisations, gérez vos exercices et saisissez vos écritures comptables.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/rootDashboardDocPage.tsx"), + () => import("../../../../features/docs/dashboard/RootDashboardDocPage.tsx"), "RootDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/dashboard/yearsDashboardDocRoute.tsx b/packages/website/src/routes/root/docs/dashboard/yearsDashboardDocRoute.tsx index cb617934..de7a0391 100644 --- a/packages/website/src/routes/root/docs/dashboard/yearsDashboardDocRoute.tsx +++ b/packages/website/src/routes/root/docs/dashboard/yearsDashboardDocRoute.tsx @@ -10,7 +10,7 @@ export const yearsDashboardDocRoute = createRoute({ "Gérez vos exercices comptables dans Arrhes : création, ouverture, clôture et paramétrage des périodes fiscales.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/dashboard/yearsDashboardDocPage.js"), + () => import("../../../../features/docs/dashboard/YearsDashboardDocPage.js"), "YearsDashboardDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/docsLayoutRoute.tsx b/packages/website/src/routes/root/docs/docsLayoutRoute.tsx index ab540ba8..4ea39288 100644 --- a/packages/website/src/routes/root/docs/docsLayoutRoute.tsx +++ b/packages/website/src/routes/root/docs/docsLayoutRoute.tsx @@ -12,5 +12,5 @@ export const docsLayoutRoute = createRoute({ description: "Documentation complète d'Arrhes : guide d'utilisation, cours de comptabilité, référence API et informations générales.", }), - component: lazyRouteComponent(() => import("../../../features/docs/docsLayout.js"), "DocsLayout"), + component: lazyRouteComponent(() => import("../../../features/docs/DocsLayout.js"), "DocsLayout"), }) diff --git a/packages/website/src/routes/root/docs/root/featuresGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/featuresGeneralDocRoute.tsx index c1298aca..8bfde20a 100644 --- a/packages/website/src/routes/root/docs/root/featuresGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/featuresGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const featuresGeneralDocRoute = createRoute({ "Découvrez les fonctionnalités d'Arrhes : saisie d'écritures, plan comptable, documents de synthèse, gestion multi-organisations et plus.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/features/featuresGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/features/FeaturesGeneralDocPage.tsx"), "FeaturesGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/legalGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/legalGeneralDocRoute.tsx index 82a643f9..eb7da105 100644 --- a/packages/website/src/routes/root/docs/root/legalGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/legalGeneralDocRoute.tsx @@ -9,7 +9,7 @@ export const legalGeneralDocRoute = createRoute({ description: "Mentions légales du logiciel de comptabilité Arrhes. Informations sur l'éditeur et l'hébergeur.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/legalGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/LegalGeneralDocPage.tsx"), "LegalGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/pricingGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/pricingGeneralDocRoute.tsx index ae7cab04..5acf6bbc 100644 --- a/packages/website/src/routes/root/docs/root/pricingGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/pricingGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const pricingGeneralDocRoute = createRoute({ "Consultez les tarifs d'Arrhes. Plan basique gratuit et services payants optionnels (licence, stockage, OCR et tokens IA).", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/pricing/pricingGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/pricing/PricingGeneralDocPage.tsx"), "PricingGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/privacyGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/privacyGeneralDocRoute.tsx index a8881a16..f39f85b9 100644 --- a/packages/website/src/routes/root/docs/root/privacyGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/privacyGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const privacyGeneralDocRoute = createRoute({ "Politique de confidentialité d'Arrhes. Découvrez comment nous protégeons vos données personnelles et comptables.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/privacyGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/PrivacyGeneralDocPage.tsx"), "PrivacyGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/rootGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/rootGeneralDocRoute.tsx index 30cbef83..57876f0b 100644 --- a/packages/website/src/routes/root/docs/root/rootGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/rootGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const rootGeneralDocRoute = createRoute({ "Documentation complète d'Arrhes : guide d'utilisation, cours de comptabilité, référence API et informations générales.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/rootGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/RootGeneralDocPage.tsx"), "RootGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/supportGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/supportGeneralDocRoute.tsx index d8adbdfb..6538da74 100644 --- a/packages/website/src/routes/root/docs/root/supportGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/supportGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const supportGeneralDocRoute = createRoute({ "Besoin d'aide avec Arrhes ? Contactez notre support ou consultez la documentation pour résoudre vos problèmes.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/supportGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/SupportGeneralDocPage.tsx"), "SupportGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/termsGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/termsGeneralDocRoute.tsx index 19d910d8..bac7cea9 100644 --- a/packages/website/src/routes/root/docs/root/termsGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/termsGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const termsGeneralDocRoute = createRoute({ "Conditions Générales d'Utilisation d'Arrhes. Consultez les règles et conditions d'utilisation du logiciel.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/termsGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/TermsGeneralDocPage.tsx"), "TermsGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/docs/root/whitepaperGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/whitepaperGeneralDocRoute.tsx index 80151250..119ff186 100644 --- a/packages/website/src/routes/root/docs/root/whitepaperGeneralDocRoute.tsx +++ b/packages/website/src/routes/root/docs/root/whitepaperGeneralDocRoute.tsx @@ -10,7 +10,7 @@ export const whitepaperGeneralDocRoute = createRoute({ "La philosophie d'Arrhes : transparence, open source et accessibilité pour la comptabilité des entreprises et associations.", }), component: lazyRouteComponent( - () => import("../../../../features/docs/general/whitepaperGeneralDocPage.tsx"), + () => import("../../../../features/docs/general/WhitepaperGeneralDocPage.tsx"), "WhitepaperGeneralDocPage", ), }) diff --git a/packages/website/src/routes/root/errorRoute.tsx b/packages/website/src/routes/root/errorRoute.tsx index 2ea162a7..79b7435a 100644 --- a/packages/website/src/routes/root/errorRoute.tsx +++ b/packages/website/src/routes/root/errorRoute.tsx @@ -8,5 +8,5 @@ export const errorRoute = createRoute({ title: "Error", robots: "noindex", }), - component: lazyRouteComponent(() => import("../../features/error/errorPage.js"), "ErrorPage"), + component: lazyRouteComponent(() => import("../../features/error/ErrorPage.js"), "ErrorPage"), }) diff --git a/packages/website/src/routes/root/home/homeRootRoute.tsx b/packages/website/src/routes/root/home/homeRootRoute.tsx index 2ec87e13..5db6add3 100644 --- a/packages/website/src/routes/root/home/homeRootRoute.tsx +++ b/packages/website/src/routes/root/home/homeRootRoute.tsx @@ -1,5 +1,5 @@ import { createRoute } from "@tanstack/react-router" -import { HomePage } from "../../../features/home/homePage.tsx" +import { HomePage } from "../../../features/home/HomePage.tsx" import { homeLayoutRoute } from "./homeLayoutRoute.tsx" export const homeRootRoute = createRoute({ diff --git a/packages/website/src/routes/root/publicInvoiceXmlRoute.tsx b/packages/website/src/routes/root/publicInvoiceXmlRoute.tsx index 4ecd0954..4a3557db 100644 --- a/packages/website/src/routes/root/publicInvoiceXmlRoute.tsx +++ b/packages/website/src/routes/root/publicInvoiceXmlRoute.tsx @@ -12,7 +12,7 @@ export const publicInvoiceXmlRoute = createRoute({ robots: "noindex, nofollow", }), component: lazyRouteComponent( - () => import("../../features/public/invoiceXml/publicInvoiceXmlPage.js"), + () => import("../../features/public/invoiceXml/PublicInvoiceXmlPage.js"), "PublicInvoiceXmlPage", ), }) diff --git a/packages/website/src/routes/root/signIn/resetPasswordRoute.tsx b/packages/website/src/routes/root/signIn/resetPasswordRoute.tsx index 24481177..d03963b8 100644 --- a/packages/website/src/routes/root/signIn/resetPasswordRoute.tsx +++ b/packages/website/src/routes/root/signIn/resetPasswordRoute.tsx @@ -18,5 +18,5 @@ export const resetPasswordRoute = createRoute({ description: "Recevez un nouveau mot de passe temporaire par email.", } }, - component: lazyRouteComponent(() => import("../../../features/signIn/resetPasswordPage.js"), "ResetPasswordPage"), + component: lazyRouteComponent(() => import("../../../features/signIn/ResetPasswordPage.js"), "ResetPasswordPage"), }) diff --git a/packages/website/src/routes/root/signIn/signInRoute.tsx b/packages/website/src/routes/root/signIn/signInRoute.tsx index ffd5548c..741035b6 100644 --- a/packages/website/src/routes/root/signIn/signInRoute.tsx +++ b/packages/website/src/routes/root/signIn/signInRoute.tsx @@ -18,5 +18,5 @@ export const signInRoute = createRoute({ description: "Connectez-vous à votre compte Arrhes pour accéder à votre espace comptable.", } }, - component: lazyRouteComponent(() => import("../../../features/signIn/signInPage.js"), "SignInPage"), + component: lazyRouteComponent(() => import("../../../features/signIn/SignInPage.js"), "SignInPage"), }) diff --git a/packages/website/src/routes/root/signUp/signUpRoute.tsx b/packages/website/src/routes/root/signUp/signUpRoute.tsx index c11aec9e..0451c969 100644 --- a/packages/website/src/routes/root/signUp/signUpRoute.tsx +++ b/packages/website/src/routes/root/signUp/signUpRoute.tsx @@ -19,5 +19,5 @@ export const signUpRoute = createRoute({ "Créez votre compte Arrhes gratuitement et commencez à gérer votre comptabilité en quelques minutes.", } }, - component: lazyRouteComponent(() => import("../../../features/signUp/signUpPage.js"), "SignUpPage"), + component: lazyRouteComponent(() => import("../../../features/signUp/SignUpPage.js"), "SignUpPage"), }) diff --git a/packages/website/src/routes/rootLayoutRoute.tsx b/packages/website/src/routes/rootLayoutRoute.tsx index fb35acd6..1bcd65c3 100644 --- a/packages/website/src/routes/rootLayoutRoute.tsx +++ b/packages/website/src/routes/rootLayoutRoute.tsx @@ -3,7 +3,7 @@ import { CircularLoader } from "@arrhes/ui" import { createRootRouteWithContext, useRouterState } from "@tanstack/react-router" import { Fragment } from "react/jsx-runtime" import type * as v from "valibot" -import { RootLayout } from "../features/rootLayout.js" +import { RootLayout } from "../features/RootLayout.js" const DEFAULT_DESCRIPTION = "Logiciel de comptabilité open source pour les entreprises et associations françaises. Gérez vos écritures, comptes et documents comptables simplement." From 83cdf9215163c0ee882f2a66dde17d2e7cc87413 Mon Sep 17 00:00:00 2001 From: &mile Date: Fri, 15 May 2026 22:32:23 +0200 Subject: [PATCH 08/14] refactor(dashboard): remove SubPageLayout and PageNavigation from layout components Replace all SubPageLayout and PageNavigation usages in dashboard layout components with simple passthroughs. This removes the sidebar nav and top navigation from OrganizationLayout, YearLayout, AdminPanelLayout, OrganizationBillingLayout, OrganizationApiLayout, OrganizationSettingsLayout, ReportsLayout, and YearSettingsLayout. Also includes prior commits: - Add Page.Banners sub-component (before header) - Simplify SubPageContent to tab-only system (remove split panel) - Remove old dashboard route sub-trees (organizations, admin, agent, profile, settings, support) and fix all broken imports --- packages/ui/package.json | 3 +- packages/ui/src/components/buttons/button.tsx | 95 ---- .../src/components/inputs/InputCombobox.tsx | 21 +- .../inputs/InputComboboxMultiple.tsx | 5 +- .../components/overlays/dialog/DialogBody.tsx | 2 +- .../overlays/dialog/DialogContent.tsx | 33 ++ .../overlays/dialog/DialogDescription.tsx | 17 + .../overlays/dialog/DialogFooter.tsx | 2 +- .../overlays/dialog/DialogHeader.tsx | 13 +- .../overlays/dialog/DialogTitle.tsx | 17 + .../src/components/overlays/dialog/dialog.tsx | 15 + .../overlays/popover/PopoverContent.tsx | 127 ++++- .../overlays/popover/popoverClose.tsx | 33 +- .../overlays/popover/popoverRoot.tsx | 61 ++- .../overlays/popover/popoverTrigger.tsx | 45 +- packages/ui/src/index.ts | 6 + packages/ui/src/stores/index.ts | 4 + packages/ui/src/stores/modalStore.tsx | 187 +++++++ packages/ui/src/stores/popoverStore.tsx | 168 ++++++ packages/website/package.json | 4 +- .../src/components/layouts/SubPageContent.tsx | 368 ++----------- .../layouts/commandPalette/CommandPalette.tsx | 11 +- .../layouts/commandPalette/commandPalette.tsx | 485 ------------------ .../components/layouts/page/PageBanners.tsx | 20 + .../src/components/layouts/page/page.tsx | 2 + .../components/layouts/tabBar/SplitTabBar.tsx | 2 +- .../src/components/layouts/tabBar/TabBar.tsx | 2 +- .../overlays/dialog/ConfirmationModal.tsx | 83 --- .../overlays/dialog/DialogContent.tsx | 47 -- .../overlays/dialog/DialogDescription.tsx | 18 - .../overlays/dialog/DialogOverlay.tsx | 34 -- .../components/overlays/dialog/DialogRoot.tsx | 13 - .../overlays/dialog/DialogTitle.tsx | 18 - .../src/components/overlays/dialog/dialog.tsx | 24 +- .../overlays/dialog/dialogPortal.tsx | 3 - .../overlays/dialog/dialogTrigger.tsx | 3 - .../overlays/popover/PopoverContent.tsx | 37 +- .../overlays/popover/popoverClose.tsx | 4 +- .../overlays/popover/popoverRoot.tsx | 4 +- .../overlays/popover/popoverTrigger.tsx | 4 +- .../website/src/contexts/RootProvider.tsx | 16 +- .../website/src/contexts/tabs/tabsContext.tsx | 3 +- .../src/contexts/tabs/tabsProvider.tsx | 64 ++- .../$idOrganization/OrganizationLayout.tsx | 84 +-- .../$idOrganization/agent/AgentLayout.tsx | 16 +- .../agent/AgentSessionContent.tsx | 305 +++++------ .../organizationApi/OrganizationApiLayout.tsx | 36 +- .../organizationApi/keys/DeleteOneApiKey.tsx | 42 +- .../CancelSubscription.tsx | 96 ++-- .../OrganizationBillingLayout.tsx | 52 +- .../ResumeSubscription.tsx | 87 ++-- .../organizationBilling/UpdateLicencePage.tsx | 43 +- .../organizationBilling/UpdateOcrPage.tsx | 46 +- .../organizationBilling/UpdateStoragePage.tsx | 61 ++- .../organizationBilling/UpdateTokensPage.tsx | 44 +- .../invoices/OrganizationInvoicePage.tsx | 6 +- .../DeleteOneOrganization.tsx | 99 ++-- .../OrganizationSettingsLayout.tsx | 36 +- .../DeleteOneOrganizationUser.tsx | 40 +- .../features/dashboard/$idYear/YearLayout.tsx | 47 +- .../$idEntryLine/DeleteOneEntryLine.tsx | 47 +- .../$idEntry/$idEntryLine/EntryLineLayout.tsx | 6 +- .../$idEntryLine/EntryLineMetadataTab.tsx | 6 +- .../$idEntry/$idEntryLine/EntryLinePage.tsx | 6 +- .../$idEntryLine/UpdateOneEntryLine.tsx | 1 + .../entries/$idEntry/CreateOneEntryLine.tsx | 1 + .../entries/$idEntry/DeleteOneEntry.tsx | 47 +- .../entries/$idEntry/DuplicateOneEntry.tsx | 102 ++-- ...EntryPage.tsx => EntryInformationsTab.tsx} | 52 +- .../$idYear/entries/$idEntry/EntryLayout.tsx | 6 +- .../entries/$idEntry/EntryLinesTab.tsx | 17 +- .../entries/$idEntry/EntryTabContent.tsx | 150 +++--- .../entries/$idEntry/UpdateManyEntryLines.tsx | 1 + .../entries/$idEntry/UpdateOneEntry.tsx | 13 +- .../$idYear/entries/$idEntry/entryPage.tsx | 118 ----- .../entries/EntriesTableSelectionActions.tsx | 48 +- .../$idYear/entries/ReverseOneEntry.tsx | 46 +- .../$idYear/files/$idFile/DeleteOneFile.tsx | 47 +- .../$idYear/files/$idFile/FileLayout.tsx | 6 +- .../$idYear/files/$idFile/UpdateOneFile.tsx | 1 + .../dashboard/$idYear/files/FileActions.tsx | 95 ++-- .../$idYear/files/FileContextMenu.tsx | 96 ++-- .../dashboard/$idYear/files/FilesPage.tsx | 15 +- .../files/FilesTableSelectionActions.tsx | 64 ++- .../dashboard/$idYear/files/FolderActions.tsx | 98 ++-- .../$idYear/files/FolderContextMenu.tsx | 99 ++-- .../$idYear/reports/ReportsLayout.tsx | 73 +-- .../$idYear/yearSettings/DeleteOneYear.tsx | 46 +- .../yearSettings/YearSettingsLayout.tsx | 91 +--- .../accounts/$idAccount/AccountLayout.tsx | 6 +- .../$idAccount/AccountMetadataTab.tsx | 6 +- .../accounts/$idAccount/AccountPage.tsx | 6 +- .../accounts/$idAccount/DeleteOneAccount.tsx | 48 +- .../accounts/$idAccount/UpdateOneAccount.tsx | 3 +- .../$idBalanceSheet/BalanceSheetLayout.tsx | 6 +- .../BalanceSheetMetadataTab.tsx | 6 +- .../$idBalanceSheet/BalanceSheetPage.tsx | 6 +- .../$idBalanceSheet/DeleteOneBalanceSheet.tsx | 47 +- .../DeleteOneIncomeStatement.tsx | 47 +- .../IncomeStatementLayout.tsx | 6 +- .../IncomeStatementMetadataTab.tsx | 6 +- .../IncomeStatementPage.tsx | 6 +- .../$idComputation/ComputationLayout.tsx | 6 +- .../$idComputation/ComputationMetadataTab.tsx | 6 +- .../$idComputation/ComputationPage.tsx | 6 +- .../$idComputation/ComputationPostesTab.tsx | 6 +- .../$idComputation/DeleteOneComputation.tsx | 47 +- .../ComputationIncomeStatementLayout.tsx | 6 +- .../ComputationIncomeStatementMetadataTab.tsx | 6 +- .../ComputationIncomeStatementPage.tsx | 6 +- .../DeleteOneComputationIncomeStatement.tsx | 47 +- .../computations/ComputationsPage.tsx | 6 +- .../journals/$idJournal/DeleteOneJournal.tsx | 47 +- .../journals/$idJournal/JournalLayout.tsx | 6 +- .../$idJournal/JournalMetadataTab.tsx | 6 +- .../journals/$idJournal/JournalPage.tsx | 6 +- .../journals/$idJournal/UpdateOneJournal.tsx | 1 + .../yearSettings/tags/$idTag/DeleteOneTag.tsx | 47 +- .../yearSettings/tags/$idTag/TagLayout.tsx | 6 +- .../tags/$idTag/TagMetadataTab.tsx | 6 +- .../yearSettings/tags/$idTag/TagPage.tsx | 6 +- .../yearSettings/tags/$idTag/UpdateOneTag.tsx | 1 + .../dashboard/admin/AdminPanelLayout.tsx | 36 +- .../admin/tickets/$idTicket/TicketLayout.tsx | 6 +- .../support/$idTicket/TicketLayout.tsx | 6 +- .../root/dashboard/admin/adminLayoutRoute.tsx | 24 - .../root/dashboard/admin/adminRoute.tsx | 12 - .../$idTicket/$idTicketLayoutRoute.tsx | 16 - .../tickets/$idTicket/$idTicketRoute.tsx | 14 - .../admin/tickets/ticketsLayoutRoute.tsx | 8 - .../dashboard/admin/tickets/ticketsRoute.tsx | 16 - .../root/dashboard/agent/agentLayoutRoute.tsx | 14 - .../root/dashboard/agent/agentRoute.tsx | 14 - .../dashboard/agent/agentSessionRoute.tsx | 31 -- .../agent/agentSessionsLayoutRoute.tsx | 7 - .../routes/root/dashboard/dashboardTree.ts | 9 - .../root/dashboard/fullDashboardTree.ts | 2 + .../organizationApiKeysRoute.tsx | 17 - .../organizationApiLayoutRoute.tsx | 14 - .../organizationApi/organizationApiRoute.tsx | 17 - .../organizationBillingHistoryRoute.tsx | 17 - .../organizationBillingLayoutRoute.tsx | 17 - .../organizationBillingRoute.tsx | 17 - .../organizationBillingsRoute.tsx | 17 - .../organizationInvoiceUblRoute.tsx | 17 - .../organizationInvoicesRoute.tsx | 17 - .../organizationLayoutRoute.tsx | 14 - .../$idOrganization/organizationPathRoute.tsx | 23 - .../$idOrganization/organizationRoute.tsx | 13 - .../organizationSecurityRoute.tsx | 17 - .../organizationSettingsLayoutRoute.tsx | 17 - .../organizationSettingsRoute.tsx | 17 - .../organizationUsersLayoutRoute.tsx | 11 - .../organizationUsersRoute.tsx | 14 - .../storage/$idFile/fileLayoutRoute.tsx | 14 - .../storage/$idFile/fileMetadataRoute.tsx | 14 - .../storage/$idFile/fileRoute.tsx | 14 - .../$idFile/fileVisualisationRoute.tsx | 14 - .../storage/storageLayoutRoute.tsx | 11 - .../$idOrganization/storage/storageRoute.tsx | 17 - .../$idEntryLine/entryLineLayoutRoute.tsx | 17 - .../$idEntryLine/entryLineMetadataRoute.tsx | 17 - .../$idEntry/$idEntryLine/entryLineRoute.tsx | 17 - .../entries/$idEntry/entryCategoriesRoute.tsx | 14 - .../entries/$idEntry/entryLayoutRoute.tsx | 14 - .../entries/$idEntry/entryLinesRoute.tsx | 14 - .../entries/$idEntry/entryMetadataRoute.tsx | 14 - .../$idYear/entries/$idEntry/entryRoute.tsx | 14 - .../$idYear/entries/entriesLayoutRoute.tsx | 11 - .../years/$idYear/entries/entriesRoute.tsx | 14 - .../$idYear/files/$idFile/fileLayoutRoute.tsx | 14 - .../files/$idFile/fileMetadataRoute.tsx | 14 - .../years/$idYear/files/$idFile/fileRoute.tsx | 14 - .../files/$idFile/fileVisualisationRoute.tsx | 14 - .../years/$idYear/files/filesLayoutRoute.tsx | 11 - .../years/$idYear/files/filesRoute.tsx | 17 - .../$idYear/reports/balanceReportRoute.tsx | 14 - .../reports/balanceSheetReportRoute.tsx | 17 - .../reports/incomeStatementReportRoute.tsx | 17 - .../$idYear/reports/journalReportRoute.tsx | 14 - .../$idYear/reports/ledgerReportRoute.tsx | 14 - .../$idYear/reports/reportsLayoutRoute.tsx | 14 - .../years/$idYear/reports/reportsRoute.tsx | 13 - .../years/$idYear/yearLayoutRoute.tsx | 30 -- .../years/$idYear/yearPathRoute.tsx | 10 - .../years/$idYear/yearRoute.tsx | 13 - .../$idAccount/accountLayoutRoute.tsx | 17 - .../$idAccount/accountMetadataRoute.tsx | 17 - .../accounts/$idAccount/accountRoute.tsx | 17 - .../accounts/accountsLayoutRoute.tsx | 11 - .../yearSettings/accounts/accountsRoute.tsx | 14 - .../balanceSheetLayoutRoute.tsx | 17 - .../balanceSheetMetadataRoute.tsx | 17 - .../$idBalanceSheet/balanceSheetRoute.tsx | 17 - .../balanceSheets/actif/actifLayoutRoute.tsx | 11 - .../balanceSheets/actif/actifRoute.tsx | 17 - .../balanceSheetsLayoutRoute.tsx | 11 - .../balanceSheets/balanceSheetsRoute.tsx | 13 - .../passif/passifLayoutRoute.tsx | 11 - .../balanceSheets/passif/passifRoute.tsx | 17 - .../incomeStatementLayoutRoute.tsx | 17 - .../incomeStatementMetadataRoute.tsx | 17 - .../incomeStatementRoute.tsx | 17 - .../computationIncomeStatementLayoutRoute.tsx | 17 - ...omputationIncomeStatementMetadataRoute.tsx | 17 - .../computationIncomeStatementRoute.tsx | 17 - .../$idComputation/computationLayoutRoute.tsx | 17 - .../computationMetadataRoute.tsx | 17 - .../$idComputation/computationPostesRoute.tsx | 17 - .../$idComputation/computationRoute.tsx | 17 - .../computations/computationsLayoutRoute.tsx | 11 - .../computations/computationsRoute.tsx | 17 - .../incomeStatementsLayoutRoute.tsx | 11 - .../incomeStatementsRoute.tsx | 17 - .../$idJournal/journalLayoutRoute.tsx | 17 - .../$idJournal/journalMetadataRoute.tsx | 17 - .../journals/$idJournal/journalRoute.tsx | 17 - .../journals/journalsLayoutRoute.tsx | 11 - .../yearSettings/journals/journalsRoute.tsx | 14 - .../tags/$idTag/tagLayoutRoute.tsx | 14 - .../tags/$idTag/tagMetadataRoute.tsx | 17 - .../yearSettings/tags/$idTag/tagRoute.tsx | 14 - .../yearSettings/tags/tagsLayoutRoute.tsx | 11 - .../$idYear/yearSettings/tags/tagsRoute.tsx | 14 - .../yearSettings/yearSettingsLayoutRoute.tsx | 14 - .../yearSettings/yearSettingsRoute.tsx | 14 - .../years/yearsLayoutRoute.tsx | 11 - .../$idOrganization/years/yearsPathRoute.tsx | 10 - .../$idOrganization/years/yearsRoute.tsx | 14 - .../organizationsLayoutRoute.tsx | 11 - .../organizations/organizationsRoute.tsx | 14 - .../profile/userProfileLayoutRoute.tsx | 11 - .../dashboard/profile/userProfileRoute.tsx | 12 - .../settings/settingsLayoutRoute.tsx | 11 - .../root/dashboard/settings/settingsRoute.tsx | 12 - .../dashboard/support/supportLayoutRoute.tsx | 11 - .../root/dashboard/support/supportRoute.tsx | 11 - .../dashboard/support/ticketLayoutRoute.tsx | 14 - .../root/dashboard/support/ticketRoute.tsx | 14 - 239 files changed, 2268 insertions(+), 4590 deletions(-) delete mode 100644 packages/ui/src/components/buttons/button.tsx rename packages/{website => ui}/src/components/overlays/dialog/DialogBody.tsx (91%) create mode 100644 packages/ui/src/components/overlays/dialog/DialogContent.tsx create mode 100644 packages/ui/src/components/overlays/dialog/DialogDescription.tsx rename packages/{website => ui}/src/components/overlays/dialog/DialogFooter.tsx (92%) rename packages/{website => ui}/src/components/overlays/dialog/DialogHeader.tsx (80%) create mode 100644 packages/ui/src/components/overlays/dialog/DialogTitle.tsx create mode 100644 packages/ui/src/components/overlays/dialog/dialog.tsx create mode 100644 packages/ui/src/stores/index.ts create mode 100644 packages/ui/src/stores/modalStore.tsx create mode 100644 packages/ui/src/stores/popoverStore.tsx delete mode 100644 packages/website/src/components/layouts/commandPalette/commandPalette.tsx create mode 100644 packages/website/src/components/layouts/page/PageBanners.tsx delete mode 100644 packages/website/src/components/overlays/dialog/ConfirmationModal.tsx delete mode 100644 packages/website/src/components/overlays/dialog/DialogContent.tsx delete mode 100644 packages/website/src/components/overlays/dialog/DialogDescription.tsx delete mode 100644 packages/website/src/components/overlays/dialog/DialogOverlay.tsx delete mode 100644 packages/website/src/components/overlays/dialog/DialogRoot.tsx delete mode 100644 packages/website/src/components/overlays/dialog/DialogTitle.tsx delete mode 100644 packages/website/src/components/overlays/dialog/dialogPortal.tsx delete mode 100644 packages/website/src/components/overlays/dialog/dialogTrigger.tsx rename packages/website/src/features/dashboard/$idYear/entries/$idEntry/{EntryPage.tsx => EntryInformationsTab.tsx} (73%) delete mode 100644 packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx delete mode 100644 packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/admin/adminRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/admin/tickets/ticketsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/agent/agentRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/agent/agentSessionsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/dashboardTree.ts delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearPathRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsPathRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/organizationsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/profile/userProfileLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/settings/settingsLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/support/supportLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/support/supportRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx delete mode 100644 packages/website/src/routes/root/dashboard/support/ticketRoute.tsx diff --git a/packages/ui/package.json b/packages/ui/package.json index 42c33366..f281d643 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -29,7 +29,6 @@ }, "dependencies": { "@pandacss/dev": "1.11.0", - "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-switch": "1.2.6", "@tabler/icons-react": "3.42.0", "@tanstack/react-router": "1.169.2", @@ -44,4 +43,4 @@ "@types/react-dom": "19.2.3", "typescript": "6.0.3" } -} +} \ No newline at end of file diff --git a/packages/ui/src/components/buttons/button.tsx b/packages/ui/src/components/buttons/button.tsx deleted file mode 100644 index 5d289f3c..00000000 --- a/packages/ui/src/components/buttons/button.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { - type ComponentProps, - createContext, - type MouseEvent, - type ReactNode, - useRef, - useState, -} from "react" -import { css, cx } from "../../utilities/cn.ts" -import { sleep } from "../../utilities/sleep.ts" - -/** - * Context for passing loading state from Button to ButtonContent - */ -export const ButtonLoadingContext = createContext(false) - -/** - * Button component - a neutral container for clickable elements - * Handles click events, loading state, and disabled state - * Use composition with ButtonContent for styled button content - * - * @example - * - */ -export function Button( - props: Omit, "children" | "disabled"> & { - hasLoader?: boolean - children: ReactNode - title?: string - isDisabled?: boolean - }, -) { - const [isLoading, setIsLoading] = useState(false) - const isLoadingRef = useRef(false) - - async function handleClick(e: MouseEvent) { - if (props.onClick === undefined) return - if (!props.hasLoader) { - props.onClick(e) - return - } - - if (isLoadingRef.current) return - isLoadingRef.current = true - setIsLoading(true) - - try { - await Promise.all([ - sleep(100), - props.onClick(e), - ]) - } finally { - isLoadingRef.current = false - setIsLoading(false) - } - } - - const { hasLoader, className, isDisabled, title, children, onClick: _onClick, ...buttonProps } = props - - return ( - - - - ) -} diff --git a/packages/ui/src/components/inputs/InputCombobox.tsx b/packages/ui/src/components/inputs/InputCombobox.tsx index f76ddb4c..4f047c2c 100644 --- a/packages/ui/src/components/inputs/InputCombobox.tsx +++ b/packages/ui/src/components/inputs/InputCombobox.tsx @@ -52,7 +52,6 @@ export function InputCombobox(props: { - + )} ) } diff --git a/packages/ui/src/components/overlays/dialog/DialogTitle.tsx b/packages/ui/src/components/overlays/dialog/DialogTitle.tsx new file mode 100644 index 00000000..cb841dae --- /dev/null +++ b/packages/ui/src/components/overlays/dialog/DialogTitle.tsx @@ -0,0 +1,17 @@ +import { css, cx } from "../../../utilities/cn.js" +import type { HTMLAttributes } from "react" + +export function DialogTitle(props: HTMLAttributes) { + return ( +

+ ) +} diff --git a/packages/ui/src/components/overlays/dialog/dialog.tsx b/packages/ui/src/components/overlays/dialog/dialog.tsx new file mode 100644 index 00000000..132ff7a1 --- /dev/null +++ b/packages/ui/src/components/overlays/dialog/dialog.tsx @@ -0,0 +1,15 @@ +import { DialogBody } from "./DialogBody.js" +import { DialogContent } from "./DialogContent.js" +import { DialogDescription } from "./DialogDescription.js" +import { DialogFooter } from "./DialogFooter.js" +import { DialogHeader } from "./DialogHeader.js" +import { DialogTitle } from "./DialogTitle.js" + +export const Dialog = { + Body: DialogBody, + Content: DialogContent, + Description: DialogDescription, + Footer: DialogFooter, + Header: DialogHeader, + Title: DialogTitle, +} diff --git a/packages/ui/src/components/overlays/popover/PopoverContent.tsx b/packages/ui/src/components/overlays/popover/PopoverContent.tsx index 24b444f6..b2881aaf 100644 --- a/packages/ui/src/components/overlays/popover/PopoverContent.tsx +++ b/packages/ui/src/components/overlays/popover/PopoverContent.tsx @@ -1,19 +1,114 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" -import type { ComponentProps } from "react" +import { type ReactNode } from "react" +import { createPortal } from "react-dom" import { css, cx } from "../../../utilities/cn.js" +import { usePopoverContext } from "./popoverRoot.js" -export function PopoverContent(props: ComponentProps) { - return ( - - + +
- + > + {props.children} +
+ , + document.body, ) } diff --git a/packages/ui/src/components/overlays/popover/popoverClose.tsx b/packages/ui/src/components/overlays/popover/popoverClose.tsx index a945fec4..36060358 100644 --- a/packages/ui/src/components/overlays/popover/popoverClose.tsx +++ b/packages/ui/src/components/overlays/popover/popoverClose.tsx @@ -1,3 +1,32 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" +import { type ReactElement, cloneElement, isValidElement } from "react" +import { usePopoverContext } from "./popoverRoot.js" -export const PopoverClose = PopoverPrimitive.Close +export function PopoverClose(props: { + children: ReactElement + asChild?: boolean +}) { + const { setOpen } = usePopoverContext() + + function handleClick() { + setOpen(false) + } + + if (props.asChild && isValidElement(props.children)) { + const child = props.children as ReactElement> + return cloneElement(child, { + ...child.props, + onClick: (e: React.MouseEvent) => { + if (typeof child.props.onClick === "function") { + child.props.onClick(e) + } + handleClick() + }, + }) + } + + return ( + + ) +} diff --git a/packages/ui/src/components/overlays/popover/popoverRoot.tsx b/packages/ui/src/components/overlays/popover/popoverRoot.tsx index 1320adea..b5c111f6 100644 --- a/packages/ui/src/components/overlays/popover/popoverRoot.tsx +++ b/packages/ui/src/components/overlays/popover/popoverRoot.tsx @@ -1,3 +1,60 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" +import { type Dispatch, type ReactNode, type SetStateAction, createContext, useContext, useEffect, useId, useState } from "react" +import { usePopoverStore } from "../../../stores/popoverStore.js" -export const PopoverRoot = PopoverPrimitive.Root +// --------------------------------------------------------------------------- +// Context shared between Root / Trigger / Content / Close +// --------------------------------------------------------------------------- + +export type PopoverContextValue = { + id: string + anchorName: string + isOpen: boolean + setOpen: Dispatch> +} + +export const PopoverContext = createContext(null) + +export function usePopoverContext(): PopoverContextValue { + const ctx = useContext(PopoverContext) + if (ctx === null) throw new Error("Popover sub-component used outside ") + return ctx +} + +// --------------------------------------------------------------------------- +// PopoverRoot +// --------------------------------------------------------------------------- + +export function PopoverRoot(props: { + children: ReactNode + /** Optionally override the auto-generated id (must be a valid CSS ident fragment). */ + id?: string + /** Controlled open state. */ + open?: boolean + /** Controlled open-change callback. */ + onOpenChange?: (open: boolean) => void +}) { + const reactId = useId() + const id = props.id ?? reactId.replace(/:/g, "") + const anchorName = `--popover-${id}` + + const isControlled = props.open !== undefined + const [localOpen, setLocalOpen] = useState(false) + + const isOpen = isControlled ? (props.open ?? false) : localOpen + + const setOpen: Dispatch> = (valueOrUpdater) => { + const next = typeof valueOrUpdater === "function" ? valueOrUpdater(isOpen) : valueOrUpdater + if (!isControlled) setLocalOpen(next) + props.onOpenChange?.(next) + } + + const store = usePopoverStore() + + useEffect(() => { + store.register(id, setOpen) + return () => store.unregister(id) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [id]) + + return {props.children} +} diff --git a/packages/ui/src/components/overlays/popover/popoverTrigger.tsx b/packages/ui/src/components/overlays/popover/popoverTrigger.tsx index d421191f..c412b266 100644 --- a/packages/ui/src/components/overlays/popover/popoverTrigger.tsx +++ b/packages/ui/src/components/overlays/popover/popoverTrigger.tsx @@ -1,3 +1,44 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" +import { type ReactElement, cloneElement, isValidElement } from "react" +import { usePopoverContext } from "./popoverRoot.js" -export const PopoverTrigger = PopoverPrimitive.Trigger +export function PopoverTrigger(props: { + children: ReactElement + /** When true the child element is used directly as the trigger (no wrapper button). */ + asChild?: boolean +}) { + const { anchorName, isOpen, setOpen } = usePopoverContext() + + function handleClick(e: React.MouseEvent) { + e.stopPropagation() + setOpen(!isOpen) + } + + if (props.asChild && isValidElement(props.children)) { + const child = props.children as ReactElement> + return cloneElement(child, { + ...child.props, + "data-popover-trigger": "", + style: { + ...(child.props.style as React.CSSProperties | undefined), + anchorName, + }, + onClick: (e: React.MouseEvent) => { + if (typeof child.props.onClick === "function") { + child.props.onClick(e) + } + handleClick(e) + }, + }) + } + + return ( + + ) +} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index dc8d34db..f2f17c9e 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -57,7 +57,13 @@ export { PageNavigation } from "./components/layouts/PageNavigation.js" export { Separator } from "./components/layouts/Separator.js" export { Virtualizer } from "./components/layouts/Virtualizer.js" // Components - Overlays +export { Dialog } from "./components/overlays/dialog/dialog.js" export { Popover } from "./components/overlays/popover/popover.js" +// Stores +export { ModalProvider, useModalStore, useModalItem } from "./stores/modalStore.js" +export type { ModalStoreValue } from "./stores/modalStore.js" +export { PopoverProvider, usePopoverStore } from "./stores/popoverStore.js" +export type { PopoverStoreValue } from "./stores/popoverStore.js" export { Toast } from "./components/overlays/toast/toast.js" export { ToasterProvider } from "./components/overlays/toast/ToasterProvider.js" export type { ToasterToast, ToastVariant } from "./components/overlays/toast/useToast.js" diff --git a/packages/ui/src/stores/index.ts b/packages/ui/src/stores/index.ts new file mode 100644 index 00000000..03e472ed --- /dev/null +++ b/packages/ui/src/stores/index.ts @@ -0,0 +1,4 @@ +export { ModalProvider, useModalStore, useModalItem, ModalStoreContext, ModalItemContext } from "./modalStore.js" +export type { ModalStoreValue } from "./modalStore.js" +export { PopoverProvider, usePopoverStore, PopoverStoreContext } from "./popoverStore.js" +export type { PopoverStoreValue } from "./popoverStore.js" diff --git a/packages/ui/src/stores/modalStore.tsx b/packages/ui/src/stores/modalStore.tsx new file mode 100644 index 00000000..c7028486 --- /dev/null +++ b/packages/ui/src/stores/modalStore.tsx @@ -0,0 +1,187 @@ +import { + type ReactNode, + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useReducer, + useRef, +} from "react" + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +type ModalEntry = { + content: ReactNode + isOpen: boolean +} + +type ModalState = Record + +type ModalAction = + | { type: "open"; id: string; content: ReactNode } + | { type: "close"; id: string } + +// --------------------------------------------------------------------------- +// Reducer +// --------------------------------------------------------------------------- + +function reducer(state: ModalState, action: ModalAction): ModalState { + switch (action.type) { + case "open": + return { ...state, [action.id]: { content: action.content, isOpen: true } } + case "close": { + const entry = state[action.id] + if (entry === undefined) return state + return { ...state, [action.id]: { ...entry, isOpen: false } } + } + default: + return state + } +} + +// --------------------------------------------------------------------------- +// Contexts +// --------------------------------------------------------------------------- + +export type ModalStoreValue = { + open: (id: string, content: ReactNode) => void + close: (id: string) => void + isOpen: (id: string) => boolean +} + +export const ModalStoreContext = createContext(null) + +/** Provided by ModalProvider around each rendered modal entry so sub-components + * (DialogHeader close button) can close the modal without needing to know its id. */ +export const ModalItemContext = createContext<{ closeModal: () => void } | null>(null) + +// --------------------------------------------------------------------------- +// Hooks +// --------------------------------------------------------------------------- + +export function useModalStore(): ModalStoreValue { + const ctx = useContext(ModalStoreContext) + if (ctx === null) throw new Error("useModalStore must be used within ModalProvider") + return ctx +} + +export function useModalItem() { + return useContext(ModalItemContext) +} + +// --------------------------------------------------------------------------- +// ModalItem — one native per modal entry +// --------------------------------------------------------------------------- + +function ModalItem({ + id, + entry, + close, +}: { + id: string + entry: ModalEntry + close: (id: string) => void +}) { + const dialogRef = useRef(null) + const wrapperRef = useRef(null) + + useEffect(() => { + const dialog = dialogRef.current + if (dialog === null) return + if (entry.isOpen) { + if (!dialog.open) dialog.showModal() + } else { + if (dialog.open) dialog.close() + } + }, [entry.isOpen]) + + function handleCancel(e: React.SyntheticEvent) { + e.preventDefault() + close(id) + } + + function handleClick(e: React.MouseEvent) { + // Clicks on the centering wrapper itself = click in the backdrop area + if (e.target === wrapperRef.current) { + close(id) + } + } + + return ( + /* + * The UA styles are reset inline so we own the full layout. + * ::backdrop is styled via the injected + {children} + {Object.entries(state).map(([id, entry]) => ( + + ))} + + ) +} diff --git a/packages/ui/src/stores/popoverStore.tsx b/packages/ui/src/stores/popoverStore.tsx new file mode 100644 index 00000000..99b58d18 --- /dev/null +++ b/packages/ui/src/stores/popoverStore.tsx @@ -0,0 +1,168 @@ +import { + type Dispatch, + type ReactNode, + type SetStateAction, + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useReducer, + useRef, +} from "react" + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +type PopoverEntry = { + isOpen: boolean +} + +type PopoverState = Record + +type PopoverAction = + | { type: "register"; id: string } + | { type: "unregister"; id: string } + | { type: "open"; id: string } + | { type: "close"; id: string } + | { type: "closeAll" } + +// --------------------------------------------------------------------------- +// Reducer +// --------------------------------------------------------------------------- + +function reducer(state: PopoverState, action: PopoverAction): PopoverState { + switch (action.type) { + case "register": + return { ...state, [action.id]: { isOpen: false } } + case "unregister": { + const { [action.id]: _removed, ...rest } = state + return rest + } + case "open": + if (state[action.id] === undefined) return state + if (state[action.id].isOpen) return state + return { ...state, [action.id]: { isOpen: true } } + case "close": + if (state[action.id] === undefined) return state + if (!state[action.id].isOpen) return state + return { ...state, [action.id]: { isOpen: false } } + case "closeAll": { + const hasOpen = Object.values(state).some((e) => e.isOpen) + if (!hasOpen) return state + const next: PopoverState = {} + for (const id of Object.keys(state)) { + next[id] = { isOpen: false } + } + return next + } + default: + return state + } +} + +// --------------------------------------------------------------------------- +// Context +// --------------------------------------------------------------------------- + +export type PopoverStoreValue = { + open: (id: string) => void + close: (id: string) => void + closeAll: () => void + isOpen: (id: string) => boolean + register: (id: string, setOpen: Dispatch>) => void + unregister: (id: string) => void +} + +export const PopoverStoreContext = createContext(null) + +// --------------------------------------------------------------------------- +// Hook +// --------------------------------------------------------------------------- + +export function usePopoverStore(): PopoverStoreValue { + const ctx = useContext(PopoverStoreContext) + if (ctx === null) throw new Error("usePopoverStore must be used within PopoverProvider") + return ctx +} + +// --------------------------------------------------------------------------- +// Provider +// --------------------------------------------------------------------------- + +export function PopoverProvider({ children }: { children: ReactNode }) { + const [state, dispatch] = useReducer(reducer, {}) + + // Mutable map of setOpen callbacks from each PopoverRoot — stored in a ref + // so changes to these callbacks don't cause a store re-render. + const setOpenCallbacksRef = useRef>>>({}) + + const open = useCallback((id: string) => { + dispatch({ type: "open", id }) + setOpenCallbacksRef.current[id]?.(true) + }, []) + + const close = useCallback((id: string) => { + dispatch({ type: "close", id }) + setOpenCallbacksRef.current[id]?.(false) + }, []) + + const closeAll = useCallback(() => { + dispatch({ type: "closeAll" }) + for (const setter of Object.values(setOpenCallbacksRef.current)) { + setter(false) + } + }, []) + + const isOpen = useCallback((id: string) => state[id]?.isOpen ?? false, [state]) + + const register = useCallback((id: string, setOpen: Dispatch>) => { + dispatch({ type: "register", id }) + setOpenCallbacksRef.current[id] = setOpen + }, []) + + const unregister = useCallback((id: string) => { + dispatch({ type: "unregister", id }) + delete setOpenCallbacksRef.current[id] + }, []) + + const value = useMemo( + () => ({ open, close, closeAll, isOpen, register, unregister }), + [open, close, closeAll, isOpen, register, unregister], + ) + + // Close all open popovers when the user clicks outside any popover/trigger + useEffect(() => { + function handleClick(e: MouseEvent) { + const target = e.target as HTMLElement + if ( + target.closest("[data-popover-content]") === null && + target.closest("[data-popover-trigger]") === null + ) { + dispatch({ type: "closeAll" }) + for (const setter of Object.values(setOpenCallbacksRef.current)) { + setter(false) + } + } + } + document.addEventListener("click", handleClick, true) + return () => document.removeEventListener("click", handleClick, true) + }, []) + + // Close all open popovers on Escape + useEffect(() => { + function handleKeyDown(e: KeyboardEvent) { + if (e.key === "Escape") { + dispatch({ type: "closeAll" }) + for (const setter of Object.values(setOpenCallbacksRef.current)) { + setter(false) + } + } + } + document.addEventListener("keydown", handleKeyDown) + return () => document.removeEventListener("keydown", handleKeyDown) + }, []) + + return {children} +} diff --git a/packages/website/package.json b/packages/website/package.json index da873c7c..8c5dbc42 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -24,8 +24,6 @@ "@arrhes/ui": "workspace:*", "@hookform/resolvers": "5.2.2", "@radix-ui/react-context-menu": "2.2.16", - "@radix-ui/react-dialog": "1.1.15", - "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-slot": "1.2.4", "@radix-ui/react-tooltip": "1.2.8", "@react-pdf/renderer": "4.5.1", @@ -55,4 +53,4 @@ "last 1 safari version" ] } -} +} \ No newline at end of file diff --git a/packages/website/src/components/layouts/SubPageContent.tsx b/packages/website/src/components/layouts/SubPageContent.tsx index e8fcda8a..a9c15bff 100644 --- a/packages/website/src/components/layouts/SubPageContent.tsx +++ b/packages/website/src/components/layouts/SubPageContent.tsx @@ -1,10 +1,7 @@ import { Button, ButtonGhostContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import * as PopoverPrimitive from "@radix-ui/react-popover" import type { Icon, IconProps } from "@tabler/icons-react" -import { IconLayoutColumns, IconX } from "@tabler/icons-react" -import { type ReactElement, type ReactNode, useCallback, useEffect, useRef, useState } from "react" -import { Popover } from "../overlays/popover/popover.js" +import { type ReactElement, type ReactNode, useState } from "react" type SectionItem = { key: string @@ -19,46 +16,26 @@ type Section = { items: SectionItem[] } -type Props = { + +/** State-based tab navigation — no TanStack Router required. */ +export function SubPageContent(props: { sections: Record defaultKey?: string -} - -type PanelProps = { - allItems: SectionItem[] - activeKey: string - setActiveKey: (key: string) => void - onOpenInSplit?: (key: string) => void - rightSlot?: ReactNode -} - -function Panel({ allItems, activeKey, setActiveKey, onOpenInSplit, rightSlot }: PanelProps) { + children?: ReactNode +}) { + const allItems = Object.values(props.sections).flatMap((s) => s.items) + const firstKey = props.defaultKey ?? allItems[0]?.key ?? "" + const [activeKey, setActiveKey] = useState(firstKey) const activeContent = allItems.find((i) => i.key === activeKey)?.content ?? null - const [contextMenuKey, setContextMenuKey] = useState(null) - - // Capture phase fires before the browser decides to show the native context menu. - useEffect(() => { - function suppressBrowserMenu(e: MouseEvent) { - if ((e.target as HTMLElement | null)?.closest?.("[data-tab-context]")) { - e.preventDefault() - } - } - document.addEventListener("contextmenu", suppressBrowserMenu, { - capture: true, - }) - return () => - document.removeEventListener("contextmenu", suppressBrowserMenu, { - capture: true, - }) - }, []) return (
{/* Tab bar */} @@ -67,108 +44,48 @@ function Panel({ allItems, activeKey, setActiveKey, onOpenInSplit, rightSlot }: flexShrink: "0", width: "100%", display: "flex", - justifyContent: "flex-start", + justifyContent: "space-between", alignItems: "center", - gap: "0.5rem", + gap: "1rem", flexWrap: "wrap", - paddingX: "1rem", - paddingY: "0.5rem", + padding: "0.5rem", borderBottom: "1px solid", borderBottomColor: "neutral/10", })} > - {allItems.map((item) => ( - { - if (!open) setContextMenuKey(null) - }} - > - - { - e.preventDefault() - setContextMenuKey(item.key) - }} - > - - - - + {allItems.map((item) => ( + - {onOpenInSplit && ( - - )} - - - ))} - {rightSlot && ( -
- {rightSlot} -
- )} + + + ))} +
+
+ {props.children} +
{/* Active tab content */} @@ -186,194 +103,3 @@ function Panel({ allItems, activeKey, setActiveKey, onOpenInSplit, rightSlot }: ) } - -/** State-based tab navigation — no TanStack Router required. */ -export function SubPageContent({ sections, defaultKey }: Props) { - const allItems = Object.values(sections).flatMap((s) => s.items) - const firstKey = defaultKey ?? allItems[0]?.key ?? "" - - const [activeKey, setActiveKey] = useState(firstKey) - const [splitEnabled, setSplitEnabled] = useState(false) - const [splitPosition, setSplitPosition] = useState(50) - - const defaultRightKey = allItems.find((i) => i.key !== firstKey)?.key ?? firstKey - const [activeKeyRight, setActiveKeyRight] = useState(defaultRightKey) - - const containerRef = useRef(null) - const isDragging = useRef(false) - const dragStartX = useRef(0) - const dragStartPosition = useRef(50) - - const handleMouseMove = useCallback((e: MouseEvent) => { - if (!isDragging.current || !containerRef.current) return - const rect = containerRef.current.getBoundingClientRect() - const deltaX = e.clientX - dragStartX.current - const deltaPct = (deltaX / rect.width) * 100 - const newPct = Math.min(80, Math.max(20, dragStartPosition.current + deltaPct)) - setSplitPosition(newPct) - }, []) - - const handleMouseUp = useCallback(() => { - isDragging.current = false - window.removeEventListener("mousemove", handleMouseMove) - window.removeEventListener("mouseup", handleMouseUp) - document.body.style.cursor = "" - document.body.style.userSelect = "" - }, [ - handleMouseMove, - ]) - - const handleDragStart = useCallback( - (e: React.MouseEvent) => { - e.preventDefault() - isDragging.current = true - dragStartX.current = e.clientX - dragStartPosition.current = splitPosition - document.body.style.cursor = "col-resize" - document.body.style.userSelect = "none" - window.addEventListener("mousemove", handleMouseMove) - window.addEventListener("mouseup", handleMouseUp) - }, - [ - splitPosition, - handleMouseMove, - handleMouseUp, - ], - ) - - // Clean up listeners on unmount - useEffect( - () => () => { - window.removeEventListener("mousemove", handleMouseMove) - window.removeEventListener("mouseup", handleMouseUp) - }, - [ - handleMouseMove, - handleMouseUp, - ], - ) - - const closeSplit = useCallback(() => { - setSplitEnabled(false) - setSplitPosition(50) - }, []) - - const handleOpenInSplit = useCallback((key: string) => { - setActiveKeyRight(key) - setSplitEnabled(true) - }, []) - - if (!splitEnabled) { - return ( -
- 1 ? handleOpenInSplit : undefined} - rightSlot={ - allItems.length > 1 ? ( - - ) : undefined - } - /> -
- ) - } - - return ( -
- {/* Left panel */} -
- setSplitEnabled(false)}> - } - text="" - isCurrent={true} - /> - - } - /> -
- - {/* Drag handle */} -
- - {/* Right panel */} -
- - } - text="" - /> - - } - /> -
-
- ) -} diff --git a/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx b/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx index 8a794faf..16a2354c 100644 --- a/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx +++ b/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx @@ -18,9 +18,16 @@ import { // ─── Fuzzy filter ───────────────────────────────────────────────────────────── +function normalize(s: string): string { + return s + .normalize("NFD") + .replace(/\p{Diacritic}/gu, "") + .toLowerCase() +} + function scoreMatch(query: string, target: string): number { - const q = query.toLowerCase() - const t = target.toLowerCase() + const q = normalize(query) + const t = normalize(target) if (t.includes(q)) return 0 return levenshtein(q, t.slice(0, Math.max(t.length, q.length))) } diff --git a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx b/packages/website/src/components/layouts/commandPalette/commandPalette.tsx deleted file mode 100644 index 7d356665..00000000 --- a/packages/website/src/components/layouts/commandPalette/commandPalette.tsx +++ /dev/null @@ -1,485 +0,0 @@ -import { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata/routes" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconBuilding, IconCalendar, IconLayoutGrid, IconSearch, IconUser } from "@tabler/icons-react" -import { useEffect, useMemo, useRef, useState } from "react" -import { createPortal } from "react-dom" -import type { OpenTabArgs } from "../../../contexts/tabs/tabDefinitions.js" -import { useTabs } from "../../../contexts/tabs/useTabs.js" -import { levenshtein } from "../../../utilities/levenshtein.js" -import { useDataFromAPI } from "../../../utilities/useHTTPData.js" -import { - type OrgSearchRoute, - orgSearchRoutes, - type SearchRoute, - userSearchRoutes, - type YearSearchRoute, - yearSearchRoutes, -} from "./searchRoutes.js" - -// ─── Fuzzy filter ───────────────────────────────────────────────────────────── - -function scoreMatch(query: string, target: string): number { - const q = query.toLowerCase() - const t = target.toLowerCase() - if (t.includes(q)) return 0 - return levenshtein(q, t.slice(0, Math.max(t.length, q.length))) -} - -function filterRoutes< - T extends { - label: string - description?: string - }, ->(query: string, routes: T[]): T[] { - if (!query) return routes - return routes - .map((r) => ({ - ...r, - _score: Math.min(scoreMatch(query, r.label), r.description ? scoreMatch(query, r.description) : 99), - })) - .filter((r) => r._score <= 3) - .sort((a, b) => a._score - b._score) -} - -// ─── Component ──────────────────────────────────────────────────────────────── - -export function CommandPalette(props: { selectedOrgId: string | null; selectedYearId: string | null }) { - const { selectedOrgId, selectedYearId } = props - const [open, setOpen] = useState(false) - const [query, setQuery] = useState("") - const [selected, setSelected] = useState(0) - const { openTab } = useTabs() - const inputRef = useRef(null) - - const orgsData = useDataFromAPI({ - routeDefinition: getAllMyOrganizationsRouteDefinition, - body: {}, - }) - - // Reset on open - useEffect(() => { - if (open) { - setQuery("") - setSelected(0) - setTimeout(() => inputRef.current?.focus(), 50) - } - }, [ - open, - ]) - - // Open via custom DOM event - useEffect(() => { - function handleOpen() { - setOpen(true) - } - window.addEventListener("arrhes:open-palette", handleOpen) - return () => window.removeEventListener("arrhes:open-palette", handleOpen) - }, []) - - // Close when a tab is opened - useEffect(() => { - function handleTabOpened() { - setOpen(false) - } - window.addEventListener("arrhes:tab-opened", handleTabOpened) - return () => window.removeEventListener("arrhes:tab-opened", handleTabOpened) - }, []) - - // Ctrl/Cmd+K shortcut - useEffect(() => { - function handleKey(e: KeyboardEvent) { - if ((e.ctrlKey || e.metaKey) && e.key === "k") { - e.preventDefault() - setOpen(true) - } - } - document.addEventListener("keydown", handleKey) - return () => document.removeEventListener("keydown", handleKey) - }, []) - - // ─── Result computation ──────────────────────────────────────────────────── - - const allOrgs = orgsData.data ?? [] - - // User section: static pages + matching orgs (when no org selected) - const filteredUserPages = filterRoutes(query, userSearchRoutes) - - const filteredOrgItems: SearchRoute[] = useMemo(() => { - if (!selectedOrgId) { - // Show orgs as navigable items — open their exercices tab. - return filterRoutes( - query, - allOrgs.map((ou) => ({ - label: ou.organization.name, - description: "Organisation", - tabComponent: "exercices", - tabProps: { - idOrganization: ou.organization.id, - }, - })), - ) - } - // Show org-level sub-routes. - return filterRoutes( - query, - orgSearchRoutes.map( - (r: OrgSearchRoute): SearchRoute => ({ - label: r.label, - description: r.description, - tabComponent: r.tabComponent, - tabProps: { - idOrganization: selectedOrgId, - }, - }), - ), - ) - }, [ - query, - allOrgs, - selectedOrgId, - ]) - - const filteredYearItems: SearchRoute[] = useMemo(() => { - if (!selectedOrgId || !selectedYearId) return [] - return filterRoutes( - query, - yearSearchRoutes.map( - (r: YearSearchRoute): SearchRoute => ({ - label: r.label, - description: r.description, - tabComponent: r.tabComponent, - tabProps: { - idOrganization: selectedOrgId, - idYear: selectedYearId, - }, - }), - ), - ) - }, [ - query, - selectedOrgId, - selectedYearId, - ]) - - const allItems: SearchRoute[] = [ - ...filteredUserPages, - ...filteredOrgItems, - ...filteredYearItems, - ] - - function activate(item: SearchRoute) { - setOpen(false) - openTab( - { - component: item.tabComponent, - props: item.tabProps, - } as OpenTabArgs, - { - newTab: true, - }, - ) - } - - function handleKeyDown(e: React.KeyboardEvent) { - if (e.key === "ArrowDown") { - e.preventDefault() - setSelected((s) => Math.min(s + 1, allItems.length - 1)) - } else if (e.key === "ArrowUp") { - e.preventDefault() - setSelected((s) => Math.max(s - 1, 0)) - } else if (e.key === "Enter") { - e.preventDefault() - const item = allItems[selected] - if (item) activate(item) - } else if (e.key === "Escape") { - setOpen(false) - } - } - - // Keep selected index in bounds when filtered list changes - useEffect(() => { - setSelected(0) - }, [ - query, - selectedOrgId, - selectedYearId, - ]) - - if (!open) return null - - // Offset counters for multi-section active tracking - const userOffset = 0 - const orgOffset = filteredUserPages.length - const yearOffset = orgOffset + filteredOrgItems.length - - return createPortal( -
{ - if (e.target === e.currentTarget) setOpen(false) - }} - > -
- {/* Search input */} -
- - setQuery(e.target.value)} - placeholder="Rechercher des pages, organisations…" - className={css({ - flex: 1, - fontSize: "0.9375rem", - border: "none", - outline: "none", - background: "transparent", - color: "neutral/900", - _placeholder: { - color: "neutral/400", - }, - })} - /> -
- - {/* Results */} -
- {allItems.length === 0 && ( -

- {query ? `Aucun résultat pour « ${query} »` : "Aucun résultat"} -

- )} - - {filteredUserPages.length > 0 && ( -
} - > - {filteredUserPages.map((page, i) => ( - } - label={page.label} - description={page.description} - active={selected === userOffset + i} - onMouseEnter={() => setSelected(userOffset + i)} - onClick={() => activate(page)} - /> - ))} -
- )} - - {filteredOrgItems.length > 0 && ( -
} - > - {filteredOrgItems.map((item, i) => ( - } - label={item.label} - description={item.description} - active={selected === orgOffset + i} - onMouseEnter={() => setSelected(orgOffset + i)} - onClick={() => activate(item)} - /> - ))} -
- )} - - {filteredYearItems.length > 0 && ( -
} - > - {filteredYearItems.map((item, i) => ( - } - label={item.label} - description={item.description} - active={selected === yearOffset + i} - onMouseEnter={() => setSelected(yearOffset + i)} - onClick={() => activate(item)} - /> - ))} -
- )} -
-
-
, - document.body, - ) -} - -// ─── Sub-components ─────────────────────────────────────────────────────────── - -function Section({ label, icon, children }: { label: string; icon?: React.ReactNode; children: React.ReactNode }) { - return ( -
-
- {icon && ( - - {icon} - - )} -

- {label} -

-
- {children} -
- ) -} - -function ResultRow(props: { - icon: React.ReactNode - label: string - description?: string - active: boolean - onMouseEnter: () => void - onClick: () => void -}) { - return ( - - ) -} diff --git a/packages/website/src/components/layouts/page/PageBanners.tsx b/packages/website/src/components/layouts/page/PageBanners.tsx new file mode 100644 index 00000000..ed01838a --- /dev/null +++ b/packages/website/src/components/layouts/page/PageBanners.tsx @@ -0,0 +1,20 @@ +import { css, cx } from "@arrhes/ui/utilities/cn.js" +import type { ComponentProps, ReactNode } from "react" + +export function PageBanners(props: { children: ReactNode; className?: ComponentProps<"div">["className"] }) { + return ( +
+ {props.children} +
+ ) +} diff --git a/packages/website/src/components/layouts/page/page.tsx b/packages/website/src/components/layouts/page/page.tsx index 4c9d6d2a..f36780aa 100644 --- a/packages/website/src/components/layouts/page/page.tsx +++ b/packages/website/src/components/layouts/page/page.tsx @@ -1,3 +1,4 @@ +import { PageBanners } from "./PageBanners.js" import { PageContent } from "./PageContent.js" import { PageDescription } from "./PageDescription.js" import { PageHeader } from "./PageHeader.js" @@ -8,6 +9,7 @@ import { PageTitle } from "./PageTitle.js" export const Page = { Root: PageRoot, + Banners: PageBanners, Navigation: PageNavigation, Header: PageHeader, Title: PageTitle, diff --git a/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx b/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx index 367bbf1b..8e6d5402 100644 --- a/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx +++ b/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx @@ -73,7 +73,7 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord title: string } ).title - const description = entry?.description + const description = entry?.description ?? (tab.type === "panel" ? tab.description : undefined) return (
Promise - children?: ReactElement> - open?: boolean - onOpenChange?: (open: boolean) => void -}) { - const [internalOpen, setInternalOpen] = useState(false) - const isControlled = props.open !== undefined - const open = isControlled ? props.open : internalOpen - const setOpen = isControlled ? (props.onOpenChange ?? (() => {})) : setInternalOpen - - async function handleSubmit() { - await props.onSubmit() - setOpen(false) - } - - return ( - setOpen(value)} - > - {props.children && ( - { - setOpen(true) - event.preventDefault() - }} - > - {props.children} - - )} - {open === false ? null : ( - - -
- -
- {props.title} -
- - {props.description} - - - - - -
- )} -
- ) -} diff --git a/packages/website/src/components/overlays/dialog/DialogContent.tsx b/packages/website/src/components/overlays/dialog/DialogContent.tsx deleted file mode 100644 index acec089e..00000000 --- a/packages/website/src/components/overlays/dialog/DialogContent.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import * as DialogPrimitive from "@radix-ui/react-dialog" -import type { ComponentPropsWithRef } from "react" -import { DialogOverlay } from "./DialogOverlay.js" -import { DialogPortal } from "./dialogPortal.js" - -export function DialogContent(props: ComponentPropsWithRef) { - return ( - - - - {props.children} - - - - ) -} diff --git a/packages/website/src/components/overlays/dialog/DialogDescription.tsx b/packages/website/src/components/overlays/dialog/DialogDescription.tsx deleted file mode 100644 index f256a431..00000000 --- a/packages/website/src/components/overlays/dialog/DialogDescription.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import * as DialogPrimitive from "@radix-ui/react-dialog" -import type { ComponentPropsWithRef } from "react" - -export function DialogDescription(props: ComponentPropsWithRef) { - return ( - - ) -} diff --git a/packages/website/src/components/overlays/dialog/DialogOverlay.tsx b/packages/website/src/components/overlays/dialog/DialogOverlay.tsx deleted file mode 100644 index e8ddde47..00000000 --- a/packages/website/src/components/overlays/dialog/DialogOverlay.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import * as DialogPrimitive from "@radix-ui/react-dialog" -import type { ComponentPropsWithRef } from "react" - -export function DialogOverlay(props: ComponentPropsWithRef) { - return ( - - ) -} diff --git a/packages/website/src/components/overlays/dialog/DialogRoot.tsx b/packages/website/src/components/overlays/dialog/DialogRoot.tsx deleted file mode 100644 index 367a7f14..00000000 --- a/packages/website/src/components/overlays/dialog/DialogRoot.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import * as DialogPrimitive from "@radix-ui/react-dialog" -import type { ComponentPropsWithRef } from "react" - -export function DialogRoot(props: ComponentPropsWithRef) { - return ( - - {props.children} - - ) -} diff --git a/packages/website/src/components/overlays/dialog/DialogTitle.tsx b/packages/website/src/components/overlays/dialog/DialogTitle.tsx deleted file mode 100644 index 70c123e9..00000000 --- a/packages/website/src/components/overlays/dialog/DialogTitle.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import * as DialogPrimitive from "@radix-ui/react-dialog" -import type { ComponentPropsWithRef } from "react" - -export function DialogTitle(props: ComponentPropsWithRef) { - return ( - - ) -} diff --git a/packages/website/src/components/overlays/dialog/dialog.tsx b/packages/website/src/components/overlays/dialog/dialog.tsx index 2127e763..b60072bf 100644 --- a/packages/website/src/components/overlays/dialog/dialog.tsx +++ b/packages/website/src/components/overlays/dialog/dialog.tsx @@ -1,23 +1 @@ -import { DialogBody } from "./DialogBody.js" -import { DialogContent } from "./DialogContent.js" -import { DialogDescription } from "./DialogDescription.js" -import { DialogFooter } from "./DialogFooter.js" -import { DialogHeader } from "./DialogHeader.js" -import { DialogOverlay } from "./DialogOverlay.js" -import { DialogPortal } from "./dialogPortal.js" -import { DialogRoot } from "./DialogRoot.js" -import { DialogTitle } from "./DialogTitle.js" -import { DialogTrigger } from "./dialogTrigger.js" - -export const Dialog = { - Content: DialogContent, - Body: DialogBody, - Description: DialogDescription, - Footer: DialogFooter, - Header: DialogHeader, - Overlay: DialogOverlay, - Portal: DialogPortal, - Root: DialogRoot, - Title: DialogTitle, - Trigger: DialogTrigger, -} +export { Dialog } from "@arrhes/ui" diff --git a/packages/website/src/components/overlays/dialog/dialogPortal.tsx b/packages/website/src/components/overlays/dialog/dialogPortal.tsx deleted file mode 100644 index 1023b949..00000000 --- a/packages/website/src/components/overlays/dialog/dialogPortal.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import * as DialogPrimitive from "@radix-ui/react-dialog" - -export const DialogPortal = DialogPrimitive.Portal diff --git a/packages/website/src/components/overlays/dialog/dialogTrigger.tsx b/packages/website/src/components/overlays/dialog/dialogTrigger.tsx deleted file mode 100644 index 85040ceb..00000000 --- a/packages/website/src/components/overlays/dialog/dialogTrigger.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import * as DialogPrimitive from "@radix-ui/react-dialog" - -export const DialogTrigger = DialogPrimitive.Trigger diff --git a/packages/website/src/components/overlays/popover/PopoverContent.tsx b/packages/website/src/components/overlays/popover/PopoverContent.tsx index 9bc4e71a..ee23a039 100644 --- a/packages/website/src/components/overlays/popover/PopoverContent.tsx +++ b/packages/website/src/components/overlays/popover/PopoverContent.tsx @@ -1,36 +1 @@ -import { css, cx } from "@arrhes/ui/utilities/cn.js" -import * as PopoverPrimitive from "@radix-ui/react-popover" -import type { ComponentProps } from "react" - -export function PopoverContent(props: ComponentProps) { - return ( - - - - ) -} +export { PopoverContent } from "@arrhes/ui/components/overlays/popover/PopoverContent.js" diff --git a/packages/website/src/components/overlays/popover/popoverClose.tsx b/packages/website/src/components/overlays/popover/popoverClose.tsx index a945fec4..6a88d6e5 100644 --- a/packages/website/src/components/overlays/popover/popoverClose.tsx +++ b/packages/website/src/components/overlays/popover/popoverClose.tsx @@ -1,3 +1 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" - -export const PopoverClose = PopoverPrimitive.Close +export { PopoverClose } from "@arrhes/ui/components/overlays/popover/popoverClose.js" diff --git a/packages/website/src/components/overlays/popover/popoverRoot.tsx b/packages/website/src/components/overlays/popover/popoverRoot.tsx index 1320adea..917b027a 100644 --- a/packages/website/src/components/overlays/popover/popoverRoot.tsx +++ b/packages/website/src/components/overlays/popover/popoverRoot.tsx @@ -1,3 +1 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" - -export const PopoverRoot = PopoverPrimitive.Root +export { PopoverRoot } from "@arrhes/ui/components/overlays/popover/popoverRoot.js" diff --git a/packages/website/src/components/overlays/popover/popoverTrigger.tsx b/packages/website/src/components/overlays/popover/popoverTrigger.tsx index d421191f..4d607233 100644 --- a/packages/website/src/components/overlays/popover/popoverTrigger.tsx +++ b/packages/website/src/components/overlays/popover/popoverTrigger.tsx @@ -1,3 +1 @@ -import * as PopoverPrimitive from "@radix-ui/react-popover" - -export const PopoverTrigger = PopoverPrimitive.Trigger +export { PopoverTrigger } from "@arrhes/ui/components/overlays/popover/popoverTrigger.js" diff --git a/packages/website/src/contexts/RootProvider.tsx b/packages/website/src/contexts/RootProvider.tsx index dc9109e3..762fc938 100644 --- a/packages/website/src/contexts/RootProvider.tsx +++ b/packages/website/src/contexts/RootProvider.tsx @@ -1,4 +1,4 @@ -import { CircularLoader, ToasterProvider } from "@arrhes/ui" +import { CircularLoader, ModalProvider, PopoverProvider, ToasterProvider } from "@arrhes/ui" import { Fragment, Suspense } from "react" import { DataProvider } from "./data/DataProvider.js" import { RouterProvider } from "./router/RouterProvider.js" @@ -7,11 +7,15 @@ export function RootProvider() { return ( - - }> - - - + + + + }> + + + + + ) } diff --git a/packages/website/src/contexts/tabs/tabsContext.tsx b/packages/website/src/contexts/tabs/tabsContext.tsx index df46c95e..b9ca007a 100644 --- a/packages/website/src/contexts/tabs/tabsContext.tsx +++ b/packages/website/src/contexts/tabs/tabsContext.tsx @@ -39,6 +39,7 @@ export type PanelTab = { id: string type: "panel" title: string + description?: string icon?: string component: React.ReactNode // never serialized } @@ -73,7 +74,7 @@ export type TabsContextValue = { activateTab: (id: string) => void navigateBack: (tabId: string) => void navigateForward: (tabId: string) => void - openPanelTab: (title: string, component: React.ReactNode, icon?: string) => string + openPanelTab: (title: string, component: React.ReactNode, description?: string, icon?: string) => string updateTabTitle: (id: string, title: string) => void reorderTabs: (tabId: string, beforeTabId: string | null) => void } diff --git a/packages/website/src/contexts/tabs/tabsProvider.tsx b/packages/website/src/contexts/tabs/tabsProvider.tsx index 04025b4d..8740bf94 100644 --- a/packages/website/src/contexts/tabs/tabsProvider.tsx +++ b/packages/website/src/contexts/tabs/tabsProvider.tsx @@ -211,7 +211,19 @@ export function TabsProvider({ children }: Props) { // Parse the destination URL/state and update tab context accordingly. useEffect(() => { const onPopState = (e: PopStateEvent) => { - const state = e.state as { tabId?: string; entryId?: string } | null + const state = e.state as { tabId?: string; entryId?: string; panelTabId?: string } | null + + // Panel-tab back/forward: re-activate the panel if it still exists, + // otherwise fall through to URL-based component-tab restoration. + if (state?.panelTabId !== undefined) { + const stillOpen = tabsRef.current.some((t) => t.id === state.panelTabId) + if (stillOpen) { + setActiveTabId(state.panelTabId) + return + } + // Panel was closed — fall through to URL restoration below. + } + let tabId: string | null = null let entryId: string | null = null if (state?.tabId !== undefined && state.entryId !== undefined) { @@ -348,11 +360,20 @@ export function TabsProvider({ children }: Props) { ), ) setActiveTabId(existing.id) - window.history.replaceState( - { tabId: existing.id, entryId: currentEntry(existing).id }, - "", - `/dashboard/${existing.id}/${currentEntry(existing).id}`, - ) + // Push so the previous tab's position is preserved in browser history. + if (currentActiveId !== existing.id) { + window.history.pushState( + { tabId: existing.id, entryId: currentEntry(existing).id }, + "", + `/dashboard/${existing.id}/${currentEntry(existing).id}`, + ) + } else { + window.history.replaceState( + { tabId: existing.id, entryId: currentEntry(existing).id }, + "", + `/dashboard/${existing.id}/${currentEntry(existing).id}`, + ) + } return } @@ -376,7 +397,12 @@ export function TabsProvider({ children }: Props) { newTab.id, ), ) - window.history.replaceState({ tabId: newTab.id, entryId: entry.id }, "", `/dashboard/${newTab.id}/${entry.id}`) + // Push so the previous tab's position is preserved in browser history. + if (currentActiveId !== null) { + window.history.pushState({ tabId: newTab.id, entryId: entry.id }, "", `/dashboard/${newTab.id}/${entry.id}`) + } else { + window.history.replaceState({ tabId: newTab.id, entryId: entry.id }, "", `/dashboard/${newTab.id}/${entry.id}`) + } }, []) const closeTab = useCallback((id: string) => { @@ -454,7 +480,14 @@ export function TabsProvider({ children }: Props) { setActiveTabId(id) const tab = tabsRef.current.find((t): t is ComponentTab => t.type === "component" && t.id === id) const entryId = tab ? currentEntry(tab).id : "0" - window.history.replaceState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) + // Push a new browser history entry when switching to a different tab so + // the back button returns to the previous tab at its exact position. + // Replace (no-op) when re-activating the already-active tab. + if (activeTabIdRef.current !== id) { + window.history.pushState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) + } else { + window.history.replaceState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) + } }, []) // Navigate within the tab's own history stack (does not add browser history entries). @@ -508,12 +541,21 @@ export function TabsProvider({ children }: Props) { ) }, []) - const openPanelTab = useCallback((title: string, component: React.ReactNode, icon?: string): string => { + const openPanelTab = useCallback((title: string, component: React.ReactNode, description?: string, icon?: string): string => { + // Dedup: if a panel tab with the same title already exists, focus it. + const existing = tabsRef.current.find((t): t is PanelTab => t.type === "panel" && t.title === title) + if (existing) { + setActiveTabId(existing.id) + window.history.pushState({ panelTabId: existing.id }, "", window.location.href) + return existing.id + } + const id = generateId() const newTab: PanelTab = { id, type: "panel", title, + description, icon, component, } @@ -522,6 +564,10 @@ export function TabsProvider({ children }: Props) { newTab, ]) setActiveTabId(id) + // Push a browser history entry so that pressing Back from a panel tab + // returns to the previous tab/panel rather than skipping it. + // Store the panel tab ID so popstate can re-activate it on forward. + window.history.pushState({ panelTabId: id }, "", window.location.href) return id }, []) diff --git a/packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx index f1147597..4dca574f 100644 --- a/packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/OrganizationLayout.tsx @@ -1,85 +1,5 @@ -import { - IconCalendarEvent, - IconFolders, - IconPlug, - IconRobot, - IconRosetteDiscountCheck, - IconSettings, - IconUsers, -} from "@tabler/icons-react" -import { Outlet, useParams } from "@tanstack/react-router" -import { Fragment } from "react/jsx-runtime" -import { PageNavigation } from "../../../components/layouts/page/PageNavigation.tsx" -import { organizationLayoutRoute } from "../../../routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx" +import { Outlet } from "@tanstack/react-router" export function OrganizationLayout() { - const params = useParams({ - from: organizationLayoutRoute.id, - }) - - return ( - - , - to: "/dashboard/organisations/$idOrganization/exercices", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Assistant", - icon: , - to: "/dashboard/organisations/$idOrganization/agent", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Stockage", - icon: , - to: "/dashboard/organisations/$idOrganization/stockage", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Membres", - icon: , - to: "/dashboard/organisations/$idOrganization/membres", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Facturation", - icon: , - to: "/dashboard/organisations/$idOrganization/facturation", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "API", - icon: , - to: "/dashboard/organisations/$idOrganization/api", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Paramètres", - icon: , - to: "/dashboard/organisations/$idOrganization/paramètres", - params: { - idOrganization: params.idOrganization, - }, - }, - ]} - /> - - - ) + return } diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx index 13736060..04e9890a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx @@ -11,14 +11,14 @@ import { Banner } from "../../../../components/layouts/Banner.tsx" import { EmptyState } from "../../../../components/layouts/EmptyState.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SearchBar } from "../../../../components/layouts/SearchBar.tsx" -import { organizationPathRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.tsx" + import { useDataFromAPI } from "../../../../utilities/useHTTPData.ts" import { extractSnippet } from "./extractSnippet.ts" export function AgentLayout() { const params = useParams({ - from: organizationPathRoute.id, - }) + strict: false, + }) as { idOrganization?: string; idAgentSession?: string } const [activeSessionId, setActiveSessionId] = useState(undefined) const [isMenuOpen, setIsMenuOpen] = useState(false) const navigate = useNavigate() @@ -37,12 +37,12 @@ export function AgentLayout() { routeDefinition: readAllAgentSessionsRouteDefinition, body: searchTrimmed ? { - idOrganization: params.idOrganization, - search: searchTrimmed, - } + idOrganization: params.idOrganization, + search: searchTrimmed, + } : { - idOrganization: params.idOrganization, - }, + idOrganization: params.idOrganization, + }, }) const displaySessions = sessions ?? [] diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx index 0c116ac2..fa922a96 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx @@ -15,9 +15,11 @@ import { ButtonOutlineContent, ButtonPlainContent, CircularLoader, + Dialog, InputSelect, InputTextArea, toast, + useModalStore, } from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { @@ -30,9 +32,8 @@ import { IconX, } from "@tabler/icons-react" import { useNavigate, useParams } from "@tanstack/react-router" -import { useCallback, useEffect, useRef, useState } from "react" +import { useCallback, useEffect, useId, useRef, useState } from "react" import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { Popover } from "../../../../components/overlays/popover/popover.tsx" import { dataClient } from "../../../../contexts/data/queryClient.ts" import { getCookie } from "../../../../utilities/cookies/getCookie.js" @@ -170,7 +171,8 @@ export function AgentSessionContent({ const _scrollContainerRef = useRef(null) const navigate = useNavigate() const [isDeleting, setIsDeleting] = useState(false) - const [deleteOpen, setDeleteOpen] = useState(false) + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const [editYear, setEditYear] = useState(undefined) const [editInstructions, setEditInstructions] = useState(undefined) const [isSavingContext, setIsSavingContext] = useState(false) @@ -360,151 +362,151 @@ export function AgentSessionContent({ setStreamMessageId(undefined) } - // SSE stream - ;(async () => { - let streamCompleted = false - try { - const headers: Record = { - "Content-Type": "application/json", - } - const orgCookie = getCookie(`${cookiePrefix}_id_organization`) - if (orgCookie) { - headers["X-Organization-Id"] = orgCookie - } - - const apiBaseUrl = resolveApiBaseUrl(import.meta.env.VITE_API_BASE_URL) - if (!apiBaseUrl) { - throw new Error("VITE_API_BASE_URL is not configured") - } + // SSE stream + ; (async () => { + let streamCompleted = false + try { + const headers: Record = { + "Content-Type": "application/json", + } + const orgCookie = getCookie(`${cookiePrefix}_id_organization`) + if (orgCookie) { + headers["X-Organization-Id"] = orgCookie + } - const response = await fetch(new URL(`${apiBaseUrl}${getStreamForAgentMessageRouteDefinition.path}`), { - method: "POST", - credentials: "include", - signal: controller.signal, - headers, - body: JSON.stringify({ - idOrganization: idOrganization, - idAgentMessage: streamMessageId, - }), - }) + const apiBaseUrl = resolveApiBaseUrl(import.meta.env.VITE_API_BASE_URL) + if (!apiBaseUrl) { + throw new Error("VITE_API_BASE_URL is not configured") + } - if (!isHealthyStreamResponse(response)) { - toast({ - title: "Le flux de reponse est indisponible", - description: "Veuillez renvoyer votre message.", - variant: "error", + const response = await fetch(new URL(`${apiBaseUrl}${getStreamForAgentMessageRouteDefinition.path}`), { + method: "POST", + credentials: "include", + signal: controller.signal, + headers, + body: JSON.stringify({ + idOrganization: idOrganization, + idAgentMessage: streamMessageId, + }), }) - if (!controller.signal.aborted) { - await finish() + + if (!isHealthyStreamResponse(response)) { + toast({ + title: "Le flux de reponse est indisponible", + description: "Veuillez renvoyer votre message.", + variant: "error", + }) + if (!controller.signal.aborted) { + await finish() + } + return } - return - } - const reader = response.body.getReader() - const decoder = new TextDecoder() - let buffer = "" + const reader = response.body.getReader() + const decoder = new TextDecoder() + let buffer = "" - while (true) { - const { done, value } = await reader.read() - if (done) break + while (true) { + const { done, value } = await reader.read() + if (done) break - buffer += decoder.decode(value, { - stream: true, - }) + buffer += decoder.decode(value, { + stream: true, + }) - const parts = buffer.split("\n\n") - buffer = parts.pop() ?? "" - - for (const part of parts) { - for (const line of part.split("\n")) { - if (!line.startsWith("data: ")) continue - const jsonStr = line.slice(6).trim() - if (!jsonStr) continue - - try { - const chunk = JSON.parse(jsonStr) - if (chunk.type === "TEXT_MESSAGE_CONTENT" && typeof chunk.delta === "string") { - if (chunk.subagentSkills && subagentStack.length > 0) { - // Accumulate subagent content - const current = subagentStack[subagentStack.length - 1] - if (current) { - current.content += chunk.delta - setActiveSubagents([ - ...subagentStack, - ]) + const parts = buffer.split("\n\n") + buffer = parts.pop() ?? "" + + for (const part of parts) { + for (const line of part.split("\n")) { + if (!line.startsWith("data: ")) continue + const jsonStr = line.slice(6).trim() + if (!jsonStr) continue + + try { + const chunk = JSON.parse(jsonStr) + if (chunk.type === "TEXT_MESSAGE_CONTENT" && typeof chunk.delta === "string") { + if (chunk.subagentSkills && subagentStack.length > 0) { + // Accumulate subagent content + const current = subagentStack[subagentStack.length - 1] + if (current) { + current.content += chunk.delta + setActiveSubagents([ + ...subagentStack, + ]) + } + } else { + accumulated += chunk.delta + setStreamingContent(accumulated) } - } else { - accumulated += chunk.delta - setStreamingContent(accumulated) } - } - if (chunk.type === "TOOL_CALL_START") { - // Emit text boundary if text accumulated since last boundary - if (accumulated.length > lastBoundaryLen) { - accumulatedToolCalls.push({ - type: "TEXT_BOUNDARY", - contentLength: accumulated.length, + if (chunk.type === "TOOL_CALL_START") { + // Emit text boundary if text accumulated since last boundary + if (accumulated.length > lastBoundaryLen) { + accumulatedToolCalls.push({ + type: "TEXT_BOUNDARY", + contentLength: accumulated.length, + }) + lastBoundaryLen = accumulated.length + } + accumulatedToolCalls.push(chunk) + setStreamingToolCalls([ + ...accumulatedToolCalls, + ]) + } + if (chunk.type === "CONTEXT_LIMIT_WARNING") { + toast({ + title: "La conversation approche de sa limite de contexte", + description: `${chunk.usage}% de la capacité utilisée. Envisagez de créer une nouvelle session.`, + variant: "warning", }) - lastBoundaryLen = accumulated.length } - accumulatedToolCalls.push(chunk) - setStreamingToolCalls([ - ...accumulatedToolCalls, - ]) - } - if (chunk.type === "CONTEXT_LIMIT_WARNING") { - toast({ - title: "La conversation approche de sa limite de contexte", - description: `${chunk.usage}% de la capacité utilisée. Envisagez de créer une nouvelle session.`, - variant: "warning", - }) - } - if (chunk.type === "TOOL_CALL_END") { - // Deduplicate: framework re-emits TOOL_CALL_END after RUN_FINISHED - const tcId = chunk.toolCallId as string | undefined - if (tcId && seenEnds.has(tcId)) continue - if (tcId) seenEnds.add(tcId) - accumulatedToolCalls.push(chunk) - setStreamingToolCalls([ - ...accumulatedToolCalls, - ]) - } - if (chunk.type === "SUBAGENT_RUN_START") { - subagentStack.push({ - role: (chunk.skills as string) ?? "subagent", - depth: chunk.depth as number, - content: "", - }) - setActiveSubagents([ - ...subagentStack, - ]) - } - if (chunk.type === "SUBAGENT_RUN_END") { - subagentStack.pop() - setActiveSubagents([ - ...subagentStack, - ]) + if (chunk.type === "TOOL_CALL_END") { + // Deduplicate: framework re-emits TOOL_CALL_END after RUN_FINISHED + const tcId = chunk.toolCallId as string | undefined + if (tcId && seenEnds.has(tcId)) continue + if (tcId) seenEnds.add(tcId) + accumulatedToolCalls.push(chunk) + setStreamingToolCalls([ + ...accumulatedToolCalls, + ]) + } + if (chunk.type === "SUBAGENT_RUN_START") { + subagentStack.push({ + role: (chunk.skills as string) ?? "subagent", + depth: chunk.depth as number, + content: "", + }) + setActiveSubagents([ + ...subagentStack, + ]) + } + if (chunk.type === "SUBAGENT_RUN_END") { + subagentStack.pop() + setActiveSubagents([ + ...subagentStack, + ]) + } + } catch { + // ignore malformed chunks } - } catch { - // ignore malformed chunks } } } - } - streamCompleted = true - } catch (err: unknown) { - if (err instanceof Error && err.name === "AbortError") return - console.error("[stream] SSE error — falling back to polling", err) - } finally { - // Only finish when the stream completed naturally. - // If the SSE failed (network/auth error), let the polling - // fallback continue running so it can detect completion. - if (streamCompleted && !controller.signal.aborted) { - finish() + streamCompleted = true + } catch (err: unknown) { + if (err instanceof Error && err.name === "AbortError") return + console.error("[stream] SSE error — falling back to polling", err) + } finally { + // Only finish when the stream completed naturally. + // If the SSE failed (network/auth error), let the polling + // fallback continue running so it can detect completion. + if (streamCompleted && !controller.signal.aborted) { + finish() + } } - } - })() + })() // Polling failsafe: if SSE fails or is slow, periodically // check the DB for the completed message @@ -1083,7 +1085,29 @@ export function AgentSessionContent({ className={css({ width: "100%", })} - onClick={() => setDeleteOpen(true)} + onClick={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer cette session ? + + + + Cette action supprimera définitivement la conversation et son historique. Cette action est irréversible. + + + + + + + , + ) + } > } @@ -1103,7 +1127,7 @@ export function AgentSessionContent({ @@ -1181,9 +1205,9 @@ export function AgentSessionContent({ yearsData === undefined ? [] : yearsData.map((year) => ({ - key: year.id, - label: year.label, - })) + key: year.id, + label: year.label, + })) } />
@@ -1267,17 +1291,6 @@ export function AgentSessionContent({ />
- diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx index b2790f97..85d08579 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.tsx @@ -1,37 +1,5 @@ -import { IconHome, IconKey } from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" -import { organizationApiLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx" +import { Outlet } from "@tanstack/react-router" export function OrganizationApiLayout() { - const params = useParams({ - from: organizationApiLayoutRoute.id, - }) - - return ( - , - to: "/dashboard/organisations/$idOrganization/api", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Clés", - icon: , - to: "/dashboard/organisations/$idOrganization/api/clés", - params: { - idOrganization: params.idOrganization, - }, - }, - ], - }, - }} - /> - ) + return } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx index 099abeca..7ef43b2d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx @@ -1,9 +1,8 @@ import type { readAllApiKeysRouteDefinition as ReadAllApiKeysRouteDefinition } from "@arrhes/application-metadata/routes" import { deleteOneApiKeyRouteDefinition, readAllApiKeysRouteDefinition } from "@arrhes/application-metadata/routes" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -11,6 +10,9 @@ export function DeleteOneApiKey(props: { apiKey: v.InferOutput[number] children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneApiKeyRouteDefinition, @@ -38,16 +40,32 @@ export function DeleteOneApiKey(props: { } return ( - + openModal( + modalId, + + + Voulez-vous supprimer cette clé API ? + + + + Cette action est irréversible. Les applications utilisant cette clé ne pourront plus accéder à l'API. + + + + + + + , + ) + } > {props.children} - + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx index 5dd62ad7..b7c34500 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx @@ -2,60 +2,74 @@ import { cancelSubscriptionRouteDefinition, readOrganizationBillingRouteDefinition, } from "@arrhes/application-metadata/routes" -import { ButtonOutlineContent, toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" import { IconPlayerPause } from "@tabler/icons-react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" +import { useId } from "react" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" export function CancelSubscription(_props: { idOrganization: string }) { - return ( - - Votre accès Premium sera maintenu jusqu'à la fin de la période en cours. -
- Aucun nouveau paiement ne sera prélevé. -
- Vous pourrez vous abonner de nouveau à tout moment. - - } - submitButtonProps={{ - text: "Mettre en pause l'abonnement", - color: "danger", - leftIcon: , - }} - onSubmit={async () => { - const response = await getResponseBodyFromAPI({ - routeDefinition: cancelSubscriptionRouteDefinition, - body: {}, - }) + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + + async function onSubmit() { + const response = await getResponseBodyFromAPI({ + routeDefinition: cancelSubscriptionRouteDefinition, + body: {}, + }) - if (response.ok === false) { - toast({ - title: "Erreur lors de la mise en pause de l'abonnement", - variant: "error", - }) - return - } + if (response.ok === false) { + toast({ + title: "Erreur lors de la mise en pause de l'abonnement", + variant: "error", + }) + return + } - await invalidateData({ - routeDefinition: readOrganizationBillingRouteDefinition, - body: {}, - }) + await invalidateData({ + routeDefinition: readOrganizationBillingRouteDefinition, + body: {}, + }) - toast({ - title: "Abonnement mis en pause", - variant: "success", - }) - }} + toast({ + title: "Abonnement mis en pause", + variant: "success", + }) + } + + return ( + + + + , + ) + } > } text="Mettre en pause l'abonnement" color="danger" /> -
+ ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx index e1d66910..a1f348d9 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.tsx @@ -1,53 +1,5 @@ -import { IconFileInvoice, IconPuzzle, IconReceipt, IconWallet } from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" -import { organizationBillingLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx" +import { Outlet } from "@tanstack/react-router" export function OrganizationBillingLayout() { - const params = useParams({ - from: organizationBillingLayoutRoute.id, - }) - - return ( - , - to: "/dashboard/organisations/$idOrganization/facturation", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Services", - icon: , - to: "/dashboard/organisations/$idOrganization/facturation/services", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Paiements", - icon: , - to: "/dashboard/organisations/$idOrganization/facturation/historique", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Factures", - icon: , - to: "/dashboard/organisations/$idOrganization/facturation/factures", - params: { - idOrganization: params.idOrganization, - }, - }, - ], - }, - }} - /> - ) + return } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx index dbbf20f7..56d84f5e 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx @@ -2,54 +2,69 @@ import { createFirstPaymentRouteDefinition, readOrganizationBillingRouteDefinition, } from "@arrhes/application-metadata/routes" -import { ButtonOutlineContent, toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" import { IconPlayerPlay } from "@tabler/icons-react" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" +import { useId } from "react" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" export function ResumeSubscription() { - return ( - - Les prélèvements mensuels automatiques reprendront à partir de la prochaine échéance. -
- Aucun nouveau paiement immédiat ne sera prélevé. - - } - submitButtonProps={{ - color: "default", - text: "Reprendre les paiements", - leftIcon: , - }} - onSubmit={async () => { - const response = await getResponseBodyFromAPI({ - routeDefinition: createFirstPaymentRouteDefinition, - body: {}, - }) + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + + async function onSubmit() { + const response = await getResponseBodyFromAPI({ + routeDefinition: createFirstPaymentRouteDefinition, + body: {}, + }) - if (response.ok === false) { - toast({ - title: "Erreur lors de la reprise des paiements", - variant: "error", - }) - return - } + if (response.ok === false) { + toast({ + title: "Erreur lors de la reprise des paiements", + variant: "error", + }) + return + } - await invalidateData({ - routeDefinition: readOrganizationBillingRouteDefinition, - body: {}, - }) + await invalidateData({ + routeDefinition: readOrganizationBillingRouteDefinition, + body: {}, + }) - window.location.href = response.data.checkoutUrl - }} + window.location.href = response.data.checkoutUrl + } + + return ( + + + + , + ) + } > } text="Reprendre l'abonnement" /> -
+ ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx index 936893b5..7d736953 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx @@ -3,20 +3,20 @@ import { updateLicenceSubscriptionRouteDefinition, } from "@arrhes/application-metadata/routes" import { getAmountTTCFromHTInCents, SUPPORT_TIERS, VAT_PERCENT } from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, Dialog, toast, useModalStore } from "@arrhes/ui" import { InputCurrency } from "@arrhes/ui/components/inputs/InputCurrency.js" import { css } from "@arrhes/ui/utilities/cn.js" import { IconDeviceFloppy } from "@tabler/icons-react" -import { useState } from "react" +import { useId, useState } from "react" import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" function UpdateLicenceForm(props: { idOrganization: string; currentAmountInCents: number }) { - const [confirmOpen, setConfirmOpen] = useState(false) + const confirmModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const [value, setValue] = useState(props.currentAmountInCents) const [isSaving, setIsSaving] = useState(false) const valueTTCInCents = getAmountTTCFromHTInCents(value) @@ -129,7 +129,29 @@ function UpdateLicenceForm(props: { idOrganization: string; currentAmountInCents + + + , + ) + } hasLoader isDisabled={isSaving} > @@ -138,16 +160,7 @@ function UpdateLicenceForm(props: { idOrganization: string; currentAmountInCents text={isSaving ? "Enregistrement..." : "Enregistrer"} /> - + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx index c9029a85..1c577b4b 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx @@ -9,13 +9,12 @@ import { OCR_PAGE_TIERS, VAT_PERCENT, } from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, ButtonPlainContent, InputNumber, toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, InputNumber, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCreditCard, IconX } from "@tabler/icons-react" -import { type ReactNode, useEffect, useState } from "react" +import { type ReactNode, useEffect, useId, useState } from "react" import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -71,7 +70,8 @@ function FormSection(props: { title: string; description?: string; children: Rea } function UpdateOcrForm(props: { idOrganization: string; currentQuantity: number; currentPagesLeft: number }) { - const [confirmOpen, setConfirmOpen] = useState(false) + const confirmModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const [quantityDelta, setQuantityDelta] = useState(0) const nextQuantity = props.currentQuantity + quantityDelta const deltaAmountInCents = quantityDelta * OCR_PAGE_PRICE_IN_CENTS @@ -246,7 +246,29 @@ function UpdateOcrForm(props: { idOrganization: string; currentQuantity: number; /> + + + , + ) + } isDisabled={quantityDelta === 0} > - ) } @@ -288,8 +300,8 @@ export function UpdateOcrPage({ idOrganization }: { idOrganization: string }) { idOrganization={idOrganization} currentQuantity={Math.max( organization.ocrPagesTotalAvailable + - organization.ocrPagesTotalUsed - - INCLUDED_OCR_PAGES, + organization.ocrPagesTotalUsed - + INCLUDED_OCR_PAGES, 0, )} currentPagesLeft={organization.ocrPagesTotalAvailable} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx index 8e5861d7..33439f01 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx @@ -8,13 +8,12 @@ import { STORAGE_PRICE_PER_GB_IN_CENTS, VAT_PERCENT, } from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, Dialog, InputNumber, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconMinus, IconPlus } from "@tabler/icons-react" -import { type ReactNode, useEffect, useState } from "react" +import { type ReactNode, useEffect, useId, useState } from "react" import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -110,7 +109,8 @@ function UpdateStorageForm(props: { currentUsageInBytes: number currentMaxUsageInBytes: number }) { - const [confirmOpen, setConfirmOpen] = useState(false) + const confirmModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const [quantityDelta, setQuantityDelta] = useState(0) const [isLoading, setIsLoading] = useState(false) const minimumQuantity = getMinimumStorageQuantityFromUsage(props.currentUsageInBytes) @@ -179,8 +179,8 @@ function UpdateStorageForm(props: { {quantityDelta > 0 ? `Augmenter le stockage est immédiat : le montant prorata du mois est débité du portefeuille. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` : quantityDelta < 0 - ? `Réduire le stockage est effectif le 1er du mois prochain. Aucun remboursement n'est appliqué. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` - : `Ajustez le stockage disponible pour l'organisation. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).`} + ? `Réduire le stockage est effectif le 1er du mois prochain. Aucun remboursement n'est appliqué. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` + : `Ajustez le stockage disponible pour l'organisation. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).`}

0 ? "warning/5" : deltaAmountInCents < 0 - ? "success/5" - : "neutral/1", + ? "success/5" + : "neutral/1", })} > 0 ? "Débité maintenant (prorata)" : deltaAmountInCents < 0 - ? "Effectif le 1er du mois" - : "Ajustement portefeuille"} + ? "Effectif le 1er du mois" + : "Ajustement portefeuille"} + + + , + ) + } isDisabled={isLoading || quantityDelta === 0} > - 0 - ? `${formatBytes(nextStorageLimitInBytes)} de stockage. ≈\u2009${formatEuros(proRataAmountTTCInCents)} TTC seront débités du portefeuille (prorata du mois en cours).` - : `Le stockage sera réduit à ${formatBytes(nextStorageLimitInBytes)}, effectif le 1er du mois prochain.` - } - submitButtonProps={{ - text: "Confirmer", - }} - onSubmit={handleSave} - /> + ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx index d8edff9d..0bd8c0f9 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx @@ -10,13 +10,12 @@ import { TOKENS_PER_PACK, VAT_PERCENT, } from "@arrhes/application-metadata/utilities" -import { Button, ButtonOutlineContent, InputNumber, toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, Dialog, InputNumber, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconPlus } from "@tabler/icons-react" -import { type ReactNode, useEffect, useState } from "react" +import { type ReactNode, useEffect, useId, useState } from "react" import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { formatEuros } from "../../../../utilities/formatEuros.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -88,7 +87,8 @@ function FormSection(props: { title: string; description?: string; children: Rea } function UpdateTokensForm(props: { idOrganization: string; currentQuantity: number; currentTokensLeft: number }) { - const [confirmOpen, setConfirmOpen] = useState(false) + const confirmModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const [quantityDelta, setQuantityDelta] = useState(0) const nextQuantity = props.currentQuantity + quantityDelta const deltaAmountInCents = quantityDelta * TOKEN_PACK_PRICE_IN_CENTS @@ -262,7 +262,29 @@ function UpdateTokensForm(props: { idOrganization: string; currentQuantity: numb + + + , + ) + } isDisabled={quantityDelta === 0} > - ) } @@ -305,7 +317,7 @@ export function UpdateTokensPage({ idOrganization }: { idOrganization: string }) (organization.tokensTotalAvailable + organization.tokensTotalUsed - INCLUDED_AGENT_TOKENS) / - INCLUDED_AGENT_TOKENS, + INCLUDED_AGENT_TOKENS, ), 0, )} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx index 0d9161ba..8fa61d69 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx @@ -8,7 +8,7 @@ import { Banner } from "../../../../../components/layouts/Banner.tsx" import { DataWrapper } from "../../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../../components/layouts/settingsSection/settingsSection.tsx" -import { organizationInvoiceUblRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.js" + import { InvoicePaymentsTable } from "./InvoicePaymentsTable.tsx" import { InvoiceXMLViewer } from "./InvoiceXMLViewer.tsx" @@ -77,8 +77,8 @@ function InvoiceTabsContent(props: { } export function OrganizationInvoicePage() { const params = useParams({ - from: organizationInvoiceUblRoute.id, - }) + strict: false, + }) as { idInvoice?: string } return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx index a1a4c49c..12c9349d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx @@ -3,10 +3,9 @@ import { getAllMyOrganizationsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -15,50 +14,66 @@ export function DeleteOneOrganization(props: { idOrganization: v.InferOutput["id"] children: ReactElement> }) { - return ( - - Cette action supprimera l'organisation et toutes les données associées. -
- Cette action est irréversible. - - } - submitButtonProps={{ - color: "danger", - text: "Supprimer l'organisation", - }} - onSubmit={async () => { - const deleteResponse = await getResponseBodyFromAPI({ - routeDefinition: deleteOneOrganizationRouteDefinition, - body: {}, - }) + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + + async function onSubmit() { + const deleteResponse = await getResponseBodyFromAPI({ + routeDefinition: deleteOneOrganizationRouteDefinition, + body: {}, + }) - if (deleteResponse.ok === false) { - toast({ - title: "Erreur lors de la suppression de l'organisation", - variant: "error", - }) - return - } + if (deleteResponse.ok === false) { + toast({ + title: "Erreur lors de la suppression de l'organisation", + variant: "error", + }) + return + } - await invalidateData({ - routeDefinition: getAllMyOrganizationsRouteDefinition, - body: {}, - }) + await invalidateData({ + routeDefinition: getAllMyOrganizationsRouteDefinition, + body: {}, + }) - toast({ - title: "Organisation supprimée", - variant: "success", - }) + toast({ + title: "Organisation supprimée", + variant: "success", + }) - applicationRouter.navigate({ - to: "/dashboard/organisations", - }) - }} + applicationRouter.navigate({ + to: "/dashboard/organisations", + }) + } + + return ( + + + + , + ) + } > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx index 31ad324a..8a7afc08 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.tsx @@ -1,37 +1,5 @@ -import { IconHome, IconLock } from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" -import { organizationSettingsLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx" +import { Outlet } from "@tanstack/react-router" export function OrganizationSettingsLayout() { - const params = useParams({ - from: organizationSettingsLayoutRoute.id, - }) - - return ( - , - to: "/dashboard/organisations/$idOrganization/paramètres", - params: { - idOrganization: params.idOrganization, - }, - }, - { - label: "Sécurité", - icon: , - to: "/dashboard/organisations/$idOrganization/paramètres/sécurité", - params: { - idOrganization: params.idOrganization, - }, - }, - ], - }, - }} - /> - ) + return } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx index ed13e08a..f07e0df3 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx @@ -3,10 +3,9 @@ import { readOneOrganizationRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -14,6 +13,9 @@ export function DeleteOneOrganizationUser(props: { organizationUser: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneOrganizationUserRouteDefinition, @@ -43,16 +45,30 @@ export function DeleteOneOrganizationUser(props: { } return ( - + openModal( + modalId, + + + Voulez-vous révoquer l'utilisateur de cette organisation ? + + + Cette action est irréversible. + + + + + + , + ) + } > {props.children} - + ) } diff --git a/packages/website/src/features/dashboard/$idYear/YearLayout.tsx b/packages/website/src/features/dashboard/$idYear/YearLayout.tsx index 86f3c444..2cc1e9ba 100644 --- a/packages/website/src/features/dashboard/$idYear/YearLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/YearLayout.tsx @@ -1,48 +1,5 @@ -import { IconPencil, IconReport, IconSettings } from "@tabler/icons-react" -import { Outlet, useParams } from "@tanstack/react-router" -import { Fragment } from "react/jsx-runtime" -import { PageNavigation } from "../../../components/layouts/page/PageNavigation.tsx" -import { yearLayoutRoute } from "../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx" +import { Outlet } from "@tanstack/react-router" export function YearLayout() { - const params = useParams({ - from: yearLayoutRoute.id, - }) - - return ( - - , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/écritures", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Documents comptables", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Paramètres", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - ]} - /> - - - ) + return } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx index 79dc6ccf..7317ca04 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx @@ -3,10 +3,9 @@ import { readAllEntryLinesRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -15,6 +14,9 @@ export function DeleteOneEntryLine(props: { entryLine: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneEntryLineRouteDefinition, @@ -64,22 +66,33 @@ export function DeleteOneEntryLine(props: { } return ( - - Cette action supprimera le mouvement et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer le mouvement", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx index ffc0d143..afd26269 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx @@ -8,14 +8,14 @@ import { Page } from "../../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../components/LinkButton.tsx" -import { entryLineLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx" + import { DeleteOneEntryLine } from "./DeleteOneEntryLine.tsx" import { UpdateOneEntryLine } from "./UpdateOneEntryLine.tsx" export function EntryLineLayout() { const params = useParams({ - from: entryLineLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idEntryLine?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx index 1d2bb371..9b6d6743 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" -import { entryLineLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx" + export function EntryLineMetadataTab() { const params = useParams({ - from: entryLineLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idEntryLine?: string } return ( , + props.entryLine.label ?? undefined, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/CreateOneEntryLine.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/CreateOneEntryLine.tsx index 41c49f79..e0c29993 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/CreateOneEntryLine.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/CreateOneEntryLine.tsx @@ -405,6 +405,7 @@ export function CreateOneEntryLine(props: { )} , + props.entry.label ?? undefined, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DeleteOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DeleteOneEntry.tsx index 5939f488..4d58ac62 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DeleteOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DeleteOneEntry.tsx @@ -1,9 +1,8 @@ import { deleteOneEntryRouteDefinition, readAllEntriesRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -12,6 +11,9 @@ export function DeleteOneEntry(props: { entry: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneEntryRouteDefinition, @@ -51,22 +53,33 @@ export function DeleteOneEntry(props: { } return ( - - Cette action supprimera l'écriture et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer l'écriture", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DuplicateOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DuplicateOneEntry.tsx index aa6f3807..c72b7709 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DuplicateOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/DuplicateOneEntry.tsx @@ -4,12 +4,11 @@ import { readAllEntryTagsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonGhostContent, ButtonPlainContent, toast } from "@arrhes/ui" +import { Button, ButtonGhostContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCopyCheck } from "@tabler/icons-react" -import { type ComponentPropsWithRef, type ReactElement, useState } from "react" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { Dialog } from "../../../../../components/overlays/dialog/dialog.tsx" import { applicationRouter } from "../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" @@ -18,7 +17,8 @@ export function DuplicateOneEntry(props: { entry: v.InferOutput children: ReactElement> }) { - const [open, setOpen] = useState(false) + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() async function onSubmit() { const duplicateResponse = await getResponseBodyFromAPI({ @@ -66,61 +66,51 @@ export function DuplicateOneEntry(props: { }, }) - setOpen(false) - } - - async function onCancel() { - setOpen(false) + closeModal(modalId) } return ( - setOpen(value)} - > - { - setOpen(true) - event.preventDefault() - }} - > - {props.children} - - {open === false ? null : ( - - -
- Voulez-vous dupliquer cette écriture ? - - Cette action dupliquera l'écriture et toutes les données associées. - -
- - - - -
- )} -
+ Voulez-vous dupliquer cette écriture ? + + Cette action dupliquera l'écriture et toutes les données associées. + + + + + + + , + ) + } + > + {props.children} + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx similarity index 73% rename from packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryPage.tsx rename to packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx index 220d7090..cf597d7a 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx @@ -5,52 +5,20 @@ import { IconPencil } from "@tabler/icons-react" import type * as v from "valibot" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { UpdateOneEntry } from "./UpdateOneEntry.tsx" +import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" -export type EntryPageData = { - entry: v.InferOutput - journal: v.InferOutput | null - entryTagLabels: string[] - file: v.InferOutput | null - totalDebit: number - totalCredit: number -} - -// Used by the tab system — receives pre-resolved data from EntryTabContent's YearDataWrapper. -export function EntryPage(props: EntryPageData) { - const { openTab } = useTabs() - - return ( - - openTab({ - component: "fichier", - props: { - idOrganization, - idFile, - }, - }) - } - /> - ) -} -function EntryInformationsTab(props: { +export function EntryInformationsTab(props: { entry: v.InferOutput journal: v.InferOutput | null entryTagLabels: string[] file: v.InferOutput | null totalDebit: number totalCredit: number - onFileClick: (idOrganization: string, idFile: string) => void }) { + const { openTab } = useTabs() + return ( ) : ( - )} diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx index 7b0f4eeb..60249379 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx @@ -18,7 +18,7 @@ import { Page } from "../../../../../components/layouts/page/page.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../components/LinkButton.js" import { Popover } from "../../../../../components/overlays/popover/popover.js" -import { entryLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx" + import { compareAmounts } from "../../../../../utilities/compareAmounts.ts" import type { YearDataKey } from "../../YearDataWrapper.tsx" import { YearDataWrapper } from "../../YearDataWrapper.tsx" @@ -38,8 +38,8 @@ const requiredKeys = [ export function EntryLayout() { const params = useParams({ - from: entryLayoutRoute.id, - }) + strict: false, + }) as { idOrganization?: string; idYear?: string; idEntry?: string } const [menuOpen, setMenuOpen] = useState(false) return ( diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx index 6b44345a..178fd312 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx @@ -3,7 +3,6 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconEdit, IconPlus } from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" import type * as v from "valibot" import { Section } from "../../../../../components/layouts/section/section.tsx" import type { YearDataKey } from "../../YearDataWrapper.tsx" @@ -18,15 +17,13 @@ const requiredKeys = [ "accounts", ] as const satisfies readonly YearDataKey[] -export function EntryLinesTab(props: { idYear?: string; idEntry?: string } = {}) { - const params = useParams({ - strict: false, - }) as { - idYear?: string - idEntry?: string - } - const idYear = props.idYear ?? params.idYear ?? "" - const idEntry = props.idEntry ?? params.idEntry ?? "" +export function EntryLinesTab(props: { + idYear: string + idEntry: string +}) { + + const idYear = props.idYear + const idEntry = props.idEntry return ( - -
- - } - text="Modifier" - /> - - - - - - - -
setMenuOpen(false)} - > - } - text="Extourner" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> -
-
- -
setMenuOpen(false)} - > - } - text="Dupliquer" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> -
-
-
-
- -
- } - title="Supprimer" - color="danger" - /> -
-
-
+ {entry.idFile !== null ? null : ( Il manque une pièce justificative. )} @@ -171,6 +93,8 @@ export function EntryTabContent(props: { idOrganization: string; idYear: string; ) )} + + , content: ( - + > + + + + + + +
setMenuOpen(false)} + > + } + text="Extourner" + className={css({ + width: "100%", + justifyContent: "start", + })} + /> +
+
+ +
setMenuOpen(false)} + > + } + text="Dupliquer" + className={css({ + width: "100%", + justifyContent: "start", + })} + /> +
+
+
+
+ +
+ } + title="Supprimer" + color="danger" + /> +
+
+
) diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx index 9c609ac3..30ae3829 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateManyEntryLines.tsx @@ -315,6 +315,7 @@ export function UpdateManyEntryLines(props: { )} , + props.entry.label ?? undefined, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx index 953317b5..190e7351 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/UpdateOneEntry.tsx @@ -23,7 +23,10 @@ import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../utilities/invalidateData.ts" -export function UpdateOneEntry(props: { entry: v.InferOutput; children: JSX.Element }) { +export function UpdateOneEntry(props: { + entry: v.InferOutput + children: JSX.Element +}) { const { openPanelTab, closeTab } = useTabs() return ( @@ -36,10 +39,7 @@ export function UpdateOneEntry(props: { entry: v.InferOutput { - const r = { - current: "", - } - r.current = openPanelTab( + const id = openPanelTab( "Modifier une écriture",
{(form) => ( @@ -202,6 +202,7 @@ export function UpdateOneEntry(props: { entry: v.InferOutput
, + props.entry.label ?? undefined, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx deleted file mode 100644 index 220d7090..00000000 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/entryPage.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonPlainContent, FormatDate, FormatNull, FormatPrice, FormatText, LinkContent } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconPencil } from "@tabler/icons-react" -import type * as v from "valibot" -import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" -import { Section } from "../../../../../components/layouts/section/section.tsx" -import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" -import { UpdateOneEntry } from "./UpdateOneEntry.tsx" - -export type EntryPageData = { - entry: v.InferOutput - journal: v.InferOutput | null - entryTagLabels: string[] - file: v.InferOutput | null - totalDebit: number - totalCredit: number -} - -// Used by the tab system — receives pre-resolved data from EntryTabContent's YearDataWrapper. -export function EntryPage(props: EntryPageData) { - const { openTab } = useTabs() - - return ( - - openTab({ - component: "fichier", - props: { - idOrganization, - idFile, - }, - }) - } - /> - ) -} - -function EntryInformationsTab(props: { - entry: v.InferOutput - journal: v.InferOutput | null - entryTagLabels: string[] - file: v.InferOutput | null - totalDebit: number - totalCredit: number - onFileClick: (idOrganization: string, idFile: string) => void -}) { - return ( - -
- - } - text="Modifier" - /> - -
- - - - - {props.entry.label} - - - - - - {props.entry.idJournal === null ? ( - - ) : props.journal !== null ? ( - {`(${props.journal.code}) ${props.journal.label}`} - ) : ( - - )} - - - {props.entry.idFile === null || props.file === null ? ( - - ) : ( - - )} - - - - - - - - - - - - - - -
- ) -} diff --git a/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx index 38673c74..8e9a1e19 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx @@ -1,11 +1,10 @@ import { deleteOneEntryRouteDefinition, readAllEntriesRouteDefinition } from "@arrhes/application-metadata/routes" -import { Button, ButtonGhostContent, toast } from "@arrhes/ui" +import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronDown, IconTrash } from "@tabler/icons-react" import type { Row } from "@tanstack/react-table" -import { useState } from "react" +import { useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Popover } from "../../../../components/overlays/popover/popover.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" @@ -13,7 +12,8 @@ import { invalidateData } from "../../../../utilities/invalidateData.js" type EntryRow = v.InferOutput[number] export function EntriesTableSelectionActions(props: { selectedRows: Array>; idYear: string }) { - const [deleteOpen, setDeleteOpen] = useState(false) + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() async function handleDelete() { const results = await Promise.all( @@ -69,7 +69,30 @@ export function EntriesTableSelectionActions(props: { selectedRows: Array setDeleteOpen(true)} + onClick={() => + openModal( + deleteModalId, + + + Supprimer les écritures sélectionnées + + + + {`Voulez-vous supprimer ${props.selectedRows.length} écriture${props.selectedRows.length > 1 ? "s" : "" + } ? Cette action est irréversible.`} + + + + + + + , + ) + } > } @@ -84,20 +107,7 @@ export function EntriesTableSelectionActions(props: { selectedRows: Array
- 1 ? "s" : "" - } ? Cette action est irréversible.`} - submitButtonProps={{ - text: "Supprimer", - leftIcon: , - color: "danger", - }} - onSubmit={handleDelete} - /> + ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx index 70cd279c..7e445d1e 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx @@ -5,10 +5,9 @@ import { readAllEntryTagsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -17,6 +16,9 @@ export function ReverseOneEntry(props: { entry: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const reverseResponse = await getResponseBodyFromAPI({ routeDefinition: reverseOneEntryRouteDefinition, @@ -71,21 +73,33 @@ export function ReverseOneEntry(props: { } return ( - - Cette action créera une écriture d'extourne avec les mêmes mouvements inversés. -
- L'écriture originale ne sera pas modifiée. - + + + + , + ) } - submitButtonProps={{ - text: "Extourner l'écriture", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx index d3d92b92..2430c6f8 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx @@ -1,9 +1,8 @@ import { readAllFilesRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../routes/applicationRouter.tsx" import { invalidateData } from "../../../../../utilities/invalidateData.ts" import { deleteFileWithSignedUrl } from "../deleteFileWithSignedUrl.ts" @@ -12,6 +11,9 @@ export function DeleteOneFile(props: { file: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const isDeleted = await deleteFileWithSignedUrl({ idFile: props.file.id, @@ -47,22 +49,33 @@ export function DeleteOneFile(props: { } return ( - - Cette action supprimera le fichier et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer le fichier", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx index 2e16fb6e..a37443c3 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx @@ -6,15 +6,15 @@ import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../components/LinkButton.tsx" -import { fileLayoutRoute } from "../../../../../routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx" + import { DeleteOneFile } from "./DeleteOneFile.tsx" import { FileData } from "./FileData.tsx" import { UpdateOneFile } from "./UpdateOneFile.tsx" export function FileLayout() { const params = useParams({ - from: fileLayoutRoute.id, - }) + strict: false, + }) as { idOrganization?: string; idFile?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx index a752020d..f645eb50 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/UpdateOneFile.tsx @@ -34,6 +34,7 @@ export function UpdateOneFile(props: { file: v.InferOutput closeTab(r.current)} /> , + props.file.name, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx index 31b276bb..a25856bc 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx @@ -4,12 +4,11 @@ import { readOrganizationBillingRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonGhostContent, Separator, toast } from "@arrhes/ui" +import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Separator, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconFileText, IconPencil, IconTrash } from "@tabler/icons-react" -import { useState } from "react" +import { useId, useState } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" import { Popover } from "../../../../components/overlays/popover/popover.js" import { useTabs } from "../../../../contexts/tabs/useTabs.js" @@ -21,8 +20,9 @@ import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" import { MoveOneFileForm } from "./MoveOneFileForm.js" export function FileActions(props: { file: v.InferOutput; idOrganization: string }) { - const [moveOpen, setMoveOpen] = useState(false) - const [deleteOpen, setDeleteOpen] = useState(false) + const moveModalId = useId() + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const [ocrLoading, setOcrLoading] = useState(false) const [ocrTooltipOpen, setOcrTooltipOpen] = useState(false) const { openPanelTab, closeTab, openTab } = useTabs() @@ -166,7 +166,26 @@ export function FileActions(props: { file: v.InferOutput setMoveOpen(true)} + onClick={() => + openModal( + moveModalId, + + + Déplacer le fichier + + + closeModal(moveModalId)} + /> + + , + ) + } > } @@ -242,7 +261,30 @@ export function FileActions(props: { file: v.InferOutput setDeleteOpen(true)} + onClick={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer ce fichier ? + + + + Cette action supprimera le fichier et toutes les données associées. + Cette action est irréversible. + + + + + + + , + ) + } > } @@ -257,45 +299,6 @@ export function FileActions(props: { file: v.InferOutput - - - - - Déplacer le fichier - - - setMoveOpen(false)} - /> - - - - - - Cette action supprimera le fichier et toutes les données associées. -
- Cette action est irréversible. - - } - submitButtonProps={{ - color: "danger", - text: "Supprimer le fichier", - }} - onSubmit={handleDelete} - open={deleteOpen} - onOpenChange={setDeleteOpen} - /> ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx index 9d6c254a..bb34ad68 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx @@ -1,12 +1,11 @@ import { readAllFilesRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, ButtonPlainContent, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconEye, IconPencil, IconTrash } from "@tabler/icons-react" -import { type ReactElement, useState } from "react" +import { type ReactElement, useId } from "react" import type * as v from "valibot" import { ContextMenu } from "../../../../components/overlays/contextMenu/contextMenu.js" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { applicationRouter } from "../../../../routes/applicationRouter.js" @@ -20,8 +19,9 @@ export function FileContextMenu(props: { idOrganization: string children: ReactElement }) { - const [moveOpen, setMoveOpen] = useState(false) - const [deleteOpen, setDeleteOpen] = useState(false) + const moveModalId = useId() + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const { openPanelTab, closeTab } = useTabs() async function handleDelete() { @@ -92,7 +92,26 @@ export function FileContextMenu(props: { } - onSelect={() => setMoveOpen(true)} + onSelect={() => + openModal( + moveModalId, + + + Déplacer le fichier + + + closeModal(moveModalId)} + /> + + , + ) + } > Déplacer @@ -100,52 +119,35 @@ export function FileContextMenu(props: { } color="danger" - onSelect={() => setDeleteOpen(true)} + onSelect={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer ce fichier ? + + + + Cette action supprimera le fichier et toutes les données associées. + Cette action est irréversible. + + + + + + + , + ) + } > Supprimer - - - - - Déplacer le fichier - - - setMoveOpen(false)} - /> - - - - - {/* Delete dialog (controlled externally) */} - - Cette action supprimera le fichier et toutes les données associées. -
- Cette action est irréversible. - - } - submitButtonProps={{ - color: "danger", - text: "Supprimer le fichier", - }} - onSubmit={handleDelete} - open={deleteOpen} - onOpenChange={setDeleteOpen} - /> ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx index 34bab188..b412c4a1 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx @@ -10,8 +10,7 @@ import { useNavigate, useParams, useSearch } from "@tanstack/react-router" import { type DragEvent, useState } from "react" import { DataWrapper } from "../../../../components/layouts/DataWrapper.js" import { Page } from "../../../../components/layouts/page/page.js" -import { storageLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.js" -import { storageRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.js" + import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" import { CreateOneFile } from "./CreateOneFile.js" @@ -20,11 +19,11 @@ import { FilesPageContent } from "./FilesPageContent.js" export function FilesPage() { const params = useParams({ - from: storageLayoutRoute.id, - }) + strict: false, + }) as { idOrganization?: string } const { idFolder } = useSearch({ - from: storageRoute.id, - }) + strict: false, + }) as { idFolder?: string } const navigate = useNavigate() // Current folder is derived from the URL search param @@ -35,8 +34,8 @@ export function FilesPage() { to: ".", search: folderId ? { - idFolder: folderId, - } + idFolder: folderId, + } : {}, }) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx index 4327bba2..865c6688 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx @@ -4,13 +4,12 @@ import { readAllFilesRouteDefinition, readAllFoldersRouteDefinition, } from "@arrhes/application-metadata/routes" -import { Button, ButtonGhostContent, toast } from "@arrhes/ui" +import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronDown, IconTrash } from "@tabler/icons-react" import type { Row } from "@tanstack/react-table" -import { useState } from "react" +import { useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Popover } from "../../../../components/overlays/popover/popover.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" import { invalidateData } from "../../../../utilities/invalidateData.js" @@ -18,19 +17,20 @@ import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" export type TableRow = | { - kind: "back" - } + kind: "back" + } | { - kind: "folder" - data: v.InferOutput - } + kind: "folder" + data: v.InferOutput + } | { - kind: "file" - data: v.InferOutput - } + kind: "file" + data: v.InferOutput + } export function FilesTableSelectionActions(props: { selectedRows: Array> }) { - const [deleteOpen, setDeleteOpen] = useState(false) + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const selectedFiles = props.selectedRows .filter((r) => r.original.kind === "file") .map( @@ -122,7 +122,30 @@ export function FilesTableSelectionActions(props: { selectedRows: Array setDeleteOpen(true)} + onClick={() => + openModal( + deleteModalId, + + + Supprimer les éléments sélectionnés + + + + {`Voulez-vous supprimer ${props.selectedRows.length} élément${props.selectedRows.length > 1 ? "s" : "" + } ? Cette action est irréversible.`} + + + + + + + , + ) + } > } @@ -137,20 +160,7 @@ export function FilesTableSelectionActions(props: { selectedRows: Array - 1 ? "s" : "" - } ? Cette action est irréversible.`} - submitButtonProps={{ - text: "Supprimer", - leftIcon: , - color: "danger", - }} - onSubmit={handleDelete} - /> + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx index a3ec32e2..5250d06e 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx @@ -1,11 +1,10 @@ import { deleteOneFolderRouteDefinition, readAllFoldersRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonGhostContent, Separator, toast } from "@arrhes/ui" +import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Separator, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconPencil, IconTrash } from "@tabler/icons-react" -import { useState } from "react" +import { useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" import { Popover } from "../../../../components/overlays/popover/popover.js" import { useTabs } from "../../../../contexts/tabs/useTabs.js" @@ -19,8 +18,9 @@ export function FolderActions(props: { idOrganization: string onFolderOpen: (folderId: string | null) => void }) { - const [moveOpen, setMoveOpen] = useState(false) - const [deleteOpen, setDeleteOpen] = useState(false) + const moveModalId = useId() + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const { openPanelTab, closeTab } = useTabs() async function handleDelete() { @@ -124,7 +124,26 @@ export function FolderActions(props: { className={css({ width: "100%", })} - onClick={() => setMoveOpen(true)} + onClick={() => + openModal( + moveModalId, + + + Déplacer le dossier + + + closeModal(moveModalId)} + /> + + , + ) + } > } @@ -142,7 +161,31 @@ export function FolderActions(props: { className={css({ width: "100%", })} - onClick={() => setDeleteOpen(true)} + onClick={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer ce dossier ? + + + + Cette action supprimera le dossier et tous ses sous-dossiers. + Les fichiers contenus ne seront pas supprimés. + Cette action est irréversible. + + + + + + + , + ) + } > } @@ -157,47 +200,6 @@ export function FolderActions(props: { - - - - - Déplacer le dossier - - - setMoveOpen(false)} - /> - - - - - - Cette action supprimera le dossier et tous ses sous-dossiers. -
- Les fichiers contenus ne seront pas supprimés. -
- Cette action est irréversible. - - } - submitButtonProps={{ - color: "danger", - text: "Supprimer le dossier", - }} - onSubmit={handleDelete} - open={deleteOpen} - onOpenChange={setDeleteOpen} - /> ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx index 1505976c..32776745 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx @@ -1,12 +1,11 @@ import { deleteOneFolderRouteDefinition, readAllFoldersRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" +import { Button, ButtonOutlineContent, ButtonPlainContent, toast, useModalStore } from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconPencil, IconTrash } from "@tabler/icons-react" -import { type ReactElement, useState } from "react" +import { type ReactElement, useId } from "react" import type * as v from "valibot" import { ContextMenu } from "../../../../components/overlays/contextMenu/contextMenu.js" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.js" import { Dialog } from "../../../../components/overlays/dialog/dialog.js" import { useTabs } from "../../../../contexts/tabs/useTabs.js" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" @@ -19,8 +18,9 @@ export function FolderContextMenu(props: { idOrganization: string children: ReactElement }) { - const [moveOpen, setMoveOpen] = useState(false) - const [deleteOpen, setDeleteOpen] = useState(false) + const moveModalId = useId() + const deleteModalId = useId() + const { open: openModal, close: closeModal } = useModalStore() const { openPanelTab, closeTab } = useTabs() async function handleDelete() { @@ -80,7 +80,26 @@ export function FolderContextMenu(props: { } - onSelect={() => setMoveOpen(true)} + onSelect={() => + openModal( + moveModalId, + + + Déplacer le dossier + + + closeModal(moveModalId)} + /> + + , + ) + } > Déplacer @@ -88,54 +107,36 @@ export function FolderContextMenu(props: { } color="danger" - onSelect={() => setDeleteOpen(true)} + onSelect={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer ce dossier ? + + + + Cette action supprimera le dossier et tous ses sous-dossiers. + Les fichiers contenus ne seront pas supprimés. + Cette action est irréversible. + + + + + + + , + ) + } > Supprimer - - - - - Déplacer le dossier - - - setMoveOpen(false)} - /> - - - - - {/* Delete dialog (controlled externally) */} - - Cette action supprimera le dossier et tous ses sous-dossiers. -
- Les fichiers contenus ne seront pas supprimés. -
- Cette action est irréversible. - - } - submitButtonProps={{ - color: "danger", - text: "Supprimer le dossier", - }} - onSubmit={handleDelete} - open={deleteOpen} - onOpenChange={setDeleteOpen} - /> ) } diff --git a/packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx b/packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx index c3efcf66..d642887f 100644 --- a/packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/reports/ReportsLayout.tsx @@ -1,74 +1,5 @@ -import { IconBook, IconBook2, IconChartBar, IconReport, IconReportMoney, IconScale } from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.js" -import { reportsLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.js" +import { Outlet } from "@tanstack/react-router" export function ReportsLayout() { - const params = useParams({ - from: reportsLayoutRoute.id, - }) - - return ( - , - items: [ - { - label: "Livre-journal", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents/livre-journal", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Grand livre", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents/grand-livre", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - ], - }, - summaries: { - title: "Synthèses", - icon: , - items: [ - { - label: "Balance", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents/balance", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Bilan", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents/bilan", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Compte de résultat", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents/compte-de-résultat", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - ], - }, - }} - /> - ) + return } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx index 7a4015ee..bfb98ab5 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx @@ -1,9 +1,8 @@ import { deleteOneYearRouteDefinition, readAllYearsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../components/overlays/dialog/ConfirmationModal.tsx" import { useTabs } from "../../../../contexts/tabs/useTabs.tsx" import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../utilities/invalidateData.ts" @@ -13,6 +12,8 @@ export function DeleteOneYear(props: { children: ReactElement> }) { const { openTab } = useTabs() + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ @@ -54,22 +55,33 @@ export function DeleteOneYear(props: { } return ( - - Cette action supprimera l'exercice et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer l'exercice", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx index d07eaa22..5dac14e7 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsLayout.tsx @@ -1,92 +1,5 @@ -import { - IconBook, - IconFileReport, - IconHome, - IconListNumbers, - IconReportMoney, - IconScale, - IconSettings, - IconTag, -} from "@tabler/icons-react" -import { useParams } from "@tanstack/react-router" -import { SubPageLayout } from "../../../../components/layouts/SubPageLayout.tsx" -import { yearSettingsLayoutRoute } from "../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx" +import { Outlet } from "@tanstack/react-router" export function YearSettingsLayout() { - const params = useParams({ - from: yearSettingsLayoutRoute.id, - }) - - return ( - , - items: [ - { - label: "Général", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Plan des comptes", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/comptes", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Journaux", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/journaux", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Catégories", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/catégories", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - ], - }, - documents: { - title: "Documents comptables", - icon: , - items: [ - { - label: "Bilan", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/bilan", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - { - label: "Compte de résultat", - icon: , - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/compte-de-résultat", - params: { - idOrganization: params.idOrganization, - idYear: params.idYear, - }, - }, - ], - }, - }} - /> - ) + return } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx index 3286d2df..da76805a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx @@ -7,14 +7,14 @@ import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.ts import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../components/LinkButton.tsx" -import { accountLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx" + import { DeleteOneAccount } from "./DeleteOneAccount.tsx" import { UpdateOneAccount } from "./UpdateOneAccount.tsx" export function AccountLayout() { const params = useParams({ - from: accountLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idAccount?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx index c054f50e..f0a00991 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" -import { accountLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx" + export function AccountMetadataTab() { const params = useParams({ - from: accountLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idAccount?: string } return ( children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneAccountRouteDefinition, @@ -52,23 +54,33 @@ export function DeleteOneAccount(props: { } return ( - - Cette action supprimera le compte et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - text: "Supprimer le compte", - color: "danger", - leftIcon: , - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx index 13895992..0125b888 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx @@ -201,7 +201,7 @@ export function UpdateOneAccount(props: { , + `${props.account.number} - ${props.account.label}`, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx index e6703772..42dfc53f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.tsx @@ -7,14 +7,14 @@ import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.ts import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../components/LinkButton.tsx" -import { balanceSheetLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx" + import { DeleteOneBalanceSheet } from "./DeleteOneBalanceSheet.tsx" import { UpdateOneBalanceSheet } from "./UpdateOneBalanceSheet.tsx" export function BalanceSheetLayout() { const params = useParams({ - from: balanceSheetLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idBalanceSheet?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx index 9c375ee8..9fe3ed5e 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" -import { balanceSheetLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx" + export function BalanceSheetMetadataTab() { const params = useParams({ - from: balanceSheetLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idBalanceSheet?: string } return ( children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneBalanceSheetRouteDefinition, @@ -54,22 +56,33 @@ export function DeleteOneBalanceSheet(props: { } return ( - - Cette action supprimera la ligne de bilan et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer la ligne de bilan", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx index f9a25a71..5b78416e 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx @@ -3,10 +3,9 @@ import { readAllIncomeStatementsRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -15,6 +14,9 @@ export function DeleteOneIncomeStatement(props: { incomeStatement: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneIncomeStatementRouteDefinition, @@ -54,22 +56,33 @@ export function DeleteOneIncomeStatement(props: { } return ( - - Cette action supprimera la ligne de compte de résultat et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer la ligne de compte de résultat", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx index ccda40f0..b9c28fbb 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx @@ -7,14 +7,14 @@ import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.ts import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../components/LinkButton.tsx" -import { incomeStatementLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx" + import { DeleteOneIncomeStatement } from "./DeleteOneIncomeStatement.tsx" import { UpdateOneIncomeStatement } from "./UpdateOneIncomeStatement.tsx" export function IncomeStatementLayout() { const params = useParams({ - from: incomeStatementLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idIncomeStatement?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx index d184436c..092ae075 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" -import { incomeStatementLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx" + export function IncomeStatementMetadataTab() { const params = useParams({ - from: incomeStatementLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idIncomeStatement?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx index 1133680f..3da1d3ab 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../components/layouts/section/section.tsx" -import { computationLayoutRoute } from "../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx" + export function ComputationMetadataTab() { const params = useParams({ - from: computationLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idComputation?: string } return ( children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneComputationRouteDefinition, @@ -54,22 +56,33 @@ export function DeleteOneComputation(props: { } return ( - - Cette action supprimera la ligne de calcul et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer la ligne de calcul", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx index 0971a5c7..0237408d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx @@ -7,14 +7,14 @@ import { DataWrapper } from "../../../../../../../../../components/layouts/DataW import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../../../../components/LinkButton.tsx" -import { computationIncomeStatementLayoutRoute } from "../../../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx" + import { DeleteOneComputationIncomeStatement } from "./DeleteOneComputationIncomeStatement.tsx" import { UpdateOneComputationIncomeStatement } from "./UpdateOneComputationIncomeStatement.tsx" export function ComputationIncomeStatementLayout() { const params = useParams({ - from: computationIncomeStatementLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idComputationIncomeStatement?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx index 0a1e4b3a..26349120 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" -import { computationIncomeStatementLayoutRoute } from "../../../../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx" + export function ComputationIncomeStatementMetadataTab() { const params = useParams({ - from: computationIncomeStatementLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idComputationIncomeStatement?: string } return ( children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneComputationIncomeStatementRouteDefinition, @@ -54,22 +56,33 @@ export function DeleteOneComputationIncomeStatement(props: { } return ( - - Cette action supprimera la ligne de compte de résultat et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer la ligne de compte de résultat", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx index 34409adc..6dbb4dc9 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx @@ -5,14 +5,14 @@ import { useParams } from "@tanstack/react-router" import { Box } from "../../../../../../components/layouts/Box.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { incomeStatementsLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx" + import { ComputationsTable } from "./ComputationsTable.tsx" import { CreateOneComputation } from "./CreateOneComputation.tsx" export function ComputationsPage() { const params = useParams({ - from: incomeStatementsLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx index 6b2bf3e3..1d03f62b 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx @@ -1,9 +1,8 @@ import { deleteOneJournalRouteDefinition, readAllJournalsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -12,6 +11,9 @@ export function DeleteOneJournal(props: { journal: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneJournalRouteDefinition, @@ -51,22 +53,33 @@ export function DeleteOneJournal(props: { } return ( - - Cette action supprimera le journal et toutes les données associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer le journal", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx index 94063fe3..f1045a19 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx @@ -7,14 +7,14 @@ import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.ts import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../components/LinkButton.tsx" -import { journalLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx" + import { DeleteOneJournal } from "./DeleteOneJournal.tsx" import { UpdateOneJournal } from "./UpdateOneJournal.tsx" export function JournalLayout() { const params = useParams({ - from: journalLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idJournal?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx index b02f0635..8a866a72 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" -import { journalLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx" + export function JournalMetadataTab() { const params = useParams({ - from: journalLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idJournal?: string } return ( , + props.journal.label, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx index c73c4755..97171de5 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx @@ -1,9 +1,8 @@ import { deleteOneTagRouteDefinition, readAllTagsRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { toast } from "@arrhes/ui" -import type { ComponentPropsWithRef, ReactElement } from "react" +import { Button, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { type ComponentPropsWithRef, type ReactElement, useId } from "react" import type * as v from "valibot" -import { ConfirmationModal } from "../../../../../../components/overlays/dialog/ConfirmationModal.tsx" import { applicationRouter } from "../../../../../../routes/applicationRouter.tsx" import { getResponseBodyFromAPI } from "../../../../../../utilities/getResponseBodyFromAPI.ts" import { invalidateData } from "../../../../../../utilities/invalidateData.ts" @@ -12,6 +11,9 @@ export function DeleteOneTag(props: { tag: v.InferOutput children: ReactElement> }) { + const modalId = useId() + const { open: openModal, close: closeModal } = useModalStore() + async function onSubmit() { const deleteResponse = await getResponseBodyFromAPI({ routeDefinition: deleteOneTagRouteDefinition, @@ -51,22 +53,33 @@ export function DeleteOneTag(props: { } return ( - - Cette action supprimera la catégorie et toutes ses mentions associées. -
- Cette action est irréversible. - + + + + , + ) } - submitButtonProps={{ - color: "danger", - text: "Supprimer la catégorie", - }} - onSubmit={onSubmit} > {props.children} -
+ ) } diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx index 237d6c47..1b1c0bc1 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx @@ -7,14 +7,14 @@ import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.ts import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" import { LinkButton } from "../../../../../../components/LinkButton.tsx" -import { tagLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx" + import { DeleteOneTag } from "./DeleteOneTag.tsx" import { UpdateOneTag } from "./UpdateOneTag.tsx" export function TagLayout() { const params = useParams({ - from: tagLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idTag?: string } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx index 71af086d..d4cf61e2 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx @@ -5,12 +5,12 @@ import { useParams } from "@tanstack/react-router" import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" -import { tagLayoutRoute } from "../../../../../../routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx" + export function TagMetadataTab() { const params = useParams({ - from: tagLayoutRoute.id, - }) + strict: false, + }) as { idYear?: string; idTag?: string } return ( , + props.tag.label ?? undefined, ) }} > diff --git a/packages/website/src/features/dashboard/admin/AdminPanelLayout.tsx b/packages/website/src/features/dashboard/admin/AdminPanelLayout.tsx index 0bbb3884..846e2890 100644 --- a/packages/website/src/features/dashboard/admin/AdminPanelLayout.tsx +++ b/packages/website/src/features/dashboard/admin/AdminPanelLayout.tsx @@ -1,39 +1,5 @@ -import { PageNavigation } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconTicket } from "@tabler/icons-react" import { Outlet } from "@tanstack/react-router" export function AdminPanelLayout() { - return ( -
- , - to: "/dashboard/admin/tickets", - }, - ]} - /> -
- -
-
- ) + return } diff --git a/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx index 1bc29268..b765281f 100644 --- a/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx +++ b/packages/website/src/features/dashboard/admin/tickets/$idTicket/TicketLayout.tsx @@ -4,14 +4,14 @@ import { css } from "@arrhes/ui/utilities/cn.js" import { IconArrowLeft } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" import { LinkButton } from "../../../../../components/LinkButton.js" -import { $idTicketLayoutRoute } from "../../../../../routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx" + import { useDataFromAPI } from "../../../../../utilities/useHTTPData.js" import { StatusToggle } from "./StatusToggle.js" export function TicketLayout() { const params = useParams({ - from: $idTicketLayoutRoute.id, - }) + strict: false, + }) as { idTicket?: string } const ticket = useDataFromAPI({ routeDefinition: adminReadOneTicketRouteDefinition, diff --git a/packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx b/packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx index 88e5a6b7..69a64ed2 100644 --- a/packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx +++ b/packages/website/src/features/dashboard/support/$idTicket/TicketLayout.tsx @@ -7,13 +7,13 @@ import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { Section } from "../../../../components/layouts/section/section.tsx" import { LinkButton } from "../../../../components/LinkButton.tsx" -import { ticketLayoutRoute } from "../../../../routes/root/dashboard/support/ticketLayoutRoute.tsx" + import { StatusToggle } from "./StatusToggle.tsx" export function TicketLayout() { const params = useParams({ - from: ticketLayoutRoute.id, - }) + strict: false, + }) as { idTicket?: string } return ( diff --git a/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx deleted file mode 100644 index b6dbd41c..00000000 --- a/packages/website/src/routes/root/dashboard/admin/adminLayoutRoute.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { createRoute, lazyRouteComponent, redirect } from "@tanstack/react-router" -import { dashboardLayoutRoute } from "../dashboardLayoutRoute.js" - -export const adminLayoutRoute = createRoute({ - getParentRoute: () => dashboardLayoutRoute, - path: "/admin", - beforeLoad: async ({ context }) => { - const userSession = await context.userSession - - if (userSession?.user.isSuperAdmin !== true) { - throw redirect({ - to: "/dashboard", - }) - } - - return { - title: "Admin", - } - }, - component: lazyRouteComponent( - () => import("../../../../features/dashboard/admin/AdminPanelLayout.js"), - "AdminPanelLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/admin/adminRoute.tsx b/packages/website/src/routes/root/dashboard/admin/adminRoute.tsx deleted file mode 100644 index 09200477..00000000 --- a/packages/website/src/routes/root/dashboard/admin/adminRoute.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { createRoute, redirect } from "@tanstack/react-router" -import { adminLayoutRoute } from "./adminLayoutRoute.js" - -export const adminRoute = createRoute({ - getParentRoute: () => adminLayoutRoute, - path: "/", - beforeLoad: () => { - throw redirect({ - to: "/dashboard/admin/tickets", - }) - }, -}) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx deleted file mode 100644 index 3a882f48..00000000 --- a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketLayoutRoute.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { CircularLoader } from "@arrhes/ui" -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { adminTicketsLayoutRoute } from "../ticketsLayoutRoute.js" - -export const $idTicketLayoutRoute = createRoute({ - getParentRoute: () => adminTicketsLayoutRoute, - path: "/$idTicket", - pendingComponent: () => , - beforeLoad: () => ({ - title: "Ticket", - }), - component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/admin/tickets/$idTicket/TicketLayout.js"), - "TicketLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx deleted file mode 100644 index 341b3be3..00000000 --- a/packages/website/src/routes/root/dashboard/admin/tickets/$idTicket/$idTicketRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { $idTicketLayoutRoute } from "./$idTicketLayoutRoute.js" - -export const $idTicketRoute = createRoute({ - getParentRoute: () => $idTicketLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/admin/tickets/$idTicket/TicketPage.js"), - "TicketPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/ticketsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/ticketsLayoutRoute.tsx deleted file mode 100644 index 5680c075..00000000 --- a/packages/website/src/routes/root/dashboard/admin/tickets/ticketsLayoutRoute.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { adminLayoutRoute } from "../adminLayoutRoute.js" - -export const adminTicketsLayoutRoute = createRoute({ - getParentRoute: () => adminLayoutRoute, - path: "/tickets", - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx b/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx deleted file mode 100644 index 2b464e5d..00000000 --- a/packages/website/src/routes/root/dashboard/admin/tickets/ticketsRoute.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { CircularLoader } from "@arrhes/ui" -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { adminTicketsLayoutRoute } from "./ticketsLayoutRoute.js" - -export const adminTicketsRoute = createRoute({ - getParentRoute: () => adminTicketsLayoutRoute, - path: "/", - pendingComponent: () => , - beforeLoad: () => ({ - title: "Tickets", - }), - component: lazyRouteComponent( - () => import("../../../../../features/dashboard/admin/tickets/TicketsPage.js"), - "TicketsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx deleted file mode 100644 index ad9f2d70..00000000 --- a/packages/website/src/routes/root/dashboard/agent/agentLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizations/$idOrganization/organizationLayoutRoute.js" - -export const agentLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/agent", - beforeLoad: () => ({ - title: "Assistant", - }), - component: lazyRouteComponent( - () => import("../../../../features/dashboard/$idOrganization/agent/AgentLayout.js"), - "AgentLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx deleted file mode 100644 index c7fdc63e..00000000 --- a/packages/website/src/routes/root/dashboard/agent/agentRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { agentLayoutRoute } from "./agentLayoutRoute.js" - -export const agentRoute = createRoute({ - getParentRoute: () => agentLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../features/dashboard/$idOrganization/agent/AgentPage.js"), - "AgentPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx deleted file mode 100644 index eb2a103b..00000000 --- a/packages/website/src/routes/root/dashboard/agent/agentSessionRoute.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { createRoute, useParams } from "@tanstack/react-router" -import { lazy, Suspense } from "react" -import { agentSessionsLayoutRoute } from "./agentSessionsLayoutRoute.js" - -const AgentSessionPage = lazy(() => - import("../../../../features/dashboard/$idOrganization/agent/AgentSessionPage.js").then((m) => ({ - default: m.AgentSessionPage, - })), -) - -// Wrapper that keys AgentSessionPage on idAgentSession so the component -// fully remounts when the user switches sessions — resetting all state/refs. -function AgentSessionPageKeyed() { - const { idAgentSession } = useParams({ - from: agentSessionRoute.id, - }) - return ( - - - - ) -} - -export const agentSessionRoute = createRoute({ - getParentRoute: () => agentSessionsLayoutRoute, - path: "/$idAgentSession", - beforeLoad: () => ({ - title: undefined, - }), - component: AgentSessionPageKeyed, -}) diff --git a/packages/website/src/routes/root/dashboard/agent/agentSessionsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/agent/agentSessionsLayoutRoute.tsx deleted file mode 100644 index 2a9fab9a..00000000 --- a/packages/website/src/routes/root/dashboard/agent/agentSessionsLayoutRoute.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { createRoute } from "@tanstack/react-router" -import { agentLayoutRoute } from "./agentLayoutRoute.js" - -export const agentSessionsLayoutRoute = createRoute({ - getParentRoute: () => agentLayoutRoute, - path: "/sessions", -}) diff --git a/packages/website/src/routes/root/dashboard/dashboardTree.ts b/packages/website/src/routes/root/dashboard/dashboardTree.ts deleted file mode 100644 index 0f1bcb7e..00000000 --- a/packages/website/src/routes/root/dashboard/dashboardTree.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { AnyRoute } from "@tanstack/react-router" -import { dashboardLayoutRoute } from "./dashboardLayoutRoute.tsx" -import { dashboardTabRoute } from "./dashboardTabRoute.tsx" - -// The dashboard tab shell handles all internal routing via per-tab memory routers. -// dashboardTabRoute (/$tabId) ensures /dashboard/:id URLs don't fall through to the catch route. -export const dashboardTree: AnyRoute = dashboardLayoutRoute.addChildren([ - dashboardTabRoute, -]) diff --git a/packages/website/src/routes/root/dashboard/fullDashboardTree.ts b/packages/website/src/routes/root/dashboard/fullDashboardTree.ts index b5969e60..090bf767 100644 --- a/packages/website/src/routes/root/dashboard/fullDashboardTree.ts +++ b/packages/website/src/routes/root/dashboard/fullDashboardTree.ts @@ -1,4 +1,5 @@ import type { AnyRoute } from "@tanstack/react-router" +import { dashboardCatchRoute } from "./dashboardCatchRoute.js" import { dashboardLayoutRoute } from "./dashboardLayoutRoute.js" import { dashboardRootRoute } from "./dashboardRootRoute.js" import { dashboardTabHistoryRoute } from "./dashboardTabHistoryRoute.js" @@ -10,4 +11,5 @@ export const fullDashboardTree: AnyRoute = dashboardLayoutRoute.addChildren([ dashboardRootRoute, dashboardTabRoute, dashboardTabHistoryRoute, + dashboardCatchRoute, ]) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx deleted file mode 100644 index 17de5917..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiKeysRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationApiLayoutRoute } from "./organizationApiLayoutRoute.js" - -export const organizationApiKeysRoute = createRoute({ - getParentRoute: () => organizationApiLayoutRoute, - path: "/clés", - beforeLoad: () => ({ - title: "Clés", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationApi/keys/OrganizationApiKeysPage.js" - ), - "OrganizationApiKeysPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx deleted file mode 100644 index 13366fc2..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizationLayoutRoute.tsx" - -export const organizationApiLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/api", - beforeLoad: () => ({ - title: "API", - }), - component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idOrganization/organizationApi/OrganizationApiLayout.js"), - "OrganizationApiLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx deleted file mode 100644 index 0acbf1f0..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationApi/organizationApiRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationApiLayoutRoute } from "./organizationApiLayoutRoute.js" - -export const organizationApiRoute = createRoute({ - getParentRoute: () => organizationApiLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.js" - ), - "OrganizationApiGeneralPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx deleted file mode 100644 index 13724bab..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingHistoryRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationBillingLayoutRoute } from "./organizationBillingLayoutRoute.js" - -export const organizationBillingHistoryRoute = createRoute({ - getParentRoute: () => organizationBillingLayoutRoute, - path: "/historique", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/OrganizationBillingHistoryPage.js" - ), - "OrganizationBillingHistoryPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx deleted file mode 100644 index f2764f53..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizationLayoutRoute.js" - -export const organizationBillingLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/facturation", - beforeLoad: () => ({ - title: "Facturation", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/OrganizationBillingLayout.js" - ), - "OrganizationBillingLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx deleted file mode 100644 index e2959e29..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationBillingLayoutRoute } from "./organizationBillingLayoutRoute.js" - -export const organizationBillingRoute = createRoute({ - getParentRoute: () => organizationBillingLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/wallet/OrganizationWalletPage.js" - ), - "OrganizationWalletPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx deleted file mode 100644 index 2118d6f0..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationBillingsRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationBillingLayoutRoute } from "./organizationBillingLayoutRoute.js" - -export const organizationServicesRoute = createRoute({ - getParentRoute: () => organizationBillingLayoutRoute, - path: "/services", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.js" - ), - "OrganizationServicesPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx deleted file mode 100644 index 6eabc5f1..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoiceUblRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationBillingLayoutRoute } from "./organizationBillingLayoutRoute.js" - -export const organizationInvoiceUblRoute = createRoute({ - getParentRoute: () => organizationBillingLayoutRoute, - path: "/facture/$idInvoice", - beforeLoad: () => ({ - title: "Facture XML", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.js" - ), - "OrganizationInvoicePage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx deleted file mode 100644 index c83a6dce..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationBilling/organizationInvoicesRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationBillingLayoutRoute } from "./organizationBillingLayoutRoute.js" - -export const organizationInvoicesRoute = createRoute({ - getParentRoute: () => organizationBillingLayoutRoute, - path: "/factures", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicesPage.js" - ), - "OrganizationInvoicesPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx deleted file mode 100644 index ffd3db3d..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationPathRoute } from "./organizationPathRoute.js" - -export const organizationLayoutRoute = createRoute({ - getParentRoute: () => organizationPathRoute, - id: "organizationLayout", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../features/dashboard/$idOrganization/OrganizationLayout.js"), - "OrganizationLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.tsx deleted file mode 100644 index 1b4f50d3..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationPathRoute.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { createRoute } from "@tanstack/react-router" -import { dataClient } from "../../../../../contexts/data/queryClient.js" -import { getCookie } from "../../../../../utilities/cookies/getCookie.js" -import { setCookie } from "../../../../../utilities/cookies/setCookie.js" -import { cookiePrefix } from "../../../../../utilities/variables.js" -import { organizationsLayoutRoute } from "../organizationsLayoutRoute.tsx" - -export const organizationPathRoute = createRoute({ - getParentRoute: () => organizationsLayoutRoute, - path: "/$idOrganization", - beforeLoad: ({ params }) => { - const previousOrganizationId = getCookie(`${cookiePrefix}_id_organization`) - setCookie(`${cookiePrefix}_id_organization`, params.idOrganization) - - if (previousOrganizationId !== params.idOrganization) { - dataClient.removeQueries() - } - - return { - title: "Organisation", - } - }, -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationRoute.tsx deleted file mode 100644 index 00fa7660..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationRoute.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { createRoute, redirect } from "@tanstack/react-router" -import { organizationLayoutRoute } from "./organizationLayoutRoute.tsx" - -export const organizationRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/", - beforeLoad: ({ params }) => { - throw redirect({ - to: "/dashboard/organisations/$idOrganization/exercices", - params: params, - }) - }, -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx deleted file mode 100644 index 8267dde7..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSecurityRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationSettingsLayoutRoute } from "./organizationSettingsLayoutRoute.js" - -export const organizationSecurityRoute = createRoute({ - getParentRoute: () => organizationSettingsLayoutRoute, - path: "/sécurité", - beforeLoad: () => ({ - title: "Sécurité", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationSettings/OrganizationSecurityPage.js" - ), - "OrganizationSecurityPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx deleted file mode 100644 index ce917e6a..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizationLayoutRoute.js" - -export const organizationSettingsLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/paramètres", - beforeLoad: () => ({ - title: "Paramètres", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsLayout.js" - ), - "OrganizationSettingsLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx deleted file mode 100644 index 91c7dda1..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationSettings/organizationSettingsRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationSettingsLayoutRoute } from "./organizationSettingsLayoutRoute.js" - -export const organizationSettingsRoute = createRoute({ - getParentRoute: () => organizationSettingsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsPage.js" - ), - "OrganizationSettingsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersLayoutRoute.tsx deleted file mode 100644 index e296c808..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizationLayoutRoute.tsx" - -export const organizationUsersLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/membres", - beforeLoad: () => ({ - title: "Membres", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx deleted file mode 100644 index 59d3a817..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/organizationUsers/organizationUsersRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationUsersLayoutRoute } from "./organizationUsersLayoutRoute.js" - -export const organizationUsersRoute = createRoute({ - getParentRoute: () => organizationUsersLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.js"), - "OrganizationUsersPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx deleted file mode 100644 index b3262d2f..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { storageLayoutRoute } from "../storageLayoutRoute.js" - -export const fileLayoutRoute = createRoute({ - getParentRoute: () => storageLayoutRoute, - path: "/$idFile", - beforeLoad: () => ({ - title: "Pièce justificative", - }), - component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FileLayout.js"), - "FileLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx deleted file mode 100644 index 94dd299f..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileMetadataRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { fileLayoutRoute } from "./fileLayoutRoute.js" - -export const fileMetadataRoute = createRoute({ - getParentRoute: () => fileLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FileMetadataTab.js"), - "FileMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx deleted file mode 100644 index e0130e18..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { fileLayoutRoute } from "./fileLayoutRoute.js" - -export const fileRoute = createRoute({ - getParentRoute: () => fileLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FilePage.js"), - "FilePage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx deleted file mode 100644 index a8d7df33..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/$idFile/fileVisualisationRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { fileLayoutRoute } from "./fileLayoutRoute.js" - -export const fileVisualisationRoute = createRoute({ - getParentRoute: () => fileLayoutRoute, - path: "/visualisation", - beforeLoad: () => ({ - title: "Visualisation", - }), - component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/files/$idFile/FileVisualisationTab.js"), - "FileVisualisationTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx deleted file mode 100644 index ab12ac7c..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizationLayoutRoute.js" - -export const storageLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/stockage", - beforeLoad: () => ({ - title: "Stockage", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx deleted file mode 100644 index 0057c6a8..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/storage/storageRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { storageLayoutRoute } from "./storageLayoutRoute.js" - -export const storageRoute = createRoute({ - getParentRoute: () => storageLayoutRoute, - path: "/", - validateSearch: (search: Record) => ({ - idFolder: typeof search.idFolder === "string" ? search.idFolder : undefined, - }), - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idYear/files/FilesPage.js"), - "FilesPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx deleted file mode 100644 index f4892920..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entriesLayoutRoute } from "../../entriesLayoutRoute.js" - -export const entryLineLayoutRoute = createRoute({ - getParentRoute: () => entriesLayoutRoute, - path: "/$idEntry/mouvements/$idEntryLine", - beforeLoad: () => ({ - title: "Ligne d'écriture", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.js" - ), - "EntryLineLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx deleted file mode 100644 index dc534197..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entryLineLayoutRoute } from "./entryLineLayoutRoute.js" - -export const entryLineMetadataRoute = createRoute({ - getParentRoute: () => entryLineLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.js" - ), - "EntryLineMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx deleted file mode 100644 index 2f7580aa..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryLine/entryLineRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entryLineLayoutRoute } from "./entryLineLayoutRoute.js" - -export const entryLineRoute = createRoute({ - getParentRoute: () => entryLineLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLinePage.js" - ), - "EntryLinePage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx deleted file mode 100644 index 80a48a67..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryCategoriesRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entryLayoutRoute } from "./entryLayoutRoute.js" - -export const entryCategoriesRoute = createRoute({ - getParentRoute: () => entryLayoutRoute, - path: "/catégories", - beforeLoad: () => ({ - title: "Catégories", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryCategoriesTab.js"), - "EntryCategoriesTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx deleted file mode 100644 index 311ee4ee..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entriesLayoutRoute } from "../entriesLayoutRoute.js" - -export const entryLayoutRoute = createRoute({ - getParentRoute: () => entriesLayoutRoute, - path: "/$idEntry", - beforeLoad: () => ({ - title: "Écriture", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryLayout.js"), - "EntryLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx deleted file mode 100644 index 367f11cb..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLinesRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entryLayoutRoute } from "./entryLayoutRoute.js" - -export const entryLinesRoute = createRoute({ - getParentRoute: () => entryLayoutRoute, - path: "/mouvements", - beforeLoad: () => ({ - title: "Mouvements", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.js"), - "EntryLinesTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx deleted file mode 100644 index b9deb889..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryMetadataRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entryLayoutRoute } from "./entryLayoutRoute.js" - -export const entryMetadataRoute = createRoute({ - getParentRoute: () => entryLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryMetadataTab.js"), - "EntryMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx deleted file mode 100644 index 4aed966d..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entryLayoutRoute } from "./entryLayoutRoute.js" - -export const entryRoute = createRoute({ - getParentRoute: () => entryLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.js"), - "EntryRoutePage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesLayoutRoute.tsx deleted file mode 100644 index 1e6db60d..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearLayoutRoute } from "../yearLayoutRoute.js" - -export const entriesLayoutRoute = createRoute({ - getParentRoute: () => yearLayoutRoute, - path: "/écritures", - beforeLoad: () => ({ - title: "Écritures", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx deleted file mode 100644 index 0783bef0..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/entries/entriesRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { entriesLayoutRoute } from "./entriesLayoutRoute.js" - -export const entriesRoute = createRoute({ - getParentRoute: () => entriesLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/entries/EntriesPage.js"), - "EntriesPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx deleted file mode 100644 index 9354a48e..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { filesLayoutRoute } from "../filesLayoutRoute.js" - -export const fileLayoutRoute = createRoute({ - getParentRoute: () => filesLayoutRoute, - path: "/$idFile", - beforeLoad: () => ({ - title: "Pièce justificative", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FileLayout.js"), - "FileLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx deleted file mode 100644 index f6639906..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileMetadataRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { fileLayoutRoute } from "./fileLayoutRoute.js" - -export const fileMetadataRoute = createRoute({ - getParentRoute: () => fileLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FileMetadataTab.js"), - "FileMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx deleted file mode 100644 index 16cb84a3..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { fileLayoutRoute } from "./fileLayoutRoute.js" - -export const fileRoute = createRoute({ - getParentRoute: () => fileLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FilePage.js"), - "FilePage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx deleted file mode 100644 index e363ea44..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/$idFile/fileVisualisationRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { fileLayoutRoute } from "./fileLayoutRoute.js" - -export const fileVisualisationRoute = createRoute({ - getParentRoute: () => fileLayoutRoute, - path: "/visualisation", - beforeLoad: () => ({ - title: "Visualisation", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/files/$idFile/FileVisualisationTab.js"), - "FileVisualisationTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesLayoutRoute.tsx deleted file mode 100644 index 805fd84a..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearLayoutRoute } from "../yearLayoutRoute.js" - -export const filesLayoutRoute = createRoute({ - getParentRoute: () => yearLayoutRoute, - path: "/stockage", - beforeLoad: () => ({ - title: "Stockage", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx deleted file mode 100644 index 21272fc1..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/files/filesRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { filesLayoutRoute } from "./filesLayoutRoute.js" - -export const filesRoute = createRoute({ - getParentRoute: () => filesLayoutRoute, - path: "/", - validateSearch: (search: Record) => ({ - idFolder: typeof search.idFolder === "string" ? search.idFolder : undefined, - }), - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/files/FilesPage.js"), - "FilesPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx deleted file mode 100644 index 5bd88884..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceReportRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { reportsLayoutRoute } from "./reportsLayoutRoute.js" - -export const balanceReportRoute = createRoute({ - getParentRoute: () => reportsLayoutRoute, - path: "/balance", - beforeLoad: () => ({ - title: "Balance", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/balanceReport/BalanceReportPage.js"), - "BalanceReportPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx deleted file mode 100644 index b375a58c..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/balanceSheetReportRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { reportsLayoutRoute } from "./reportsLayoutRoute.js" - -export const balanceSheetReportRoute = createRoute({ - getParentRoute: () => reportsLayoutRoute, - path: "/bilan", - beforeLoad: () => ({ - title: "Bilan", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../features/dashboard/$idYear/reports/balanceSheetReport/BalanceSheetReportPage.js" - ), - "BalanceSheetReportPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx deleted file mode 100644 index ff415f60..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/incomeStatementReportRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { reportsLayoutRoute } from "./reportsLayoutRoute.js" - -export const incomeStatementReportRoute = createRoute({ - getParentRoute: () => reportsLayoutRoute, - path: "/compte-de-résultat", - beforeLoad: () => ({ - title: "Compte de résultat", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../features/dashboard/$idYear/reports/incomeStatementReport/IncomeStatementReportPage.js" - ), - "IncomeStatementReportPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx deleted file mode 100644 index 32fed85c..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/journalReportRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { reportsLayoutRoute } from "./reportsLayoutRoute.js" - -export const journalReportRoute = createRoute({ - getParentRoute: () => reportsLayoutRoute, - path: "/livre-journal", - beforeLoad: () => ({ - title: "Livre-journal", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/journalReport/JournalReportPage.js"), - "JournalReportPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx deleted file mode 100644 index 5340f371..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/ledgerReportRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { reportsLayoutRoute } from "./reportsLayoutRoute.js" - -export const ledgerReportRoute = createRoute({ - getParentRoute: () => reportsLayoutRoute, - path: "/grand-livre", - beforeLoad: () => ({ - title: "Grand livre", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/ledgerReport/LedgerReportPage.js"), - "LedgerReportPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx deleted file mode 100644 index 032338da..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { yearLayoutRoute } from "../yearLayoutRoute.js" - -export const reportsLayoutRoute = createRoute({ - getParentRoute: () => yearLayoutRoute, - path: "/documents", - beforeLoad: () => ({ - title: "Documents comptables", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/reports/ReportsLayout.js"), - "ReportsLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsRoute.tsx deleted file mode 100644 index aa6266f3..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/reports/reportsRoute.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { createRoute, redirect } from "@tanstack/react-router" -import { reportsLayoutRoute } from "./reportsLayoutRoute.js" - -export const reportsRoute = createRoute({ - getParentRoute: () => reportsLayoutRoute, - path: "/", - beforeLoad: ({ params }) => { - throw redirect({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/documents/livre-journal", - params: params, - }) - }, -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx deleted file mode 100644 index e0698aec..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearLayoutRoute.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { CircularLoader } from "@arrhes/ui" -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { Page } from "../../../../../../../components/layouts/page/page.js" -import { prefetchYearData } from "../../../../../../../utilities/prefetchYearData.js" -import { yearPathRoute } from "./yearPathRoute.js" - -export const yearLayoutRoute = createRoute({ - getParentRoute: () => yearPathRoute, - id: "yearLayout", - pendingComponent: () => ( - - - - - - ), - beforeLoad: ({ params }) => { - prefetchYearData({ - idYear: params.idYear, - }) - - return { - title: undefined, - } - }, - component: lazyRouteComponent( - () => import("../../../../../../../features/dashboard/$idYear/YearLayout.js"), - "YearLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearPathRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearPathRoute.tsx deleted file mode 100644 index 122ba089..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearPathRoute.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { createRoute } from "@tanstack/react-router" -import { yearsPathRoute } from "../yearsPathRoute.tsx" - -export const yearPathRoute = createRoute({ - getParentRoute: () => yearsPathRoute, - path: "/$idYear", - beforeLoad: () => ({ - title: "Exercice", - }), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearRoute.tsx deleted file mode 100644 index 37166558..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearRoute.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { createRoute, redirect } from "@tanstack/react-router" -import { yearLayoutRoute } from "./yearLayoutRoute.tsx" - -export const yearRoute = createRoute({ - getParentRoute: () => yearLayoutRoute, - path: "/", - beforeLoad: ({ params }) => { - throw redirect({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/écritures", - params: params, - }) - }, -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx deleted file mode 100644 index 6d70fa86..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { accountsLayoutRoute } from "../accountsLayoutRoute.js" - -export const accountLayoutRoute = createRoute({ - getParentRoute: () => accountsLayoutRoute, - path: "/$idAccount", - beforeLoad: () => ({ - title: "Compte", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.js" - ), - "AccountLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx deleted file mode 100644 index b7832679..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { accountLayoutRoute } from "./accountLayoutRoute.js" - -export const accountMetadataRoute = createRoute({ - getParentRoute: () => accountLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.js" - ), - "AccountMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx deleted file mode 100644 index ffe9ffa1..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/accountRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { accountLayoutRoute } from "./accountLayoutRoute.js" - -export const accountRoute = createRoute({ - getParentRoute: () => accountLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountPage.js" - ), - "AccountPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsLayoutRoute.tsx deleted file mode 100644 index 9870ce10..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearSettingsLayoutRoute } from "../yearSettingsLayoutRoute.js" - -export const accountsLayoutRoute = createRoute({ - getParentRoute: () => yearSettingsLayoutRoute, - path: "/comptes", - beforeLoad: () => ({ - title: "Plan des comptes", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx deleted file mode 100644 index d846e1fc..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { accountsLayoutRoute } from "./accountsLayoutRoute.js" - -export const accountsRoute = createRoute({ - getParentRoute: () => accountsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/accounts/AccountsPage.js"), - "AccountsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx deleted file mode 100644 index f02c11b6..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { balanceSheetsLayoutRoute } from "../balanceSheetsLayoutRoute.js" - -export const balanceSheetLayoutRoute = createRoute({ - getParentRoute: () => balanceSheetsLayoutRoute, - path: "/$idBalanceSheet", - beforeLoad: () => ({ - title: "Ligne de bilan", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetLayout.js" - ), - "BalanceSheetLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx deleted file mode 100644 index b16b3f7d..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { balanceSheetLayoutRoute } from "./balanceSheetLayoutRoute.js" - -export const balanceSheetMetadataRoute = createRoute({ - getParentRoute: () => balanceSheetLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.js" - ), - "BalanceSheetMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx deleted file mode 100644 index 7eefd843..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/balanceSheetRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { balanceSheetLayoutRoute } from "./balanceSheetLayoutRoute.js" - -export const balanceSheetRoute = createRoute({ - getParentRoute: () => balanceSheetLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetPage.js" - ), - "BalanceSheetPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifLayoutRoute.tsx deleted file mode 100644 index b3b2655b..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { balanceSheetsLayoutRoute } from "../balanceSheetsLayoutRoute.js" - -export const actifLayoutRoute = createRoute({ - getParentRoute: () => balanceSheetsLayoutRoute, - path: "/actif", - beforeLoad: () => ({ - title: "Actif", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx deleted file mode 100644 index a0b7710f..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/actif/actifRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { actifLayoutRoute } from "./actifLayoutRoute.js" - -export const actifRoute = createRoute({ - getParentRoute: () => actifLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.js" - ), - "BalanceSheetsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsLayoutRoute.tsx deleted file mode 100644 index c3e1c162..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearSettingsLayoutRoute } from "../yearSettingsLayoutRoute.js" - -export const balanceSheetsLayoutRoute = createRoute({ - getParentRoute: () => yearSettingsLayoutRoute, - path: "/bilan", - beforeLoad: () => ({ - title: "Bilan", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoute.tsx deleted file mode 100644 index 58ffd1f5..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoute.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { createRoute, redirect } from "@tanstack/react-router" -import { balanceSheetsLayoutRoute } from "./balanceSheetsLayoutRoute.js" - -export const balanceSheetsRoute = createRoute({ - getParentRoute: () => balanceSheetsLayoutRoute, - path: "/", - beforeLoad: ({ params }) => { - throw redirect({ - to: "/dashboard/organisations/$idOrganization/exercices/$idYear/paramètres/bilan/actif", - params: params, - }) - }, -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifLayoutRoute.tsx deleted file mode 100644 index b63fb1c7..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { balanceSheetsLayoutRoute } from "../balanceSheetsLayoutRoute.js" - -export const passifLayoutRoute = createRoute({ - getParentRoute: () => balanceSheetsLayoutRoute, - path: "/passif", - beforeLoad: () => ({ - title: "Passif", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx deleted file mode 100644 index 70667bc2..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/passif/passifRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { passifLayoutRoute } from "./passifLayoutRoute.js" - -export const passifRoute = createRoute({ - getParentRoute: () => passifLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/balanceSheets/BalanceSheetsPage.js" - ), - "BalanceSheetsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx deleted file mode 100644 index c6868a07..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { incomeStatementsLayoutRoute } from "../incomeStatementsLayoutRoute.js" - -export const incomeStatementLayoutRoute = createRoute({ - getParentRoute: () => incomeStatementsLayoutRoute, - path: "/$idIncomeStatement", - beforeLoad: () => ({ - title: "Ligne de compte de résultat", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.js" - ), - "IncomeStatementLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx deleted file mode 100644 index 6f8bccbb..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { incomeStatementLayoutRoute } from "./incomeStatementLayoutRoute.js" - -export const incomeStatementMetadataRoute = createRoute({ - getParentRoute: () => incomeStatementLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.js" - ), - "IncomeStatementMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx deleted file mode 100644 index 1da41feb..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/incomeStatementRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { incomeStatementLayoutRoute } from "./incomeStatementLayoutRoute.js" - -export const incomeStatementRoute = createRoute({ - getParentRoute: () => incomeStatementLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementPage.js" - ), - "IncomeStatementPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx deleted file mode 100644 index d7e0f4d7..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationsLayoutRoute } from "../../computationsLayoutRoute.js" - -export const computationIncomeStatementLayoutRoute = createRoute({ - getParentRoute: () => computationsLayoutRoute, - path: "/$idComputation/postes/$idComputationIncomeStatement", - beforeLoad: () => ({ - title: "Terme du calcul", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.js" - ), - "ComputationIncomeStatementLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx deleted file mode 100644 index 1e1ddc19..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationIncomeStatementLayoutRoute } from "./computationIncomeStatementLayoutRoute.js" - -export const computationIncomeStatementMetadataRoute = createRoute({ - getParentRoute: () => computationIncomeStatementLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.js" - ), - "ComputationIncomeStatementMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx deleted file mode 100644 index 08eed31b..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/$idComputationIncomeStatement/computationIncomeStatementRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationIncomeStatementLayoutRoute } from "./computationIncomeStatementLayoutRoute.js" - -export const computationIncomeStatementRoute = createRoute({ - getParentRoute: () => computationIncomeStatementLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementPage.js" - ), - "ComputationIncomeStatementPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx deleted file mode 100644 index 8933ae74..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationsLayoutRoute } from "../computationsLayoutRoute.js" - -export const computationLayoutRoute = createRoute({ - getParentRoute: () => computationsLayoutRoute, - path: "/$idComputation", - beforeLoad: () => ({ - title: "Calcul", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationLayout.js" - ), - "ComputationLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx deleted file mode 100644 index a4c2419d..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationLayoutRoute } from "./computationLayoutRoute.js" - -export const computationMetadataRoute = createRoute({ - getParentRoute: () => computationLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.js" - ), - "ComputationMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx deleted file mode 100644 index 7d3b8ada..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationPostesRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationLayoutRoute } from "./computationLayoutRoute.js" - -export const computationPostesRoute = createRoute({ - getParentRoute: () => computationLayoutRoute, - path: "/postes", - beforeLoad: () => ({ - title: "Postes", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPostesTab.js" - ), - "ComputationPostesTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx deleted file mode 100644 index 67910511..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationLayoutRoute } from "./computationLayoutRoute.js" - -export const computationRoute = createRoute({ - getParentRoute: () => computationLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationPage.js" - ), - "ComputationPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsLayoutRoute.tsx deleted file mode 100644 index 26178db8..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { incomeStatementsLayoutRoute } from "../incomeStatementsLayoutRoute.js" - -export const computationsLayoutRoute = createRoute({ - getParentRoute: () => incomeStatementsLayoutRoute, - path: "/calculs", - beforeLoad: () => ({ - title: "Calculs", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx deleted file mode 100644 index 167b26c3..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/computations/computationsRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { computationsLayoutRoute } from "./computationsLayoutRoute.js" - -export const computationsRoute = createRoute({ - getParentRoute: () => computationsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.js" - ), - "ComputationsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx deleted file mode 100644 index 99234119..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearSettingsLayoutRoute } from "../yearSettingsLayoutRoute.js" - -export const incomeStatementsLayoutRoute = createRoute({ - getParentRoute: () => yearSettingsLayoutRoute, - path: "/compte-de-résultat", - beforeLoad: () => ({ - title: "Compte de résultat", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx deleted file mode 100644 index 97902f99..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { incomeStatementsLayoutRoute } from "./incomeStatementsLayoutRoute.js" - -export const incomeStatementsRoute = createRoute({ - getParentRoute: () => incomeStatementsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../features/dashboard/$idYear/yearSettings/incomeStatements/IncomeStatementsPage.js" - ), - "IncomeStatementsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx deleted file mode 100644 index b4187608..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalLayoutRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { journalsLayoutRoute } from "../journalsLayoutRoute.js" - -export const journalLayoutRoute = createRoute({ - getParentRoute: () => journalsLayoutRoute, - path: "/$idJournal", - beforeLoad: () => ({ - title: "Journal", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.js" - ), - "JournalLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx deleted file mode 100644 index 760168d5..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { journalLayoutRoute } from "./journalLayoutRoute.js" - -export const journalMetadataRoute = createRoute({ - getParentRoute: () => journalLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.js" - ), - "JournalMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx deleted file mode 100644 index b1444341..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/journalRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { journalLayoutRoute } from "./journalLayoutRoute.js" - -export const journalRoute = createRoute({ - getParentRoute: () => journalLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalPage.js" - ), - "JournalPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsLayoutRoute.tsx deleted file mode 100644 index 843511f1..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearSettingsLayoutRoute } from "../yearSettingsLayoutRoute.js" - -export const journalsLayoutRoute = createRoute({ - getParentRoute: () => yearSettingsLayoutRoute, - path: "/journaux", - beforeLoad: () => ({ - title: "Journaux", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx deleted file mode 100644 index ea59ddce..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { journalsLayoutRoute } from "./journalsLayoutRoute.js" - -export const journalsRoute = createRoute({ - getParentRoute: () => journalsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/journals/JournalsPage.js"), - "JournalsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx deleted file mode 100644 index 5502bb75..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { tagsLayoutRoute } from "../tagsLayoutRoute.js" - -export const tagLayoutRoute = createRoute({ - getParentRoute: () => tagsLayoutRoute, - path: "/$idTag", - beforeLoad: () => ({ - title: "Catégorie", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.js"), - "TagLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx deleted file mode 100644 index 8e694bcc..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagMetadataRoute.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { tagLayoutRoute } from "./tagLayoutRoute.js" - -export const tagMetadataRoute = createRoute({ - getParentRoute: () => tagLayoutRoute, - path: "/métadonnées", - beforeLoad: () => ({ - title: "Métadonnées", - }), - component: lazyRouteComponent( - () => - import( - "../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.js" - ), - "TagMetadataTab", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx deleted file mode 100644 index d1d79bf9..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/tagRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { tagLayoutRoute } from "./tagLayoutRoute.js" - -export const tagRoute = createRoute({ - getParentRoute: () => tagLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/$idTag/TagPage.js"), - "TagPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsLayoutRoute.tsx deleted file mode 100644 index ada2b19e..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { yearSettingsLayoutRoute } from "../yearSettingsLayoutRoute.js" - -export const tagsLayoutRoute = createRoute({ - getParentRoute: () => yearSettingsLayoutRoute, - path: "/catégories", - beforeLoad: () => ({ - title: "Catégories", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx deleted file mode 100644 index 77eac6e2..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { tagsLayoutRoute } from "./tagsLayoutRoute.js" - -export const tagsRoute = createRoute({ - getParentRoute: () => tagsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../../features/dashboard/$idYear/yearSettings/tags/TagsPage.js"), - "TagsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx deleted file mode 100644 index 3f4d1c70..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { yearLayoutRoute } from "../yearLayoutRoute.js" - -export const yearSettingsLayoutRoute = createRoute({ - getParentRoute: () => yearLayoutRoute, - path: "/paramètres", - beforeLoad: () => ({ - title: "Paramètres", - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/yearSettings/YearSettingsLayout.js"), - "YearSettingsLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx deleted file mode 100644 index 47ca8d97..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { yearSettingsLayoutRoute } from "./yearSettingsLayoutRoute.js" - -export const yearSettingsRoute = createRoute({ - getParentRoute: () => yearSettingsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../../../../../features/dashboard/$idYear/yearSettings/YearSettingsPage.js"), - "YearSettingsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsLayoutRoute.tsx deleted file mode 100644 index 169cb397..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { organizationLayoutRoute } from "../organizationLayoutRoute.js" - -export const yearsLayoutRoute = createRoute({ - getParentRoute: () => organizationLayoutRoute, - path: "/exercices", - beforeLoad: () => ({ - title: "Exercices", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsPathRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsPathRoute.tsx deleted file mode 100644 index 79d4a136..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsPathRoute.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { createRoute } from "@tanstack/react-router" -import { organizationPathRoute } from "../organizationPathRoute.js" - -export const yearsPathRoute = createRoute({ - getParentRoute: () => organizationPathRoute, - path: "/exercices", - beforeLoad: () => ({ - title: "Exercices", - }), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx deleted file mode 100644 index 785d6851..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/$idOrganization/years/yearsRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { yearsLayoutRoute } from "./yearsLayoutRoute.js" - -export const yearsRoute = createRoute({ - getParentRoute: () => yearsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: "Exercices fiscaux", - }), - component: lazyRouteComponent( - () => import("../../../../../../features/dashboard/$idOrganization/years/YearsPage.js"), - "YearsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/organizationsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/organizationsLayoutRoute.tsx deleted file mode 100644 index 76900106..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/organizationsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { dashboardLayoutRoute } from "../dashboardLayoutRoute.js" - -export const organizationsLayoutRoute = createRoute({ - getParentRoute: () => dashboardLayoutRoute, - path: "/organisations", - beforeLoad: () => ({ - title: undefined, - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx b/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx deleted file mode 100644 index 3e000230..00000000 --- a/packages/website/src/routes/root/dashboard/organizations/organizationsRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { organizationsLayoutRoute } from "./organizationsLayoutRoute.js" - -export const organizationsRoute = createRoute({ - getParentRoute: () => organizationsLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: "Organisations", - }), - component: lazyRouteComponent( - () => import("../../../../features/dashboard/organizations/OrganizationsPage.js"), - "OrganizationsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/profile/userProfileLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/profile/userProfileLayoutRoute.tsx deleted file mode 100644 index 4c80301c..00000000 --- a/packages/website/src/routes/root/dashboard/profile/userProfileLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { dashboardLayoutRoute } from "../dashboardLayoutRoute.js" - -export const userProfileLayoutRoute = createRoute({ - getParentRoute: () => dashboardLayoutRoute, - path: "/profil", - beforeLoad: () => ({ - title: "Profil", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx b/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx deleted file mode 100644 index 5c63304f..00000000 --- a/packages/website/src/routes/root/dashboard/profile/userProfileRoute.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { userProfileLayoutRoute } from "./userProfileLayoutRoute.js" - -export const userProfileRoute = createRoute({ - getParentRoute: () => userProfileLayoutRoute, - path: "/", - beforeLoad: () => {}, - component: lazyRouteComponent( - () => import("../../../../features/dashboard/profile/UserProfilePage.js"), - "UserProfilePage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/settings/settingsLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/settings/settingsLayoutRoute.tsx deleted file mode 100644 index c950326c..00000000 --- a/packages/website/src/routes/root/dashboard/settings/settingsLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { dashboardLayoutRoute } from "../dashboardLayoutRoute.js" - -export const settingsLayoutRoute = createRoute({ - getParentRoute: () => dashboardLayoutRoute, - path: "/paramètres", - beforeLoad: () => ({ - title: "Paramètres", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx b/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx deleted file mode 100644 index e7429ff9..00000000 --- a/packages/website/src/routes/root/dashboard/settings/settingsRoute.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { settingsLayoutRoute } from "./settingsLayoutRoute.js" - -export const settingsRoute = createRoute({ - getParentRoute: () => settingsLayoutRoute, - path: "/", - beforeLoad: () => {}, - component: lazyRouteComponent( - () => import("../../../../features/dashboard/settings/SettingsPage.js"), - "SettingsPage", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/support/supportLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/support/supportLayoutRoute.tsx deleted file mode 100644 index 69d03f3b..00000000 --- a/packages/website/src/routes/root/dashboard/support/supportLayoutRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, Outlet } from "@tanstack/react-router" -import { dashboardLayoutRoute } from "../dashboardLayoutRoute.js" - -export const supportLayoutRoute = createRoute({ - getParentRoute: () => dashboardLayoutRoute, - path: "/support", - beforeLoad: () => ({ - title: "Support", - }), - component: () => , -}) diff --git a/packages/website/src/routes/root/dashboard/support/supportRoute.tsx b/packages/website/src/routes/root/dashboard/support/supportRoute.tsx deleted file mode 100644 index da96efb9..00000000 --- a/packages/website/src/routes/root/dashboard/support/supportRoute.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { supportLayoutRoute } from "./supportLayoutRoute.js" - -export const supportRoute = createRoute({ - getParentRoute: () => supportLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent(() => import("../../../../features/dashboard/support/SupportPage.js"), "SupportPage"), -}) diff --git a/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx b/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx deleted file mode 100644 index dffd23fd..00000000 --- a/packages/website/src/routes/root/dashboard/support/ticketLayoutRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { supportLayoutRoute } from "./supportLayoutRoute.js" - -export const ticketLayoutRoute = createRoute({ - getParentRoute: () => supportLayoutRoute, - path: "/tickets/$idTicket", - beforeLoad: () => ({ - title: "Ticket", - }), - component: lazyRouteComponent( - () => import("../../../../features/dashboard/support/$idTicket/TicketLayout.js"), - "TicketLayout", - ), -}) diff --git a/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx b/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx deleted file mode 100644 index 0387c5ee..00000000 --- a/packages/website/src/routes/root/dashboard/support/ticketRoute.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createRoute, lazyRouteComponent } from "@tanstack/react-router" -import { ticketLayoutRoute } from "./ticketLayoutRoute.js" - -export const ticketRoute = createRoute({ - getParentRoute: () => ticketLayoutRoute, - path: "/", - beforeLoad: () => ({ - title: undefined, - }), - component: lazyRouteComponent( - () => import("../../../../features/dashboard/support/$idTicket/TicketPage.js"), - "TicketPage", - ), -}) From 03e57241bdba6fc690134cffea14a346cfee8516 Mon Sep 17 00:00:00 2001 From: &mile Date: Mon, 18 May 2026 12:52:09 +0200 Subject: [PATCH 09/14] fix(lint): apply Biome import sort and type-import fixes across packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix import ordering (organizeImports) in packages/ui, packages/api, packages/website - Fix useImportType in popover/dialog components - Fix useParams cast types (string | undefined → string) in dashboard feature pages - Fix broken EntryRoutePage import (EntryPage → EntryInformationsTab) - Fix string | null incompatibility in UpdateOneJournal --- packages/tools/src/schemas.ts | 10 +- packages/ui/src/components/buttons/Button.tsx | 9 +- .../components/buttons/ButtonGhostContent.tsx | 2 +- .../buttons/ButtonOutlineContent.tsx | 2 +- .../components/buttons/ButtonPlainContent.tsx | 2 +- .../formats/display/FormatFileSize.tsx | 5 +- .../src/components/inputs/InputCombobox.tsx | 20 +- .../inputs/InputComboboxMultiple.tsx | 4 +- .../components/overlays/dialog/DialogBody.tsx | 2 +- .../overlays/dialog/DialogContent.tsx | 2 +- .../overlays/dialog/DialogDescription.tsx | 2 +- .../overlays/dialog/DialogFooter.tsx | 2 +- .../overlays/dialog/DialogHeader.tsx | 6 +- .../overlays/dialog/DialogTitle.tsx | 2 +- .../overlays/popover/PopoverContent.tsx | 2 +- .../components/overlays/popover/popover.tsx | 2 +- .../overlays/popover/popoverClose.tsx | 12 +- .../overlays/popover/popoverRoot.tsx | 28 +- .../overlays/popover/popoverTrigger.tsx | 8 +- packages/ui/src/index.ts | 38 +-- packages/ui/src/stores/index.ts | 4 +- packages/ui/src/stores/modalStore.tsx | 93 ++++-- packages/ui/src/stores/popoverStore.tsx | 108 +++++-- .../src/components/layouts/SubPageContent.tsx | 1 - .../layouts/commandPalette/CommandPalette.tsx | 72 +++-- .../components/layouts/tabBar/SplitTabBar.tsx | 34 +-- .../src/components/layouts/tabBar/TabBar.tsx | 52 +++- .../src/components/layouts/table/table.tsx | 4 +- .../overlays/contextMenu/ContextMenuItem.tsx | 14 +- .../components/overlays/popover/popover.tsx | 2 +- .../dashboard/DashboardContextProvider.tsx | 11 +- .../src/contexts/tabs/tabDefinitions.ts | 2 +- .../src/contexts/tabs/tabsProvider.tsx | 232 ++++++++++---- .../website/src/contexts/tabs/tabsStorage.ts | 9 +- .../OrganizationTabContent.tsx | 4 +- .../$idOrganization/agent/AgentLayout.tsx | 15 +- .../agent/AgentSessionContent.tsx | 283 +++++++++--------- .../OrganizationApiGeneralPage.tsx | 2 +- .../organizationApi/keys/DeleteOneApiKey.tsx | 16 +- .../CancelSubscription.tsx | 19 +- .../ResumeSubscription.tsx | 13 +- .../organizationBilling/UpdateLicencePage.tsx | 9 +- .../organizationBilling/UpdateOcrPage.tsx | 17 +- .../organizationBilling/UpdateStoragePage.tsx | 21 +- .../organizationBilling/UpdateTokensPage.tsx | 15 +- .../invoices/OrganizationInvoicePage.tsx | 4 +- .../DeleteOneOrganization.tsx | 17 +- .../DeleteOneOrganizationUser.tsx | 13 +- .../dashboard/$idYear/YearDataProvider.tsx | 2 - .../dashboard/$idYear/YearDataWrapper.tsx | 83 +++-- .../$idEntryLine/DeleteOneEntryLine.tsx | 17 +- .../$idEntry/$idEntryLine/EntryLineLayout.tsx | 9 +- .../$idEntryLine/EntryLineMetadataTab.tsx | 8 +- .../$idEntry/$idEntryLine/EntryLinePage.tsx | 8 +- .../entries/$idEntry/DeleteOneEntry.tsx | 17 +- .../entries/$idEntry/EntryInformationsTab.tsx | 3 +- .../$idYear/entries/$idEntry/EntryLayout.tsx | 8 +- .../entries/$idEntry/EntryLinesTab.tsx | 6 +- .../entries/$idEntry/EntryLinesTable.tsx | 2 +- .../entries/$idEntry/EntryRoutePage.tsx | 11 +- .../entries/$idEntry/EntryTabContent.tsx | 2 +- .../entries/$idEntry/UpdateOneEntry.tsx | 5 +- .../$idYear/entries/EntriesTable.tsx | 14 +- .../entries/EntriesTableSelectionActions.tsx | 30 +- .../$idYear/entries/ReverseOneEntry.tsx | 8 +- .../$idYear/files/$idFile/DeleteOneFile.tsx | 17 +- .../$idYear/files/$idFile/FileLayout.tsx | 7 +- .../dashboard/$idYear/files/FileActions.tsx | 23 +- .../$idYear/files/FileContextMenu.tsx | 17 +- .../dashboard/$idYear/files/FilesPage.tsx | 12 +- .../files/FilesTableSelectionActions.tsx | 46 ++- .../dashboard/$idYear/files/FolderActions.tsx | 29 +- .../$idYear/files/FolderContextMenu.tsx | 18 +- .../dashboard/$idYear/yearDataContext.tsx | 6 +- .../$idYear/yearSettings/DeleteOneYear.tsx | 17 +- .../$idYear/yearSettings/YearSettingsPage.tsx | 2 +- .../accounts/$idAccount/AccountLayout.tsx | 8 +- .../$idAccount/AccountMetadataTab.tsx | 8 +- .../accounts/$idAccount/AccountPage.tsx | 8 +- .../accounts/$idAccount/DeleteOneAccount.tsx | 18 +- .../accounts/$idAccount/UpdateOneAccount.tsx | 2 +- .../$idBalanceSheet/BalanceSheetLayout.tsx | 8 +- .../BalanceSheetMetadataTab.tsx | 8 +- .../$idBalanceSheet/BalanceSheetPage.tsx | 8 +- .../$idBalanceSheet/DeleteOneBalanceSheet.tsx | 17 +- .../DeleteOneIncomeStatement.tsx | 13 +- .../IncomeStatementLayout.tsx | 8 +- .../IncomeStatementMetadataTab.tsx | 8 +- .../IncomeStatementPage.tsx | 8 +- .../$idComputation/ComputationLayout.tsx | 8 +- .../$idComputation/ComputationMetadataTab.tsx | 8 +- .../$idComputation/ComputationPage.tsx | 8 +- .../$idComputation/ComputationPostesTab.tsx | 5 +- .../$idComputation/DeleteOneComputation.tsx | 17 +- .../ComputationIncomeStatementLayout.tsx | 9 +- .../ComputationIncomeStatementMetadataTab.tsx | 8 +- .../ComputationIncomeStatementPage.tsx | 8 +- .../DeleteOneComputationIncomeStatement.tsx | 13 +- .../ComputationIncomeStatementsTable.tsx | 2 +- .../computations/ComputationsPage.tsx | 5 +- .../computations/ComputationsTable.tsx | 2 +- .../journals/$idJournal/DeleteOneJournal.tsx | 17 +- .../journals/$idJournal/JournalLayout.tsx | 8 +- .../$idJournal/JournalMetadataTab.tsx | 8 +- .../journals/$idJournal/JournalPage.tsx | 8 +- .../journals/$idJournal/UpdateOneJournal.tsx | 2 +- .../yearSettings/tags/$idTag/DeleteOneTag.tsx | 17 +- .../yearSettings/tags/$idTag/TagLayout.tsx | 8 +- .../tags/$idTag/TagMetadataTab.tsx | 8 +- .../yearSettings/tags/$idTag/TagPage.tsx | 8 +- .../dashboard/OrganizationContextSelect.tsx | 10 +- .../features/dashboard/YearContextSelect.tsx | 12 +- .../admin/tickets/$idTicket/TicketLayout.tsx | 4 +- .../dashboard/admin/tickets/TicketsPage.tsx | 4 +- .../dashboardLayout/DashboardLayout.tsx | 1 - .../dashboardLayout/DashboardShell.tsx | 131 ++++++-- .../support/$idTicket/TicketLayout.tsx | 6 +- .../website/src/features/docs/DocsLayout.tsx | 2 +- .../GlossaryResourcesAccountingDocPage.tsx | 2 +- .../GettingStartedDashboardDocPage.tsx | 7 +- .../src/features/home/OrganizationsBanner.tsx | 2 +- .../root/dashboard/dashboardLayoutRoute.tsx | 5 +- pnpm-lock.yaml | 9 - 123 files changed, 1471 insertions(+), 696 deletions(-) diff --git a/packages/tools/src/schemas.ts b/packages/tools/src/schemas.ts index f9f1feb3..8af92de2 100644 --- a/packages/tools/src/schemas.ts +++ b/packages/tools/src/schemas.ts @@ -6,6 +6,11 @@ // file using relative paths that drizzle-kit's resolver can handle. // ============================================================================= +export { + agentMessageModel, + agentMessageRelations, + agentMessageStateEnum, +} from "../../metadata/src/models/AgentMessage.ts" export { accountBalanceSheetColumnEnum, accountBalanceSheetFlowEnum, @@ -13,11 +18,6 @@ export { accountRelations, accountTypeEnum, } from "../../metadata/src/models/account.ts" -export { - agentMessageModel, - agentMessageRelations, - agentMessageStateEnum, -} from "../../metadata/src/models/AgentMessage.ts" export { agentSessionModel, agentSessionRelations } from "../../metadata/src/models/agentSession.ts" export { apiKeyModel, apiKeyRelations } from "../../metadata/src/models/apiKey.ts" export { balanceSheetModel, balanceSheetRelations } from "../../metadata/src/models/balanceSheet.ts" diff --git a/packages/ui/src/components/buttons/Button.tsx b/packages/ui/src/components/buttons/Button.tsx index 5d289f3c..8c704d60 100644 --- a/packages/ui/src/components/buttons/Button.tsx +++ b/packages/ui/src/components/buttons/Button.tsx @@ -1,11 +1,4 @@ -import { - type ComponentProps, - createContext, - type MouseEvent, - type ReactNode, - useRef, - useState, -} from "react" +import { type ComponentProps, createContext, type MouseEvent, type ReactNode, useRef, useState } from "react" import { css, cx } from "../../utilities/cn.ts" import { sleep } from "../../utilities/sleep.ts" diff --git a/packages/ui/src/components/buttons/ButtonGhostContent.tsx b/packages/ui/src/components/buttons/ButtonGhostContent.tsx index 447b0e5b..837a07fc 100644 --- a/packages/ui/src/components/buttons/ButtonGhostContent.tsx +++ b/packages/ui/src/components/buttons/ButtonGhostContent.tsx @@ -1,6 +1,6 @@ import { sva } from "@arrhes/ui/css" -import { useButtonLoading } from "./useButtonLoading" import { type ButtonContentProps, renderButtonContent } from "./buttonContent" +import { useButtonLoading } from "./useButtonLoading" const ghostRecipe = sva({ slots: [ diff --git a/packages/ui/src/components/buttons/ButtonOutlineContent.tsx b/packages/ui/src/components/buttons/ButtonOutlineContent.tsx index 89bfd443..b4e4b54b 100644 --- a/packages/ui/src/components/buttons/ButtonOutlineContent.tsx +++ b/packages/ui/src/components/buttons/ButtonOutlineContent.tsx @@ -1,6 +1,6 @@ import { sva } from "@arrhes/ui/css" -import { useButtonLoading } from "./useButtonLoading" import { type ButtonContentProps, renderButtonContent } from "./buttonContent" +import { useButtonLoading } from "./useButtonLoading" const outlineRecipe = sva({ slots: [ diff --git a/packages/ui/src/components/buttons/ButtonPlainContent.tsx b/packages/ui/src/components/buttons/ButtonPlainContent.tsx index 6fa30be2..2c328162 100644 --- a/packages/ui/src/components/buttons/ButtonPlainContent.tsx +++ b/packages/ui/src/components/buttons/ButtonPlainContent.tsx @@ -1,6 +1,6 @@ import { sva } from "@arrhes/ui/css" -import { useButtonLoading } from "./useButtonLoading" import { type ButtonContentProps, renderButtonContent } from "./buttonContent" +import { useButtonLoading } from "./useButtonLoading" const plainRecipe = sva({ slots: [ diff --git a/packages/ui/src/components/formats/display/FormatFileSize.tsx b/packages/ui/src/components/formats/display/FormatFileSize.tsx index bfe2dabb..9f03af92 100644 --- a/packages/ui/src/components/formats/display/FormatFileSize.tsx +++ b/packages/ui/src/components/formats/display/FormatFileSize.tsx @@ -4,10 +4,7 @@ import { FormatBase } from "../FormatBase.js" import { FormatNull } from "../FormatNull.js" import { formatFileSize } from "../formatFileSize.js" -export function FormatFileSize(props: { - size?: number | null - className?: ComponentProps<"div">["className"] -}) { +export function FormatFileSize(props: { size?: number | null; className?: ComponentProps<"div">["className"] }) { if (props.size === undefined || props.size === null) return return ( diff --git a/packages/ui/src/components/inputs/InputCombobox.tsx b/packages/ui/src/components/inputs/InputCombobox.tsx index 4f047c2c..6c87f429 100644 --- a/packages/ui/src/components/inputs/InputCombobox.tsx +++ b/packages/ui/src/components/inputs/InputCombobox.tsx @@ -67,8 +67,8 @@ export function InputCombobox(props: { }), props.isDisabled ? css({ - cursor: "not-allowed", - }) + cursor: "not-allowed", + }) : "", props.className, )} @@ -96,15 +96,15 @@ export function InputCombobox(props: { }), props.error !== undefined ? css({ - borderColor: "error", - }) + borderColor: "error", + }) : "", currentOption === undefined ? css({ - "& span": { - color: "neutral/50", - }, - }) + "& span": { + color: "neutral/50", + }, + }) : "", )} /> @@ -172,8 +172,8 @@ export function InputCombobox(props: { }), isSelected ? css({ - backgroundColor: "background", - }) + backgroundColor: "background", + }) : "", )} isCurrent={isSelected} diff --git a/packages/ui/src/components/inputs/InputComboboxMultiple.tsx b/packages/ui/src/components/inputs/InputComboboxMultiple.tsx index e36ff3c9..b282888b 100644 --- a/packages/ui/src/components/inputs/InputComboboxMultiple.tsx +++ b/packages/ui/src/components/inputs/InputComboboxMultiple.tsx @@ -139,8 +139,8 @@ export function InputComboboxMultiple(props: InputCombobo }), props.isDisabled ? css({ - cursor: "not-allowed", - }) + cursor: "not-allowed", + }) : "", )} onClick={() => { diff --git a/packages/ui/src/components/overlays/dialog/DialogBody.tsx b/packages/ui/src/components/overlays/dialog/DialogBody.tsx index 50def9cb..0ac8d473 100644 --- a/packages/ui/src/components/overlays/dialog/DialogBody.tsx +++ b/packages/ui/src/components/overlays/dialog/DialogBody.tsx @@ -1,5 +1,5 @@ -import { css, cx } from "../../../utilities/cn.js" import type { HTMLAttributes } from "react" +import { css, cx } from "../../../utilities/cn.js" export function DialogBody(props: HTMLAttributes) { return ( diff --git a/packages/ui/src/components/overlays/dialog/DialogContent.tsx b/packages/ui/src/components/overlays/dialog/DialogContent.tsx index aba5dcbd..8ebffea9 100644 --- a/packages/ui/src/components/overlays/dialog/DialogContent.tsx +++ b/packages/ui/src/components/overlays/dialog/DialogContent.tsx @@ -1,5 +1,5 @@ -import { css, cx } from "../../../utilities/cn.js" import type { HTMLAttributes } from "react" +import { css, cx } from "../../../utilities/cn.js" export function DialogContent(props: HTMLAttributes) { return ( diff --git a/packages/ui/src/components/overlays/dialog/DialogDescription.tsx b/packages/ui/src/components/overlays/dialog/DialogDescription.tsx index 6a129779..cab5831e 100644 --- a/packages/ui/src/components/overlays/dialog/DialogDescription.tsx +++ b/packages/ui/src/components/overlays/dialog/DialogDescription.tsx @@ -1,5 +1,5 @@ -import { css, cx } from "../../../utilities/cn.js" import type { HTMLAttributes } from "react" +import { css, cx } from "../../../utilities/cn.js" export function DialogDescription(props: HTMLAttributes) { return ( diff --git a/packages/ui/src/components/overlays/dialog/DialogFooter.tsx b/packages/ui/src/components/overlays/dialog/DialogFooter.tsx index c72fff1d..959c534b 100644 --- a/packages/ui/src/components/overlays/dialog/DialogFooter.tsx +++ b/packages/ui/src/components/overlays/dialog/DialogFooter.tsx @@ -1,5 +1,5 @@ -import { css, cx } from "../../../utilities/cn.js" import type { HTMLAttributes } from "react" +import { css, cx } from "../../../utilities/cn.js" export function DialogFooter(props: HTMLAttributes) { return ( diff --git a/packages/ui/src/components/overlays/dialog/DialogHeader.tsx b/packages/ui/src/components/overlays/dialog/DialogHeader.tsx index 2d3b8def..2b455a46 100644 --- a/packages/ui/src/components/overlays/dialog/DialogHeader.tsx +++ b/packages/ui/src/components/overlays/dialog/DialogHeader.tsx @@ -1,8 +1,8 @@ -import { ButtonGhostContent } from "../../buttons/ButtonGhostContent.js" -import { css, cx } from "../../../utilities/cn.js" import { IconX } from "@tabler/icons-react" -import { useModalItem } from "../../../stores/modalStore.js" import type { HTMLAttributes } from "react" +import { useModalItem } from "../../../stores/modalStore.js" +import { css, cx } from "../../../utilities/cn.js" +import { ButtonGhostContent } from "../../buttons/ButtonGhostContent.js" export function DialogHeader(props: HTMLAttributes) { const modalItem = useModalItem() diff --git a/packages/ui/src/components/overlays/dialog/DialogTitle.tsx b/packages/ui/src/components/overlays/dialog/DialogTitle.tsx index cb841dae..7f0af8bc 100644 --- a/packages/ui/src/components/overlays/dialog/DialogTitle.tsx +++ b/packages/ui/src/components/overlays/dialog/DialogTitle.tsx @@ -1,5 +1,5 @@ -import { css, cx } from "../../../utilities/cn.js" import type { HTMLAttributes } from "react" +import { css, cx } from "../../../utilities/cn.js" export function DialogTitle(props: HTMLAttributes) { return ( diff --git a/packages/ui/src/components/overlays/popover/PopoverContent.tsx b/packages/ui/src/components/overlays/popover/PopoverContent.tsx index b2881aaf..55b19152 100644 --- a/packages/ui/src/components/overlays/popover/PopoverContent.tsx +++ b/packages/ui/src/components/overlays/popover/PopoverContent.tsx @@ -1,4 +1,4 @@ -import { type ReactNode } from "react" +import type { ReactNode } from "react" import { createPortal } from "react-dom" import { css, cx } from "../../../utilities/cn.js" import { usePopoverContext } from "./popoverRoot.js" diff --git a/packages/ui/src/components/overlays/popover/popover.tsx b/packages/ui/src/components/overlays/popover/popover.tsx index 1d1b8fa8..2da98283 100644 --- a/packages/ui/src/components/overlays/popover/popover.tsx +++ b/packages/ui/src/components/overlays/popover/popover.tsx @@ -1,5 +1,5 @@ -import { PopoverClose } from "./popoverClose.js" import { PopoverContent } from "./PopoverContent.js" +import { PopoverClose } from "./popoverClose.js" import { PopoverRoot } from "./popoverRoot.js" import { PopoverTrigger } from "./popoverTrigger.js" diff --git a/packages/ui/src/components/overlays/popover/popoverClose.tsx b/packages/ui/src/components/overlays/popover/popoverClose.tsx index 36060358..58aab1f1 100644 --- a/packages/ui/src/components/overlays/popover/popoverClose.tsx +++ b/packages/ui/src/components/overlays/popover/popoverClose.tsx @@ -1,10 +1,7 @@ -import { type ReactElement, cloneElement, isValidElement } from "react" +import { cloneElement, isValidElement, type ReactElement } from "react" import { usePopoverContext } from "./popoverRoot.js" -export function PopoverClose(props: { - children: ReactElement - asChild?: boolean -}) { +export function PopoverClose(props: { children: ReactElement; asChild?: boolean }) { const { setOpen } = usePopoverContext() function handleClick() { @@ -25,7 +22,10 @@ export function PopoverClose(props: { } return ( - ) diff --git a/packages/ui/src/components/overlays/popover/popoverRoot.tsx b/packages/ui/src/components/overlays/popover/popoverRoot.tsx index b5c111f6..36b2b9a4 100644 --- a/packages/ui/src/components/overlays/popover/popoverRoot.tsx +++ b/packages/ui/src/components/overlays/popover/popoverRoot.tsx @@ -1,4 +1,13 @@ -import { type Dispatch, type ReactNode, type SetStateAction, createContext, useContext, useEffect, useId, useState } from "react" +import { + createContext, + type Dispatch, + type ReactNode, + type SetStateAction, + useContext, + useEffect, + useId, + useState, +} from "react" import { usePopoverStore } from "../../../stores/popoverStore.js" // --------------------------------------------------------------------------- @@ -54,7 +63,20 @@ export function PopoverRoot(props: { store.register(id, setOpen) return () => store.unregister(id) // eslint-disable-next-line react-hooks/exhaustive-deps - }, [id]) + }, [ + id, + ]) - return {props.children} + return ( + + {props.children} + + ) } diff --git a/packages/ui/src/components/overlays/popover/popoverTrigger.tsx b/packages/ui/src/components/overlays/popover/popoverTrigger.tsx index c412b266..2481cd81 100644 --- a/packages/ui/src/components/overlays/popover/popoverTrigger.tsx +++ b/packages/ui/src/components/overlays/popover/popoverTrigger.tsx @@ -1,4 +1,4 @@ -import { type ReactElement, cloneElement, isValidElement } from "react" +import { cloneElement, isValidElement, type ReactElement } from "react" import { usePopoverContext } from "./popoverRoot.js" export function PopoverTrigger(props: { @@ -35,7 +35,11 @@ export function PopoverTrigger(props: { ) diff --git a/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx b/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx index 8e6d5402..4602baaf 100644 --- a/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx +++ b/packages/website/src/components/layouts/tabBar/SplitTabBar.tsx @@ -19,7 +19,11 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord const [dragOverTabId, setDragOverTabId] = useState(null) const panelTabs = tabIds.flatMap((id) => { const t = tabs.find((x) => x.id === id) - return t ? [t] : [] + return t + ? [ + t, + ] + : [] }) function handleDrop(e: React.DragEvent, insertBeforeTabId: string | null) { @@ -69,10 +73,10 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord const title = entry ? entry.title : ( - tab as { - title: string - } - ).title + tab as { + title: string + } + ).title const description = entry?.description ?? (tab.type === "panel" ? tab.description : undefined) return (
{ @@ -118,22 +119,17 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord e.stopPropagation() const rect = e.currentTarget.getBoundingClientRect() const insertBeforeTabId = - e.clientX < rect.left + rect.width / 2 - ? tab.id - : (panelTabs[index + 1]?.id ?? null) + e.clientX < rect.left + rect.width / 2 ? tab.id : (panelTabs[index + 1]?.id ?? null) setDragOverTabId(insertBeforeTabId) } }} onDragLeave={(e) => { - if (!e.currentTarget.contains(e.relatedTarget as Node | null)) - setDragOverTabId(null) + if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setDragOverTabId(null) }} onDrop={(e) => { const rect = e.currentTarget.getBoundingClientRect() const insertBeforeTabId = - e.clientX < rect.left + rect.width / 2 - ? tab.id - : (panelTabs[index + 1]?.id ?? null) + e.clientX < rect.left + rect.width / 2 ? tab.id : (panelTabs[index + 1]?.id ?? null) handleDrop(e, insertBeforeTabId) }} onClick={() => onActivate(tab.id)} @@ -153,8 +149,7 @@ export function SplitTabBar({ tabIds, activeTabId, onActivate, onRemove, onReord
) })} - ) } diff --git a/packages/website/src/components/layouts/tabBar/TabBar.tsx b/packages/website/src/components/layouts/tabBar/TabBar.tsx index 8f9ff11b..bccf3f2e 100644 --- a/packages/website/src/components/layouts/tabBar/TabBar.tsx +++ b/packages/website/src/components/layouts/tabBar/TabBar.tsx @@ -25,14 +25,29 @@ type TabBarProps = { } export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanels, panel }: TabBarProps = {}) { - const { tabs: allTabs, activeTabId: contextActiveTabId, activateTab, closeTab, navigateBack, navigateForward, reorderTabs } = useTabs() + const { + tabs: allTabs, + activeTabId: contextActiveTabId, + activateTab, + closeTab, + navigateBack, + navigateForward, + reorderTabs, + } = useTabs() const isRightPanel = panel !== undefined const dragDataType = isRightPanel ? "application/arrhes-right-tab" : "application/arrhes-left-tab" const crossDragDataType = isRightPanel ? "application/arrhes-left-tab" : "application/arrhes-right-tab" const tabs = isRightPanel - ? panel.tabIds.flatMap((id) => { const t = allTabs.find((x) => x.id === id); return t ? [t] : [] }) + ? panel.tabIds.flatMap((id) => { + const t = allTabs.find((x) => x.id === id) + return t + ? [ + t, + ] + : [] + }) : allTabs.filter((t) => !excludeTabIds?.includes(t.id)) const activeTabId = isRightPanel ? panel.activeTabId : contextActiveTabId @@ -60,14 +75,17 @@ export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanel const [dragOverTabId, setDragOverTabId] = useState(null) const [contextMenuTabId, setContextMenuTabId] = useState(null) const contextTab = contextMenuTabId !== null ? (tabs.find((t) => t.id === contextMenuTabId) ?? null) : null - const contextTabCanGoBack = - contextTab?.type === "component" && (contextTab as ComponentTab).historyIndex > 0 + const contextTabCanGoBack = contextTab?.type === "component" && (contextTab as ComponentTab).historyIndex > 0 const contextTabCanGoForward = contextTab?.type === "component" && (contextTab as ComponentTab).historyIndex < (contextTab as ComponentTab).history.length - 1 return ( - { if (!open) setContextMenuTabId(null) }}> + { + if (!open) setContextMenuTabId(null) + }} + >
{ const isActive = tab.id === activeTabId const entry = tab.type === "component" ? currentEntry(tab as ComponentTab) : null - const title = entry ? entry.title : (tab as { title: string }).title + const title = entry + ? entry.title + : ( + tab as { + title: string + } + ).title const description = entry?.description ?? (tab.type === "panel" ? tab.description : undefined) return (
{ @@ -151,7 +173,9 @@ export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanel if (!isRightPanel && e.dataTransfer.dropEffect === "none") { window.dispatchEvent( new CustomEvent("arrhes:split-tab", { - detail: { tabId: tab.id }, + detail: { + tabId: tab.id, + }, }), ) } @@ -186,9 +210,7 @@ export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanel if (!draggedTabId) return const rect = e.currentTarget.getBoundingClientRect() const insertBeforeTabId = - e.clientX < rect.left + rect.width / 2 - ? tab.id - : (tabs[index + 1]?.id ?? null) + e.clientX < rect.left + rect.width / 2 ? tab.id : (tabs[index + 1]?.id ?? null) if (fromSamePanel) onReorderTab(draggedTabId, insertBeforeTabId) else onCrossDropTab(draggedTabId, insertBeforeTabId) }} @@ -302,7 +324,9 @@ export function TabBar({ excludeTabIds, rightSlot, onDropFromRight, onMergePanel onSelect={() => window.dispatchEvent( new CustomEvent("arrhes:split-tab", { - detail: { tabId: contextTab.id }, + detail: { + tabId: contextTab.id, + }, }), ) } diff --git a/packages/website/src/components/layouts/table/table.tsx b/packages/website/src/components/layouts/table/table.tsx index 02d03349..6e78afce 100644 --- a/packages/website/src/components/layouts/table/table.tsx +++ b/packages/website/src/components/layouts/table/table.tsx @@ -1,12 +1,12 @@ import { FilterPopover } from "../FilterPopover.js" import { SortPopover } from "../SortPopover.js" +import { TableRoot } from "./TableRoot.js" import { TableBodyCell } from "./tableBody/TableBodyCell.js" -import { TableBodyRoot } from "./tableBody/tableBodyRoot.js" import { TableBodyRow } from "./tableBody/TableBodyRow.js" +import { TableBodyRoot } from "./tableBody/tableBodyRoot.js" import { TableHeaderCell } from "./tableHeader/TableHeaderCell.js" import { TableHeaderRoot } from "./tableHeader/TableHeaderRoot.js" import { TableHeaderRow } from "./tableHeader/TableHeaderRow.js" -import { TableRoot } from "./TableRoot.js" export const Table = { Root: TableRoot, diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx index 9c05ffa5..52c7d796 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx @@ -40,14 +40,14 @@ export function ContextMenuItem( }), color === "danger" ? css({ - color: "error", - _hover: { - backgroundColor: "red.50", - }, - }) + color: "error", + _hover: { + backgroundColor: "red.50", + }, + }) : css({ - color: "neutral", - }), + color: "neutral", + }), props.className, )} > diff --git a/packages/website/src/components/overlays/popover/popover.tsx b/packages/website/src/components/overlays/popover/popover.tsx index 1d1b8fa8..2da98283 100644 --- a/packages/website/src/components/overlays/popover/popover.tsx +++ b/packages/website/src/components/overlays/popover/popover.tsx @@ -1,5 +1,5 @@ -import { PopoverClose } from "./popoverClose.js" import { PopoverContent } from "./PopoverContent.js" +import { PopoverClose } from "./popoverClose.js" import { PopoverRoot } from "./popoverRoot.js" import { PopoverTrigger } from "./popoverTrigger.js" diff --git a/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx b/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx index 2deb4ed8..e35e61e5 100644 --- a/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx +++ b/packages/website/src/contexts/dashboard/DashboardContextProvider.tsx @@ -19,7 +19,7 @@ function writeStorage(key: string, value: string | null): void { try { if (value !== null) localStorage.setItem(key, value) else localStorage.removeItem(key) - } catch { } + } catch {} } export function DashboardContextProvider(props: { children: ReactNode }) { @@ -45,7 +45,14 @@ export function DashboardContextProvider(props: { children: ReactNode }) { }, []) return ( - + {props.children} ) diff --git a/packages/website/src/contexts/tabs/tabDefinitions.ts b/packages/website/src/contexts/tabs/tabDefinitions.ts index 07b5345e..bcd9d213 100644 --- a/packages/website/src/contexts/tabs/tabDefinitions.ts +++ b/packages/website/src/contexts/tabs/tabDefinitions.ts @@ -1,5 +1,6 @@ import { createElement } from "react" import { AgentTabContent } from "../../features/dashboard/$idOrganization/agent/AgentTabContent.js" +import { OrganizationTabContent } from "../../features/dashboard/$idOrganization/OrganizationTabContent.js" import { OrganizationApiTabContent } from "../../features/dashboard/$idOrganization/organizationApi/OrganizationApiTabContent.js" import { OrganizationBillingTabContent } from "../../features/dashboard/$idOrganization/organizationBilling/OrganizationBillingTabContent.js" import { UpdateLicencePage } from "../../features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.js" @@ -9,7 +10,6 @@ import { UpdateTokensPage } from "../../features/dashboard/$idOrganization/organ import { WalletTopUpPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/WalletTopUpPage.js" import { WalletWithdrawalPage } from "../../features/dashboard/$idOrganization/organizationBilling/wallet/WalletWithdrawalPage.js" import { OrganizationSettingsTabContent } from "../../features/dashboard/$idOrganization/organizationSettings/OrganizationSettingsTabContent.js" -import { OrganizationTabContent } from "../../features/dashboard/$idOrganization/OrganizationTabContent.js" import { OrganizationUsersPage } from "../../features/dashboard/$idOrganization/organizationUsers/OrganizationUsersPage.js" import { YearsPage } from "../../features/dashboard/$idOrganization/years/YearsPage.js" import { EntryTabContent } from "../../features/dashboard/$idYear/entries/$idEntry/EntryTabContent.js" diff --git a/packages/website/src/contexts/tabs/tabsProvider.tsx b/packages/website/src/contexts/tabs/tabsProvider.tsx index 8740bf94..7c8bf066 100644 --- a/packages/website/src/contexts/tabs/tabsProvider.tsx +++ b/packages/website/src/contexts/tabs/tabsProvider.tsx @@ -202,7 +202,14 @@ export function TabsProvider({ children }: Props) { } else { const tab = tabsRef.current.find((t): t is ComponentTab => t.type === "component" && t.id === activeTabId) const entryId = tab ? currentEntry(tab).id : "0" - window.history.replaceState({ tabId: activeTabId, entryId }, "", `/dashboard/${activeTabId}/${entryId}`) + window.history.replaceState( + { + tabId: activeTabId, + entryId, + }, + "", + `/dashboard/${activeTabId}/${entryId}`, + ) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) @@ -211,7 +218,11 @@ export function TabsProvider({ children }: Props) { // Parse the destination URL/state and update tab context accordingly. useEffect(() => { const onPopState = (e: PopStateEvent) => { - const state = e.state as { tabId?: string; entryId?: string; panelTabId?: string } | null + const state = e.state as { + tabId?: string + entryId?: string + panelTabId?: string + } | null // Panel-tab back/forward: re-activate the panel if it still exists, // otherwise fall through to URL-based component-tab restoration. @@ -245,15 +256,17 @@ export function TabsProvider({ children }: Props) { applyLruEviction( prev.map((t) => { if (t.type !== "component" || t.id !== tabId) return t - const historyIndex = entryId - ? t.history.findIndex((e) => e.id === entryId) - : t.historyIndex + const historyIndex = entryId ? t.history.findIndex((e) => e.id === entryId) : t.historyIndex if (historyIndex < 0) return t const history = t.history.map((e, i) => { if (i !== historyIndex || e.component !== null) return e return buildEntry(e.definitionKey, e.definitionProps, e.id) }) - return { ...t, history, historyIndex } + return { + ...t, + history, + historyIndex, + } }), tabId, ), @@ -308,17 +321,20 @@ export function TabsProvider({ children }: Props) { prev.map((t) => t.id === activeTab.id ? { - ...t, - history: newHistory, - historyIndex: newIndex, - } + ...t, + history: newHistory, + historyIndex: newIndex, + } : t, ), activeTab.id, ), ) window.history.pushState( - { tabId: activeTab.id, entryId: entry.id }, + { + tabId: activeTab.id, + entryId: entry.id, + }, "", `/dashboard/${activeTab.id}/${entry.id}`, ) @@ -363,13 +379,19 @@ export function TabsProvider({ children }: Props) { // Push so the previous tab's position is preserved in browser history. if (currentActiveId !== existing.id) { window.history.pushState( - { tabId: existing.id, entryId: currentEntry(existing).id }, + { + tabId: existing.id, + entryId: currentEntry(existing).id, + }, "", `/dashboard/${existing.id}/${currentEntry(existing).id}`, ) } else { window.history.replaceState( - { tabId: existing.id, entryId: currentEntry(existing).id }, + { + tabId: existing.id, + entryId: currentEntry(existing).id, + }, "", `/dashboard/${existing.id}/${currentEntry(existing).id}`, ) @@ -399,9 +421,23 @@ export function TabsProvider({ children }: Props) { ) // Push so the previous tab's position is preserved in browser history. if (currentActiveId !== null) { - window.history.pushState({ tabId: newTab.id, entryId: entry.id }, "", `/dashboard/${newTab.id}/${entry.id}`) + window.history.pushState( + { + tabId: newTab.id, + entryId: entry.id, + }, + "", + `/dashboard/${newTab.id}/${entry.id}`, + ) } else { - window.history.replaceState({ tabId: newTab.id, entryId: entry.id }, "", `/dashboard/${newTab.id}/${entry.id}`) + window.history.replaceState( + { + tabId: newTab.id, + entryId: entry.id, + }, + "", + `/dashboard/${newTab.id}/${entry.id}`, + ) } }, []) @@ -423,7 +459,11 @@ export function TabsProvider({ children }: Props) { } else { // Find the most recently focused tab that still exists. const existingIds = new Set(next.map((t) => t.id)) - const lastFocused = [...focusHistoryRef.current].reverse().find((fid) => existingIds.has(fid)) + const lastFocused = [ + ...focusHistoryRef.current, + ] + .reverse() + .find((fid) => existingIds.has(fid)) newActiveId = lastFocused ?? next[Math.min(idx, next.length - 1)].id } @@ -438,7 +478,11 @@ export function TabsProvider({ children }: Props) { setActiveTabId((currentActive) => { if (currentActive !== id) return currentActive const existingIds = new Set(n.map((t) => t.id)) - const lastFocused = [...focusHistoryRef.current].reverse().find((fid) => existingIds.has(fid)) + const lastFocused = [ + ...focusHistoryRef.current, + ] + .reverse() + .find((fid) => existingIds.has(fid)) return lastFocused ?? n[Math.min(i, n.length - 1)].id }) return n @@ -450,7 +494,10 @@ export function TabsProvider({ children }: Props) { const newActiveTab = next.find((t): t is ComponentTab => t.type === "component" && t.id === newActiveId) const entryId = newActiveTab ? currentEntry(newActiveTab).id : "0" window.history.replaceState( - { tabId: newActiveId, entryId }, + { + tabId: newActiveId, + entryId, + }, "", `/dashboard/${newActiveId}/${entryId}`, ) @@ -459,7 +506,10 @@ export function TabsProvider({ children }: Props) { const activateTab = useCallback((id: string) => { // Record in focus history (append, deduplicate from earlier positions). - focusHistoryRef.current = [...focusHistoryRef.current.filter((fid) => fid !== id), id] + focusHistoryRef.current = [ + ...focusHistoryRef.current.filter((fid) => fid !== id), + id, + ] setTabs((prev) => { const revived = prev.map((t) => { @@ -484,9 +534,23 @@ export function TabsProvider({ children }: Props) { // the back button returns to the previous tab at its exact position. // Replace (no-op) when re-activating the already-active tab. if (activeTabIdRef.current !== id) { - window.history.pushState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) + window.history.pushState( + { + tabId: id, + entryId, + }, + "", + `/dashboard/${id}/${entryId}`, + ) } else { - window.history.replaceState({ tabId: id, entryId }, "", `/dashboard/${id}/${entryId}`) + window.history.replaceState( + { + tabId: id, + entryId, + }, + "", + `/dashboard/${id}/${entryId}`, + ) } }, []) @@ -505,12 +569,23 @@ export function TabsProvider({ children }: Props) { return buildEntry(e.definitionKey, e.definitionProps, e.id) }) return applyLruEviction( - prev.map((pt) => (pt.id === tabId ? { ...t, history, historyIndex: idx } : pt)), + prev.map((pt) => + pt.id === tabId + ? { + ...t, + history, + historyIndex: idx, + } + : pt, + ), tabId, ) }) window.history.replaceState( - { tabId, entryId: targetEntry.id }, + { + tabId, + entryId: targetEntry.id, + }, "", `/dashboard/${tabId}/${targetEntry.id}`, ) @@ -530,46 +605,72 @@ export function TabsProvider({ children }: Props) { return buildEntry(e.definitionKey, e.definitionProps, e.id) }) return applyLruEviction( - prev.map((pt) => (pt.id === tabId ? { ...t, history, historyIndex: idx } : pt)), + prev.map((pt) => + pt.id === tabId + ? { + ...t, + history, + historyIndex: idx, + } + : pt, + ), tabId, ) }) window.history.replaceState( - { tabId, entryId: targetEntry.id }, + { + tabId, + entryId: targetEntry.id, + }, "", `/dashboard/${tabId}/${targetEntry.id}`, ) }, []) - const openPanelTab = useCallback((title: string, component: React.ReactNode, description?: string, icon?: string): string => { - // Dedup: if a panel tab with the same title already exists, focus it. - const existing = tabsRef.current.find((t): t is PanelTab => t.type === "panel" && t.title === title) - if (existing) { - setActiveTabId(existing.id) - window.history.pushState({ panelTabId: existing.id }, "", window.location.href) - return existing.id - } + const openPanelTab = useCallback( + (title: string, component: React.ReactNode, description?: string, icon?: string): string => { + // Dedup: if a panel tab with the same title already exists, focus it. + const existing = tabsRef.current.find((t): t is PanelTab => t.type === "panel" && t.title === title) + if (existing) { + setActiveTabId(existing.id) + window.history.pushState( + { + panelTabId: existing.id, + }, + "", + window.location.href, + ) + return existing.id + } - const id = generateId() - const newTab: PanelTab = { - id, - type: "panel", - title, - description, - icon, - component, - } - setTabs((prev) => [ - ...prev, - newTab, - ]) - setActiveTabId(id) - // Push a browser history entry so that pressing Back from a panel tab - // returns to the previous tab/panel rather than skipping it. - // Store the panel tab ID so popstate can re-activate it on forward. - window.history.pushState({ panelTabId: id }, "", window.location.href) - return id - }, []) + const id = generateId() + const newTab: PanelTab = { + id, + type: "panel", + title, + description, + icon, + component, + } + setTabs((prev) => [ + ...prev, + newTab, + ]) + setActiveTabId(id) + // Push a browser history entry so that pressing Back from a panel tab + // returns to the previous tab/panel rather than skipping it. + // Store the panel tab ID so popstate can re-activate it on forward. + window.history.pushState( + { + panelTabId: id, + }, + "", + window.location.href, + ) + return id + }, + [], + ) const updateTabTitle = useCallback((id: string, title: string) => { setTabs((prev) => @@ -579,9 +680,9 @@ export function TabsProvider({ children }: Props) { const history = t.history.map((e, i) => i === t.historyIndex ? { - ...e, - title, - } + ...e, + title, + } : e, ) return { @@ -597,10 +698,22 @@ export function TabsProvider({ children }: Props) { const tab = prev.find((t) => t.id === tabId) if (!tab) return prev const without = prev.filter((t) => t.id !== tabId) - if (beforeTabId === null) return [...without, tab] + if (beforeTabId === null) + return [ + ...without, + tab, + ] const idx = without.findIndex((t) => t.id === beforeTabId) - if (idx === -1) return [...without, tab] - return [...without.slice(0, idx), tab, ...without.slice(idx)] + if (idx === -1) + return [ + ...without, + tab, + ] + return [ + ...without.slice(0, idx), + tab, + ...without.slice(idx), + ] }) }, []) @@ -637,4 +750,3 @@ export function TabsProvider({ children }: Props) { ) } - diff --git a/packages/website/src/contexts/tabs/tabsStorage.ts b/packages/website/src/contexts/tabs/tabsStorage.ts index ca64a0e7..4491a406 100644 --- a/packages/website/src/contexts/tabs/tabsStorage.ts +++ b/packages/website/src/contexts/tabs/tabsStorage.ts @@ -96,7 +96,14 @@ export function normalisePersisted(state: PersistedState): PersistedState { ...state, tabs: state.tabs.map((t) => ({ ...t, - history: t.history.map((e) => (e.id ? e : { ...e, id: generateId() })), + history: t.history.map((e) => + e.id + ? e + : { + ...e, + id: generateId(), + }, + ), })), } } diff --git a/packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx b/packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx index 04884ca1..897b131c 100644 --- a/packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/OrganizationTabContent.tsx @@ -194,7 +194,9 @@ export function OrganizationTabContent(props: { idOrganization: string }) { {items.map((item) => (
diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx index 04e9890a..b942c36f 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentLayout.tsx @@ -18,7 +18,10 @@ import { extractSnippet } from "./extractSnippet.ts" export function AgentLayout() { const params = useParams({ strict: false, - }) as { idOrganization?: string; idAgentSession?: string } + }) as { + idOrganization: string + idAgentSession: string + } const [activeSessionId, setActiveSessionId] = useState(undefined) const [isMenuOpen, setIsMenuOpen] = useState(false) const navigate = useNavigate() @@ -37,12 +40,12 @@ export function AgentLayout() { routeDefinition: readAllAgentSessionsRouteDefinition, body: searchTrimmed ? { - idOrganization: params.idOrganization, - search: searchTrimmed, - } + idOrganization: params.idOrganization, + search: searchTrimmed, + } : { - idOrganization: params.idOrganization, - }, + idOrganization: params.idOrganization, + }, }) const displaySessions = sessions ?? [] diff --git a/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx index fa922a96..3b99f5de 100644 --- a/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/agent/AgentSessionContent.tsx @@ -362,151 +362,151 @@ export function AgentSessionContent({ setStreamMessageId(undefined) } - // SSE stream - ; (async () => { - let streamCompleted = false - try { - const headers: Record = { - "Content-Type": "application/json", - } - const orgCookie = getCookie(`${cookiePrefix}_id_organization`) - if (orgCookie) { - headers["X-Organization-Id"] = orgCookie - } + // SSE stream + ;(async () => { + let streamCompleted = false + try { + const headers: Record = { + "Content-Type": "application/json", + } + const orgCookie = getCookie(`${cookiePrefix}_id_organization`) + if (orgCookie) { + headers["X-Organization-Id"] = orgCookie + } - const apiBaseUrl = resolveApiBaseUrl(import.meta.env.VITE_API_BASE_URL) - if (!apiBaseUrl) { - throw new Error("VITE_API_BASE_URL is not configured") - } + const apiBaseUrl = resolveApiBaseUrl(import.meta.env.VITE_API_BASE_URL) + if (!apiBaseUrl) { + throw new Error("VITE_API_BASE_URL is not configured") + } - const response = await fetch(new URL(`${apiBaseUrl}${getStreamForAgentMessageRouteDefinition.path}`), { - method: "POST", - credentials: "include", - signal: controller.signal, - headers, - body: JSON.stringify({ - idOrganization: idOrganization, - idAgentMessage: streamMessageId, - }), - }) + const response = await fetch(new URL(`${apiBaseUrl}${getStreamForAgentMessageRouteDefinition.path}`), { + method: "POST", + credentials: "include", + signal: controller.signal, + headers, + body: JSON.stringify({ + idOrganization: idOrganization, + idAgentMessage: streamMessageId, + }), + }) - if (!isHealthyStreamResponse(response)) { - toast({ - title: "Le flux de reponse est indisponible", - description: "Veuillez renvoyer votre message.", - variant: "error", - }) - if (!controller.signal.aborted) { - await finish() - } - return + if (!isHealthyStreamResponse(response)) { + toast({ + title: "Le flux de reponse est indisponible", + description: "Veuillez renvoyer votre message.", + variant: "error", + }) + if (!controller.signal.aborted) { + await finish() } + return + } - const reader = response.body.getReader() - const decoder = new TextDecoder() - let buffer = "" + const reader = response.body.getReader() + const decoder = new TextDecoder() + let buffer = "" - while (true) { - const { done, value } = await reader.read() - if (done) break + while (true) { + const { done, value } = await reader.read() + if (done) break - buffer += decoder.decode(value, { - stream: true, - }) + buffer += decoder.decode(value, { + stream: true, + }) - const parts = buffer.split("\n\n") - buffer = parts.pop() ?? "" - - for (const part of parts) { - for (const line of part.split("\n")) { - if (!line.startsWith("data: ")) continue - const jsonStr = line.slice(6).trim() - if (!jsonStr) continue - - try { - const chunk = JSON.parse(jsonStr) - if (chunk.type === "TEXT_MESSAGE_CONTENT" && typeof chunk.delta === "string") { - if (chunk.subagentSkills && subagentStack.length > 0) { - // Accumulate subagent content - const current = subagentStack[subagentStack.length - 1] - if (current) { - current.content += chunk.delta - setActiveSubagents([ - ...subagentStack, - ]) - } - } else { - accumulated += chunk.delta - setStreamingContent(accumulated) + const parts = buffer.split("\n\n") + buffer = parts.pop() ?? "" + + for (const part of parts) { + for (const line of part.split("\n")) { + if (!line.startsWith("data: ")) continue + const jsonStr = line.slice(6).trim() + if (!jsonStr) continue + + try { + const chunk = JSON.parse(jsonStr) + if (chunk.type === "TEXT_MESSAGE_CONTENT" && typeof chunk.delta === "string") { + if (chunk.subagentSkills && subagentStack.length > 0) { + // Accumulate subagent content + const current = subagentStack[subagentStack.length - 1] + if (current) { + current.content += chunk.delta + setActiveSubagents([ + ...subagentStack, + ]) } + } else { + accumulated += chunk.delta + setStreamingContent(accumulated) } - if (chunk.type === "TOOL_CALL_START") { - // Emit text boundary if text accumulated since last boundary - if (accumulated.length > lastBoundaryLen) { - accumulatedToolCalls.push({ - type: "TEXT_BOUNDARY", - contentLength: accumulated.length, - }) - lastBoundaryLen = accumulated.length - } - accumulatedToolCalls.push(chunk) - setStreamingToolCalls([ - ...accumulatedToolCalls, - ]) - } - if (chunk.type === "CONTEXT_LIMIT_WARNING") { - toast({ - title: "La conversation approche de sa limite de contexte", - description: `${chunk.usage}% de la capacité utilisée. Envisagez de créer une nouvelle session.`, - variant: "warning", - }) - } - if (chunk.type === "TOOL_CALL_END") { - // Deduplicate: framework re-emits TOOL_CALL_END after RUN_FINISHED - const tcId = chunk.toolCallId as string | undefined - if (tcId && seenEnds.has(tcId)) continue - if (tcId) seenEnds.add(tcId) - accumulatedToolCalls.push(chunk) - setStreamingToolCalls([ - ...accumulatedToolCalls, - ]) - } - if (chunk.type === "SUBAGENT_RUN_START") { - subagentStack.push({ - role: (chunk.skills as string) ?? "subagent", - depth: chunk.depth as number, - content: "", + } + if (chunk.type === "TOOL_CALL_START") { + // Emit text boundary if text accumulated since last boundary + if (accumulated.length > lastBoundaryLen) { + accumulatedToolCalls.push({ + type: "TEXT_BOUNDARY", + contentLength: accumulated.length, }) - setActiveSubagents([ - ...subagentStack, - ]) + lastBoundaryLen = accumulated.length } - if (chunk.type === "SUBAGENT_RUN_END") { - subagentStack.pop() - setActiveSubagents([ - ...subagentStack, - ]) - } - } catch { - // ignore malformed chunks + accumulatedToolCalls.push(chunk) + setStreamingToolCalls([ + ...accumulatedToolCalls, + ]) + } + if (chunk.type === "CONTEXT_LIMIT_WARNING") { + toast({ + title: "La conversation approche de sa limite de contexte", + description: `${chunk.usage}% de la capacité utilisée. Envisagez de créer une nouvelle session.`, + variant: "warning", + }) + } + if (chunk.type === "TOOL_CALL_END") { + // Deduplicate: framework re-emits TOOL_CALL_END after RUN_FINISHED + const tcId = chunk.toolCallId as string | undefined + if (tcId && seenEnds.has(tcId)) continue + if (tcId) seenEnds.add(tcId) + accumulatedToolCalls.push(chunk) + setStreamingToolCalls([ + ...accumulatedToolCalls, + ]) + } + if (chunk.type === "SUBAGENT_RUN_START") { + subagentStack.push({ + role: (chunk.skills as string) ?? "subagent", + depth: chunk.depth as number, + content: "", + }) + setActiveSubagents([ + ...subagentStack, + ]) + } + if (chunk.type === "SUBAGENT_RUN_END") { + subagentStack.pop() + setActiveSubagents([ + ...subagentStack, + ]) } + } catch { + // ignore malformed chunks } } } + } - streamCompleted = true - } catch (err: unknown) { - if (err instanceof Error && err.name === "AbortError") return - console.error("[stream] SSE error — falling back to polling", err) - } finally { - // Only finish when the stream completed naturally. - // If the SSE failed (network/auth error), let the polling - // fallback continue running so it can detect completion. - if (streamCompleted && !controller.signal.aborted) { - finish() - } + streamCompleted = true + } catch (err: unknown) { + if (err instanceof Error && err.name === "AbortError") return + console.error("[stream] SSE error — falling back to polling", err) + } finally { + // Only finish when the stream completed naturally. + // If the SSE failed (network/auth error), let the polling + // fallback continue running so it can detect completion. + if (streamCompleted && !controller.signal.aborted) { + finish() } - })() + } + })() // Polling failsafe: if SSE fails or is slow, periodically // check the DB for the completed message @@ -1090,19 +1090,32 @@ export function AgentSessionContent({ deleteModalId, - Voulez-vous supprimer cette session ? + + Voulez-vous supprimer cette session ? + - Cette action supprimera définitivement la conversation et son historique. Cette action est irréversible. + Cette action supprimera définitivement la + conversation et son historique. Cette action est + irréversible. - , @@ -1127,7 +1140,7 @@ export function AgentSessionContent({ @@ -1205,9 +1218,9 @@ export function AgentSessionContent({ yearsData === undefined ? [] : yearsData.map((year) => ({ - key: year.id, - label: year.label, - })) + key: year.id, + label: year.label, + })) } />
diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx index 3ce5f766..fb06013d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/OrganizationApiGeneralPage.tsx @@ -1,8 +1,8 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { IconBook2 } from "@tabler/icons-react" +import { LinkButton } from "../../../../components/LinkButton.tsx" import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" -import { LinkButton } from "../../../../components/LinkButton.tsx" export function OrganizationApiGeneralPage() { return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx index 7ef43b2d..587bc3d6 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationApi/keys/DeleteOneApiKey.tsx @@ -50,15 +50,25 @@ export function DeleteOneApiKey(props: { - Cette action est irréversible. Les applications utilisant cette clé ne pourront plus accéder à l'API. + Cette action est irréversible. Les applications utilisant cette clé ne pourront plus + accéder à l'API. - , diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx index b7c34500..e118ce68 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/CancelSubscription.tsx @@ -48,17 +48,26 @@ export function CancelSubscription(_props: { idOrganization: string }) { - Votre accès Premium sera maintenu jusqu'à la fin de la période en cours. - Aucun nouveau paiement ne sera prélevé. - Vous pourrez vous abonner de nouveau à tout moment. + Votre accès Premium sera maintenu jusqu'à la fin de la période en cours. Aucun nouveau + paiement ne sera prélevé. Vous pourrez vous abonner de nouveau à tout moment. - , diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx index 56d84f5e..e83e115b 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/ResumeSubscription.tsx @@ -53,8 +53,17 @@ export function ResumeSubscription() { - , diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx index 7d736953..f996dad2 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateLicencePage.tsx @@ -145,7 +145,13 @@ function UpdateLicenceForm(props: { idOrganization: string; currentAmountInCents - @@ -160,7 +166,6 @@ function UpdateLicenceForm(props: { idOrganization: string; currentAmountInCents text={isSaving ? "Enregistrement..." : "Enregistrer"} /> -
) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx index 1c577b4b..51b91953 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateOcrPage.tsx @@ -262,8 +262,17 @@ function UpdateOcrForm(props: { idOrganization: string; currentQuantity: number; - , @@ -300,8 +309,8 @@ export function UpdateOcrPage({ idOrganization }: { idOrganization: string }) { idOrganization={idOrganization} currentQuantity={Math.max( organization.ocrPagesTotalAvailable + - organization.ocrPagesTotalUsed - - INCLUDED_OCR_PAGES, + organization.ocrPagesTotalUsed - + INCLUDED_OCR_PAGES, 0, )} currentPagesLeft={organization.ocrPagesTotalAvailable} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx index 33439f01..9e3bfed7 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateStoragePage.tsx @@ -179,8 +179,8 @@ function UpdateStorageForm(props: { {quantityDelta > 0 ? `Augmenter le stockage est immédiat : le montant prorata du mois est débité du portefeuille. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` : quantityDelta < 0 - ? `Réduire le stockage est effectif le 1er du mois prochain. Aucun remboursement n'est appliqué. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` - : `Ajustez le stockage disponible pour l'organisation. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).`} + ? `Réduire le stockage est effectif le 1er du mois prochain. Aucun remboursement n'est appliqué. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).` + : `Ajustez le stockage disponible pour l'organisation. Montants en HT (TVA ${VAT_PERCENT}\u00a0%).`}

0 ? "warning/5" : deltaAmountInCents < 0 - ? "success/5" - : "neutral/1", + ? "success/5" + : "neutral/1", })} > 0 ? "Débité maintenant (prorata)" : deltaAmountInCents < 0 - ? "Effectif le 1er du mois" - : "Ajustement portefeuille"} + ? "Effectif le 1er du mois" + : "Ajustement portefeuille"} closeModal(confirmModalId)}> - @@ -445,7 +451,6 @@ function UpdateStorageForm(props: { text="Enregistrer le stockage" /> - ) } diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx index 0bd8c0f9..b489b95d 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/UpdateTokensPage.tsx @@ -278,8 +278,17 @@ function UpdateTokensForm(props: { idOrganization: string; currentQuantity: numb - , @@ -317,7 +326,7 @@ export function UpdateTokensPage({ idOrganization }: { idOrganization: string }) (organization.tokensTotalAvailable + organization.tokensTotalUsed - INCLUDED_AGENT_TOKENS) / - INCLUDED_AGENT_TOKENS, + INCLUDED_AGENT_TOKENS, ), 0, )} diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx index 8fa61d69..74601692 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/invoices/OrganizationInvoicePage.tsx @@ -78,7 +78,9 @@ function InvoiceTabsContent(props: { export function OrganizationInvoicePage() { const params = useParams({ strict: false, - }) as { idInvoice?: string } + }) as { + idInvoice: string + } return ( diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx index 12c9349d..03b69305 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationSettings/DeleteOneOrganization.tsx @@ -57,16 +57,25 @@ export function DeleteOneOrganization(props: { - Cette action supprimera l'organisation et toutes les données associées. - Cette action est irréversible. + Cette action supprimera l'organisation et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx index f07e0df3..4671198a 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationUsers/$idOrganizationUser/DeleteOneOrganizationUser.tsx @@ -60,8 +60,17 @@ export function DeleteOneOrganizationUser(props: { - , diff --git a/packages/website/src/features/dashboard/$idYear/YearDataProvider.tsx b/packages/website/src/features/dashboard/$idYear/YearDataProvider.tsx index f4bf6d47..a4dd6243 100644 --- a/packages/website/src/features/dashboard/$idYear/YearDataProvider.tsx +++ b/packages/website/src/features/dashboard/$idYear/YearDataProvider.tsx @@ -144,5 +144,3 @@ export function YearDataProvider(props: { idYear: string; children: ReactNode }) return {props.children} } - - diff --git a/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx b/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx index d2621adc..23892d36 100644 --- a/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx +++ b/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx @@ -76,7 +76,12 @@ const yearQueryEntries = Object.entries(yearQueries) as [ ][] // Stable index for dereferencing results by key name (avoids magic numbers). -const KEY_INDEX = Object.fromEntries(yearQueryEntries.map(([key], i) => [key, i])) as Record +const KEY_INDEX = Object.fromEntries( + yearQueryEntries.map(([key], i) => [ + key, + i, + ]), +) as Record export function YearDataWrapper(props: { idYear: string @@ -87,12 +92,17 @@ export function YearDataWrapper(props: { () => ({ idYear: props.idYear, }), - [props.idYear], + [ + props.idYear, + ], ) const results = useQueries({ queries: yearQueryEntries.map(([_key, routeDef]) => ({ - queryKey: [routeDef.path, body], + queryKey: [ + routeDef.path, + body, + ], queryFn: async (context: { signal: AbortSignal }) => { const response = await getResponseBodyFromAPI({ routeDefinition: routeDef, @@ -113,7 +123,9 @@ export function YearDataWrapper(props: { const requiredIndices = useMemo( () => props.requiredKeys.map((key) => KEY_INDEX[key]), - [props.requiredKeys], + [ + props.requiredKeys, + ], ) const isPending = requiredIndices.some((index) => results[index].isPending) @@ -132,7 +144,9 @@ export function YearDataWrapper(props: { const balanceSheetsData = results[KEY_INDEX.balanceSheets].data as YearData["balanceSheets"] | undefined const incomeStatementsData = results[KEY_INDEX.incomeStatements].data as YearData["incomeStatements"] | undefined const computationsData = results[KEY_INDEX.computations].data as YearData["computations"] | undefined - const computationIncomeStatementsData = results[KEY_INDEX.computationIncomeStatements].data as YearData["computationIncomeStatements"] | undefined + const computationIncomeStatementsData = results[KEY_INDEX.computationIncomeStatements].data as + | YearData["computationIncomeStatements"] + | undefined // Memoized raw-array object — reference stable as long as query data references don't change. // eslint-disable-next-line react-hooks/exhaustive-deps @@ -175,81 +189,111 @@ export function YearDataWrapper(props: { const m = new Map() for (const e of arrays.entries) m.set(e.id, e) return m - }, [arrays.entries]) + }, [ + arrays.entries, + ]) const entryLinesByEntryId = useMemo(() => { const m = new Map>() for (const line of arrays.entryLines) { const arr = m.get(line.idEntry) if (arr) arr.push(line) - else m.set(line.idEntry, [line]) + else + m.set(line.idEntry, [ + line, + ]) } return m - }, [arrays.entryLines]) + }, [ + arrays.entryLines, + ]) const entryTagsByEntryId = useMemo(() => { const m = new Map>() for (const et of arrays.entryTags) { const arr = m.get(et.idEntry) if (arr) arr.push(et) - else m.set(et.idEntry, [et]) + else + m.set(et.idEntry, [ + et, + ]) } return m - }, [arrays.entryTags]) + }, [ + arrays.entryTags, + ]) const journalById = useMemo(() => { const m = new Map() for (const j of arrays.journals) m.set(j.id, j) return m - }, [arrays.journals]) + }, [ + arrays.journals, + ]) const tagById = useMemo(() => { const m = new Map() for (const t of arrays.tags) m.set(t.id, t) return m - }, [arrays.tags]) + }, [ + arrays.tags, + ]) const fileById = useMemo(() => { const m = new Map() for (const f of arrays.files) m.set(f.id, f) return m - }, [arrays.files]) + }, [ + arrays.files, + ]) const folderById = useMemo(() => { const m = new Map() for (const f of arrays.folders) m.set(f.id, f) return m - }, [arrays.folders]) + }, [ + arrays.folders, + ]) const accountById = useMemo(() => { const m = new Map() for (const a of arrays.accounts) m.set(a.id, a) return m - }, [arrays.accounts]) + }, [ + arrays.accounts, + ]) const accountByNumber = useMemo(() => { const m = new Map() for (const a of arrays.accounts) m.set(a.number, a) return m - }, [arrays.accounts]) + }, [ + arrays.accounts, + ]) const balanceSheetById = useMemo(() => { const m = new Map() for (const bs of arrays.balanceSheets) m.set(bs.id, bs) return m - }, [arrays.balanceSheets]) + }, [ + arrays.balanceSheets, + ]) const incomeStatementById = useMemo(() => { const m = new Map() for (const is of arrays.incomeStatements) m.set(is.id, is) return m - }, [arrays.incomeStatements]) + }, [ + arrays.incomeStatements, + ]) const computationById = useMemo(() => { const m = new Map() for (const c of arrays.computations) m.set(c.id, c) return m - }, [arrays.computations]) + }, [ + arrays.computations, + ]) const maps: YearDataMaps = useMemo( () => ({ @@ -309,4 +353,3 @@ export function YearDataWrapper(props: { ...maps, }) } - diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx index 7317ca04..891d1dd6 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/DeleteOneEntryLine.tsx @@ -76,16 +76,25 @@ export function DeleteOneEntryLine(props: { - Cette action supprimera le mouvement et toutes les données associées. - Cette action est irréversible. + Cette action supprimera le mouvement et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx index afd26269..a5ea07ee 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineLayout.tsx @@ -3,11 +3,11 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Page } from "../../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DeleteOneEntryLine } from "./DeleteOneEntryLine.tsx" import { UpdateOneEntryLine } from "./UpdateOneEntryLine.tsx" @@ -15,7 +15,12 @@ import { UpdateOneEntryLine } from "./UpdateOneEntryLine.tsx" export function EntryLineLayout() { const params = useParams({ strict: false, - }) as { idYear?: string; idEntryLine?: string } + }) as { + idYear: string + idEntryLine: string + idOrganization: string + idEntry: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx index 9b6d6743..58c71758 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/$idEntryLine/EntryLineMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneEntryLineRouteDefinition } from "@arrhes/application-metadata/ro import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" - export function EntryLineMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idEntryLine?: string } + }) as { + idYear: string + idEntryLine: string + } return ( - Cette action supprimera l'écriture et toutes les données associées. - Cette action est irréversible. + Cette action supprimera l'écriture et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx index cf597d7a..b8e0b4f3 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryInformationsTab.tsx @@ -5,9 +5,8 @@ import { IconPencil } from "@tabler/icons-react" import type * as v from "valibot" import { DataBlock } from "../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" -import { UpdateOneEntry } from "./UpdateOneEntry.tsx" import { useTabs } from "../../../../../contexts/tabs/useTabs.tsx" - +import { UpdateOneEntry } from "./UpdateOneEntry.tsx" export function EntryInformationsTab(props: { entry: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx index 60249379..38a65b20 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLayout.tsx @@ -13,10 +13,10 @@ import { } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" import { useState } from "react" +import { LinkButton } from "../../../../../components/LinkButton.js" import { Banner } from "../../../../../components/layouts/Banner.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../components/LinkButton.js" import { Popover } from "../../../../../components/overlays/popover/popover.js" import { compareAmounts } from "../../../../../utilities/compareAmounts.ts" @@ -39,7 +39,11 @@ const requiredKeys = [ export function EntryLayout() { const params = useParams({ strict: false, - }) as { idOrganization?: string; idYear?: string; idEntry?: string } + }) as { + idOrganization: string + idYear: string + idEntry: string + } const [menuOpen, setMenuOpen] = useState(false) return ( diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx index 178fd312..b1a78f8c 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTab.tsx @@ -17,11 +17,7 @@ const requiredKeys = [ "accounts", ] as const satisfies readonly YearDataKey[] -export function EntryLinesTab(props: { - idYear: string - idEntry: string -}) { - +export function EntryLinesTab(props: { idYear: string; idEntry: string }) { const idYear = props.idYear const idEntry = props.idEntry diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTable.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTable.tsx index fe74d2cc..0acc68ce 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryLinesTable.tsx @@ -4,8 +4,8 @@ import { ButtonGhostContent, FormatDateTime, FormatNull, FormatPrice, FormatText import { css } from "@arrhes/ui/utilities/cn.js" import { IconEye, IconPencil } from "@tabler/icons-react" import type * as v from "valibot" -import { DataTable } from "../../../../../components/layouts/DataTable.tsx" import { LinkButton } from "../../../../../components/LinkButton.tsx" +import { DataTable } from "../../../../../components/layouts/DataTable.tsx" import { UpdateOneEntryLine } from "./$idEntryLine/UpdateOneEntryLine.tsx" export function EntryLinesTable(props: { diff --git a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx index 9ced18f3..941293ff 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/$idEntry/EntryRoutePage.tsx @@ -1,7 +1,7 @@ import { useParams } from "@tanstack/react-router" import type { YearDataKey } from "../../YearDataWrapper.js" import { YearDataWrapper } from "../../YearDataWrapper.js" -import { EntryPage } from "./EntryPage.js" +import { EntryInformationsTab } from "./EntryInformationsTab.js" const routeRequiredKeys = [ "entries", @@ -14,7 +14,12 @@ const routeRequiredKeys = [ // Used by TanStack Router as a standalone route component — resolves data itself via YearDataWrapper. export function EntryRoutePage() { - const params = useParams({ strict: false }) as { idYear?: string; idEntry?: string } + const params = useParams({ + strict: false, + }) as { + idYear?: string + idEntry?: string + } const idYear = params.idYear ?? "" const idEntry = params.idEntry ?? "" @@ -45,7 +50,7 @@ export function EntryRoutePage() { } return ( - - children: JSX.Element -}) { +export function UpdateOneEntry(props: { entry: v.InferOutput; children: JSX.Element }) { const { openPanelTab, closeTab } = useTabs() return ( diff --git a/packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx b/packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx index ae06a27e..1c836cfa 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/EntriesTable.tsx @@ -1,7 +1,4 @@ -import type { - readAllAccountsRouteDefinition, - readAllEntriesRouteDefinition, -} from "@arrhes/application-metadata/routes" +import type { readAllAccountsRouteDefinition, readAllEntriesRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { Button, FormatDate, FormatDateTime, FormatNull, FormatPrice, FormatText, LinkContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" @@ -40,10 +37,15 @@ export function EntriesTable(props: { const tagsByEntry = useMemo(() => { const m = new Map() for (const [entryId, ets] of props.entryTagsByEntryId) { - m.set(entryId, ets.map((et) => et.idTag)) + m.set( + entryId, + ets.map((et) => et.idTag), + ) } return m - }, [props.entryTagsByEntryId]) + }, [ + props.entryTagsByEntryId, + ]) const filesMap = props.fileById const accountsMap = props.accountById diff --git a/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx index 8e9a1e19..712b80b3 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/EntriesTableSelectionActions.tsx @@ -1,5 +1,13 @@ import { deleteOneEntryRouteDefinition, readAllEntriesRouteDefinition } from "@arrhes/application-metadata/routes" -import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { + Button, + ButtonGhostContent, + ButtonOutlineContent, + ButtonPlainContent, + Dialog, + toast, + useModalStore, +} from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronDown, IconTrash } from "@tabler/icons-react" import type { Row } from "@tanstack/react-table" @@ -78,16 +86,27 @@ export function EntriesTableSelectionActions(props: { selectedRows: Array - {`Voulez-vous supprimer ${props.selectedRows.length} écriture${props.selectedRows.length > 1 ? "s" : "" - } ? Cette action est irréversible.`} + {`Voulez-vous supprimer ${props.selectedRows.length} écriture${ + props.selectedRows.length > 1 ? "s" : "" + } ? Cette action est irréversible.`} - , @@ -107,7 +126,6 @@ export function EntriesTableSelectionActions(props: { selectedRows: Array - ) } diff --git a/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx b/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx index 7e445d1e..8af98a01 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/ReverseOneEntry.tsx @@ -91,7 +91,13 @@ export function ReverseOneEntry(props: { - diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx index 2430c6f8..907b09df 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/DeleteOneFile.tsx @@ -59,16 +59,25 @@ export function DeleteOneFile(props: { - Cette action supprimera le fichier et toutes les données associées. - Cette action est irréversible. + Cette action supprimera le fichier et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx index a37443c3..7d991552 100644 --- a/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/$idFile/FileLayout.tsx @@ -2,10 +2,10 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconEye, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../components/LinkButton.tsx" import { Page } from "../../../../../components/layouts/page/page.tsx" import { Section } from "../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../components/LinkButton.tsx" import { DeleteOneFile } from "./DeleteOneFile.tsx" import { FileData } from "./FileData.tsx" @@ -14,7 +14,10 @@ import { UpdateOneFile } from "./UpdateOneFile.tsx" export function FileLayout() { const params = useParams({ strict: false, - }) as { idOrganization?: string; idFile?: string } + }) as { + idOrganization: string + idFile: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx index a25856bc..82e36845 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx @@ -4,7 +4,15 @@ import { readOrganizationBillingRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Separator, toast, useModalStore } from "@arrhes/ui" +import { + Button, + ButtonGhostContent, + ButtonOutlineContent, + ButtonPlainContent, + Separator, + toast, + useModalStore, +} from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconFileText, IconPencil, IconTrash } from "@tabler/icons-react" import { useId, useState } from "react" @@ -278,8 +286,17 @@ export function FileActions(props: { file: v.InferOutput closeModal(deleteModalId)}> - , diff --git a/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx index bb34ad68..a5c4303c 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx @@ -128,16 +128,25 @@ export function FileContextMenu(props: { - Cette action supprimera le fichier et toutes les données associées. - Cette action est irréversible. + Cette action supprimera le fichier et toutes les données associées. Cette + action est irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx index b412c4a1..19002606 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesPage.tsx @@ -20,10 +20,14 @@ import { FilesPageContent } from "./FilesPageContent.js" export function FilesPage() { const params = useParams({ strict: false, - }) as { idOrganization?: string } + }) as { + idOrganization: string + } const { idFolder } = useSearch({ strict: false, - }) as { idFolder?: string } + }) as { + idFolder?: string + } const navigate = useNavigate() // Current folder is derived from the URL search param @@ -34,8 +38,8 @@ export function FilesPage() { to: ".", search: folderId ? { - idFolder: folderId, - } + idFolder: folderId, + } : {}, }) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx index 865c6688..13a58d83 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx @@ -4,7 +4,15 @@ import { readAllFilesRouteDefinition, readAllFoldersRouteDefinition, } from "@arrhes/application-metadata/routes" -import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Dialog, toast, useModalStore } from "@arrhes/ui" +import { + Button, + ButtonGhostContent, + ButtonOutlineContent, + ButtonPlainContent, + Dialog, + toast, + useModalStore, +} from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronDown, IconTrash } from "@tabler/icons-react" import type { Row } from "@tanstack/react-table" @@ -17,16 +25,16 @@ import { deleteFileWithSignedUrl } from "./deleteFileWithSignedUrl.js" export type TableRow = | { - kind: "back" - } + kind: "back" + } | { - kind: "folder" - data: v.InferOutput - } + kind: "folder" + data: v.InferOutput + } | { - kind: "file" - data: v.InferOutput - } + kind: "file" + data: v.InferOutput + } export function FilesTableSelectionActions(props: { selectedRows: Array> }) { const deleteModalId = useId() @@ -131,16 +139,27 @@ export function FilesTableSelectionActions(props: { selectedRows: Array - {`Voulez-vous supprimer ${props.selectedRows.length} élément${props.selectedRows.length > 1 ? "s" : "" - } ? Cette action est irréversible.`} + {`Voulez-vous supprimer ${props.selectedRows.length} élément${ + props.selectedRows.length > 1 ? "s" : "" + } ? Cette action est irréversible.`} - , @@ -160,7 +179,6 @@ export function FilesTableSelectionActions(props: { selectedRows: Array - ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx index 5250d06e..85f9055c 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx @@ -1,6 +1,14 @@ import { deleteOneFolderRouteDefinition, readAllFoldersRouteDefinition } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonGhostContent, ButtonOutlineContent, ButtonPlainContent, Separator, toast, useModalStore } from "@arrhes/ui" +import { + Button, + ButtonGhostContent, + ButtonOutlineContent, + ButtonPlainContent, + Separator, + toast, + useModalStore, +} from "@arrhes/ui" import { css } from "@arrhes/ui/css" import { IconArrowsMove, IconDotsVertical, IconEye, IconPencil, IconTrash } from "@tabler/icons-react" import { useId } from "react" @@ -170,17 +178,26 @@ export function FolderActions(props: { - Cette action supprimera le dossier et tous ses sous-dossiers. - Les fichiers contenus ne seront pas supprimés. - Cette action est irréversible. + Cette action supprimera le dossier et tous ses sous-dossiers. Les + fichiers contenus ne seront pas supprimés. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx index 32776745..38af5f30 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx @@ -116,17 +116,25 @@ export function FolderContextMenu(props: { - Cette action supprimera le dossier et tous ses sous-dossiers. - Les fichiers contenus ne seront pas supprimés. - Cette action est irréversible. + Cette action supprimera le dossier et tous ses sous-dossiers. Les fichiers + contenus ne seront pas supprimés. Cette action est irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx b/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx index aecf0cfc..a4dd6243 100644 --- a/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearDataContext.tsx @@ -46,8 +46,8 @@ type YearScopedRouteDefinition = { schemas: { body: v.ObjectSchema return: - | v.ObjectSchema - | v.ArraySchema, undefined> + | v.ObjectSchema + | v.ArraySchema, undefined> } } @@ -144,5 +144,3 @@ export function YearDataProvider(props: { idYear: string; children: ReactNode }) return {props.children} } - - diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx index bfb98ab5..c581163d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/DeleteOneYear.tsx @@ -65,16 +65,25 @@ export function DeleteOneYear(props: { - Cette action supprimera l'exercice et toutes les données associées. - Cette action est irréversible. + Cette action supprimera l'exercice et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx index 93502704..a41f57cd 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/YearSettingsPage.tsx @@ -3,8 +3,8 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { IconPencil, IconTrash } from "@tabler/icons-react" import { useParams } from "@tanstack/react-router" import { DataWrapper } from "../../../../components/layouts/DataWrapper.tsx" -import { Page } from "../../../../components/layouts/page/page.tsx" import { PageRoot } from "../../../../components/layouts/page/PageRoot.tsx" +import { Page } from "../../../../components/layouts/page/page.tsx" import { SettingsSection } from "../../../../components/layouts/settingsSection/settingsSection.tsx" import { DeleteOneYear } from "./DeleteOneYear.tsx" import { UpdateOneYear } from "./UpdateOneYear.tsx" diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx index da76805a..5e9f17b7 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountLayout.tsx @@ -3,10 +3,10 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DeleteOneAccount } from "./DeleteOneAccount.tsx" import { UpdateOneAccount } from "./UpdateOneAccount.tsx" @@ -14,7 +14,11 @@ import { UpdateOneAccount } from "./UpdateOneAccount.tsx" export function AccountLayout() { const params = useParams({ strict: false, - }) as { idYear?: string; idAccount?: string } + }) as { + idYear: string + idAccount: string + idOrganization: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx index f0a00991..02b0ab52 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/AccountMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneAccountRouteDefinition } from "@arrhes/application-metadata/rout import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" - export function AccountMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idAccount?: string } + }) as { + idYear: string + idAccount: string + } return ( - Cette action supprimera le compte et toutes les données associées. - Cette action est irréversible. + Cette action supprimera le compte et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx index 0125b888..b63c5559 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/accounts/$idAccount/UpdateOneAccount.tsx @@ -201,7 +201,7 @@ export function UpdateOneAccount(props: { diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx index 9fe3ed5e..7b9f0b02 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/balanceSheets/$idBalanceSheet/BalanceSheetMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneBalanceSheetRouteDefinition } from "@arrhes/application-metadata import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" - export function BalanceSheetMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idBalanceSheet?: string } + }) as { + idYear: string + idBalanceSheet: string + } return ( - Cette action supprimera la ligne de bilan et toutes les données associées. - Cette action est irréversible. + Cette action supprimera la ligne de bilan et toutes les données associées. Cette action + est irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx index 5b78416e..bc3cf8db 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/DeleteOneIncomeStatement.tsx @@ -74,8 +74,17 @@ export function DeleteOneIncomeStatement(props: { - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx index b9c28fbb..650432e9 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementLayout.tsx @@ -3,10 +3,10 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DeleteOneIncomeStatement } from "./DeleteOneIncomeStatement.tsx" import { UpdateOneIncomeStatement } from "./UpdateOneIncomeStatement.tsx" @@ -14,7 +14,11 @@ import { UpdateOneIncomeStatement } from "./UpdateOneIncomeStatement.tsx" export function IncomeStatementLayout() { const params = useParams({ strict: false, - }) as { idYear?: string; idIncomeStatement?: string } + }) as { + idYear: string + idIncomeStatement: string + idOrganization: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx index 092ae075..f013b70c 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/$idIncomeStatement/IncomeStatementMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneIncomeStatementRouteDefinition } from "@arrhes/application-metad import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" - export function IncomeStatementMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idIncomeStatement?: string } + }) as { + idYear: string + idIncomeStatement: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx index 3da1d3ab..5d370d69 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/ComputationMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneComputationRouteDefinition } from "@arrhes/application-metadata/ import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../../components/layouts/section/section.tsx" - export function ComputationMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idComputation?: string } + }) as { + idYear: string + idComputation: string + } return ( - Cette action supprimera la ligne de calcul et toutes les données associées. - Cette action est irréversible. + Cette action supprimera la ligne de calcul et toutes les données associées. Cette action + est irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx index 0237408d..e7b9b71d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementLayout.tsx @@ -3,10 +3,10 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../../../../components/LinkButton.tsx" import { DeleteOneComputationIncomeStatement } from "./DeleteOneComputationIncomeStatement.tsx" import { UpdateOneComputationIncomeStatement } from "./UpdateOneComputationIncomeStatement.tsx" @@ -14,7 +14,12 @@ import { UpdateOneComputationIncomeStatement } from "./UpdateOneComputationIncom export function ComputationIncomeStatementLayout() { const params = useParams({ strict: false, - }) as { idYear?: string; idComputationIncomeStatement?: string } + }) as { + idYear: string + idComputationIncomeStatement: string + idOrganization: string + idComputation: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx index 26349120..9c177b8f 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/ComputationIncomeStatementMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneComputationIncomeStatementRouteDefinition } from "@arrhes/applic import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../../../../components/layouts/section/section.tsx" - export function ComputationIncomeStatementMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idComputationIncomeStatement?: string } + }) as { + idYear: string + idComputationIncomeStatement: string + } return ( closeModal(modalId)}> - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx index f1c1cb22..665c7962 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/$idComputation/computationIncomeStatements/ComputationIncomeStatementsTable.tsx @@ -6,9 +6,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { ButtonGhostContent, Chip, FormatDateTime, FormatText } from "@arrhes/ui" import { IconEye } from "@tabler/icons-react" import type * as v from "valibot" +import { LinkButton } from "../../../../../../../../components/LinkButton.tsx" import { DataTable } from "../../../../../../../../components/layouts/DataTable.tsx" import { DataWrapper } from "../../../../../../../../components/layouts/DataWrapper.tsx" -import { LinkButton } from "../../../../../../../../components/LinkButton.tsx" export function ComputationIncomeStatementsTable(props: { computation: v.InferOutput diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx index 6dbb4dc9..6e8cead1 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsPage.tsx @@ -12,7 +12,10 @@ import { CreateOneComputation } from "./CreateOneComputation.tsx" export function ComputationsPage() { const params = useParams({ strict: false, - }) as { idYear?: string } + }) as { + idYear: string + idOrganization: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx index 5e01d433..ce0abba3 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/incomeStatements/computations/ComputationsTable.tsx @@ -3,9 +3,9 @@ import type { returnedSchemas } from "@arrhes/application-metadata/schemas" import { css } from "@arrhes/ui/utilities/cn.js" import { IconCalculator } from "@tabler/icons-react" import type * as v from "valibot" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { EmptyState } from "../../../../../../components/layouts/EmptyState.tsx" -import { LinkButton } from "../../../../../../components/LinkButton.tsx" export function ComputationsTable(props: { idOrganization: v.InferOutput["id"] diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx index 1d03f62b..c692758a 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/DeleteOneJournal.tsx @@ -63,16 +63,25 @@ export function DeleteOneJournal(props: { - Cette action supprimera le journal et toutes les données associées. - Cette action est irréversible. + Cette action supprimera le journal et toutes les données associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx index f1045a19..50b180c1 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalLayout.tsx @@ -3,10 +3,10 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DeleteOneJournal } from "./DeleteOneJournal.tsx" import { UpdateOneJournal } from "./UpdateOneJournal.tsx" @@ -14,7 +14,11 @@ import { UpdateOneJournal } from "./UpdateOneJournal.tsx" export function JournalLayout() { const params = useParams({ strict: false, - }) as { idYear?: string; idJournal?: string } + }) as { + idYear: string + idJournal: string + idOrganization: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx index 8a866a72..66146b55 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/journals/$idJournal/JournalMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneJournalRouteDefinition } from "@arrhes/application-metadata/rout import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" - export function JournalMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idJournal?: string } + }) as { + idYear: string + idJournal: string + } return ( , - props.journal.label, + props.journal.label ?? undefined, ) }} > diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx index 97171de5..43909ba2 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/DeleteOneTag.tsx @@ -63,16 +63,25 @@ export function DeleteOneTag(props: { - Cette action supprimera la catégorie et toutes ses mentions associées. - Cette action est irréversible. + Cette action supprimera la catégorie et toutes ses mentions associées. Cette action est + irréversible. - , diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx index 1b1c0bc1..7ae9ea1d 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagLayout.tsx @@ -3,10 +3,10 @@ import { ButtonOutlineContent, ButtonPlainContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronLeft, IconDatabase, IconInfoCircle, IconPencil, IconTrash } from "@tabler/icons-react" import { Outlet, useParams } from "@tanstack/react-router" +import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" import { Tab } from "../../../../../../components/layouts/tab/tab.tsx" -import { LinkButton } from "../../../../../../components/LinkButton.tsx" import { DeleteOneTag } from "./DeleteOneTag.tsx" import { UpdateOneTag } from "./UpdateOneTag.tsx" @@ -14,7 +14,11 @@ import { UpdateOneTag } from "./UpdateOneTag.tsx" export function TagLayout() { const params = useParams({ strict: false, - }) as { idYear?: string; idTag?: string } + }) as { + idYear: string + idTag: string + idOrganization: string + } return ( diff --git a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx index d4cf61e2..a3152748 100644 --- a/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx +++ b/packages/website/src/features/dashboard/$idYear/yearSettings/tags/$idTag/TagMetadataTab.tsx @@ -2,15 +2,17 @@ import { readOneTagRouteDefinition } from "@arrhes/application-metadata/routes" import { FormatDateTime, FormatText } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { useParams } from "@tanstack/react-router" -import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { DataWrapper } from "../../../../../../components/layouts/DataWrapper.tsx" +import { DataBlock } from "../../../../../../components/layouts/dataBlock/dataBlock.tsx" import { Section } from "../../../../../../components/layouts/section/section.tsx" - export function TagMetadataTab() { const params = useParams({ strict: false, - }) as { idYear?: string; idTag?: string } + }) as { + idYear: string + idTag: string + } return ( void }) { @@ -29,7 +29,10 @@ export function OrganizationContextSelect(props: { value: string | null; onChang } return ( - + ) } diff --git a/packages/ui/src/components/inputs/InputToggle.tsx b/packages/ui/src/components/inputs/InputToggle.tsx index f1670a83..69da2133 100644 --- a/packages/ui/src/components/inputs/InputToggle.tsx +++ b/packages/ui/src/components/inputs/InputToggle.tsx @@ -1,11 +1,10 @@ -import type * as SwitchPrimitives from "@radix-ui/react-switch" -import type { ComponentProps, JSX } from "react" +import type { ButtonHTMLAttributes, JSX } from "react" import { css, cx } from "../../utilities/cn.js" import { Button } from "../buttons/Button.js" import { ButtonGhostContent } from "../buttons/ButtonGhostContent.js" export function InputToggle( - props: Omit, "value" | "onChange"> & { + props: Omit, "value" | "onChange"> & { value: TValue | null | undefined onChange: (value: TValue | null | undefined) => void options: Array<{ diff --git a/packages/website/package.json b/packages/website/package.json index 8c5dbc42..715cb723 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -23,9 +23,6 @@ "@arrhes/application-metadata": "workspace:*", "@arrhes/ui": "workspace:*", "@hookform/resolvers": "5.2.2", - "@radix-ui/react-context-menu": "2.2.16", - "@radix-ui/react-slot": "1.2.4", - "@radix-ui/react-tooltip": "1.2.8", "@react-pdf/renderer": "4.5.1", "@tabler/icons-react": "3.42.0", "@tanstack/react-query": "5.100.9", @@ -53,4 +50,4 @@ "last 1 safari version" ] } -} \ No newline at end of file +} diff --git a/packages/website/plugins/DOC_PAGE_MANIFEST.ts b/packages/website/plugins/DOC_PAGE_MANIFEST.ts new file mode 100644 index 00000000..011335e3 --- /dev/null +++ b/packages/website/plugins/DOC_PAGE_MANIFEST.ts @@ -0,0 +1,337 @@ +import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" +import { dirname, resolve } from "node:path" +import react from "@vitejs/plugin-react" +import { defineConfig, type Plugin, build as viteBuild } from "vite" + +// ─────────────────────────── Docs Search Index Plugin ───────────────────────────── + +interface DocPageManifestEntry { + path: string + file: string // relative from package root + section: string + navGroup: string + navLabel: string +} + +// Maps every static doc page route to its source file and nav metadata. +// Content strings are extracted automatically from the TSX source at build time. +export const DOC_PAGE_MANIFEST: DocPageManifestEntry[] = [ + // ── Général / Introduction ──────────────────────────────────────────────── + { + path: "/documentation", + file: "src/features/docs/general/rootGeneralDocPage.tsx", + section: "Général", + navGroup: "Introduction", + navLabel: "Accueil", + }, + { + path: "/documentation/fonctionnalités", + file: "src/features/docs/general/features/featuresGeneralDocPage.tsx", + section: "Général", + navGroup: "Introduction", + navLabel: "Fonctionnalités", + }, + { + path: "/documentation/philosophie", + file: "src/features/docs/general/whitepaperGeneralDocPage.tsx", + section: "Général", + navGroup: "Introduction", + navLabel: "Philosophie", + }, + { + path: "/documentation/tarifs", + file: "src/features/docs/general/pricing/pricingGeneralDocPage.tsx", + section: "Général", + navGroup: "Introduction", + navLabel: "Tarifs", + }, + { + path: "/documentation/support", + file: "src/features/docs/general/supportGeneralDocPage.tsx", + section: "Général", + navGroup: "Introduction", + navLabel: "Support", + }, + // ── Général / Légal ─────────────────────────────────────────────────────── + { + path: "/documentation/mentions-légales", + file: "src/features/docs/general/legalGeneralDocPage.tsx", + section: "Général", + navGroup: "Légal", + navLabel: "Mentions légales", + }, + { + path: "/documentation/cgu", + file: "src/features/docs/general/termsGeneralDocPage.tsx", + section: "Général", + navGroup: "Légal", + navLabel: "Conditions Générales d'Utilisation", + }, + { + path: "/documentation/confidentialité", + file: "src/features/docs/general/privacyGeneralDocPage.tsx", + section: "Général", + navGroup: "Légal", + navLabel: "Politique de confidentialité", + }, + // ── Comptabilité / Introduction ─────────────────────────────────────────── + { + path: "/documentation/comptabilité", + file: "src/features/docs/accounting/introduction/rootAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Introduction", + navLabel: "Accueil", + }, + { + path: "/documentation/comptabilité/introduction", + file: "src/features/docs/accounting/introduction/introductionAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Introduction", + navLabel: "Introduction", + }, + { + path: "/documentation/comptabilité/introduction/partie-double", + file: "src/features/docs/accounting/introduction/doubleEntryAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Introduction", + navLabel: "La partie double", + }, + { + path: "/documentation/comptabilité/introduction/écritures", + file: "src/features/docs/accounting/introduction/entriesAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Introduction", + navLabel: "Les écritures", + }, + // ── Comptabilité / Comptes ──────────────────────────────────────────────── + { + path: "/documentation/comptabilité/introduction/comptes", + file: "src/features/docs/accounting/introduction/accountsAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Comptes", + navLabel: "Introduction", + }, + { + path: "/documentation/comptabilité/introduction/classes", + file: "src/features/docs/accounting/introduction/classesAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Comptes", + navLabel: "Classes de comptes", + }, + { + path: "/documentation/comptabilité/ressources/comptes", + file: "src/features/docs/accounting/resources/accounts/accountsResourcesAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Comptes", + navLabel: "Liste des comptes", + }, + // ── Comptabilité / Documents ────────────────────────────────────────────── + { + path: "/documentation/comptabilité/documents", + file: "src/features/docs/accounting/reports/reportsAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Introduction", + }, + { + path: "/documentation/comptabilité/documents/journal", + file: "src/features/docs/accounting/reports/journalAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Journal", + }, + { + path: "/documentation/comptabilité/documents/grand-livre", + file: "src/features/docs/accounting/reports/ledgerAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Grand livre", + }, + { + path: "/documentation/comptabilité/documents/balance", + file: "src/features/docs/accounting/reports/balanceAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Balance", + }, + { + path: "/documentation/comptabilité/documents/bilan", + file: "src/features/docs/accounting/reports/balanceSheetAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Bilan", + }, + { + path: "/documentation/comptabilité/documents/compte-de-résultat", + file: "src/features/docs/accounting/reports/incomeStatementAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Compte de résultat", + }, + { + path: "/documentation/comptabilité/documents/annexe", + file: "src/features/docs/accounting/reports/notesAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "Annexe", + }, + { + path: "/documentation/comptabilité/documents/fec", + file: "src/features/docs/accounting/reports/fecAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Documents", + navLabel: "FEC", + }, + // ── Comptabilité / Scénarios ───────────────────────────────────────────── + { + path: "/documentation/comptabilité/ressources/scénarios", + file: "src/features/docs/accounting/resources/scenarios/scenariosResourcesAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Scénarios", + navLabel: "Scénarios", + }, + // ── Comptabilité / Glossaire ────────────────────────────────────────────── + { + path: "/documentation/comptabilité/ressources/glossaire", + file: "src/features/docs/accounting/resources/glossary/glossaryResourcesAccountingDocPage.tsx", + section: "Comptabilité", + navGroup: "Glossaire", + navLabel: "Glossaire", + }, + // ── Dashboard / Guide d'utilisation ────────────────────────────────────── + { + path: "/documentation/dashboard", + file: "src/features/docs/dashboard/rootDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Accueil", + }, + { + path: "/documentation/dashboard/démarrage", + file: "src/features/docs/dashboard/gettingStartedDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Démarrage", + }, + { + path: "/documentation/dashboard/organisations", + file: "src/features/docs/dashboard/organizationsDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Organisations", + }, + { + path: "/documentation/dashboard/exercices", + file: "src/features/docs/dashboard/yearsDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Exercices", + }, + { + path: "/documentation/dashboard/écritures", + file: "src/features/docs/dashboard/entriesDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Saisie des écritures", + }, + { + path: "/documentation/dashboard/stockage", + file: "src/features/docs/dashboard/filesDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Stockage", + }, + { + path: "/documentation/dashboard/documents", + file: "src/features/docs/dashboard/reportsDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Documents comptables", + }, + { + path: "/documentation/dashboard/facturation", + file: "src/features/docs/dashboard/BillingDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Facturation", + }, + { + path: "/documentation/dashboard/màj", + file: "src/features/docs/dashboard/UpdatesDashboardDocPage.tsx", + section: "Dashboard", + navGroup: "Guide d'utilisation", + navLabel: "Mises à jour", + }, + // ── Dashboard / Assistant IA ────────────────────────────────────────────── + { + path: "/documentation/dashboard/assistant", + file: "src/features/docs/ai/rootAiDocPage.tsx", + section: "Dashboard", + navGroup: "Assistant IA", + navLabel: "Introduction", + }, + { + path: "/documentation/dashboard/assistant/modèles", + file: "src/features/docs/ai/modelsAiDocPage.tsx", + section: "Dashboard", + navGroup: "Assistant IA", + navLabel: "Modèles", + }, + { + path: "/documentation/dashboard/assistant/outils", + file: "src/features/docs/ai/toolsAiDocPage.tsx", + section: "Dashboard", + navGroup: "Assistant IA", + navLabel: "Outils", + }, + { + path: "/documentation/dashboard/assistant/ocr", + file: "src/features/docs/ai/ocrAiDocPage.tsx", + section: "Dashboard", + navGroup: "Assistant IA", + navLabel: "OCR", + }, + // ── API ─────────────────────────────────────────────────────────────────── + { + path: "/documentation/api", + file: "src/features/docs/api/rootApiDocPage.tsx", + section: "API", + navGroup: "API", + navLabel: "Présentation", + }, + { + path: "/documentation/api/introduction", + file: "src/features/docs/api/introductionApiDocPage.tsx", + section: "API", + navGroup: "API", + navLabel: "Introduction", + }, + { + path: "/documentation/api/authentification", + file: "src/features/docs/api/authenticationApiDocPage.tsx", + section: "API", + navGroup: "API", + navLabel: "Authentification", + }, + { + path: "/documentation/api/organisation", + file: "src/features/docs/api/organizationApiDocPage.tsx", + section: "API", + navGroup: "API", + navLabel: "Organisation", + }, + { + path: "/documentation/api/exercice", + file: "src/features/docs/api/yearApiDocPage.tsx", + section: "API", + navGroup: "API", + navLabel: "Exercice", + }, + { + path: "/documentation/api/stockage", + file: "src/features/docs/api/filesApiDocPage.tsx", + section: "API", + navGroup: "API", + navLabel: "Fichiers et documents", + }, +] diff --git a/packages/website/plugins/docsSearchIndexPlugin.ts b/packages/website/plugins/docsSearchIndexPlugin.ts new file mode 100644 index 00000000..00847c13 --- /dev/null +++ b/packages/website/plugins/docsSearchIndexPlugin.ts @@ -0,0 +1,228 @@ +import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" +import { dirname, resolve } from "node:path" +import react from "@vitejs/plugin-react" +import { defineConfig, type Plugin, build as viteBuild } from "vite" +import { DOC_PAGE_MANIFEST } from "./DOC_PAGE_MANIFEST.ts" + +/** + * Extracts searchable text from a TSX doc page source file. + * Pulls: title/description/text prop strings, DocList items, and JSX text nodes. + */ +function extractDocPageContent(source: string): string { + const parts: string[] = [] + + // Strip comments so we don't extract text from them + const stripped = source + .replace(/\{\/\*[\s\S]*?\*\/\}/g, "") // JSX block comments + .replace(/\/\/[^\n]*/g, "") // line comments + + // 1. Named text props (title, description, text, label, headers, variant-unrelated names) + const propRe = /\b(?:title|description)\s*=\s*"([^"]+)"/g + for (const m of stripped.matchAll(propRe)) parts.push(m[1]) + + // 2. String items inside items={["...", ...]} — DocList, DocTable rows, etc. + const itemsBlockRe = /\bitems\s*=\s*\{\s*\[([^\]]*?)\]\s*\}/gs + for (const m of stripped.matchAll(itemsBlockRe)) { + for (const s of m[1].matchAll(/"([^"]{4,})"/g)) parts.push(s[1]) + } + + // 3. DocTable rows={[["cell", "cell"], ...]} + const rowsBlockRe = /\brows\s*=\s*\{\s*\[([^\]]*?\][^\]]*?)\]\s*\}/gs + for (const m of stripped.matchAll(rowsBlockRe)) { + for (const s of m[1].matchAll(/"([^"]{4,})"/g)) parts.push(s[1]) + } + + // 4. JSX text nodes: text between > and < that is not whitespace-only + const textNodeRe = />([^<>{}\n]{8,})= 8 && !/^\s*$/.test(t)) parts.push(t) + } + + // Deduplicate consecutive identical strings and collapse whitespace + return [ + ...new Set(parts), + ] + .map((p) => p.replace(/\s+/g, " ").trim()) + .filter(Boolean) + .join(" ") +} + +const DOCS_SEARCH_VIRTUAL_MODULE_ID = "virtual:docs-search-index" +const RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID = `\0${DOCS_SEARCH_VIRTUAL_MODULE_ID}` + +interface GeneratedSearchEntry { + path: string + title: string + description: string + section: string + navGroup: string + navLabel: string + content: string +} + +/** + * Parses accountsData.ts source and returns one search entry per account. + * Content is compact: number + label + description + className + type + side. + */ +function extractAccountEntries(source: string): GeneratedSearchEntry[] { + const entries: GeneratedSearchEntry[] = [] + const chunks = source.split(/(?=\bdefineAccount\()/) + for (const chunk of chunks) { + if (!/^\s*defineAccount\s*\(\s*"/.test(chunk)) continue + const numMatch = chunk.match(/defineAccount\(\s*"([^"]+)"/) + if (!numMatch) continue + const number = numMatch[1] + const labelMatch = chunk.match(/defineAccount\(\s*"[^"]+",\s*"([^"]+)"/) + if (!labelMatch) continue + const label = labelMatch[1] + const description = chunk.match(/\bdescription\s*:\s*"([^"]+)"/)?.[1] ?? "" + const className = chunk.match(/\bclassName\s*:\s*"([^"]+)"/)?.[1] ?? "" + const type = chunk.match(/\btype\s*:\s*"([^"]+)"/)?.[1] ?? "" + const side = chunk.match(/\bside\s*:\s*"([^"]+)"/)?.[1] ?? "" + entries.push({ + path: `/documentation/comptabilité/ressources/comptes/${number}`, + title: `${number} — ${label}`, + description, + section: "Comptabilité", + navGroup: "Comptes", + navLabel: label, + content: [ + number, + label, + description, + className, + type, + side, + ] + .filter(Boolean) + .join(" "), + }) + } + return entries +} + +/** + * Parses glossaryData.ts source and returns one search entry per glossary term. + * Content: term + englishTranslation + definition + relatedTerms. + */ +function extractGlossaryEntries(source: string): GeneratedSearchEntry[] { + const toSlug = (term: string) => + term + .toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, "") + + const entries: GeneratedSearchEntry[] = [] + const chunks = source.split(/(?=\bdefineTerm\()/) + for (const chunk of chunks) { + if (!/^\s*defineTerm\s*\(\s*"/.test(chunk)) continue + const m = chunk.match(/defineTerm\(\s*"([^"]+)",\s*"([^"]+)",\s*"([^"]+)"/) + if (!m) continue + const [, term, englishTranslation, definition] = m + const relatedTerms: string[] = [] + const rtBlock = chunk.match(/relatedTerms\s*:\s*\[([^\]]*)\]/) + if (rtBlock) { + for (const rt of rtBlock[1].matchAll(/"([^"]+)"/g)) relatedTerms.push(rt[1]) + } + entries.push({ + path: `/documentation/comptabilité/ressources/glossaire/${toSlug(term)}`, + title: term, + description: definition, + section: "Comptabilité", + navGroup: "Glossaire", + navLabel: term, + content: [ + term, + englishTranslation, + definition, + ...relatedTerms, + ].join(" "), + }) + } + return entries +} + +export function docsSearchIndexPlugin(): Plugin { + const pkgRoot = resolve(__dirname, "..") + const accountsDataPath = resolve(pkgRoot, "src/features/docs/accounting/resources/accounts/accountsData.ts") + const glossaryDataPath = resolve(pkgRoot, "src/features/docs/accounting/resources/glossary/glossaryData.ts") + + function buildIndex(): string { + const pageEntries = DOC_PAGE_MANIFEST.map((entry) => { + const filePath = resolve(pkgRoot, entry.file) + let source = "" + try { + source = readFileSync(filePath, "utf-8") + } catch { + console.warn(`[docs-search] Could not read ${entry.file}`) + } + const content = extractDocPageContent(source) + return { + path: entry.path, + title: extractTitle(source, entry.navLabel), + description: extractDescription(source, ""), + section: entry.section, + navGroup: entry.navGroup, + navLabel: entry.navLabel, + content: [ + entry.navGroup, + entry.navLabel, + content, + ] + .filter(Boolean) + .join(" "), + } + }) + + const accountEntries = extractAccountEntries(readFileSync(accountsDataPath, "utf-8")) + const glossaryEntries = extractGlossaryEntries(readFileSync(glossaryDataPath, "utf-8")) + + const entries = [ + ...pageEntries, + ...accountEntries, + ...glossaryEntries, + ] + return `export const docsSearchIndex = ${JSON.stringify(entries, null, 4)};` + } + + return { + name: "docs-search-index", + resolveId(id) { + if (id === DOCS_SEARCH_VIRTUAL_MODULE_ID) return RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID + }, + load(id) { + if (id === RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID) return buildIndex() + }, + handleHotUpdate({ file, server }) { + const isDocPage = DOC_PAGE_MANIFEST.some((e) => file.endsWith(e.file.replace(/\//g, "/"))) + const isDataFile = file === accountsDataPath || file === glossaryDataPath + if (isDocPage || isDataFile) { + const mod = server.moduleGraph.getModuleById(RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID) + if (mod) server.moduleGraph.invalidateModule(mod) + server.ws.send({ + type: "full-reload", + }) + } + }, + } +} + +/** Extract the `title` prop from a DocHeader (falls back to navLabel). */ +function extractTitle(source: string, fallback: string): string { + const m = source.match(/DocHeader[^>]*\btitle\s*=\s*"([^"]+)"/) + if (m) return m[1] + // Custom pages with

or plain heading text + const h1 = source.match(/]*>\s*([^<\n]{3,})\s*<\/h1>/) + if (h1) return h1[1].trim() + return fallback +} + +/** Extract the `description` prop from a DocHeader, falling back to

below

. */ +function extractDescription(source: string, fallback: string): string { + const m = source.match(/DocHeader[^>]*\bdescription\s*=\s*"([^"]+)"/) + if (m) return m[1] + return fallback +} diff --git a/packages/website/plugins/fontPreloadPlugin.ts b/packages/website/plugins/fontPreloadPlugin.ts new file mode 100644 index 00000000..c1119ca4 --- /dev/null +++ b/packages/website/plugins/fontPreloadPlugin.ts @@ -0,0 +1,24 @@ +import type { Plugin } from "vite" + +export function fontPreloadPlugin(): Plugin { + return { + name: "font-preload", + transformIndexHtml: { + order: "post", + handler(_html, ctx) { + const fontAssets = (ctx.bundle ? Object.keys(ctx.bundle) : []).filter((name) => name.endsWith(".woff2")) + return fontAssets.map((font) => ({ + tag: "link", + attrs: { + rel: "preload", + as: "font", + type: "font/woff2", + href: `/${font}`, + crossorigin: "anonymous", + }, + injectTo: "head" as const, + })) + }, + }, + } +} diff --git a/packages/website/plugins/prerenderPlugin.ts b/packages/website/plugins/prerenderPlugin.ts new file mode 100644 index 00000000..614729c2 --- /dev/null +++ b/packages/website/plugins/prerenderPlugin.ts @@ -0,0 +1,136 @@ +import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" +import { dirname, resolve } from "node:path" +import react from "@vitejs/plugin-react" +import { type Plugin, build as viteBuild } from "vite" +import { DOC_PAGE_MANIFEST } from "./DOC_PAGE_MANIFEST" +import { docsSearchIndexPlugin } from "./docsSearchIndexPlugin" + +export function prerenderPlugin(): Plugin { + return { + name: "prerender", + async closeBundle() { + if (process.env.BUILD_PRERENDER) return + process.env.BUILD_PRERENDER = "1" + + try { + const pkgRoot = resolve(__dirname, "..") + const buildDir = resolve(pkgRoot, "build") + const renderBuildDir = resolve(pkgRoot, "build-render") + + const spaShell = readFileSync(resolve(buildDir, "index.html"), "utf-8") + + // Build a Node.js bundle of render.tsx so we can call renderToString() for each route + await viteBuild({ + root: resolve(pkgRoot, "src"), + base: "/", + envDir: pkgRoot, + plugins: [ + react({ + include: "**/*.tsx", + }), + docsSearchIndexPlugin(), + ], + build: { + ssr: "../plugins/render.tsx", + outDir: renderBuildDir, + emptyOutDir: true, + rollupOptions: { + output: { + entryFileNames: "render.js", + format: "es", + }, + }, + }, + logLevel: "warn", + }) + + // Load the render bundle and generate static HTML for each route + const { render } = (await import(`file://${resolve(renderBuildDir, "render.js")}`)) as { + render: (url: string) => Promise + } + + // Collect all routes to prerender + const routes: string[] = [ + "/", + "/connexion", + "/inscription", + "/mot-de-passe-oublié", + ...DOC_PAGE_MANIFEST.map((e) => e.path), + ] + + // Dynamic account slugs + const accountsDataPath = resolve( + pkgRoot, + "src/features/docs/accounting/resources/accounts/accountsData.ts", + ) + for (const m of readFileSync(accountsDataPath, "utf-8").matchAll( + /defineAccount\(\s*\n?\s*"([^"]+)"/g, + )) { + routes.push(`/documentation/comptabilité/ressources/comptes/${m[1]}`) + } + + // Dynamic glossary slugs + const toSlug = (term: string) => + term + .toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, "") + const glossaryDataPath = resolve( + pkgRoot, + "src/features/docs/accounting/resources/glossary/glossaryData.ts", + ) + for (const m of readFileSync(glossaryDataPath, "utf-8").matchAll(/defineTerm\(\s*\n?\s*"([^"]+)"/g)) { + routes.push(`/documentation/comptabilité/ressources/glossaire/${toSlug(m[1])}`) + } + + // Scenario paths + const scenariosDataPath = resolve( + pkgRoot, + "src/features/docs/accounting/resources/scenarios/scenariosData.ts", + ) + for (const m of readFileSync(scenariosDataPath, "utf-8").matchAll( + /path:\s*"(\/documentation\/comptabilité\/scénarios\/[^"]+)"/g, + )) { + routes.push(m[1]) + } + + let count = 0 + for (const route of routes) { + try { + const appHtml = await render(route) + + // Extract the page-specific rendered by React and update <head> + const renderedTitle = /<title>([\s\S]*?)<\/title>/.exec(appHtml)?.[1] + let html = spaShell + if (renderedTitle) { + html = html.replace(/<title>[^<]*<\/title>/, `<title>${renderedTitle}`) + } + html = html.replace('
', `
${appHtml}
`) + + const outFile = + route === "/" + ? resolve(buildDir, "index.html") + : resolve(buildDir, route.slice(1), "index.html") + mkdirSync(dirname(outFile), { + recursive: true, + }) + writeFileSync(outFile, html, "utf-8") + count++ + } catch (err) { + console.warn(`[prerender] Failed to render ${route}:`, err) + } + } + + rmSync(renderBuildDir, { + recursive: true, + force: true, + }) + console.log(`[prerender] Generated ${count} static HTML files`) + } finally { + delete process.env.BUILD_PRERENDER + } + }, + } +} diff --git a/packages/website/plugins/render.tsx b/packages/website/plugins/render.tsx new file mode 100644 index 00000000..2ba806f1 --- /dev/null +++ b/packages/website/plugins/render.tsx @@ -0,0 +1,25 @@ +import { createMemoryHistory, createRouter, RouterProvider } from "@tanstack/react-router" +import { renderToString } from "react-dom/server" +import { applicationTree } from "../src/routes/applicationTree.js" + +export async function render(url: string): Promise { + const router = createRouter({ + routeTree: applicationTree, + history: createMemoryHistory({ + initialEntries: [ + url, + ], + }), + scrollRestoration: false, + context: { + title: undefined, + section: undefined, + description: undefined, + robots: undefined, + isAuthenticated: false, + userSession: undefined, + }, + }) + await router.load() + return renderToString() +} diff --git a/packages/website/plugins/sitemapPlugin.ts b/packages/website/plugins/sitemapPlugin.ts new file mode 100644 index 00000000..33e46f8a --- /dev/null +++ b/packages/website/plugins/sitemapPlugin.ts @@ -0,0 +1,360 @@ +import { readFileSync, writeFileSync } from "node:fs" +import { resolve } from "node:path" +import type { Plugin } from "vite" + +export function sitemapPlugin(): Plugin { + return { + name: "sitemap-generator", + closeBundle() { + const baseUrl = "https://arrhes.com" + const today = new Date().toISOString().split("T")[0] + + // Static public routes + const staticRoutes = [ + { + path: "/", + priority: "1.0", + changefreq: "weekly", + }, + { + path: "/connexion", + priority: "0.5", + changefreq: "monthly", + }, + { + path: "/inscription", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/mot-de-passe-oublié", + priority: "0.5", + changefreq: "monthly", + }, + + // General docs + { + path: "/documentation", + priority: "0.8", + changefreq: "weekly", + }, + { + path: "/documentation/fonctionnalités", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/philosophie", + priority: "0.5", + changefreq: "monthly", + }, + { + path: "/documentation/tarifs", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/support", + priority: "0.5", + changefreq: "monthly", + }, + { + path: "/documentation/mentions-légales", + priority: "0.3", + changefreq: "yearly", + }, + { + path: "/documentation/cgu", + priority: "0.3", + changefreq: "yearly", + }, + { + path: "/documentation/confidentialité", + priority: "0.3", + changefreq: "yearly", + }, + + // Accounting docs + { + path: "/documentation/comptabilité", + priority: "0.8", + changefreq: "weekly", + }, + { + path: "/documentation/comptabilité/introduction", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/partie-double", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/écritures", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/comptes/introduction", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/comptes/classes", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/comptes/liste", + priority: "0.8", + changefreq: "weekly", + }, + { + path: "/documentation/comptabilité/documents", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/journal", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/grand-livre", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/balance", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/bilan", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/compte-de-résultat", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/annexe", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/documents/fec", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/scénarios", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/comptabilité/glossaire", + priority: "0.7", + changefreq: "monthly", + }, + + // Dashboard docs + { + path: "/documentation/dashboard", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/démarrage", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/organisations", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/exercices", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/écritures", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/stockage", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/documents", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/facturation", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/màj", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/assistant", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/assistant/modèles", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/assistant/outils", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/dashboard/assistant/ocr", + priority: "0.6", + changefreq: "monthly", + }, + + // API docs + { + path: "/documentation/api", + priority: "0.7", + changefreq: "monthly", + }, + { + path: "/documentation/api/introduction", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/api/authentification", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/api/organisation", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/api/exercice", + priority: "0.6", + changefreq: "monthly", + }, + { + path: "/documentation/api/stockage", + priority: "0.6", + changefreq: "monthly", + }, + ] + + // Extract dynamic account slugs from source + const accountsDataPath = resolve( + __dirname, + "../src/features/docs/accounting/resources/accounts/accountsData.ts", + ) + const accountsSrc = readFileSync(accountsDataPath, "utf-8") + const accountSlugs = [ + ...accountsSrc.matchAll(/defineAccount\(\s*\n?\s*"([^"]+)"/g), + ].map((m) => m[1]) + + // Extract dynamic glossary slugs from source + const glossaryDataPath = resolve( + __dirname, + "../src/features/docs/accounting/resources/glossary/glossaryData.ts", + ) + const glossarySrc = readFileSync(glossaryDataPath, "utf-8") + // The toSlug function: lowercase, NFD normalize, strip diacritics, replace non-alnum with -, trim - + const glossaryTerms = [ + ...glossarySrc.matchAll(/defineTerm\(\s*\n?\s*"([^"]+)"/g), + ].map((m) => m[1]) + const toSlug = (term: string) => + term + .toLowerCase() + .normalize("NFD") + .replace(/[\u0300-\u036f]/g, "") + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, "") + const glossarySlugs = glossaryTerms.map(toSlug) + + // Extract scenario paths directly from scenariosData.ts + const scenariosDataPath = resolve( + __dirname, + "../src/features/docs/accounting/resources/scenarios/scenariosData.ts", + ) + const scenariosSrc = readFileSync(scenariosDataPath, "utf-8") + const scenarioPaths = [ + ...scenariosSrc.matchAll(/path:\s*"(\/documentation\/comptabilité\/scénarios\/[^"]+)"/g), + ].map((m) => m[1]) + + // Build URL entries + const routeMap = new Map< + string, + { + changefreq: string + priority: string + } + >() + const addRoute = (path: string, changefreq: string, priority: string) => { + if (!routeMap.has(path)) { + routeMap.set(path, { + changefreq, + priority, + }) + } + } + + for (const route of staticRoutes) { + addRoute(route.path, route.changefreq, route.priority) + } + + for (const slug of accountSlugs) { + addRoute(`/documentation/comptabilité/comptes/liste/${slug}`, "monthly", "0.5") + } + + for (const slug of glossarySlugs) { + addRoute(`/documentation/comptabilité/glossaire/${slug}`, "monthly", "0.5") + } + + for (const path of scenarioPaths) { + addRoute(path, "monthly", "0.5") + } + + const urls = [ + ...routeMap.entries(), + ] + .sort(([pathA], [pathB]) => pathA.localeCompare(pathB, "fr")) + .map( + ([path, metadata]) => ` + ${encodeURI(`${baseUrl}${path}`)} + ${today} + ${metadata.changefreq} + ${metadata.priority} + `, + ) + + const sitemap = ` + +${urls.join("\n")} + +` + const outPath = resolve(__dirname, "../build/sitemap.xml") + writeFileSync(outPath, sitemap, "utf-8") + + console.log(`[sitemap] Generated sitemap.xml with ${urls.length} URLs`) + }, + } +} diff --git a/packages/website/src/components/forms/FormControl.tsx b/packages/website/src/components/forms/FormControl.tsx index 77fd024c..dba113fe 100644 --- a/packages/website/src/components/forms/FormControl.tsx +++ b/packages/website/src/components/forms/FormControl.tsx @@ -1,9 +1,19 @@ import { CircularLoader } from "@arrhes/ui" -import { Slot } from "@radix-ui/react-slot" -import { type ComponentProps, Suspense } from "react" +import { cloneElement, type HTMLAttributes, isValidElement, type ReactElement, Suspense } from "react" import { useFormField } from "./useFormField.js" -type FormControl = ComponentProps +type FormControl = HTMLAttributes & { + children?: ReactElement +} + +function Slot({ children, ...slotProps }: FormControl) { + if (!isValidElement(children)) return null + const element = children as ReactElement> + return cloneElement(element, { + ...slotProps, + ...element.props, + }) +} export function FormControl(props: FormControl) { const { error, formItemId, formDescriptionId, formMessageId } = useFormField() diff --git a/packages/website/src/components/forms/FormLabel.tsx b/packages/website/src/components/forms/FormLabel.tsx index 7f308ccc..612dfc36 100644 --- a/packages/website/src/components/forms/FormLabel.tsx +++ b/packages/website/src/components/forms/FormLabel.tsx @@ -1,7 +1,11 @@ import { css } from "@arrhes/ui/utilities/cn.js" -import { Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger } from "@radix-ui/react-tooltip" import { IconInfoSquare } from "@tabler/icons-react" import type { HTMLAttributes } from "react" +import { TooltipContent } from "../overlays/tooltip/TooltipContent.js" +import { TooltipPortal } from "../overlays/tooltip/tooltipPortal.js" +import { TooltipProvider } from "../overlays/tooltip/tooltipProvider.js" +import { TooltipRoot as Tooltip } from "../overlays/tooltip/tooltipRoot.js" +import { TooltipTrigger } from "../overlays/tooltip/tooltipTrigger.js" import { useFormField } from "./useFormField.js" type FormLabel = { diff --git a/packages/website/src/components/layouts/commandPalette/searchRoutes.ts b/packages/website/src/components/layouts/commandPalette/searchRoutes.ts index e5fc2d40..ec602b3f 100644 --- a/packages/website/src/components/layouts/commandPalette/searchRoutes.ts +++ b/packages/website/src/components/layouts/commandPalette/searchRoutes.ts @@ -47,7 +47,7 @@ export type OrgSearchRoute = { export const orgSearchRoutes: OrgSearchRoute[] = [ { - label: "Agent IA", + label: "Assistant IA", description: "Assistant comptable intelligent", tabComponent: "agent", }, diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx index 92f7d4ae..2199c9b4 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx @@ -1,33 +1,64 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" -import { ContextMenuPortal, ContextMenuContent as RadixContextMenuContent } from "@radix-ui/react-context-menu" -import type { ComponentPropsWithRef } from "react" +import { type ComponentPropsWithRef, useEffect, useRef } from "react" +import { createPortal } from "react-dom" +import { useContextMenu } from "./ContextMenuRoot.js" -export function ContextMenuContent(props: ComponentPropsWithRef) { - return ( - - - {props.children} - - +export function ContextMenuContent({ children, className, ...props }: ComponentPropsWithRef<"div">) { + const ctx = useContextMenu() + const ref = useRef(null) + + useEffect(() => { + if (!ctx?.open) return + function handleClickOutside(e: MouseEvent) { + if (ref.current && !ref.current.contains(e.target as Node)) { + ctx?.closeMenu() + } + } + function handleKeyDown(e: KeyboardEvent) { + if (e.key === "Escape") ctx?.closeMenu() + } + document.addEventListener("mousedown", handleClickOutside) + document.addEventListener("keydown", handleKeyDown) + return () => { + document.removeEventListener("mousedown", handleClickOutside) + document.removeEventListener("keydown", handleKeyDown) + } + }, [ + ctx?.open, + ]) + + if (!ctx?.open) return null + + return createPortal( +
+ {children} +
, + document.body, ) } diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx index 52c7d796..944bc184 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuItem.tsx @@ -1,17 +1,32 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" -import { ContextMenuItem as RadixContextMenuItem } from "@radix-ui/react-context-menu" import type { ComponentPropsWithRef, ReactElement } from "react" +import { useContextMenu } from "./ContextMenuRoot.js" -export function ContextMenuItem( - props: ComponentPropsWithRef & { - leftIcon?: ReactElement - color?: "default" | "danger" - }, -) { - const { leftIcon, color = "default", ...rest } = props +type ContextMenuItemProps = ComponentPropsWithRef<"button"> & { + leftIcon?: ReactElement + color?: "default" | "danger" + onSelect?: () => void +} + +export function ContextMenuItem({ + leftIcon, + color = "default", + onSelect, + onClick, + children, + className, + ...props +}: ContextMenuItemProps) { + const ctx = useContextMenu() return ( - { + ctx?.closeMenu() + onSelect?.() + onClick?.(e) + }} className={cx( css({ width: "100%", @@ -28,11 +43,7 @@ export function ContextMenuItem( _hover: { backgroundColor: "neutral/5", }, - "&[data-highlighted]": { - backgroundColor: "neutral/5", - outline: "none", - }, - "&[data-disabled]": { + _disabled: { opacity: 0.4, cursor: "default", pointerEvents: "none", @@ -48,7 +59,7 @@ export function ContextMenuItem( : css({ color: "neutral", }), - props.className, + className, )} > {leftIcon && ( @@ -61,7 +72,7 @@ export function ContextMenuItem( {leftIcon} )} - {props.children} - + {children} + ) } diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuRoot.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuRoot.tsx index 26cfc1bc..e1318490 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuRoot.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuRoot.tsx @@ -1,13 +1,57 @@ -import { ContextMenu } from "@radix-ui/react-context-menu" -import type { ComponentPropsWithRef } from "react" +import { createContext, type ReactNode, useContext, useState } from "react" + +type ContextMenuContextValue = { + open: boolean + position: { + x: number + y: number + } + openMenu: (x: number, y: number) => void + closeMenu: () => void +} + +export const ContextMenuContext = createContext(null) + +export function useContextMenu() { + return useContext(ContextMenuContext) +} + +type ContextMenuRootProps = { + children: ReactNode + onOpenChange?: (open: boolean) => void +} + +export function ContextMenuRoot({ children, onOpenChange }: ContextMenuRootProps) { + const [open, setOpen] = useState(false) + const [position, setPosition] = useState({ + x: 0, + y: 0, + }) + + function openMenu(x: number, y: number) { + setPosition({ + x, + y, + }) + setOpen(true) + onOpenChange?.(true) + } + + function closeMenu() { + setOpen(false) + onOpenChange?.(false) + } -export function ContextMenuRoot(props: ComponentPropsWithRef) { return ( - - {props.children} - + {children} + ) } diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuSeparator.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuSeparator.tsx index 8206fa85..7b11b9ac 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuSeparator.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuSeparator.tsx @@ -1,10 +1,9 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" -import { ContextMenuSeparator as RadixContextMenuSeparator } from "@radix-ui/react-context-menu" import type { ComponentPropsWithRef } from "react" -export function ContextMenuSeparator(props: ComponentPropsWithRef) { +export function ContextMenuSeparator({ className, ...props }: ComponentPropsWithRef<"div">) { return ( - ) diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuTrigger.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuTrigger.tsx index f6a8660c..99a5a2ec 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuTrigger.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuTrigger.tsx @@ -1,6 +1,35 @@ -import { ContextMenuTrigger as RadixContextMenuTrigger } from "@radix-ui/react-context-menu" -import type { ComponentPropsWithRef } from "react" +import { type ComponentPropsWithRef, cloneElement, isValidElement, type ReactElement } from "react" +import { useContextMenu } from "./ContextMenuRoot.js" -export function ContextMenuTrigger(props: ComponentPropsWithRef) { - return {props.children} +type ContextMenuTriggerProps = ComponentPropsWithRef<"div"> & { + asChild?: boolean +} + +export function ContextMenuTrigger({ children, asChild, ...props }: ContextMenuTriggerProps) { + const ctx = useContextMenu() + + function handleContextMenu(e: React.MouseEvent) { + e.preventDefault() + ctx?.openMenu(e.clientX, e.clientY) + } + + if (asChild && isValidElement(children)) { + const child = children as ReactElement> + return cloneElement(child, { + ...child.props, + onContextMenu: (e: React.MouseEvent) => { + handleContextMenu(e) + ;(child.props.onContextMenu as ((e: React.MouseEvent) => void) | undefined)?.(e) + }, + }) + } + + return ( +
+ {children} +
+ ) } diff --git a/packages/website/src/components/overlays/tooltip/TooltipContent.tsx b/packages/website/src/components/overlays/tooltip/TooltipContent.tsx index 8e946a65..72b1e1e7 100644 --- a/packages/website/src/components/overlays/tooltip/TooltipContent.tsx +++ b/packages/website/src/components/overlays/tooltip/TooltipContent.tsx @@ -1,12 +1,59 @@ import { css, cx } from "@arrhes/ui/utilities/cn.js" -import * as TooltipPrimitive from "@radix-ui/react-tooltip" -import type { ComponentProps } from "react" +import { type ComponentPropsWithRef, useLayoutEffect, useRef, useState } from "react" +import { createPortal } from "react-dom" +import { useTooltipRoot } from "./tooltipRoot.js" -export function TooltipContent(props: ComponentProps) { - return ( - & { + sideOffset?: number +} + +export function TooltipContent({ sideOffset = 4, children, className, style, ...props }: TooltipContentProps) { + const ctx = useTooltipRoot() + const ref = useRef(null) + const [pos, setPos] = useState<{ + top: number + left: number + ready: boolean + }>({ + top: 0, + left: 0, + ready: false, + }) + + useLayoutEffect(() => { + if (!ctx?.open) { + setPos((p) => ({ + ...p, + ready: false, + })) + return + } + if (!ref.current || !ctx.triggerRef.current) return + const tr = ctx.triggerRef.current.getBoundingClientRect() + const cr = ref.current.getBoundingClientRect() + setPos({ + top: tr.top - cr.height - sideOffset, + left: Math.max(8, tr.left + tr.width / 2 - cr.width / 2), + ready: true, + }) + }, [ + ctx?.open, + sideOffset, + ]) + + if (!ctx?.open) return null + + return createPortal( +
- {props.children} + {children} - +
, + document.body, ) } diff --git a/packages/website/src/components/overlays/tooltip/tooltipPortal.tsx b/packages/website/src/components/overlays/tooltip/tooltipPortal.tsx index 75269276..2c8911af 100644 --- a/packages/website/src/components/overlays/tooltip/tooltipPortal.tsx +++ b/packages/website/src/components/overlays/tooltip/tooltipPortal.tsx @@ -1,3 +1,6 @@ -import * as TooltipPrimitive from "@radix-ui/react-tooltip" +import type { ReactNode } from "react" -export const TooltipPortal = TooltipPrimitive.Portal +// Portal is a no-op; TooltipContent handles its own portal rendering +export function TooltipPortal({ children }: { children: ReactNode; container?: Element }) { + return <>{children} +} diff --git a/packages/website/src/components/overlays/tooltip/tooltipProvider.tsx b/packages/website/src/components/overlays/tooltip/tooltipProvider.tsx index d9e93e49..ec85a40e 100644 --- a/packages/website/src/components/overlays/tooltip/tooltipProvider.tsx +++ b/packages/website/src/components/overlays/tooltip/tooltipProvider.tsx @@ -1,3 +1,6 @@ -import * as TooltipPrimitive from "@radix-ui/react-tooltip" +import type { ReactNode } from "react" -export const TooltipProvider = TooltipPrimitive.Provider +// Provider is a no-op wrapper kept for API compatibility +export function TooltipProvider({ children }: { children: ReactNode; delayDuration?: number }) { + return <>{children} +} diff --git a/packages/website/src/components/overlays/tooltip/tooltipRoot.tsx b/packages/website/src/components/overlays/tooltip/tooltipRoot.tsx index 75d0c7e1..a8847fc9 100644 --- a/packages/website/src/components/overlays/tooltip/tooltipRoot.tsx +++ b/packages/website/src/components/overlays/tooltip/tooltipRoot.tsx @@ -1,3 +1,47 @@ -import * as TooltipPrimitive from "@radix-ui/react-tooltip" +import { createContext, type MutableRefObject, type ReactNode, useContext, useRef, useState } from "react" -export const TooltipRoot = TooltipPrimitive.Root +type TooltipRootContextValue = { + open: boolean + openTooltip: () => void + closeTooltip: () => void + triggerRef: MutableRefObject +} + +export const TooltipRootContext = createContext(null) + +export function useTooltipRoot() { + return useContext(TooltipRootContext) +} + +export function TooltipRoot({ children, delayDuration = 700 }: { children: ReactNode; delayDuration?: number }) { + const [open, setOpen] = useState(false) + const triggerRef = useRef(null) + const timerRef = useRef | undefined>(undefined) + + function openTooltip() { + clearTimeout(timerRef.current) + if (delayDuration === 0) { + setOpen(true) + } else { + timerRef.current = setTimeout(() => setOpen(true), delayDuration) + } + } + + function closeTooltip() { + clearTimeout(timerRef.current) + setOpen(false) + } + + return ( + + {children} + + ) +} diff --git a/packages/website/src/components/overlays/tooltip/tooltipTrigger.tsx b/packages/website/src/components/overlays/tooltip/tooltipTrigger.tsx index 7b76ab16..2d5ba272 100644 --- a/packages/website/src/components/overlays/tooltip/tooltipTrigger.tsx +++ b/packages/website/src/components/overlays/tooltip/tooltipTrigger.tsx @@ -1,3 +1,35 @@ -import * as TooltipPrimitive from "@radix-ui/react-tooltip" +import type { ComponentPropsWithRef } from "react" +import { useTooltipRoot } from "./tooltipRoot.js" -export const TooltipTrigger = TooltipPrimitive.Trigger +export function TooltipTrigger({ children, ...props }: ComponentPropsWithRef<"button">) { + const ctx = useTooltipRoot() + return ( + + ) +} diff --git a/packages/website/src/contexts/tabs/tabDefinitions.ts b/packages/website/src/contexts/tabs/tabDefinitions.ts index bcd9d213..0d88f164 100644 --- a/packages/website/src/contexts/tabs/tabDefinitions.ts +++ b/packages/website/src/contexts/tabs/tabDefinitions.ts @@ -96,7 +96,7 @@ export const TAB_REGISTRY = { agent: (props: { idOrganization: string }): TabDefinition => ({ id: `agent-${props.idOrganization}`, - title: "Agent IA", + title: "Assistant IA", description: "Assistant comptable intelligent", component: createElement(AgentTabContent, { idOrganization: props.idOrganization, diff --git a/packages/website/src/root.tsx b/packages/website/src/root.tsx index a723be78..6de177b4 100644 --- a/packages/website/src/root.tsx +++ b/packages/website/src/root.tsx @@ -3,13 +3,9 @@ import { createRoot } from "react-dom/client" import "./assets/css/root.css" import { RootProvider } from "./contexts/RootProvider.js" -const rootElement = document.getElementById("root")! -if (!rootElement.innerHTML) { - localStorage.theme = "light" - const root = createRoot(rootElement) - root.render( - - - , - ) -} +localStorage.theme = "light" +createRoot(document.getElementById("root")!).render( + + + , +) diff --git a/packages/website/src/utilities/cookies/getCookie.ts b/packages/website/src/utilities/cookies/getCookie.ts index 0ae832b8..2d74d4d4 100644 --- a/packages/website/src/utilities/cookies/getCookie.ts +++ b/packages/website/src/utilities/cookies/getCookie.ts @@ -1,4 +1,5 @@ export function getCookie(name: string) { + if (typeof document === "undefined") return undefined const encodedName = encodeURIComponent(name) const stringCookies = document?.cookie?.split("; ") const cookie = stringCookies?.find((x) => x.startsWith(`${encodedName}=`)) diff --git a/packages/website/tsconfig.json b/packages/website/tsconfig.json index 2eb77bf8..182b1ba8 100644 --- a/packages/website/tsconfig.json +++ b/packages/website/tsconfig.json @@ -30,7 +30,7 @@ "incremental": true, "tsBuildInfoFile": "./.tsbuildinfo" }, - "include": ["src"], + "include": ["src", "plugins"], "exclude": ["styled-system", "build", "node_modules"], "references": [ { diff --git a/packages/website/vite.config.ts b/packages/website/vite.config.ts index d15954ac..4ebb2d8b 100644 --- a/packages/website/vite.config.ts +++ b/packages/website/vite.config.ts @@ -1,943 +1,11 @@ -import { readFileSync, writeFileSync } from "node:fs" -import { resolve } from "node:path" +import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" +import { dirname, resolve } from "node:path" import react from "@vitejs/plugin-react" -import { defineConfig, type Plugin } from "vite" - -// ─────────────────────────── Docs Search Index Plugin ───────────────────────────── - -interface DocPageManifestEntry { - path: string - file: string // relative from package root - section: string - navGroup: string - navLabel: string -} - -// Maps every static doc page route to its source file and nav metadata. -// Content strings are extracted automatically from the TSX source at build time. -const DOC_PAGE_MANIFEST: DocPageManifestEntry[] = [ - // ── Général / Introduction ──────────────────────────────────────────────── - { - path: "/documentation", - file: "src/features/docs/general/rootGeneralDocPage.tsx", - section: "Général", - navGroup: "Introduction", - navLabel: "Accueil", - }, - { - path: "/documentation/fonctionnalités", - file: "src/features/docs/general/features/featuresGeneralDocPage.tsx", - section: "Général", - navGroup: "Introduction", - navLabel: "Fonctionnalités", - }, - { - path: "/documentation/philosophie", - file: "src/features/docs/general/whitepaperGeneralDocPage.tsx", - section: "Général", - navGroup: "Introduction", - navLabel: "Philosophie", - }, - { - path: "/documentation/tarifs", - file: "src/features/docs/general/pricing/pricingGeneralDocPage.tsx", - section: "Général", - navGroup: "Introduction", - navLabel: "Tarifs", - }, - { - path: "/documentation/support", - file: "src/features/docs/general/supportGeneralDocPage.tsx", - section: "Général", - navGroup: "Introduction", - navLabel: "Support", - }, - // ── Général / Légal ─────────────────────────────────────────────────────── - { - path: "/documentation/mentions-légales", - file: "src/features/docs/general/legalGeneralDocPage.tsx", - section: "Général", - navGroup: "Légal", - navLabel: "Mentions légales", - }, - { - path: "/documentation/cgu", - file: "src/features/docs/general/termsGeneralDocPage.tsx", - section: "Général", - navGroup: "Légal", - navLabel: "Conditions Générales d'Utilisation", - }, - { - path: "/documentation/confidentialité", - file: "src/features/docs/general/privacyGeneralDocPage.tsx", - section: "Général", - navGroup: "Légal", - navLabel: "Politique de confidentialité", - }, - // ── Comptabilité / Introduction ─────────────────────────────────────────── - { - path: "/documentation/comptabilité", - file: "src/features/docs/accounting/introduction/rootAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Introduction", - navLabel: "Accueil", - }, - { - path: "/documentation/comptabilité/introduction", - file: "src/features/docs/accounting/introduction/introductionAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Introduction", - navLabel: "Introduction", - }, - { - path: "/documentation/comptabilité/introduction/partie-double", - file: "src/features/docs/accounting/introduction/doubleEntryAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Introduction", - navLabel: "La partie double", - }, - { - path: "/documentation/comptabilité/introduction/écritures", - file: "src/features/docs/accounting/introduction/entriesAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Introduction", - navLabel: "Les écritures", - }, - // ── Comptabilité / Comptes ──────────────────────────────────────────────── - { - path: "/documentation/comptabilité/introduction/comptes", - file: "src/features/docs/accounting/introduction/accountsAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Comptes", - navLabel: "Introduction", - }, - { - path: "/documentation/comptabilité/introduction/classes", - file: "src/features/docs/accounting/introduction/classesAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Comptes", - navLabel: "Classes de comptes", - }, - { - path: "/documentation/comptabilité/ressources/comptes", - file: "src/features/docs/accounting/resources/accounts/accountsResourcesAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Comptes", - navLabel: "Liste des comptes", - }, - // ── Comptabilité / Documents ────────────────────────────────────────────── - { - path: "/documentation/comptabilité/documents", - file: "src/features/docs/accounting/reports/reportsAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Introduction", - }, - { - path: "/documentation/comptabilité/documents/journal", - file: "src/features/docs/accounting/reports/journalAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Journal", - }, - { - path: "/documentation/comptabilité/documents/grand-livre", - file: "src/features/docs/accounting/reports/ledgerAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Grand livre", - }, - { - path: "/documentation/comptabilité/documents/balance", - file: "src/features/docs/accounting/reports/balanceAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Balance", - }, - { - path: "/documentation/comptabilité/documents/bilan", - file: "src/features/docs/accounting/reports/balanceSheetAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Bilan", - }, - { - path: "/documentation/comptabilité/documents/compte-de-résultat", - file: "src/features/docs/accounting/reports/incomeStatementAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Compte de résultat", - }, - { - path: "/documentation/comptabilité/documents/annexe", - file: "src/features/docs/accounting/reports/notesAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "Annexe", - }, - { - path: "/documentation/comptabilité/documents/fec", - file: "src/features/docs/accounting/reports/fecAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Documents", - navLabel: "FEC", - }, - // ── Comptabilité / Scénarios ───────────────────────────────────────────── - { - path: "/documentation/comptabilité/ressources/scénarios", - file: "src/features/docs/accounting/resources/scenarios/scenariosResourcesAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Scénarios", - navLabel: "Scénarios", - }, - // ── Comptabilité / Glossaire ────────────────────────────────────────────── - { - path: "/documentation/comptabilité/ressources/glossaire", - file: "src/features/docs/accounting/resources/glossary/glossaryResourcesAccountingDocPage.tsx", - section: "Comptabilité", - navGroup: "Glossaire", - navLabel: "Glossaire", - }, - // ── Dashboard / Guide d'utilisation ────────────────────────────────────── - { - path: "/documentation/dashboard", - file: "src/features/docs/dashboard/rootDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Accueil", - }, - { - path: "/documentation/dashboard/démarrage", - file: "src/features/docs/dashboard/gettingStartedDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Démarrage", - }, - { - path: "/documentation/dashboard/organisations", - file: "src/features/docs/dashboard/organizationsDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Organisations", - }, - { - path: "/documentation/dashboard/exercices", - file: "src/features/docs/dashboard/yearsDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Exercices", - }, - { - path: "/documentation/dashboard/écritures", - file: "src/features/docs/dashboard/entriesDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Saisie des écritures", - }, - { - path: "/documentation/dashboard/stockage", - file: "src/features/docs/dashboard/filesDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Stockage", - }, - { - path: "/documentation/dashboard/documents", - file: "src/features/docs/dashboard/reportsDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Documents comptables", - }, - { - path: "/documentation/dashboard/facturation", - file: "src/features/docs/dashboard/BillingDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Facturation", - }, - { - path: "/documentation/dashboard/màj", - file: "src/features/docs/dashboard/UpdatesDashboardDocPage.tsx", - section: "Dashboard", - navGroup: "Guide d'utilisation", - navLabel: "Mises à jour", - }, - // ── Dashboard / Assistant IA ────────────────────────────────────────────── - { - path: "/documentation/dashboard/assistant", - file: "src/features/docs/ai/rootAiDocPage.tsx", - section: "Dashboard", - navGroup: "Assistant IA", - navLabel: "Introduction", - }, - { - path: "/documentation/dashboard/assistant/modèles", - file: "src/features/docs/ai/modelsAiDocPage.tsx", - section: "Dashboard", - navGroup: "Assistant IA", - navLabel: "Modèles", - }, - { - path: "/documentation/dashboard/assistant/outils", - file: "src/features/docs/ai/toolsAiDocPage.tsx", - section: "Dashboard", - navGroup: "Assistant IA", - navLabel: "Outils", - }, - { - path: "/documentation/dashboard/assistant/ocr", - file: "src/features/docs/ai/ocrAiDocPage.tsx", - section: "Dashboard", - navGroup: "Assistant IA", - navLabel: "OCR", - }, - // ── API ─────────────────────────────────────────────────────────────────── - { - path: "/documentation/api", - file: "src/features/docs/api/rootApiDocPage.tsx", - section: "API", - navGroup: "API", - navLabel: "Présentation", - }, - { - path: "/documentation/api/introduction", - file: "src/features/docs/api/introductionApiDocPage.tsx", - section: "API", - navGroup: "API", - navLabel: "Introduction", - }, - { - path: "/documentation/api/authentification", - file: "src/features/docs/api/authenticationApiDocPage.tsx", - section: "API", - navGroup: "API", - navLabel: "Authentification", - }, - { - path: "/documentation/api/organisation", - file: "src/features/docs/api/organizationApiDocPage.tsx", - section: "API", - navGroup: "API", - navLabel: "Organisation", - }, - { - path: "/documentation/api/exercice", - file: "src/features/docs/api/yearApiDocPage.tsx", - section: "API", - navGroup: "API", - navLabel: "Exercice", - }, - { - path: "/documentation/api/stockage", - file: "src/features/docs/api/filesApiDocPage.tsx", - section: "API", - navGroup: "API", - navLabel: "Fichiers et documents", - }, -] - -/** - * Extracts searchable text from a TSX doc page source file. - * Pulls: title/description/text prop strings, DocList items, and JSX text nodes. - */ -function extractDocPageContent(source: string): string { - const parts: string[] = [] - - // Strip comments so we don't extract text from them - const stripped = source - .replace(/\{\/\*[\s\S]*?\*\/\}/g, "") // JSX block comments - .replace(/\/\/[^\n]*/g, "") // line comments - - // 1. Named text props (title, description, text, label, headers, variant-unrelated names) - const propRe = /\b(?:title|description)\s*=\s*"([^"]+)"/g - for (const m of stripped.matchAll(propRe)) parts.push(m[1]) - - // 2. String items inside items={["...", ...]} — DocList, DocTable rows, etc. - const itemsBlockRe = /\bitems\s*=\s*\{\s*\[([^\]]*?)\]\s*\}/gs - for (const m of stripped.matchAll(itemsBlockRe)) { - for (const s of m[1].matchAll(/"([^"]{4,})"/g)) parts.push(s[1]) - } - - // 3. DocTable rows={[["cell", "cell"], ...]} - const rowsBlockRe = /\brows\s*=\s*\{\s*\[([^\]]*?\][^\]]*?)\]\s*\}/gs - for (const m of stripped.matchAll(rowsBlockRe)) { - for (const s of m[1].matchAll(/"([^"]{4,})"/g)) parts.push(s[1]) - } - - // 4. JSX text nodes: text between > and < that is not whitespace-only - const textNodeRe = />([^<>{}\n]{8,})= 8 && !/^\s*$/.test(t)) parts.push(t) - } - - // Deduplicate consecutive identical strings and collapse whitespace - return [ - ...new Set(parts), - ] - .map((p) => p.replace(/\s+/g, " ").trim()) - .filter(Boolean) - .join(" ") -} - -const DOCS_SEARCH_VIRTUAL_MODULE_ID = "virtual:docs-search-index" -const RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID = `\0${DOCS_SEARCH_VIRTUAL_MODULE_ID}` - -interface GeneratedSearchEntry { - path: string - title: string - description: string - section: string - navGroup: string - navLabel: string - content: string -} - -/** - * Parses accountsData.ts source and returns one search entry per account. - * Content is compact: number + label + description + className + type + side. - */ -function extractAccountEntries(source: string): GeneratedSearchEntry[] { - const entries: GeneratedSearchEntry[] = [] - const chunks = source.split(/(?=\bdefineAccount\()/) - for (const chunk of chunks) { - if (!/^\s*defineAccount\s*\(\s*"/.test(chunk)) continue - const numMatch = chunk.match(/defineAccount\(\s*"([^"]+)"/) - if (!numMatch) continue - const number = numMatch[1] - const labelMatch = chunk.match(/defineAccount\(\s*"[^"]+",\s*"([^"]+)"/) - if (!labelMatch) continue - const label = labelMatch[1] - const description = chunk.match(/\bdescription\s*:\s*"([^"]+)"/)?.[1] ?? "" - const className = chunk.match(/\bclassName\s*:\s*"([^"]+)"/)?.[1] ?? "" - const type = chunk.match(/\btype\s*:\s*"([^"]+)"/)?.[1] ?? "" - const side = chunk.match(/\bside\s*:\s*"([^"]+)"/)?.[1] ?? "" - entries.push({ - path: `/documentation/comptabilité/ressources/comptes/${number}`, - title: `${number} — ${label}`, - description, - section: "Comptabilité", - navGroup: "Comptes", - navLabel: label, - content: [ - number, - label, - description, - className, - type, - side, - ] - .filter(Boolean) - .join(" "), - }) - } - return entries -} - -/** - * Parses glossaryData.ts source and returns one search entry per glossary term. - * Content: term + englishTranslation + definition + relatedTerms. - */ -function extractGlossaryEntries(source: string): GeneratedSearchEntry[] { - const toSlug = (term: string) => - term - .toLowerCase() - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") - .replace(/[^a-z0-9]+/g, "-") - .replace(/(^-|-$)/g, "") - - const entries: GeneratedSearchEntry[] = [] - const chunks = source.split(/(?=\bdefineTerm\()/) - for (const chunk of chunks) { - if (!/^\s*defineTerm\s*\(\s*"/.test(chunk)) continue - const m = chunk.match(/defineTerm\(\s*"([^"]+)",\s*"([^"]+)",\s*"([^"]+)"/) - if (!m) continue - const [, term, englishTranslation, definition] = m - const relatedTerms: string[] = [] - const rtBlock = chunk.match(/relatedTerms\s*:\s*\[([^\]]*)\]/) - if (rtBlock) { - for (const rt of rtBlock[1].matchAll(/"([^"]+)"/g)) relatedTerms.push(rt[1]) - } - entries.push({ - path: `/documentation/comptabilité/ressources/glossaire/${toSlug(term)}`, - title: term, - description: definition, - section: "Comptabilité", - navGroup: "Glossaire", - navLabel: term, - content: [ - term, - englishTranslation, - definition, - ...relatedTerms, - ].join(" "), - }) - } - return entries -} - -function docsSearchIndexPlugin(): Plugin { - const pkgRoot = resolve(__dirname) - const accountsDataPath = resolve(pkgRoot, "src/features/docs/accounting/resources/accounts/accountsData.ts") - const glossaryDataPath = resolve(pkgRoot, "src/features/docs/accounting/resources/glossary/glossaryData.ts") - - function buildIndex(): string { - const pageEntries = DOC_PAGE_MANIFEST.map((entry) => { - const filePath = resolve(pkgRoot, entry.file) - let source = "" - try { - source = readFileSync(filePath, "utf-8") - } catch { - console.warn(`[docs-search] Could not read ${entry.file}`) - } - const content = extractDocPageContent(source) - return { - path: entry.path, - title: extractTitle(source, entry.navLabel), - description: extractDescription(source, ""), - section: entry.section, - navGroup: entry.navGroup, - navLabel: entry.navLabel, - content: [ - entry.navGroup, - entry.navLabel, - content, - ] - .filter(Boolean) - .join(" "), - } - }) - - const accountEntries = extractAccountEntries(readFileSync(accountsDataPath, "utf-8")) - const glossaryEntries = extractGlossaryEntries(readFileSync(glossaryDataPath, "utf-8")) - - const entries = [ - ...pageEntries, - ...accountEntries, - ...glossaryEntries, - ] - return `export const docsSearchIndex = ${JSON.stringify(entries, null, 4)};` - } - - return { - name: "docs-search-index", - resolveId(id) { - if (id === DOCS_SEARCH_VIRTUAL_MODULE_ID) return RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID - }, - load(id) { - if (id === RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID) return buildIndex() - }, - handleHotUpdate({ file, server }) { - const isDocPage = DOC_PAGE_MANIFEST.some((e) => file.endsWith(e.file.replace(/\//g, "/"))) - const isDataFile = file === accountsDataPath || file === glossaryDataPath - if (isDocPage || isDataFile) { - const mod = server.moduleGraph.getModuleById(RESOLVED_DOCS_SEARCH_VIRTUAL_MODULE_ID) - if (mod) server.moduleGraph.invalidateModule(mod) - server.ws.send({ - type: "full-reload", - }) - } - }, - } -} - -/** Extract the `title` prop from a DocHeader (falls back to navLabel). */ -function extractTitle(source: string, fallback: string): string { - const m = source.match(/DocHeader[^>]*\btitle\s*=\s*"([^"]+)"/) - if (m) return m[1] - // Custom pages with

or plain heading text - const h1 = source.match(/]*>\s*([^<\n]{3,})\s*<\/h1>/) - if (h1) return h1[1].trim() - return fallback -} - -/** Extract the `description` prop from a DocHeader, falling back to

below

. */ -function extractDescription(source: string, fallback: string): string { - const m = source.match(/DocHeader[^>]*\bdescription\s*=\s*"([^"]+)"/) - if (m) return m[1] - return fallback -} - -function fontPreloadPlugin(): Plugin { - return { - name: "font-preload", - transformIndexHtml: { - order: "post", - handler(_html, ctx) { - const fontAssets = (ctx.bundle ? Object.keys(ctx.bundle) : []).filter((name) => name.endsWith(".woff2")) - return fontAssets.map((font) => ({ - tag: "link", - attrs: { - rel: "preload", - as: "font", - type: "font/woff2", - href: `/${font}`, - crossorigin: "anonymous", - }, - injectTo: "head" as const, - })) - }, - }, - } -} - -function sitemapPlugin(): Plugin { - return { - name: "sitemap-generator", - closeBundle() { - const baseUrl = "https://arrhes.com" - const today = new Date().toISOString().split("T")[0] - - // Static public routes - const staticRoutes = [ - { - path: "/", - priority: "1.0", - changefreq: "weekly", - }, - { - path: "/connexion", - priority: "0.5", - changefreq: "monthly", - }, - { - path: "/inscription", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/mot-de-passe-oublié", - priority: "0.5", - changefreq: "monthly", - }, - - // General docs - { - path: "/documentation", - priority: "0.8", - changefreq: "weekly", - }, - { - path: "/documentation/fonctionnalités", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/philosophie", - priority: "0.5", - changefreq: "monthly", - }, - { - path: "/documentation/tarifs", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/support", - priority: "0.5", - changefreq: "monthly", - }, - { - path: "/documentation/mentions-légales", - priority: "0.3", - changefreq: "yearly", - }, - { - path: "/documentation/cgu", - priority: "0.3", - changefreq: "yearly", - }, - { - path: "/documentation/confidentialité", - priority: "0.3", - changefreq: "yearly", - }, - - // Accounting docs - { - path: "/documentation/comptabilité", - priority: "0.8", - changefreq: "weekly", - }, - { - path: "/documentation/comptabilité/introduction", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/partie-double", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/écritures", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/comptes/introduction", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/comptes/classes", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/comptes/liste", - priority: "0.8", - changefreq: "weekly", - }, - { - path: "/documentation/comptabilité/documents", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/journal", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/grand-livre", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/balance", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/bilan", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/compte-de-résultat", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/annexe", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/documents/fec", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/scénarios", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/comptabilité/glossaire", - priority: "0.7", - changefreq: "monthly", - }, - - // Dashboard docs - { - path: "/documentation/dashboard", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/démarrage", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/organisations", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/exercices", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/écritures", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/stockage", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/documents", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/facturation", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/màj", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/assistant", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/assistant/modèles", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/assistant/outils", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/dashboard/assistant/ocr", - priority: "0.6", - changefreq: "monthly", - }, - - // API docs - { - path: "/documentation/api", - priority: "0.7", - changefreq: "monthly", - }, - { - path: "/documentation/api/introduction", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/api/authentification", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/api/organisation", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/api/exercice", - priority: "0.6", - changefreq: "monthly", - }, - { - path: "/documentation/api/stockage", - priority: "0.6", - changefreq: "monthly", - }, - ] - - // Extract dynamic account slugs from source - const accountsDataPath = resolve( - __dirname, - "src/features/docs/accounting/resources/accounts/accountsData.ts", - ) - const accountsSrc = readFileSync(accountsDataPath, "utf-8") - const accountSlugs = [ - ...accountsSrc.matchAll(/defineAccount\(\s*\n?\s*"([^"]+)"/g), - ].map((m) => m[1]) - - // Extract dynamic glossary slugs from source - const glossaryDataPath = resolve( - __dirname, - "src/features/docs/accounting/resources/glossary/glossaryData.ts", - ) - const glossarySrc = readFileSync(glossaryDataPath, "utf-8") - // The toSlug function: lowercase, NFD normalize, strip diacritics, replace non-alnum with -, trim - - const glossaryTerms = [ - ...glossarySrc.matchAll(/defineTerm\(\s*\n?\s*"([^"]+)"/g), - ].map((m) => m[1]) - const toSlug = (term: string) => - term - .toLowerCase() - .normalize("NFD") - .replace(/[\u0300-\u036f]/g, "") - .replace(/[^a-z0-9]+/g, "-") - .replace(/(^-|-$)/g, "") - const glossarySlugs = glossaryTerms.map(toSlug) - - // Extract scenario paths directly from scenariosData.ts - const scenariosDataPath = resolve( - __dirname, - "src/features/docs/accounting/resources/scenarios/scenariosData.ts", - ) - const scenariosSrc = readFileSync(scenariosDataPath, "utf-8") - const scenarioPaths = [ - ...scenariosSrc.matchAll(/path:\s*"(\/documentation\/comptabilité\/scénarios\/[^"]+)"/g), - ].map((m) => m[1]) - - // Build URL entries - const routeMap = new Map< - string, - { - changefreq: string - priority: string - } - >() - const addRoute = (path: string, changefreq: string, priority: string) => { - if (!routeMap.has(path)) { - routeMap.set(path, { - changefreq, - priority, - }) - } - } - - for (const route of staticRoutes) { - addRoute(route.path, route.changefreq, route.priority) - } - - for (const slug of accountSlugs) { - addRoute(`/documentation/comptabilité/comptes/liste/${slug}`, "monthly", "0.5") - } - - for (const slug of glossarySlugs) { - addRoute(`/documentation/comptabilité/glossaire/${slug}`, "monthly", "0.5") - } - - for (const path of scenarioPaths) { - addRoute(path, "monthly", "0.5") - } - - const urls = [ - ...routeMap.entries(), - ] - .sort(([pathA], [pathB]) => pathA.localeCompare(pathB, "fr")) - .map( - ([path, metadata]) => ` - ${encodeURI(`${baseUrl}${path}`)} - ${today} - ${metadata.changefreq} - ${metadata.priority} - `, - ) - - const sitemap = ` - -${urls.join("\n")} - -` - const outPath = resolve(__dirname, "build/sitemap.xml") - writeFileSync(outPath, sitemap, "utf-8") - - console.log(`[sitemap] Generated sitemap.xml with ${urls.length} URLs`) - }, - } -} +import { defineConfig, type Plugin, build as viteBuild } from "vite" +import { docsSearchIndexPlugin } from "./plugins/docsSearchIndexPlugin" +import { fontPreloadPlugin } from "./plugins/fontPreloadPlugin" +import { prerenderPlugin } from "./plugins/prerenderPlugin" +import { sitemapPlugin } from "./plugins/sitemapPlugin" export default defineConfig(() => { return { @@ -948,6 +16,7 @@ export default defineConfig(() => { fontPreloadPlugin(), sitemapPlugin(), docsSearchIndexPlugin(), + prerenderPlugin(), ], assetsInclude: [ "**/*.md", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ea00c7f3..f87f4037 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -140,9 +140,6 @@ importers: '@pandacss/dev': specifier: 1.11.0 version: 1.11.0(typescript@6.0.3) - '@radix-ui/react-switch': - specifier: 1.2.6 - version: 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@tabler/icons-react': specifier: 3.42.0 version: 3.42.0(react@19.2.6) @@ -186,15 +183,6 @@ importers: '@hookform/resolvers': specifier: 5.2.2 version: 5.2.2(react-hook-form@7.75.0(react@19.2.6)) - '@radix-ui/react-context-menu': - specifier: 2.2.16 - version: 2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': - specifier: 1.2.4 - version: 1.2.4(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-tooltip': - specifier: 1.2.8 - version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@react-pdf/renderer': specifier: 4.5.1 version: 4.5.1(react@19.2.6) @@ -537,28 +525,24 @@ packages: engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - libc: [musl] '@biomejs/cli-linux-arm64@2.4.14': resolution: {integrity: sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - libc: [glibc] '@biomejs/cli-linux-x64-musl@2.4.14': resolution: {integrity: sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - libc: [musl] '@biomejs/cli-linux-x64@2.4.14': resolution: {integrity: sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - libc: [glibc] '@biomejs/cli-win32-arm64@2.4.14': resolution: {integrity: sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==} @@ -1069,21 +1053,6 @@ packages: cpu: [x64] os: [win32] - '@floating-ui/core@1.7.5': - resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} - - '@floating-ui/dom@1.7.6': - resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} - - '@floating-ui/react-dom@2.1.8': - resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - - '@floating-ui/utils@0.2.11': - resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} - '@google-cloud/aiplatform@6.7.0': resolution: {integrity: sha512-CxMkLxRPiJ6fUd9gLiM8tyENX58b9xuX+86RG8wXfYyEUqvZQZdvpSnHq50EQcsn9jzqPGeMkEFHdrO7+ugvCg==} engines: {node: '>=18'} @@ -1346,355 +1315,6 @@ packages: peerDependencies: typescript: '>=4.1' - '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - - '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-context-menu@2.2.16': - resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-direction@1.1.1': - resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-menu@2.1.16': - resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-roving-focus@1.1.11': - resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-slot@1.2.4': - resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-switch@1.2.6': - resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-tooltip@1.2.8': - resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-previous@1.1.1': - resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-visually-hidden@1.2.3': - resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} - peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - - '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - '@react-pdf/fns@3.1.3': resolution: {integrity: sha512-0I7pApDr1/RLAKbizuLy/IHTEa93LSPy/bEwYniboC3Xqnp6Od8xFJKbKEzGw2wh/5zKFFwl00g4t9RwgIMc3w==} @@ -1773,42 +1393,36 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} @@ -2315,10 +1929,6 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -2567,9 +2177,6 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -2905,10 +2512,6 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} - get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} - get-port@5.1.1: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} engines: {node: '>=8'} @@ -3194,56 +2797,48 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] lightningcss-linux-arm64-gnu@1.32.0: resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] lightningcss-linux-arm64-musl@1.31.1: resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] lightningcss-linux-x64-gnu@1.31.1: resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] lightningcss-linux-x64-musl@1.31.1: resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] lightningcss-win32-arm64-msvc@1.31.1: resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} @@ -3787,36 +3382,6 @@ packages: '@types/react': '>=18' react: '>=18' - react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - react-remove-scroll@2.7.2: - resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - react@19.2.6: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} @@ -4163,26 +3728,6 @@ packages: peerDependencies: browserslist: '>= 4.21.0' - use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -5196,23 +4741,6 @@ snapshots: '@esbuild/win32-x64@0.27.7': optional: true - '@floating-ui/core@1.7.5': - dependencies: - '@floating-ui/utils': 0.2.11 - - '@floating-ui/dom@1.7.6': - dependencies: - '@floating-ui/core': 1.7.5 - '@floating-ui/utils': 0.2.11 - - '@floating-ui/react-dom@2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@floating-ui/dom': 1.7.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - - '@floating-ui/utils@0.2.11': {} - '@google-cloud/aiplatform@6.7.0': dependencies: google-gax: 5.0.6 @@ -5624,347 +5152,6 @@ snapshots: '@qdrant/js-client-rest': 1.17.0(typescript@6.0.3) typescript: 6.0.3 - '@radix-ui/primitive@1.1.3': {} - - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - aria-hidden: 1.2.6 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/rect': 1.1.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-switch@1.2.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/rect': 1.1.1 - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.6)': - dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': - dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) - - '@radix-ui/rect@1.1.1': {} - '@react-pdf/fns@3.1.3': {} '@react-pdf/font@4.0.8': @@ -6735,10 +5922,6 @@ snapshots: ansi-styles@6.2.3: {} - aria-hidden@1.2.6: - dependencies: - tslib: 2.8.1 - assertion-error@2.0.1: {} astral-regex@2.0.0: {} @@ -6949,8 +6132,6 @@ snapshots: detect-libc@2.1.2: {} - detect-node-es@1.1.0: {} - devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -7322,8 +6503,6 @@ snapshots: hasown: 2.0.3 math-intrinsics: 1.1.0 - get-nonce@1.0.1: {} - get-port@5.1.1: {} get-proto@1.0.1: @@ -8295,33 +7474,6 @@ snapshots: transitivePeerDependencies: - supports-color - react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.6): - dependencies: - react: 19.2.6 - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.6) - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.6): - dependencies: - react: 19.2.6 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.6) - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.6) - tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.6) - use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.6) - optionalDependencies: - '@types/react': 19.2.14 - - react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.6): - dependencies: - get-nonce: 1.0.1 - react: 19.2.6 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - react@19.2.6: {} readable-stream@3.6.2: @@ -8706,21 +7858,6 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.6): - dependencies: - react: 19.2.6 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - - use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.6): - dependencies: - detect-node-es: 1.1.0 - react: 19.2.6 - tslib: 2.8.1 - optionalDependencies: - '@types/react': 19.2.14 - use-sync-external-store@1.6.0(react@19.2.6): dependencies: react: 19.2.6 From 757c98e6b52a309b888b9cd139fcc74f146c2172 Mon Sep 17 00:00:00 2001 From: &mile Date: Tue, 19 May 2026 16:35:31 +0200 Subject: [PATCH 11/14] feat(docs): align CLI and API docs, add DocCode to table commands - Remove organisations GET/POST from API docs (dashboard-only) - Add org delete CLI command + doc - Add entries CRUD, compute, lines, tags to CLI - Add years settle-balance-sheet/settle-income-statement to CLI - Create balance-sheets and income-statements CLI commands + docs - Add XBRL exports to CLI - Register all new commands in CLI index - Remove DocNextPage component from all doc pages - Make --url optional in cli login (default: https://api.arrhes.com) - Wrap all CLI command table cells with DocCode component - Update DocTable to accept ReactNode rows --- .github/workflows/cli-release.yml | 174 +++ .gitignore | 4 + biome.json | 2 +- .../.pnpm-workspace-state-v1.json | 48 + .../checkAdminUserSessionMiddleware.ts | 4 +- ...onMiddleware.ts => checkAuthMiddleware.ts} | 31 +- .../requireCookieSessionMiddleware.ts | 21 + .../requireOrganizationMiddleware.ts | 12 + .../resolveOrganizationMiddleware.ts | 21 +- .../organizationPayment/readOneInvoice.ts | 36 - .../organizationUsersRoutes.ts | 10 - .../entries/$idEntry/deleteOneEntry.ts | 31 - .../$idEntryLine/readOneEntryLine.ts | 35 - .../$idEntry/entryTags/removeOneEntryTag.ts | 31 - .../$idYear/entries/$idEntry/readOneEntry.ts | 31 - .../auth/$idYear/entries/readAllEntries.ts | 30 - .../auth/$idYear/entries/readAllEntryTags.ts | 30 - .../auth/$idYear/files/$idFile/readOneFile.ts | 30 - .../routes/auth/$idYear/files/readAllFiles.ts | 30 - .../folders/$idFolder/deleteOneFolder.ts | 30 - .../folders/$idFolder/readOneFolder.ts | 30 - .../folders/$idFolder/updateOneFolder.ts | 36 - .../auth/$idYear/folders/readAllFolders.ts | 30 - .../src/routes/auth/$idYear/readOneYear.ts | 30 - .../accounts/$idAccount/deleteOneAccount.ts | 31 - .../accounts/$idAccount/readOneAccount.ts | 31 - .../yearSettings/accounts/readAllAccounts.ts | 30 - .../$idYear/yearSettings/general/closeYear.ts | 35 - .../yearSettings/general/deleteOneYear.ts | 30 - .../journals/$idJournal/deleteOneJournal.ts | 31 - .../journals/$idJournal/readOneJournal.ts | 31 - .../yearSettings/journals/readAllJournals.ts | 30 - .../yearSettings/tags/$idTag/deleteOneTag.ts | 31 - .../yearSettings/tags/$idTag/readOneTag.ts | 31 - .../yearSettings/tags/$idTag/updateOneTag.ts | 37 - .../$idYear/yearSettings/tags/createOneTag.ts | 40 - .../$idYear/yearSettings/tags/readAllTags.ts | 30 - .../agent/agentFile/createOneAgentFile.ts | 16 +- .../auth/agent/agentMessage/agentUndo.ts | 8 +- .../agentMessage/createOneAgentMessage.ts | 4 +- .../agentMessage/getStreamForAgentMessage.ts | 4 +- .../agentMessage/readAllAgentMessages.ts | 4 +- .../agentSession/createOneAgentSession.ts | 4 +- .../agentSession/deleteOneAgentSession.ts | 4 +- .../agentSession/readAllAgentSessions.ts | 4 +- .../agent/agentSession/readOneAgentSession.ts | 4 +- .../agentSession/updateOneAgentSession.ts | 4 +- .../routes/auth/agent/searchReferenceable.ts | 4 +- packages/api/src/routes/auth/authRoute.ts | 10 +- .../$idOrganization/$idOrganizationRoutes.ts | 10 +- .../apiKey/apiKeyRoutes.ts | 0 .../apiKey/createOneApiKey.ts | 26 +- .../apiKey/deleteOneApiKey.ts | 24 +- .../apiKey/readAllApiKeys.ts | 22 +- .../deleteOneOrganization.ts | 22 +- .../cancelOrganizationBilling.ts | 24 +- .../organizationPayment/cancelSubscription.ts | 10 +- .../organizationPayment/createFirstPayment.ts | 10 +- .../createPaymentMethodCheckout.ts | 30 +- .../createResourceSubscription.ts | 32 +- .../createWalletTopUpCheckout.ts | 30 +- .../createWalletWithdrawal.ts | 28 +- .../generateInvoiceGetSignedUrl.ts | 22 +- .../organizationPaymentsRoutes.ts | 0 .../organizationPayment/readAllInvoices.ts | 22 +- .../readAllOrganizationBillings.ts | 22 +- .../readAllOrganizationPayments.ts | 22 +- .../organizationPayment/readOneInvoice.ts | 40 + .../readOrganizationBilling.ts | 24 +- .../updateLicenceSubscription.ts | 24 +- .../updateOcrSubscription.ts | 35 +- .../updateStorageSubscription.ts | 32 +- .../updateTokensSubscription.ts | 38 +- .../organizationSettingsRoutes.ts | 0 .../createOneOrganizationUser.ts | 26 +- .../deleteOneOrganizationUser.ts | 24 +- .../organizationUsersRoutes.ts} | 6 +- .../readAllOrganizationUsers.ts | 20 +- .../readOneOrganizationUser.ts | 14 +- .../updateOneOrganizationUser.ts | 26 +- .../updateOneOrganization.ts | 24 +- .../$idOrganization/readOneOrganization.ts | 20 +- .../years}/$idYear/$idYearRoutes.ts | 8 +- .../entries/$idEntry/$idEntryRoutes.ts | 0 .../entries/$idEntry/deleteOneEntry.ts | 35 + .../entries/$idEntry/duplicateOneEntry.ts | 28 +- .../$idEntryLine/$idEntryLineRoutes.ts | 0 .../$idEntryLine/deleteOneEntryLine.ts | 16 +- .../$idEntryLine/readOneEntryLine.ts | 39 + .../$idEntryLine/updateOneEntryLine.ts | 18 +- .../$idEntry/entryLines/createOneEntryLine.ts | 20 +- .../$idEntry/entryLines/entryLinesRoutes.ts | 0 .../$idEntry/entryLines/readAllEntryLines.ts | 18 +- .../entryLines/updateManyEntryLines.ts | 20 +- .../$idEntry/entryTags/addOneEntryTag.ts | 20 +- .../$idEntry/entryTags/entryTagsRoutes.ts | 0 .../$idEntry/entryTags/removeOneEntryTag.ts | 35 + .../$idYear/entries/$idEntry/readOneEntry.ts | 35 + .../entries/$idEntry/reverseOneEntry.ts | 28 +- .../entries/$idEntry/updateOneEntry.ts | 20 +- .../years}/$idYear/entries/createOneEntry.ts | 20 +- .../entries/createOneEntryFromTemplate.ts | 22 +- .../years}/$idYear/entries/entriesRoutes.ts | 0 .../years/$idYear/entries/readAllEntries.ts | 34 + .../years/$idYear/entries/readAllEntryTags.ts | 34 + .../years/$idYear/exports/exportsRoutes.ts} | 4 +- .../exports}/generateBalanceSheetXml.ts | 26 +- .../years/$idYear/exports/generateFec.ts | 236 ++++ .../exports}/generateIncomeStatementXml.ts | 26 +- .../$idYear/files/$idFile/$idFileRoutes.ts | 0 .../$idYear/files/$idFile/deleteOneFile.ts | 22 +- .../files/$idFile/finalizeFileUpload.ts | 18 +- .../$idFile/generateFileDeleteSignedUrl.ts | 20 +- .../files/$idFile/generateFileGetSignedUrl.ts | 20 +- .../files/$idFile/generateFilePutSignedUrl.ts | 22 +- .../years}/$idYear/files/$idFile/ocrFile.ts | 34 +- .../$idYear/files/$idFile/readOneFile.ts | 34 + .../$idYear/files/$idFile/updateOneFile.ts | 20 +- .../years}/$idYear/files/createOneFile.ts | 20 +- .../years}/$idYear/files/filesRoutes.ts | 0 .../years/$idYear/files/readAllFiles.ts | 34 + .../folders/$idFolder/$idFolderRoutes.ts | 0 .../folders/$idFolder/deleteOneFolder.ts | 34 + .../folders/$idFolder/readOneFolder.ts | 34 + .../folders/$idFolder/updateOneFolder.ts | 40 + .../years}/$idYear/folders/createOneFolder.ts | 20 +- .../years}/$idYear/folders/foldersRoutes.ts | 0 .../years/$idYear/folders/readAllFolders.ts | 34 + .../years/$idYear/readOneYear.ts | 34 + .../accounts/$idAccount/$idAccountRoutes.ts | 0 .../accounts/$idAccount/deleteOneAccount.ts | 35 + .../accounts/$idAccount/readOneAccount.ts | 35 + .../accounts/$idAccount/updateOneAccount.ts | 20 +- .../yearSettings/accounts/accountsRoutes.ts | 0 .../yearSettings/accounts/createOneAccount.ts | 22 +- .../yearSettings/accounts/generateAccounts.ts | 19 +- .../yearSettings/accounts/readAllAccounts.ts | 34 + .../$idBalanceSheet/$idBalanceSheetRoutes.ts | 0 .../$idBalanceSheet/deleteOneBalanceSheet.ts | 16 +- .../$idBalanceSheet/readOneBalanceSheet.ts | 16 +- .../$idBalanceSheet/updateOneBalanceSheet.ts | 18 +- .../balanceSheets/balanceSheetsRoutes.ts | 0 .../connectAccountsToBalanceSheets.ts | 14 +- .../balanceSheets/createOneBalanceSheet.ts | 18 +- .../balanceSheets/generateBalanceSheets.ts | 16 +- .../balanceSheets/readAllBalanceSheets.ts | 16 +- .../$idComputation/$idComputationRoutes.ts | 0 .../$idComputationIncomeStatementRoutes.ts | 0 .../deleteOneComputationIncomeStatement.ts | 16 +- .../readOneComputationIncomeStatement.ts | 16 +- .../updateOneComputationIncomeStatement.ts | 18 +- .../computationIncomeStatementsRoutes.ts | 0 .../createOneComputationIncomeStatement.ts | 18 +- .../readAllComputationIncomeStatements.ts | 16 +- .../$idComputation/deleteOneComputation.ts | 16 +- .../$idComputation/readOneComputation.ts | 16 +- .../$idComputation/updateOneComputation.ts | 18 +- .../computations/computationsRoutes.ts | 0 .../computations/createOneComputation.ts | 18 +- .../computations/generateComputations.ts | 16 +- .../computations/readAllComputations.ts | 16 +- .../$idYear/yearSettings/general/closeYear.ts | 39 + .../yearSettings/general/deleteOneYear.ts | 34 + .../yearSettings/general/generalRoutes.ts | 0 .../$idYear/yearSettings/general/openYear.ts | 12 +- .../general/settleBalanceSheet.ts | 30 +- .../general/settleIncomeStatement.ts | 32 +- .../yearSettings/general/updateOneYear.ts | 20 +- .../$idIncomeStatementRoutes.ts | 0 .../deleteOneIncomeStatement.ts | 16 +- .../readOneIncomeStatement.ts | 16 +- .../updateOneIncomeStatement.ts | 18 +- .../connectAccountsToIncomeStatements.ts | 14 +- .../createOneIncomeStatement.ts | 18 +- .../generateIncomeStatements.ts | 16 +- .../incomeStatementsRoutes.ts | 0 .../readAllIncomeStatements.ts | 16 +- .../journals/$idJournal/$idJournalRoute.ts | 0 .../journals/$idJournal/deleteOneJournal.ts | 35 + .../journals/$idJournal/readOneJournal.ts | 35 + .../journals/$idJournal/updateOneJournal.ts | 20 +- .../yearSettings/journals/createOneJournal.ts | 20 +- .../yearSettings/journals/generateJournals.ts | 17 +- .../yearSettings/journals/journalsRoutes.ts | 0 .../yearSettings/journals/readAllJournals.ts | 34 + .../yearSettings/tags/$idTag/$idTagRoutes.ts | 0 .../yearSettings/tags/$idTag/deleteOneTag.ts | 35 + .../yearSettings/tags/$idTag/readOneTag.ts | 35 + .../yearSettings/tags/$idTag/updateOneTag.ts | 41 + .../$idYear/yearSettings/tags/createOneTag.ts | 44 + .../$idYear/yearSettings/tags/readAllTags.ts | 34 + .../$idYear/yearSettings/tags/tagsRoutes.ts | 0 .../$idYear/yearSettings/yearSettingsRoute.ts | 0 .../$idOrganization/years/createOneYear.ts | 30 +- .../$idOrganization/years/readAllYears.ts | 20 +- .../$idOrganization/years/yearsRoutes.ts | 2 +- .../activateOrganizationMembership.ts | 4 +- .../auth/organizations/addNewOrganization.ts | 4 +- .../organizations/getAllMyOrganizations.ts | 4 +- .../auth/organizations/organizationsRoutes.ts | 8 +- .../src/routes/auth/settings/activateUser.ts | 8 +- .../src/routes/auth/settings/deleteUser.ts | 8 +- .../routes/auth/settings/readUserSession.ts | 8 +- .../auth/settings/resendEmailValidation.ts | 4 +- .../routes/auth/settings/settingsRoutes.ts | 16 +- .../src/routes/auth/settings/updateUser.ts | 8 +- .../routes/auth/settings/updateUserEmail.ts | 8 +- .../auth/settings/updateUserPassword.ts | 4 +- .../routes/auth/settings/validateUserEmail.ts | 8 +- .../routes/auth/support/createOneTicket.ts | 8 +- .../auth/support/createOneTicketMessage.ts | 4 +- .../auth/support/readAllTicketMessages.ts | 4 +- .../src/routes/auth/support/readAllTickets.ts | 8 +- .../src/routes/auth/support/readOneTicket.ts | 8 +- .../routes/auth/support/updateOneTicket.ts | 8 +- .../auth/support/updateOneTicketStatus.ts | 4 +- .../api/src/routes/public/mollieWebhook.ts | 4 +- packages/api/src/routes/public/publicRoute.ts | 12 +- .../routes/public/{ => user}/resetPassword.ts | 16 +- .../routes/public/{ => user}/sendMagicLink.ts | 10 +- .../src/routes/public/{ => user}/signIn.ts | 24 +- .../src/routes/public/{ => user}/signOut.ts | 22 +- .../src/routes/public/{ => user}/signUp.ts | 24 +- packages/api/src/routes/routes.ts | 6 +- .../api/src/utilities/cookies/parseCookies.ts | 2 +- .../api/src/utilities/cookies/signString.ts | 2 +- .../api/src/utilities/cookies/unsignString.ts | 4 +- packages/api/src/utilities/getEnv.ts | 2 +- packages/api/src/utilities/registerRoute.ts | 22 + packages/api/src/utilities/response.ts | 4 +- packages/api/src/utilities/safeParseJSON.ts | 4 +- packages/api/src/utilities/sql/deleteMany.ts | 2 +- packages/api/src/utilities/sql/deleteOne.ts | 2 +- packages/api/src/utilities/sql/insertMany.ts | 2 +- packages/api/src/utilities/sql/insertOne.ts | 2 +- packages/api/src/utilities/sql/selectMany.ts | 2 +- packages/api/src/utilities/sql/selectOne.ts | 2 +- packages/api/src/utilities/sql/updateOne.ts | 2 +- .../api/src/utilities/storage/deleteObject.ts | 6 +- .../storage/generateDeleteSignedUrl.ts | 6 +- .../utilities/storage/generateGetSignedUrl.ts | 8 +- .../utilities/storage/generatePutSignedUrl.ts | 6 +- .../api/src/utilities/storage/getObject.ts | 6 +- .../api/src/utilities/storage/putObject.ts | 6 +- packages/api/src/utilities/validate.ts | 2 +- packages/cli/arrhes.sh | 1060 +++++++++++++++ packages/cli/install.sh | 32 + packages/cli/package.json | 7 + .../src/components/values/routePath.ts | 1 + .../agent/agentFile/createOneAgentFile.ts | 3 +- .../agentMessage/createOneAgentMessage.ts | 3 +- .../agentMessage/getStreamForAgentMessage.ts | 3 +- .../agentMessage/readAllAgentMessages.ts | 3 +- .../agentSession/createOneAgentSession.ts | 3 +- .../agentSession/deleteOneAgentSession.ts | 3 +- .../agentSession/readAllAgentSessions.ts | 3 +- .../agent/agentSession/readOneAgentSession.ts | 3 +- .../agentSession/updateOneAgentSession.ts | 3 +- .../dashboard/auth/agent/getChatStream.ts | 3 +- .../auth/agent/searchReferenceable.ts | 3 +- .../dashboard/auth/agent/undoAgentAction.ts | 3 +- .../organizations/$idOrganization/index.ts | 5 +- .../apiKey/createOneApiKey.ts | 3 +- .../apiKey/deleteOneApiKey.ts | 3 +- .../apiKey/readAllApiKeys.ts | 3 +- .../deleteOneOrganization.ts | 3 +- .../cancelOrganizationBilling.ts | 3 +- .../organizationPayment/cancelSubscription.ts | 3 +- .../organizationPayment/createFirstPayment.ts | 3 +- .../createPaymentMethodCheckout.ts | 3 +- .../createResourceSubscription.ts | 3 +- .../createWalletTopUpCheckout.ts | 3 +- .../createWalletWithdrawal.ts | 3 +- .../generateInvoiceGetSignedUrl.ts | 3 +- .../organizationPayment/readAllInvoices.ts | 3 +- .../readAllOrganizationBillings.ts | 3 +- .../readAllOrganizationPayments.ts | 3 +- .../organizationPayment/readOneInvoice.ts | 3 +- .../readOrganizationBilling.ts | 3 +- .../updateLicenceSubscription.ts | 3 +- .../updateOcrSubscription.ts | 3 +- .../updateStorageSubscription.ts | 3 +- .../updateTokensSubscription.ts | 3 +- .../createOneOrganizationUser.ts | 3 +- .../deleteOneOrganizationUser.ts | 3 +- .../readAllOrganizationUsers.ts | 3 +- .../readOneOrganizationUser.ts | 3 +- .../updateOneOrganizationUser.ts | 3 +- .../updateOneOrganization.ts | 3 +- .../$idOrganization/readOneOrganization.ts | 3 +- .../entries/$idEntry/computeOneEntry.ts | 3 +- .../entries/$idEntry/deleteOneEntry.ts | 3 +- .../entries/$idEntry/duplicateOneEntry.ts | 3 +- .../$idEntryLine/deleteOneEntryLine.ts | 3 +- .../$idEntryLine/readOneEntryLine.ts | 3 +- .../$idEntryLine/updateOneEntryLine.ts | 3 +- .../$idEntry/entryLines/createOneEntryLine.ts | 3 +- .../$idEntry/entryLines/readAllEntryLines.ts | 3 +- .../entryLines/updateManyEntryLines.ts | 3 +- .../$idEntry/entryTags/addOneEntryTag.ts | 3 +- .../$idEntry/entryTags/removeOneEntryTag.ts | 3 +- .../$idYear/entries/$idEntry/readOneEntry.ts | 3 +- .../entries/$idEntry/reverseOneEntry.ts | 3 +- .../entries/$idEntry/updateOneEntry.ts | 3 +- .../years/$idYear/entries/createOneEntry.ts | 3 +- .../entries/createOneEntryFromTemplate.ts | 3 +- .../years/$idYear/entries/readAllEntries.ts | 3 +- .../years/$idYear/entries/readAllEntryTags.ts | 3 +- .../generateBalanceSheetXml.ts | 3 +- .../years/$idYear/exports/generateFec.ts | 18 + .../generateIncomeStatementXml.ts | 3 +- .../$idYear/{reports => exports}/index.ts | 1 + .../$idYear/files/$idFile/deleteOneFile.ts | 3 +- .../files/$idFile/finalizeFileUpload.ts | 3 +- .../$idFile/generateFileDeleteSignedUrl.ts | 3 +- .../files/$idFile/generateFileGetSignedUrl.ts | 3 +- .../files/$idFile/generateFilePutSignedUrl.ts | 3 +- .../years/$idYear/files/$idFile/ocrFile.ts | 3 +- .../$idYear/files/$idFile/readOneFile.ts | 3 +- .../$idYear/files/$idFile/updateOneFile.ts | 3 +- .../years/$idYear/files/createOneFile.ts | 3 +- .../years/$idYear/files/readAllFiles.ts | 3 +- .../folders/$idFolder/deleteOneFolder.ts | 3 +- .../folders/$idFolder/readOneFolder.ts | 3 +- .../folders/$idFolder/updateOneFolder.ts | 3 +- .../years/$idYear/folders/createOneFolder.ts | 3 +- .../years/$idYear/folders/readAllFolders.ts | 3 +- .../years/$idYear/readOneYear.ts | 3 +- .../accounts/$idAccount/deleteOneAccount.ts | 3 +- .../accounts/$idAccount/readOneAccount.ts | 3 +- .../accounts/$idAccount/updateOneAccount.ts | 3 +- .../yearSettings/accounts/createOneAccount.ts | 3 +- .../yearSettings/accounts/generateAccounts.ts | 5 +- .../yearSettings/accounts/readAllAccounts.ts | 3 +- .../$idBalanceSheet/deleteOneBalanceSheet.ts | 3 +- .../$idBalanceSheet/readOneBalanceSheet.ts | 3 +- .../$idBalanceSheet/updateOneBalanceSheet.ts | 3 +- .../connectAccountsToBalanceSheets.ts | 5 +- .../balanceSheets/createOneBalanceSheet.ts | 3 +- .../balanceSheets/generateBalanceSheets.ts | 5 +- .../balanceSheets/readAllBalanceSheets.ts | 3 +- .../deleteOneComputationIncomeStatement.ts | 3 +- .../readOneComputationIncomeStatement.ts | 3 +- .../updateOneComputationIncomeStatement.ts | 3 +- .../createOneComputationIncomeStatement.ts | 3 +- .../readAllComputationIncomeStatements.ts | 3 +- .../$idComputation/deleteOneComputation.ts | 3 +- .../$idComputation/readOneComputation.ts | 3 +- .../$idComputation/updateOneComputation.ts | 3 +- .../computations/createOneComputation.ts | 3 +- .../computations/generateComputations.ts | 5 +- .../computations/readAllComputations.ts | 3 +- .../$idYear/yearSettings/general/closeYear.ts | 3 +- .../yearSettings/general/deleteOneYear.ts | 3 +- .../$idYear/yearSettings/general/openYear.ts | 3 +- .../general/settleBalanceSheet.ts | 3 +- .../general/settleIncomeStatement.ts | 3 +- .../yearSettings/general/updateOneYear.ts | 3 +- .../deleteOneIncomeStatement.ts | 3 +- .../readOneIncomeStatement.ts | 3 +- .../updateOneIncomeStatement.ts | 3 +- .../connectAccountsToIncomeStatements.ts | 5 +- .../createOneIncomeStatement.ts | 3 +- .../generateIncomeStatements.ts | 10 +- .../readAllIncomeStatements.ts | 3 +- .../journals/$idJournal/deleteOneJournal.ts | 3 +- .../journals/$idJournal/readOneJournal.ts | 3 +- .../journals/$idJournal/updateOneJournal.ts | 3 +- .../yearSettings/journals/createOneJournal.ts | 3 +- .../yearSettings/journals/generateJournals.ts | 5 +- .../yearSettings/journals/readAllJournals.ts | 3 +- .../yearSettings/tags/$idTag/deleteOneTag.ts | 3 +- .../yearSettings/tags/$idTag/readOneTag.ts | 3 +- .../yearSettings/tags/$idTag/updateOneTag.ts | 3 +- .../$idYear/yearSettings/tags/createOneTag.ts | 3 +- .../$idYear/yearSettings/tags/readAllTags.ts | 3 +- .../$idOrganization/years/createOneYear.ts | 3 +- .../$idOrganization/years/readAllYears.ts | 3 +- .../activateOrganizationMembership.ts | 3 +- .../auth/organizations/addNewOrganization.ts | 3 +- .../organizations/getAllMyOrganizations.ts | 3 +- .../dashboard/auth/settings/activateUser.ts | 3 +- .../dashboard/auth/settings/deleteUser.ts | 3 +- .../auth/settings/readUserSession.ts | 3 +- .../auth/settings/resendEmailValidation.ts | 3 +- .../dashboard/auth/settings/updateUser.ts | 3 +- .../auth/settings/updateUserEmail.ts | 3 +- .../auth/settings/updateUserPassword.ts | 3 +- .../auth/settings/validateUserEmail.ts | 3 +- .../dashboard/auth/support/createOneTicket.ts | 3 +- .../auth/support/createOneTicketMessage.ts | 3 +- .../auth/support/readAllTicketMessages.ts | 3 +- .../dashboard/auth/support/readAllTickets.ts | 3 +- .../dashboard/auth/support/readOneTicket.ts | 3 +- .../dashboard/auth/support/updateOneTicket.ts | 3 +- .../auth/support/updateOneTicketStatus.ts | 3 +- .../routes/dashboard/public/mollieWebhook.ts | 3 +- .../dashboard/public/user/resetPassword.ts | 3 +- .../dashboard/public/user/sendMagicLink.ts | 3 +- .../routes/dashboard/public/user/signIn.ts | 3 +- .../routes/dashboard/public/user/signOut.ts | 3 +- .../routes/dashboard/public/user/signUp.ts | 3 +- .../metadata/src/utilities/routeDefinition.ts | 6 + .../overlays/popover/popoverRoot.tsx | 21 +- packages/website/plugins/DOC_PAGE_MANIFEST.ts | 5 - .../src/components/document/DocCode.tsx | 19 + .../src/components/document/DocCodeBlock.tsx | 88 ++ .../src/components/document/DocNextPage.tsx | 51 - .../components/document/DocRouteRequest.tsx | 65 +- .../src/components/document/DocTable.tsx | 3 +- .../dashboard/$idYear/YearDataProvider.tsx | 1 + .../dashboard/$idYear/YearDataWrapper.tsx | 1 + .../$idYear/entries/ExportFecFile.tsx | 239 +--- .../dashboard/$idYear/yearDataContext.tsx | 1 + .../website/src/features/docs/DocsLayout.tsx | 1 + .../AccountsAccountingDocPage.tsx | 7 - .../introduction/ClassesAccountingDocPage.tsx | 6 - .../DoubleEntryAccountingDocPage.tsx | 7 - .../introduction/EntriesAccountingDocPage.tsx | 7 - .../IntroductionAccountingDocPage.tsx | 6 - .../introduction/RootAccountingDocPage.tsx | 6 - .../reports/BalanceAccountingDocPage.tsx | 6 - .../reports/BalanceSheetAccountingDocPage.tsx | 6 - .../reports/FecAccountingDocPage.tsx | 6 - .../IncomeStatementAccountingDocPage.tsx | 6 - .../reports/JournalAccountingDocPage.tsx | 6 - .../reports/LedgerAccountingDocPage.tsx | 6 - .../reports/NotesAccountingDocPage.tsx | 6 - .../reports/ReportsAccountingDocPage.tsx | 6 - .../src/features/docs/ai/ModelsAiDocPage.tsx | 6 - .../src/features/docs/ai/OcrAiDocPage.tsx | 4 +- .../features/docs/api/AccountsApiDocPage.tsx | 35 + .../features/docs/api/ApiKeysApiDocPage.tsx | 40 + .../docs/api/AuthenticationApiDocPage.tsx | 33 +- .../docs/api/BalanceSheetsApiDocPage.tsx | 35 + .../docs/api/ComputationsApiDocPage.tsx | 52 + .../features/docs/api/EntriesApiDocPage.tsx | 80 ++ .../docs/api/EntryLinesApiDocPage.tsx | 47 + .../src/features/docs/api/FilesApiDocPage.tsx | 39 +- .../features/docs/api/FoldersApiDocPage.tsx | 36 + .../docs/api/IncomeStatementsApiDocPage.tsx | 69 + .../docs/api/IntroductionApiDocPage.tsx | 84 +- .../features/docs/api/JournalsApiDocPage.tsx | 35 + .../features/docs/api/OrgUsersApiDocPage.tsx | 42 + .../docs/api/OrganizationApiDocPage.tsx | 77 +- .../src/features/docs/api/RootApiDocPage.tsx | 8 +- .../src/features/docs/api/TagsApiDocPage.tsx | 35 + .../docs/api/XBRLReportsApiDocPage.tsx | 52 + .../src/features/docs/api/YearApiDocPage.tsx | 185 +-- .../docs/cli/AuthenticationCliDocPage.tsx | 80 ++ .../features/docs/cli/CommandsCliDocPage.tsx | 145 +++ .../features/docs/cli/DemarrerCliDocPage.tsx | 68 + .../docs/cli/InstallationCliDocPage.tsx | 37 + .../src/features/docs/cli/RootCliDocPage.tsx | 73 ++ .../BalanceSheetsCommandsCliDocPage.tsx | 111 ++ .../commands/ClesApiCommandsCliDocPage.tsx | 80 ++ .../commands/ComptesCommandsCliDocPage.tsx | 146 +++ .../commands/EcrituresCommandsCliDocPage.tsx | 349 +++++ .../commands/ExercicesCommandsCliDocPage.tsx | 215 ++++ .../commands/ExportsCommandsCliDocPage.tsx | 120 ++ .../commands/FichiersCommandsCliDocPage.tsx | 262 ++++ .../IncomeStatementsCommandsCliDocPage.tsx | 193 +++ .../commands/JournauxCommandsCliDocPage.tsx | 120 ++ .../commands/LibellesCommandsCliDocPage.tsx | 93 ++ .../commands/MembresCommandsCliDocPage.tsx | 101 ++ .../cli/commands/OrgCommandsCliDocPage.tsx | 92 ++ .../dashboard/EntriesDashboardDocPage.tsx | 6 - .../docs/dashboard/FilesDashboardDocPage.tsx | 6 - .../GettingStartedDashboardDocPage.tsx | 6 - .../OrganizationsDashboardDocPage.tsx | 6 - .../docs/dashboard/YearsDashboardDocPage.tsx | 6 - .../website/src/features/docs/docSections.tsx | 161 ++- .../website/src/routes/applicationTree.ts | 2 + packages/website/src/routes/root/cliRoute.tsx | 12 + .../root/docs/api/accountsApiDocRoute.tsx | 15 + .../root/docs/api/apiKeysApiDocRoute.tsx | 15 + .../docs/api/balanceSheetsApiDocRoute.tsx | 15 + .../root/docs/api/computationsApiDocRoute.tsx | 15 + .../root/docs/api/entriesApiDocRoute.tsx | 15 + .../root/docs/api/entryLinesApiDocRoute.tsx | 15 + .../root/docs/api/foldersApiDocRoute.tsx | 15 + .../docs/api/incomeStatementsApiDocRoute.tsx | 15 + .../root/docs/api/journalsApiDocRoute.tsx | 15 + .../root/docs/api/orgUsersApiDocRoute.tsx | 15 + .../routes/root/docs/api/tagsApiDocRoute.tsx | 12 + .../root/docs/api/xbrlReportsApiDocRoute.tsx | 15 + .../docs/cli/authenticationCliDocRoute.tsx | 16 + .../root/docs/cli/cliDocLayoutRoute.tsx | 8 + .../balanceSheetsCommandsCliDocRoute.tsx | 15 + .../commands/clesApiCommandsCliDocRoute.tsx | 15 + .../docs/cli/commands/commandsCliDocTree.ts | 29 + .../commands/comptesCommandsCliDocRoute.tsx | 15 + .../commands/ecrituresCommandsCliDocRoute.tsx | 15 + .../commands/exercicesCommandsCliDocRoute.tsx | 15 + .../commands/exportsCommandsCliDocRoute.tsx | 15 + .../commands/fichiersCommandsCliDocRoute.tsx | 15 + .../incomeStatementsCommandsCliDocRoute.tsx | 16 + .../commands/journauxCommandsCliDocRoute.tsx | 15 + .../commands/libellesCommandsCliDocRoute.tsx | 15 + .../commands/membresCommandsCliDocRoute.tsx | 15 + .../cli/commands/orgCommandsCliDocRoute.tsx | 15 + .../root/docs/cli/commandsCliDocRoute.tsx | 8 + .../root/docs/cli/demarrerCliDocRoute.tsx | 15 + .../root/docs/cli/installationCliDocRoute.tsx | 15 + .../routes/root/docs/cli/rootCliDocRoute.tsx | 13 + .../website/src/routes/root/docs/docsTree.ts | 35 +- .../src/utilities/getResponseBodyFromAPI.ts | 64 +- .../website/src/utilities/prefetchYearData.ts | 1 + packages/website/src/utilities/useHTTPData.ts | 4 + pnpm-lock.yaml | 1022 +++++++++++++++ scripts/migrate-handlers.mjs | 115 ++ scripts/migrate-routes.mjs | 1146 +++++++++++++++++ 512 files changed, 10383 insertions(+), 2771 deletions(-) create mode 100644 .github/workflows/cli-release.yml create mode 100644 node_modules_old/.pnpm-workspace-state-v1.json rename packages/api/src/middlewares/{checkUserSessionMiddleware.ts => checkAuthMiddleware.ts} (77%) create mode 100644 packages/api/src/middlewares/requireCookieSessionMiddleware.ts create mode 100644 packages/api/src/middlewares/requireOrganizationMiddleware.ts delete mode 100644 packages/api/src/routes/auth/$idOrganization/organizationPayment/readOneInvoice.ts delete mode 100644 packages/api/src/routes/auth/$idOrganization/organizationUser/organizationUsersRoutes.ts delete mode 100644 packages/api/src/routes/auth/$idYear/entries/$idEntry/deleteOneEntry.ts delete mode 100644 packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts delete mode 100644 packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts delete mode 100644 packages/api/src/routes/auth/$idYear/entries/$idEntry/readOneEntry.ts delete mode 100644 packages/api/src/routes/auth/$idYear/entries/readAllEntries.ts delete mode 100644 packages/api/src/routes/auth/$idYear/entries/readAllEntryTags.ts delete mode 100644 packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts delete mode 100644 packages/api/src/routes/auth/$idYear/files/readAllFiles.ts delete mode 100644 packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts delete mode 100644 packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts delete mode 100644 packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts delete mode 100644 packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts delete mode 100644 packages/api/src/routes/auth/$idYear/readOneYear.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/accounts/readAllAccounts.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/general/closeYear.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/general/deleteOneYear.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/journals/readAllJournals.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/readOneTag.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/updateOneTag.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/tags/createOneTag.ts delete mode 100644 packages/api/src/routes/auth/$idYear/yearSettings/tags/readAllTags.ts rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/$idOrganizationRoutes.ts (51%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/apiKey/apiKeyRoutes.ts (100%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/apiKey/createOneApiKey.ts (59%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/apiKey/deleteOneApiKey.ts (52%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/apiKey/readAllApiKeys.ts (53%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/organizationSettings/deleteOneOrganization.ts (59%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/cancelOrganizationBilling.ts (80%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/cancelSubscription.ts (61%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/createFirstPayment.ts (63%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/createPaymentMethodCheckout.ts (76%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/createResourceSubscription.ts (86%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/createWalletTopUpCheckout.ts (75%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/createWalletWithdrawal.ts (85%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/generateInvoiceGetSignedUrl.ts (60%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/organizationPaymentsRoutes.ts (100%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/readAllInvoices.ts (70%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/readAllOrganizationBillings.ts (60%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/readAllOrganizationPayments.ts (61%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/readOrganizationBilling.ts (67%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/updateLicenceSubscription.ts (68%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/updateOcrSubscription.ts (76%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/updateStorageSubscription.ts (77%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationPayment/updateTokensSubscription.ts (75%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/organizationSettings/organizationSettingsRoutes.ts (100%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationUser/createOneOrganizationUser.ts (72%) rename packages/api/src/routes/auth/{$idOrganization/organizationUser/$idOrganizationUser => organizations/$idOrganization/organizationSettings/organizationUser}/deleteOneOrganizationUser.ts (57%) rename packages/api/src/routes/auth/{$idOrganization/organizationUser/$idOrganizationUser/$idOrganizationUserRoutes.ts => organizations/$idOrganization/organizationSettings/organizationUser/organizationUsersRoutes.ts} (56%) rename packages/api/src/routes/auth/{$idOrganization => organizations/$idOrganization/organizationSettings}/organizationUser/readAllOrganizationUsers.ts (62%) rename packages/api/src/routes/auth/{$idOrganization/organizationUser/$idOrganizationUser => organizations/$idOrganization/organizationSettings/organizationUser}/readOneOrganizationUser.ts (77%) rename packages/api/src/routes/auth/{$idOrganization/organizationUser/$idOrganizationUser => organizations/$idOrganization/organizationSettings/organizationUser}/updateOneOrganizationUser.ts (64%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/organizationSettings/updateOneOrganization.ts (61%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/readOneOrganization.ts (65%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/$idYearRoutes.ts (55%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/$idEntryRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/duplicateOneEntry.ts (77%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/$idEntryLine/$idEntryLineRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts (57%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts (68%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts (70%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/entryLinesRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts (55%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts (73%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts (60%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/entryTags/entryTagsRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/reverseOneEntry.ts (77%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/$idEntry/updateOneEntry.ts (57%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/createOneEntry.ts (52%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/createOneEntryFromTemplate.ts (75%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/entries/entriesRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts rename packages/api/src/routes/auth/{$idYear/reports/reportsRoutes.ts => organizations/$idOrganization/years/$idYear/exports/exportsRoutes.ts} (68%) rename packages/api/src/routes/auth/{$idYear/reports => organizations/$idOrganization/years/$idYear/exports}/generateBalanceSheetXml.ts (91%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts rename packages/api/src/routes/auth/{$idYear/reports => organizations/$idOrganization/years/$idYear/exports}/generateIncomeStatementXml.ts (90%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/$idFileRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/deleteOneFile.ts (59%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/finalizeFileUpload.ts (70%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts (59%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/generateFileGetSignedUrl.ts (59%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/generateFilePutSignedUrl.ts (69%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/ocrFile.ts (83%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/$idFile/updateOneFile.ts (50%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/createOneFile.ts (54%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/files/filesRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/folders/$idFolder/$idFolderRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/folders/createOneFolder.ts (50%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/folders/foldersRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/accounts/$idAccount/$idAccountRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts (62%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/accounts/accountsRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/accounts/createOneAccount.ts (70%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/accounts/generateAccounts.ts (82%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/$idBalanceSheet/$idBalanceSheetRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts (58%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts (58%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts (62%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/balanceSheetsRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts (89%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts (63%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts (83%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts (55%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/$idComputationRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/$idComputationIncomeStatementRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts (63%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts (63%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts (66%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/computationIncomeStatementsRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts (63%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts (69%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts (58%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts (58%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts (60%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/computationsRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/createOneComputation.ts (60%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/generateComputations.ts (84%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/computations/readAllComputations.ts (55%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/general/generalRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/general/openYear.ts (88%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/general/settleBalanceSheet.ts (81%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/general/settleIncomeStatement.ts (84%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/general/updateOneYear.ts (51%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/$idIncomeStatement/$idIncomeStatementRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts (59%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts (59%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts (63%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts (85%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts (63%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts (83%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/incomeStatementsRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts (56%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/journals/$idJournal/$idJournalRoute.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts (50%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/journals/createOneJournal.ts (50%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/journals/generateJournals.ts (69%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/journals/journalsRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/tags/$idTag/$idTagRoutes.ts (100%) create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts create mode 100644 packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/tags/tagsRoutes.ts (100%) rename packages/api/src/routes/auth/{ => organizations/$idOrganization/years}/$idYear/yearSettings/yearSettingsRoute.ts (100%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/years/createOneYear.ts (92%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/years/readAllYears.ts (51%) rename packages/api/src/routes/auth/{ => organizations}/$idOrganization/years/yearsRoutes.ts (77%) rename packages/api/src/routes/public/{ => user}/resetPassword.ts (71%) rename packages/api/src/routes/public/{ => user}/sendMagicLink.ts (61%) rename packages/api/src/routes/public/{ => user}/signIn.ts (76%) rename packages/api/src/routes/public/{ => user}/signOut.ts (72%) rename packages/api/src/routes/public/{ => user}/signUp.ts (80%) create mode 100644 packages/api/src/utilities/registerRoute.ts create mode 100644 packages/cli/arrhes.sh create mode 100644 packages/cli/install.sh create mode 100644 packages/cli/package.json rename packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/{reports => exports}/generateBalanceSheetXml.ts (82%) create mode 100644 packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts rename packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/{reports => exports}/generateIncomeStatementXml.ts (81%) rename packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/{reports => exports}/index.ts (74%) create mode 100644 packages/website/src/components/document/DocCode.tsx create mode 100644 packages/website/src/components/document/DocCodeBlock.tsx delete mode 100644 packages/website/src/components/document/DocNextPage.tsx create mode 100644 packages/website/src/features/docs/api/AccountsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/ApiKeysApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/BalanceSheetsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/ComputationsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/EntriesApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/EntryLinesApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/FoldersApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/IncomeStatementsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/JournalsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/OrgUsersApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/TagsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/api/XBRLReportsApiDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/AuthenticationCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/CommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/DemarrerCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/InstallationCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/RootCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/BalanceSheetsCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/ClesApiCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/ComptesCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/EcrituresCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/ExercicesCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/ExportsCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/FichiersCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/IncomeStatementsCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/JournauxCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/LibellesCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/MembresCommandsCliDocPage.tsx create mode 100644 packages/website/src/features/docs/cli/commands/OrgCommandsCliDocPage.tsx create mode 100644 packages/website/src/routes/root/cliRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/accountsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/apiKeysApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/balanceSheetsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/computationsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/entriesApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/entryLinesApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/foldersApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/incomeStatementsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/journalsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/orgUsersApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/tagsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/api/xbrlReportsApiDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/authenticationCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/cliDocLayoutRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/balanceSheetsCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/clesApiCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/commandsCliDocTree.ts create mode 100644 packages/website/src/routes/root/docs/cli/commands/comptesCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/ecrituresCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/exercicesCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/exportsCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/fichiersCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/incomeStatementsCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/journauxCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/libellesCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/membresCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commands/orgCommandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/commandsCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/demarrerCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/installationCliDocRoute.tsx create mode 100644 packages/website/src/routes/root/docs/cli/rootCliDocRoute.tsx create mode 100644 scripts/migrate-handlers.mjs create mode 100644 scripts/migrate-routes.mjs diff --git a/.github/workflows/cli-release.yml b/.github/workflows/cli-release.yml new file mode 100644 index 00000000..79f9c308 --- /dev/null +++ b/.github/workflows/cli-release.yml @@ -0,0 +1,174 @@ +name: Release CLI + +on: + release: + types: [published] + workflow_dispatch: + inputs: + publish_npm: + description: "Publish to npm" + type: boolean + default: false + +jobs: + build-binaries: + name: Build binary (${{ matrix.asset_name }}) + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: ubuntu-22.04 + asset_name: arrhes-linux-x64 + node_version: 22 + - os: macos-13 + asset_name: arrhes-macos-x64 + node_version: 22 + - os: macos-15 + asset_name: arrhes-macos-arm64 + node_version: 22 + - os: windows-2025 + asset_name: arrhes-windows-x64.exe + node_version: 22 + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Node.js + uses: actions/setup-node@v5 + with: + node-version: ${{ matrix.node_version }} + + - name: Install pnpm + run: npm install -g pnpm + + - name: Install dependencies + run: CI=true pnpm install --no-frozen-lockfile + + - name: Build metadata + run: pnpm --filter @arrhes/application-metadata build + + - name: Bundle CLI (inline all deps) + working-directory: packages/cli + run: pnpm bundle + + - name: Generate SEA blob + working-directory: packages/cli + run: node --experimental-sea-config sea-config.json + + - name: Create standalone binary (Linux / macOS) + if: runner.os != 'Windows' + working-directory: packages/cli + run: | + mkdir -p binaries + cp $(which node) binaries/${{ matrix.asset_name }} + node_modules/.bin/postject binaries/${{ matrix.asset_name }} NODE_SEA_BLOB sea-prep.blob \ + --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 + if [[ "$RUNNER_OS" == "macOS" ]]; then + # macOS: codesign BEFORE UPX (UPX is skipped on macOS — breaks signing) + codesign --sign - binaries/${{ matrix.asset_name }} + fi + + - name: Create standalone binary (Windows) + if: runner.os == 'Windows' + working-directory: packages/cli + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path binaries + $nodePath = (Get-Command node).Source + Copy-Item $nodePath binaries\${{ matrix.asset_name }} + node_modules\.bin\postject binaries\${{ matrix.asset_name }} NODE_SEA_BLOB sea-prep.blob ` + --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 + + # UPX compresses ~60-65% (123 MB → ~40 MB). + # Skipped on macOS: UPX invalidates the codesignature and Gatekeeper rejects the binary. + - name: Compress binary with UPX (Linux) + if: runner.os == 'Linux' + working-directory: packages/cli + run: | + sudo apt-get install -y upx-ucl -q + upx --best --lzma binaries/${{ matrix.asset_name }} + + - name: Compress binary with UPX (Windows) + if: runner.os == 'Windows' + working-directory: packages/cli + shell: pwsh + run: | + choco install upx -y --no-progress + upx --best --lzma binaries\${{ matrix.asset_name }} + + - name: Upload binary to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: packages/cli/binaries/${{ matrix.asset_name }} + asset_name: ${{ matrix.asset_name }} + asset_content_type: application/octet-stream + + # Upload install scripts once (only from the Linux runner to avoid duplicates) + - name: Upload install.sh to release + if: runner.os == 'Linux' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: packages/cli/install.sh + asset_name: install.sh + asset_content_type: text/plain + + - name: Upload install.ps1 to release + if: runner.os == 'Linux' + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: packages/cli/install.ps1 + asset_name: install.ps1 + asset_content_type: text/plain + + publish-npm: + name: Publish to npm + runs-on: ubuntu-22.04 + needs: build-binaries + if: github.event_name == 'release' || inputs.publish_npm + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Set up Node.js + uses: actions/setup-node@v5 + with: + node-version: 22 + registry-url: https://registry.npmjs.org + + - name: Install pnpm + run: npm install -g pnpm + + - name: Install dependencies + run: CI=true pnpm install --no-frozen-lockfile + + - name: Build metadata + run: pnpm --filter @arrhes/application-metadata build + + - name: Build CLI (tsc) + working-directory: packages/cli + run: pnpm build + + - name: Set version from release tag + if: github.event_name == 'release' + working-directory: packages/cli + run: | + VERSION="${{ github.event.release.tag_name }}" + VERSION="${VERSION#v}" # strip leading 'v' + npm pkg set version="$VERSION" + + - name: Publish + working-directory: packages/cli + run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index ed3747f3..bca0930d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,10 @@ build .vscode .agents +packages/cli/binaries/ +packages/cli/dist/ +packages/cli/sea-prep.blob + .pnpm-store *.tsbuildinfo diff --git a/biome.json b/biome.json index 88f50741..a31bcec3 100644 --- a/biome.json +++ b/biome.json @@ -6,7 +6,7 @@ "useIgnoreFile": true }, "files": { - "includes": ["**", "!**/dist", "!**/build", "!**/styled-system", "!**/.workflows"] + "includes": ["**", "!**/dist", "!**/build", "!**/styled-system", "!**/.workflows", "!scripts"] }, "assist": { "actions": { "source": { "organizeImports": "on" } } }, "formatter": { diff --git a/node_modules_old/.pnpm-workspace-state-v1.json b/node_modules_old/.pnpm-workspace-state-v1.json new file mode 100644 index 00000000..65e67dfb --- /dev/null +++ b/node_modules_old/.pnpm-workspace-state-v1.json @@ -0,0 +1,48 @@ +{ + "lastValidatedTimestamp": 1779115049031, + "projects": { + "/workspace": { + "name": "arrhes" + }, + "/workspace/packages/api": { + "name": "@arrhes/application-api" + }, + "/workspace/packages/metadata": { + "name": "@arrhes/application-metadata" + }, + "/workspace/packages/tools": { + "name": "@arrhes/application-tools" + }, + "/workspace/packages/ui": { + "name": "@arrhes/ui", + "version": "0.0.1" + }, + "/workspace/packages/website": { + "name": "@arrhes/application-website" + }, + "/workspace/packages/worker": { + "name": "@evidensy/worker" + } + }, + "pnpmfiles": [], + "settings": { + "autoInstallPeers": true, + "catalogs": {}, + "dedupeDirectDeps": false, + "dedupeInjectedDeps": true, + "dedupePeerDependents": true, + "dev": true, + "excludeLinksFromLockfile": false, + "hoistPattern": ["*"], + "hoistWorkspacePackages": true, + "injectWorkspacePackages": false, + "linkWorkspacePackages": false, + "nodeLinker": "isolated", + "optional": true, + "preferWorkspacePackages": false, + "production": true, + "publicHoistPattern": [], + "workspacePackagePatterns": ["./packages/*"] + }, + "filteredInstall": false +} diff --git a/packages/api/src/middlewares/checkAdminUserSessionMiddleware.ts b/packages/api/src/middlewares/checkAdminUserSessionMiddleware.ts index cd1a3b14..ab35c38f 100644 --- a/packages/api/src/middlewares/checkAdminUserSessionMiddleware.ts +++ b/packages/api/src/middlewares/checkAdminUserSessionMiddleware.ts @@ -5,10 +5,10 @@ import { parseCookies } from "../utilities/cookies/parseCookies.js" import { unsignString } from "../utilities/cookies/unsignString.js" import { Exception } from "../utilities/exception.js" import { productName } from "../utilities/variables.js" -import { checkUserSessionMiddleware } from "./checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "./checkAuthMiddleware.js" async function trySuperAdminDashboardFallback(parameters: { context: Context }) { - const userSession = await checkUserSessionMiddleware({ + const userSession = await checkAuthMiddleware({ context: parameters.context, }) if (userSession.user.isSuperAdmin !== true) { diff --git a/packages/api/src/middlewares/checkUserSessionMiddleware.ts b/packages/api/src/middlewares/checkAuthMiddleware.ts similarity index 77% rename from packages/api/src/middlewares/checkUserSessionMiddleware.ts rename to packages/api/src/middlewares/checkAuthMiddleware.ts index 6b8248f8..a92feebd 100644 --- a/packages/api/src/middlewares/checkUserSessionMiddleware.ts +++ b/packages/api/src/middlewares/checkAuthMiddleware.ts @@ -5,20 +5,21 @@ import type { Context } from "hono" import { parseCookies } from "../utilities/cookies/parseCookies.js" import { unsignString } from "../utilities/cookies/unsignString.js" import { Exception } from "../utilities/exception.js" +import { selectOne } from "../utilities/sql/selectOne.js" import { productName } from "../utilities/variables.js" import { resolveOrganizationMiddleware } from "./resolveOrganizationMiddleware.js" -export async function checkUserSessionMiddleware(parameters: { context: Context }) { +export async function checkAuthMiddleware(parameters: { context: Context }) { try { // 1. Try cookie auth first const cookieAuth = await tryAuthWithCookie(parameters.context) - if (cookieAuth) { + if (cookieAuth !== null) { return cookieAuth } // 2. Try Bearer token auth (API key) const bearerAuth = await tryAuthWithBearer(parameters.context) - if (bearerAuth) { + if (bearerAuth !== null) { return bearerAuth } @@ -57,16 +58,20 @@ async function tryAuthWithCookie(context: Context) { return null } - const userSession = await context.var.clients.sql.query.userSessionModel.findFirst({ - where: eq(models.userSession.id, idUserSession), + const userSession = await selectOne({ + database: context.var.clients.sql, + table: models.userSession, + where: (table) => eq(table.id, idUserSession), }) if (!userSession || userSession.isActive === false) { return null } - const user = await context.var.clients.sql.query.userModel.findFirst({ - where: eq(models.user.id, userSession.idUser), + const user = await selectOne({ + database: context.var.clients.sql, + table: models.user, + where: (table) => eq(table.id, userSession.idUser), }) if (!user) { @@ -109,16 +114,20 @@ async function tryAuthWithBearer(context: Context) { const keyHash = createHash("sha256").update(rawKey).digest("hex") - const apiKey = await context.var.clients.sql.query.apiKeyModel.findFirst({ - where: and(eq(models.apiKey.keyHash, keyHash), eq(models.apiKey.isActive, true)), + const apiKey = await selectOne({ + database: context.var.clients.sql, + table: models.apiKey, + where: (table) => and(eq(table.keyHash, keyHash), eq(table.isActive, true)), }) if (!apiKey) { return null } - const user = await context.var.clients.sql.query.userModel.findFirst({ - where: eq(models.user.id, apiKey.idUser), + const user = await selectOne({ + database: context.var.clients.sql, + table: models.user, + where: (table) => eq(table.id, apiKey.idUser), }) if (!user) { diff --git a/packages/api/src/middlewares/requireCookieSessionMiddleware.ts b/packages/api/src/middlewares/requireCookieSessionMiddleware.ts new file mode 100644 index 00000000..d0c7c5e3 --- /dev/null +++ b/packages/api/src/middlewares/requireCookieSessionMiddleware.ts @@ -0,0 +1,21 @@ +import type { Context } from "hono" +import { Exception } from "../utilities/exception.js" +import { checkAuthMiddleware } from "./checkAuthMiddleware.js" + +export async function requireCookieSessionMiddleware(parameters: { context: Context }) { + const auth = await checkAuthMiddleware({ + context: parameters.context, + }) + + if (auth.userSession === null) { + throw new Exception({ + statusCode: 401, + internalMessage: "Session required", + cause: "This route requires cookie session authentication", + }) + } + + return auth as typeof auth & { + userSession: NonNullable + } +} diff --git a/packages/api/src/middlewares/requireOrganizationMiddleware.ts b/packages/api/src/middlewares/requireOrganizationMiddleware.ts new file mode 100644 index 00000000..a4dd35a1 --- /dev/null +++ b/packages/api/src/middlewares/requireOrganizationMiddleware.ts @@ -0,0 +1,12 @@ +import { Exception } from "../utilities/exception.js" + +export async function requireOrganizationMiddleware(parameters: { idOrganization: string | undefined }) { + if (parameters.idOrganization !== undefined) { + return parameters.idOrganization + } + + throw new Exception({ + internalMessage: "Organization required", + cause: "No organization context found in the request", + }) +} diff --git a/packages/api/src/middlewares/resolveOrganizationMiddleware.ts b/packages/api/src/middlewares/resolveOrganizationMiddleware.ts index c6f81324..795e5f99 100644 --- a/packages/api/src/middlewares/resolveOrganizationMiddleware.ts +++ b/packages/api/src/middlewares/resolveOrganizationMiddleware.ts @@ -5,21 +5,28 @@ import { productName } from "../utilities/variables.js" /** * Resolves idOrganization from the request context using the following priority: - * 1. X-Organization-Id header - * 2. arrhes_id_organization cookie - * 3. body.idOrganization (legacy fallback) + * 1. URL path param `:idOrganization` (highest — used by REST routes like /v1/organizations/:idOrganization) + * 2. X-Organization-Id header + * 3. arrhes_id_organization cookie + * 4. body.idOrganization (legacy fallback) * * For Bearer token auth, the caller should use apiKey.idOrganization directly * instead of calling this middleware. */ export async function resolveOrganizationMiddleware(parameters: { context: Context }): Promise { - // 1. X-Organization-Id header + // 1. URL path param (REST routes) + const paramValue = parameters.context.req.param("idOrganization") + if (paramValue) { + return paramValue + } + + // 2. X-Organization-Id header const headerValue = parameters.context.req.header("X-Organization-Id") if (headerValue) { return headerValue } - // 2. arrhes_id_organization cookie + // 3. arrhes_id_organization cookie const cookieMap = parseCookies({ value: parameters.context.req.header("Cookie"), }) @@ -28,7 +35,7 @@ export async function resolveOrganizationMiddleware(parameters: { context: Conte return cookieValue } - // 3. body.idOrganization (legacy fallback) + // 4. body.idOrganization (legacy fallback) try { const body = await parameters.context.req.json() if (body?.idOrganization) { @@ -42,6 +49,6 @@ export async function resolveOrganizationMiddleware(parameters: { context: Conte statusCode: 400, internalMessage: "Could not resolve organization", externalMessage: "Organization identifier is required", - cause: "No idOrganization found in X-Organization-Id header, cookie, or request body", + cause: "No idOrganization found in URL param, X-Organization-Id header, cookie, or request body", }) } diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readOneInvoice.ts b/packages/api/src/routes/auth/$idOrganization/organizationPayment/readOneInvoice.ts deleted file mode 100644 index cb6b0720..00000000 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readOneInvoice.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { models, readOneInvoiceRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" - -export const readOneInvoiceRoute = apiFactory.createApp().post(readOneInvoiceRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneInvoiceRouteDefinition.schemas.body, - }) - - await selectOne({ - database: c.var.clients.sql, - table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), - }) - - const invoice = await selectOne({ - database: c.var.clients.sql, - table: models.invoice, - where: (table) => and(eq(table.id, body.idInvoice), eq(table.idOrganization, idOrganization)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneInvoiceRouteDefinition.schemas.return, - data: invoice, - }) -}) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/organizationUsersRoutes.ts b/packages/api/src/routes/auth/$idOrganization/organizationUser/organizationUsersRoutes.ts deleted file mode 100644 index 39f8d8c6..00000000 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/organizationUsersRoutes.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { $idOrganizationUserRoutes } from "./$idOrganizationUser/$idOrganizationUserRoutes.js" -import { createOneOrganizationUserRoute } from "./createOneOrganizationUser.js" -import { readAllOrganizationUsersRoute } from "./readAllOrganizationUsers.js" - -export const organizationUsersRoutes = [ - createOneOrganizationUserRoute, - readAllOrganizationUsersRoute, - - ...$idOrganizationUserRoutes, -] diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/deleteOneEntry.ts b/packages/api/src/routes/auth/$idYear/entries/$idEntry/deleteOneEntry.ts deleted file mode 100644 index 963b7757..00000000 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/deleteOneEntry.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { deleteOneEntryRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { deleteOne } from "../../../../../utilities/sql/deleteOne.js" - -export const deleteOneEntryRoute = apiFactory.createApp().post(deleteOneEntryRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: deleteOneEntryRouteDefinition.schemas.body, - }) - - const deleteOneEntry = await deleteOne({ - database: c.var.clients.sql, - table: models.entry, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idEntry)), - }) - - return response({ - context: c, - statusCode: 200, - schema: deleteOneEntryRouteDefinition.schemas.return, - data: deleteOneEntry, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts b/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts deleted file mode 100644 index 3c35e80c..00000000 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { models, readOneEntryLineRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../../utilities/sql/selectOne.js" - -export const readOneEntryLineRoute = apiFactory.createApp().post(readOneEntryLineRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneEntryLineRouteDefinition.schemas.body, - }) - - const readOneEntryLine = await selectOne({ - database: c.var.clients.sql, - table: models.entryLine, - where: (table) => - and( - eq(table.idOrganization, idOrganization), - eq(table.idYear, body.idYear), - eq(table.id, body.idEntryLine), - ), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneEntryLineRouteDefinition.schemas.return, - data: readOneEntryLine, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts b/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts deleted file mode 100644 index 2b07f6a2..00000000 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { models, removeOneEntryTagRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" - -export const removeOneEntryTagRoute = apiFactory.createApp().post(removeOneEntryTagRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: removeOneEntryTagRouteDefinition.schemas.body, - }) - - const removeOneEntryTag = await deleteOne({ - database: c.var.clients.sql, - table: models.entryTag, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idEntryTag)), - }) - - return response({ - context: c, - statusCode: 200, - schema: removeOneEntryTagRouteDefinition.schemas.return, - data: removeOneEntryTag, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/readOneEntry.ts b/packages/api/src/routes/auth/$idYear/entries/$idEntry/readOneEntry.ts deleted file mode 100644 index 6ac7e85b..00000000 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/readOneEntry.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { models, readOneEntryRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" - -export const readOneEntryRoute = apiFactory.createApp().post(readOneEntryRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneEntryRouteDefinition.schemas.body, - }) - - const readOneEntry = await selectOne({ - database: c.var.clients.sql, - table: models.entry, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idEntry)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneEntryRouteDefinition.schemas.return, - data: readOneEntry, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/entries/readAllEntries.ts b/packages/api/src/routes/auth/$idYear/entries/readAllEntries.ts deleted file mode 100644 index 997fdd8e..00000000 --- a/packages/api/src/routes/auth/$idYear/entries/readAllEntries.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllEntriesRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" - -export const readAllEntriesRoute = apiFactory.createApp().post(readAllEntriesRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readAllEntriesRouteDefinition.schemas.body, - }) - - const readAllEntries = await selectMany({ - database: c.var.clients.sql, - table: models.entry, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllEntriesRouteDefinition.schemas.return, - data: readAllEntries, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/entries/readAllEntryTags.ts b/packages/api/src/routes/auth/$idYear/entries/readAllEntryTags.ts deleted file mode 100644 index c53b34b9..00000000 --- a/packages/api/src/routes/auth/$idYear/entries/readAllEntryTags.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllEntryTagsRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" - -export const readAllEntryTagsRoute = apiFactory.createApp().post(readAllEntryTagsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readAllEntryTagsRouteDefinition.schemas.body, - }) - - const readAllEntryTags = await selectMany({ - database: c.var.clients.sql, - table: models.entryTag, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllEntryTagsRouteDefinition.schemas.return, - data: readAllEntryTags, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts b/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts deleted file mode 100644 index 6e2c4294..00000000 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/readOneFile.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readOneFileRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" - -export const readOneFileRoute = apiFactory.createApp().post(readOneFileRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneFileRouteDefinition.schemas.body, - }) - - const readOneFile = await selectOne({ - database: c.var.clients.sql, - table: models.file, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneFileRouteDefinition.schemas.return, - data: readOneFile, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts b/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts deleted file mode 100644 index 883c790f..00000000 --- a/packages/api/src/routes/auth/$idYear/files/readAllFiles.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllFilesRouteDefinition } from "@arrhes/application-metadata" -import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" - -export const readAllFilesRoute = apiFactory.createApp().post(readAllFilesRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - await validateBodyMiddleware({ - context: c, - schema: readAllFilesRouteDefinition.schemas.body, - }) - - const readAllFiles = await selectMany({ - database: c.var.clients.sql, - table: models.file, - where: (table) => eq(table.idOrganization, idOrganization), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllFilesRouteDefinition.schemas.return, - data: readAllFiles, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts deleted file mode 100644 index e63ae5e0..00000000 --- a/packages/api/src/routes/auth/$idYear/folders/$idFolder/deleteOneFolder.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { deleteOneFolderRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { deleteOne } from "../../../../../utilities/sql/deleteOne.js" - -export const deleteOneFolderRoute = apiFactory.createApp().post(deleteOneFolderRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: deleteOneFolderRouteDefinition.schemas.body, - }) - - const deleteOneFolder = await deleteOne({ - database: c.var.clients.sql, - table: models.folder, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), - }) - - return response({ - context: c, - statusCode: 200, - schema: deleteOneFolderRouteDefinition.schemas.return, - data: deleteOneFolder, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts deleted file mode 100644 index d5f0be0e..00000000 --- a/packages/api/src/routes/auth/$idYear/folders/$idFolder/readOneFolder.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readOneFolderRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" - -export const readOneFolderRoute = apiFactory.createApp().post(readOneFolderRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneFolderRouteDefinition.schemas.body, - }) - - const readOneFolder = await selectOne({ - database: c.var.clients.sql, - table: models.folder, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneFolderRouteDefinition.schemas.return, - data: readOneFolder, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts b/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts deleted file mode 100644 index 90576646..00000000 --- a/packages/api/src/routes/auth/$idYear/folders/$idFolder/updateOneFolder.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { models, updateOneFolderRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" - -export const updateOneFolderRoute = apiFactory.createApp().post(updateOneFolderRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: updateOneFolderRouteDefinition.schemas.body, - }) - - const updateOneFolder = await updateOne({ - database: c.var.clients.sql, - table: models.folder, - data: { - name: body.name, - idFolderParent: body.idFolderParent, - lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, - }, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), - }) - - return response({ - context: c, - statusCode: 200, - schema: updateOneFolderRouteDefinition.schemas.return, - data: updateOneFolder, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts b/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts deleted file mode 100644 index 2d73d783..00000000 --- a/packages/api/src/routes/auth/$idYear/folders/readAllFolders.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllFoldersRouteDefinition } from "@arrhes/application-metadata" -import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" - -export const readAllFoldersRoute = apiFactory.createApp().post(readAllFoldersRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readAllFoldersRouteDefinition.schemas.body, - }) - - const readAllFolders = await selectMany({ - database: c.var.clients.sql, - table: models.folder, - where: (table) => eq(table.idOrganization, idOrganization), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllFoldersRouteDefinition.schemas.return, - data: readAllFolders, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/readOneYear.ts b/packages/api/src/routes/auth/$idYear/readOneYear.ts deleted file mode 100644 index b6d887fe..00000000 --- a/packages/api/src/routes/auth/$idYear/readOneYear.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readOneYearRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" -import { response } from "../../../utilities/response.js" -import { selectOne } from "../../../utilities/sql/selectOne.js" - -export const readOneYearRoute = apiFactory.createApp().post(readOneYearRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneYearRouteDefinition.schemas.body, - }) - - const readOneYear = await selectOne({ - database: c.var.clients.sql, - table: models.year, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneYearRouteDefinition.schemas.return, - data: readOneYear, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts b/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts deleted file mode 100644 index a07d6986..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { deleteOneAccountRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" - -export const deleteOneAccountRoute = apiFactory.createApp().post(deleteOneAccountRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: deleteOneAccountRouteDefinition.schemas.body, - }) - - const deleteOneAccount = await deleteOne({ - database: c.var.clients.sql, - table: models.account, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idAccount)), - }) - - return response({ - context: c, - statusCode: 200, - schema: deleteOneAccountRouteDefinition.schemas.return, - data: deleteOneAccount, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts b/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts deleted file mode 100644 index 89bea6c6..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { models, readOneAccountRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" - -export const readOneAccountRoute = apiFactory.createApp().post(readOneAccountRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneAccountRouteDefinition.schemas.body, - }) - - const readOneAccount = await selectOne({ - database: c.var.clients.sql, - table: models.account, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idAccount)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneAccountRouteDefinition.schemas.return, - data: readOneAccount, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/readAllAccounts.ts b/packages/api/src/routes/auth/$idYear/yearSettings/accounts/readAllAccounts.ts deleted file mode 100644 index 338930a8..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/readAllAccounts.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllAccountsRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" - -export const readAllAccountsRoute = apiFactory.createApp().post(readAllAccountsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readAllAccountsRouteDefinition.schemas.body, - }) - - const readAllAccounts = await selectMany({ - database: c.var.clients.sql, - table: models.account, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllAccountsRouteDefinition.schemas.return, - data: readAllAccounts, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/closeYear.ts b/packages/api/src/routes/auth/$idYear/yearSettings/general/closeYear.ts deleted file mode 100644 index 9c672654..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/general/closeYear.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { closeYearRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq, not } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" - -export const closeYearRoute = apiFactory.createApp().post(closeYearRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: closeYearRouteDefinition.schemas.body, - }) - - const closeYear = await updateOne({ - database: c.var.clients.sql, - table: models.year, - data: { - isClosed: not(models.year.isClosed), - lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, - }, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: closeYearRouteDefinition.schemas.return, - data: closeYear, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/deleteOneYear.ts b/packages/api/src/routes/auth/$idYear/yearSettings/general/deleteOneYear.ts deleted file mode 100644 index a82c0536..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/general/deleteOneYear.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { deleteOneYearRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { deleteOne } from "../../../../../utilities/sql/deleteOne.js" - -export const deleteOneYearRoute = apiFactory.createApp().post(deleteOneYearRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: deleteOneYearRouteDefinition.schemas.body, - }) - - const deleteOneYear = await deleteOne({ - database: c.var.clients.sql, - table: models.year, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: deleteOneYearRouteDefinition.schemas.return, - data: deleteOneYear, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts b/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts deleted file mode 100644 index 5d358aab..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { deleteOneJournalRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" - -export const deleteOneJournalRoute = apiFactory.createApp().post(deleteOneJournalRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: deleteOneJournalRouteDefinition.schemas.body, - }) - - const deleteOneJournal = await deleteOne({ - database: c.var.clients.sql, - table: models.journal, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idJournal)), - }) - - return response({ - context: c, - statusCode: 200, - schema: deleteOneJournalRouteDefinition.schemas.return, - data: deleteOneJournal, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts b/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts deleted file mode 100644 index d3483f49..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { models, readOneJournalRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" - -export const readOneJournalRoute = apiFactory.createApp().post(readOneJournalRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneJournalRouteDefinition.schemas.body, - }) - - const readOneJournal = await selectOne({ - database: c.var.clients.sql, - table: models.journal, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idJournal)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneJournalRouteDefinition.schemas.return, - data: readOneJournal, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/readAllJournals.ts b/packages/api/src/routes/auth/$idYear/yearSettings/journals/readAllJournals.ts deleted file mode 100644 index fc6995f0..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/journals/readAllJournals.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllJournalsRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" - -export const readAllJournalsRoute = apiFactory.createApp().post(readAllJournalsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readAllJournalsRouteDefinition.schemas.body, - }) - - const readAllJournals = await selectMany({ - database: c.var.clients.sql, - table: models.journal, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllJournalsRouteDefinition.schemas.return, - data: readAllJournals, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts b/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts deleted file mode 100644 index 6c93fa68..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { deleteOneTagRouteDefinition, models } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" - -export const deleteOneTagRoute = apiFactory.createApp().post(deleteOneTagRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: deleteOneTagRouteDefinition.schemas.body, - }) - - const deleteOneTag = await deleteOne({ - database: c.var.clients.sql, - table: models.tag, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idTag)), - }) - - return response({ - context: c, - statusCode: 200, - schema: deleteOneTagRouteDefinition.schemas.return, - data: deleteOneTag, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/readOneTag.ts b/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/readOneTag.ts deleted file mode 100644 index da5032e8..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/readOneTag.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { models, readOneTagRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" - -export const readOneTagRoute = apiFactory.createApp().post(readOneTagRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readOneTagRouteDefinition.schemas.body, - }) - - const readOneTag = await selectOne({ - database: c.var.clients.sql, - table: models.tag, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idTag)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readOneTagRouteDefinition.schemas.return, - data: readOneTag, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/updateOneTag.ts b/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/updateOneTag.ts deleted file mode 100644 index 976d2243..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/updateOneTag.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { models, updateOneTagRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" - -export const updateOneTagRoute = apiFactory.createApp().post(updateOneTagRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: updateOneTagRouteDefinition.schemas.body, - }) - - const updateOneTag = await updateOne({ - database: c.var.clients.sql, - table: models.tag, - data: { - label: body.label, - - lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, - }, - where: (table) => - and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idTag)), - }) - - return response({ - context: c, - statusCode: 200, - schema: updateOneTagRouteDefinition.schemas.return, - data: updateOneTag, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/createOneTag.ts b/packages/api/src/routes/auth/$idYear/yearSettings/tags/createOneTag.ts deleted file mode 100644 index 783a82f6..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/tags/createOneTag.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { createOneTagRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" - -export const createOneTagRoute = apiFactory.createApp().post(createOneTagRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: createOneTagRouteDefinition.schemas.body, - }) - - const createOneTag = await insertOne({ - database: c.var.clients.sql, - table: models.tag, - data: { - id: generateId(), - idOrganization: idOrganization, - idYear: body.idYear, - - label: body.label, - - createdAt: new Date().toISOString(), - lastUpdatedAt: null, - createdBy: user.id, - lastUpdatedBy: null, - }, - }) - - return response({ - context: c, - statusCode: 200, - schema: createOneTagRouteDefinition.schemas.return, - data: createOneTag, - }) -}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/readAllTags.ts b/packages/api/src/routes/auth/$idYear/yearSettings/tags/readAllTags.ts deleted file mode 100644 index 3e2d2c63..00000000 --- a/packages/api/src/routes/auth/$idYear/yearSettings/tags/readAllTags.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { models, readAllTagsRouteDefinition } from "@arrhes/application-metadata" -import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" - -export const readAllTagsRoute = apiFactory.createApp().post(readAllTagsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ - context: c, - }) - const body = await validateBodyMiddleware({ - context: c, - schema: readAllTagsRouteDefinition.schemas.body, - }) - - const readAllTags = await selectMany({ - database: c.var.clients.sql, - table: models.tag, - where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), - }) - - return response({ - context: c, - statusCode: 200, - schema: readAllTagsRouteDefinition.schemas.return, - data: readAllTags, - }) -}) diff --git a/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts b/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts index f4bd4009..7e7bdbf7 100644 --- a/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts +++ b/packages/api/src/routes/auth/agent/agentFile/createOneAgentFile.ts @@ -1,7 +1,8 @@ import { createOneAgentFileRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq, isNull, sql } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../middlewares/requireOrganizationMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { Exception } from "../../../../utilities/exception.js" @@ -16,9 +17,12 @@ const MAX_AGENT_FILE_SIZE = 50_000_000 export const createOneAgentFileRoute = apiFactory .createApp() .post(createOneAgentFileRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneAgentFileRouteDefinition.schemas.body, @@ -43,7 +47,7 @@ export const createOneAgentFileRoute = apiFactory where: (table) => eq(table.id, body.idAgentSession), }) - if (session.idUser !== user.id) { + if (session.idUser !== auth.user.id) { throw new Exception({ statusCode: 403, internalMessage: "Agent session access denied", @@ -127,7 +131,7 @@ export const createOneAgentFileRoute = apiFactory idFolderParent: null, name: ".agent", createdAt: new Date().toISOString(), - createdBy: user.id, + createdBy: auth.user.id, }, }) agentFolderId = newFolder.id @@ -150,7 +154,7 @@ export const createOneAgentFileRoute = apiFactory size: body.fileSize, hash: body.fileHash, createdAt: new Date().toISOString(), - createdBy: user.id, + createdBy: auth.user.id, }, }) @@ -170,7 +174,7 @@ export const createOneAgentFileRoute = apiFactory contentType: body.fileType, metadata: { idOrganization: idOrganization, - idUser: user.id, + idUser: auth.user.id, }, }) diff --git a/packages/api/src/routes/auth/agent/agentMessage/agentUndo.ts b/packages/api/src/routes/auth/agent/agentMessage/agentUndo.ts index 59c5d994..71a97d3c 100644 --- a/packages/api/src/routes/auth/agent/agentMessage/agentUndo.ts +++ b/packages/api/src/routes/auth/agent/agentMessage/agentUndo.ts @@ -1,14 +1,14 @@ import { models, undoAgentActionRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" import { Exception } from "../../../../utilities/exception.js" +import { registerRoute } from "../../../../utilities/registerRoute.js" import { response } from "../../../../utilities/response.js" import { selectOne } from "../../../../utilities/sql/selectOne.js" -export const undoAgentActionRoute = apiFactory.createApp().post(undoAgentActionRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const undoAgentActionRoute = registerRoute(undoAgentActionRouteDefinition, async (c) => { + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentMessage/createOneAgentMessage.ts b/packages/api/src/routes/auth/agent/agentMessage/createOneAgentMessage.ts index 2123eefd..e2d029fd 100644 --- a/packages/api/src/routes/auth/agent/agentMessage/createOneAgentMessage.ts +++ b/packages/api/src/routes/auth/agent/agentMessage/createOneAgentMessage.ts @@ -1,7 +1,7 @@ import { createOneAgentMessageRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { Exception } from "../../../../utilities/exception.js" @@ -12,7 +12,7 @@ import { selectOne } from "../../../../utilities/sql/selectOne.js" export const createOneAgentMessageRoute = apiFactory .createApp() .post(createOneAgentMessageRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentMessage/getStreamForAgentMessage.ts b/packages/api/src/routes/auth/agent/agentMessage/getStreamForAgentMessage.ts index dc98a6bc..41fe95ca 100644 --- a/packages/api/src/routes/auth/agent/agentMessage/getStreamForAgentMessage.ts +++ b/packages/api/src/routes/auth/agent/agentMessage/getStreamForAgentMessage.ts @@ -1,7 +1,7 @@ import { getStreamForAgentMessageRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" import { streamText } from "hono/streaming" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { Exception } from "../../../../utilities/exception.js" @@ -19,7 +19,7 @@ export const getStreamForAgentMessageRoute = apiFactory await next() }) .post(getStreamForAgentMessageRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ + await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentMessage/readAllAgentMessages.ts b/packages/api/src/routes/auth/agent/agentMessage/readAllAgentMessages.ts index a479b086..67389ac1 100644 --- a/packages/api/src/routes/auth/agent/agentMessage/readAllAgentMessages.ts +++ b/packages/api/src/routes/auth/agent/agentMessage/readAllAgentMessages.ts @@ -1,6 +1,6 @@ import { models, readAllAgentMessagesRouteDefinition } from "@arrhes/application-metadata" import { and, asc, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { response } from "../../../../utilities/response.js" @@ -9,7 +9,7 @@ import { selectMany } from "../../../../utilities/sql/selectMany.js" export const readAllAgentMessagesRoute = apiFactory .createApp() .post(readAllAgentMessagesRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ + await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentSession/createOneAgentSession.ts b/packages/api/src/routes/auth/agent/agentSession/createOneAgentSession.ts index 959e3cbd..f092ccd8 100644 --- a/packages/api/src/routes/auth/agent/agentSession/createOneAgentSession.ts +++ b/packages/api/src/routes/auth/agent/agentSession/createOneAgentSession.ts @@ -1,6 +1,6 @@ import { createOneAgentSessionRouteDefinition, generateId, models } from "@arrhes/application-metadata" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { response } from "../../../../utilities/response.js" @@ -9,7 +9,7 @@ import { insertOne } from "../../../../utilities/sql/insertOne.js" export const createOneAgentSessionRoute = apiFactory .createApp() .post(createOneAgentSessionRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentSession/deleteOneAgentSession.ts b/packages/api/src/routes/auth/agent/agentSession/deleteOneAgentSession.ts index c6c91bbb..ef44b453 100644 --- a/packages/api/src/routes/auth/agent/agentSession/deleteOneAgentSession.ts +++ b/packages/api/src/routes/auth/agent/agentSession/deleteOneAgentSession.ts @@ -1,6 +1,6 @@ import { deleteOneAgentSessionRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { response } from "../../../../utilities/response.js" @@ -9,7 +9,7 @@ import { deleteOne } from "../../../../utilities/sql/deleteOne.js" export const deleteOneAgentSessionRoute = apiFactory .createApp() .post(deleteOneAgentSessionRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentSession/readAllAgentSessions.ts b/packages/api/src/routes/auth/agent/agentSession/readAllAgentSessions.ts index 040278a9..c0112e42 100644 --- a/packages/api/src/routes/auth/agent/agentSession/readAllAgentSessions.ts +++ b/packages/api/src/routes/auth/agent/agentSession/readAllAgentSessions.ts @@ -1,6 +1,6 @@ import { models, readAllAgentSessionsRouteDefinition } from "@arrhes/application-metadata" import { and, desc, eq, ilike, or } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { response } from "../../../../utilities/response.js" @@ -9,7 +9,7 @@ import { selectMany } from "../../../../utilities/sql/selectMany.js" export const readAllAgentSessionsRoute = apiFactory .createApp() .post(readAllAgentSessionsRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentSession/readOneAgentSession.ts b/packages/api/src/routes/auth/agent/agentSession/readOneAgentSession.ts index 11f2e952..04fbd7a4 100644 --- a/packages/api/src/routes/auth/agent/agentSession/readOneAgentSession.ts +++ b/packages/api/src/routes/auth/agent/agentSession/readOneAgentSession.ts @@ -1,6 +1,6 @@ import { models, readOneAgentSessionRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { response } from "../../../../utilities/response.js" @@ -9,7 +9,7 @@ import { selectOne } from "../../../../utilities/sql/selectOne.js" export const readOneAgentSessionRoute = apiFactory .createApp() .post(readOneAgentSessionRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts b/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts index b14208f9..6a005ca2 100644 --- a/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts +++ b/packages/api/src/routes/auth/agent/agentSession/updateOneAgentSession.ts @@ -1,7 +1,7 @@ import { models, updateOneAgentSessionRouteDefinition } from "@arrhes/application-metadata" import { and, eq, inArray } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../../utilities/apiFactory.js" import { Exception } from "../../../../utilities/exception.js" @@ -13,7 +13,7 @@ import { updateOne } from "../../../../utilities/sql/updateOne.js" export const updateOneAgentSessionRoute = apiFactory .createApp() .post(updateOneAgentSessionRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/agent/searchReferenceable.ts b/packages/api/src/routes/auth/agent/searchReferenceable.ts index 75660d6e..f8ee5126 100644 --- a/packages/api/src/routes/auth/agent/searchReferenceable.ts +++ b/packages/api/src/routes/auth/agent/searchReferenceable.ts @@ -1,6 +1,6 @@ import { models, searchReferenceableRouteDefinition } from "@arrhes/application-metadata" import { and, eq, ilike, or, sql } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -11,7 +11,7 @@ const MAX_TOTAL = 50 export const searchReferenceableRoute = apiFactory .createApp() .post(searchReferenceableRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ + await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/authRoute.ts b/packages/api/src/routes/auth/authRoute.ts index 91b5c7cc..d7f7356f 100644 --- a/packages/api/src/routes/auth/authRoute.ts +++ b/packages/api/src/routes/auth/authRoute.ts @@ -1,9 +1,9 @@ -import { adminRoutes } from "../../routes/auth/admin/adminRoutes.js" -import { agentRoutes } from "../../routes/auth/agent/agentRoutes.js" -import { organizationsRoutes } from "../../routes/auth/organizations/organizationsRoutes.js" -import { settingsRoutes } from "../../routes/auth/settings/settingsRoutes.js" -import { supportRoutes } from "../../routes/auth/support/supportRoutes.js" import { apiFactory } from "../../utilities/apiFactory.js" +import { adminRoutes } from "./admin/adminRoutes.js" +import { agentRoutes } from "./agent/agentRoutes.js" +import { organizationsRoutes } from "./organizations/organizationsRoutes.js" +import { settingsRoutes } from "./settings/settingsRoutes.js" +import { supportRoutes } from "./support/supportRoutes.js" export const authRoute = apiFactory.createApp() diff --git a/packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/$idOrganizationRoutes.ts similarity index 51% rename from packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/$idOrganizationRoutes.ts index 35d6caac..794ae368 100644 --- a/packages/api/src/routes/auth/$idOrganization/$idOrganizationRoutes.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/$idOrganizationRoutes.ts @@ -1,9 +1,7 @@ -import { filesRoutes } from "../$idYear/files/filesRoutes.js" -import { foldersRoutes } from "../$idYear/folders/foldersRoutes.js" -import { apiKeyRoutes } from "./apiKey/apiKeyRoutes.js" -import { organizationPaymentsRoutes } from "./organizationPayment/organizationPaymentsRoutes.js" +import { apiKeyRoutes } from "./organizationSettings/apiKey/apiKeyRoutes.js" +import { organizationPaymentsRoutes } from "./organizationSettings/organizationPayment/organizationPaymentsRoutes.js" import { organizationSettingsRoutes } from "./organizationSettings/organizationSettingsRoutes.js" -import { organizationUsersRoutes } from "./organizationUser/organizationUsersRoutes.js" +import { organizationUsersRoutes } from "./organizationSettings/organizationUser/organizationUsersRoutes.js" import { readOneOrganizationRoute } from "./readOneOrganization.js" import { yearsRoutes } from "./years/yearsRoutes.js" @@ -15,6 +13,4 @@ export const $idOrganizationRoutes = [ ...organizationSettingsRoutes, ...organizationPaymentsRoutes, ...apiKeyRoutes, - ...filesRoutes, - ...foldersRoutes, ] diff --git a/packages/api/src/routes/auth/$idOrganization/apiKey/apiKeyRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/apiKeyRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idOrganization/apiKey/apiKeyRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/apiKeyRoutes.ts diff --git a/packages/api/src/routes/auth/$idOrganization/apiKey/createOneApiKey.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts similarity index 59% rename from packages/api/src/routes/auth/$idOrganization/apiKey/createOneApiKey.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts index cece533c..003719bd 100644 --- a/packages/api/src/routes/auth/$idOrganization/apiKey/createOneApiKey.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts @@ -1,18 +1,22 @@ import { createHash } from "node:crypto" import { createOneApiKeyRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { registerRoute } from "../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" -export const createOneApiKeyRoute = apiFactory.createApp().post(createOneApiKeyRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneApiKeyRoute = registerRoute(createOneApiKeyRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneApiKeyRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const createOneApiKeyRoute = apiFactory.createApp().post(createOneApiKeyR const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -41,7 +45,7 @@ export const createOneApiKeyRoute = apiFactory.createApp().post(createOneApiKeyR data: { id: generateId(), idOrganization: idOrganization, - idUser: user.id, + idUser: auth.user.id, keyHash: keyHash, name: body.name ?? new Date().toISOString(), isDefault: false, diff --git a/packages/api/src/routes/auth/$idOrganization/apiKey/deleteOneApiKey.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts similarity index 52% rename from packages/api/src/routes/auth/$idOrganization/apiKey/deleteOneApiKey.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts index 908d6e0f..b1ce4f61 100644 --- a/packages/api/src/routes/auth/$idOrganization/apiKey/deleteOneApiKey.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts @@ -1,17 +1,21 @@ import { deleteOneApiKeyRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { deleteOne } from "../../../../utilities/sql/deleteOne.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { registerRoute } from "../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" -export const deleteOneApiKeyRoute = apiFactory.createApp().post(deleteOneApiKeyRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const deleteOneApiKeyRoute = registerRoute(deleteOneApiKeyRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneApiKeyRouteDefinition.schemas.body, @@ -21,7 +25,7 @@ export const deleteOneApiKeyRoute = apiFactory.createApp().post(deleteOneApiKeyR const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ diff --git a/packages/api/src/routes/auth/$idOrganization/apiKey/readAllApiKeys.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts similarity index 53% rename from packages/api/src/routes/auth/$idOrganization/apiKey/readAllApiKeys.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts index 3a6e1469..65a146e3 100644 --- a/packages/api/src/routes/auth/$idOrganization/apiKey/readAllApiKeys.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts @@ -1,16 +1,20 @@ import { models, readAllApiKeysRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { registerRoute } from "../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" -export const readAllApiKeysRoute = apiFactory.createApp().post(readAllApiKeysRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const readAllApiKeysRoute = registerRoute(readAllApiKeysRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: readAllApiKeysRouteDefinition.schemas.body, @@ -20,7 +24,7 @@ export const readAllApiKeysRoute = apiFactory.createApp().post(readAllApiKeysRou const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationSettings/deleteOneOrganization.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts similarity index 59% rename from packages/api/src/routes/auth/$idOrganization/organizationSettings/deleteOneOrganization.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts index 78ea44c6..6744df71 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationSettings/deleteOneOrganization.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts @@ -1,19 +1,23 @@ import { deleteOneOrganizationRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { deleteOne } from "../../../../utilities/sql/deleteOne.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../utilities/exception.js" +import { response } from "../../../../../utilities/response.js" +import { deleteOne } from "../../../../../utilities/sql/deleteOne.js" +import { selectOne } from "../../../../../utilities/sql/selectOne.js" export const deleteOneOrganizationRoute = apiFactory .createApp() .post(deleteOneOrganizationRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: deleteOneOrganizationRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const deleteOneOrganizationRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/cancelOrganizationBilling.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts similarity index 80% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/cancelOrganizationBilling.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts index 4830e127..54568f17 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/cancelOrganizationBilling.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts @@ -1,12 +1,13 @@ import { cancelOrganizationBillingRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq, sql } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" // How much each resource unit removes from limits (mirrors createResourceSubscription) const UNIT_LIMITS = { @@ -40,9 +41,12 @@ function getEndOfCurrentMonth(): Date { export const cancelOrganizationBillingRoute = apiFactory .createApp() .post(cancelOrganizationBillingRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: cancelOrganizationBillingRouteDefinition.schemas.body, @@ -51,7 +55,7 @@ export const cancelOrganizationBillingRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -81,7 +85,7 @@ export const cancelOrganizationBillingRoute = apiFactory status: "cancelled", endsAt: endsAt.toISOString(), lastUpdatedAt: now.toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, subscription.id), }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/cancelSubscription.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts similarity index 61% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/cancelSubscription.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts index 6c753594..6084ac99 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/cancelSubscription.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts @@ -1,13 +1,13 @@ import { cancelSubscriptionRouteDefinition } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../utilities/response.js" export const cancelSubscriptionRoute = apiFactory .createApp() .post(cancelSubscriptionRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ + await checkAuthMiddleware({ context: c, }) await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createFirstPayment.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts similarity index 63% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/createFirstPayment.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts index d83330d7..3f2bbbc4 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createFirstPayment.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts @@ -1,13 +1,13 @@ import { createFirstPaymentRouteDefinition } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" export const createFirstPaymentRoute = apiFactory .createApp() .post(createFirstPaymentRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ + await checkAuthMiddleware({ context: c, }) await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createPaymentMethodCheckout.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts similarity index 76% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/createPaymentMethodCheckout.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts index 84f7f629..8be38aef 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createPaymentMethodCheckout.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts @@ -1,15 +1,16 @@ import { createPaymentMethodCheckoutRouteDefinition, models } from "@arrhes/application-metadata" import { SequenceType } from "@mollie/api-client" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { recordOrganizationPayment } from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" -import { productName } from "../../../../utilities/variables.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { recordOrganizationPayment } from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { productName } from "../../../../../../utilities/variables.js" const SETUP_PAYMENT_AMOUNT_IN_CENTS = 1 @@ -20,9 +21,12 @@ function formatAmountFromCents(cents: number): string { export const createPaymentMethodCheckoutRoute = apiFactory .createApp() .post(createPaymentMethodCheckoutRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: createPaymentMethodCheckoutRouteDefinition.schemas.body, @@ -31,7 +35,7 @@ export const createPaymentMethodCheckoutRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { @@ -75,7 +79,7 @@ export const createPaymentMethodCheckoutRoute = apiFactory data: { mollieCustomerId, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, organization.id), }) @@ -102,7 +106,7 @@ export const createPaymentMethodCheckoutRoute = apiFactory description: "Ajout du moyen de paiement", sequenceType: "setup", molliePaymentId: molliePayment.id, - createdBy: user.id, + createdBy: auth.user.id, }) const checkoutUrl = molliePayment.getCheckoutUrl() diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createResourceSubscription.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts similarity index 86% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/createResourceSubscription.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts index 3ee643e3..3716a0ad 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createResourceSubscription.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts @@ -1,8 +1,9 @@ import { createResourceSubscriptionRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" import { FREE_STORAGE_BYTES, getOcrAddonQuantity, @@ -14,19 +15,22 @@ import { getTotalTokensFromQuantity, INCLUDED_OCR_PAGES, isOneTimeServiceType, -} from "../../../../utilities/billing/subscriptionPricing.js" -import { creditOrganizationWallet, debitOrganizationWallet } from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +} from "../../../../../../utilities/billing/subscriptionPricing.js" +import { creditOrganizationWallet, debitOrganizationWallet } from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" export const createResourceSubscriptionRoute = apiFactory .createApp() .post(createResourceSubscriptionRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createResourceSubscriptionRouteDefinition.schemas.body, @@ -35,7 +39,7 @@ export const createResourceSubscriptionRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -139,7 +143,7 @@ export const createResourceSubscriptionRoute = apiFactory await debitOrganizationWallet({ database: c.var.clients.sql, idOrganization, - idUser: user.id, + idUser: auth.user.id, amountHTInCents: deltaAmountInCents, quantity: body.type === "ocr_pages_hundred" ? deltaQuantity * INCLUDED_OCR_PAGES : deltaQuantity, unitAmountHTInCents: getResourceSubscriptionUnitPriceInCents(body.type), @@ -157,7 +161,7 @@ export const createResourceSubscriptionRoute = apiFactory await creditOrganizationWallet({ database: c.var.clients.sql, idOrganization, - idUser: user.id, + idUser: auth.user.id, amountHTInCents: deltaAmountInCents, serviceType: body.type, description: "Réduction du stockage créditée au portefeuille", @@ -176,7 +180,7 @@ export const createResourceSubscriptionRoute = apiFactory ? Math.max(nextTokensTotal - organization.tokensTotalUsed, 0) : undefined, lastUpdatedAt: now.toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, idOrganization), }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createWalletTopUpCheckout.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts similarity index 75% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/createWalletTopUpCheckout.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts index 9858a0fd..548e5771 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createWalletTopUpCheckout.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts @@ -1,22 +1,26 @@ import { createWalletTopUpCheckoutRouteDefinition, models } from "@arrhes/application-metadata" import { SequenceType } from "@mollie/api-client" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { formatAmountFromCents, recordOrganizationPayment } from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" -import { productName } from "../../../../utilities/variables.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { formatAmountFromCents, recordOrganizationPayment } from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { productName } from "../../../../../../utilities/variables.js" export const createWalletTopUpCheckoutRoute = apiFactory .createApp() .post(createWalletTopUpCheckoutRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createWalletTopUpCheckoutRouteDefinition.schemas.body, @@ -25,7 +29,7 @@ export const createWalletTopUpCheckoutRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -60,7 +64,7 @@ export const createWalletTopUpCheckoutRoute = apiFactory data: { mollieCustomerId, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, organization.id), }) @@ -87,7 +91,7 @@ export const createWalletTopUpCheckoutRoute = apiFactory description: "Recharge portefeuille", sequenceType: "oneoff", molliePaymentId: molliePayment.id, - createdBy: user.id, + createdBy: auth.user.id, }) const checkoutUrl = molliePayment.getCheckoutUrl() diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createWalletWithdrawal.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts similarity index 85% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/createWalletWithdrawal.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts index 18413910..8efb5785 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/createWalletWithdrawal.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts @@ -1,25 +1,29 @@ import { createWalletWithdrawalRouteDefinition, models } from "@arrhes/application-metadata" import { and, desc, eq, gte, inArray, lt, ne } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" import { formatAmountFromCents, mapMollieRefundStatusToPaymentStatus, recordOrganizationPayment, -} from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { productName } from "../../../../utilities/variables.js" +} from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { productName } from "../../../../../../utilities/variables.js" export const createWalletWithdrawalRoute = apiFactory .createApp() .post(createWalletWithdrawalRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createWalletWithdrawalRouteDefinition.schemas.body, @@ -28,7 +32,7 @@ export const createWalletWithdrawalRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -164,7 +168,7 @@ export const createWalletWithdrawalRoute = apiFactory amountInCents: body.amountInCents, description: "Retrait portefeuille", molliePaymentId: sourcePayment.molliePaymentId, - createdBy: user.id, + createdBy: auth.user.id, }) return response({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/generateInvoiceGetSignedUrl.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts similarity index 60% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/generateInvoiceGetSignedUrl.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts index 29b6ca0c..6f42a157 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/generateInvoiceGetSignedUrl.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts @@ -1,19 +1,23 @@ import { generateInvoiceGetSignedUrlRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { generateGetSignedUrl } from "../../../../utilities/storage/generateGetSignedUrl.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { generateGetSignedUrl } from "../../../../../../utilities/storage/generateGetSignedUrl.js" export const generateInvoiceGetSignedUrlRoute = apiFactory .createApp() .post(generateInvoiceGetSignedUrlRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: generateInvoiceGetSignedUrlRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const generateInvoiceGetSignedUrlRoute = apiFactory await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) const invoice = await selectOne({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/organizationPaymentsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/organizationPaymentsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/organizationPaymentsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/organizationPaymentsRoutes.ts diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllInvoices.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts similarity index 70% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllInvoices.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts index f93955d3..84ac9ea7 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllInvoices.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts @@ -1,16 +1,20 @@ import { models, readAllInvoicesRouteDefinition } from "@arrhes/application-metadata" import { and, desc, eq, inArray, isNotNull, sum } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" -export const readAllInvoicesRoute = apiFactory.createApp().post(readAllInvoicesRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const readAllInvoicesRoute = registerRoute(readAllInvoicesRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: readAllInvoicesRouteDefinition.schemas.body, @@ -19,7 +23,7 @@ export const readAllInvoicesRoute = apiFactory.createApp().post(readAllInvoicesR await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) const invoices = await selectMany({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllOrganizationBillings.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts similarity index 60% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllOrganizationBillings.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts index 17bddd73..3556b289 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllOrganizationBillings.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts @@ -1,22 +1,26 @@ import { models, readAllOrganizationBillingsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" import { getSubscriptionMonthlyAmountInCents, isResourceSubscriptionType, -} from "../../../../utilities/billing/subscriptionPricing.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +} from "../../../../../../utilities/billing/subscriptionPricing.js" +import { response } from "../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const readAllOrganizationBillingsRoute = apiFactory .createApp() .post(readAllOrganizationBillingsRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: readAllOrganizationBillingsRouteDefinition.schemas.body, @@ -25,7 +29,7 @@ export const readAllOrganizationBillingsRoute = apiFactory await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) const subscriptions = await selectMany({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllOrganizationPayments.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts similarity index 61% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllOrganizationPayments.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts index ab5baf3d..442b41ae 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readAllOrganizationPayments.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts @@ -1,19 +1,23 @@ import { models, readAllOrganizationPaymentsRouteDefinition } from "@arrhes/application-metadata" import { and, desc, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const readAllOrganizationPaymentsRoute = apiFactory .createApp() .post(readAllOrganizationPaymentsRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: readAllOrganizationPaymentsRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const readAllOrganizationPaymentsRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts new file mode 100644 index 00000000..35aca9ef --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts @@ -0,0 +1,40 @@ +import { models, readOneInvoiceRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" + +export const readOneInvoiceRoute = registerRoute(readOneInvoiceRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneInvoiceRouteDefinition.schemas.body, + }) + + await selectOne({ + database: c.var.clients.sql, + table: models.organizationUser, + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), + }) + + const invoice = await selectOne({ + database: c.var.clients.sql, + table: models.invoice, + where: (table) => and(eq(table.id, body.idInvoice), eq(table.idOrganization, idOrganization)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneInvoiceRouteDefinition.schemas.return, + data: invoice, + }) +}) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readOrganizationBilling.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts similarity index 67% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/readOrganizationBilling.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts index 61e6614f..4e486097 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/readOrganizationBilling.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts @@ -1,29 +1,33 @@ import { models, readOrganizationBillingRouteDefinition } from "@arrhes/application-metadata" import { and, desc, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { computeMonthlyTotal } from "../../../../utilities/billing/computeMonthlyTotal.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { computeMonthlyTotal } from "../../../../../../utilities/billing/computeMonthlyTotal.js" +import { response } from "../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const readOrganizationBillingRoute = apiFactory .createApp() .post(readOrganizationBillingRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: readOrganizationBillingRouteDefinition.schemas.body, }) - // Verify user is member of the organization + // Verify auth.user is member of the organization await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) // Get organization diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateLicenceSubscription.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts similarity index 68% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/updateLicenceSubscription.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts index 113a2b26..f8df588c 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateLicenceSubscription.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts @@ -1,19 +1,23 @@ import { models, updateLicenceSubscriptionRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" export const updateLicenceSubscriptionRoute = apiFactory .createApp() .post(updateLicenceSubscriptionRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateLicenceSubscriptionRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const updateLicenceSubscriptionRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -55,7 +59,7 @@ export const updateLicenceSubscriptionRoute = apiFactory data: { licenceAmountPending: pendingValue, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, idOrganization), }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateOcrSubscription.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts similarity index 76% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/updateOcrSubscription.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts index f91f06a6..351863b0 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateOcrSubscription.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts @@ -1,23 +1,30 @@ import { models, updateOcrSubscriptionRouteDefinition } from "@arrhes/application-metadata" import { OCR_PAGE_PRICE_IN_CENTS } from "@arrhes/application-metadata/utilities" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { findOrCreateCurrentPeriodInvoice, getCurrentMonthRange } from "../../../../utilities/billing/billingInvoice.js" -import { INCLUDED_OCR_PAGES } from "../../../../utilities/billing/subscriptionPricing.js" -import { recordOrganizationPayment } from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { + findOrCreateCurrentPeriodInvoice, + getCurrentMonthRange, +} from "../../../../../../utilities/billing/billingInvoice.js" +import { INCLUDED_OCR_PAGES } from "../../../../../../utilities/billing/subscriptionPricing.js" +import { recordOrganizationPayment } from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" export const updateOcrSubscriptionRoute = apiFactory .createApp() .post(updateOcrSubscriptionRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOcrSubscriptionRouteDefinition.schemas.body, @@ -26,7 +33,7 @@ export const updateOcrSubscriptionRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -85,7 +92,7 @@ export const updateOcrSubscriptionRoute = apiFactory ocrPagesTotalAvailable: Math.max(nextOcrTotal - organization.ocrPagesTotalUsed, 0), walletBalanceInCents: newWalletBalanceInCents, lastUpdatedAt: now.toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, idOrganization), }) @@ -110,7 +117,7 @@ export const updateOcrSubscriptionRoute = apiFactory description: "Achat pages OCR", serviceType: "ocr_pages_hundred", idInvoice, - createdBy: user.id, + createdBy: auth.user.id, }) } }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateStorageSubscription.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts similarity index 77% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/updateStorageSubscription.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts index a3b76828..1907fc67 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateStorageSubscription.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts @@ -1,18 +1,19 @@ import { models, updateStorageSubscriptionRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" import { FREE_STORAGE_BYTES, getResourceSubscriptionUnitPriceInCents, getStorageAddonQuantity, -} from "../../../../utilities/billing/subscriptionPricing.js" -import { debitOrganizationWallet } from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +} from "../../../../../../utilities/billing/subscriptionPricing.js" +import { debitOrganizationWallet } from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" function getDaysInMonth(date: Date): number { return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)).getUTCDate() @@ -27,9 +28,12 @@ function calculateProRataAmountCents(fullMonthlyAmountCents: number, from: Date) export const updateStorageSubscriptionRoute = apiFactory .createApp() .post(updateStorageSubscriptionRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateStorageSubscriptionRouteDefinition.schemas.body, @@ -38,7 +42,7 @@ export const updateStorageSubscriptionRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -80,7 +84,7 @@ export const updateStorageSubscriptionRoute = apiFactory await debitOrganizationWallet({ database: c.var.clients.sql, idOrganization, - idUser: user.id, + idUser: auth.user.id, amountHTInCents: proRataAmountCents, description: "Augmentation du stockage (prorata)", serviceType: "storage_gb", @@ -93,7 +97,7 @@ export const updateStorageSubscriptionRoute = apiFactory storageLimit: nextStorageLimit, storageLimitPending: null, lastUpdatedAt: now.toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, idOrganization), }) @@ -107,7 +111,7 @@ export const updateStorageSubscriptionRoute = apiFactory data: { storageLimitPending: pendingValue, lastUpdatedAt: now.toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, idOrganization), }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateTokensSubscription.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts similarity index 75% rename from packages/api/src/routes/auth/$idOrganization/organizationPayment/updateTokensSubscription.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts index c5261331..30de174e 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationPayment/updateTokensSubscription.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts @@ -1,23 +1,33 @@ import { models, updateTokensSubscriptionRouteDefinition } from "@arrhes/application-metadata" import { TOKEN_PACK_PRICE_IN_CENTS } from "@arrhes/application-metadata/utilities" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { findOrCreateCurrentPeriodInvoice, getCurrentMonthRange } from "../../../../utilities/billing/billingInvoice.js" -import { getTokenAddonQuantity, getTotalTokensFromQuantity } from "../../../../utilities/billing/subscriptionPricing.js" -import { recordOrganizationPayment } from "../../../../utilities/billing/wallet.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { + findOrCreateCurrentPeriodInvoice, + getCurrentMonthRange, +} from "../../../../../../utilities/billing/billingInvoice.js" +import { + getTokenAddonQuantity, + getTotalTokensFromQuantity, +} from "../../../../../../utilities/billing/subscriptionPricing.js" +import { recordOrganizationPayment } from "../../../../../../utilities/billing/wallet.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" export const updateTokensSubscriptionRoute = apiFactory .createApp() .post(updateTokensSubscriptionRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateTokensSubscriptionRouteDefinition.schemas.body, @@ -26,7 +36,7 @@ export const updateTokensSubscriptionRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -84,7 +94,7 @@ export const updateTokensSubscriptionRoute = apiFactory tokensTotalAvailable: Math.max(nextTokensTotal - organization.tokensTotalUsed, 0), walletBalanceInCents: newWalletBalanceInCents, lastUpdatedAt: now.toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, idOrganization), }) @@ -107,7 +117,7 @@ export const updateTokensSubscriptionRoute = apiFactory description: "Achat tokens Assistant IA", serviceType: "agent_tokens_million", idInvoice, - createdBy: user.id, + createdBy: auth.user.id, }) } }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationSettings/organizationSettingsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationSettingsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idOrganization/organizationSettings/organizationSettingsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationSettingsRoutes.ts diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/createOneOrganizationUser.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts similarity index 72% rename from packages/api/src/routes/auth/$idOrganization/organizationUser/createOneOrganizationUser.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts index e0de212d..1a208f3f 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/createOneOrganizationUser.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts @@ -1,19 +1,23 @@ import { createOneOrganizationUserRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const createOneOrganizationUserRoute = apiFactory .createApp() .post(createOneOrganizationUserRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneOrganizationUserRouteDefinition.schemas.body, @@ -23,7 +27,7 @@ export const createOneOrganizationUserRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -33,7 +37,7 @@ export const createOneOrganizationUserRoute = apiFactory }) } - // the user must exist + // the auth.user must exist const toAddUser = await selectOne({ database: c.var.clients.sql, table: models.user, @@ -59,7 +63,7 @@ export const createOneOrganizationUserRoute = apiFactory status: "invited", createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/deleteOneOrganizationUser.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts similarity index 57% rename from packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/deleteOneOrganizationUser.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts index ebdec1b2..da3c303c 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/deleteOneOrganizationUser.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts @@ -1,29 +1,33 @@ import { deleteOneOrganizationUserRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteOne } from "../../../../../utilities/sql/deleteOne.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const deleteOneOrganizationUserRoute = apiFactory .createApp() .post(deleteOneOrganizationUserRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneOrganizationUserRouteDefinition.schemas.body, }) - // Check if the user is admin of the organization + // Check if the auth.user is admin of the organization const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/$idOrganizationUserRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/organizationUsersRoutes.ts similarity index 56% rename from packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/$idOrganizationUserRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/organizationUsersRoutes.ts index 8c261711..c3b077f3 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/$idOrganizationUserRoutes.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/organizationUsersRoutes.ts @@ -1,8 +1,12 @@ +import { createOneOrganizationUserRoute } from "./createOneOrganizationUser.js" import { deleteOneOrganizationUserRoute } from "./deleteOneOrganizationUser.js" +import { readAllOrganizationUsersRoute } from "./readAllOrganizationUsers.js" import { readOneOrganizationUserRoute } from "./readOneOrganizationUser.js" import { updateOneOrganizationUserRoute } from "./updateOneOrganizationUser.js" -export const $idOrganizationUserRoutes = [ +export const organizationUsersRoutes = [ + createOneOrganizationUserRoute, + readAllOrganizationUsersRoute, deleteOneOrganizationUserRoute, readOneOrganizationUserRoute, updateOneOrganizationUserRoute, diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/readAllOrganizationUsers.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts similarity index 62% rename from packages/api/src/routes/auth/$idOrganization/organizationUser/readAllOrganizationUsers.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts index 151336a7..5d870a58 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/readAllOrganizationUsers.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts @@ -1,18 +1,22 @@ import { models, readAllOrganizationUsersRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const readAllOrganizationUsersRoute = apiFactory .createApp() .post(readAllOrganizationUsersRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const _body = await validateBodyMiddleware({ context: c, schema: readAllOrganizationUsersRouteDefinition.schemas.body, @@ -21,7 +25,7 @@ export const readAllOrganizationUsersRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/readOneOrganizationUser.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts similarity index 77% rename from packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/readOneOrganizationUser.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts index a0585bc0..37178e2b 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/readOneOrganizationUser.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts @@ -1,16 +1,16 @@ import { models, readOneOrganizationUserRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" export const readOneOrganizationUserRoute = apiFactory .createApp() .post(readOneOrganizationUserRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ + await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/updateOneOrganizationUser.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts similarity index 64% rename from packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/updateOneOrganizationUser.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts index b1e80426..2045f5fb 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationUser/$idOrganizationUser/updateOneOrganizationUser.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts @@ -1,29 +1,33 @@ import { models, updateOneOrganizationUserRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../utilities/exception.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../utilities/sql/updateOne.js" export const updateOneOrganizationUserRoute = apiFactory .createApp() .post(updateOneOrganizationUserRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneOrganizationUserRouteDefinition.schemas.body, }) - // Check if the user is admin of the organization + // Check if the auth.user is admin of the organization const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -48,7 +52,7 @@ export const updateOneOrganizationUserRoute = apiFactory data: { isAdmin: body.isAdmin, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, body.idOrganizationUser), }) diff --git a/packages/api/src/routes/auth/$idOrganization/organizationSettings/updateOneOrganization.ts b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts similarity index 61% rename from packages/api/src/routes/auth/$idOrganization/organizationSettings/updateOneOrganization.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts index 4a032b9d..82dfafb9 100644 --- a/packages/api/src/routes/auth/$idOrganization/organizationSettings/updateOneOrganization.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts @@ -1,19 +1,23 @@ import { models, updateOneOrganizationRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../utilities/exception.js" +import { response } from "../../../../../utilities/response.js" +import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../utilities/sql/updateOne.js" export const updateOneOrganizationRoute = apiFactory .createApp() .post(updateOneOrganizationRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneOrganizationRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const updateOneOrganizationRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idUser, user.id), eq(table.idOrganization, idOrganization)), + where: (table) => and(eq(table.idUser, auth.user.id), eq(table.idOrganization, idOrganization)), }) if (organizationUser.isAdmin === false) { throw new Exception({ @@ -40,7 +44,7 @@ export const updateOneOrganizationRoute = apiFactory name: body.name, email: body.email, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => eq(table.id, organizationUser.idOrganization), }) diff --git a/packages/api/src/routes/auth/$idOrganization/readOneOrganization.ts b/packages/api/src/routes/auth/organizations/$idOrganization/readOneOrganization.ts similarity index 65% rename from packages/api/src/routes/auth/$idOrganization/readOneOrganization.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/readOneOrganization.ts index 30a748a0..943dd457 100644 --- a/packages/api/src/routes/auth/$idOrganization/readOneOrganization.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/readOneOrganization.ts @@ -1,18 +1,22 @@ import { models, readOneOrganizationRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" -import { Exception } from "../../../utilities/exception.js" -import { response } from "../../../utilities/response.js" -import { selectOne } from "../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../utilities/apiFactory.js" +import { Exception } from "../../../../utilities/exception.js" +import { response } from "../../../../utilities/response.js" +import { selectOne } from "../../../../utilities/sql/selectOne.js" export const readOneOrganizationRoute = apiFactory .createApp() .post(readOneOrganizationRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readOneOrganizationRouteDefinition.schemas.body, @@ -29,7 +33,7 @@ export const readOneOrganizationRoute = apiFactory const organizationUser = await selectOne({ database: c.var.clients.sql, table: models.organizationUser, - where: (table) => and(eq(table.idOrganization, body.idOrganization), eq(table.idUser, user.id)), + where: (table) => and(eq(table.idOrganization, body.idOrganization), eq(table.idUser, auth.user.id)), }) const readOneOrganization = await selectOne({ diff --git a/packages/api/src/routes/auth/$idYear/$idYearRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/$idYearRoutes.ts similarity index 55% rename from packages/api/src/routes/auth/$idYear/$idYearRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/$idYearRoutes.ts index 40b134b0..57b12191 100644 --- a/packages/api/src/routes/auth/$idYear/$idYearRoutes.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/$idYearRoutes.ts @@ -1,12 +1,16 @@ import { entriesRoutes } from "./entries/entriesRoutes.js" +import { exportsRoutes } from "./exports/exportsRoutes.js" +import { filesRoutes } from "./files/filesRoutes.js" +import { foldersRoutes } from "./folders/foldersRoutes.js" import { readOneYearRoute } from "./readOneYear.js" -import { reportsRoutes } from "./reports/reportsRoutes.js" import { yearSettingsRoute } from "./yearSettings/yearSettingsRoute.js" export const $idYearRoutes = [ readOneYearRoute, ...entriesRoutes, - ...reportsRoutes, + ...exportsRoutes, + ...filesRoutes, + ...foldersRoutes, ...yearSettingsRoute, ] diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/$idEntryRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/$idEntryRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/$idEntryRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts new file mode 100644 index 00000000..25b1d45b --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts @@ -0,0 +1,35 @@ +import { deleteOneEntryRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../utilities/sql/deleteOne.js" + +export const deleteOneEntryRoute = registerRoute(deleteOneEntryRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: deleteOneEntryRouteDefinition.schemas.body, + }) + + const deleteOneEntry = await deleteOne({ + database: c.var.clients.sql, + table: models.entry, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idEntry)), + }) + + return response({ + context: c, + statusCode: 200, + schema: deleteOneEntryRouteDefinition.schemas.return, + data: deleteOneEntry, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/duplicateOneEntry.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts similarity index 77% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/duplicateOneEntry.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts index 65fca814..49a4a29f 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/duplicateOneEntry.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts @@ -1,18 +1,22 @@ import { duplicateOneEntryRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" -export const duplicateOneEntryRoute = apiFactory.createApp().post(duplicateOneEntryRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const duplicateOneEntryRoute = registerRoute(duplicateOneEntryRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: duplicateOneEntryRouteDefinition.schemas.body, @@ -54,7 +58,7 @@ export const duplicateOneEntryRoute = apiFactory.createApp().post(duplicateOneEn date: originalEntry.date, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) @@ -78,7 +82,7 @@ export const duplicateOneEntryRoute = apiFactory.createApp().post(duplicateOneEn credit: entryLine.credit, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, })), }) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/$idEntryLineRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/$idEntryLineRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/$idEntryLineRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/$idEntryLineRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts similarity index 57% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts index e1d23f59..1a6d91ce 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts @@ -1,17 +1,21 @@ import { deleteOneEntryLineRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../../utilities/sql/deleteOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../../utilities/sql/deleteOne.js" export const deleteOneEntryLineRoute = apiFactory .createApp() .post(deleteOneEntryLineRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneEntryLineRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts new file mode 100644 index 00000000..2925ca9c --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts @@ -0,0 +1,39 @@ +import { models, readOneEntryLineRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../../utilities/sql/selectOne.js" + +export const readOneEntryLineRoute = registerRoute(readOneEntryLineRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneEntryLineRouteDefinition.schemas.body, + }) + + const readOneEntryLine = await selectOne({ + database: c.var.clients.sql, + table: models.entryLine, + where: (table) => + and( + eq(table.idOrganization, idOrganization), + eq(table.idYear, body.idYear), + eq(table.id, body.idEntryLine), + ), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneEntryLineRouteDefinition.schemas.return, + data: readOneEntryLine, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts similarity index 68% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts index aa9105aa..8cae690f 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts @@ -1,17 +1,21 @@ import { models, updateOneEntryLineRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../../utilities/sql/updateOne.js" export const updateOneEntryLineRoute = apiFactory .createApp() .post(updateOneEntryLineRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneEntryLineRouteDefinition.schemas.body, @@ -32,7 +36,7 @@ export const updateOneEntryLineRoute = apiFactory debit: body.debit, credit: body.credit, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts similarity index 70% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts index ae6e50f1..a843b516 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts @@ -1,18 +1,22 @@ import { createOneEntryLineRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { insertOne } from "../../../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" export const createOneEntryLineRoute = apiFactory .createApp() .post(createOneEntryLineRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneEntryLineRouteDefinition.schemas.body, @@ -48,7 +52,7 @@ export const createOneEntryLineRoute = apiFactory credit: body.credit ?? "0.00", createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/entryLinesRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/entryLinesRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/entryLinesRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/entryLinesRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts similarity index 55% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts index 69eb7935..935bbbe0 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts @@ -1,15 +1,19 @@ import { models, readAllEntryLinesRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectMany } from "../../../../../../utilities/sql/selectMany.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../../utilities/sql/selectMany.js" -export const readAllEntryLinesRoute = apiFactory.createApp().post(readAllEntryLinesRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ +export const readAllEntryLinesRoute = registerRoute(readAllEntryLinesRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readAllEntryLinesRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts similarity index 73% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts index 8a397eeb..e6b90d9f 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts @@ -1,18 +1,22 @@ import { models, updateManyEntryLinesRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectMany } from "../../../../../../utilities/sql/selectMany.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../../utilities/sql/selectMany.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" export const updateManyEntryLinesRoute = apiFactory .createApp() .post(updateManyEntryLinesRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateManyEntryLinesRouteDefinition.schemas.body, @@ -43,7 +47,7 @@ export const updateManyEntryLinesRoute = apiFactory isComputedForIncomeStatementReport: body.isComputedForIncomeStatementReport, label: body.label, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts similarity index 60% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts index 0411c51f..d69bb416 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts @@ -1,16 +1,20 @@ import { addOneEntryTagRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { insertOne } from "../../../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" -export const addOneEntryTagRoute = apiFactory.createApp().post(addOneEntryTagRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ +export const addOneEntryTagRoute = registerRoute(addOneEntryTagRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: addOneEntryTagRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/entryTagsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/entryTagsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/entryTags/entryTagsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/entryTagsRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts new file mode 100644 index 00000000..f26571cd --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts @@ -0,0 +1,35 @@ +import { models, removeOneEntryTagRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" + +export const removeOneEntryTagRoute = registerRoute(removeOneEntryTagRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: removeOneEntryTagRouteDefinition.schemas.body, + }) + + const removeOneEntryTag = await deleteOne({ + database: c.var.clients.sql, + table: models.entryTag, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idEntryTag)), + }) + + return response({ + context: c, + statusCode: 200, + schema: removeOneEntryTagRouteDefinition.schemas.return, + data: removeOneEntryTag, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts new file mode 100644 index 00000000..a8a90a44 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts @@ -0,0 +1,35 @@ +import { models, readOneEntryRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" + +export const readOneEntryRoute = registerRoute(readOneEntryRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneEntryRouteDefinition.schemas.body, + }) + + const readOneEntry = await selectOne({ + database: c.var.clients.sql, + table: models.entry, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idEntry)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneEntryRouteDefinition.schemas.return, + data: readOneEntry, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/reverseOneEntry.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts similarity index 77% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/reverseOneEntry.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts index 69884bc0..bfd911dc 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/reverseOneEntry.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts @@ -1,18 +1,22 @@ import { generateId, models, reverseOneEntryRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" -export const reverseOneEntryRoute = apiFactory.createApp().post(reverseOneEntryRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const reverseOneEntryRoute = registerRoute(reverseOneEntryRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: reverseOneEntryRouteDefinition.schemas.body, @@ -54,7 +58,7 @@ export const reverseOneEntryRoute = apiFactory.createApp().post(reverseOneEntryR date: originalEntry.date, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) @@ -78,7 +82,7 @@ export const reverseOneEntryRoute = apiFactory.createApp().post(reverseOneEntryR credit: entryLine.debit, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, })), }) diff --git a/packages/api/src/routes/auth/$idYear/entries/$idEntry/updateOneEntry.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts similarity index 57% rename from packages/api/src/routes/auth/$idYear/entries/$idEntry/updateOneEntry.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts index 84477ab8..185fc2a5 100644 --- a/packages/api/src/routes/auth/$idYear/entries/$idEntry/updateOneEntry.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts @@ -1,15 +1,19 @@ import { models, updateOneEntryRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" -export const updateOneEntryRoute = apiFactory.createApp().post(updateOneEntryRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const updateOneEntryRoute = registerRoute(updateOneEntryRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneEntryRouteDefinition.schemas.body, @@ -25,7 +29,7 @@ export const updateOneEntryRoute = apiFactory.createApp().post(updateOneEntryRou label: body.label, date: body.date, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/entries/createOneEntry.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts similarity index 52% rename from packages/api/src/routes/auth/$idYear/entries/createOneEntry.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts index 69a3e6c6..de1a102e 100644 --- a/packages/api/src/routes/auth/$idYear/entries/createOneEntry.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts @@ -1,14 +1,18 @@ import { createOneEntryRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../utilities/sql/insertOne.js" -export const createOneEntryRoute = apiFactory.createApp().post(createOneEntryRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneEntryRoute = registerRoute(createOneEntryRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneEntryRouteDefinition.schemas.body, @@ -27,7 +31,7 @@ export const createOneEntryRoute = apiFactory.createApp().post(createOneEntryRou date: body.date, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/entries/createOneEntryFromTemplate.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts similarity index 75% rename from packages/api/src/routes/auth/$idYear/entries/createOneEntryFromTemplate.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts index f8e8f79a..40f1e7b0 100644 --- a/packages/api/src/routes/auth/$idYear/entries/createOneEntryFromTemplate.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts @@ -1,17 +1,21 @@ import { createOneEntryFromTemplateRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { insertMany } from "../../../../utilities/sql/insertMany.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../utilities/response.js" +import { insertMany } from "../../../../../../../utilities/sql/insertMany.js" +import { insertOne } from "../../../../../../../utilities/sql/insertOne.js" export const createOneEntryFromTemplateRoute = apiFactory .createApp() .post(createOneEntryFromTemplateRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneEntryFromTemplateRouteDefinition.schemas.body, @@ -31,7 +35,7 @@ export const createOneEntryFromTemplateRoute = apiFactory date: body.date, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) @@ -56,7 +60,7 @@ export const createOneEntryFromTemplateRoute = apiFactory credit: line.credit ?? "0.00", createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, })), }) diff --git a/packages/api/src/routes/auth/$idYear/entries/entriesRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/entriesRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/entries/entriesRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/entriesRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts new file mode 100644 index 00000000..fda96c6d --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts @@ -0,0 +1,34 @@ +import { models, readAllEntriesRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" + +export const readAllEntriesRoute = registerRoute(readAllEntriesRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readAllEntriesRouteDefinition.schemas.body, + }) + + const readAllEntries = await selectMany({ + database: c.var.clients.sql, + table: models.entry, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllEntriesRouteDefinition.schemas.return, + data: readAllEntries, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts new file mode 100644 index 00000000..d6700ec0 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts @@ -0,0 +1,34 @@ +import { models, readAllEntryTagsRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" + +export const readAllEntryTagsRoute = registerRoute(readAllEntryTagsRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readAllEntryTagsRouteDefinition.schemas.body, + }) + + const readAllEntryTags = await selectMany({ + database: c.var.clients.sql, + table: models.entryTag, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllEntryTagsRouteDefinition.schemas.return, + data: readAllEntryTags, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/reports/reportsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/exportsRoutes.ts similarity index 68% rename from packages/api/src/routes/auth/$idYear/reports/reportsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/exportsRoutes.ts index 37f0d71f..3686ce6b 100644 --- a/packages/api/src/routes/auth/$idYear/reports/reportsRoutes.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/exportsRoutes.ts @@ -1,7 +1,9 @@ import { generateBalanceSheetXmlRoute } from "./generateBalanceSheetXml.js" +import { generateFecRoute } from "./generateFec.js" import { generateIncomeStatementXmlRoute } from "./generateIncomeStatementXml.js" -export const reportsRoutes = [ +export const exportsRoutes = [ generateBalanceSheetXmlRoute, + generateFecRoute, generateIncomeStatementXmlRoute, ] diff --git a/packages/api/src/routes/auth/$idYear/reports/generateBalanceSheetXml.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateBalanceSheetXml.ts similarity index 91% rename from packages/api/src/routes/auth/$idYear/reports/generateBalanceSheetXml.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateBalanceSheetXml.ts index fe2f2df9..3c06e24a 100644 --- a/packages/api/src/routes/auth/$idYear/reports/generateBalanceSheetXml.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateBalanceSheetXml.ts @@ -1,13 +1,14 @@ import { generateBalanceSheetXmlRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { generateGetSignedUrl } from "../../../../utilities/storage/generateGetSignedUrl.js" -import { putObject } from "../../../../utilities/storage/putObject.js" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../utilities/sql/selectOne.js" +import { generateGetSignedUrl } from "../../../../../../../utilities/storage/generateGetSignedUrl.js" +import { putObject } from "../../../../../../../utilities/storage/putObject.js" // --------------------------------------------------------------------------- // Helpers @@ -246,9 +247,12 @@ ${facts.join("\n")} export const generateBalanceSheetXmlRoute = apiFactory .createApp() .post(generateBalanceSheetXmlRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: generateBalanceSheetXmlRouteDefinition.schemas.body, @@ -298,7 +302,7 @@ export const generateBalanceSheetXmlRoute = apiFactory }) const xmlBuffer = Buffer.from(xml, "utf-8") - const storageKey = `organizations/${idOrganization}/${body.idYear}/reports/balance-sheet.xml` + const storageKey = `organizations/${idOrganization}/${body.idYear}/exports/balance-sheet.xml` await putObject({ var: c.var, @@ -309,7 +313,7 @@ export const generateBalanceSheetXmlRoute = apiFactory metadata: { idOrganization, idYear: body.idYear, - idUser: user.id, + idUser: auth.user.id, }, }) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts new file mode 100644 index 00000000..ea9d4ae6 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts @@ -0,0 +1,236 @@ +import { generateFecRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../utilities/sql/selectOne.js" +import { generateGetSignedUrl } from "../../../../../../../utilities/storage/generateGetSignedUrl.js" +import { putObject } from "../../../../../../../utilities/storage/putObject.js" + +// --------------------------------------------------------------------------- +// FEC helpers +// --------------------------------------------------------------------------- + +/** + * Format a date string as YYYYMMDD for FEC compliance. + */ +function formatFecDate(rawDate: string | Date): string { + const date = new Date(rawDate) + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, "0") + const day = String(date.getDate()).padStart(2, "0") + return `${year}${month}${day}` +} + +/** + * Format a numeric amount for FEC: comma decimal separator, no thousands, 2 decimals. + * e.g. 1234.5 -> "1234,50" + */ +function formatFecAmount(value: number | string): string { + const num = Number(value) + const abs = Math.abs(num) < 0.009 ? 0 : num + return abs.toFixed(2).replace(".", ",") +} + +const FEC_HEADERS = [ + "JournalCode", + "JournalLib", + "EcritureNum", + "EcritureDate", + "CompteNum", + "CompteLib", + "CompAuxNum", + "CompAuxLib", + "PieceRef", + "PieceDate", + "EcritureLib", + "Debit", + "Credit", + "EcritureLet", + "DateLet", + "ValidDate", + "Montantdevise", + "Idevise", +] as const + +// --------------------------------------------------------------------------- +// Route +// --------------------------------------------------------------------------- + +export const generateFecRoute = apiFactory.createApp().post(generateFecRouteDefinition.path, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: generateFecRouteDefinition.schemas.body, + }) + + const [organization, entries, entryLines, accounts, journals] = await Promise.all([ + selectOne({ + database: c.var.clients.sql, + table: models.organization, + where: (t) => eq(t.id, idOrganization), + }), + selectMany({ + database: c.var.clients.sql, + table: models.entry, + where: (t) => and(eq(t.idOrganization, idOrganization), eq(t.idYear, body.idYear)), + }), + selectMany({ + database: c.var.clients.sql, + table: models.entryLine, + where: (t) => and(eq(t.idOrganization, idOrganization), eq(t.idYear, body.idYear)), + }), + selectMany({ + database: c.var.clients.sql, + table: models.account, + where: (t) => and(eq(t.idOrganization, idOrganization), eq(t.idYear, body.idYear)), + }), + selectMany({ + database: c.var.clients.sql, + table: models.journal, + where: (t) => eq(t.idOrganization, idOrganization), + }), + ]) + + const accountsMap = new Map( + accounts.map((a) => [ + a.id, + { + number: a.number, + label: a.label, + }, + ]), + ) + const journalsMap = new Map( + journals.map((j) => [ + j.id, + { + code: j.code, + label: j.label, + }, + ]), + ) + const entriesMap = new Map( + entries.map((e) => [ + e.id, + e, + ]), + ) + + // Build sequential EcritureNum per entry, sorted by date then id + const sortedEntries = [ + ...entries, + ].sort((a, b) => { + const dateCompare = a.date.localeCompare(b.date) + if (dateCompare !== 0) return dateCompare + return a.id.localeCompare(b.id) + }) + const ecritureNumMap = new Map() + for (let i = 0; i < sortedEntries.length; i++) { + ecritureNumMap.set(sortedEntries[i].id, String(i + 1)) + } + + // Sort rows by entry date, then EcritureNum, then row id + const sortedRows = [ + ...entryLines, + ].sort((a, b) => { + const entryA = entriesMap.get(a.idEntry) + const entryB = entriesMap.get(b.idEntry) + if (!entryA || !entryB) return 0 + const dateCompare = entryA.date.localeCompare(entryB.date) + if (dateCompare !== 0) return dateCompare + const numCompare = (ecritureNumMap.get(a.idEntry) ?? "").localeCompare( + ecritureNumMap.get(b.idEntry) ?? "", + undefined, + { + numeric: true, + }, + ) + if (numCompare !== 0) return numCompare + return a.id.localeCompare(b.id) + }) + + const rows = sortedRows + .map((row) => { + const entry = entriesMap.get(row.idEntry) + if (!entry) return null + + const account = accountsMap.get(row.idAccount) + const journal = entry.idJournal ? journalsMap.get(entry.idJournal) : null + + const ecritureDate = formatFecDate(entry.date) + const pieceDate = formatFecDate(entry.date) + const validDate = formatFecDate(entry.createdAt) + + return [ + journal?.code ?? "", + journal?.label ?? "", + ecritureNumMap.get(entry.id) ?? "", + ecritureDate, + account?.number ?? "", + account?.label ?? "", + "", // CompAuxNum - not supported + "", // CompAuxLib - not supported + entry.label, // PieceRef + pieceDate, + row.label ?? entry.label, // EcritureLib + formatFecAmount(row.debit), + formatFecAmount(row.credit), + "", // EcritureLet - not supported + "", // DateLet - not supported + validDate, + "", // Montantdevise + "", // Idevise + ].join("\t") + }) + .filter((row): row is string => row !== null) + + const BOM = "\uFEFF" + const fecContent = + BOM + + [ + FEC_HEADERS.join("\t"), + ...rows, + ].join("\n") + + const siren = organization.siren ?? "" + const filename = `${siren}FEC${formatFecDate(new Date())}.txt` + const fecBuffer = Buffer.from(fecContent, "utf-8") + const storageKey = `organizations/${idOrganization}/${body.idYear}/exports/fec.txt` + + await putObject({ + var: c.var, + body: fecBuffer, + storageKey, + contentType: "text/plain;charset=utf-8", + contentLength: fecBuffer.length, + metadata: { + idOrganization, + idYear: body.idYear, + idUser: auth.user.id, + filename, + }, + }) + + const url = await generateGetSignedUrl({ + var: c.var, + storageKey, + }) + + return response({ + context: c, + statusCode: 200, + schema: generateFecRouteDefinition.schemas.return, + data: { + url, + }, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/reports/generateIncomeStatementXml.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateIncomeStatementXml.ts similarity index 90% rename from packages/api/src/routes/auth/$idYear/reports/generateIncomeStatementXml.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateIncomeStatementXml.ts index dbc7ccb5..69d94348 100644 --- a/packages/api/src/routes/auth/$idYear/reports/generateIncomeStatementXml.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/exports/generateIncomeStatementXml.ts @@ -1,13 +1,14 @@ import { generateIncomeStatementXmlRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { generateGetSignedUrl } from "../../../../utilities/storage/generateGetSignedUrl.js" -import { putObject } from "../../../../utilities/storage/putObject.js" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../utilities/sql/selectOne.js" +import { generateGetSignedUrl } from "../../../../../../../utilities/storage/generateGetSignedUrl.js" +import { putObject } from "../../../../../../../utilities/storage/putObject.js" // --------------------------------------------------------------------------- // Types @@ -191,9 +192,12 @@ ${facts.join("\n")} export const generateIncomeStatementXmlRoute = apiFactory .createApp() .post(generateIncomeStatementXmlRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: generateIncomeStatementXmlRouteDefinition.schemas.body, @@ -256,7 +260,7 @@ export const generateIncomeStatementXmlRoute = apiFactory }) const xmlBuffer = Buffer.from(xml, "utf-8") - const storageKey = `organizations/${idOrganization}/${body.idYear}/reports/income-statement.xml` + const storageKey = `organizations/${idOrganization}/${body.idYear}/exports/income-statement.xml` await putObject({ var: c.var, @@ -267,7 +271,7 @@ export const generateIncomeStatementXmlRoute = apiFactory metadata: { idOrganization, idYear: body.idYear, - idUser: user.id, + idUser: auth.user.id, }, }) diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/$idFileRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/$idFileRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/files/$idFile/$idFileRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/$idFileRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/deleteOneFile.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts similarity index 59% rename from packages/api/src/routes/auth/$idYear/files/$idFile/deleteOneFile.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts index 04bfa159..bd2a317c 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/deleteOneFile.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts @@ -1,17 +1,21 @@ import { deleteOneFileRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq, sql } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { deleteOne } from "../../../../../utilities/sql/deleteOne.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../utilities/sql/deleteOne.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" -export const deleteOneFileRoute = apiFactory.createApp().post(deleteOneFileRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ +export const deleteOneFileRoute = registerRoute(deleteOneFileRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneFileRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/finalizeFileUpload.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts similarity index 70% rename from packages/api/src/routes/auth/$idYear/files/$idFile/finalizeFileUpload.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts index 60abc761..8e66cd4c 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/finalizeFileUpload.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts @@ -1,18 +1,22 @@ import { finalizeFileUploadRouteDefinition, models } from "@arrhes/application-metadata" import { HeadObjectCommand } from "@aws-sdk/client-s3" import { and, eq, sql } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" export const finalizeFileUploadRoute = apiFactory .createApp() .post(finalizeFileUploadRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: finalizeFileUploadRouteDefinition.schemas.body, @@ -34,7 +38,7 @@ export const finalizeFileUploadRoute = apiFactory type: storageHead.ContentType, size: storageHead.ContentLength, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), }) diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts similarity index 59% rename from packages/api/src/routes/auth/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts index 8c4f64e7..5ec33cd3 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts @@ -1,19 +1,23 @@ import { generateFileDeleteSignedUrlRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { generateDeleteSignedUrl } from "../../../../../utilities/storage/generateDeleteSignedUrl.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { generateDeleteSignedUrl } from "../../../../../../../../utilities/storage/generateDeleteSignedUrl.js" export const generateFileDeleteSignedUrlRoute = apiFactory .createApp() .post(generateFileDeleteSignedUrlRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: generateFileDeleteSignedUrlRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts similarity index 59% rename from packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts index 7413a045..215d6840 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFileGetSignedUrl.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts @@ -1,19 +1,23 @@ import { generateFileGetSignedUrlRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { generateGetSignedUrl } from "../../../../../utilities/storage/generateGetSignedUrl.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { generateGetSignedUrl } from "../../../../../../../../utilities/storage/generateGetSignedUrl.js" export const generateFileGetSignedUrlRoute = apiFactory .createApp() .post(generateFileGetSignedUrlRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: generateFileGetSignedUrlRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFilePutSignedUrl.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts similarity index 69% rename from packages/api/src/routes/auth/$idYear/files/$idFile/generateFilePutSignedUrl.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts index 6901a29c..079caca5 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/generateFilePutSignedUrl.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts @@ -1,19 +1,23 @@ import { generateFilePutSignedUrlRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { generatePutSignedUrl } from "../../../../../utilities/storage/generatePutSignedUrl.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { generatePutSignedUrl } from "../../../../../../../../utilities/storage/generatePutSignedUrl.js" export const generateFilePutSignedUrlRoute = apiFactory .createApp() .post(generateFilePutSignedUrlRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: generateFilePutSignedUrlRouteDefinition.schemas.body, @@ -57,7 +61,7 @@ export const generateFilePutSignedUrlRoute = apiFactory metadata: { idOrganization: idOrganization, idFile: readOneFile.id, - idUser: user.id, + idUser: auth.user.id, }, }) diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts similarity index 83% rename from packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts index bc153ff3..2ae9d70e 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/ocrFile.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts @@ -1,16 +1,17 @@ import { generateId, models, ocrFileRouteDefinition } from "@arrhes/application-metadata" import { and, eq, sql } from "drizzle-orm" -import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" -import { getObject } from "../../../../../utilities/storage/getObject.js" -import { putObject } from "../../../../../utilities/storage/putObject.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { checkOrganizationSubscriptionSessionMiddleware } from "../../../../../../../../middlewares/checkOrganizationSubscriptionSessionMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" +import { getObject } from "../../../../../../../../utilities/storage/getObject.js" +import { putObject } from "../../../../../../../../utilities/storage/putObject.js" function fixCommonMojibake(text: string) { // Heuristic: repair common UTF-8 text interpreted as Latin-1 (e.g. "Numéro" -> "Numéro"). @@ -22,10 +23,13 @@ function fixCommonMojibake(text: string) { return repaired.includes("�") ? text : repaired } -export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const ocrFileRoute = registerRoute(ocrFileRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: ocrFileRouteDefinition.schemas.body, @@ -179,7 +183,7 @@ export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.p type: "text/markdown", size: markdownBuffer.length, createdAt: new Date().toISOString(), - createdBy: user.id, + createdBy: auth.user.id, }, }) @@ -190,7 +194,7 @@ export const ocrFileRoute = apiFactory.createApp().post(ocrFileRouteDefinition.p contentType: "text/markdown; charset=utf-8", metadata: { idOrganization: idOrganization, - idUser: user.id, + idUser: auth.user.id, }, body: markdownBuffer, }) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts new file mode 100644 index 00000000..94a05cc3 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts @@ -0,0 +1,34 @@ +import { models, readOneFileRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" + +export const readOneFileRoute = registerRoute(readOneFileRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneFileRouteDefinition.schemas.body, + }) + + const readOneFile = await selectOne({ + database: c.var.clients.sql, + table: models.file, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneFileRouteDefinition.schemas.return, + data: readOneFile, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts similarity index 50% rename from packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts index 87de540a..53c98eba 100644 --- a/packages/api/src/routes/auth/$idYear/files/$idFile/updateOneFile.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts @@ -1,15 +1,19 @@ import { models, updateOneFileRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" -export const updateOneFileRoute = apiFactory.createApp().post(updateOneFileRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const updateOneFileRoute = registerRoute(updateOneFileRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneFileRouteDefinition.schemas.body, @@ -24,7 +28,7 @@ export const updateOneFileRoute = apiFactory.createApp().post(updateOneFileRoute date: body.date, idFolder: body.idFolder, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFile)), }) diff --git a/packages/api/src/routes/auth/$idYear/files/createOneFile.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts similarity index 54% rename from packages/api/src/routes/auth/$idYear/files/createOneFile.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts index 68bfb902..de5a9fc8 100644 --- a/packages/api/src/routes/auth/$idYear/files/createOneFile.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts @@ -1,14 +1,18 @@ import { createOneFileRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../utilities/sql/insertOne.js" -export const createOneFileRoute = apiFactory.createApp().post(createOneFileRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneFileRoute = registerRoute(createOneFileRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneFileRouteDefinition.schemas.body, @@ -29,7 +33,7 @@ export const createOneFileRoute = apiFactory.createApp().post(createOneFileRoute hash: body.hash, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/files/filesRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/filesRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/files/filesRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/filesRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts new file mode 100644 index 00000000..590d5421 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts @@ -0,0 +1,34 @@ +import { models, readAllFilesRouteDefinition } from "@arrhes/application-metadata" +import { eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" + +export const readAllFilesRoute = registerRoute(readAllFilesRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + await validateBodyMiddleware({ + context: c, + schema: readAllFilesRouteDefinition.schemas.body, + }) + + const readAllFiles = await selectMany({ + database: c.var.clients.sql, + table: models.file, + where: (table) => eq(table.idOrganization, idOrganization), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllFilesRouteDefinition.schemas.return, + data: readAllFiles, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/folders/$idFolder/$idFolderRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/$idFolderRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/folders/$idFolder/$idFolderRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/$idFolderRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts new file mode 100644 index 00000000..32bc66b4 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts @@ -0,0 +1,34 @@ +import { deleteOneFolderRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../utilities/sql/deleteOne.js" + +export const deleteOneFolderRoute = registerRoute(deleteOneFolderRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: deleteOneFolderRouteDefinition.schemas.body, + }) + + const deleteOneFolder = await deleteOne({ + database: c.var.clients.sql, + table: models.folder, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), + }) + + return response({ + context: c, + statusCode: 200, + schema: deleteOneFolderRouteDefinition.schemas.return, + data: deleteOneFolder, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts new file mode 100644 index 00000000..f3b41ad3 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts @@ -0,0 +1,34 @@ +import { models, readOneFolderRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" + +export const readOneFolderRoute = registerRoute(readOneFolderRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneFolderRouteDefinition.schemas.body, + }) + + const readOneFolder = await selectOne({ + database: c.var.clients.sql, + table: models.folder, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneFolderRouteDefinition.schemas.return, + data: readOneFolder, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts new file mode 100644 index 00000000..087ace3f --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts @@ -0,0 +1,40 @@ +import { models, updateOneFolderRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" + +export const updateOneFolderRoute = registerRoute(updateOneFolderRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: updateOneFolderRouteDefinition.schemas.body, + }) + + const updateOneFolder = await updateOne({ + database: c.var.clients.sql, + table: models.folder, + data: { + name: body.name, + idFolderParent: body.idFolderParent, + lastUpdatedAt: new Date().toISOString(), + lastUpdatedBy: auth.user.id, + }, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idFolder)), + }) + + return response({ + context: c, + statusCode: 200, + schema: updateOneFolderRouteDefinition.schemas.return, + data: updateOneFolder, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts similarity index 50% rename from packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts index 442c1b1e..5ef7b50c 100644 --- a/packages/api/src/routes/auth/$idYear/folders/createOneFolder.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts @@ -1,14 +1,18 @@ import { createOneFolderRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../utilities/sql/insertOne.js" -export const createOneFolderRoute = apiFactory.createApp().post(createOneFolderRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneFolderRoute = registerRoute(createOneFolderRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneFolderRouteDefinition.schemas.body, @@ -24,7 +28,7 @@ export const createOneFolderRoute = apiFactory.createApp().post(createOneFolderR name: body.name, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/folders/foldersRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/foldersRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/folders/foldersRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/foldersRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts new file mode 100644 index 00000000..e87efd9e --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts @@ -0,0 +1,34 @@ +import { models, readAllFoldersRouteDefinition } from "@arrhes/application-metadata" +import { eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" + +export const readAllFoldersRoute = registerRoute(readAllFoldersRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const _body = await validateBodyMiddleware({ + context: c, + schema: readAllFoldersRouteDefinition.schemas.body, + }) + + const readAllFolders = await selectMany({ + database: c.var.clients.sql, + table: models.folder, + where: (table) => eq(table.idOrganization, idOrganization), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllFoldersRouteDefinition.schemas.return, + data: readAllFolders, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts new file mode 100644 index 00000000..9966c11c --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts @@ -0,0 +1,34 @@ +import { models, readOneYearRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../utilities/sql/selectOne.js" + +export const readOneYearRoute = registerRoute(readOneYearRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneYearRouteDefinition.schemas.body, + }) + + const readOneYear = await selectOne({ + database: c.var.clients.sql, + table: models.year, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneYearRouteDefinition.schemas.return, + data: readOneYear, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/$idAccountRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/$idAccountRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/$idAccountRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/$idAccountRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts new file mode 100644 index 00000000..6f2acbeb --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts @@ -0,0 +1,35 @@ +import { deleteOneAccountRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" + +export const deleteOneAccountRoute = registerRoute(deleteOneAccountRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: deleteOneAccountRouteDefinition.schemas.body, + }) + + const deleteOneAccount = await deleteOne({ + database: c.var.clients.sql, + table: models.account, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idAccount)), + }) + + return response({ + context: c, + statusCode: 200, + schema: deleteOneAccountRouteDefinition.schemas.return, + data: deleteOneAccount, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts new file mode 100644 index 00000000..bc22bb33 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts @@ -0,0 +1,35 @@ +import { models, readOneAccountRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" + +export const readOneAccountRoute = registerRoute(readOneAccountRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneAccountRouteDefinition.schemas.body, + }) + + const readOneAccount = await selectOne({ + database: c.var.clients.sql, + table: models.account, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idAccount)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneAccountRouteDefinition.schemas.return, + data: readOneAccount, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts similarity index 62% rename from packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts index 569b807a..b7b836fc 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts @@ -1,15 +1,19 @@ import { models, updateOneAccountRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" -export const updateOneAccountRoute = apiFactory.createApp().post(updateOneAccountRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const updateOneAccountRoute = registerRoute(updateOneAccountRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneAccountRouteDefinition.schemas.body, @@ -36,7 +40,7 @@ export const updateOneAccountRoute = apiFactory.createApp().post(updateOneAccoun label: body.label, type: body.type, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idAccount)), diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/accountsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/accounts/accountsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/accountsRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/createOneAccount.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts similarity index 70% rename from packages/api/src/routes/auth/$idYear/yearSettings/accounts/createOneAccount.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts index 821c7feb..9597c2fc 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/createOneAccount.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts @@ -1,16 +1,20 @@ import { createOneAccountRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" -export const createOneAccountRoute = apiFactory.createApp().post(createOneAccountRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneAccountRoute = registerRoute(createOneAccountRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneAccountRouteDefinition.schemas.body, @@ -59,7 +63,7 @@ export const createOneAccountRoute = apiFactory.createApp().post(createOneAccoun isOptional: false, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/generateAccounts.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts similarity index 82% rename from packages/api/src/routes/auth/$idYear/yearSettings/accounts/generateAccounts.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts index 9dd010ca..4bd5519a 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/accounts/generateAccounts.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts @@ -10,14 +10,15 @@ import { } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" import type * as v from "valibot" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" function generateAccounts(parameters: { accounts: Array @@ -68,7 +69,7 @@ function generateAccounts(parameters: { return newAccounts } -export const generateAccountsRoute = apiFactory.createApp().post(generateAccountsRouteDefinition.path, async (c) => { +export const generateAccountsRoute = registerRoute(generateAccountsRouteDefinition, async (c) => { const { idOrganization } = await checkUserSessionMiddleware({ context: c }) const body = await validateBodyMiddleware({ context: c, diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts new file mode 100644 index 00000000..d46fe9bd --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts @@ -0,0 +1,34 @@ +import { models, readAllAccountsRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" + +export const readAllAccountsRoute = registerRoute(readAllAccountsRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readAllAccountsRouteDefinition.schemas.body, + }) + + const readAllAccounts = await selectMany({ + database: c.var.clients.sql, + table: models.account, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllAccountsRouteDefinition.schemas.return, + data: readAllAccounts, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/$idBalanceSheetRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/$idBalanceSheetRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/$idBalanceSheetRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/$idBalanceSheetRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts similarity index 58% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts index bdaa971a..7bd301ba 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts @@ -1,17 +1,21 @@ import { deleteOneBalanceSheetRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" export const deleteOneBalanceSheetRoute = apiFactory .createApp() .post(deleteOneBalanceSheetRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneBalanceSheetRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts similarity index 58% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts index abfcb38b..99213725 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts @@ -1,17 +1,21 @@ import { models, readOneBalanceSheetRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" export const readOneBalanceSheetRoute = apiFactory .createApp() .post(readOneBalanceSheetRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readOneBalanceSheetRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts similarity index 62% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts index 346c0bc4..14b2d8d6 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts @@ -1,17 +1,21 @@ import { models, updateOneBalanceSheetRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" export const updateOneBalanceSheetRoute = apiFactory .createApp() .post(updateOneBalanceSheetRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneBalanceSheetRouteDefinition.schemas.body, @@ -26,7 +30,7 @@ export const updateOneBalanceSheetRoute = apiFactory number: body.number, label: body.label, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/balanceSheetsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/balanceSheetsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/balanceSheetsRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts similarity index 89% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts index 92a217dd..65cfd621 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts @@ -6,13 +6,13 @@ import { models, } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" export const connectAccountsToBalanceSheetsRoute = apiFactory .createApp() diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts similarity index 63% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts index ef60a50b..0aa1818c 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts @@ -1,16 +1,20 @@ import { createOneBalanceSheetRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" export const createOneBalanceSheetRoute = apiFactory .createApp() .post(createOneBalanceSheetRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneBalanceSheetRouteDefinition.schemas.body, @@ -31,7 +35,7 @@ export const createOneBalanceSheetRoute = apiFactory label: body.label, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts similarity index 83% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts index 12fe1f76..121975ac 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts @@ -9,14 +9,14 @@ import { } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" import type * as v from "valibot" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" export const generateBalanceSheetsRoute = apiFactory .createApp() diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts similarity index 55% rename from packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts index 4728efab..3297fa96 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts @@ -1,17 +1,21 @@ import { models, readAllBalanceSheetsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" export const readAllBalanceSheetsRoute = apiFactory .createApp() .post(readAllBalanceSheetsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readAllBalanceSheetsRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/$idComputationRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/$idComputationRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/$idComputationRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/$idComputationRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/$idComputationIncomeStatementRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/$idComputationIncomeStatementRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/$idComputationIncomeStatementRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/$idComputationIncomeStatementRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts similarity index 63% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts index fabff1e1..4dd5f01e 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts @@ -1,17 +1,21 @@ import { deleteOneComputationIncomeStatementRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../../../utilities/sql/deleteOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../../../utilities/sql/deleteOne.js" export const deleteOneComputationIncomeStatementRoute = apiFactory .createApp() .post(deleteOneComputationIncomeStatementRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneComputationIncomeStatementRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts similarity index 63% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts index fe5b9df8..e03c6d5c 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts @@ -1,17 +1,21 @@ import { models, readOneComputationIncomeStatementRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../../../utilities/sql/selectOne.js" export const readOneComputationIncomeStatementRoute = apiFactory .createApp() .post(readOneComputationIncomeStatementRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readOneComputationIncomeStatementRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts similarity index 66% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts index b752a645..5cfee2b0 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts @@ -1,17 +1,21 @@ import { models, updateOneComputationIncomeStatementRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../../../utilities/sql/updateOne.js" export const updateOneComputationIncomeStatementRoute = apiFactory .createApp() .post(updateOneComputationIncomeStatementRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneComputationIncomeStatementRouteDefinition.schemas.body, @@ -25,7 +29,7 @@ export const updateOneComputationIncomeStatementRoute = apiFactory idIncomeStatement: body.idIncomeStatement, operation: body.operation, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/computationIncomeStatementsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/computationIncomeStatementsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/computationIncomeStatementsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/computationIncomeStatementsRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts similarity index 63% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts index c7dbb652..7d6317fb 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts @@ -1,16 +1,20 @@ import { createOneComputationIncomeStatementRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../utilities/response.js" -import { insertOne } from "../../../../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../../../utilities/sql/insertOne.js" export const createOneComputationIncomeStatementRoute = apiFactory .createApp() .post(createOneComputationIncomeStatementRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneComputationIncomeStatementRouteDefinition.schemas.body, @@ -29,7 +33,7 @@ export const createOneComputationIncomeStatementRoute = apiFactory index: body.index, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts similarity index 69% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts index a9f8a29b..803c4b5b 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts @@ -1,17 +1,21 @@ import { models, readAllComputationIncomeStatementsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../../utilities/response.js" -import { selectMany } from "../../../../../../../utilities/sql/selectMany.js" +import { checkAuthMiddleware } from "../../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../../../utilities/sql/selectMany.js" export const readAllComputationIncomeStatementsRoute = apiFactory .createApp() .post(readAllComputationIncomeStatementsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readAllComputationIncomeStatementsRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts similarity index 58% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts index 6f4d0632..aed4f642 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts @@ -1,17 +1,21 @@ import { deleteOneComputationRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" export const deleteOneComputationRoute = apiFactory .createApp() .post(deleteOneComputationRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneComputationRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts similarity index 58% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts index c5ddff30..64a0713a 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts @@ -1,17 +1,21 @@ import { models, readOneComputationRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" export const readOneComputationRoute = apiFactory .createApp() .post(readOneComputationRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readOneComputationRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts similarity index 60% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts index cefd42c3..c0b7a6d4 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts @@ -1,17 +1,21 @@ import { models, updateOneComputationRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" export const updateOneComputationRoute = apiFactory .createApp() .post(updateOneComputationRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneComputationRouteDefinition.schemas.body, @@ -24,7 +28,7 @@ export const updateOneComputationRoute = apiFactory number: body.number, label: body.label, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/computationsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/computationsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/computationsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/computationsRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/createOneComputation.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts similarity index 60% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/createOneComputation.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts index 75449fe5..77f799d8 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/createOneComputation.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts @@ -1,16 +1,20 @@ import { createOneComputationRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" export const createOneComputationRoute = apiFactory .createApp() .post(createOneComputationRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneComputationRouteDefinition.schemas.body, @@ -28,7 +32,7 @@ export const createOneComputationRoute = apiFactory label: body.label, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/generateComputations.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts similarity index 84% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/generateComputations.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts index a1b29ac2..742088e5 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/generateComputations.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts @@ -6,14 +6,14 @@ import { models, } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" export const generateComputationsRoute = apiFactory .createApp() diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/computations/readAllComputations.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts similarity index 55% rename from packages/api/src/routes/auth/$idYear/yearSettings/computations/readAllComputations.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts index 48d4da17..0a91c06d 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/computations/readAllComputations.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts @@ -1,17 +1,21 @@ import { models, readAllComputationsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" export const readAllComputationsRoute = apiFactory .createApp() .post(readAllComputationsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readAllComputationsRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts new file mode 100644 index 00000000..0f74ac8e --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts @@ -0,0 +1,39 @@ +import { closeYearRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq, not } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" + +export const closeYearRoute = registerRoute(closeYearRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: closeYearRouteDefinition.schemas.body, + }) + + const closeYear = await updateOne({ + database: c.var.clients.sql, + table: models.year, + data: { + isClosed: not(models.year.isClosed), + lastUpdatedAt: new Date().toISOString(), + lastUpdatedBy: auth.user.id, + }, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: closeYearRouteDefinition.schemas.return, + data: closeYear, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts new file mode 100644 index 00000000..55aabd03 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts @@ -0,0 +1,34 @@ +import { deleteOneYearRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../utilities/sql/deleteOne.js" + +export const deleteOneYearRoute = registerRoute(deleteOneYearRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: deleteOneYearRouteDefinition.schemas.body, + }) + + const deleteOneYear = await deleteOne({ + database: c.var.clients.sql, + table: models.year, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: deleteOneYearRouteDefinition.schemas.return, + data: deleteOneYear, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/generalRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/generalRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/general/generalRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/generalRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/openYear.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts similarity index 88% rename from packages/api/src/routes/auth/$idYear/yearSettings/general/openYear.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts index 2fd4febb..da94ae85 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/general/openYear.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts @@ -1,11 +1,11 @@ import { openYearRouteDefinition } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" -export const openYearRoute = apiFactory.createApp().post(openYearRouteDefinition.path, async (c) => { - await checkUserSessionMiddleware({ +export const openYearRoute = registerRoute(openYearRouteDefinition, async (c) => { + await checkAuthMiddleware({ context: c, }) const _body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/settleBalanceSheet.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts similarity index 81% rename from packages/api/src/routes/auth/$idYear/yearSettings/general/settleBalanceSheet.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts index 64fcd15e..3b4ecfb1 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/general/settleBalanceSheet.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts @@ -1,22 +1,26 @@ import { generateId, models, settleBalanceSheetRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" export const settleBalanceSheetRoute = apiFactory .createApp() .post(settleBalanceSheetRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: settleBalanceSheetRouteDefinition.schemas.body, @@ -98,7 +102,7 @@ export const settleBalanceSheetRoute = apiFactory credit: algebraicBalance > 0 ? String(algebraicBalance.toFixed(2)) : "0.00", createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }) } @@ -125,7 +129,7 @@ export const settleBalanceSheetRoute = apiFactory date: year.endingAt, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/settleIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts similarity index 84% rename from packages/api/src/routes/auth/$idYear/yearSettings/general/settleIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts index c5d7e6de..f9b9bb97 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/general/settleIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts @@ -1,22 +1,26 @@ import { generateId, models, settleIncomeStatementRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" export const settleIncomeStatementRoute = apiFactory .createApp() .post(settleIncomeStatementRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: settleIncomeStatementRouteDefinition.schemas.body, @@ -98,7 +102,7 @@ export const settleIncomeStatementRoute = apiFactory credit: algebraicBalance > 0 ? String(algebraicBalance.toFixed(2)) : "0.00", createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }) } @@ -130,7 +134,7 @@ export const settleIncomeStatementRoute = apiFactory date: year.endingAt, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) @@ -157,7 +161,7 @@ export const settleIncomeStatementRoute = apiFactory credit: algebraicResult < 0 ? String((-algebraicResult).toFixed(2)) : "0.00", createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/general/updateOneYear.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts similarity index 51% rename from packages/api/src/routes/auth/$idYear/yearSettings/general/updateOneYear.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts index f2b71762..99321e8f 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/general/updateOneYear.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts @@ -1,15 +1,19 @@ import { models, updateOneYearRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" -export const updateOneYearRoute = apiFactory.createApp().post(updateOneYearRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const updateOneYearRoute = registerRoute(updateOneYearRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneYearRouteDefinition.schemas.body, @@ -24,7 +28,7 @@ export const updateOneYearRoute = apiFactory.createApp().post(updateOneYearRoute startingAt: body.startingAt, endingAt: body.endingAt, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.id, body.idYear)), }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/$idIncomeStatementRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/$idIncomeStatementRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/$idIncomeStatementRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/$idIncomeStatementRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts similarity index 59% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts index 6ec5242a..6f069362 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts @@ -1,17 +1,21 @@ import { deleteOneIncomeStatementRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { deleteOne } from "../../../../../../utilities/sql/deleteOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" export const deleteOneIncomeStatementRoute = apiFactory .createApp() .post(deleteOneIncomeStatementRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: deleteOneIncomeStatementRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts similarity index 59% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts index 94cd428a..42a5aa79 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts @@ -1,17 +1,21 @@ import { models, readOneIncomeStatementRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { selectOne } from "../../../../../../utilities/sql/selectOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" export const readOneIncomeStatementRoute = apiFactory .createApp() .post(readOneIncomeStatementRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readOneIncomeStatementRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts similarity index 63% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts index 8be0aef2..05cda039 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts @@ -1,17 +1,21 @@ import { models, updateOneIncomeStatementRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" export const updateOneIncomeStatementRoute = apiFactory .createApp() .post(updateOneIncomeStatementRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneIncomeStatementRouteDefinition.schemas.body, @@ -26,7 +30,7 @@ export const updateOneIncomeStatementRoute = apiFactory number: body.number, label: body.label, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts similarity index 85% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts index 21c0dfce..60ab1607 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts @@ -6,13 +6,13 @@ import { models, } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../../utilities/sql/updateOne.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../../../../utilities/sql/updateOne.js" export const connectAccountsToIncomeStatementsRoute = apiFactory .createApp() diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts similarity index 63% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts index c4cba3c2..b1a09c3e 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts @@ -1,16 +1,20 @@ import { createOneIncomeStatementRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" export const createOneIncomeStatementRoute = apiFactory .createApp() .post(createOneIncomeStatementRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneIncomeStatementRouteDefinition.schemas.body, @@ -30,7 +34,7 @@ export const createOneIncomeStatementRoute = apiFactory label: body.label, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts similarity index 83% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts index 3700288f..cdcfbcfc 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts @@ -9,14 +9,14 @@ import { } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" import type * as v from "valibot" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" -import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" +import { selectOne } from "../../../../../../../../utilities/sql/selectOne.js" export const generateIncomeStatementsRoute = apiFactory .createApp() diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/incomeStatementsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/incomeStatementsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/incomeStatementsRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts similarity index 56% rename from packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts index 5b3bc5bc..34dea83d 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts @@ -1,17 +1,21 @@ import { models, readAllIncomeStatementsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { selectMany } from "../../../../../utilities/sql/selectMany.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" export const readAllIncomeStatementsRoute = apiFactory .createApp() .post(readAllIncomeStatementsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: readAllIncomeStatementsRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/$idJournalRoute.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/$idJournalRoute.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/$idJournalRoute.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/$idJournalRoute.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts new file mode 100644 index 00000000..9b6ad365 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts @@ -0,0 +1,35 @@ +import { deleteOneJournalRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" + +export const deleteOneJournalRoute = registerRoute(deleteOneJournalRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: deleteOneJournalRouteDefinition.schemas.body, + }) + + const deleteOneJournal = await deleteOne({ + database: c.var.clients.sql, + table: models.journal, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idJournal)), + }) + + return response({ + context: c, + statusCode: 200, + schema: deleteOneJournalRouteDefinition.schemas.return, + data: deleteOneJournal, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts new file mode 100644 index 00000000..9dd90b7e --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts @@ -0,0 +1,35 @@ +import { models, readOneJournalRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" + +export const readOneJournalRoute = registerRoute(readOneJournalRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneJournalRouteDefinition.schemas.body, + }) + + const readOneJournal = await selectOne({ + database: c.var.clients.sql, + table: models.journal, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idJournal)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneJournalRouteDefinition.schemas.return, + data: readOneJournal, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts similarity index 50% rename from packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts index a11b5fc3..f5448ecd 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts @@ -1,15 +1,19 @@ import { models, updateOneJournalRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../../utilities/apiFactory.js" -import { response } from "../../../../../../utilities/response.js" -import { updateOne } from "../../../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" -export const updateOneJournalRoute = apiFactory.createApp().post(updateOneJournalRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const updateOneJournalRoute = registerRoute(updateOneJournalRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: updateOneJournalRouteDefinition.schemas.body, @@ -22,7 +26,7 @@ export const updateOneJournalRoute = apiFactory.createApp().post(updateOneJourna code: body.code, label: body.label, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idJournal)), diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/createOneJournal.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts similarity index 50% rename from packages/api/src/routes/auth/$idYear/yearSettings/journals/createOneJournal.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts index 0a75a95d..89c78efa 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/journals/createOneJournal.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts @@ -1,14 +1,18 @@ import { createOneJournalRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { response } from "../../../../../utilities/response.js" -import { insertOne } from "../../../../../utilities/sql/insertOne.js" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" -export const createOneJournalRoute = apiFactory.createApp().post(createOneJournalRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneJournalRoute = registerRoute(createOneJournalRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneJournalRouteDefinition.schemas.body, @@ -25,7 +29,7 @@ export const createOneJournalRoute = apiFactory.createApp().post(createOneJourna label: body.label, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/generateJournals.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts similarity index 69% rename from packages/api/src/routes/auth/$idYear/yearSettings/journals/generateJournals.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts index 213595a3..f87e902b 100644 --- a/packages/api/src/routes/auth/$idYear/yearSettings/journals/generateJournals.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts @@ -1,15 +1,16 @@ /* import { defaultJournals, generateId, generateJournalsRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../../utilities/apiFactory.js" -import { Exception } from "../../../../../utilities/exception.js" -import { response } from "../../../../../utilities/response.js" -import { deleteMany } from "../../../../../utilities/sql/deleteMany.js" -import { insertMany } from "../../../../../utilities/sql/insertMany.js" +import { checkUserSessionMiddleware } from "../../../../../../../../../../middlewares/checkUserSessionMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { apiFactory } from "../../../../../../../../utilities/apiFactory.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { Exception } from "../../../../../../../../utilities/exception.js" +import { response } from "../../../../../../../../utilities/response.js" +import { deleteMany } from "../../../../../../../../utilities/sql/deleteMany.js" +import { insertMany } from "../../../../../../../../utilities/sql/insertMany.js" -export const generateJournalsRoute = apiFactory.createApp().post(generateJournalsRouteDefinition.path, async (c) => { +export const generateJournalsRoute = registerRoute(generateJournalsRouteDefinition, async (c) => { const { idOrganization } = await checkUserSessionMiddleware({ context: c }) const body = await validateBodyMiddleware({ context: c, diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/journals/journalsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/journals/journalsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/journalsRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts new file mode 100644 index 00000000..d7d6359e --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts @@ -0,0 +1,34 @@ +import { models, readAllJournalsRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" + +export const readAllJournalsRoute = registerRoute(readAllJournalsRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readAllJournalsRouteDefinition.schemas.body, + }) + + const readAllJournals = await selectMany({ + database: c.var.clients.sql, + table: models.journal, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllJournalsRouteDefinition.schemas.return, + data: readAllJournals, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/$idTagRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/$idTagRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/tags/$idTag/$idTagRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/$idTagRoutes.ts diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts new file mode 100644 index 00000000..d28eef7d --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts @@ -0,0 +1,35 @@ +import { deleteOneTagRouteDefinition, models } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { deleteOne } from "../../../../../../../../../utilities/sql/deleteOne.js" + +export const deleteOneTagRoute = registerRoute(deleteOneTagRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: deleteOneTagRouteDefinition.schemas.body, + }) + + const deleteOneTag = await deleteOne({ + database: c.var.clients.sql, + table: models.tag, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idTag)), + }) + + return response({ + context: c, + statusCode: 200, + schema: deleteOneTagRouteDefinition.schemas.return, + data: deleteOneTag, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts new file mode 100644 index 00000000..87787765 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts @@ -0,0 +1,35 @@ +import { models, readOneTagRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { selectOne } from "../../../../../../../../../utilities/sql/selectOne.js" + +export const readOneTagRoute = registerRoute(readOneTagRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readOneTagRouteDefinition.schemas.body, + }) + + const readOneTag = await selectOne({ + database: c.var.clients.sql, + table: models.tag, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idTag)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readOneTagRouteDefinition.schemas.return, + data: readOneTag, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts new file mode 100644 index 00000000..0bd149a0 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts @@ -0,0 +1,41 @@ +import { models, updateOneTagRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../../utilities/response.js" +import { updateOne } from "../../../../../../../../../utilities/sql/updateOne.js" + +export const updateOneTagRoute = registerRoute(updateOneTagRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: updateOneTagRouteDefinition.schemas.body, + }) + + const updateOneTag = await updateOne({ + database: c.var.clients.sql, + table: models.tag, + data: { + label: body.label, + + lastUpdatedAt: new Date().toISOString(), + lastUpdatedBy: auth.user.id, + }, + where: (table) => + and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear), eq(table.id, body.idTag)), + }) + + return response({ + context: c, + statusCode: 200, + schema: updateOneTagRouteDefinition.schemas.return, + data: updateOneTag, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts new file mode 100644 index 00000000..07f3811c --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts @@ -0,0 +1,44 @@ +import { createOneTagRouteDefinition, generateId, models } from "@arrhes/application-metadata" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { insertOne } from "../../../../../../../../utilities/sql/insertOne.js" + +export const createOneTagRoute = registerRoute(createOneTagRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: createOneTagRouteDefinition.schemas.body, + }) + + const createOneTag = await insertOne({ + database: c.var.clients.sql, + table: models.tag, + data: { + id: generateId(), + idOrganization: idOrganization, + idYear: body.idYear, + + label: body.label, + + createdAt: new Date().toISOString(), + lastUpdatedAt: null, + createdBy: auth.user.id, + lastUpdatedBy: null, + }, + }) + + return response({ + context: c, + statusCode: 200, + schema: createOneTagRouteDefinition.schemas.return, + data: createOneTag, + }) +}) diff --git a/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts new file mode 100644 index 00000000..18a998c3 --- /dev/null +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts @@ -0,0 +1,34 @@ +import { models, readAllTagsRouteDefinition } from "@arrhes/application-metadata" +import { and, eq } from "drizzle-orm" +import { checkAuthMiddleware } from "../../../../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../../../../utilities/registerRoute.js" +import { response } from "../../../../../../../../utilities/response.js" +import { selectMany } from "../../../../../../../../utilities/sql/selectMany.js" + +export const readAllTagsRoute = registerRoute(readAllTagsRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ + context: c, + }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) + const body = await validateBodyMiddleware({ + context: c, + schema: readAllTagsRouteDefinition.schemas.body, + }) + + const readAllTags = await selectMany({ + database: c.var.clients.sql, + table: models.tag, + where: (table) => and(eq(table.idOrganization, idOrganization), eq(table.idYear, body.idYear)), + }) + + return response({ + context: c, + statusCode: 200, + schema: readAllTagsRouteDefinition.schemas.return, + data: readAllTags, + }) +}) diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/tags/tagsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoutes.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/tags/tagsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/tagsRoutes.ts diff --git a/packages/api/src/routes/auth/$idYear/yearSettings/yearSettingsRoute.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.ts similarity index 100% rename from packages/api/src/routes/auth/$idYear/yearSettings/yearSettingsRoute.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/$idYear/yearSettings/yearSettingsRoute.ts diff --git a/packages/api/src/routes/auth/$idOrganization/years/createOneYear.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/createOneYear.ts similarity index 92% rename from packages/api/src/routes/auth/$idOrganization/years/createOneYear.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/createOneYear.ts index fe03189d..8e7758f5 100644 --- a/packages/api/src/routes/auth/$idOrganization/years/createOneYear.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/createOneYear.ts @@ -15,14 +15,15 @@ import { } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" import type * as v from "valibot" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { response } from "../../../../utilities/response.js" -import { insertMany } from "../../../../utilities/sql/insertMany.js" -import { insertOne } from "../../../../utilities/sql/insertOne.js" -import { selectOne } from "../../../../utilities/sql/selectOne.js" -import { updateOne } from "../../../../utilities/sql/updateOne.js" +import { checkAuthMiddleware } from "../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../../../utilities/registerRoute.js" +import { response } from "../../../../../utilities/response.js" +import { insertMany } from "../../../../../utilities/sql/insertMany.js" +import { insertOne } from "../../../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../../../utilities/sql/updateOne.js" function buildAccountRows(parameters: { accounts: Array @@ -73,10 +74,13 @@ function buildAccountRows(parameters: { return newAccounts } -export const createOneYearRoute = apiFactory.createApp().post(createOneYearRouteDefinition.path, async (c) => { - const { user, idOrganization } = await checkUserSessionMiddleware({ +export const createOneYearRoute = registerRoute(createOneYearRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) const body = await validateBodyMiddleware({ context: c, schema: createOneYearRouteDefinition.schemas.body, @@ -98,7 +102,7 @@ export const createOneYearRoute = apiFactory.createApp().post(createOneYearRoute endingAt: body.endingAt, createdAt: new Date().toISOString(), lastUpdatedAt: null, - createdBy: user.id, + createdBy: auth.user.id, lastUpdatedBy: null, }, }) @@ -303,7 +307,7 @@ export const createOneYearRoute = apiFactory.createApp().post(createOneYearRoute defaultBalanceSheet.side === "liability" ? defaultAccount.flow : undefined, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( @@ -339,7 +343,7 @@ export const createOneYearRoute = apiFactory.createApp().post(createOneYearRoute data: { idIncomeStatement: incomeStatement.id, lastUpdatedAt: new Date().toISOString(), - lastUpdatedBy: user.id, + lastUpdatedBy: auth.user.id, }, where: (table) => and( diff --git a/packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/readAllYears.ts similarity index 51% rename from packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/readAllYears.ts index 85aa48aa..ec0825ee 100644 --- a/packages/api/src/routes/auth/$idOrganization/years/readAllYears.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/readAllYears.ts @@ -1,16 +1,20 @@ import { models, readAllYearsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../../middlewares/checkUserSessionMiddleware.js" -import { validateBodyMiddleware } from "../../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../../utilities/apiFactory.js" -import { Exception } from "../../../../utilities/exception.js" -import { response } from "../../../../utilities/response.js" -import { selectMany } from "../../../../utilities/sql/selectMany.js" +import { checkAuthMiddleware } from "../../../../../middlewares/checkAuthMiddleware.js" +import { requireOrganizationMiddleware } from "../../../../../middlewares/requireOrganizationMiddleware.js" +import { validateBodyMiddleware } from "../../../../../middlewares/validateBody.middleware.js" +import { Exception } from "../../../../../utilities/exception.js" +import { registerRoute } from "../../../../../utilities/registerRoute.js" +import { response } from "../../../../../utilities/response.js" +import { selectMany } from "../../../../../utilities/sql/selectMany.js" -export const readAllYearsRoute = apiFactory.createApp().post(readAllYearsRouteDefinition.path, async (c) => { - const { idOrganization } = await checkUserSessionMiddleware({ +export const readAllYearsRoute = registerRoute(readAllYearsRouteDefinition, async (c) => { + const auth = await checkAuthMiddleware({ context: c, }) + const idOrganization = await requireOrganizationMiddleware({ + idOrganization: auth.idOrganization, + }) if (!idOrganization) { throw new Exception({ statusCode: 400, diff --git a/packages/api/src/routes/auth/$idOrganization/years/yearsRoutes.ts b/packages/api/src/routes/auth/organizations/$idOrganization/years/yearsRoutes.ts similarity index 77% rename from packages/api/src/routes/auth/$idOrganization/years/yearsRoutes.ts rename to packages/api/src/routes/auth/organizations/$idOrganization/years/yearsRoutes.ts index 63be947b..f300ee72 100644 --- a/packages/api/src/routes/auth/$idOrganization/years/yearsRoutes.ts +++ b/packages/api/src/routes/auth/organizations/$idOrganization/years/yearsRoutes.ts @@ -1,4 +1,4 @@ -import { $idYearRoutes } from "../../$idYear/$idYearRoutes.js" +import { $idYearRoutes } from "./$idYear/$idYearRoutes.js" import { createOneYearRoute } from "./createOneYear.js" import { readAllYearsRoute } from "./readAllYears.js" diff --git a/packages/api/src/routes/auth/organizations/activateOrganizationMembership.ts b/packages/api/src/routes/auth/organizations/activateOrganizationMembership.ts index c72ad7ce..a7a9673f 100644 --- a/packages/api/src/routes/auth/organizations/activateOrganizationMembership.ts +++ b/packages/api/src/routes/auth/organizations/activateOrganizationMembership.ts @@ -1,6 +1,6 @@ import { activateOrganizationMembershipRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -9,7 +9,7 @@ import { updateOne } from "../../../utilities/sql/updateOne.js" export const activateOrganizationMembershipRoute = apiFactory .createApp() .post(activateOrganizationMembershipRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/organizations/addNewOrganization.ts b/packages/api/src/routes/auth/organizations/addNewOrganization.ts index d31f851c..68779247 100644 --- a/packages/api/src/routes/auth/organizations/addNewOrganization.ts +++ b/packages/api/src/routes/auth/organizations/addNewOrganization.ts @@ -1,5 +1,5 @@ import { addNewOrganizationRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -8,7 +8,7 @@ import { insertOne } from "../../../utilities/sql/insertOne.js" export const addNewOrganizationRoute = apiFactory .createApp() .post(addNewOrganizationRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/organizations/getAllMyOrganizations.ts b/packages/api/src/routes/auth/organizations/getAllMyOrganizations.ts index d50ad9d5..040c302e 100644 --- a/packages/api/src/routes/auth/organizations/getAllMyOrganizations.ts +++ b/packages/api/src/routes/auth/organizations/getAllMyOrganizations.ts @@ -1,6 +1,6 @@ import { getAllMyOrganizationsRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -8,7 +8,7 @@ import { response } from "../../../utilities/response.js" export const getAllMyOrganizationsRoute = apiFactory .createApp() .post(getAllMyOrganizationsRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const _body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/organizations/organizationsRoutes.ts b/packages/api/src/routes/auth/organizations/organizationsRoutes.ts index 52d8f3b8..1d1784e9 100644 --- a/packages/api/src/routes/auth/organizations/organizationsRoutes.ts +++ b/packages/api/src/routes/auth/organizations/organizationsRoutes.ts @@ -1,7 +1,7 @@ -import { $idOrganizationRoutes } from "../../../routes/auth/$idOrganization/$idOrganizationRoutes.js" -import { activateOrganizationMembershipRoute } from "../../../routes/auth/organizations/activateOrganizationMembership.js" -import { addNewOrganizationRoute } from "../../../routes/auth/organizations/addNewOrganization.js" -import { getAllMyOrganizationsRoute } from "../../../routes/auth/organizations/getAllMyOrganizations.js" +import { $idOrganizationRoutes } from "./$idOrganization/$idOrganizationRoutes.js" +import { activateOrganizationMembershipRoute } from "./activateOrganizationMembership.js" +import { addNewOrganizationRoute } from "./addNewOrganization.js" +import { getAllMyOrganizationsRoute } from "./getAllMyOrganizations.js" export const organizationsRoutes = [ activateOrganizationMembershipRoute, diff --git a/packages/api/src/routes/auth/settings/activateUser.ts b/packages/api/src/routes/auth/settings/activateUser.ts index 7ff47716..8e260577 100644 --- a/packages/api/src/routes/auth/settings/activateUser.ts +++ b/packages/api/src/routes/auth/settings/activateUser.ts @@ -1,14 +1,14 @@ import { activateUserRouteDefinition, models } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" import { Exception } from "../../../utilities/exception.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { updateOne } from "../../../utilities/sql/updateOne.js" -export const activateUserRoute = apiFactory.createApp().post(activateUserRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const activateUserRoute = registerRoute(activateUserRouteDefinition, async (c) => { + const { user } = await requireCookieSessionMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/settings/deleteUser.ts b/packages/api/src/routes/auth/settings/deleteUser.ts index 04499443..734b92a3 100644 --- a/packages/api/src/routes/auth/settings/deleteUser.ts +++ b/packages/api/src/routes/auth/settings/deleteUser.ts @@ -1,16 +1,16 @@ import { pbkdf2Sync } from "node:crypto" import { deleteUserRouteDefinition, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" import { Exception } from "../../../utilities/exception.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { deleteOne } from "../../../utilities/sql/deleteOne.js" import { selectMany } from "../../../utilities/sql/selectMany.js" -export const deleteUserRoute = apiFactory.createApp().post(deleteUserRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const deleteUserRoute = registerRoute(deleteUserRouteDefinition, async (c) => { + const { user } = await requireCookieSessionMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/settings/readUserSession.ts b/packages/api/src/routes/auth/settings/readUserSession.ts index 02b38a24..307781fc 100644 --- a/packages/api/src/routes/auth/settings/readUserSession.ts +++ b/packages/api/src/routes/auth/settings/readUserSession.ts @@ -1,10 +1,10 @@ import { readUserSessionRouteDefinition } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" -export const readUserSessionRoute = apiFactory.createApp().post(readUserSessionRouteDefinition.path, async (c) => { - const { user, userSession } = await checkUserSessionMiddleware({ +export const readUserSessionRoute = registerRoute(readUserSessionRouteDefinition, async (c) => { + const { user, userSession } = await requireCookieSessionMiddleware({ context: c, }) diff --git a/packages/api/src/routes/auth/settings/resendEmailValidation.ts b/packages/api/src/routes/auth/settings/resendEmailValidation.ts index 3bd3112a..e4fe4d53 100644 --- a/packages/api/src/routes/auth/settings/resendEmailValidation.ts +++ b/packages/api/src/routes/auth/settings/resendEmailValidation.ts @@ -1,6 +1,6 @@ import { models, resendEmailValidationRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { sendEmail } from "../../../utilities/email/sendEmail.js" import { emailValidationTemplate } from "../../../utilities/email/templates/emailValidation.js" @@ -12,7 +12,7 @@ import { updateOne } from "../../../utilities/sql/updateOne.js" export const resendEmailValidationRoute = apiFactory .createApp() .post(resendEmailValidationRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await requireCookieSessionMiddleware({ context: c, }) diff --git a/packages/api/src/routes/auth/settings/settingsRoutes.ts b/packages/api/src/routes/auth/settings/settingsRoutes.ts index 56b3335c..53a22b74 100644 --- a/packages/api/src/routes/auth/settings/settingsRoutes.ts +++ b/packages/api/src/routes/auth/settings/settingsRoutes.ts @@ -1,11 +1,11 @@ -import { activateUserRoute } from "../../../routes/auth/settings/activateUser.js" -import { deleteUserRoute } from "../../../routes/auth/settings/deleteUser.js" -import { readUserSessionRoute } from "../../../routes/auth/settings/readUserSession.js" -import { resendEmailValidationRoute } from "../../../routes/auth/settings/resendEmailValidation.js" -import { updateUserRoute } from "../../../routes/auth/settings/updateUser.js" -import { updateUserEmailRoute } from "../../../routes/auth/settings/updateUserEmail.js" -import { updateUserPasswordRoute } from "../../../routes/auth/settings/updateUserPassword.js" -import { validateUserEmailRoute } from "../../../routes/auth/settings/validateUserEmail.js" +import { activateUserRoute } from "./activateUser.js" +import { deleteUserRoute } from "./deleteUser.js" +import { readUserSessionRoute } from "./readUserSession.js" +import { resendEmailValidationRoute } from "./resendEmailValidation.js" +import { updateUserRoute } from "./updateUser.js" +import { updateUserEmailRoute } from "./updateUserEmail.js" +import { updateUserPasswordRoute } from "./updateUserPassword.js" +import { validateUserEmailRoute } from "./validateUserEmail.js" export const settingsRoutes = [ activateUserRoute, diff --git a/packages/api/src/routes/auth/settings/updateUser.ts b/packages/api/src/routes/auth/settings/updateUser.ts index 62d44369..0329124d 100644 --- a/packages/api/src/routes/auth/settings/updateUser.ts +++ b/packages/api/src/routes/auth/settings/updateUser.ts @@ -1,13 +1,13 @@ import { models, updateUserRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { updateOne } from "../../../utilities/sql/updateOne.js" -export const updateUserRoute = apiFactory.createApp().post(updateUserRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const updateUserRoute = registerRoute(updateUserRouteDefinition, async (c) => { + const { user } = await requireCookieSessionMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/settings/updateUserEmail.ts b/packages/api/src/routes/auth/settings/updateUserEmail.ts index b0fa9f48..316e2283 100644 --- a/packages/api/src/routes/auth/settings/updateUserEmail.ts +++ b/packages/api/src/routes/auth/settings/updateUserEmail.ts @@ -1,18 +1,18 @@ import { pbkdf2Sync } from "node:crypto" import { models, updateUserEmailRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" import { sendEmail } from "../../../utilities/email/sendEmail.js" import { emailValidationTemplate } from "../../../utilities/email/templates/emailValidation.js" import { Exception } from "../../../utilities/exception.js" import { generateVerificationToken } from "../../../utilities/generateVerificationToken.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { updateOne } from "../../../utilities/sql/updateOne.js" -export const updateUserEmailRoute = apiFactory.createApp().post(updateUserEmailRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const updateUserEmailRoute = registerRoute(updateUserEmailRouteDefinition, async (c) => { + const { user } = await requireCookieSessionMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/settings/updateUserPassword.ts b/packages/api/src/routes/auth/settings/updateUserPassword.ts index 55867b28..ba261755 100644 --- a/packages/api/src/routes/auth/settings/updateUserPassword.ts +++ b/packages/api/src/routes/auth/settings/updateUserPassword.ts @@ -1,7 +1,7 @@ import { pbkdf2Sync } from "node:crypto" import { models, updateUserPasswordRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { Exception } from "../../../utilities/exception.js" @@ -11,7 +11,7 @@ import { updateOne } from "../../../utilities/sql/updateOne.js" export const updateUserPasswordRoute = apiFactory .createApp() .post(updateUserPasswordRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await requireCookieSessionMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/settings/validateUserEmail.ts b/packages/api/src/routes/auth/settings/validateUserEmail.ts index 4f962891..05df5732 100644 --- a/packages/api/src/routes/auth/settings/validateUserEmail.ts +++ b/packages/api/src/routes/auth/settings/validateUserEmail.ts @@ -1,14 +1,14 @@ import { models, validateUserEmailRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { requireCookieSessionMiddleware } from "../../../middlewares/requireCookieSessionMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" import { Exception } from "../../../utilities/exception.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { updateOne } from "../../../utilities/sql/updateOne.js" -export const validateUserEmailRoute = apiFactory.createApp().post(validateUserEmailRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const validateUserEmailRoute = registerRoute(validateUserEmailRouteDefinition, async (c) => { + const { user } = await requireCookieSessionMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/createOneTicket.ts b/packages/api/src/routes/auth/support/createOneTicket.ts index e6c15314..1e31ab67 100644 --- a/packages/api/src/routes/auth/support/createOneTicket.ts +++ b/packages/api/src/routes/auth/support/createOneTicket.ts @@ -1,14 +1,14 @@ import { createOneTicketRouteDefinition, generateId, models } from "@arrhes/application-metadata" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" import { sendEmail } from "../../../utilities/email/sendEmail.js" import { supportTemplate } from "../../../utilities/email/templates/support.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { insertOne } from "../../../utilities/sql/insertOne.js" -export const createOneTicketRoute = apiFactory.createApp().post(createOneTicketRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const createOneTicketRoute = registerRoute(createOneTicketRouteDefinition, async (c) => { + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/createOneTicketMessage.ts b/packages/api/src/routes/auth/support/createOneTicketMessage.ts index b270490b..f9889a7d 100644 --- a/packages/api/src/routes/auth/support/createOneTicketMessage.ts +++ b/packages/api/src/routes/auth/support/createOneTicketMessage.ts @@ -1,6 +1,6 @@ import { createOneTicketMessageRouteDefinition, generateId, models } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -11,7 +11,7 @@ import { updateOne } from "../../../utilities/sql/updateOne.js" export const createOneTicketMessageRoute = apiFactory .createApp() .post(createOneTicketMessageRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/readAllTicketMessages.ts b/packages/api/src/routes/auth/support/readAllTicketMessages.ts index e5c12b7f..9c25b3af 100644 --- a/packages/api/src/routes/auth/support/readAllTicketMessages.ts +++ b/packages/api/src/routes/auth/support/readAllTicketMessages.ts @@ -1,6 +1,6 @@ import { models, readAllTicketMessagesRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -10,7 +10,7 @@ import { selectOne } from "../../../utilities/sql/selectOne.js" export const readAllTicketMessagesRoute = apiFactory .createApp() .post(readAllTicketMessagesRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/readAllTickets.ts b/packages/api/src/routes/auth/support/readAllTickets.ts index bb4ccd77..028dc0ce 100644 --- a/packages/api/src/routes/auth/support/readAllTickets.ts +++ b/packages/api/src/routes/auth/support/readAllTickets.ts @@ -1,13 +1,13 @@ import { models, readAllTicketsRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { selectMany } from "../../../utilities/sql/selectMany.js" -export const readAllTicketsRoute = apiFactory.createApp().post(readAllTicketsRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const readAllTicketsRoute = registerRoute(readAllTicketsRouteDefinition, async (c) => { + const { user } = await checkAuthMiddleware({ context: c, }) await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/readOneTicket.ts b/packages/api/src/routes/auth/support/readOneTicket.ts index ea77515b..6589ae86 100644 --- a/packages/api/src/routes/auth/support/readOneTicket.ts +++ b/packages/api/src/routes/auth/support/readOneTicket.ts @@ -1,13 +1,13 @@ import { models, readOneTicketRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { selectOne } from "../../../utilities/sql/selectOne.js" -export const readOneTicketRoute = apiFactory.createApp().post(readOneTicketRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const readOneTicketRoute = registerRoute(readOneTicketRouteDefinition, async (c) => { + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/updateOneTicket.ts b/packages/api/src/routes/auth/support/updateOneTicket.ts index 7df31e32..b11a6c2b 100644 --- a/packages/api/src/routes/auth/support/updateOneTicket.ts +++ b/packages/api/src/routes/auth/support/updateOneTicket.ts @@ -1,14 +1,14 @@ import { models, updateOneTicketRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../../utilities/apiFactory.js" +import { registerRoute } from "../../../utilities/registerRoute.js" import { response } from "../../../utilities/response.js" import { selectOne } from "../../../utilities/sql/selectOne.js" import { updateOne } from "../../../utilities/sql/updateOne.js" -export const updateOneTicketRoute = apiFactory.createApp().post(updateOneTicketRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ +export const updateOneTicketRoute = registerRoute(updateOneTicketRouteDefinition, async (c) => { + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/auth/support/updateOneTicketStatus.ts b/packages/api/src/routes/auth/support/updateOneTicketStatus.ts index d604152b..b4e40a72 100644 --- a/packages/api/src/routes/auth/support/updateOneTicketStatus.ts +++ b/packages/api/src/routes/auth/support/updateOneTicketStatus.ts @@ -1,6 +1,6 @@ import { models, updateOneTicketStatusRouteDefinition } from "@arrhes/application-metadata" import { and, eq } from "drizzle-orm" -import { checkUserSessionMiddleware } from "../../../middlewares/checkUserSessionMiddleware.js" +import { checkAuthMiddleware } from "../../../middlewares/checkAuthMiddleware.js" import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" import { apiFactory } from "../../../utilities/apiFactory.js" import { response } from "../../../utilities/response.js" @@ -10,7 +10,7 @@ import { updateOne } from "../../../utilities/sql/updateOne.js" export const updateOneTicketStatusRoute = apiFactory .createApp() .post(updateOneTicketStatusRouteDefinition.path, async (c) => { - const { user } = await checkUserSessionMiddleware({ + const { user } = await checkAuthMiddleware({ context: c, }) const body = await validateBodyMiddleware({ diff --git a/packages/api/src/routes/public/mollieWebhook.ts b/packages/api/src/routes/public/mollieWebhook.ts index 7d0f0d95..b950c958 100644 --- a/packages/api/src/routes/public/mollieWebhook.ts +++ b/packages/api/src/routes/public/mollieWebhook.ts @@ -1,12 +1,12 @@ import { models, mollieWebhookRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { apiFactory } from "../../utilities/apiFactory.js" import { apiLog } from "../../utilities/apiLog.js" +import { registerRoute } from "../../utilities/registerRoute.js" import { response } from "../../utilities/response.js" import { updateOne } from "../../utilities/sql/updateOne.js" import { validate } from "../../utilities/validate.js" -export const mollieWebhookRoute = apiFactory.createApp().post(mollieWebhookRouteDefinition.path, async (c) => { +export const mollieWebhookRoute = registerRoute(mollieWebhookRouteDefinition, async (c) => { try { // Mollie sends webhooks as application/x-www-form-urlencoded (body: id=tr_xxx) const rawBody = await c.req.parseBody() diff --git a/packages/api/src/routes/public/publicRoute.ts b/packages/api/src/routes/public/publicRoute.ts index f0c3d9e3..90a4f1fd 100644 --- a/packages/api/src/routes/public/publicRoute.ts +++ b/packages/api/src/routes/public/publicRoute.ts @@ -1,10 +1,10 @@ -import { mollieWebhookRoute } from "../../routes/public/mollieWebhook.js" -import { resetPasswordRoute } from "../../routes/public/resetPassword.js" -import { sendMagicLinkRoute } from "../../routes/public/sendMagicLink.js" -import { signInRoute } from "../../routes/public/signIn.js" -import { signOutRoute } from "../../routes/public/signOut.js" -import { signUpRoute } from "../../routes/public/signUp.js" import { apiFactory } from "../../utilities/apiFactory.js" +import { mollieWebhookRoute } from "./mollieWebhook.js" +import { resetPasswordRoute } from "./user/resetPassword.js" +import { sendMagicLinkRoute } from "./user/sendMagicLink.js" +import { signInRoute } from "./user/signIn.js" +import { signOutRoute } from "./user/signOut.js" +import { signUpRoute } from "./user/signUp.js" export const publicRoute = apiFactory .createApp() diff --git a/packages/api/src/routes/public/resetPassword.ts b/packages/api/src/routes/public/user/resetPassword.ts similarity index 71% rename from packages/api/src/routes/public/resetPassword.ts rename to packages/api/src/routes/public/user/resetPassword.ts index 4a44af5d..7ca64913 100644 --- a/packages/api/src/routes/public/resetPassword.ts +++ b/packages/api/src/routes/public/user/resetPassword.ts @@ -1,19 +1,19 @@ import { pbkdf2Sync, randomBytes } from "node:crypto" import { models, resetPasswordRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { validateBodyMiddleware } from "../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../utilities/apiFactory.js" -import { sendEmail } from "../../utilities/email/sendEmail.js" -import { resetPasswordTemplate } from "../../utilities/email/templates/resetPassword.js" -import { response } from "../../utilities/response.js" -import { selectOne } from "../../utilities/sql/selectOne.js" -import { updateOne } from "../../utilities/sql/updateOne.js" +import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" +import { sendEmail } from "../../../utilities/email/sendEmail.js" +import { resetPasswordTemplate } from "../../../utilities/email/templates/resetPassword.js" +import { registerRoute } from "../../../utilities/registerRoute.js" +import { response } from "../../../utilities/response.js" +import { selectOne } from "../../../utilities/sql/selectOne.js" +import { updateOne } from "../../../utilities/sql/updateOne.js" function generateTemporaryPassword() { return randomBytes(12).toString("base64url") } -export const resetPasswordRoute = apiFactory.createApp().post(resetPasswordRouteDefinition.path, async (c) => { +export const resetPasswordRoute = registerRoute(resetPasswordRouteDefinition, async (c) => { const body = await validateBodyMiddleware({ context: c, schema: resetPasswordRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/public/sendMagicLink.ts b/packages/api/src/routes/public/user/sendMagicLink.ts similarity index 61% rename from packages/api/src/routes/public/sendMagicLink.ts rename to packages/api/src/routes/public/user/sendMagicLink.ts index 0e09f00d..6fb74084 100644 --- a/packages/api/src/routes/public/sendMagicLink.ts +++ b/packages/api/src/routes/public/user/sendMagicLink.ts @@ -1,11 +1,11 @@ import { models, sendMagicLinkRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { validateBodyMiddleware } from "../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../utilities/apiFactory.js" -import { response } from "../../utilities/response.js" -import { selectOne } from "../../utilities/sql/selectOne.js" +import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" +import { registerRoute } from "../../../utilities/registerRoute.js" +import { response } from "../../../utilities/response.js" +import { selectOne } from "../../../utilities/sql/selectOne.js" -export const sendMagicLinkRoute = apiFactory.createApp().post(sendMagicLinkRouteDefinition.path, async (c) => { +export const sendMagicLinkRoute = registerRoute(sendMagicLinkRouteDefinition, async (c) => { const body = await validateBodyMiddleware({ context: c, schema: sendMagicLinkRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/public/signIn.ts b/packages/api/src/routes/public/user/signIn.ts similarity index 76% rename from packages/api/src/routes/public/signIn.ts rename to packages/api/src/routes/public/user/signIn.ts index 0e403f03..a403191f 100644 --- a/packages/api/src/routes/public/signIn.ts +++ b/packages/api/src/routes/public/user/signIn.ts @@ -1,19 +1,19 @@ import { pbkdf2Sync } from "node:crypto" import { generateId, models, signInRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { validateBodyMiddleware } from "../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../utilities/apiFactory.js" -import { getCookieDomainFromHost } from "../../utilities/cookies/getCookieDomainFromHost.js" -import { serializeCookie } from "../../utilities/cookies/serializeCookie.js" -import { signString } from "../../utilities/cookies/signString.js" -import { Exception } from "../../utilities/exception.js" -import { getRemoteAddress } from "../../utilities/getRemoteAddress.js" -import { response } from "../../utilities/response.js" -import { insertOne } from "../../utilities/sql/insertOne.js" -import { selectOne } from "../../utilities/sql/selectOne.js" -import { getCookieSecurityOptions, productName, userSessionCookieMaxAge } from "../../utilities/variables.js" +import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" +import { getCookieDomainFromHost } from "../../../utilities/cookies/getCookieDomainFromHost.js" +import { serializeCookie } from "../../../utilities/cookies/serializeCookie.js" +import { signString } from "../../../utilities/cookies/signString.js" +import { Exception } from "../../../utilities/exception.js" +import { getRemoteAddress } from "../../../utilities/getRemoteAddress.js" +import { registerRoute } from "../../../utilities/registerRoute.js" +import { response } from "../../../utilities/response.js" +import { insertOne } from "../../../utilities/sql/insertOne.js" +import { selectOne } from "../../../utilities/sql/selectOne.js" +import { getCookieSecurityOptions, productName, userSessionCookieMaxAge } from "../../../utilities/variables.js" -export const signInRoute = apiFactory.createApp().post(signInRouteDefinition.path, async (c) => { +export const signInRoute = registerRoute(signInRouteDefinition, async (c) => { const body = await validateBodyMiddleware({ context: c, schema: signInRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/public/signOut.ts b/packages/api/src/routes/public/user/signOut.ts similarity index 72% rename from packages/api/src/routes/public/signOut.ts rename to packages/api/src/routes/public/user/signOut.ts index b9e62188..405b76c3 100644 --- a/packages/api/src/routes/public/signOut.ts +++ b/packages/api/src/routes/public/user/signOut.ts @@ -1,17 +1,17 @@ import { models, signOutRouteDefinition } from "@arrhes/application-metadata" import { eq } from "drizzle-orm" -import { validateBodyMiddleware } from "../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../utilities/apiFactory.js" -import { getCookieDomainFromHost } from "../../utilities/cookies/getCookieDomainFromHost.js" -import { parseCookies } from "../../utilities/cookies/parseCookies.js" -import { serializeCookie } from "../../utilities/cookies/serializeCookie.js" -import { unsignString } from "../../utilities/cookies/unsignString.js" -import { Exception } from "../../utilities/exception.js" -import { response } from "../../utilities/response.js" -import { updateOne } from "../../utilities/sql/updateOne.js" -import { getCookieSecurityOptions, productName } from "../../utilities/variables.js" +import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" +import { getCookieDomainFromHost } from "../../../utilities/cookies/getCookieDomainFromHost.js" +import { parseCookies } from "../../../utilities/cookies/parseCookies.js" +import { serializeCookie } from "../../../utilities/cookies/serializeCookie.js" +import { unsignString } from "../../../utilities/cookies/unsignString.js" +import { Exception } from "../../../utilities/exception.js" +import { registerRoute } from "../../../utilities/registerRoute.js" +import { response } from "../../../utilities/response.js" +import { updateOne } from "../../../utilities/sql/updateOne.js" +import { getCookieSecurityOptions, productName } from "../../../utilities/variables.js" -export const signOutRoute = apiFactory.createApp().post(signOutRouteDefinition.path, async (c) => { +export const signOutRoute = registerRoute(signOutRouteDefinition, async (c) => { const _body = await validateBodyMiddleware({ context: c, schema: signOutRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/public/signUp.ts b/packages/api/src/routes/public/user/signUp.ts similarity index 80% rename from packages/api/src/routes/public/signUp.ts rename to packages/api/src/routes/public/user/signUp.ts index 225f351a..77d0008e 100644 --- a/packages/api/src/routes/public/signUp.ts +++ b/packages/api/src/routes/public/user/signUp.ts @@ -1,18 +1,18 @@ import { pbkdf2Sync } from "node:crypto" import { generateId, models, signUpRouteDefinition } from "@arrhes/application-metadata" -import { validateBodyMiddleware } from "../../middlewares/validateBody.middleware.js" -import { apiFactory } from "../../utilities/apiFactory.js" -import { getCookieDomainFromHost } from "../../utilities/cookies/getCookieDomainFromHost.js" -import { serializeCookie } from "../../utilities/cookies/serializeCookie.js" -import { signString } from "../../utilities/cookies/signString.js" -import { Exception } from "../../utilities/exception.js" -import { generateVerificationToken } from "../../utilities/generateVerificationToken.js" -import { getRemoteAddress } from "../../utilities/getRemoteAddress.js" -import { response } from "../../utilities/response.js" -import { insertOne } from "../../utilities/sql/insertOne.js" -import { getCookieSecurityOptions, productName, userSessionCookieMaxAge } from "../../utilities/variables.js" +import { validateBodyMiddleware } from "../../../middlewares/validateBody.middleware.js" +import { getCookieDomainFromHost } from "../../../utilities/cookies/getCookieDomainFromHost.js" +import { serializeCookie } from "../../../utilities/cookies/serializeCookie.js" +import { signString } from "../../../utilities/cookies/signString.js" +import { Exception } from "../../../utilities/exception.js" +import { generateVerificationToken } from "../../../utilities/generateVerificationToken.js" +import { getRemoteAddress } from "../../../utilities/getRemoteAddress.js" +import { registerRoute } from "../../../utilities/registerRoute.js" +import { response } from "../../../utilities/response.js" +import { insertOne } from "../../../utilities/sql/insertOne.js" +import { getCookieSecurityOptions, productName, userSessionCookieMaxAge } from "../../../utilities/variables.js" -export const signUpRoute = apiFactory.createApp().post(signUpRouteDefinition.path, async (c) => { +export const signUpRoute = registerRoute(signUpRouteDefinition, async (c) => { const body = await validateBodyMiddleware({ context: c, schema: signUpRouteDefinition.schemas.body, diff --git a/packages/api/src/routes/routes.ts b/packages/api/src/routes/routes.ts index befa44dc..891042d3 100644 --- a/packages/api/src/routes/routes.ts +++ b/packages/api/src/routes/routes.ts @@ -1,6 +1,6 @@ -import { authRoute } from "../routes/auth/authRoute.js" -import { internalRoute } from "../routes/internal/internalRoute.js" -import { publicRoute } from "../routes/public/publicRoute.js" import { apiFactory } from "../utilities/apiFactory.js" +import { authRoute } from "./auth/authRoute.js" +import { internalRoute } from "./internal/internalRoute.js" +import { publicRoute } from "./public/publicRoute.js" export const routes = apiFactory.createApp().route("/", authRoute).route("/", publicRoute).route("/", internalRoute) diff --git a/packages/api/src/utilities/cookies/parseCookies.ts b/packages/api/src/utilities/cookies/parseCookies.ts index 396440af..f1133e6e 100644 --- a/packages/api/src/utilities/cookies/parseCookies.ts +++ b/packages/api/src/utilities/cookies/parseCookies.ts @@ -1,4 +1,4 @@ -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export function parseCookies(parameters: { value: string | undefined }) { try { diff --git a/packages/api/src/utilities/cookies/signString.ts b/packages/api/src/utilities/cookies/signString.ts index 7e2d36de..b55df26d 100644 --- a/packages/api/src/utilities/cookies/signString.ts +++ b/packages/api/src/utilities/cookies/signString.ts @@ -1,5 +1,5 @@ import { createHmac } from "node:crypto" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export function signString(parameters: { value: string; secret: string }) { try { diff --git a/packages/api/src/utilities/cookies/unsignString.ts b/packages/api/src/utilities/cookies/unsignString.ts index bef499f7..253bb54c 100644 --- a/packages/api/src/utilities/cookies/unsignString.ts +++ b/packages/api/src/utilities/cookies/unsignString.ts @@ -1,6 +1,6 @@ import { timingSafeEqual } from "node:crypto" -import { signString } from "../../utilities/cookies/signString.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" +import { signString } from "./signString.js" export function unsignString(parameters: { signedValue: string | undefined; secret: string }) { try { diff --git a/packages/api/src/utilities/getEnv.ts b/packages/api/src/utilities/getEnv.ts index 0ce0b92a..88582131 100644 --- a/packages/api/src/utilities/getEnv.ts +++ b/packages/api/src/utilities/getEnv.ts @@ -1,5 +1,5 @@ import * as v from "valibot" -import { validate } from "../utilities/validate.js" +import { validate } from "./validate.js" enum Env { development = "development", diff --git a/packages/api/src/utilities/registerRoute.ts b/packages/api/src/utilities/registerRoute.ts new file mode 100644 index 00000000..f32da35d --- /dev/null +++ b/packages/api/src/utilities/registerRoute.ts @@ -0,0 +1,22 @@ +import type { Handler } from "hono" +import { type ApiEnv, apiFactory } from "./apiFactory.js" + +type RouteDefinitionRef = { + method: "GET" | "POST" | "PATCH" | "DELETE" + path: string +} + +/** + * Creates a Hono app with a single route registered using the HTTP method + * and path from the routeDefinition. Use this in handler files instead of + * `apiFactory.createApp().post(...)` so routes respect their declared method. + */ +export function registerRoute( + routeDef: RouteDefinitionRef, + handler: Handler, +): ReturnType { + const app = apiFactory.createApp() + const method = routeDef.method.toLowerCase() as "get" | "post" | "patch" | "delete" + app[method](routeDef.path, handler) + return app +} diff --git a/packages/api/src/utilities/response.ts b/packages/api/src/utilities/response.ts index 2a00d46e..e826eb1e 100644 --- a/packages/api/src/utilities/response.ts +++ b/packages/api/src/utilities/response.ts @@ -2,8 +2,8 @@ import type { routeDefinition } from "@arrhes/application-metadata" import type { Context } from "hono" import type { ContentfulStatusCode } from "hono/utils/http-status" import type * as v from "valibot" -import type { ApiEnv } from "../utilities/apiFactory.js" -import { validate } from "../utilities/validate.js" +import type { ApiEnv } from "./apiFactory.js" +import { validate } from "./validate.js" type GContext = Context diff --git a/packages/api/src/utilities/safeParseJSON.ts b/packages/api/src/utilities/safeParseJSON.ts index c2a1d9c9..0f373c75 100644 --- a/packages/api/src/utilities/safeParseJSON.ts +++ b/packages/api/src/utilities/safeParseJSON.ts @@ -1,5 +1,5 @@ -import { completeStringifiedJSON } from "../utilities/completeStringifiedJSON.js" -import { Exception } from "../utilities/exception.js" +import { completeStringifiedJSON } from "./completeStringifiedJSON.js" +import { Exception } from "./exception.js" export function safeParseJSON(parameters: { rawString: string }) { try { diff --git a/packages/api/src/utilities/sql/deleteMany.ts b/packages/api/src/utilities/sql/deleteMany.ts index afd6b855..043c1daf 100644 --- a/packages/api/src/utilities/sql/deleteMany.ts +++ b/packages/api/src/utilities/sql/deleteMany.ts @@ -1,7 +1,7 @@ import type { SQL, TableConfig } from "drizzle-orm" import type { PgTable } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export async function deleteMany>(parameters: { database: ReturnType | Parameters["transaction"]>[0]>[0] diff --git a/packages/api/src/utilities/sql/deleteOne.ts b/packages/api/src/utilities/sql/deleteOne.ts index d08ad461..6f345a39 100644 --- a/packages/api/src/utilities/sql/deleteOne.ts +++ b/packages/api/src/utilities/sql/deleteOne.ts @@ -1,7 +1,7 @@ import type { SQL, TableConfig } from "drizzle-orm" import type { PgTable } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export async function deleteOne>(parameters: { database: ReturnType | Parameters["transaction"]>[0]>[0] diff --git a/packages/api/src/utilities/sql/insertMany.ts b/packages/api/src/utilities/sql/insertMany.ts index db5dae4c..7d779200 100644 --- a/packages/api/src/utilities/sql/insertMany.ts +++ b/packages/api/src/utilities/sql/insertMany.ts @@ -1,6 +1,6 @@ import type { PgInsertValue, PgTable, TableConfig } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" // : Promise> diff --git a/packages/api/src/utilities/sql/insertOne.ts b/packages/api/src/utilities/sql/insertOne.ts index 08e50372..fec6d46c 100644 --- a/packages/api/src/utilities/sql/insertOne.ts +++ b/packages/api/src/utilities/sql/insertOne.ts @@ -1,7 +1,7 @@ import type { TableConfig } from "drizzle-orm" import type { PgInsertValue, PgTable } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export async function insertOne>(parameters: { database: ReturnType | Parameters["transaction"]>[0]>[0] diff --git a/packages/api/src/utilities/sql/selectMany.ts b/packages/api/src/utilities/sql/selectMany.ts index 497448fb..62caf660 100644 --- a/packages/api/src/utilities/sql/selectMany.ts +++ b/packages/api/src/utilities/sql/selectMany.ts @@ -1,7 +1,7 @@ import type { SQL, TableConfig } from "drizzle-orm" import type { PgTable } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export async function selectMany>(parameters: { database: ReturnType | Parameters["transaction"]>[0]>[0] diff --git a/packages/api/src/utilities/sql/selectOne.ts b/packages/api/src/utilities/sql/selectOne.ts index fa9dae5d..37ffc8a3 100644 --- a/packages/api/src/utilities/sql/selectOne.ts +++ b/packages/api/src/utilities/sql/selectOne.ts @@ -1,7 +1,7 @@ import type { SQL, TableConfig } from "drizzle-orm" import type { PgTable } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export async function selectOne>(parameters: { database: ReturnType | Parameters["transaction"]>[0]>[0] diff --git a/packages/api/src/utilities/sql/updateOne.ts b/packages/api/src/utilities/sql/updateOne.ts index b89ccd97..2238e095 100644 --- a/packages/api/src/utilities/sql/updateOne.ts +++ b/packages/api/src/utilities/sql/updateOne.ts @@ -1,7 +1,7 @@ import type { SQL, TableConfig } from "drizzle-orm" import type { PgTable, PgUpdateSetSource } from "drizzle-orm/pg-core" import type { sqlClient } from "../../clients/sqlClient.js" -import { Exception } from "../../utilities/exception.js" +import { Exception } from "../exception.js" export async function updateOne>(parameters: { database: ReturnType | Parameters["transaction"]>[0]>[0] diff --git a/packages/api/src/utilities/storage/deleteObject.ts b/packages/api/src/utilities/storage/deleteObject.ts index c60184e9..1c4c0da3 100644 --- a/packages/api/src/utilities/storage/deleteObject.ts +++ b/packages/api/src/utilities/storage/deleteObject.ts @@ -1,7 +1,7 @@ import { DeleteObjectCommand } from "@aws-sdk/client-s3" -import { Exception } from "../../utilities/exception.js" -import type { getClients } from "../../utilities/getClients.js" -import type { getEnv } from "../../utilities/getEnv.js" +import { Exception } from "../exception.js" +import type { getClients } from "../getClients.js" +import type { getEnv } from "../getEnv.js" export async function deleteObject(parameters: { var: { diff --git a/packages/api/src/utilities/storage/generateDeleteSignedUrl.ts b/packages/api/src/utilities/storage/generateDeleteSignedUrl.ts index 843de839..52bc6e9d 100644 --- a/packages/api/src/utilities/storage/generateDeleteSignedUrl.ts +++ b/packages/api/src/utilities/storage/generateDeleteSignedUrl.ts @@ -1,8 +1,8 @@ import { DeleteObjectCommand } from "@aws-sdk/client-s3" import { getSignedUrl } from "@aws-sdk/s3-request-presigner" -import { Exception } from "../../utilities/exception.js" -import type { getClients } from "../../utilities/getClients.js" -import type { getEnv } from "../../utilities/getEnv.js" +import { Exception } from "../exception.js" +import type { getClients } from "../getClients.js" +import type { getEnv } from "../getEnv.js" export async function generateDeleteSignedUrl(parameters: { var: { diff --git a/packages/api/src/utilities/storage/generateGetSignedUrl.ts b/packages/api/src/utilities/storage/generateGetSignedUrl.ts index ff9f80c8..df4de615 100644 --- a/packages/api/src/utilities/storage/generateGetSignedUrl.ts +++ b/packages/api/src/utilities/storage/generateGetSignedUrl.ts @@ -1,9 +1,9 @@ import { GetObjectCommand } from "@aws-sdk/client-s3" import { getSignedUrl } from "@aws-sdk/s3-request-presigner" -import { Exception } from "../../utilities/exception.js" -import type { getClients } from "../../utilities/getClients.js" -import type { getEnv } from "../../utilities/getEnv.js" -import { storageFileExpiresIn } from "../../utilities/variables.js" +import { Exception } from "../exception.js" +import type { getClients } from "../getClients.js" +import type { getEnv } from "../getEnv.js" +import { storageFileExpiresIn } from "../variables.js" export async function generateGetSignedUrl(parameters: { var: { diff --git a/packages/api/src/utilities/storage/generatePutSignedUrl.ts b/packages/api/src/utilities/storage/generatePutSignedUrl.ts index b344ceb6..763a572c 100644 --- a/packages/api/src/utilities/storage/generatePutSignedUrl.ts +++ b/packages/api/src/utilities/storage/generatePutSignedUrl.ts @@ -1,8 +1,8 @@ import { PutObjectCommand } from "@aws-sdk/client-s3" import { getSignedUrl } from "@aws-sdk/s3-request-presigner" -import { Exception } from "../../utilities/exception.js" -import type { getClients } from "../../utilities/getClients.js" -import type { getEnv } from "../../utilities/getEnv.js" +import { Exception } from "../exception.js" +import type { getClients } from "../getClients.js" +import type { getEnv } from "../getEnv.js" export async function generatePutSignedUrl(parameters: { var: { diff --git a/packages/api/src/utilities/storage/getObject.ts b/packages/api/src/utilities/storage/getObject.ts index 23150194..d4f2667b 100644 --- a/packages/api/src/utilities/storage/getObject.ts +++ b/packages/api/src/utilities/storage/getObject.ts @@ -1,7 +1,7 @@ import { GetObjectCommand } from "@aws-sdk/client-s3" -import { Exception } from "../../utilities/exception.js" -import type { getClients } from "../../utilities/getClients.js" -import type { getEnv } from "../../utilities/getEnv.js" +import { Exception } from "../exception.js" +import type { getClients } from "../getClients.js" +import type { getEnv } from "../getEnv.js" export async function getObject(parameters: { var: { diff --git a/packages/api/src/utilities/storage/putObject.ts b/packages/api/src/utilities/storage/putObject.ts index 55f8e20c..6dd12f64 100644 --- a/packages/api/src/utilities/storage/putObject.ts +++ b/packages/api/src/utilities/storage/putObject.ts @@ -1,7 +1,7 @@ import { PutObjectCommand } from "@aws-sdk/client-s3" -import { Exception } from "../../utilities/exception.js" -import type { getClients } from "../../utilities/getClients.js" -import type { getEnv } from "../../utilities/getEnv.js" +import { Exception } from "../exception.js" +import type { getClients } from "../getClients.js" +import type { getEnv } from "../getEnv.js" export async function putObject(parameters: { var: { diff --git a/packages/api/src/utilities/validate.ts b/packages/api/src/utilities/validate.ts index 20edd85e..cb3333f8 100644 --- a/packages/api/src/utilities/validate.ts +++ b/packages/api/src/utilities/validate.ts @@ -1,5 +1,5 @@ import * as v from "valibot" -import { Exception } from "../utilities/exception.js" +import { Exception } from "./exception.js" export function validate>(parameters: { schema: T diff --git a/packages/cli/arrhes.sh b/packages/cli/arrhes.sh new file mode 100644 index 00000000..6ea62c04 --- /dev/null +++ b/packages/cli/arrhes.sh @@ -0,0 +1,1060 @@ +#!/bin/sh +# arrhes — Arrhes API CLI +# Requires: curl +# Config: ~/.arrhes/config (ARRHES_URL, ARRHES_API_KEY) +set -e + +VERSION="0.1.0" +DEFAULT_URL="https://api.arrhes.com" +CONFIG_FILE="${ARRHES_CONFIG:-${HOME}/.arrhes/config}" + +# ── Utilities ───────────────────────────────────────────────────────────────── + +_die() { printf 'arrhes: %s\n' "$*" >&2; exit 1; } +_need_cmd() { command -v "$1" >/dev/null 2>&1 || _die "'$1' is required but not found"; } +_jesc() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; } + +# JSON body accumulator +_JBODY='' +_jbody_reset() { _JBODY=''; } +_jbody_raw() { + [ -n "$_JBODY" ] && _JBODY="${_JBODY}," + _JBODY="${_JBODY}\"$1\":$2" +} +# _jstr: add "key":"value" — skip if value is empty +_jstr() { [ -n "$2" ] && _jbody_raw "$1" "\"$(_jesc "$2")\"" || true; } +# _jstr_null: add "key":"value" or "key":null +_jstr_null() { + if [ -n "$2" ]; then _jbody_raw "$1" "\"$(_jesc "$2")\""; else _jbody_raw "$1" "null"; fi +} +# _jnum: add "key":number — skip if value is empty +_jnum() { [ -n "$2" ] && _jbody_raw "$1" "$2" || true; } +# _jbool: add "key":true|false +_jbool() { _jbody_raw "$1" "$2"; } +# _jbody: emit the accumulated JSON object +_jbody() { printf '{%s}' "$_JBODY"; } + +# ── Config ──────────────────────────────────────────────────────────────────── + +_cfg_read() { + ARRHES_URL="$DEFAULT_URL" + ARRHES_API_KEY='' + [ -f "$CONFIG_FILE" ] && . "$CONFIG_FILE" +} + +_cfg_write() { + # $1=url $2=api_key + mkdir -p "$(dirname "$CONFIG_FILE")" + printf 'ARRHES_URL=%s\nARRHES_API_KEY=%s\n' "$1" "$2" > "$CONFIG_FILE" + chmod 600 "$CONFIG_FILE" +} + +_require_cfg() { + _cfg_read + [ -n "$ARRHES_API_KEY" ] || _die "Not logged in. Run: arrhes login --api-key " +} + +# ── HTTP ────────────────────────────────────────────────────────────────────── + +_RESP=$(mktemp) +trap 'rm -f "$_RESP"' EXIT INT TERM + +_api() { + # _api METHOD /path [json_body] + method="$1"; path="$2"; body="${3:-}" + url="${ARRHES_URL}${path}" + if [ -n "$body" ]; then + HTTP_CODE=$(curl -sS -o "$_RESP" -w "%{http_code}" \ + -X "$method" \ + -H "Authorization: Bearer ${ARRHES_API_KEY}" \ + -H "Content-Type: application/json" \ + -d "$body" "$url") + else + HTTP_CODE=$(curl -sS -o "$_RESP" -w "%{http_code}" \ + -X "$method" \ + -H "Authorization: Bearer ${ARRHES_API_KEY}" \ + "$url") + fi + case "$HTTP_CODE" in + 2??) cat "$_RESP" ;; + *) cat "$_RESP" >&2; exit 1 ;; + esac +} + +# The API key is scoped to an org; the server uses its own org ID from the key. +# 'me' is just a valid URL placeholder for :idOrganization. +_org_path() { printf '/v1/organizations/me'; } +_year_path() { printf '/v1/organizations/me/years/%s' "$1"; } + +# ── login / whoami / logout ─────────────────────────────────────────────────── + +_cmd_login() { + api_key=''; base_url='' + while [ $# -gt 0 ]; do + case "$1" in + --api-key) api_key="$2"; shift ;; + --url) base_url="$2"; shift ;; + *) _die "Unknown option: $1" ;; + esac; shift + done + [ -n "$api_key" ] || _die "--api-key is required" + base_url="${base_url:-$DEFAULT_URL}"; base_url="${base_url%/}" + ARRHES_URL="$base_url" ARRHES_API_KEY="$api_key" _api GET "/v1/users/me" > /dev/null + _cfg_write "$base_url" "$api_key" + printf 'Logged in. Config saved to %s\n' "$CONFIG_FILE" +} + +_cmd_whoami() { + _require_cfg + _api GET "/v1/users/me" +} + +_cmd_logout() { + _cfg_read + _cfg_write "${ARRHES_URL:-$DEFAULT_URL}" "" + printf 'Logged out.\n' +} + +# ── org ─────────────────────────────────────────────────────────────────────── + +_cmd_org() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + get) + _require_cfg; _api GET "$(_org_path)" + ;; + update) + _org_update "$@" + ;; + delete) + _require_cfg + _api DELETE "$(_org_path)" > /dev/null + printf 'Organization deleted.\n' + ;; + *) _die "arrhes org: unknown subcommand '$subcmd'. Use: get, update, delete" ;; + esac +} + +_org_update() { + name=''; email=''; siren='' + while [ $# -gt 0 ]; do + case "$1" in + --name) name="$2"; shift ;; + --email) email="$2"; shift ;; + --siren) siren="$2"; shift ;; + *) _die "Unknown option: $1" ;; + esac; shift + done + _require_cfg + _jbody_reset; _jstr name "$name"; _jstr email "$email"; _jstr siren "$siren" + _api PATCH "$(_org_path)" "$(_jbody)" +} + +# ── years ───────────────────────────────────────────────────────────────────── + +_cmd_years() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _require_cfg; _api GET "$(_org_path)/years" ;; + get) _years_get "$@" ;; + create) _years_create "$@" ;; + update) _years_update "$@" ;; + delete) _years_delete "$@" ;; + close) _years_close "$@" ;; + open) _years_open "$@" ;; + settle-balance-sheet) _years_settle_bs "$@" ;; + settle-income-statement) _years_settle_is "$@" ;; + *) _die "arrhes years: unknown subcommand '$subcmd'" ;; + esac +} + +_years_get() { + id="${1:?Usage: arrhes years get }" + _require_cfg; _api GET "$(_year_path "$id")" +} + +_years_create() { + start=''; end=''; label='' + while [ $# -gt 0 ]; do + case "$1" in --start) start="$2"; shift ;; --end) end="$2"; shift ;; --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$start" ] || _die "--start is required" + [ -n "$end" ] || _die "--end is required" + _require_cfg; _jbody_reset; _jstr startingAt "$start"; _jstr endingAt "$end"; _jstr label "$label" + _api POST "$(_org_path)/years" "$(_jbody)" +} + +_years_update() { + id="${1:?Usage: arrhes years update }"; shift + start=''; end=''; label='' + while [ $# -gt 0 ]; do + case "$1" in --start) start="$2"; shift ;; --end) end="$2"; shift ;; --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + _require_cfg; _jbody_reset; _jstr startingAt "$start"; _jstr endingAt "$end"; _jstr label "$label" + _api PATCH "$(_year_path "$id")" "$(_jbody)" +} + +_years_delete() { + id="${1:?Usage: arrhes years delete }" + _require_cfg; _api DELETE "$(_year_path "$id")" > /dev/null + printf 'Year %s deleted.\n' "$id" +} + +_years_close() { + id="${1:?Usage: arrhes years close }" + _require_cfg; _api POST "$(_year_path "$id")/close" +} + +_years_open() { + id="${1:?Usage: arrhes years open }"; shift + journal_opening='' + while [ $# -gt 0 ]; do + case "$1" in --journal-opening) journal_opening="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$journal_opening" ] || _die "--journal-opening is required" + _require_cfg; _jbody_reset; _jstr idJournalOpening "$journal_opening" + _api POST "$(_year_path "$id")/open" "$(_jbody)" +} + +_years_settle_bs() { + id="${1:?Usage: arrhes years settle-balance-sheet }"; shift + journal_closing='' + while [ $# -gt 0 ]; do + case "$1" in --journal-closing) journal_closing="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$journal_closing" ] || _die "--journal-closing is required" + _require_cfg; _jbody_reset; _jstr idJournalClosing "$journal_closing" + _api POST "$(_year_path "$id")/settle-balance-sheet" "$(_jbody)" +} + +_years_settle_is() { + id="${1:?Usage: arrhes years settle-income-statement }"; shift + journal_closing='' + while [ $# -gt 0 ]; do + case "$1" in --journal-closing) journal_closing="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$journal_closing" ] || _die "--journal-closing is required" + _require_cfg; _jbody_reset; _jstr idJournalClosing "$journal_closing" + _api POST "$(_year_path "$id")/settle-income-statement" "$(_jbody)" +} + +# ── journals ────────────────────────────────────────────────────────────────── + +_cmd_journals() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _journals_list "$@" ;; get) _journals_get "$@" ;; + create) _journals_create "$@" ;; update) _journals_update "$@" ;; + delete) _journals_delete "$@" ;; + *) _die "arrhes journals: unknown subcommand '$subcmd'" ;; + esac +} + +_journals_base() { printf '%s/journals' "$(_year_path "$1")"; } + +_journals_list() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api GET "$(_journals_base "$year")" +} + +_journals_get() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes journals get --year " + _require_cfg; _api GET "$(_journals_base "$year")/$id" +} + +_journals_create() { + year=''; code=''; label='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; --code) code="$2"; shift ;; --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$year" ] && [ -n "$code" ] && [ -n "$label" ] || _die "--year, --code, and --label are required" + _require_cfg; _jbody_reset; _jstr code "$code"; _jstr label "$label" + _api POST "$(_journals_base "$year")" "$(_jbody)" +} + +_journals_update() { + id=''; year=''; code=''; label='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; --code) code="$2"; shift ;; --label) label="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift + done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes journals update --year " + _require_cfg; _jbody_reset; _jstr code "$code"; _jstr label "$label" + _api PATCH "$(_journals_base "$year")/$id" "$(_jbody)" +} + +_journals_delete() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes journals delete --year " + _require_cfg; _api DELETE "$(_journals_base "$year")/$id" > /dev/null + printf 'Journal %s deleted.\n' "$id" +} + +# ── accounts ────────────────────────────────────────────────────────────────── + +_cmd_accounts() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _accounts_list "$@" ;; get) _accounts_get "$@" ;; + create) _accounts_create "$@" ;; update) _accounts_update "$@" ;; + delete) _accounts_delete "$@" ;; + *) _die "arrhes accounts: unknown subcommand '$subcmd'" ;; + esac +} + +_accounts_base() { printf '%s/accounts' "$(_year_path "$1")"; } + +_accounts_list() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api GET "$(_accounts_base "$year")" +} + +_accounts_get() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes accounts get --year " + _require_cfg; _api GET "$(_accounts_base "$year")/$id" +} + +_accounts_create() { + year=''; number=''; label=''; type=''; parent=''; selectable='true' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; + --number) number="$2"; shift ;; + --label) label="$2"; shift ;; + --type) type="$2"; shift ;; + --parent) parent="$2"; shift ;; + --no-selectable) selectable='false' ;; + *) _die "Unknown: $1" ;; + esac; shift + done + [ -n "$year" ] && [ -n "$number" ] && [ -n "$label" ] && [ -n "$type" ] && [ -n "$parent" ] || \ + _die "--year, --number, --label, --type, and --parent are required" + _require_cfg; _jbody_reset + _jstr number "$number"; _jstr label "$label"; _jstr type "$type" + _jstr idAccountParent "$parent"; _jbool isSelectable "$selectable" + _api POST "$(_accounts_base "$year")" "$(_jbody)" +} + +_accounts_update() { + id=''; year=''; number=''; label=''; type=''; parent='' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; --number) number="$2"; shift ;; --label) label="$2"; shift ;; + --type) type="$2"; shift ;; --parent) parent="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; + esac; shift + done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes accounts update --year " + _require_cfg; _jbody_reset; _jstr number "$number"; _jstr label "$label"; _jstr type "$type"; _jstr idAccountParent "$parent" + _api PATCH "$(_accounts_base "$year")/$id" "$(_jbody)" +} + +_accounts_delete() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes accounts delete --year " + _require_cfg; _api DELETE "$(_accounts_base "$year")/$id" > /dev/null + printf 'Account %s deleted.\n' "$id" +} + +# ── tags ────────────────────────────────────────────────────────────────────── + +_cmd_tags() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _tags_list "$@" ;; get) _tags_get "$@" ;; + create) _tags_create "$@" ;; update) _tags_update "$@" ;; + delete) _tags_delete "$@" ;; + *) _die "arrhes tags: unknown subcommand '$subcmd'" ;; + esac +} + +_tags_base() { printf '%s/tags' "$(_year_path "$1")"; } + +_tags_list() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api GET "$(_tags_base "$year")" +} + +_tags_get() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes tags get --year " + _require_cfg; _api GET "$(_tags_base "$year")/$id" +} + +_tags_create() { + year=''; label='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] && [ -n "$label" ] || _die "--year and --label are required" + _require_cfg; _jbody_reset; _jstr label "$label" + _api POST "$(_tags_base "$year")" "$(_jbody)" +} + +_tags_update() { + id=''; year=''; label='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; --label) label="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes tags update --year " + _require_cfg; _jbody_reset; _jstr label "$label" + _api PATCH "$(_tags_base "$year")/$id" "$(_jbody)" +} + +_tags_delete() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes tags delete --year " + _require_cfg; _api DELETE "$(_tags_base "$year")/$id" > /dev/null + printf 'Tag %s deleted.\n' "$id" +} + +# ── entries ─────────────────────────────────────────────────────────────────── + +_cmd_entries() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _entries_list "$@" ;; get) _entries_get "$@" ;; + create) _entries_create "$@" ;; update) _entries_update "$@" ;; + duplicate) _entries_duplicate "$@" ;; reverse) _entries_reverse "$@" ;; + delete) _entries_delete "$@" ;; compute) _entries_compute "$@" ;; + lines) _cmd_entry_lines "$@" ;; tags) _cmd_entry_tags "$@" ;; + *) _die "arrhes entries: unknown subcommand '$subcmd'" ;; + esac +} + +_entries_base() { printf '%s/entries' "$(_year_path "$1")"; } + +_entries_list() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api GET "$(_entries_base "$year")" +} + +_entries_get() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes entries get --year " + _require_cfg; _api GET "$(_entries_base "$year")/$id" +} + +_entries_create() { + year=''; journal=''; label=''; date='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; --journal) journal="$2"; shift ;; --label) label="$2"; shift ;; --date) date="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$year" ] && [ -n "$journal" ] || _die "--year and --journal are required" + date="${date:-$(date +%Y-%m-%d)}" + _require_cfg; _jbody_reset; _jstr idJournal "$journal"; _jstr label "$label"; _jstr date "$date" + _api POST "$(_entries_base "$year")" "$(_jbody)" +} + +_entries_update() { + id=''; year=''; label=''; date=''; journal=''; file='' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; --label) label="$2"; shift ;; + --date) date="$2"; shift ;; --journal) journal="$2"; shift ;; + --file) file="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; + esac; shift + done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes entries update --year " + _require_cfg; _jbody_reset; _jstr label "$label"; _jstr date "$date"; _jstr idJournal "$journal"; _jstr idFile "$file" + _api PATCH "$(_entries_base "$year")/$id" "$(_jbody)" +} + +_entries_duplicate() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes entries duplicate --year " + _require_cfg; _api POST "$(_entries_base "$year")/$id/duplicate" +} + +_entries_reverse() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes entries reverse --year " + _require_cfg; _api POST "$(_entries_base "$year")/$id/reverse" +} + +_entries_delete() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes entries delete --year " + _require_cfg; _api DELETE "$(_entries_base "$year")/$id" > /dev/null + printf 'Entry %s deleted.\n' "$id" +} + +_entries_compute() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes entries compute --year " + _require_cfg; _api POST "$(_entries_base "$year")/$id/compute" +} + +# ── entries lines ───────────────────────────────────────────────────────────── + +_cmd_entry_lines() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _lines_list "$@" ;; get) _lines_get "$@" ;; + create) _lines_create "$@" ;; update) _lines_update "$@" ;; + delete) _lines_delete "$@" ;; + *) _die "arrhes entries lines: unknown subcommand '$subcmd'" ;; + esac +} + +_lines_base() { printf '%s/%s/lines' "$(_entries_base "$1")" "$2"; } + +_lines_list() { + entry=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) entry="$1" ;; esac; shift; done + [ -n "$entry" ] && [ -n "$year" ] || _die "Usage: arrhes entries lines list --year " + _require_cfg; _api GET "$(_lines_base "$year" "$entry")" +} + +_lines_get() { + entry=''; line=''; year='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; + *) if [ -z "$entry" ]; then entry="$1"; else line="$1"; fi ;; + esac; shift + done + [ -n "$entry" ] && [ -n "$line" ] && [ -n "$year" ] || _die "Usage: arrhes entries lines get --year " + _require_cfg; _api GET "$(_lines_base "$year" "$entry")/$line" +} + +_lines_create() { + entry=''; year=''; account=''; label=''; debit=''; credit='' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; --account) account="$2"; shift ;; + --label) label="$2"; shift ;; --debit) debit="$2"; shift ;; + --credit) credit="$2"; shift ;; -*) _die "Unknown: $1" ;; *) entry="$1" ;; + esac; shift + done + [ -n "$entry" ] && [ -n "$year" ] && [ -n "$account" ] || \ + _die "Usage: arrhes entries lines create --year --account " + _require_cfg; _jbody_reset; _jstr idAccount "$account"; _jstr label "$label"; _jnum debit "$debit"; _jnum credit "$credit" + _api POST "$(_lines_base "$year" "$entry")" "$(_jbody)" +} + +_lines_update() { + entry=''; line=''; year=''; label=''; debit=''; credit='' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; --label) label="$2"; shift ;; + --debit) debit="$2"; shift ;; --credit) credit="$2"; shift ;; + -*) _die "Unknown: $1" ;; *) if [ -z "$entry" ]; then entry="$1"; else line="$1"; fi ;; + esac; shift + done + [ -n "$entry" ] && [ -n "$line" ] && [ -n "$year" ] || _die "Usage: arrhes entries lines update --year " + _require_cfg; _jbody_reset; _jstr label "$label"; _jnum debit "$debit"; _jnum credit "$credit" + _api PATCH "$(_lines_base "$year" "$entry")/$line" "$(_jbody)" +} + +_lines_delete() { + entry=''; line=''; year='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; + *) if [ -z "$entry" ]; then entry="$1"; else line="$1"; fi ;; + esac; shift + done + [ -n "$entry" ] && [ -n "$line" ] && [ -n "$year" ] || _die "Usage: arrhes entries lines delete --year " + _require_cfg; _api DELETE "$(_lines_base "$year" "$entry")/$line" > /dev/null + printf 'Line %s deleted.\n' "$line" +} + +# ── entries tags ────────────────────────────────────────────────────────────── + +_cmd_entry_tags() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + add) _entry_tag_add "$@" ;; + remove) _entry_tag_remove "$@" ;; + *) _die "arrhes entries tags: use 'add' or 'remove'" ;; + esac +} + +_entry_tag_add() { + entry=''; year=''; tag='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; --tag) tag="$2"; shift ;; -*) _die "Unknown: $1" ;; *) entry="$1" ;; esac; shift + done + [ -n "$entry" ] && [ -n "$year" ] && [ -n "$tag" ] || \ + _die "Usage: arrhes entries tags add --year --tag " + _require_cfg; _jbody_reset; _jstr idTag "$tag" + _api POST "$(_entries_base "$year")/$entry/tags" "$(_jbody)" +} + +_entry_tag_remove() { + entry=''; tag=''; year='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; + *) if [ -z "$entry" ]; then entry="$1"; else tag="$1"; fi ;; + esac; shift + done + [ -n "$entry" ] && [ -n "$tag" ] && [ -n "$year" ] || \ + _die "Usage: arrhes entries tags remove --year " + _require_cfg; _api DELETE "$(_entries_base "$year")/$entry/tags/$tag" > /dev/null + printf 'Tag removed.\n' +} + +# ── files ───────────────────────────────────────────────────────────────────── + +_cmd_files() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _files_list "$@" ;; get) _files_get "$@" ;; + create) _files_create "$@" ;; update) _files_update "$@" ;; + delete) _files_delete "$@" ;; download-url) _files_download_url "$@" ;; + folders) _cmd_folders "$@" ;; + *) _die "arrhes files: unknown subcommand '$subcmd'" ;; + esac +} + +_files_base() { printf '%s/files' "$(_year_path "$1")"; } + +_files_list() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api GET "$(_files_base "$year")" +} + +_files_get() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files get --year " + _require_cfg; _api GET "$(_files_base "$year")/$id" +} + +_files_create() { + year=''; name=''; reference=''; hash=''; folder='' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; --name) name="$2"; shift ;; + --reference) reference="$2"; shift ;; --hash) hash="$2"; shift ;; + --folder) folder="$2"; shift ;; *) _die "Unknown: $1" ;; + esac; shift + done + [ -n "$year" ] && [ -n "$name" ] && [ -n "$reference" ] && [ -n "$hash" ] || \ + _die "--year, --name, --reference, and --hash are required" + _require_cfg; _jbody_reset; _jstr name "$name"; _jstr reference "$reference"; _jstr hash "$hash"; _jstr idFolder "$folder" + _api POST "$(_files_base "$year")" "$(_jbody)" +} + +_files_update() { + id=''; year=''; name=''; reference=''; date=''; folder='' + while [ $# -gt 0 ]; do + case "$1" in + --year) year="$2"; shift ;; --name) name="$2"; shift ;; + --reference) reference="$2"; shift ;; --date) date="$2"; shift ;; + --folder) folder="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; + esac; shift + done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files update --year " + _require_cfg; _jbody_reset; _jstr name "$name"; _jstr reference "$reference"; _jstr date "$date"; _jstr idFolder "$folder" + _api PATCH "$(_files_base "$year")/$id" "$(_jbody)" +} + +_files_delete() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files delete --year " + _require_cfg; _api DELETE "$(_files_base "$year")/$id" > /dev/null + printf 'File %s deleted.\n' "$id" +} + +_files_download_url() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files download-url --year " + _require_cfg + _api POST "$(_files_base "$year")/$id/download-url" | sed 's/.*"url":"\([^"]*\)".*/\1/' +} + +# ── files folders ───────────────────────────────────────────────────────────── + +_cmd_folders() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _folders_list "$@" ;; get) _folders_get "$@" ;; + create) _folders_create "$@" ;; update) _folders_update "$@" ;; + delete) _folders_delete "$@" ;; + *) _die "arrhes files folders: unknown subcommand '$subcmd'" ;; + esac +} + +_folders_base() { printf '%s/folders' "$(_year_path "$1")"; } + +_folders_list() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api GET "$(_folders_base "$year")" +} + +_folders_get() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files folders get --year " + _require_cfg; _api GET "$(_folders_base "$year")/$id" +} + +_folders_create() { + year=''; name=''; parent='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; --name) name="$2"; shift ;; --parent) parent="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$year" ] && [ -n "$name" ] || _die "--year and --name are required" + _require_cfg; _jbody_reset; _jstr name "$name"; _jstr idFolderParent "$parent" + _api POST "$(_folders_base "$year")" "$(_jbody)" +} + +_folders_update() { + id=''; year=''; name=''; parent='' + while [ $# -gt 0 ]; do + case "$1" in --year) year="$2"; shift ;; --name) name="$2"; shift ;; --parent) parent="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift + done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files folders update --year " + _require_cfg; _jbody_reset; _jstr name "$name"; _jstr idFolderParent "$parent" + _api PATCH "$(_folders_base "$year")/$id" "$(_jbody)" +} + +_folders_delete() { + id=''; year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift; done + [ -n "$id" ] && [ -n "$year" ] || _die "Usage: arrhes files folders delete --year " + _require_cfg; _api DELETE "$(_folders_base "$year")/$id" > /dev/null + printf 'Folder %s deleted.\n' "$id" +} + +# ── members ─────────────────────────────────────────────────────────────────── + +_cmd_members() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _require_cfg; _api GET "$(_org_path)/users" ;; + get) _members_get "$@" ;; + invite) _members_invite "$@" ;; + update) _members_update "$@" ;; + remove) _members_remove "$@" ;; + *) _die "arrhes members: unknown subcommand '$subcmd'" ;; + esac +} + +_members_get() { + id="${1:?Usage: arrhes members get }" + _require_cfg; _api GET "$(_org_path)/users/$id" +} + +_members_invite() { + email=''; is_admin='false' + while [ $# -gt 0 ]; do + case "$1" in --email) email="$2"; shift ;; --admin) is_admin='true' ;; *) _die "Unknown: $1" ;; esac; shift + done + [ -n "$email" ] || _die "--email is required" + _require_cfg + _api POST "$(_org_path)/users" \ + "{\"isAdmin\":${is_admin},\"user\":{\"email\":\"$(_jesc "$email")\"}}" +} + +_members_update() { + id=''; is_admin='' + while [ $# -gt 0 ]; do + case "$1" in --admin) is_admin='true' ;; --no-admin) is_admin='false' ;; -*) _die "Unknown: $1" ;; *) id="$1" ;; esac; shift + done + [ -n "$id" ] || _die "Usage: arrhes members update [--admin|--no-admin]" + _require_cfg; _jbody_reset; [ -n "$is_admin" ] && _jbool isAdmin "$is_admin" || true + _api PATCH "$(_org_path)/users/$id" "$(_jbody)" +} + +_members_remove() { + id="${1:?Usage: arrhes members remove }" + _require_cfg; _api DELETE "$(_org_path)/users/$id" > /dev/null + printf 'Member %s removed.\n' "$id" +} + +# ── api-keys ────────────────────────────────────────────────────────────────── + +_cmd_api_keys() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _require_cfg; _api GET "$(_org_path)/api-keys" ;; + create) _api_keys_create "$@" ;; + delete) _api_keys_delete "$@" ;; + *) _die "arrhes api-keys: unknown subcommand '$subcmd'" ;; + esac +} + +_api_keys_create() { + name='' + while [ $# -gt 0 ]; do case "$1" in --name) name="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + _require_cfg; _jbody_reset; _jstr name "$name" + _api POST "$(_org_path)/api-keys" "$(_jbody)" +} + +_api_keys_delete() { + id="${1:?Usage: arrhes api-keys delete }" + _require_cfg; _api DELETE "$(_org_path)/api-keys/$id" > /dev/null + printf 'API key %s deleted.\n' "$id" +} + +# ── exports ─────────────────────────────────────────────────────────────────── + +_cmd_exports() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + fec) _exports_fec "$@" ;; + xbrl-balance-sheet) _exports_xbrl_bs "$@" ;; + xbrl-income-statement) _exports_xbrl_is "$@" ;; + *) _die "arrhes exports: unknown subcommand '$subcmd'" ;; + esac +} + +_exports_fec() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api POST "$(_year_path "$year")/exports/fec" | sed 's/.*"url":"\([^"]*\)".*/\1/' +} + +_exports_xbrl_bs() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api POST "$(_year_path "$year")/exports/balance-sheet" | sed 's/.*"url":"\([^"]*\)".*/\1/' +} + +_exports_xbrl_is() { + year='' + while [ $# -gt 0 ]; do case "$1" in --year) year="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$year" ] || _die "--year is required" + _require_cfg; _api POST "$(_year_path "$year")/exports/income-statement" | sed 's/.*"url":"\([^"]*\)".*/\1/' +} + +# ── balance-sheets ──────────────────────────────────────────────────────────── + +_cmd_balance_sheets() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _bs_list "$@" ;; get) _bs_get "$@" ;; + create) _bs_create "$@" ;; update) _bs_update "$@" ;; + delete) _bs_delete "$@" ;; + *) _die "arrhes balance-sheets: unknown subcommand '$subcmd'" ;; + esac +} + +_bs_base() { printf '%s/balance-sheets' "$(_year_path "$1")"; } + +_bs_list() { + year="${1:?Usage: arrhes balance-sheets list }" + _require_cfg; _api GET "$(_bs_base "$year")" +} + +_bs_get() { + year="${1:?Usage: arrhes balance-sheets get }" + bs="${2:?missing }" + _require_cfg; _api GET "$(_bs_base "$year")/$bs" +} + +_bs_create() { + year="${1:?Usage: arrhes balance-sheets create }"; shift + parent=''; label='' + while [ $# -gt 0 ]; do case "$1" in --parent) parent="$2"; shift ;; --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + _require_cfg; _jbody_reset; _jstr_null idBalanceSheetParent "$parent"; _jstr label "$label" + _api POST "$(_bs_base "$year")" "$(_jbody)" +} + +_bs_update() { + year="${1:?Usage: arrhes balance-sheets update }" + bs="${2:?missing }"; shift 2 + parent=''; label='' + while [ $# -gt 0 ]; do case "$1" in --parent) parent="$2"; shift ;; --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + _require_cfg; _jbody_reset; _jstr idBalanceSheetParent "$parent"; _jstr label "$label" + _api PATCH "$(_bs_base "$year")/$bs" "$(_jbody)" +} + +_bs_delete() { + year="${1:?Usage: arrhes balance-sheets delete }" + bs="${2:?missing }" + _require_cfg; _api DELETE "$(_bs_base "$year")/$bs" > /dev/null + printf 'Balance sheet node %s deleted.\n' "$bs" +} + +# ── income-statements ───────────────────────────────────────────────────────── + +_cmd_income_statements() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _is_list "$@" ;; get) _is_get "$@" ;; + create) _is_create "$@" ;; update) _is_update "$@" ;; + delete) _is_delete "$@" ;; computations) _cmd_computations "$@" ;; + *) _die "arrhes income-statements: unknown subcommand '$subcmd'" ;; + esac +} + +_is_base() { printf '%s/income-statements' "$(_year_path "$1")"; } + +_is_list() { + year="${1:?Usage: arrhes income-statements list }" + _require_cfg; _api GET "$(_is_base "$year")" +} + +_is_get() { + year="${1:?Usage: arrhes income-statements get }" + is="${2:?missing }" + _require_cfg; _api GET "$(_is_base "$year")/$is" +} + +_is_create() { + year="${1:?Usage: arrhes income-statements create }"; shift + label=''; parent='' + while [ $# -gt 0 ]; do case "$1" in --label) label="$2"; shift ;; --parent) parent="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$label" ] || _die "--label is required" + _require_cfg; _jbody_reset; _jstr label "$label"; _jstr_null idIncomeStatementParent "$parent" + _api POST "$(_is_base "$year")" "$(_jbody)" +} + +_is_update() { + year="${1:?Usage: arrhes income-statements update }" + is="${2:?missing }"; shift 2 + label=''; parent='' + while [ $# -gt 0 ]; do case "$1" in --label) label="$2"; shift ;; --parent) parent="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + _require_cfg; _jbody_reset; _jstr label "$label"; _jstr idIncomeStatementParent "$parent" + _api PATCH "$(_is_base "$year")/$is" "$(_jbody)" +} + +_is_delete() { + year="${1:?Usage: arrhes income-statements delete }" + is="${2:?missing }" + _require_cfg; _api DELETE "$(_is_base "$year")/$is" > /dev/null + printf 'Income statement node %s deleted.\n' "$is" +} + +# ── computations ────────────────────────────────────────────────────────────── + +_cmd_computations() { + subcmd="${1:-}"; [ $# -gt 0 ] && shift + case "$subcmd" in + list) _comp_list "$@" ;; get) _comp_get "$@" ;; + create) _comp_create "$@" ;; update) _comp_update "$@" ;; + delete) _comp_delete "$@" ;; + *) _die "arrhes income-statements computations: unknown subcommand '$subcmd'" ;; + esac +} + +_comp_base() { printf '%s/computations' "$(_year_path "$1")"; } + +_comp_list() { + year="${1:?Usage: arrhes income-statements computations list }" + _require_cfg; _api GET "$(_comp_base "$year")" +} + +_comp_get() { + year="${1:?Usage: arrhes income-statements computations get }" + comp="${2:?missing }" + _require_cfg; _api GET "$(_comp_base "$year")/$comp" +} + +_comp_create() { + year="${1:?Usage: arrhes income-statements computations create }"; shift + label='' + while [ $# -gt 0 ]; do case "$1" in --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + [ -n "$label" ] || _die "--label is required" + _require_cfg; _jbody_reset; _jstr label "$label" + _api POST "$(_comp_base "$year")" "$(_jbody)" +} + +_comp_update() { + year="${1:?Usage: arrhes income-statements computations update }" + comp="${2:?missing }"; shift 2 + label='' + while [ $# -gt 0 ]; do case "$1" in --label) label="$2"; shift ;; *) _die "Unknown: $1" ;; esac; shift; done + _require_cfg; _jbody_reset; _jstr label "$label" + _api PATCH "$(_comp_base "$year")/$comp" "$(_jbody)" +} + +_comp_delete() { + year="${1:?Usage: arrhes income-statements computations delete }" + comp="${2:?missing }" + _require_cfg; _api DELETE "$(_comp_base "$year")/$comp" > /dev/null + printf 'Computation %s deleted.\n' "$comp" +} + +# ── usage ───────────────────────────────────────────────────────────────────── + +_usage() { + cat << 'EOF' +Usage: arrhes [subcommand] [options] + +Authentication: + login --api-key [--url ] + whoami + logout + +Commands: + org get | update | delete + years list | get | create | update | delete | close | open + settle-balance-sheet | settle-income-statement + journals list | get | create | update | delete + accounts list | get | create | update | delete + tags list | get | create | update | delete + entries list | get | create | update | duplicate | reverse | delete | compute + entries lines list | get | create | update | delete + entries tags add | remove + files list | get | create | update | delete | download-url + files folders list | get | create | update | delete + members list | get | invite | update | remove + api-keys list | create | delete + exports fec | xbrl-balance-sheet | xbrl-income-statement + balance-sheets list | get | create | update | delete + income-statements list | get | create | update | delete + income-statements computations list | get | create | update | delete + +Options: + --help, -h Show this help + --version, -v Show version ($VERSION) + +Output is JSON. Pipe through jq for filtering: + arrhes years list --year yr_xxx | jq '.[].id' +EOF +} + +# ── main ────────────────────────────────────────────────────────────────────── + +main() { + _need_cmd curl + cmd="${1:-}"; [ $# -gt 0 ] && shift + case "$cmd" in + login) _cmd_login "$@" ;; + whoami) _cmd_whoami ;; + logout) _cmd_logout ;; + org) _cmd_org "$@" ;; + years) _cmd_years "$@" ;; + journals) _cmd_journals "$@" ;; + accounts) _cmd_accounts "$@" ;; + tags) _cmd_tags "$@" ;; + entries) _cmd_entries "$@" ;; + files) _cmd_files "$@" ;; + members) _cmd_members "$@" ;; + api-keys) _cmd_api_keys "$@" ;; + exports) _cmd_exports "$@" ;; + balance-sheets) _cmd_balance_sheets "$@" ;; + income-statements) _cmd_income_statements "$@" ;; + --version|-v) printf 'arrhes %s\n' "$VERSION" ;; + --help|-h|'') _usage ;; + *) printf 'arrhes: unknown command: %s\n' "$cmd" >&2; _usage >&2; exit 1 ;; + esac +} + +main "$@" diff --git a/packages/cli/install.sh b/packages/cli/install.sh new file mode 100644 index 00000000..22fce5ec --- /dev/null +++ b/packages/cli/install.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# Arrhes CLI installer for macOS and Linux +# Usage: curl -fsSL https://arrhes.com/cli/install.sh | sh +set -e + +REPO="arrhes/application" +INSTALL_DIR="${ARRHES_INSTALL_DIR:-$HOME/.local/bin}" +DEST="${INSTALL_DIR}/arrhes" + +command -v curl >/dev/null 2>&1 || { echo "Error: curl is required."; exit 1; } + +URL="https://github.com/${REPO}/releases/latest/download/arrhes.sh" + +echo "Downloading arrhes CLI..." +mkdir -p "$INSTALL_DIR" +curl -fsSL --progress-bar "$URL" -o "$DEST" +chmod +x "$DEST" + +echo "Installed: $DEST" +echo "Version: $($DEST --version)" + +# ── PATH hint ───────────────────────────────────────────────────────────────── +case ":$PATH:" in + *":${INSTALL_DIR}:"*) + echo "Run: arrhes --help" + ;; + *) + printf '\nAdd to PATH: export PATH="$HOME/.local/bin:$PATH"\n' + printf 'Then reload your shell, or run: source ~/.bashrc\n' + ;; +esac + diff --git a/packages/cli/package.json b/packages/cli/package.json new file mode 100644 index 00000000..23e8af66 --- /dev/null +++ b/packages/cli/package.json @@ -0,0 +1,7 @@ +{ + "name": "@arrhes/cli", + "version": "0.1.0", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/metadata/src/components/values/routePath.ts b/packages/metadata/src/components/values/routePath.ts index 0bb26b04..4bd79aef 100644 --- a/packages/metadata/src/components/values/routePath.ts +++ b/packages/metadata/src/components/values/routePath.ts @@ -2,4 +2,5 @@ export const routePath = { public: "/public", auth: "/auth", admin: "/admin", + v1: "/v1", } diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentFile/createOneAgentFile.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentFile/createOneAgentFile.ts index ae6c080a..bda53b07 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentFile/createOneAgentFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentFile/createOneAgentFile.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const createOneAgentFileRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-agent-file`, + method: "POST", + path: `${routePath.v1}/agent/sessions/:idAgentSession/files`, schemas: { body: v.object({ idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/createOneAgentMessage.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/createOneAgentMessage.ts index df20ef3e..e26dac02 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/createOneAgentMessage.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/createOneAgentMessage.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const createOneAgentMessageRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-agent-message`, + method: "POST", + path: `${routePath.v1}/agent/sessions/:idAgentSession/messages`, schemas: { body: v.object({ idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/getStreamForAgentMessage.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/getStreamForAgentMessage.ts index 542df643..f2808f67 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/getStreamForAgentMessage.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/getStreamForAgentMessage.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const getStreamForAgentMessageRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/get-stream-for-agent-message`, + method: "GET", + path: `${routePath.v1}/agent/sessions/:idAgentSession/messages/:idAgentMessage/stream`, schemas: { body: v.object({ idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/readAllAgentMessages.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/readAllAgentMessages.ts index aee9193e..f7eb1444 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/readAllAgentMessages.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentMessage/readAllAgentMessages.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const readAllAgentMessagesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-agent-messages`, + method: "GET", + path: `${routePath.v1}/agent/sessions/:idAgentSession/messages`, schemas: { body: v.object({ idAgentSession: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/createOneAgentSession.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/createOneAgentSession.ts index ef8e6687..3d2ddceb 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/createOneAgentSession.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/createOneAgentSession.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const createOneAgentSessionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-agent-session`, + method: "POST", + path: `${routePath.v1}/agent/sessions`, schemas: { body: v.object({ idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/deleteOneAgentSession.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/deleteOneAgentSession.ts index 42f54f8f..c61ab0e2 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/deleteOneAgentSession.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/deleteOneAgentSession.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const deleteOneAgentSessionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-agent-session`, + method: "DELETE", + path: `${routePath.v1}/agent/sessions/:idAgentSession`, schemas: { body: v.object({ idAgentSession: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readAllAgentSessions.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readAllAgentSessions.ts index f632493a..e6b2f636 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readAllAgentSessions.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readAllAgentSessions.ts @@ -16,7 +16,8 @@ export const agentSessionWithMatchedContentSchema = v.object({ export const readAllAgentSessionsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-agent-sessions`, + method: "GET", + path: `${routePath.v1}/agent/sessions`, schemas: { body: v.object({ idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readOneAgentSession.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readOneAgentSession.ts index 245d8799..d747f287 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readOneAgentSession.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/readOneAgentSession.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const readOneAgentSessionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-agent-session`, + method: "GET", + path: `${routePath.v1}/agent/sessions/:idAgentSession`, schemas: { body: v.object({ idAgentSession: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/updateOneAgentSession.ts b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/updateOneAgentSession.ts index 72945eba..d0f9f813 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/agentSession/updateOneAgentSession.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/agentSession/updateOneAgentSession.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const updateOneAgentSessionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-agent-session`, + method: "PATCH", + path: `${routePath.v1}/agent/sessions/:idAgentSession`, schemas: { body: v.object({ idAgentSession: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/getChatStream.ts b/packages/metadata/src/routes/dashboard/auth/agent/getChatStream.ts index 48acb5f2..e4217dbf 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/getChatStream.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/getChatStream.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const getChatStreamRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/get-chat-stream`, + method: "GET", + path: `${routePath.v1}/agent/sessions/:idAgentSession/stream`, schemas: { body: v.object({ idAgentMessage: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/searchReferenceable.ts b/packages/metadata/src/routes/dashboard/auth/agent/searchReferenceable.ts index b6faa360..0451fbac 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/searchReferenceable.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/searchReferenceable.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const searchReferenceableRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/search-referenceable`, + method: "GET", + path: `${routePath.v1}/agent/search`, schemas: { body: v.object({ idOrganization: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/agent/undoAgentAction.ts b/packages/metadata/src/routes/dashboard/auth/agent/undoAgentAction.ts index 239ba040..7bb92cb2 100644 --- a/packages/metadata/src/routes/dashboard/auth/agent/undoAgentAction.ts +++ b/packages/metadata/src/routes/dashboard/auth/agent/undoAgentAction.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const undoAgentActionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/undo-agent-action`, + method: "POST", + path: `${routePath.v1}/agent/sessions/:idAgentSession/undo`, schemas: { body: v.object({ idAgentMessage: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/index.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/index.ts index 49ba5c83..19a0a6de 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/index.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/index.ts @@ -46,6 +46,9 @@ export { createOneEntryRouteDefinition } from "./years/$idYear/entries/createOne export { createOneEntryFromTemplateRouteDefinition } from "./years/$idYear/entries/createOneEntryFromTemplate.js" export { readAllEntriesRouteDefinition } from "./years/$idYear/entries/readAllEntries.js" export { readAllEntryTagsRouteDefinition } from "./years/$idYear/entries/readAllEntryTags.js" +export { generateBalanceSheetXmlRouteDefinition } from "./years/$idYear/exports/generateBalanceSheetXml.js" +export { generateFecRouteDefinition } from "./years/$idYear/exports/generateFec.js" +export { generateIncomeStatementXmlRouteDefinition } from "./years/$idYear/exports/generateIncomeStatementXml.js" export { deleteOneFileRouteDefinition } from "./years/$idYear/files/$idFile/deleteOneFile.js" export { finalizeFileUploadRouteDefinition } from "./years/$idYear/files/$idFile/finalizeFileUpload.js" export { generateFileDeleteSignedUrlRouteDefinition } from "./years/$idYear/files/$idFile/generateFileDeleteSignedUrl.js" @@ -64,8 +67,6 @@ export { createOneFolderRouteDefinition } from "./years/$idYear/folders/createOn export { readAllFoldersRouteDefinition } from "./years/$idYear/folders/readAllFolders.js" // year export { readOneYearRouteDefinition } from "./years/$idYear/readOneYear.js" -export { generateBalanceSheetXmlRouteDefinition } from "./years/$idYear/reports/generateBalanceSheetXml.js" -export { generateIncomeStatementXmlRouteDefinition } from "./years/$idYear/reports/generateIncomeStatementXml.js" export { deleteOneAccountRouteDefinition } from "./years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.js" export { readOneAccountRouteDefinition } from "./years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.js" export { updateOneAccountRouteDefinition } from "./years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.js" diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts index 60194f88..0384ce1c 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/createOneApiKey.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createOneApiKeyRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-api-key`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/api-keys`, schemas: { body: v.object({ name: v.optional(apiKeySchema.entries.name), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts index 7e68bcd8..5e03206a 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/deleteOneApiKey.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const deleteOneApiKeyRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-api-key`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/api-keys/:idApiKey`, schemas: { body: v.object({ idApiKey: apiKeySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts index de5f432c..53aae96e 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/apiKey/readAllApiKeys.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readAllApiKeysRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-api-keys`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/api-keys`, schemas: { body: v.object({}), return: v.array(apiKeySchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts index fcbdcf29..eacd370d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/deleteOneOrganization.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../utilities/routeDefinition.js" export const deleteOneOrganizationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-organization`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization`, schemas: { body: v.object({}), return: v.object({}), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts index b89674b5..533a627c 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelOrganizationBilling.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const cancelOrganizationBillingRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/cancel-organization-billing`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/billing`, schemas: { body: v.object({ idBilling: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts index b4ca3d27..d320c9e1 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/cancelSubscription.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const cancelSubscriptionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/cancel-subscription`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/billing/cancel-subscription`, schemas: { body: v.object({}), return: v.object({}), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts index 8a1650a6..f8d7b8bd 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createFirstPayment.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createFirstPaymentRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-first-payment`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/billing/first-payment`, schemas: { body: v.object({}), return: v.object({ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts index bc9c7d86..de770f6c 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createPaymentMethodCheckout.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createPaymentMethodCheckoutRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-payment-method-checkout`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/billing/payment-method-checkout`, schemas: { body: v.object({}), return: v.object({ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts index ec775597..8ba9fe99 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createResourceSubscription.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createResourceSubscriptionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-resource-subscription`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/billing/resource-subscription`, schemas: { body: v.object({ type: v.picklist( diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts index 7691bfac..ae7b56f2 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletTopUpCheckout.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createWalletTopUpCheckoutRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-wallet-top-up-checkout`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/billing/wallet-top-up`, schemas: { body: v.object({ amountInCents: v.pipe(integerSchema, v.minValue(1)), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts index 55b9e04e..99d21e11 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/createWalletWithdrawal.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createWalletWithdrawalRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-wallet-withdrawal`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/billing/wallet-withdrawal`, schemas: { body: v.object({ amountInCents: v.pipe(integerSchema, v.minValue(1)), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts index ccaaf616..44d26209 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/generateInvoiceGetSignedUrl.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const generateInvoiceGetSignedUrlRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-invoice-get-signed-url`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/invoices/:idInvoice/download-url`, schemas: { body: v.object({ idInvoice: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts index cb77d553..1b828e5e 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllInvoices.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readAllInvoicesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-invoices`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/invoices`, schemas: { body: v.object({}), return: v.array(invoiceSchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts index 88fbb764..3ea833b4 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationBillings.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readAllOrganizationBillingsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-organization-billings`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/billings`, schemas: { body: v.object({}), return: v.array(organizationBillingSchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts index 44ecbf04..46be6216 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readAllOrganizationPayments.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readAllOrganizationPaymentsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-organization-payments`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/payments`, schemas: { body: v.object({}), return: v.array(organizationPaymentSchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts index 290c7c8d..75a630bc 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOneInvoice.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readOneInvoiceRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-invoice`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/invoices/:idInvoice`, schemas: { body: v.object({ idInvoice: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts index 5f166416..f4e4b31d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/readOrganizationBilling.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readOrganizationBillingRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-organization-billing`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/billing`, schemas: { body: v.object({}), return: v.object({ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts index d94676f6..69a16ec7 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateLicenceSubscription.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const updateLicenceSubscriptionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-licence-subscription`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/billing/licence-subscription`, schemas: { body: v.object({ newAmountInCents: v.pipe(integerSchema, v.minValue(0)), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts index db430c91..ce9b85b0 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateOcrSubscription.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const updateOcrSubscriptionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-ocr-subscription`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/billing/ocr-subscription`, schemas: { body: v.object({ newQuantity: v.pipe(integerSchema, v.minValue(0)), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts index 8e806d2a..446ed3bc 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateStorageSubscription.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const updateStorageSubscriptionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-storage-subscription`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/billing/storage-subscription`, schemas: { body: v.object({ newQuantity: v.pipe(integerSchema, v.minValue(0)), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts index 976528d8..3fc54827 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationPayment/updateTokensSubscription.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const updateTokensSubscriptionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-tokens-subscription`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/billing/tokens-subscription`, schemas: { body: v.object({ newQuantity: v.pipe(integerSchema, v.minValue(0)), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts index da7eb9c4..7670d0a4 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/createOneOrganizationUser.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const createOneOrganizationUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-organization-user`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/users`, schemas: { body: v.object({ isAdmin: organizationUserSchema.entries.isAdmin, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts index 32cbb49e..283f9913 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/deleteOneOrganizationUser.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const deleteOneOrganizationUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-organization-user`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/users/:idOrganizationUser`, schemas: { body: v.object({ idOrganizationUser: organizationUserSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts index 6e58d478..6f8c0126 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readAllOrganizationUsers.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readAllOrganizationUsersRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-organization-users`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/users`, schemas: { body: v.object({}), return: v.array( diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts index 4541194b..ae0c8af0 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/readOneOrganizationUser.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readOneOrganizationUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-organization-user`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/users/:idOrganizationUser`, schemas: { body: v.object({ idOrganizationUser: organizationUserSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts index 6d929510..0ea14453 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/organizationUser/updateOneOrganizationUser.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const updateOneOrganizationUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-organization-user`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/users/:idOrganizationUser`, schemas: { body: v.object({ idOrganizationUser: organizationUserSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts index 8a2fe6b3..33f5c37c 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/organizationSettings/updateOneOrganization.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../utilities/routeDefinition.js" export const updateOneOrganizationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-organization`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization`, schemas: { body: v.object({ siren: v.optional(organizationSchema.entries.siren), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/readOneOrganization.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/readOneOrganization.ts index 4dafab17..1c5eaa3b 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/readOneOrganization.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/readOneOrganization.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../utilities/routeDefinition.js" export const readOneOrganizationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-organization`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization`, schemas: { body: v.object({ idOrganization: organizationSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/computeOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/computeOneEntry.ts index 1ebbb4f0..e8110d19 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/computeOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/computeOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const computeOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/compute-one-entry`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/compute`, schemas: { body: v.object({ idEntry: entrySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts index 7426faa7..fc718368 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/deleteOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const deleteOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-entry`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry`, schemas: { body: v.object({ idEntry: entrySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts index 6b3863d9..c4861ecb 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/duplicateOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const duplicateOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/duplicate-one-entry`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/duplicate`, schemas: { body: v.object({ idEntry: entrySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts index 17d779b3..defb24fb 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/deleteOneEntryLine.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../../utilities/rout export const deleteOneEntryLineRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-entry-line`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines/:idEntryLine`, schemas: { body: v.object({ idEntryLine: entryLineSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts index ed070c1f..7d3fff1b 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/readOneEntryLine.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../../utilities/rout export const readOneEntryLineRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-entry-line`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines/:idEntryLine`, schemas: { body: v.object({ idEntryLine: entryLineSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts index fc406201..3fcf4052 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/$idEntryLine/updateOneEntryLine.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../../utilities/rout export const updateOneEntryLineRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-entry-line`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines/:idEntryLine`, schemas: { body: v.object({ idEntryLine: entryLineSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts index c50e7ec3..ad971040 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/createOneEntryLine.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const createOneEntryLineRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-entry-line`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines`, schemas: { body: v.object({ idYear: entryLineSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts index 552f95a0..14093f49 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/readAllEntryLines.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readAllEntryLinesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-entry-lines`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines`, schemas: { body: v.object({ idYear: entryLineSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts index ec4b4ee1..cfc1f063 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryLines/updateManyEntryLines.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateManyEntryLinesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-many-entry-lines`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines`, schemas: { body: v.object({ idEntry: entryLineSchema.entries.idEntry, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts index 225d6b14..b2348123 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/addOneEntryTag.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const addOneEntryTagRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/add-one-entry-tag`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/tags`, schemas: { body: v.object({ idYear: entryTagSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts index ae7f3da0..bb77d1ea 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/entryTags/removeOneEntryTag.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const removeOneEntryTagRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/remove-one-entry-tag`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/tags/:idTag`, schemas: { body: v.object({ idYear: entryTagSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts index e81434f7..1ab0b636 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/readOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-entry`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry`, schemas: { body: v.object({ idEntry: entrySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts index 9780bcdd..7e560dac 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/reverseOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const reverseOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/reverse-one-entry`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/reverse`, schemas: { body: v.object({ idEntry: entrySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts index 95465416..f068d17e 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/$idEntry/updateOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const updateOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-entry`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry`, schemas: { body: v.object({ idEntry: entrySchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts index cae13123..716f2a50 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntry.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const createOneEntryRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-entry`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries`, schemas: { body: v.object({ idYear: entrySchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts index 2c5180c1..2cb182bd 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/createOneEntryFromTemplate.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const createOneEntryFromTemplateRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-entry-from-template`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/from-template`, schemas: { body: v.object({ idYear: entrySchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts index 1f91d99f..7aa48d53 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntries.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const readAllEntriesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-entries`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entries`, schemas: { body: v.object({ idYear: entrySchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts index c647ea2f..7ef5d0e6 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/entries/readAllEntryTags.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const readAllEntryTagsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-entry-tags`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/entry-tags`, schemas: { body: v.object({ idYear: entryTagSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/generateBalanceSheetXml.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateBalanceSheetXml.ts similarity index 82% rename from packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/generateBalanceSheetXml.ts rename to packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateBalanceSheetXml.ts index a259db0a..8f53dec9 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/generateBalanceSheetXml.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateBalanceSheetXml.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const generateBalanceSheetXmlRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-balance-sheet-xml`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/exports/balance-sheet`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts new file mode 100644 index 00000000..77f6dbd1 --- /dev/null +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateFec.ts @@ -0,0 +1,18 @@ +import * as v from "valibot" +import { routePath } from "../../../../../../../../components/index.js" +import { yearSchema } from "../../../../../../../../schemas/year.js" +import { routeDefinition } from "../../../../../../../../utilities/routeDefinition.js" + +export const generateFecRouteDefinition = routeDefinition({ + protocol: "http", + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/exports/fec`, + schemas: { + body: v.object({ + idYear: yearSchema.entries.id, + }), + return: v.object({ + url: v.string(), + }), + }, +}) diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/generateIncomeStatementXml.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateIncomeStatementXml.ts similarity index 81% rename from packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/generateIncomeStatementXml.ts rename to packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateIncomeStatementXml.ts index 46ec6090..ebc26252 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/generateIncomeStatementXml.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/generateIncomeStatementXml.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const generateIncomeStatementXmlRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-income-statement-xml`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/exports/income-statement`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/index.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/index.ts similarity index 74% rename from packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/index.ts rename to packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/index.ts index be42041a..e7d7a225 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/reports/index.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/exports/index.ts @@ -1,2 +1,3 @@ export { generateBalanceSheetXmlRouteDefinition } from "./generateBalanceSheetXml.js" +export { generateFecRouteDefinition } from "./generateFec.js" export { generateIncomeStatementXmlRouteDefinition } from "./generateIncomeStatementXml.js" diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts index 380068a1..6731bd90 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/deleteOneFile.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const deleteOneFileRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-file`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts index b2dc0b1a..a9eeacb9 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/finalizeFileUpload.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const finalizeFileUploadRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/finalize-file-upload`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/finalize`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts index df9243d9..b25c83d7 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileDeleteSignedUrl.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateFileDeleteSignedUrlRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-file-delete-signed-url`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/delete-url`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts index 6b907bad..49eee553 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFileGetSignedUrl.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateFileGetSignedUrlRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-file-get-signed-url`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/download-url`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts index 347e7c8e..c9f80fda 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/generateFilePutSignedUrl.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateFilePutSignedUrlRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-file-put-signed-url`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/upload-url`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts index b14f4924..1973ab10 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/ocrFile.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const ocrFileRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/ocr-file`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/ocr`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts index 3df53d37..bfd27d22 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/readOneFile.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readOneFileRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-file`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts index b89eb7b8..fd414a5f 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/$idFile/updateOneFile.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const updateOneFileRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-file`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile`, schemas: { body: v.object({ idFile: fileSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts index 7e9d07bf..215fc2fb 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/createOneFile.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const createOneFileRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-file`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files`, schemas: { body: v.object({ idFolder: v.optional(fileSchema.entries.idFolder), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts index f04a724d..9416bcd1 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/files/readAllFiles.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const readAllFilesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-files`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/files`, schemas: { body: v.object({}), return: v.array(fileSchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts index 024c33c6..d0271198 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/deleteOneFolder.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const deleteOneFolderRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-folder`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/folders/:idFolder`, schemas: { body: v.object({ idFolder: folderSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts index df2083a4..87843874 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/readOneFolder.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readOneFolderRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-folder`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/folders/:idFolder`, schemas: { body: v.object({ idFolder: folderSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts index ed1cfe74..6afc5550 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/$idFolder/updateOneFolder.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const updateOneFolderRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-folder`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/folders/:idFolder`, schemas: { body: v.object({ idFolder: folderSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts index f45afc32..856c685a 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/createOneFolder.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const createOneFolderRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-folder`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/folders`, schemas: { body: v.object({ idFolderParent: v.optional(folderSchema.entries.idFolderParent), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts index 9abcd579..d891d64d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/folders/readAllFolders.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../utilities/routeDefiniti export const readAllFoldersRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-folders`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/folders`, schemas: { body: v.object({}), return: v.array(folderSchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts index 1579ec7b..061330c9 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/readOneYear.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../utilities/routeDefinition. export const readOneYearRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-year`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts index 7800207d..8becee14 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/deleteOneAccount.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const deleteOneAccountRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-account`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/:idAccount`, schemas: { body: v.object({ idAccount: accountSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts index 99638fde..3c1dfbbc 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/readOneAccount.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readOneAccountRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-account`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/:idAccount`, schemas: { body: v.object({ idAccount: accountSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts index b9ca1ebf..ed90c971 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/$idAccount/updateOneAccount.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateOneAccountRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-account`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/:idAccount`, schemas: { body: v.object({ idAccount: accountSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts index fc1ac463..317abf7d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/createOneAccount.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const createOneAccountRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-account`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts`, schemas: { body: v.object({ idYear: accountSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts index b76a13b2..fe79d867 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/generateAccounts.ts @@ -1,4 +1,3 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" import { booleanSchema } from "../../../../../../../../../components/schemas/booleanSchema.js" @@ -7,7 +6,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateAccountsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-accounts`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/generate`, schemas: { body: v.object({ idYear: accountSchema.entries.idYear, @@ -17,4 +17,3 @@ export const generateAccountsRouteDefinition = routeDefinition({ return: v.array(accountSchemaReturn), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts index cd19b290..6a9acdbd 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/accounts/readAllAccounts.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readAllAccountsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-accounts`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts`, schemas: { body: v.object({ idYear: accountSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts index 73129b7c..512bd043 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/deleteOneBalanceSheet.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const deleteOneBalanceSheetRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-balance-sheet`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/:idBalanceSheet`, schemas: { body: v.object({ idBalanceSheet: balanceSheetSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts index bf5dff56..b01bcfff 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/readOneBalanceSheet.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readOneBalanceSheetRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-balance-sheet`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/:idBalanceSheet`, schemas: { body: v.object({ idBalanceSheet: balanceSheetSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts index 68cfc18e..64b9dfe6 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/$idBalanceSheet/updateOneBalanceSheet.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateOneBalanceSheetRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-balance-sheet`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/:idBalanceSheet`, schemas: { body: v.object({ idBalanceSheet: balanceSheetSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts index ad90b01b..2664645c 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/connectAccountsToBalanceSheets.ts @@ -1,4 +1,3 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" import { incomeStatementSchema } from "../../../../../../../../../schemas/incomeStatement.js" @@ -6,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const connectAccountsToBalanceSheetsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/connect-accounts-to-balance-sheets`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/connect-accounts`, schemas: { body: v.object({ idYear: incomeStatementSchema.entries.idYear, @@ -14,4 +14,3 @@ export const connectAccountsToBalanceSheetsRouteDefinition = routeDefinition({ return: v.object({}), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts index 257f51c1..a5825eba 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/createOneBalanceSheet.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const createOneBalanceSheetRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-balance-sheet`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets`, schemas: { body: v.object({ idYear: balanceSheetSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts index b7611c0c..abce8a80 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/generateBalanceSheets.ts @@ -1,4 +1,3 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" import { balanceSheetSchema, balanceSheetSchemaReturn } from "../../../../../../../../../schemas/balanceSheet.js" @@ -6,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateBalanceSheetsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-balance-sheets`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/generate`, schemas: { body: v.object({ idYear: balanceSheetSchema.entries.idYear, @@ -14,4 +14,3 @@ export const generateBalanceSheetsRouteDefinition = routeDefinition({ return: v.array(balanceSheetSchemaReturn), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts index 810c24ca..9bd5b495 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/balanceSheets/readAllBalanceSheets.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readAllBalanceSheetsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-balance-sheets`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets`, schemas: { body: v.object({ idYear: balanceSheetSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts index 437c2eca..8f6869ca 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/deleteOneComputationIncomeStatement.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../../../utilities/r export const deleteOneComputationIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-computation-income-statement`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements/:idComputationIncomeStatement`, schemas: { body: v.object({ idComputationIncomeStatement: computationIncomeStatementSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts index 2f63ae00..47ac74a8 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/readOneComputationIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../../../utilities/r export const readOneComputationIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-computation-income-statement`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements/:idComputationIncomeStatement`, schemas: { body: v.object({ idComputationIncomeStatement: computationIncomeStatementSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts index 45111246..0fce6280 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/$idComputationIncomeStatement/updateOneComputationIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../../../utilities/r export const updateOneComputationIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-computation-income-statement`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements/:idComputationIncomeStatement`, schemas: { body: v.object({ idComputationIncomeStatement: computationIncomeStatementSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts index 9ba64a42..04956bf9 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/createOneComputationIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../../utilities/rout export const createOneComputationIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-computation-income-statement`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements`, schemas: { body: v.object({ idYear: computationIncomeStatementSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts index 1438848e..2c3d670f 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/computationIncomeStatements/readAllComputationIncomeStatements.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../../utilities/rout export const readAllComputationIncomeStatementsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-computation-income-statements`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements`, schemas: { body: v.object({ idYear: computationIncomeStatementSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts index d9a67317..2c7bf41f 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/deleteOneComputation.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const deleteOneComputationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-computation`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation`, schemas: { body: v.object({ idComputation: computationSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts index b4024a0a..d0af7e4b 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/readOneComputation.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readOneComputationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-computation`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation`, schemas: { body: v.object({ idComputation: computationSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts index bba04783..7daa815d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/$idComputation/updateOneComputation.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateOneComputationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-computation`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation`, schemas: { body: v.object({ idComputation: computationSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts index d4f466e0..41332a15 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/createOneComputation.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const createOneComputationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-computation`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations`, schemas: { body: v.object({ idYear: computationSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts index a4d08704..d47284f2 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/generateComputations.ts @@ -1,4 +1,3 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" import { computationSchema, computationSchemaReturn } from "../../../../../../../../../schemas/computation.js" @@ -6,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateComputationsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-computations`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/generate`, schemas: { body: v.object({ idYear: computationSchema.entries.idYear, @@ -14,4 +14,3 @@ export const generateComputationsRouteDefinition = routeDefinition({ return: v.array(computationSchemaReturn), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts index 45344a08..88abf6e7 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/computations/readAllComputations.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readAllComputationsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-computations`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/computations`, schemas: { body: v.object({ idYear: computationSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts index 133de514..7562b951 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/closeYear.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const closeYearRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/close-year`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/close`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts index 5b8ebc5e..af23220d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/deleteOneYear.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const deleteOneYearRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-year`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts index a431f48a..dd3d4b01 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/openYear.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const openYearRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/open-year`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/open`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts index 4ec1a110..b476e184 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleBalanceSheet.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const settleBalanceSheetRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/settle-balance-sheet`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/settle-balance-sheet`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts index 6594c69b..f6ee3729 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/settleIncomeStatement.ts @@ -7,7 +7,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const settleIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/settle-income-statement`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/settle-income-statement`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts index 5f62155c..fec23514 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/general/updateOneYear.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const updateOneYearRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-year`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear`, schemas: { body: v.object({ idYear: yearSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts index 0854de2c..1370da2c 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/deleteOneIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const deleteOneIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-income-statement`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/:idIncomeStatement`, schemas: { body: v.object({ idIncomeStatement: incomeStatementSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts index 4be747a9..66943c1b 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/readOneIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readOneIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-income-statement`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/:idIncomeStatement`, schemas: { body: v.object({ idIncomeStatement: incomeStatementSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts index ee5de726..f9b06037 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/$idIncomeStatement/updateOneIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateOneIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-income-statement`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/:idIncomeStatement`, schemas: { body: v.object({ idIncomeStatement: incomeStatementSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts index 175686f5..bc2e956f 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/connectAccountsToIncomeStatements.ts @@ -1,4 +1,3 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" import { incomeStatementSchema } from "../../../../../../../../../schemas/incomeStatement.js" @@ -6,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const connectAccountsToIncomeStatementsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/connect-accounts-to-income-statements`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/connect-accounts`, schemas: { body: v.object({ idYear: incomeStatementSchema.entries.idYear, @@ -14,4 +14,3 @@ export const connectAccountsToIncomeStatementsRouteDefinition = routeDefinition( return: v.object({}), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts index 46163923..01d56e01 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/createOneIncomeStatement.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const createOneIncomeStatementRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-income-statement`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements`, schemas: { body: v.object({ idYear: incomeStatementSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts index 1842fd2e..9717b26d 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/generateIncomeStatements.ts @@ -1,12 +1,15 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" -import { incomeStatementSchema, incomeStatementSchemaReturn } from "../../../../../../../../../schemas/incomeStatement.js" +import { + incomeStatementSchema, + incomeStatementSchemaReturn, +} from "../../../../../../../../../schemas/incomeStatement.js" import { routeDefinition } from "../../../../../../../../../utilities/routeDefinition.js" export const generateIncomeStatementsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-income-statements`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/generate`, schemas: { body: v.object({ idYear: incomeStatementSchema.entries.idYear, @@ -14,4 +17,3 @@ export const generateIncomeStatementsRouteDefinition = routeDefinition({ return: v.array(incomeStatementSchemaReturn), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts index 7389c57f..81d455ba 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/incomeStatements/readAllIncomeStatements.ts @@ -8,7 +8,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readAllIncomeStatementsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-income-statements`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements`, schemas: { body: v.object({ idYear: incomeStatementSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts index 145051c0..d710a51a 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/deleteOneJournal.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const deleteOneJournalRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-journal`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/:idJournal`, schemas: { body: v.object({ idJournal: journalSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts index 09e77925..0fea76bb 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/readOneJournal.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readOneJournalRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-journal`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/:idJournal`, schemas: { body: v.object({ idJournal: journalSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts index c8180b62..9ea2b786 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/$idJournal/updateOneJournal.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateOneJournalRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-journal`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/:idJournal`, schemas: { body: v.object({ idJournal: journalSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts index f3b9f009..617734f5 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/createOneJournal.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const createOneJournalRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-journal`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/journals`, schemas: { body: v.object({ idYear: journalSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts index 85a17f7e..01710e72 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/generateJournals.ts @@ -1,4 +1,3 @@ -/* import * as v from "valibot" import { routePath } from "../../../../../../../../../components/index.js" import { journalSchema, journalSchemaReturn } from "../../../../../../../../../schemas/journal.js" @@ -6,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const generateJournalsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/generate-journals`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/generate`, schemas: { body: v.object({ idYear: journalSchema.entries.idYear, @@ -14,4 +14,3 @@ export const generateJournalsRouteDefinition = routeDefinition({ return: v.array(journalSchemaReturn), }, }) -*/ diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts index fddffa20..85e36c61 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/journals/readAllJournals.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readAllJournalsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-journals`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/journals`, schemas: { body: v.object({ idYear: journalSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts index 3fb0a22e..fd9393d1 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/deleteOneTag.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const deleteOneTagRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-one-tag`, + method: "DELETE", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/tags/:idTag`, schemas: { body: v.object({ idTag: tagSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts index 58440703..0154a9ba 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/readOneTag.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const readOneTagRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-tag`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/tags/:idTag`, schemas: { body: v.object({ idTag: tagSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts index 395e7bb2..7b2f0d46 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/$idTag/updateOneTag.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../../utilities/routeDe export const updateOneTagRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-tag`, + method: "PATCH", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/tags/:idTag`, schemas: { body: v.object({ idTag: tagSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts index bbb873c6..a0221ef0 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/createOneTag.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const createOneTagRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-tag`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/tags`, schemas: { body: v.object({ idYear: tagSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts index eca7e036..744b45aa 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/$idYear/yearSettings/tags/readAllTags.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../../../../utilities/routeDefin export const readAllTagsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-tags`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years/:idYear/tags`, schemas: { body: v.object({ idYear: tagSchema.entries.idYear, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/createOneYear.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/createOneYear.ts index 60ffed67..c4ab4add 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/createOneYear.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/createOneYear.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../utilities/routeDefinition.js" export const createOneYearRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-year`, + method: "POST", + path: `${routePath.v1}/organizations/:idOrganization/years`, schemas: { body: v.object({ idYearPrevious: v.optional(yearSchema.entries.idYearPrevious), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts index 97210379..bd73c4a2 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/$idOrganization/years/readAllYears.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../../../utilities/routeDefinition.js" export const readAllYearsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-years`, + method: "GET", + path: `${routePath.v1}/organizations/:idOrganization/years`, schemas: { body: v.object({ idOrganization: v.optional(v.string()), diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/activateOrganizationMembership.ts b/packages/metadata/src/routes/dashboard/auth/organizations/activateOrganizationMembership.ts index e1cd61c9..5926ac6e 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/activateOrganizationMembership.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/activateOrganizationMembership.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const activateOrganizationMembershipRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/activate-organization-membership`, + method: "POST", + path: `${routePath.v1}/organizations/activate-membership`, schemas: { body: v.object({ idOrganizationUser: organizationUserSchema.entries.id, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/addNewOrganization.ts b/packages/metadata/src/routes/dashboard/auth/organizations/addNewOrganization.ts index 249e8b06..335ad1a1 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/addNewOrganization.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/addNewOrganization.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const addNewOrganizationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/add-new-organization`, + method: "POST", + path: `${routePath.v1}/organizations`, schemas: { body: v.object({ scope: organizationSchema.entries.scope, diff --git a/packages/metadata/src/routes/dashboard/auth/organizations/getAllMyOrganizations.ts b/packages/metadata/src/routes/dashboard/auth/organizations/getAllMyOrganizations.ts index 0f0f4315..9d59793f 100644 --- a/packages/metadata/src/routes/dashboard/auth/organizations/getAllMyOrganizations.ts +++ b/packages/metadata/src/routes/dashboard/auth/organizations/getAllMyOrganizations.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const getAllMyOrganizationsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/get-all-my-organization`, + method: "GET", + path: `${routePath.v1}/organizations`, schemas: { body: v.object({}), return: v.array( diff --git a/packages/metadata/src/routes/dashboard/auth/settings/activateUser.ts b/packages/metadata/src/routes/dashboard/auth/settings/activateUser.ts index 1bdd702c..d2633771 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/activateUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/activateUser.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const activateUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/activate-user`, + method: "POST", + path: `${routePath.v1}/users/me/activate`, schemas: { body: v.object({ emailToken: v.nonNullable(userSchema.entries.emailToken), diff --git a/packages/metadata/src/routes/dashboard/auth/settings/deleteUser.ts b/packages/metadata/src/routes/dashboard/auth/settings/deleteUser.ts index 552c8cbd..4276c68c 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/deleteUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/deleteUser.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const deleteUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/delete-user`, + method: "DELETE", + path: `${routePath.v1}/users/me`, schemas: { body: v.object({ currentPassword: v.nonNullable(stringSchema, "Le mot de passe doit être renseigné"), diff --git a/packages/metadata/src/routes/dashboard/auth/settings/readUserSession.ts b/packages/metadata/src/routes/dashboard/auth/settings/readUserSession.ts index 73c491c2..257d29b3 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/readUserSession.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/readUserSession.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const readUserSessionRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-user-session`, + method: "GET", + path: `${routePath.v1}/users/me`, schemas: { body: v.object({}), return: v.object({ diff --git a/packages/metadata/src/routes/dashboard/auth/settings/resendEmailValidation.ts b/packages/metadata/src/routes/dashboard/auth/settings/resendEmailValidation.ts index feef7019..0a83a49c 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/resendEmailValidation.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/resendEmailValidation.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const resendEmailValidationRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/resend-email-validation`, + method: "POST", + path: `${routePath.v1}/users/me/email/resend-validation`, schemas: { body: v.object({}), return: userSchemaReturn, diff --git a/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts b/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts index e6eb4a9f..06822c12 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/updateUser.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const updateUserRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-user`, + method: "PATCH", + path: `${routePath.v1}/users/me`, schemas: { body: v.object({ alias: v.optional(userSchema.entries.alias), diff --git a/packages/metadata/src/routes/dashboard/auth/settings/updateUserEmail.ts b/packages/metadata/src/routes/dashboard/auth/settings/updateUserEmail.ts index 03da76d4..cebe85ad 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/updateUserEmail.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/updateUserEmail.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const updateUserEmailRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-user-email`, + method: "PATCH", + path: `${routePath.v1}/users/me/email`, schemas: { body: v.object({ currentPassword: v.nonNullable(stringSchema, "Le mot de passe doit être renseigné"), diff --git a/packages/metadata/src/routes/dashboard/auth/settings/updateUserPassword.ts b/packages/metadata/src/routes/dashboard/auth/settings/updateUserPassword.ts index 10ad01c1..55269d3a 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/updateUserPassword.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/updateUserPassword.ts @@ -7,7 +7,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const updateUserPasswordRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-user-password`, + method: "PATCH", + path: `${routePath.v1}/users/me/password`, schemas: { body: v.object({ currentPassword: v.nonNullable(stringSchema, "Le mot de passe actuel doit être renseigné"), diff --git a/packages/metadata/src/routes/dashboard/auth/settings/validateUserEmail.ts b/packages/metadata/src/routes/dashboard/auth/settings/validateUserEmail.ts index 8959edcf..ba2c7c79 100644 --- a/packages/metadata/src/routes/dashboard/auth/settings/validateUserEmail.ts +++ b/packages/metadata/src/routes/dashboard/auth/settings/validateUserEmail.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const validateUserEmailRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/validate-user-email`, + method: "POST", + path: `${routePath.v1}/users/me/email/validate`, schemas: { body: v.object({ emailToken: v.nonNullable(userSchema.entries.emailToken), diff --git a/packages/metadata/src/routes/dashboard/auth/support/createOneTicket.ts b/packages/metadata/src/routes/dashboard/auth/support/createOneTicket.ts index 7f80cc8c..9cb3cb57 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/createOneTicket.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/createOneTicket.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const createOneTicketRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-ticket`, + method: "POST", + path: `${routePath.v1}/support/tickets`, schemas: { body: v.object({ category: v.picklist(ticketType, "Valeur invalide"), diff --git a/packages/metadata/src/routes/dashboard/auth/support/createOneTicketMessage.ts b/packages/metadata/src/routes/dashboard/auth/support/createOneTicketMessage.ts index 64b9d9cd..cbf4f272 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/createOneTicketMessage.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/createOneTicketMessage.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const createOneTicketMessageRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/create-one-ticket-message`, + method: "POST", + path: `${routePath.v1}/support/tickets/:idTicket/messages`, schemas: { body: v.object({ idTicket: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/support/readAllTicketMessages.ts b/packages/metadata/src/routes/dashboard/auth/support/readAllTicketMessages.ts index b877616c..2b326d56 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/readAllTicketMessages.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/readAllTicketMessages.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const readAllTicketMessagesRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-ticket-messages`, + method: "GET", + path: `${routePath.v1}/support/tickets/:idTicket/messages`, schemas: { body: v.object({ idTicket: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/support/readAllTickets.ts b/packages/metadata/src/routes/dashboard/auth/support/readAllTickets.ts index 61ee9062..a0a49f8d 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/readAllTickets.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/readAllTickets.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const readAllTicketsRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-all-tickets`, + method: "GET", + path: `${routePath.v1}/support/tickets`, schemas: { body: v.object({}), return: v.array(ticketSchemaReturn), diff --git a/packages/metadata/src/routes/dashboard/auth/support/readOneTicket.ts b/packages/metadata/src/routes/dashboard/auth/support/readOneTicket.ts index 6c7d03e9..13cd98e3 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/readOneTicket.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/readOneTicket.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const readOneTicketRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/read-one-ticket`, + method: "GET", + path: `${routePath.v1}/support/tickets/:idTicket`, schemas: { body: v.object({ idTicket: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/support/updateOneTicket.ts b/packages/metadata/src/routes/dashboard/auth/support/updateOneTicket.ts index 853ccb11..abb9abb0 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/updateOneTicket.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/updateOneTicket.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const updateOneTicketRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-ticket`, + method: "PATCH", + path: `${routePath.v1}/support/tickets/:idTicket`, schemas: { body: v.object({ idTicket: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/auth/support/updateOneTicketStatus.ts b/packages/metadata/src/routes/dashboard/auth/support/updateOneTicketStatus.ts index 727bf20d..0eb37279 100644 --- a/packages/metadata/src/routes/dashboard/auth/support/updateOneTicketStatus.ts +++ b/packages/metadata/src/routes/dashboard/auth/support/updateOneTicketStatus.ts @@ -6,7 +6,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const updateOneTicketStatusRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.auth}/update-one-ticket-status`, + method: "PATCH", + path: `${routePath.v1}/support/tickets/:idTicket/status`, schemas: { body: v.object({ idTicket: v.nonNullable(idSchema, "Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/public/mollieWebhook.ts b/packages/metadata/src/routes/dashboard/public/mollieWebhook.ts index da004143..b1b95d59 100644 --- a/packages/metadata/src/routes/dashboard/public/mollieWebhook.ts +++ b/packages/metadata/src/routes/dashboard/public/mollieWebhook.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../utilities/routeDefinition.js" export const mollieWebhookRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.public}/mollie-webhook`, + method: "POST", + path: `${routePath.v1}/webhooks/mollie`, schemas: { body: v.object({ id: v.string("Ce champ est requis"), diff --git a/packages/metadata/src/routes/dashboard/public/user/resetPassword.ts b/packages/metadata/src/routes/dashboard/public/user/resetPassword.ts index 5c90d14a..4d9d4415 100644 --- a/packages/metadata/src/routes/dashboard/public/user/resetPassword.ts +++ b/packages/metadata/src/routes/dashboard/public/user/resetPassword.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const resetPasswordRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.public}/reset-password`, + method: "POST", + path: `${routePath.v1}/auth/reset-password`, schemas: { body: v.object({ email: v.nonNullable(userSchema.entries.email), diff --git a/packages/metadata/src/routes/dashboard/public/user/sendMagicLink.ts b/packages/metadata/src/routes/dashboard/public/user/sendMagicLink.ts index 89d68b7e..9ad0edba 100644 --- a/packages/metadata/src/routes/dashboard/public/user/sendMagicLink.ts +++ b/packages/metadata/src/routes/dashboard/public/user/sendMagicLink.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const sendMagicLinkRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.public}/send-magic-link`, + method: "POST", + path: `${routePath.v1}/auth/magic-link`, schemas: { body: v.object({ email: v.nonNullable(userSchema.entries.email), diff --git a/packages/metadata/src/routes/dashboard/public/user/signIn.ts b/packages/metadata/src/routes/dashboard/public/user/signIn.ts index b3538c95..fc6108f7 100644 --- a/packages/metadata/src/routes/dashboard/public/user/signIn.ts +++ b/packages/metadata/src/routes/dashboard/public/user/signIn.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const signInRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.public}/sign-in`, + method: "POST", + path: `${routePath.v1}/auth/sign-in`, schemas: { body: v.object({ email: userSchema.entries.email, diff --git a/packages/metadata/src/routes/dashboard/public/user/signOut.ts b/packages/metadata/src/routes/dashboard/public/user/signOut.ts index f7148565..95959012 100644 --- a/packages/metadata/src/routes/dashboard/public/user/signOut.ts +++ b/packages/metadata/src/routes/dashboard/public/user/signOut.ts @@ -4,7 +4,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const signOutRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.public}/sign-out`, + method: "POST", + path: `${routePath.v1}/auth/sign-out`, schemas: { body: v.object({}), return: v.object({}), diff --git a/packages/metadata/src/routes/dashboard/public/user/signUp.ts b/packages/metadata/src/routes/dashboard/public/user/signUp.ts index 47cc961d..87a746f0 100644 --- a/packages/metadata/src/routes/dashboard/public/user/signUp.ts +++ b/packages/metadata/src/routes/dashboard/public/user/signUp.ts @@ -5,7 +5,8 @@ import { routeDefinition } from "../../../../utilities/routeDefinition.js" export const signUpRouteDefinition = routeDefinition({ protocol: "http", - path: `${routePath.public}/sign-up`, + method: "POST", + path: `${routePath.v1}/auth/sign-up`, schemas: { body: v.object({ email: userSchema.entries.email, diff --git a/packages/metadata/src/utilities/routeDefinition.ts b/packages/metadata/src/utilities/routeDefinition.ts index f52e2568..05072f69 100644 --- a/packages/metadata/src/utilities/routeDefinition.ts +++ b/packages/metadata/src/utilities/routeDefinition.ts @@ -8,6 +8,11 @@ export function routeDefinition< | v.ArraySchema, undefined>, >(parameters: { protocol: "http" | "ws" + /** + * HTTP method for this route. Defaults to "POST" for backward compatibility. + * Use "GET" for read operations, "PATCH" for updates, "DELETE" for deletions. + */ + method?: "GET" | "POST" | "PATCH" | "DELETE" path: TPath schemas: { body: TSchemaBody @@ -15,6 +20,7 @@ export function routeDefinition< } }) { return { + method: (parameters.method ?? "POST") as "GET" | "POST" | "PATCH" | "DELETE", path: parameters.path, schemas: parameters.schemas, } diff --git a/packages/ui/src/components/overlays/popover/popoverRoot.tsx b/packages/ui/src/components/overlays/popover/popoverRoot.tsx index 36b2b9a4..24630e32 100644 --- a/packages/ui/src/components/overlays/popover/popoverRoot.tsx +++ b/packages/ui/src/components/overlays/popover/popoverRoot.tsx @@ -3,6 +3,7 @@ import { type Dispatch, type ReactNode, type SetStateAction, + useCallback, useContext, useEffect, useId, @@ -51,11 +52,18 @@ export function PopoverRoot(props: { const isOpen = isControlled ? (props.open ?? false) : localOpen - const setOpen: Dispatch> = (valueOrUpdater) => { - const next = typeof valueOrUpdater === "function" ? valueOrUpdater(isOpen) : valueOrUpdater - if (!isControlled) setLocalOpen(next) - props.onOpenChange?.(next) - } + const setOpen: Dispatch> = useCallback( + (valueOrUpdater) => { + const next = typeof valueOrUpdater === "function" ? valueOrUpdater(isOpen) : valueOrUpdater + if (!isControlled) setLocalOpen(next) + props.onOpenChange?.(next) + }, + [ + isControlled, + isOpen, + props.onOpenChange, + ], + ) const store = usePopoverStore() @@ -65,6 +73,9 @@ export function PopoverRoot(props: { // eslint-disable-next-line react-hooks/exhaustive-deps }, [ id, + store.unregister, + store.register, + setOpen, ]) return ( diff --git a/packages/website/plugins/DOC_PAGE_MANIFEST.ts b/packages/website/plugins/DOC_PAGE_MANIFEST.ts index 011335e3..c644148e 100644 --- a/packages/website/plugins/DOC_PAGE_MANIFEST.ts +++ b/packages/website/plugins/DOC_PAGE_MANIFEST.ts @@ -1,8 +1,3 @@ -import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" -import { dirname, resolve } from "node:path" -import react from "@vitejs/plugin-react" -import { defineConfig, type Plugin, build as viteBuild } from "vite" - // ─────────────────────────── Docs Search Index Plugin ───────────────────────────── interface DocPageManifestEntry { diff --git a/packages/website/src/components/document/DocCode.tsx b/packages/website/src/components/document/DocCode.tsx new file mode 100644 index 00000000..a5260b60 --- /dev/null +++ b/packages/website/src/components/document/DocCode.tsx @@ -0,0 +1,19 @@ +import { css } from "@arrhes/ui/utilities/cn.js" +import type { ReactNode } from "react" + +export function DocCode(props: { children: ReactNode }) { + return ( + + {props.children} + + ) +} diff --git a/packages/website/src/components/document/DocCodeBlock.tsx b/packages/website/src/components/document/DocCodeBlock.tsx new file mode 100644 index 00000000..da0293e5 --- /dev/null +++ b/packages/website/src/components/document/DocCodeBlock.tsx @@ -0,0 +1,88 @@ +import { css, cx } from "@arrhes/ui/utilities/cn.js" +import { IconCheck, IconCopy } from "@tabler/icons-react" +import { useState } from "react" + +export function DocCodeBlock(props: { children: string }) { + const [copied, setCopied] = useState(false) + + function handleCopy() { + void navigator.clipboard.writeText(props.children) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } + + return ( +
+
+                {props.children}
+            
+ +
+ ) +} diff --git a/packages/website/src/components/document/DocNextPage.tsx b/packages/website/src/components/document/DocNextPage.tsx deleted file mode 100644 index 34cc52db..00000000 --- a/packages/website/src/components/document/DocNextPage.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { ButtonOutlineContent } from "@arrhes/ui" -import { css } from "@arrhes/ui/utilities/cn.js" -import { IconChevronRight } from "@tabler/icons-react" -import type { ValidParams, ValidRoutes } from "../../routes/applicationRouter.js" -import { LinkButton } from "../LinkButton.js" - -export function DocNextPage(props: { to: ValidRoutes; params?: ValidParams; label: string; description?: string }) { - return ( -
- - Page suivante - - {props.description && ( -

- {props.description} -

- )} - - } - /> - -
- ) -} diff --git a/packages/website/src/components/document/DocRouteRequest.tsx b/packages/website/src/components/document/DocRouteRequest.tsx index 64b1a46a..3c9136cb 100644 --- a/packages/website/src/components/document/DocRouteRequest.tsx +++ b/packages/website/src/components/document/DocRouteRequest.tsx @@ -2,6 +2,53 @@ import type { routeDefinition } from "@arrhes/application-metadata/utilities" import { css } from "@arrhes/ui/utilities/cn.js" import { useState } from "react" +const methodBadgeClassName: Record<"GET" | "POST" | "PATCH" | "DELETE", string> = { + GET: css({ + fontSize: "xs", + fontWeight: "bold", + paddingX: "0.5rem", + paddingY: "0.15rem", + borderRadius: "sm", + backgroundColor: "information/10", + color: "information", + textTransform: "uppercase", + letterSpacing: "wider", + }), + POST: css({ + fontSize: "xs", + fontWeight: "bold", + paddingX: "0.5rem", + paddingY: "0.15rem", + borderRadius: "sm", + backgroundColor: "success/10", + color: "success", + textTransform: "uppercase", + letterSpacing: "wider", + }), + PATCH: css({ + fontSize: "xs", + fontWeight: "bold", + paddingX: "0.5rem", + paddingY: "0.15rem", + borderRadius: "sm", + backgroundColor: "warning/10", + color: "warning", + textTransform: "uppercase", + letterSpacing: "wider", + }), + DELETE: css({ + fontSize: "xs", + fontWeight: "bold", + paddingX: "0.5rem", + paddingY: "0.15rem", + borderRadius: "sm", + backgroundColor: "error/10", + color: "error", + textTransform: "uppercase", + letterSpacing: "wider", + }), +} + type SchemaLike = { type: string entries?: Readonly> @@ -253,20 +300,8 @@ export function DocRouteRequest(props: { routeDefinition: ReturnType - - POST + + {props.routeDefinition.method} - {props.routeDefinition.path} + {props.routeDefinition.path.replace(/^\/v1/, "")}
diff --git a/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx b/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx index 23892d36..f5135643 100644 --- a/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx +++ b/packages/website/src/features/dashboard/$idYear/YearDataWrapper.tsx @@ -61,6 +61,7 @@ export type YearDataMaps = { } type YearScopedRouteDefinition = { + method: "GET" | "POST" | "PATCH" | "DELETE" path: string schemas: { body: v.ObjectSchema diff --git a/packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx b/packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx index 7847527c..1052381a 100644 --- a/packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx +++ b/packages/website/src/features/dashboard/$idYear/entries/ExportFecFile.tsx @@ -1,63 +1,15 @@ import { - readAllAccountsRouteDefinition, + generateFecRouteDefinition, type readAllEntriesRouteDefinition, type readAllEntryLinesRouteDefinition, - readAllJournalsRouteDefinition, - readOneOrganizationRouteDefinition, } from "@arrhes/application-metadata/routes" import type { returnedSchemas } from "@arrhes/application-metadata/schemas" -import { Button, ButtonPlainContent, LinkContent, toast } from "@arrhes/ui" +import { Button, ButtonPlainContent, toast } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconFileExport } from "@tabler/icons-react" -import { useEffect, useMemo, useState } from "react" import type * as v from "valibot" -import { Banner } from "../../../../components/layouts/Banner.js" -import { useTabs } from "../../../../contexts/tabs/useTabs.js" - import { getResponseBodyFromAPI } from "../../../../utilities/getResponseBodyFromAPI.js" -/** - * Format a date string as YYYYMMDD for FEC compliance. - */ -function formatFecDate(rawDate: string | Date): string { - const date = new Date(rawDate) - const year = date.getFullYear() - const month = String(date.getMonth() + 1).padStart(2, "0") - const day = String(date.getDate()).padStart(2, "0") - return `${year}${month}${day}` -} - -/** - * Format a numeric amount for FEC: comma as decimal separator, no thousands separator, 2 decimals. - * e.g. 1234.5 -> "1234,50" - */ -function formatFecAmount(value: number | string): string { - const num = Number(value) - const abs = Math.abs(num) < 0.009 ? 0 : num - return abs.toFixed(2).replace(".", ",") -} - -const FEC_HEADERS = [ - "JournalCode", - "JournalLib", - "EcritureNum", - "EcritureDate", - "CompteNum", - "CompteLib", - "CompAuxNum", - "CompAuxLib", - "PieceRef", - "PieceDate", - "EcritureLib", - "Debit", - "Credit", - "EcritureLet", - "DateLet", - "ValidDate", - "Montantdevise", - "Idevise", -] as const - export function ExportFecFile(props: { idOrganization: v.InferOutput["id"] idYear: v.InferOutput["id"] @@ -65,35 +17,6 @@ export function ExportFecFile(props: { entryLines: v.InferOutput onClose: () => void }) { - const [siren, setSiren] = useState(null) - const { openTab } = useTabs() - - useEffect(() => { - getResponseBodyFromAPI({ - routeDefinition: readOneOrganizationRouteDefinition, - body: { - idOrganization: props.idOrganization, - }, - }).then((response) => { - if (response.ok) { - setSiren(response.data.siren ?? "") - } - }) - }, [ - props.idOrganization, - ]) - - const entriesMap = useMemo(() => { - return new Map( - props.entries.map((r) => [ - r.id, - r, - ]), - ) - }, [ - props.entries, - ]) - async function handleExport() { if (props.entryLines.length === 0) { toast({ @@ -103,139 +26,27 @@ export function ExportFecFile(props: { return } - const [accountsResponse, journalsResponse] = await Promise.all([ - getResponseBodyFromAPI({ - routeDefinition: readAllAccountsRouteDefinition, - body: { - idYear: props.idYear, - }, - }), - getResponseBodyFromAPI({ - routeDefinition: readAllJournalsRouteDefinition, - body: { - idYear: props.idYear, - }, - }), - ]) + const result = await getResponseBodyFromAPI({ + routeDefinition: generateFecRouteDefinition, + body: { + idYear: props.idYear, + }, + }) - if (!accountsResponse.ok || !journalsResponse.ok) { + if (!result.ok) { toast({ - title: "Impossible de charger les données", + title: "Erreur lors de la génération du FEC", variant: "error", }) return } - const accountsMap = new Map( - accountsResponse.data.map((a) => [ - a.id, - { - number: a.number, - label: a.label, - }, - ]), - ) - const journalsMap = new Map( - journalsResponse.data.map((j) => [ - j.id, - { - code: j.code, - label: j.label, - }, - ]), - ) - - // Build a sequential EcritureNum per entry, sorted by date then id - const sortedEntries = [ - ...props.entries, - ].sort((a, b) => { - const dateCompare = a.date.localeCompare(b.date) - if (dateCompare !== 0) return dateCompare - return a.id.localeCompare(b.id) - }) - const ecritureNumMap = new Map() - for (let i = 0; i < sortedEntries.length; i++) { - ecritureNumMap.set(sortedEntries[i].id, String(i + 1)) - } - - // Build rows sorted by entry date, then EcritureNum, then row order - const sortedRows = [ - ...props.entryLines, - ].sort((a, b) => { - const entryA = entriesMap.get(a.idEntry) - const entryB = entriesMap.get(b.idEntry) - if (!entryA || !entryB) return 0 - const dateCompare = entryA.date.localeCompare(entryB.date) - if (dateCompare !== 0) return dateCompare - const numCompare = (ecritureNumMap.get(a.idEntry) ?? "").localeCompare( - ecritureNumMap.get(b.idEntry) ?? "", - undefined, - { - numeric: true, - }, - ) - if (numCompare !== 0) return numCompare - return a.id.localeCompare(b.id) - }) - - const rows = sortedRows - .map((row) => { - const entry = entriesMap.get(row.idEntry) - if (!entry) return null - - const account = accountsMap.get(row.idAccount) - const journal = entry.idJournal ? journalsMap.get(entry.idJournal) : null - - const ecritureDate = formatFecDate(entry.date) - const pieceDate = formatFecDate(entry.date) - const validDate = formatFecDate(entry.createdAt) - - return [ - journal?.code ?? "", - journal?.label ?? "", - ecritureNumMap.get(entry.id) ?? "", - ecritureDate, - account?.number ?? "", - account?.label ?? "", - "", // CompAuxNum - not supported - "", // CompAuxLib - not supported - entry.label, // PieceRef - pieceDate, - row.label ?? entry.label, // EcritureLib - formatFecAmount(row.debit), - formatFecAmount(row.credit), - "", // EcritureLet - not supported - "", // DateLet - not supported - validDate, - "", // Montantdevise - "", // Idevise - ].join("\t") - }) - .filter((row) => row !== null) - - const fecContent = [ - FEC_HEADERS.join("\t"), - ...rows, - ].join("\n") - - const BOM = "\uFEFF" - const blob = new Blob( - [ - BOM + fecContent, - ], - { - type: "text/plain;charset=utf-8;", - }, - ) - const url = URL.createObjectURL(blob) const link = document.createElement("a") - link.href = url - link.download = `${siren ?? ""}FEC${formatFecDate(new Date())}.txt` + link.href = result.data.url link.click() - URL.revokeObjectURL(url) toast({ - title: `${sortedRows.length} mouvements exportés au format FEC`, + title: `${props.entryLines.length} mouvement${props.entryLines.length > 1 ? "s" : ""} exporté${props.entryLines.length > 1 ? "s" : ""} au format FEC`, variant: "success", }) props.onClose() @@ -289,32 +100,6 @@ export function ExportFecFile(props: { .

- {siren === "" && ( - - Le numéro SIREN de l'organisation n'est pas renseigné. Le nom du fichier FEC ne sera pas conforme. - Vous pouvez l'ajouter dans les{" "} - - . - - )}

diff --git a/packages/website/src/features/docs/DocsLayout.tsx b/packages/website/src/features/docs/DocsLayout.tsx index 52b7995b..9824ad38 100644 --- a/packages/website/src/features/docs/DocsLayout.tsx +++ b/packages/website/src/features/docs/DocsLayout.tsx @@ -15,6 +15,7 @@ function getCurrentSection(pathname: string): DocSectionId { if (pathname.startsWith("/documentation/comptabilité")) return "comptabilite" if (pathname.startsWith("/documentation/dashboard")) return "dashboard" if (pathname.startsWith("/documentation/api")) return "api" + if (pathname.startsWith("/documentation/cli")) return "cli" return "general" } diff --git a/packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx index b5a0dbf7..afdd50f7 100644 --- a/packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/introduction/AccountsAccountingDocPage.tsx @@ -4,7 +4,6 @@ import { DocExample } from "../../../../components/document/DocExample.js" import { DocHeader } from "../../../../components/document/DocHeader.js" import { DocLink } from "../../../../components/document/DocLink.js" import { DocList } from "../../../../components/document/DocList.js" -import { DocNextPage } from "../../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../../components/document/DocParagraph.js" import { DocRoot } from "../../../../components/document/DocRoot.js" import { DocSection } from "../../../../components/document/DocSection.js" @@ -417,12 +416,6 @@ export function AccountsAccountingDocPage() { - - - - - - - - - utiliser Arrhes efficacement. - - ) } diff --git a/packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx b/packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx index 48d0f9b6..6ae76069 100644 --- a/packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx +++ b/packages/website/src/features/docs/accounting/reports/BalanceAccountingDocPage.tsx @@ -4,7 +4,6 @@ import { DocExample } from "../../../../components/document/DocExample.js" import { DocHeader } from "../../../../components/document/DocHeader.js" import { DocLink } from "../../../../components/document/DocLink.js" import { DocList } from "../../../../components/document/DocList.js" -import { DocNextPage } from "../../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../../components/document/DocParagraph.js" import { DocRoot } from "../../../../components/document/DocRoot.js" import { DocSection } from "../../../../components/document/DocSection.js" @@ -237,11 +236,6 @@ export function BalanceAccountingDocPage() { - - - - - - - - - - - - - - - - - - ) } diff --git a/packages/website/src/features/docs/ai/OcrAiDocPage.tsx b/packages/website/src/features/docs/ai/OcrAiDocPage.tsx index 9307ac36..b1b39cbb 100644 --- a/packages/website/src/features/docs/ai/OcrAiDocPage.tsx +++ b/packages/website/src/features/docs/ai/OcrAiDocPage.tsx @@ -1,3 +1,4 @@ +import { DocCode } from "../../../components/document/DocCode.tsx" import { DocHeader } from "../../../components/document/DocHeader.tsx" import { DocLink } from "../../../components/document/DocLink.tsx" import { DocList } from "../../../components/document/DocList.tsx" @@ -20,7 +21,8 @@ export function OcrAiDocPage() { PDF) et de créer un nouveau fichier au format Markdown dans votre espace de stockage. - L'OCR est disponible depuis l'interface de stockage et via l'outil assistant ocr_file. + L'OCR est disponible depuis l'interface de stockage et via l'outil assistant{" "} + ocr_file. diff --git a/packages/website/src/features/docs/api/AccountsApiDocPage.tsx b/packages/website/src/features/docs/api/AccountsApiDocPage.tsx new file mode 100644 index 00000000..3c78e827 --- /dev/null +++ b/packages/website/src/features/docs/api/AccountsApiDocPage.tsx @@ -0,0 +1,35 @@ +import { + createOneAccountRouteDefinition, + deleteOneAccountRouteDefinition, + readAllAccountsRouteDefinition, + readOneAccountRouteDefinition, + updateOneAccountRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function AccountsApiDocPage() { + return ( + + + + + + Le plan comptable de l'exercice. Les comptes sont organisés en arborescence avec des classes (1 à 7) + à la racine. + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/ApiKeysApiDocPage.tsx b/packages/website/src/features/docs/api/ApiKeysApiDocPage.tsx new file mode 100644 index 00000000..63fc22d6 --- /dev/null +++ b/packages/website/src/features/docs/api/ApiKeysApiDocPage.tsx @@ -0,0 +1,40 @@ +import { + createOneApiKeyRouteDefinition, + deleteOneApiKeyRouteDefinition, + readAllApiKeysRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocCode } from "../../../components/document/DocCode.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" + +export function ApiKeysApiDocPage() { + return ( + + + + + + Les clés API permettent un accès programmatique sans passer par le cookie de session. Chaque clé est + liée à une organisation et nécessite un abonnement premium actif. + + + + + + La clé brute (rawKey) n'est retournée qu'au moment de la création. Conservez-la + précieusement car elle ne pourra pas être récupérée ultérieurement. + + + + ) +} diff --git a/packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx b/packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx index de9f49d1..c3620d33 100644 --- a/packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx +++ b/packages/website/src/features/docs/api/AuthenticationApiDocPage.tsx @@ -1,6 +1,6 @@ +import { DocCode } from "../../../components/document/DocCode.tsx" import { DocHeader } from "../../../components/document/DocHeader.tsx" import { DocList } from "../../../components/document/DocList.tsx" -import { DocNextPage } from "../../../components/document/DocNextPage.tsx" import { DocParagraph } from "../../../components/document/DocParagraph.tsx" import { DocRoot } from "../../../components/document/DocRoot.tsx" import { DocSection } from "../../../components/document/DocSection.tsx" @@ -43,16 +43,17 @@ export function AuthenticationApiDocPage() { - Lors de la connexion via l'interface web, un cookie arrhes_id_user_session (httpOnly) - est automatiquement défini. Ce cookie identifie l'utilisateur pour toutes les requêtes suivantes. + Lors de la connexion via l'interface web, un cookie arrhes_id_user_session{" "} + (httpOnly) est automatiquement défini. Ce cookie identifie l'utilisateur pour toutes les requêtes + suivantes. Avec cette méthode, l'organisation cible doit être spécifiée séparément via l'en-tête{" "} - X-Organization-Id ou le cookie arrhes_id_organization. + X-Organization-Id ou le cookie arrhes_id_organization. - L'en-tête X-Organization-Id a la priorité sur le cookie{" "} - arrhes_id_organization. + L'en-tête X-Organization-Id a la priorité sur le cookie{", "} + arrhes_id_organization. @@ -62,7 +63,7 @@ export function AuthenticationApiDocPage() { spécifique et nécessitent un abonnement premium. - L'en-tête Authorization doit contenir le token au format Bearer : + L'en-tête Authorization doit contenir le token au format Bearer : Avec une clé API, l'organisation est automatiquement déterminée par la clé elle-même. Il n'est pas - nécessaire de fournir l'en-tête X-Organization-Id. + nécessaire de fournir l'en-tête X-Organization-Id. - La clé brute (rawKey) n'est retournée qu'au moment de la création via la route{" "} - POST /auth/create-one-api-key. Conservez-la précieusement, elle ne pourra pas être - récupérée ultérieurement. + La clé brute (rawKey) n'est retournée qu'au moment de la création via la route + {", "} + POST /v1/organizations/:idOrganization/api-keys. Conservez-la précieusement, elle + ne pourra pas être récupérée ultérieurement. @@ -114,8 +116,8 @@ export function AuthenticationApiDocPage() { ]} /> - * L'en-tête X-Organization-Id peut être remplacé par le cookie{" "} - arrhes_id_organization. + * L'en-tête X-Organization-Id peut être remplacé par le cookie{", "} + arrhes_id_organization. @@ -136,11 +138,6 @@ export function AuthenticationApiDocPage() { ]} /> - - ) } diff --git a/packages/website/src/features/docs/api/BalanceSheetsApiDocPage.tsx b/packages/website/src/features/docs/api/BalanceSheetsApiDocPage.tsx new file mode 100644 index 00000000..cad234b3 --- /dev/null +++ b/packages/website/src/features/docs/api/BalanceSheetsApiDocPage.tsx @@ -0,0 +1,35 @@ +import { + createOneBalanceSheetRouteDefinition, + deleteOneBalanceSheetRouteDefinition, + readAllBalanceSheetsRouteDefinition, + readOneBalanceSheetRouteDefinition, + updateOneBalanceSheetRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function BalanceSheetsApiDocPage() { + return ( + + + + + + Structure du bilan comptable (actif et passif). Les lignes de bilan sont liées aux comptes pour + calculer automatiquement les soldes. + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/ComputationsApiDocPage.tsx b/packages/website/src/features/docs/api/ComputationsApiDocPage.tsx new file mode 100644 index 00000000..3c1038ed --- /dev/null +++ b/packages/website/src/features/docs/api/ComputationsApiDocPage.tsx @@ -0,0 +1,52 @@ +import { + createOneComputationIncomeStatementRouteDefinition, + createOneComputationRouteDefinition, + deleteOneComputationIncomeStatementRouteDefinition, + deleteOneComputationRouteDefinition, + readAllComputationIncomeStatementsRouteDefinition, + readAllComputationsRouteDefinition, + readOneComputationIncomeStatementRouteDefinition, + readOneComputationRouteDefinition, + updateOneComputationIncomeStatementRouteDefinition, + updateOneComputationRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function ComputationsApiDocPage() { + return ( + + + + + + Les calculs sont des formules personnalisées qui combinent des lignes de compte de résultat pour + produire des valeurs dérivées (résultat d'exploitation, EBE, etc.). + + + + + + + + + + + Liens entre les calculs et les lignes de compte de résultat. Chaque lien définit si la ligne est + ajoutée ou soustraite dans le calcul. + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/EntriesApiDocPage.tsx b/packages/website/src/features/docs/api/EntriesApiDocPage.tsx new file mode 100644 index 00000000..a270f246 --- /dev/null +++ b/packages/website/src/features/docs/api/EntriesApiDocPage.tsx @@ -0,0 +1,80 @@ +import { + addOneEntryTagRouteDefinition, + computeOneEntryRouteDefinition, + createOneEntryFromTemplateRouteDefinition, + createOneEntryLineRouteDefinition, + createOneEntryRouteDefinition, + deleteOneEntryLineRouteDefinition, + deleteOneEntryRouteDefinition, + duplicateOneEntryRouteDefinition, + readAllEntriesRouteDefinition, + readAllEntryLinesRouteDefinition, + readAllEntryTagsRouteDefinition, + readOneEntryLineRouteDefinition, + readOneEntryRouteDefinition, + removeOneEntryTagRouteDefinition, + reverseOneEntryRouteDefinition, + updateManyEntryLinesRouteDefinition, + updateOneEntryLineRouteDefinition, + updateOneEntryRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function EntriesApiDocPage() { + return ( + + + + + + Les écritures comptables sont les opérations enregistrées dans les journaux. Chaque écriture + contient une ou plusieurs lignes (débit/crédit). + + + + + + + + + + + + + + + + Chaque ligne d'écriture représente un mouvement de débit ou de crédit sur un compte. + + + + + + + + + + + Association de libellés (tags) à une écriture pour la catégoriser. + + + + + ) +} diff --git a/packages/website/src/features/docs/api/EntryLinesApiDocPage.tsx b/packages/website/src/features/docs/api/EntryLinesApiDocPage.tsx new file mode 100644 index 00000000..6355d65c --- /dev/null +++ b/packages/website/src/features/docs/api/EntryLinesApiDocPage.tsx @@ -0,0 +1,47 @@ +import { + addOneEntryTagRouteDefinition, + createOneEntryLineRouteDefinition, + deleteOneEntryLineRouteDefinition, + readAllEntryLinesRouteDefinition, + readOneEntryLineRouteDefinition, + removeOneEntryTagRouteDefinition, + updateManyEntryLinesRouteDefinition, + updateOneEntryLineRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function EntryLinesApiDocPage() { + return ( + + + + + + Chaque ligne d'écriture représente un mouvement de débit ou de crédit sur un compte. + + + + + + + + + + + Association de libellés (tags) à une écriture pour la catégoriser. + + + + + ) +} diff --git a/packages/website/src/features/docs/api/FilesApiDocPage.tsx b/packages/website/src/features/docs/api/FilesApiDocPage.tsx index 012d953d..a2c75209 100644 --- a/packages/website/src/features/docs/api/FilesApiDocPage.tsx +++ b/packages/website/src/features/docs/api/FilesApiDocPage.tsx @@ -3,11 +3,11 @@ import { createOneFolderRouteDefinition, deleteOneFileRouteDefinition, deleteOneFolderRouteDefinition, - generateBalanceSheetXmlRouteDefinition, + finalizeFileUploadRouteDefinition, generateFileDeleteSignedUrlRouteDefinition, generateFileGetSignedUrlRouteDefinition, generateFilePutSignedUrlRouteDefinition, - generateIncomeStatementXmlRouteDefinition, + ocrFileRouteDefinition, readAllFilesRouteDefinition, readAllFoldersRouteDefinition, readOneFileRouteDefinition, @@ -15,6 +15,7 @@ import { updateOneFileRouteDefinition, updateOneFolderRouteDefinition, } from "@arrhes/application-metadata/routes" +import { DocCode } from "../../../components/document/DocCode.tsx" import { DocHeader } from "../../../components/document/DocHeader.tsx" import { DocParagraph } from "../../../components/document/DocParagraph.tsx" import { DocRoot } from "../../../components/document/DocRoot.tsx" @@ -26,8 +27,8 @@ export function FilesApiDocPage() { return ( @@ -52,33 +53,31 @@ export function FilesApiDocPage() { routeDefinition={generateFileDeleteSignedUrlRouteDefinition} description="Générer une URL signée pour supprimer un fichier." /> + + - La taille maximale par fichier est de 50 Mo. Au-delà, l'API retourne une erreur 400. + La taille maximale par fichier est de 50 Mo. Au-delà, l'API retourne une erreur{" "} + 400. - Les dossiers permettent d'organiser les fichiers au sein d'un exercice. + + Les dossiers permettent d'organiser les fichiers au sein d'un exercice. Ils supportent une + hiérarchie imbriquée via le champ idFolderParent. + - - - - Génération de rapports comptables en XBRL (taxonomie ANC française) : bilans et comptes de résultat. - - - - ) } diff --git a/packages/website/src/features/docs/api/FoldersApiDocPage.tsx b/packages/website/src/features/docs/api/FoldersApiDocPage.tsx new file mode 100644 index 00000000..fb92b4e3 --- /dev/null +++ b/packages/website/src/features/docs/api/FoldersApiDocPage.tsx @@ -0,0 +1,36 @@ +import { + createOneFolderRouteDefinition, + deleteOneFolderRouteDefinition, + readAllFoldersRouteDefinition, + readOneFolderRouteDefinition, + updateOneFolderRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocCode } from "../../../components/document/DocCode.tsx" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function FoldersApiDocPage() { + return ( + + + + + + Les dossiers permettent d'organiser les fichiers au sein d'un exercice. Ils supportent une + hiérarchie imbriquée via le champ idFolderParent. + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/IncomeStatementsApiDocPage.tsx b/packages/website/src/features/docs/api/IncomeStatementsApiDocPage.tsx new file mode 100644 index 00000000..c97a2021 --- /dev/null +++ b/packages/website/src/features/docs/api/IncomeStatementsApiDocPage.tsx @@ -0,0 +1,69 @@ +import { + createOneComputationIncomeStatementRouteDefinition, + createOneComputationRouteDefinition, + createOneIncomeStatementRouteDefinition, + deleteOneComputationIncomeStatementRouteDefinition, + deleteOneComputationRouteDefinition, + deleteOneIncomeStatementRouteDefinition, + readAllComputationIncomeStatementsRouteDefinition, + readAllComputationsRouteDefinition, + readAllIncomeStatementsRouteDefinition, + readOneComputationIncomeStatementRouteDefinition, + readOneComputationRouteDefinition, + readOneIncomeStatementRouteDefinition, + updateOneComputationIncomeStatementRouteDefinition, + updateOneComputationRouteDefinition, + updateOneIncomeStatementRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function IncomeStatementsApiDocPage() { + return ( + + + + + + Structure du compte de résultat (produits et charges). Fonctionne de manière similaire aux bilans : + les lignes sont liées aux comptes pour le calcul automatique des soldes. + + + + + + + + + + + Les calculs sont des formules personnalisées qui combinent des lignes de compte de résultat pour + produire des valeurs dérivées (résultat d'exploitation, EBE, etc.). + + + + + + + + + + + Liens entre les calculs et les lignes de compte de résultat. Chaque lien définit si la ligne est + ajoutée ou soustraite dans le calcul. + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/IntroductionApiDocPage.tsx b/packages/website/src/features/docs/api/IntroductionApiDocPage.tsx index 4ff5128f..f9d551cd 100644 --- a/packages/website/src/features/docs/api/IntroductionApiDocPage.tsx +++ b/packages/website/src/features/docs/api/IntroductionApiDocPage.tsx @@ -1,7 +1,7 @@ +import { DocCode } from "../../../components/document/DocCode.tsx" import { DocHeader } from "../../../components/document/DocHeader.tsx" import { DocLink } from "../../../components/document/DocLink.tsx" import { DocList } from "../../../components/document/DocList.tsx" -import { DocNextPage } from "../../../components/document/DocNextPage.tsx" import { DocParagraph } from "../../../components/document/DocParagraph.tsx" import { DocRoot } from "../../../components/document/DocRoot.tsx" import { DocSection } from "../../../components/document/DocSection.tsx" @@ -17,19 +17,26 @@ export function IntroductionApiDocPage() { /> - L'API d'Arrhes suit un ensemble de conventions simples et uniformes : + L'API d'Arrhes suit les conventions REST standard : - Les identifiants d'entités (idYear, idEntry, idAccount, etc.) sont passés dans le corps de la - requête. L'organisation est identifiée via le token d'authentification, et non dans le corps de la - requête, ni dans l'URL. + Les identifiants d'entités (idYear, idEntry, idAccount, etc.) sont passés dans les paramètres d'URL + (ex : :idOrganization, :idYear). L'organisation est identifiée + via le token d'authentification ou l'en-tête X-Organization-Id, et non dans le + corps de la requête. + + + Les chemins affichés dans cette documentation n'incluent pas le préfixe de version{" "} + /v1. Utilisez toujours la dernière version du CLI Arrhes pour + bénéficier automatiquement du bon préfixe de version. Si vous appelez l'API directement, préfixez + chaque chemin avec /v1. @@ -95,7 +102,7 @@ export function IntroductionApiDocPage() { - L'API expose 90 routes protégées réparties en 17 catégories. Le tableau ci-dessous résume chaque + L'API expose 110 routes protégées réparties en 19 catégories. Le tableau ci-dessous résume chaque catégorie : - - ) } diff --git a/packages/website/src/features/docs/api/JournalsApiDocPage.tsx b/packages/website/src/features/docs/api/JournalsApiDocPage.tsx new file mode 100644 index 00000000..8b0cd7eb --- /dev/null +++ b/packages/website/src/features/docs/api/JournalsApiDocPage.tsx @@ -0,0 +1,35 @@ +import { + createOneJournalRouteDefinition, + deleteOneJournalRouteDefinition, + readAllJournalsRouteDefinition, + readOneJournalRouteDefinition, + updateOneJournalRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function JournalsApiDocPage() { + return ( + + + + + + Les journaux comptables regroupent les écritures par type d'opération (achats, ventes, trésorerie, + OD, etc.). + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/OrgUsersApiDocPage.tsx b/packages/website/src/features/docs/api/OrgUsersApiDocPage.tsx new file mode 100644 index 00000000..e0056c53 --- /dev/null +++ b/packages/website/src/features/docs/api/OrgUsersApiDocPage.tsx @@ -0,0 +1,42 @@ +import { + activateOrganizationMembershipRouteDefinition, + createOneOrganizationUserRouteDefinition, + deleteOneOrganizationUserRouteDefinition, + readAllOrganizationUsersRouteDefinition, + readOneOrganizationUserRouteDefinition, + updateOneOrganizationUserRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function OrgUsersApiDocPage() { + return ( + + + + + + Invitation, lecture, modification et suppression des membres d'une organisation. + + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/OrganizationApiDocPage.tsx b/packages/website/src/features/docs/api/OrganizationApiDocPage.tsx index c327ee53..d66955d1 100644 --- a/packages/website/src/features/docs/api/OrganizationApiDocPage.tsx +++ b/packages/website/src/features/docs/api/OrganizationApiDocPage.tsx @@ -1,24 +1,9 @@ import { - cancelSubscriptionRouteDefinition, - createFirstPaymentRouteDefinition, - createOneApiKeyRouteDefinition, - createOneOrganizationUserRouteDefinition, - createOneYearRouteDefinition, - deleteOneApiKeyRouteDefinition, deleteOneOrganizationRouteDefinition, - deleteOneOrganizationUserRouteDefinition, - readAllApiKeysRouteDefinition, - readAllOrganizationPaymentsRouteDefinition, - readAllOrganizationUsersRouteDefinition, - readAllYearsRouteDefinition, readOneOrganizationRouteDefinition, - readOneOrganizationUserRouteDefinition, - readOrganizationBillingRouteDefinition, updateOneOrganizationRouteDefinition, - updateOneOrganizationUserRouteDefinition, } from "@arrhes/application-metadata/routes" import { DocHeader } from "../../../components/document/DocHeader.tsx" -import { DocNextPage } from "../../../components/document/DocNextPage.tsx" import { DocParagraph } from "../../../components/document/DocParagraph.tsx" import { DocRoot } from "../../../components/document/DocRoot.tsx" import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" @@ -30,17 +15,17 @@ export function OrganizationApiDocPage() { - Lecture, modification et suppression de l'organisation. Les routes de modification et suppression + Lecture, modification et suppression de l'organisation. La modification et la suppression nécessitent que l'utilisateur soit administrateur. - La suppression d'une organisation est irréversible et supprime toutes les données associées. Cela - supprimera également la clé utilisée pour la suppression. + La suppression d'une organisation est irréversible et supprime toutes les données associées. - - - - Gestion des clés API de l'organisation. Nécessite un abonnement premium actif. - - - - - - La clé brute (rawKey) n'est retournée qu'au moment de la création. Conservez-la - précieusement. - - - - - - Gestion de l'abonnement premium et de l'historique des paiements. Les routes de paiement et - d'annulation nécessitent le rôle administrateur. - - - - - - - - - Gestion des membres d'une organisation. - - - - - - - - - Création et listing des exercices comptables d'une organisation. - - - - - ) } diff --git a/packages/website/src/features/docs/api/RootApiDocPage.tsx b/packages/website/src/features/docs/api/RootApiDocPage.tsx index 122f9a15..f7f5d10c 100644 --- a/packages/website/src/features/docs/api/RootApiDocPage.tsx +++ b/packages/website/src/features/docs/api/RootApiDocPage.tsx @@ -1,6 +1,7 @@ import { ButtonOutlineContent } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" import { IconChevronRight } from "@tabler/icons-react" +import { DocCode } from "../../../components/document/DocCode.tsx" import { DocHeader } from "../../../components/document/DocHeader.tsx" import { DocLink } from "../../../components/document/DocLink.tsx" import { DocRoot } from "../../../components/document/DocRoot.tsx" @@ -35,8 +36,9 @@ export function RootApiDocPage() { lineHeight: "relaxed", })} > - L'API d'Arrhes utilise exclusivement la méthode POST. L'organisation est identifiée via la clé API - (Bearer token). L'API expose 90 routes protégées réparties en 17 catégories. + L'API d'Arrhes suit les conventions REST (GET, POST, PATCH, DELETE). L'organisation est identifiée + via la clé API (Bearer token) ou l'en-tête X-Organization-Id. L'API expose 110 + routes protégées réparties en 19 catégories.

L'API supporte deux méthodes d'authentification : les cookies de session (pour l'interface web) et les - clés API avec l'en-tête Authorization: Bearer <clé> (pour l'intégration + clés API avec l'en-tête Authorization: Bearer <clé> (pour l'intégration programmatique). diff --git a/packages/website/src/features/docs/api/TagsApiDocPage.tsx b/packages/website/src/features/docs/api/TagsApiDocPage.tsx new file mode 100644 index 00000000..cbb82668 --- /dev/null +++ b/packages/website/src/features/docs/api/TagsApiDocPage.tsx @@ -0,0 +1,35 @@ +import { + createOneTagRouteDefinition, + deleteOneTagRouteDefinition, + readAllTagsRouteDefinition, + readOneTagRouteDefinition, + updateOneTagRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" + +export function TagsApiDocPage() { + return ( + + + + + + Les libellés (tags) permettent de catégoriser les écritures comptables avec des étiquettes + réutilisables définies au niveau de l'exercice. + + + + + + + + + ) +} diff --git a/packages/website/src/features/docs/api/XBRLReportsApiDocPage.tsx b/packages/website/src/features/docs/api/XBRLReportsApiDocPage.tsx new file mode 100644 index 00000000..9e57d629 --- /dev/null +++ b/packages/website/src/features/docs/api/XBRLReportsApiDocPage.tsx @@ -0,0 +1,52 @@ +import { + generateBalanceSheetXmlRouteDefinition, + generateFecRouteDefinition, + generateIncomeStatementXmlRouteDefinition, +} from "@arrhes/application-metadata/routes" +import { DocHeader } from "../../../components/document/DocHeader.tsx" +import { DocParagraph } from "../../../components/document/DocParagraph.tsx" +import { DocRoot } from "../../../components/document/DocRoot.tsx" +import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" +import { DocSection } from "../../../components/document/DocSection.tsx" +import { DocTip } from "../../../components/document/DocTip.tsx" + +export function XBRLReportsApiDocPage() { + return ( + + + + + + Le Fichier des Écritures Comptables (FEC) est un export normalisé requis par l'administration + fiscale française. Généré côté serveur et retourne une URL signée pour téléchargement. + + + + + + + Génération de rapports comptables en XBRL (taxonomie ANC française) : bilan et compte de résultat. + Ces rapports sont générés côté serveur et retournent une URL signée pour le téléchargement. + + + + + Les URLs signées retournent une durée de validité limitée. Téléchargez le fichier immédiatement + après génération. + + + + ) +} diff --git a/packages/website/src/features/docs/api/YearApiDocPage.tsx b/packages/website/src/features/docs/api/YearApiDocPage.tsx index 2404255c..c82ec18e 100644 --- a/packages/website/src/features/docs/api/YearApiDocPage.tsx +++ b/packages/website/src/features/docs/api/YearApiDocPage.tsx @@ -1,63 +1,15 @@ import { closeYearRouteDefinition, - computeOneEntryRouteDefinition, - createOneAccountRouteDefinition, - createOneBalanceSheetRouteDefinition, - createOneComputationIncomeStatementRouteDefinition, - createOneComputationRouteDefinition, - createOneEntryFromTemplateRouteDefinition, - createOneEntryLineRouteDefinition, - createOneEntryRouteDefinition, - createOneIncomeStatementRouteDefinition, - createOneJournalRouteDefinition, - createOneTagRouteDefinition, - deleteOneAccountRouteDefinition, - deleteOneBalanceSheetRouteDefinition, - deleteOneComputationIncomeStatementRouteDefinition, - deleteOneComputationRouteDefinition, - deleteOneEntryLineRouteDefinition, - deleteOneEntryRouteDefinition, - deleteOneIncomeStatementRouteDefinition, - deleteOneJournalRouteDefinition, - deleteOneTagRouteDefinition, + createOneYearRouteDefinition, deleteOneYearRouteDefinition, - duplicateOneEntryRouteDefinition, openYearRouteDefinition, - readAllAccountsRouteDefinition, - readAllBalanceSheetsRouteDefinition, - readAllComputationIncomeStatementsRouteDefinition, - readAllComputationsRouteDefinition, - readAllEntriesRouteDefinition, - readAllEntryLinesRouteDefinition, - readAllIncomeStatementsRouteDefinition, - readAllJournalsRouteDefinition, - readAllTagsRouteDefinition, - readOneAccountRouteDefinition, - readOneBalanceSheetRouteDefinition, - readOneComputationIncomeStatementRouteDefinition, - readOneComputationRouteDefinition, - readOneEntryLineRouteDefinition, - readOneEntryRouteDefinition, - readOneIncomeStatementRouteDefinition, - readOneJournalRouteDefinition, - readOneTagRouteDefinition, + readAllYearsRouteDefinition, readOneYearRouteDefinition, settleBalanceSheetRouteDefinition, settleIncomeStatementRouteDefinition, - updateManyEntryLinesRouteDefinition, - updateOneAccountRouteDefinition, - updateOneBalanceSheetRouteDefinition, - updateOneComputationIncomeStatementRouteDefinition, - updateOneComputationRouteDefinition, - updateOneEntryLineRouteDefinition, - updateOneEntryRouteDefinition, - updateOneIncomeStatementRouteDefinition, - updateOneJournalRouteDefinition, - updateOneTagRouteDefinition, updateOneYearRouteDefinition, } from "@arrhes/application-metadata/routes" import { DocHeader } from "../../../components/document/DocHeader.tsx" -import { DocNextPage } from "../../../components/document/DocNextPage.tsx" import { DocParagraph } from "../../../components/document/DocParagraph.tsx" import { DocRoot } from "../../../components/document/DocRoot.tsx" import { DocRouteRequest } from "../../../components/document/DocRouteRequest.tsx" @@ -68,142 +20,31 @@ export function YearApiDocPage() { return ( + + Création et listing des exercices comptables d'une organisation. + + + + + - Routes de lecture, modification, clôture et ouverture d'un exercice comptable. + Modification, suppression et gestion du cycle de vie d'un exercice comptable. - - + La clôture d'un exercice empêche toute modification ultérieure des écritures. - - - - Le plan comptable de l'organisation. Les comptes sont organisés en arborescence avec des classes (1 - à 7) à la racine. - - - - - - - - - - Les journaux comptables regroupent les écritures par type d'opération. - - - - - - - - - - Structure du bilan comptable (actif et passif). Les lignes de bilan sont liées aux comptes pour - calculer automatiquement les soldes. - - - - - - - - - - - Structure du compte de résultat. Fonctionne de manière similaire aux bilans. - - - - - - - - - - - Les libellés permettent de catégoriser les écritures comptables avec des étiquettes réutilisables. - - - - - - - - - - - Les calculs sont des formules personnalisées qui combinent des lignes de compte de résultat pour - produire des valeurs dérivées (par exemple le résultat d'exploitation). - - - - - - - - - - - Liens entre les calculs et les lignes de compte de résultat. Chaque lien définit si la ligne est - ajoutée ou soustraite dans le calcul. - - - - - - - - - - - Les écritures comptables sont les opérations enregistrées dans les journaux. Chaque écriture - contient une ou plusieurs lignes (débit/crédit). - - - - - - - - - - - - - - Chaque ligne d'écriture représente un mouvement de débit ou de crédit sur un compte. - - - - - - - - - - ) } diff --git a/packages/website/src/features/docs/cli/AuthenticationCliDocPage.tsx b/packages/website/src/features/docs/cli/AuthenticationCliDocPage.tsx new file mode 100644 index 00000000..dc1b86fa --- /dev/null +++ b/packages/website/src/features/docs/cli/AuthenticationCliDocPage.tsx @@ -0,0 +1,80 @@ +import { DocCode } from "../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../components/document/DocCodeBlock.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTip } from "../../../components/document/DocTip.js" + +export function AuthenticationCliDocPage() { + return ( + + + + + + Le CLI s'authentifie exclusivement par clé API. Pour en créer une, rendez-vous dans le dashboard : + + + Dashboard → Organisation → API → Clés → Nouvelle clé + + + Copiez la clé immédiatement après sa création — elle ne sera plus affichée ensuite. + + + + + + {"arrhes login --api-key --org "} + + + + {"arrhes login --api-key --org --url https://api.mondomaine.com"} + + + + Le CLI vérifie la clé auprès de l'API, puis enregistre la configuration dans{" "} + ~/.arrhes/config.json. + + + L'identifiant d'organisation (--org) est requis — il est automatiquement injecté + dans toutes les commandes. + + + L'option --url est facultative. Par défaut, le CLI se connecte à{" "} + https://api.arrhes.com. Si vous hébergez l'API vous-même, passez l'URL de votre + instance — elle sera sauvegardée dans ~/.arrhes/config.json et réutilisée pour + toutes les commandes suivantes. + + + + + arrhes whoami + + + + Pour effacer les identifiants stockés localement : + arrhes logout + + + + + Les identifiants sont stockés en clair dans ~/.arrhes/config.json. Vous pouvez + éditer ce fichier directement si nécessaire. + + + Pour utiliser plusieurs comptes ou environnements, il suffit de relancer{", "} + arrhes login avec une autre clé — le fichier est écrasé. + + + En savoir plus sur l'authentification par clé API + + + + ) +} diff --git a/packages/website/src/features/docs/cli/CommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/CommandsCliDocPage.tsx new file mode 100644 index 00000000..88152c02 --- /dev/null +++ b/packages/website/src/features/docs/cli/CommandsCliDocPage.tsx @@ -0,0 +1,145 @@ +import { DocCode } from "../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../components/document/DocCodeBlock.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTable } from "../../../components/document/DocTable.js" +import { DocTip } from "../../../components/document/DocTip.js" + +export function CommandsCliDocPage() { + return ( + + + + + + Chaque commande accepte --help pour afficher ses options. + + {"arrhes --help\narrhes entries create --help"} + + Toutes les réponses sont en JSON. Utilisez{", "} + | jq pour les filtrer ou les formater. + + + + + {"arrhes login --api-key --url --org "}, + "Enregistre les identifiants", + ], + [ + arrhes whoami, + "Affiche l'utilisateur connecté", + ], + [ + arrhes logout, + "Supprime les identifiants locaux", + ], + ]} + /> + + + + arrhes years list, + "Liste les exercices de l'organisation", + ], + [ + {"arrhes years get "}, + "Détails d'un exercice", + ], + [ + {"arrhes years create --start --end "}, + "Crée un nouvel exercice", + ], + ]} + /> + + {"arrhes years list | jq '.[].id'"} + + + + + {"arrhes entries list --year "}, + "Liste les écritures d'un exercice", + ], + [ + {"arrhes entries get --year "}, + "Détails d'une écriture", + ], + [ + + {"arrhes entries create --year --journal [--label ] [--date ]"} + , + "Crée une écriture", + ], + [ + {"arrhes entries delete --year "}, + "Supprime une écriture", + ], + ]} + /> + + + { + 'arrhes entries create \\\n --year \\\n --journal \\\n --label "Facture fournisseur" \\\n --date 2025-03-15' + } + + + + + + {"arrhes files list --year "}, + "Liste les fichiers d'un exercice", + ], + [ + {"arrhes files create --year --name [--folder ]"}, + "Enregistre un fichier", + ], + ]} + /> + + + + + + + ) +} diff --git a/packages/website/src/features/docs/cli/DemarrerCliDocPage.tsx b/packages/website/src/features/docs/cli/DemarrerCliDocPage.tsx new file mode 100644 index 00000000..1cdd50f1 --- /dev/null +++ b/packages/website/src/features/docs/cli/DemarrerCliDocPage.tsx @@ -0,0 +1,68 @@ +import { DocCode } from "../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTip } from "../../../components/document/DocTip.js" + +export function DemarrerCliDocPage() { + return ( + + + + + + Le CLI est un binaire autonome — aucune installation de Node.js ou de dépendance requise. Collez + l'une des commandes suivantes dans votre terminal : + + curl -fsSL https://arrhes.com/cli/install.sh | sh + Sur Windows (PowerShell) : + irm https://arrhes.com/cli/install.ps1 | iex + + Pour les options d'installation avancées (installation manuelle, autres architectures), consultez la{" "} + page Installation. + + + + + arrhes --version + + + + + Le CLI s'authentifie exclusivement par clé API. Rendez-vous dans le dashboard pour en créer une : + + + Dashboard → Organisation → API → Clés → Nouvelle clé + + + Copiez la clé immédiatement après sa création — elle ne sera plus affichée ensuite. + + + + + + {"arrhes login --api-key --url https://api.arrhes.com --org "} + + + Le CLI vérifie la clé et enregistre la configuration dans ~/.arrhes/config.json. + L'identifiant d'organisation est requis — il est utilisé automatiquement pour toutes les commandes. + + + + + Vérifiez que tout fonctionne en listant vos exercices : + arrhes years list + + Toutes les réponses du CLI sont en JSON. Combinez-les avec jq pour filtrer ou + formater les résultats. + + + + ) +} diff --git a/packages/website/src/features/docs/cli/InstallationCliDocPage.tsx b/packages/website/src/features/docs/cli/InstallationCliDocPage.tsx new file mode 100644 index 00000000..0faf37cd --- /dev/null +++ b/packages/website/src/features/docs/cli/InstallationCliDocPage.tsx @@ -0,0 +1,37 @@ +import { DocCode } from "../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../components/document/DocCodeBlock.js" +import { DocExample } from "../../../components/document/DocExample.js" +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTip } from "../../../components/document/DocTip.js" + +export function InstallationCliDocPage() { + return ( + + + + + + Collez la commande suivante dans votre terminal. Elle télécharge le script CLI et l'installe dans{" "} + ~/.local/bin. + + + curl -fsSL https://arrhes.com/cli/install.sh | sh + + + Si ~/.local/bin n'est pas dans votre PATH, le script vous + indique la ligne à ajouter dans votre ~/.bashrc ou ~/.zshrc. + + + + + arrhes --version + + + ) +} diff --git a/packages/website/src/features/docs/cli/RootCliDocPage.tsx b/packages/website/src/features/docs/cli/RootCliDocPage.tsx new file mode 100644 index 00000000..6c1387b9 --- /dev/null +++ b/packages/website/src/features/docs/cli/RootCliDocPage.tsx @@ -0,0 +1,73 @@ +import { DocHeader } from "../../../components/document/DocHeader.js" +import { DocLink } from "../../../components/document/DocLink.js" +import { DocList } from "../../../components/document/DocList.js" +import { DocParagraph } from "../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../components/document/DocRoot.js" +import { DocSection } from "../../../components/document/DocSection.js" +import { DocTip } from "../../../components/document/DocTip.js" + +export function RootCliDocPage() { + return ( + + + + + + Le CLI Arrhes est une interface en ligne de commande qui vous permet de gérer vos organisations, + exercices, écritures et fichiers directement depuis votre terminal, sans passer par l'interface web. + + + + + + + + Le CLI utilise la même API REST que l'interface web. Tout ce qui est possible dans le dashboard peut + être automatisé via le CLI. + + + + + + Installer le CLI + , + + Se connecter avec une clé API + , + + Référence des commandes + , + ]} + /> + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/BalanceSheetsCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/BalanceSheetsCommandsCliDocPage.tsx new file mode 100644 index 00000000..5a459d07 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/BalanceSheetsCommandsCliDocPage.tsx @@ -0,0 +1,111 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" + +export function BalanceSheetsCommandsCliDocPage() { + return ( + + + + + {"arrhes balance-sheets list "}, + "Liste les nœuds du bilan", + ], + [ + {"arrhes balance-sheets get "}, + "Détails d'un nœud", + ], + [ + {"arrhes balance-sheets create "}, + "Crée un nœud de bilan", + ], + [ + {"arrhes balance-sheets update "}, + "Modifie un nœud", + ], + [ + {"arrhes balance-sheets delete "}, + "Supprime un nœud", + ], + ]} + /> + + + + arrhes balance-sheets list year_xyz + + + + arrhes balance-sheets get year_xyz bs_abc + + + + Crée un nœud de bilan. Le parent est facultatif (nœud racine si absent). + ", + "Non", + "ID du nœud parent", + ], + [ + "--label ", + "Non", + "Libellé du nœud", + ], + ]} + /> + arrhes balance-sheets create year_xyz --label "Actif immobilisé" + + arrhes balance-sheets create year_xyz --parent bs_root --label "Immobilisations corporelles" + + + + + ", + "Non", + "ID du nœud parent", + ], + [ + "--label ", + "Non", + "Libellé du nœud", + ], + ]} + /> + arrhes balance-sheets update year_xyz bs_abc --label "Actif circulant" + + + + arrhes balance-sheets delete year_xyz bs_abc + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/ClesApiCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/ClesApiCommandsCliDocPage.tsx new file mode 100644 index 00000000..6e16f6f5 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/ClesApiCommandsCliDocPage.tsx @@ -0,0 +1,80 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function ClesApiCommandsCliDocPage() { + return ( + + + + + arrhes api-keys list, + "Liste les clés API de l'organisation", + ], + [ + arrhes api-keys create, + "Crée une nouvelle clé API", + ], + [ + {"arrhes api-keys delete "}, + "Révoque une clé API", + ], + ]} + /> + + + + arrhes api-keys list + + + + + Crée une nouvelle clé API. La valeur brute de la clé n'est affichée qu'une seule fois à la création + — conservez-la en lieu sûr. + + ", + "Non", + "Nom mnémotechnique pour la clé", + ], + ]} + /> + arrhes api-keys create --name "CI/CD pipeline" + + La valeur du champ rawKey dans la réponse est la clé secrète. Elle ne sera plus + jamais accessible après cette commande. + + + + + + Révoque définitivement une clé API. Toutes les intégrations utilisant cette clé cesseront de + fonctionner immédiatement. + + arrhes api-keys delete key_abc + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/ComptesCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/ComptesCommandsCliDocPage.tsx new file mode 100644 index 00000000..62ef14f3 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/ComptesCommandsCliDocPage.tsx @@ -0,0 +1,146 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" + +export function ComptesCommandsCliDocPage() { + return ( + + + + + {"arrhes accounts list --year "}, + "Liste les comptes d'un exercice", + ], + [ + {"arrhes accounts get --year "}, + "Détails d'un compte", + ], + [ + + {"arrhes accounts create --year --number --label --type --parent "} + , + "Crée un compte", + ], + [ + {"arrhes accounts update --year "}, + "Modifie un compte", + ], + [ + {"arrhes accounts delete --year "}, + "Supprime un compte", + ], + ]} + /> + + + + Retourne l'ensemble des comptes du plan comptable de l'exercice. + arrhes accounts list --year year_xyz + {"arrhes accounts list --year year_xyz | jq '.[].number'"} + + + + arrhes accounts get acc_abc --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--number ", + "Oui", + "Numéro de compte (ex. 401)", + ], + [ + "--label ", + "Oui", + "Libellé du compte", + ], + [ + "--type ", + "Oui", + "Type de compte", + ], + [ + "--parent ", + "Oui", + "Identifiant du compte parent", + ], + [ + "--no-selectable", + "Non", + "Marque le compte comme non sélectionnable pour les écritures", + ], + ]} + /> + + arrhes accounts create --year year_xyz --number 401 --label "Fournisseurs" --type liability --parent + acc_root + + + + + ", + "Non", + "Nouveau numéro de compte", + ], + [ + "--label ", + "Non", + "Nouveau libellé", + ], + [ + "--type ", + "Non", + "Nouveau type", + ], + [ + "--parent ", + "Non", + "Nouveau compte parent", + ], + ]} + /> + + arrhes accounts update acc_abc --year year_xyz --label "Fournisseurs divers" + + + + + arrhes accounts delete acc_abc --year year_xyz + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/EcrituresCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/EcrituresCommandsCliDocPage.tsx new file mode 100644 index 00000000..2a261c8a --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/EcrituresCommandsCliDocPage.tsx @@ -0,0 +1,349 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function EcrituresCommandsCliDocPage() { + return ( + + + + + {"arrhes entries list --year "}, + "Liste les écritures d'un exercice", + ], + [ + {"arrhes entries get --year "}, + "Détails d'une écriture", + ], + [ + {"arrhes entries create --year --journal "}, + "Crée une écriture", + ], + [ + {"arrhes entries update --year "}, + "Modifie une écriture", + ], + [ + {"arrhes entries duplicate --year "}, + "Duplique une écriture", + ], + [ + {"arrhes entries reverse --year "}, + "Extourne une écriture", + ], + [ + {"arrhes entries delete --year "}, + "Supprime une écriture", + ], + [ + {"arrhes entries compute --year "}, + "Calcule les totaux d'une écriture", + ], + [ + {"arrhes entries lines list --year "}, + "Liste les lignes d'une écriture", + ], + [ + {"arrhes entries lines get --year "}, + "Détails d'une ligne", + ], + [ + + {"arrhes entries lines create --year --account "} + , + "Crée une ligne d'écriture", + ], + [ + + {"arrhes entries lines update --year "} + , + "Modifie une ligne", + ], + [ + + {"arrhes entries lines delete --year "} + , + "Supprime une ligne", + ], + [ + {"arrhes entries tags add --year --tag "}, + "Ajoute un libellé à une écriture", + ], + [ + {"arrhes entries tags remove --year "}, + "Retire un libellé", + ], + ]} + /> + + + + arrhes entries list --year year_xyz + {"arrhes entries list --year year_xyz | jq '.[].label'"} + + + + arrhes entries get entry_123 --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--journal ", + "Oui", + "Identifiant du journal", + ], + [ + "--label ", + "Non", + "Libellé de l'écriture", + ], + [ + "--date ", + "Non", + "Date au format YYYY-MM-DD (défaut : aujourd'hui)", + ], + ]} + /> + + { + 'arrhes entries create \\\n --year year_xyz \\\n --journal AC \\\n --label "Facture fournisseur" \\\n --date 2025-03-15' + } + + + Utilisez arrhes journals list --year <id> pour retrouver les identifiants + de journaux disponibles dans un exercice. + + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--label ", + "Non", + "Nouveau libellé", + ], + [ + "--date ", + "Non", + "Nouvelle date (YYYY-MM-DD)", + ], + [ + "--journal ", + "Non", + "Nouveau journal", + ], + [ + "--file ", + "Non", + "Pièce justificative associée", + ], + ]} + /> + arrhes entries update entry_123 --year year_xyz --label "Libellé corrigé" + + + + Crée une copie de l'écriture avec les mêmes lignes. + arrhes entries duplicate entry_123 --year year_xyz + + + + + Crée une écriture d'extourne (contrepartie) pour annuler l'écriture d'origine. + + arrhes entries reverse entry_123 --year year_xyz + + + + Supprime définitivement une écriture et ses lignes d'écriture associées. + arrhes entries delete entry_123 --year year_xyz + + La suppression est irréversible. L'ensemble des lignes d'écriture liées sera également supprimé. + + + + + Calcule les totaux (débit / crédit) d'une écriture. + ", + "Oui", + "Identifiant de l'exercice", + ], + ]} + /> + arrhes entries compute entry_123 --year year_xyz + + + + arrhes entries lines list entry_123 --year year_xyz + + + + arrhes entries lines get entry_123 line_abc --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--account ", + "Oui", + "Identifiant du compte", + ], + [ + "--label ", + "Non", + "Libellé de la ligne", + ], + [ + "--debit ", + "Non", + "Montant au débit", + ], + [ + "--credit ", + "Non", + "Montant au crédit", + ], + ]} + /> + + arrhes entries lines create entry_123 --year year_xyz --account acc_xyz --debit 1000 + + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--label ", + "Non", + "Nouveau libellé", + ], + [ + "--debit ", + "Non", + "Nouveau montant au débit", + ], + [ + "--credit ", + "Non", + "Nouveau montant au crédit", + ], + ]} + /> + arrhes entries lines update entry_123 line_abc --year year_xyz --debit 1500 + + + + arrhes entries lines delete entry_123 line_abc --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--tag ", + "Oui", + "Identifiant du libellé", + ], + ]} + /> + arrhes entries tags add entry_123 --year year_xyz --tag tag_abc + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + ]} + /> + arrhes entries tags remove entry_123 tag_abc --year year_xyz + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/ExercicesCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/ExercicesCommandsCliDocPage.tsx new file mode 100644 index 00000000..c2f63659 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/ExercicesCommandsCliDocPage.tsx @@ -0,0 +1,215 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function ExercicesCommandsCliDocPage() { + return ( + + + + + arrhes years list, + "Liste les exercices de l'organisation", + ], + [ + {"arrhes years get "}, + "Détails d'un exercice", + ], + [ + {"arrhes years create --start --end "}, + "Crée un exercice", + ], + [ + {"arrhes years update "}, + "Modifie un exercice", + ], + [ + {"arrhes years delete "}, + "Supprime un exercice", + ], + [ + {"arrhes years close "}, + "Clôture un exercice", + ], + [ + {"arrhes years open --journal-opening "}, + "Réouvre un exercice", + ], + [ + + {"arrhes years settle-balance-sheet --journal-closing "} + , + "Solde le bilan", + ], + [ + + {"arrhes years settle-income-statement --journal-closing "} + , + "Solde le compte de résultat", + ], + ]} + /> + + + + Liste tous les exercices comptables de l'organisation configurée. + arrhes years list + {"arrhes years list | jq '.[].id'"} + + + + Retourne les détails d'un exercice par son identifiant. + arrhes years get year_xyz + + + + Crée un nouvel exercice dans l'organisation spécifiée. + ", + "Oui", + "Date de début (YYYY-MM-DD)", + ], + [ + "--end ", + "Oui", + "Date de fin (YYYY-MM-DD)", + ], + [ + "--label ", + "Non", + "Libellé de l'exercice", + ], + ]} + /> + + arrhes years create --start 2025-01-01 --end 2025-12-31 --label "Exercice 2025" + + + La commande retourne l'objet exercice créé, incluant son identifiant à utiliser dans les commandes{" "} + entries, journals et files. + + + + + ", + "Non", + "Nouvelle date de début", + ], + [ + "--end ", + "Non", + "Nouvelle date de fin", + ], + [ + "--label ", + "Non", + "Nouveau libellé", + ], + ]} + /> + arrhes years update year_xyz --label "FY 2025" + + + + Supprime définitivement un exercice et toutes ses données. + arrhes years delete year_xyz + + + + + Clôture un exercice. Une fois clôturé, les écritures ne peuvent plus être modifiées. + + arrhes years close year_xyz + + + + Réouvre un exercice clôturé. Nécessite un journal d'ouverture. + ", + "Oui", + "Identifiant du journal d'ouverture", + ], + ]} + /> + arrhes years open year_xyz --journal-opening jrn_abc + + + + Génère les écritures de solde du bilan dans le journal de clôture spécifié. + ", + "Oui", + "Identifiant du journal de clôture", + ], + ]} + /> + arrhes years settle-balance-sheet year_xyz --journal-closing jrn_closing + + + + + Génère les écritures de solde du compte de résultat dans le journal de clôture spécifié. + + ", + "Oui", + "Identifiant du journal de clôture", + ], + ]} + /> + arrhes years settle-income-statement year_xyz --journal-closing jrn_closing + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/ExportsCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/ExportsCommandsCliDocPage.tsx new file mode 100644 index 00000000..ec9e68c5 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/ExportsCommandsCliDocPage.tsx @@ -0,0 +1,120 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function ExportsCommandsCliDocPage() { + return ( + + + + + {"arrhes exports fec --year "}, + "Génère un export FEC", + ], + [ + {"arrhes exports xbrl-balance-sheet --year "}, + "Génère un export XBRL du bilan", + ], + [ + {"arrhes exports xbrl-income-statement --year "}, + "Génère un export XBRL du compte de résultat", + ], + ]} + /> + + + + + Génère un Fichier des Écritures Comptables (FEC) pour l'exercice spécifié. La commande retourne une + URL signée pour télécharger le fichier. + + ", + "Oui", + "Identifiant de l'exercice", + ], + ]} + /> + arrhes exports fec --year year_xyz + {'URL=$(arrhes exports fec --year year_xyz)\ncurl -o fec.txt "$URL"'} + + Le FEC est un fichier texte au format réglementaire requis par l'administration fiscale française. + Il est généré à partir de toutes les écritures validées de l'exercice. Utilisez la commande{" "} + arrhes years close avant de générer le FEC final. + + + + + + Génère un fichier XBRL du bilan comptable pour l'exercice spécifié. La commande retourne une URL + signée pour télécharger le fichier. + + ", + "Oui", + "Identifiant de l'exercice", + ], + ]} + /> + arrhes exports xbrl-balance-sheet --year year_xyz + + {'URL=$(arrhes exports xbrl-balance-sheet --year year_xyz)\ncurl -o bilan.xml "$URL"'} + + + + + + Génère un fichier XBRL du compte de résultat pour l'exercice spécifié. La commande retourne une URL + signée pour télécharger le fichier. + + ", + "Oui", + "Identifiant de l'exercice", + ], + ]} + /> + arrhes exports xbrl-income-statement --year year_xyz + + {'URL=$(arrhes exports xbrl-income-statement --year year_xyz)\ncurl -o compte-resultat.xml "$URL"'} + + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/FichiersCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/FichiersCommandsCliDocPage.tsx new file mode 100644 index 00000000..d36ad7de --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/FichiersCommandsCliDocPage.tsx @@ -0,0 +1,262 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function FichiersCommandsCliDocPage() { + return ( + + + + + {"arrhes files list --year "}, + "Liste les fichiers d'un exercice", + ], + [ + {"arrhes files get --year "}, + "Détails d'un fichier", + ], + [ + + {"arrhes files create --year --name --reference --hash "} + , + "Enregistre un fichier", + ], + [ + {"arrhes files update --year "}, + "Modifie un fichier", + ], + [ + {"arrhes files delete --year "}, + "Supprime un fichier", + ], + [ + {"arrhes files download-url --year "}, + "Génère une URL de téléchargement", + ], + ]} + /> + + + + arrhes files list --year year_xyz + + + + arrhes files get file_abc --year year_xyz + + + + Enregistre les métadonnées d'un fichier dans l'exercice. + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--name ", + "Oui", + "Nom du fichier (avec extension)", + ], + [ + "--reference ", + "Oui", + "Numéro de référence du fichier", + ], + [ + "--hash ", + "Oui", + "Hash SHA-256 du fichier", + ], + [ + "--folder ", + "Non", + "Identifiant du dossier parent", + ], + ]} + /> + + { + "arrhes files create --year year_xyz \\\n --name facture-2025-001.pdf --reference FA-001 --hash abc123..." + } + + + Pour uploader physiquement un fichier, utilisez les routes API de génération d'URL signée + disponibles dans la documentation API. + + + + + ", + "Non", + "Nouveau nom du fichier", + ], + [ + "--reference ", + "Non", + "Nouvelle référence", + ], + [ + "--date ", + "Non", + "Date du fichier (YYYY-MM-DD)", + ], + [ + "--folder ", + "Non", + "Nouveau dossier parent", + ], + ]} + /> + arrhes files update file_abc --year year_xyz --name facture-corrigee.pdf + + + + arrhes files delete file_abc --year year_xyz + + + + + Génère une URL signée temporaire pour télécharger le fichier. L'URL est affichée dans la sortie + standard. + + arrhes files download-url file_abc --year year_xyz + + {'URL=$(arrhes files download-url file_abc --year year_xyz)\ncurl -o facture.pdf "$URL"'} + + + + + + Les dossiers sont gérés via le sous-groupe arrhes files folders. + + {"arrhes files folders list --year "}, + "Liste les dossiers d'un exercice", + ], + [ + {"arrhes files folders get --year "}, + "Détails d'un dossier", + ], + [ + {"arrhes files folders create --year --name "}, + "Crée un dossier", + ], + [ + {"arrhes files folders update --year "}, + "Modifie un dossier", + ], + [ + {"arrhes files folders delete --year "}, + "Supprime un dossier", + ], + ]} + /> + + + + arrhes files folders list --year year_xyz + + + + arrhes files folders get folder_abc --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--name ", + "Oui", + "Nom du dossier", + ], + [ + "--parent ", + "Non", + "Identifiant du dossier parent", + ], + ]} + /> + arrhes files folders create --year year_xyz --name "Factures fournisseurs" + + arrhes files folders create --year year_xyz --name "Mars 2025" --parent folder_abc + + + + + ", + "Non", + "Nouveau nom", + ], + [ + "--parent ", + "Non", + "Nouveau dossier parent", + ], + ]} + /> + + arrhes files folders update folder_abc --year year_xyz --name "Factures achats" + + + + + Supprime un dossier vide. + arrhes files folders delete folder_abc --year year_xyz + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/IncomeStatementsCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/IncomeStatementsCommandsCliDocPage.tsx new file mode 100644 index 00000000..360653a5 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/IncomeStatementsCommandsCliDocPage.tsx @@ -0,0 +1,193 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" + +export function IncomeStatementsCommandsCliDocPage() { + return ( + + + + + {"arrhes income-statements list "}, + "Liste les nœuds du compte de résultat", + ], + [ + {"arrhes income-statements get "}, + "Détails d'un nœud", + ], + [ + {"arrhes income-statements create "}, + "Crée un nœud", + ], + [ + {"arrhes income-statements update "}, + "Modifie un nœud", + ], + [ + {"arrhes income-statements delete "}, + "Supprime un nœud", + ], + [ + {"arrhes income-statements computations list "}, + "Liste les calculs", + ], + [ + + {"arrhes income-statements computations get "} + , + "Détails d'un calcul", + ], + [ + {"arrhes income-statements computations create "}, + "Crée un calcul", + ], + [ + + {"arrhes income-statements computations update "} + , + "Modifie un calcul", + ], + [ + + {"arrhes income-statements computations delete "} + , + "Supprime un calcul", + ], + ]} + /> + + + + arrhes income-statements list year_xyz + + + + arrhes income-statements get year_xyz is_abc + + + + + Crée un nœud de compte de résultat. Le parent est facultatif (nœud racine si absent). + + ", + "Oui", + "Libellé du nœud", + ], + [ + "--parent ", + "Non", + "ID du nœud parent", + ], + ]} + /> + arrhes income-statements create year_xyz --label "Produits d'exploitation" + + arrhes income-statements create year_xyz --parent is_root --label "Chiffre d'affaires" + + + + + ", + "Non", + "Libellé du nœud", + ], + [ + "--parent ", + "Non", + "ID du nœud parent", + ], + ]} + /> + + arrhes income-statements update year_xyz is_abc --label "Charges d'exploitation" + + + + + arrhes income-statements delete year_xyz is_abc + + + + arrhes income-statements computations list year_xyz + + + + arrhes income-statements computations get year_xyz cmp_abc + + + + ", + "Oui", + "Libellé du calcul", + ], + ]} + /> + + arrhes income-statements computations create year_xyz --label "Résultat d'exploitation" + + + + + ", + "Non", + "Libellé du calcul", + ], + ]} + /> + + arrhes income-statements computations update year_xyz cmp_abc --label "Résultat net" + + + + + arrhes income-statements computations delete year_xyz cmp_abc + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/JournauxCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/JournauxCommandsCliDocPage.tsx new file mode 100644 index 00000000..bb654571 --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/JournauxCommandsCliDocPage.tsx @@ -0,0 +1,120 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" + +export function JournauxCommandsCliDocPage() { + return ( + + + + + {"arrhes journals list --year "}, + "Liste les journaux d'un exercice", + ], + [ + {"arrhes journals get --year "}, + "Détails d'un journal", + ], + [ + + {"arrhes journals create --year --code --label "} + , + "Crée un journal", + ], + [ + {"arrhes journals update --year "}, + "Modifie un journal", + ], + [ + {"arrhes journals delete --year "}, + "Supprime un journal", + ], + ]} + /> + + + + arrhes journals list --year year_xyz + {"arrhes journals list --year year_xyz | jq '.[].code'"} + + + + arrhes journals get jrn_abc --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--code ", + "Oui", + "Code du journal (ex : ACH, VTE, BQ)", + ], + [ + "--label ", + "Oui", + "Libellé du journal", + ], + ]} + /> + arrhes journals create --year year_xyz --code ACH --label "Achats" + + + + ", + "Non", + "Nouveau code", + ], + [ + "--label ", + "Non", + "Nouveau libellé", + ], + ]} + /> + + arrhes journals update jrn_abc --year year_xyz --label "Achats fournisseurs" + + + + + + Supprime un journal. Cette action échoue si des écritures y sont encore rattachées. + + arrhes journals delete jrn_abc --year year_xyz + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/LibellesCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/LibellesCommandsCliDocPage.tsx new file mode 100644 index 00000000..4661b87b --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/LibellesCommandsCliDocPage.tsx @@ -0,0 +1,93 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" + +export function LibellesCommandsCliDocPage() { + return ( + + + + + {"arrhes tags list --year "}, + "Liste les libellés d'un exercice", + ], + [ + {"arrhes tags get --year "}, + "Détails d'un libellé", + ], + [ + {"arrhes tags create --year --label "}, + "Crée un libellé", + ], + [ + {"arrhes tags update --year "}, + "Modifie un libellé", + ], + [ + {"arrhes tags delete --year "}, + "Supprime un libellé", + ], + ]} + /> + + + + arrhes tags list --year year_xyz + + + + arrhes tags get tag_abc --year year_xyz + + + + ", + "Oui", + "Identifiant de l'exercice", + ], + [ + "--label ", + "Oui", + "Libellé du tag", + ], + ]} + /> + arrhes tags create --year year_xyz --label "Investissement" + + + + + arrhes tags update tag_abc --year year_xyz --label "Investissement matériel" + + + + + + Supprime un libellé. Les écritures associées conservent leurs autres libellés. + + arrhes tags delete tag_abc --year year_xyz + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/MembresCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/MembresCommandsCliDocPage.tsx new file mode 100644 index 00000000..134d9a4c --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/MembresCommandsCliDocPage.tsx @@ -0,0 +1,101 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function MembresCommandsCliDocPage() { + return ( + + + + + arrhes members list, + "Liste les membres de l'organisation", + ], + [ + {"arrhes members get "}, + "Détails d'un membre", + ], + [ + {"arrhes members invite --email "}, + "Invite un utilisateur", + ], + [ + {"arrhes members update "}, + "Modifie les droits d'un membre", + ], + [ + {"arrhes members remove "}, + "Retire un membre de l'organisation", + ], + ]} + /> + + + + arrhes members list + + + + arrhes members get usr_abc + + + + ", + "Oui", + "Adresse email de l'utilisateur à inviter", + ], + [ + "--admin", + "Non", + "Accorder les droits administrateur", + ], + ]} + /> + arrhes members invite --email colleague@example.com + arrhes members invite --email admin@example.com --admin + + + + + Modifie les droits d'un membre. Utilisez --admin pour accorder les droits + administrateur ou --no-admin pour les révoquer. + + arrhes members update usr_abc --admin + arrhes members update usr_abc --no-admin + + + + + Retire un membre de l'organisation. L'utilisateur perd immédiatement l'accès. + + arrhes members remove usr_abc + + Cette action est irréversible. L'utilisateur devra être réinvité pour retrouver l'accès. + + + + ) +} diff --git a/packages/website/src/features/docs/cli/commands/OrgCommandsCliDocPage.tsx b/packages/website/src/features/docs/cli/commands/OrgCommandsCliDocPage.tsx new file mode 100644 index 00000000..ac191fcc --- /dev/null +++ b/packages/website/src/features/docs/cli/commands/OrgCommandsCliDocPage.tsx @@ -0,0 +1,92 @@ +import { DocCode } from "../../../../components/document/DocCode.js" +import { DocCodeBlock } from "../../../../components/document/DocCodeBlock.js" +import { DocHeader } from "../../../../components/document/DocHeader.js" +import { DocParagraph } from "../../../../components/document/DocParagraph.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocSection } from "../../../../components/document/DocSection.js" +import { DocTable } from "../../../../components/document/DocTable.js" +import { DocTip } from "../../../../components/document/DocTip.js" + +export function OrgCommandsCliDocPage() { + return ( + + + + + arrhes org get, + "Affiche les détails de l'organisation", + ], + [ + arrhes org update, + "Modifie les informations de l'organisation", + ], + [ + arrhes org delete, + "Supprime l'organisation et toutes ses données", + ], + ]} + /> + + + + + Retourne les informations de l'organisation active (nom, email, SIREN, etc.). + + arrhes org get + + + + + Modifie les informations de l'organisation. Toutes les options sont facultatives. + + ", + "Non", + "Nom de l'organisation", + ], + [ + "--email ", + "Non", + "Email de contact de l'organisation", + ], + [ + "--siren ", + "Non", + "Numéro SIREN de l'organisation", + ], + ]} + /> + arrhes org update --name "Ma Société" + arrhes org update --email contact@example.com --siren 123456789 + + + + + Supprime l'organisation active et toutes ses données de façon irréversible. Nécessite le rôle + administrateur. + + arrhes org delete + + La suppression est irréversible et supprime tous les exercices, écritures et fichiers associés. + + + + ) +} diff --git a/packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx index 11b9c968..1669cada 100644 --- a/packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/EntriesDashboardDocPage.tsx @@ -3,7 +3,6 @@ import { DocExample } from "../../../components/document/DocExample.js" import { DocHeader } from "../../../components/document/DocHeader.js" import { DocLink } from "../../../components/document/DocLink.js" import { DocList } from "../../../components/document/DocList.js" -import { DocNextPage } from "../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../components/document/DocParagraph.js" import { DocRoot } from "../../../components/document/DocRoot.js" import { DocSection } from "../../../components/document/DocSection.js" @@ -167,11 +166,6 @@ export function EntriesDashboardDocPage() { ]} /> - - ) } diff --git a/packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx index 0834fe80..3f4da31c 100644 --- a/packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/FilesDashboardDocPage.tsx @@ -2,7 +2,6 @@ import { DocExample } from "../../../components/document/DocExample.js" import { DocHeader } from "../../../components/document/DocHeader.js" import { DocLink } from "../../../components/document/DocLink.js" import { DocList } from "../../../components/document/DocList.js" -import { DocNextPage } from "../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../components/document/DocParagraph.js" import { DocRoot } from "../../../components/document/DocRoot.js" import { DocSection } from "../../../components/document/DocSection.js" @@ -90,11 +89,6 @@ export function FilesDashboardDocPage() { documents numériquement, mais pensez également à conserver vos originaux papier conformément à la réglementation. - - ) } diff --git a/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx index 11008403..b87eb30d 100644 --- a/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/GettingStartedDashboardDocPage.tsx @@ -2,7 +2,6 @@ import { DocExample } from "../../../components/document/DocExample.js" import { DocHeader } from "../../../components/document/DocHeader.js" import { DocLink } from "../../../components/document/DocLink.js" import { DocList } from "../../../components/document/DocList.js" -import { DocNextPage } from "../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../components/document/DocParagraph.js" import { DocRoot } from "../../../components/document/DocRoot.js" import { DocSection } from "../../../components/document/DocSection.js" @@ -180,11 +179,6 @@ export function GettingStartedDashboardDocPage() { ]} /> - - ) } diff --git a/packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx index 24007ccb..c21b910a 100644 --- a/packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/OrganizationsDashboardDocPage.tsx @@ -3,7 +3,6 @@ import { DocExample } from "../../../components/document/DocExample.js" import { DocHeader } from "../../../components/document/DocHeader.js" import { DocLink } from "../../../components/document/DocLink.js" import { DocList } from "../../../components/document/DocList.js" -import { DocNextPage } from "../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../components/document/DocParagraph.js" import { DocRoot } from "../../../components/document/DocRoot.js" import { DocSection } from "../../../components/document/DocSection.js" @@ -85,11 +84,6 @@ export function OrganizationsDashboardDocPage() { - - ) } diff --git a/packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx b/packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx index ee3576d7..ee416399 100644 --- a/packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx +++ b/packages/website/src/features/docs/dashboard/YearsDashboardDocPage.tsx @@ -2,7 +2,6 @@ import { DocExample } from "../../../components/document/DocExample.js" import { DocHeader } from "../../../components/document/DocHeader.js" import { DocLink } from "../../../components/document/DocLink.js" import { DocList } from "../../../components/document/DocList.js" -import { DocNextPage } from "../../../components/document/DocNextPage.js" import { DocParagraph } from "../../../components/document/DocParagraph.js" import { DocRoot } from "../../../components/document/DocRoot.js" import { DocSection } from "../../../components/document/DocSection.js" @@ -65,11 +64,6 @@ export function YearsDashboardDocPage() { vous en avez plusieurs). - - ) } diff --git a/packages/website/src/features/docs/docSections.tsx b/packages/website/src/features/docs/docSections.tsx index 439335e0..c8f4eb2e 100644 --- a/packages/website/src/features/docs/docSections.tsx +++ b/packages/website/src/features/docs/docSections.tsx @@ -9,6 +9,7 @@ import { IconReport, IconRobot, IconStack, + IconTerminal, } from "@tabler/icons-react" import type { DocSection } from "./SectionTab.tsx" @@ -257,14 +258,20 @@ export const docSections: Record = { path: "/documentation/api", icon: , navigation: { - api: { - title: "API", - icon: , + home: { + title: undefined, + icon: undefined, items: [ { path: "/documentation/api", label: "Présentation", }, + ], + }, + basicsGroup: { + title: "Généralités", + icon: , + items: [ { path: "/documentation/api/introduction", label: "Introduction", @@ -273,17 +280,159 @@ export const docSections: Record = { path: "/documentation/api/authentification", label: "Authentification", }, + ], + }, + organisationGroup: { + title: "Organisation", + icon: , + items: [ { path: "/documentation/api/organisation", label: "Organisation", }, { - path: "/documentation/api/exercice", - label: "Exercice", + path: "/documentation/api/membres", + label: "Membres", + }, + { + path: "/documentation/api/clés-api", + label: "Clés API", }, { path: "/documentation/api/stockage", - label: "Fichiers et documents", + label: "Stockage", + }, + ], + }, + exerciceGroup: { + title: "Exercice", + icon: , + items: [ + { + path: "/documentation/api/exercice", + label: "Exercices", + }, + { + path: "/documentation/api/comptes", + label: "Comptes", + }, + { + path: "/documentation/api/journaux", + label: "Journaux", + }, + { + path: "/documentation/api/bilans", + label: "Bilans", + }, + { + path: "/documentation/api/comptes-de-résultat", + label: "Comptes de résultat", + }, + { + path: "/documentation/api/libellés", + label: "Libellés", + }, + { + path: "/documentation/api/écritures", + label: "Écritures", + }, + { + path: "/documentation/api/exports", + label: "Exports", + }, + ], + }, + }, + }, + cli: { + id: "cli", + label: "CLI", + path: "/documentation/cli", + icon: , + navigation: { + home: { + items: [ + { + path: "/documentation/cli", + label: "Présentation", + }, + ], + }, + guide: { + title: "Guide", + icon: , + items: [ + { + path: "/documentation/cli/installation", + label: "Installation", + }, + { + path: "/documentation/cli/demarrer", + label: "Démarrer", + }, + { + path: "/documentation/cli/authentification", + label: "Authentification", + }, + ], + }, + organisationGroup: { + title: "Organisation", + icon: , + items: [ + { + path: "/documentation/cli/commandes/organisation", + label: "Organisation", + }, + { + path: "/documentation/cli/commandes/membres", + label: "Membres", + }, + { + path: "/documentation/cli/commandes/cles-api", + label: "Clés API", + }, + { + path: "/documentation/cli/commandes/stockage", + label: "Stockage", + }, + ], + }, + exerciceGroup: { + title: "Exercice", + icon: , + items: [ + { + path: "/documentation/cli/commandes/exercices", + label: "Exercices", + }, + { + path: "/documentation/cli/commandes/journaux", + label: "Journaux", + }, + { + path: "/documentation/cli/commandes/comptes", + label: "Comptes", + }, + { + path: "/documentation/cli/commandes/libelles", + label: "Libellés", + }, + { + path: "/documentation/cli/commandes/ecritures", + label: "Écritures", + }, + { + path: "/documentation/cli/commandes/exports", + label: "Exports", + }, + { + path: "/documentation/cli/commandes/bilans", + label: "Bilans", + }, + { + path: "/documentation/cli/commandes/comptes-de-resultat", + label: "Comptes de résultat", }, ], }, diff --git a/packages/website/src/routes/applicationTree.ts b/packages/website/src/routes/applicationTree.ts index 15511026..63f4c1c5 100644 --- a/packages/website/src/routes/applicationTree.ts +++ b/packages/website/src/routes/applicationTree.ts @@ -1,5 +1,6 @@ import type { AnyRoute } from "@tanstack/react-router" import { catchRoute } from "./catchRoute.js" +import { cliRoute } from "./root/cliRoute.js" import { fullDashboardTree } from "./root/dashboard/fullDashboardTree.js" import { docsTree } from "./root/docs/docsTree.js" import { homeLayoutRoute } from "./root/home/homeLayoutRoute.js" @@ -15,6 +16,7 @@ export const applicationTree: AnyRoute = rootLayoutRoute.addChildren([ ]), docsTree, + cliRoute, signUpRoute, signInRoute, resetPasswordRoute, diff --git a/packages/website/src/routes/root/cliRoute.tsx b/packages/website/src/routes/root/cliRoute.tsx new file mode 100644 index 00000000..7af43ec3 --- /dev/null +++ b/packages/website/src/routes/root/cliRoute.tsx @@ -0,0 +1,12 @@ +import { createRoute, redirect } from "@tanstack/react-router" +import { rootLayoutRoute } from "../rootLayoutRoute.js" + +export const cliRoute = createRoute({ + getParentRoute: () => rootLayoutRoute, + path: "/cli", + beforeLoad: () => { + throw redirect({ + href: "https://github.com/arrhes/application/releases/latest", + }) + }, +}) diff --git a/packages/website/src/routes/root/docs/api/accountsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/accountsApiDocRoute.tsx new file mode 100644 index 00000000..b7afff31 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/accountsApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const accountsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/comptes", + beforeLoad: () => ({ + title: "Comptes", + description: "Endpoints API pour la gestion du plan comptable d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/AccountsApiDocPage.tsx"), + "AccountsApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/apiKeysApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/apiKeysApiDocRoute.tsx new file mode 100644 index 00000000..e3fe99c1 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/apiKeysApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const apiKeysApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/clés-api", + beforeLoad: () => ({ + title: "Clés API", + description: "Endpoints API pour la gestion des clés d'accès programmatique à l'API Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/ApiKeysApiDocPage.tsx"), + "ApiKeysApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/balanceSheetsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/balanceSheetsApiDocRoute.tsx new file mode 100644 index 00000000..f6f84ecb --- /dev/null +++ b/packages/website/src/routes/root/docs/api/balanceSheetsApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const balanceSheetsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/bilans", + beforeLoad: () => ({ + title: "Bilans", + description: "Endpoints API pour la structure du bilan comptable d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/BalanceSheetsApiDocPage.tsx"), + "BalanceSheetsApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/computationsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/computationsApiDocRoute.tsx new file mode 100644 index 00000000..53de1eb4 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/computationsApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const computationsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/calculs", + beforeLoad: () => ({ + title: "Calculs", + description: "Endpoints API pour la gestion des calculs et formules personnalisées d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/ComputationsApiDocPage.tsx"), + "ComputationsApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/entriesApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/entriesApiDocRoute.tsx new file mode 100644 index 00000000..d574df31 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/entriesApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const entriesApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/écritures", + beforeLoad: () => ({ + title: "Écritures", + description: "Endpoints API pour la gestion des écritures comptables d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/EntriesApiDocPage.tsx"), + "EntriesApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/entryLinesApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/entryLinesApiDocRoute.tsx new file mode 100644 index 00000000..9f81ecd9 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/entryLinesApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const entryLinesApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/lignes", + beforeLoad: () => ({ + title: "Lignes d'écriture", + description: "Endpoints API pour la gestion des lignes de débit/crédit et des tags des écritures Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/EntryLinesApiDocPage.tsx"), + "EntryLinesApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/foldersApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/foldersApiDocRoute.tsx new file mode 100644 index 00000000..6c67c146 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/foldersApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const foldersApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/dossiers", + beforeLoad: () => ({ + title: "Dossiers", + description: "Endpoints API pour la gestion des dossiers de fichiers d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/FoldersApiDocPage.tsx"), + "FoldersApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/incomeStatementsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/incomeStatementsApiDocRoute.tsx new file mode 100644 index 00000000..35b0fc9d --- /dev/null +++ b/packages/website/src/routes/root/docs/api/incomeStatementsApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const incomeStatementsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/comptes-de-résultat", + beforeLoad: () => ({ + title: "Comptes de résultat", + description: "Endpoints API pour la structure du compte de résultat d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/IncomeStatementsApiDocPage.tsx"), + "IncomeStatementsApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/journalsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/journalsApiDocRoute.tsx new file mode 100644 index 00000000..3d77ab40 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/journalsApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const journalsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/journaux", + beforeLoad: () => ({ + title: "Journaux", + description: "Endpoints API pour la gestion des journaux comptables d'un exercice Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/JournalsApiDocPage.tsx"), + "JournalsApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/orgUsersApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/orgUsersApiDocRoute.tsx new file mode 100644 index 00000000..3b8d017d --- /dev/null +++ b/packages/website/src/routes/root/docs/api/orgUsersApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const orgUsersApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/membres", + beforeLoad: () => ({ + title: "Membres", + description: "Endpoints API pour la gestion des membres d'une organisation Arrhes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/OrgUsersApiDocPage.tsx"), + "OrgUsersApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/api/tagsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/tagsApiDocRoute.tsx new file mode 100644 index 00000000..b8c4f0ce --- /dev/null +++ b/packages/website/src/routes/root/docs/api/tagsApiDocRoute.tsx @@ -0,0 +1,12 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const tagsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/libellés", + beforeLoad: () => ({ + title: "Libellés", + description: "Endpoints API pour la gestion des libellés d'écriture d'un exercice Arrhes.", + }), + component: lazyRouteComponent(() => import("../../../../features/docs/api/TagsApiDocPage.tsx"), "TagsApiDocPage"), +}) diff --git a/packages/website/src/routes/root/docs/api/xbrlReportsApiDocRoute.tsx b/packages/website/src/routes/root/docs/api/xbrlReportsApiDocRoute.tsx new file mode 100644 index 00000000..0e92cb12 --- /dev/null +++ b/packages/website/src/routes/root/docs/api/xbrlReportsApiDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { apiDocLayoutRoute } from "./apiDocLayoutRoute.tsx" + +export const xbrlReportsApiDocRoute = createRoute({ + getParentRoute: () => apiDocLayoutRoute, + path: "/exports", + beforeLoad: () => ({ + title: "Exports", + description: "Endpoints API pour la génération de rapports comptables XBRL (taxonomie ANC française).", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/api/XBRLReportsApiDocPage.tsx"), + "XBRLReportsApiDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/authenticationCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/authenticationCliDocRoute.tsx new file mode 100644 index 00000000..9cdaea3d --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/authenticationCliDocRoute.tsx @@ -0,0 +1,16 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { cliDocLayoutRoute } from "./cliDocLayoutRoute.js" + +export const authenticationCliDocRoute = createRoute({ + getParentRoute: () => cliDocLayoutRoute, + path: "/authentification", + beforeLoad: () => ({ + title: "Authentification", + description: + "Connectez le CLI Arrhes à votre compte via une clé API et configurez votre organisation par défaut.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/cli/AuthenticationCliDocPage.js"), + "AuthenticationCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/cliDocLayoutRoute.tsx b/packages/website/src/routes/root/docs/cli/cliDocLayoutRoute.tsx new file mode 100644 index 00000000..745f6bca --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/cliDocLayoutRoute.tsx @@ -0,0 +1,8 @@ +import { createRoute, Outlet } from "@tanstack/react-router" +import { docsLayoutRoute } from "../docsLayoutRoute.js" + +export const cliDocLayoutRoute = createRoute({ + getParentRoute: () => docsLayoutRoute, + path: "/cli", + component: () => , +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/balanceSheetsCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/balanceSheetsCommandsCliDocRoute.tsx new file mode 100644 index 00000000..ddc1d816 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/balanceSheetsCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const balanceSheetsCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/bilans", + beforeLoad: () => ({ + title: "Bilans", + description: "Commandes de gestion de la structure du bilan comptable : arrhes balance-sheets.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/BalanceSheetsCommandsCliDocPage.js"), + "BalanceSheetsCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/clesApiCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/clesApiCommandsCliDocRoute.tsx new file mode 100644 index 00000000..c579bd7b --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/clesApiCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const clesApiCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/cles-api", + beforeLoad: () => ({ + title: "Clés API", + description: "Commandes de gestion des clés API : arrhes api-keys.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/ClesApiCommandsCliDocPage.js"), + "ClesApiCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/commandsCliDocTree.ts b/packages/website/src/routes/root/docs/cli/commands/commandsCliDocTree.ts new file mode 100644 index 00000000..967a51a4 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/commandsCliDocTree.ts @@ -0,0 +1,29 @@ +import type { AnyRoute } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" +import { balanceSheetsCommandsCliDocRoute } from "./balanceSheetsCommandsCliDocRoute.js" +import { clesApiCommandsCliDocRoute } from "./clesApiCommandsCliDocRoute.js" +import { comptesCommandsCliDocRoute } from "./comptesCommandsCliDocRoute.js" +import { ecrituresCommandsCliDocRoute } from "./ecrituresCommandsCliDocRoute.js" +import { exercicesCommandsCliDocRoute } from "./exercicesCommandsCliDocRoute.js" +import { exportsCommandsCliDocRoute } from "./exportsCommandsCliDocRoute.js" +import { fichiersCommandsCliDocRoute } from "./fichiersCommandsCliDocRoute.js" +import { incomeStatementsCommandsCliDocRoute } from "./incomeStatementsCommandsCliDocRoute.js" +import { journauxCommandsCliDocRoute } from "./journauxCommandsCliDocRoute.js" +import { libellesCommandsCliDocRoute } from "./libellesCommandsCliDocRoute.js" +import { membresCommandsCliDocRoute } from "./membresCommandsCliDocRoute.js" +import { orgCommandsCliDocRoute } from "./orgCommandsCliDocRoute.js" + +export const commandsCliDocTree: AnyRoute = commandsCliDocLayoutRoute.addChildren([ + orgCommandsCliDocRoute, + exercicesCommandsCliDocRoute, + journauxCommandsCliDocRoute, + comptesCommandsCliDocRoute, + libellesCommandsCliDocRoute, + ecrituresCommandsCliDocRoute, + fichiersCommandsCliDocRoute, + membresCommandsCliDocRoute, + clesApiCommandsCliDocRoute, + exportsCommandsCliDocRoute, + balanceSheetsCommandsCliDocRoute, + incomeStatementsCommandsCliDocRoute, +]) diff --git a/packages/website/src/routes/root/docs/cli/commands/comptesCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/comptesCommandsCliDocRoute.tsx new file mode 100644 index 00000000..2702f412 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/comptesCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const comptesCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/comptes", + beforeLoad: () => ({ + title: "Comptes", + description: "Commandes de gestion du plan comptable : arrhes accounts.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/ComptesCommandsCliDocPage.js"), + "ComptesCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/ecrituresCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/ecrituresCommandsCliDocRoute.tsx new file mode 100644 index 00000000..84668e7c --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/ecrituresCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const ecrituresCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/ecritures", + beforeLoad: () => ({ + title: "Écritures", + description: "Commandes de gestion des écritures comptables : arrhes entries list, get, create et delete.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/EcrituresCommandsCliDocPage.js"), + "EcrituresCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/exercicesCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/exercicesCommandsCliDocRoute.tsx new file mode 100644 index 00000000..22569a24 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/exercicesCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const exercicesCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/exercices", + beforeLoad: () => ({ + title: "Exercices", + description: "Commandes de gestion des exercices comptables : arrhes years list, get et create.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/ExercicesCommandsCliDocPage.js"), + "ExercicesCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/exportsCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/exportsCommandsCliDocRoute.tsx new file mode 100644 index 00000000..34323ae0 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/exportsCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const exportsCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/exports", + beforeLoad: () => ({ + title: "Exports", + description: "Commandes d'export comptable : arrhes exports.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/ExportsCommandsCliDocPage.js"), + "ExportsCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/fichiersCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/fichiersCommandsCliDocRoute.tsx new file mode 100644 index 00000000..7f23ca71 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/fichiersCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const fichiersCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/stockage", + beforeLoad: () => ({ + title: "Stockage", + description: "Commandes de gestion des fichiers et dossiers d'un exercice : arrhes files.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/FichiersCommandsCliDocPage.js"), + "FichiersCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/incomeStatementsCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/incomeStatementsCommandsCliDocRoute.tsx new file mode 100644 index 00000000..388124a4 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/incomeStatementsCommandsCliDocRoute.tsx @@ -0,0 +1,16 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const incomeStatementsCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/comptes-de-resultat", + beforeLoad: () => ({ + title: "Comptes de résultat", + description: + "Commandes de gestion de la structure du compte de résultat et des calculs : arrhes income-statements.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/IncomeStatementsCommandsCliDocPage.js"), + "IncomeStatementsCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/journauxCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/journauxCommandsCliDocRoute.tsx new file mode 100644 index 00000000..9d3abc41 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/journauxCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const journauxCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/journaux", + beforeLoad: () => ({ + title: "Journaux", + description: "Commandes de gestion des journaux comptables : arrhes journals.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/JournauxCommandsCliDocPage.js"), + "JournauxCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/libellesCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/libellesCommandsCliDocRoute.tsx new file mode 100644 index 00000000..2da28fbb --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/libellesCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const libellesCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/libelles", + beforeLoad: () => ({ + title: "Libellés", + description: "Commandes de gestion des libellés (tags) : arrhes tags.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/LibellesCommandsCliDocPage.js"), + "LibellesCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/membresCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/membresCommandsCliDocRoute.tsx new file mode 100644 index 00000000..324c544f --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/membresCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const membresCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/membres", + beforeLoad: () => ({ + title: "Membres", + description: "Commandes de gestion des membres d'une organisation : arrhes members.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/MembresCommandsCliDocPage.js"), + "MembresCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commands/orgCommandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commands/orgCommandsCliDocRoute.tsx new file mode 100644 index 00000000..b8c1b711 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commands/orgCommandsCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { commandsCliDocLayoutRoute } from "../commandsCliDocRoute.js" + +export const orgCommandsCliDocRoute = createRoute({ + getParentRoute: () => commandsCliDocLayoutRoute, + path: "/organisation", + beforeLoad: () => ({ + title: "Organisation", + description: "Commandes de gestion de l'organisation configurée : arrhes org.", + }), + component: lazyRouteComponent( + () => import("../../../../../features/docs/cli/commands/OrgCommandsCliDocPage.js"), + "OrgCommandsCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/commandsCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/commandsCliDocRoute.tsx new file mode 100644 index 00000000..adbaaed9 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/commandsCliDocRoute.tsx @@ -0,0 +1,8 @@ +import { createRoute, Outlet } from "@tanstack/react-router" +import { cliDocLayoutRoute } from "./cliDocLayoutRoute.js" + +export const commandsCliDocLayoutRoute = createRoute({ + getParentRoute: () => cliDocLayoutRoute, + path: "/commandes", + component: () => , +}) diff --git a/packages/website/src/routes/root/docs/cli/demarrerCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/demarrerCliDocRoute.tsx new file mode 100644 index 00000000..9caf8108 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/demarrerCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { cliDocLayoutRoute } from "./cliDocLayoutRoute.js" + +export const demarrerCliDocRoute = createRoute({ + getParentRoute: () => cliDocLayoutRoute, + path: "/demarrer", + beforeLoad: () => ({ + title: "Démarrer", + description: "Mettre en place le CLI Arrhes et effectuer votre première opération en moins de 5 minutes.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/cli/DemarrerCliDocPage.js"), + "DemarrerCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/installationCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/installationCliDocRoute.tsx new file mode 100644 index 00000000..1a578e0d --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/installationCliDocRoute.tsx @@ -0,0 +1,15 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { cliDocLayoutRoute } from "./cliDocLayoutRoute.js" + +export const installationCliDocRoute = createRoute({ + getParentRoute: () => cliDocLayoutRoute, + path: "/installation", + beforeLoad: () => ({ + title: "Installation", + description: "Installez le CLI Arrhes sur macOS et Linux en une commande. Seul curl est requis.", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/cli/InstallationCliDocPage.js"), + "InstallationCliDocPage", + ), +}) diff --git a/packages/website/src/routes/root/docs/cli/rootCliDocRoute.tsx b/packages/website/src/routes/root/docs/cli/rootCliDocRoute.tsx new file mode 100644 index 00000000..1ba46fc4 --- /dev/null +++ b/packages/website/src/routes/root/docs/cli/rootCliDocRoute.tsx @@ -0,0 +1,13 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { cliDocLayoutRoute } from "./cliDocLayoutRoute.js" + +export const rootCliDocRoute = createRoute({ + getParentRoute: () => cliDocLayoutRoute, + path: "/", + beforeLoad: () => ({ + title: "CLI", + description: + "Présentation de l'interface en ligne de commande Arrhes : automatisez la gestion de votre comptabilité depuis le terminal.", + }), + component: lazyRouteComponent(() => import("../../../../features/docs/cli/RootCliDocPage.js"), "RootCliDocPage"), +}) diff --git a/packages/website/src/routes/root/docs/docsTree.ts b/packages/website/src/routes/root/docs/docsTree.ts index 9884406e..d76ca1a8 100644 --- a/packages/website/src/routes/root/docs/docsTree.ts +++ b/packages/website/src/routes/root/docs/docsTree.ts @@ -9,13 +9,28 @@ import { modelsAiDocRoute } from "./ai/modelsAiDocRoute.js" import { ocrAiDocRoute } from "./ai/ocrAiDocRoute.js" import { rootAiDocRoute } from "./ai/rootAiDocRoute.js" import { toolsAiDocRoute } from "./ai/toolsAiDocRoute.js" +import { accountsApiDocRoute } from "./api/accountsApiDocRoute.js" import { apiDocLayoutRoute } from "./api/apiDocLayoutRoute.js" +import { apiKeysApiDocRoute } from "./api/apiKeysApiDocRoute.js" import { authenticationApiDocRoute } from "./api/authenticationApiDocRoute.js" +import { balanceSheetsApiDocRoute } from "./api/balanceSheetsApiDocRoute.js" +import { entriesApiDocRoute } from "./api/entriesApiDocRoute.js" import { filesApiDocRoute } from "./api/filesApiDocRoute.js" +import { incomeStatementsApiDocRoute } from "./api/incomeStatementsApiDocRoute.js" import { introductionApiDocRoute } from "./api/introductionApiDocRoute.js" +import { journalsApiDocRoute } from "./api/journalsApiDocRoute.js" import { organizationApiDocRoute } from "./api/organizationApiDocRoute.js" +import { orgUsersApiDocRoute } from "./api/orgUsersApiDocRoute.js" import { rootApiDocRoute } from "./api/rootApiDocRoute.js" +import { tagsApiDocRoute } from "./api/tagsApiDocRoute.js" +import { xbrlReportsApiDocRoute } from "./api/xbrlReportsApiDocRoute.js" import { yearApiDocRoute } from "./api/yearApiDocRoute.js" +import { authenticationCliDocRoute } from "./cli/authenticationCliDocRoute.js" +import { cliDocLayoutRoute } from "./cli/cliDocLayoutRoute.js" +import { commandsCliDocTree } from "./cli/commands/commandsCliDocTree.js" +import { demarrerCliDocRoute } from "./cli/demarrerCliDocRoute.js" +import { installationCliDocRoute } from "./cli/installationCliDocRoute.js" +import { rootCliDocRoute } from "./cli/rootCliDocRoute.js" import { billingDashboardDocRoute } from "./dashboard/BillingDashboardDocRoute.js" import { dashboardDocLayoutRoute } from "./dashboard/dashboardDocLayoutRoute.js" import { entriesDashboardDocRoute } from "./dashboard/entriesDashboardDocRoute.js" @@ -58,6 +73,15 @@ export const docsTree: AnyRoute = docsLayoutRoute.addChildren([ resourcesAccountingTree, ]), + // CLI section + cliDocLayoutRoute.addChildren([ + rootCliDocRoute, + installationCliDocRoute, + demarrerCliDocRoute, + authenticationCliDocRoute, + commandsCliDocTree, + ]), + // Dashboard section (guide d'utilisation) dashboardDocLayoutRoute.addChildren([ rootDashboardDocRoute, @@ -84,7 +108,16 @@ export const docsTree: AnyRoute = docsLayoutRoute.addChildren([ introductionApiDocRoute, authenticationApiDocRoute, organizationApiDocRoute, - yearApiDocRoute, + apiKeysApiDocRoute, + orgUsersApiDocRoute, filesApiDocRoute, + yearApiDocRoute, + accountsApiDocRoute, + journalsApiDocRoute, + balanceSheetsApiDocRoute, + incomeStatementsApiDocRoute, + tagsApiDocRoute, + entriesApiDocRoute, + xbrlReportsApiDocRoute, ]), ]) diff --git a/packages/website/src/utilities/getResponseBodyFromAPI.ts b/packages/website/src/utilities/getResponseBodyFromAPI.ts index d93b40bc..fe58a2bf 100644 --- a/packages/website/src/utilities/getResponseBodyFromAPI.ts +++ b/packages/website/src/utilities/getResponseBodyFromAPI.ts @@ -7,6 +7,51 @@ import { resolveApiBaseUrl } from "./resolveApiBaseUrl.js" import { validate } from "./validate.js" import { cookiePrefix } from "./variables.js" +/** + * Interpolates URL path params (e.g. `:idOrganization`) with values from the + * `params` map. Any remaining body fields (not consumed as path params) are + * sent as query string for GET requests, or as the JSON body for POST/PATCH/DELETE. + */ +function buildUrl( + apiBaseUrl: string, + rawPath: string, + params: Record | undefined, + body: Record, + method: "GET" | "POST" | "PATCH" | "DELETE", +): { + url: URL + remainingBody: Record +} { + let path = rawPath + const consumed = new Set() + + if (params) { + for (const [key, value] of Object.entries(params)) { + const token = `:${key}` + if (path.includes(token)) { + path = path.replace(token, encodeURIComponent(value)) + consumed.add(key) + } + } + } + + const url = new URL(`${apiBaseUrl}${path}`) + const remaining = Object.fromEntries(Object.entries(body).filter(([k]) => !consumed.has(k))) + + if (method === "GET") { + for (const [key, value] of Object.entries(remaining)) { + if (value !== undefined && value !== null) { + url.searchParams.set(key, String(value)) + } + } + } + + return { + url, + remainingBody: remaining, + } +} + export async function getResponseBodyFromAPI< TSchemaBody extends v.ObjectSchema, TSchemaReturn extends @@ -15,6 +60,8 @@ export async function getResponseBodyFromAPI< >(parameters: { routeDefinition: ReturnType> body: v.InferOutput + /** URL path params to interpolate (e.g. `{ idOrganization: "abc" }` for `:idOrganization`) */ + params?: Record signal?: AbortSignal hasToastMessage?: boolean }) { @@ -34,6 +81,7 @@ export async function getResponseBodyFromAPI< } } + const method = parameters.routeDefinition.method const abortController = parameters.signal ? undefined : new AbortController() const signal = parameters.signal ?? abortController!.signal try { @@ -46,17 +94,25 @@ export async function getResponseBodyFromAPI< headers["X-Organization-Id"] = idOrganization } - const response = await fetch(new URL(`${apiBaseUrl}${parameters.routeDefinition.path}`), { - method: "POST", + const { url, remainingBody } = buildUrl( + apiBaseUrl, + parameters.routeDefinition.path, + parameters.params, + parameters.body as Record, + method, + ) + + const response = await fetch(url, { + method, headers, credentials: "include", - body: JSON.stringify(parameters.body), + body: method === "GET" ? undefined : JSON.stringify(remainingBody), signal, }) const jsonResponse = JSON.parse((await response.text()) || "{}") if (response.ok === false) { throw new ClientError({ - message: "Error with the POST request response", + message: `Error with the ${method} request response`, cause: jsonResponse.cause ?? jsonResponse.message, }) } diff --git a/packages/website/src/utilities/prefetchYearData.ts b/packages/website/src/utilities/prefetchYearData.ts index 35b1c83a..5828f950 100644 --- a/packages/website/src/utilities/prefetchYearData.ts +++ b/packages/website/src/utilities/prefetchYearData.ts @@ -21,6 +21,7 @@ type YearScopedBody = { } type YearScopedRouteDefinition = { + method: "GET" | "POST" | "PATCH" | "DELETE" path: string schemas: { body: v.ObjectSchema diff --git a/packages/website/src/utilities/useHTTPData.ts b/packages/website/src/utilities/useHTTPData.ts index 971bf691..d5018730 100644 --- a/packages/website/src/utilities/useHTTPData.ts +++ b/packages/website/src/utilities/useHTTPData.ts @@ -13,18 +13,22 @@ export function useDataFromAPI< >(parameters: { routeDefinition: ReturnType> body: v.InferOutput + /** URL path params to interpolate (e.g. `{ idOrganization: "abc" }` for `:idOrganization`) */ + params?: Record enabled?: boolean select?: (data: v.InferOutput) => TSelected }) { return useQuery({ queryKey: [ parameters.routeDefinition.path, + parameters.params, parameters.body, ], queryFn: async (context) => { const response = await getResponseBodyFromAPI({ routeDefinition: parameters.routeDefinition, body: parameters.body, + params: parameters.params, signal: context.signal, }) if (response.ok === false) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f87f4037..c6f80838 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,6 +85,37 @@ importers: specifier: 4.1.5 version: 4.1.5(@types/node@25.6.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)) + packages/cli: + dependencies: + '@arrhes/application-metadata': + specifier: workspace:* + version: link:../metadata + commander: + specifier: 14.0.0 + version: 14.0.0 + valibot: + specifier: 1.4.0 + version: 1.4.0(typescript@6.0.3) + devDependencies: + '@types/node': + specifier: 25.6.0 + version: 25.6.0 + '@yao-pkg/pkg': + specifier: 5.16.0 + version: 5.16.0 + postject: + specifier: 1.0.0-alpha.6 + version: 1.0.0-alpha.6 + tsup: + specifier: 8.5.0 + version: 8.5.0(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0)(typescript@6.0.3) + tsx: + specifier: 4.21.0 + version: 4.21.0 + typescript: + specifier: 6.0.3 + version: 6.0.3 + packages/metadata: dependencies: drizzle-orm: @@ -478,6 +509,10 @@ packages: resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} engines: {node: '>=18.0.0'} + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -525,24 +560,28 @@ packages: engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [musl] '@biomejs/cli-linux-arm64@2.4.14': resolution: {integrity: sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] + libc: [glibc] '@biomejs/cli-linux-x64-musl@2.4.14': resolution: {integrity: sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [musl] '@biomejs/cli-linux-x64@2.4.14': resolution: {integrity: sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] + libc: [glibc] '@biomejs/cli-win32-arm64@2.4.14': resolution: {integrity: sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==} @@ -1108,9 +1147,19 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} @@ -1393,36 +1442,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} @@ -1453,6 +1508,144 @@ packages: '@rolldown/pluginutils@1.0.0-rc.7': resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} + '@rollup/rollup-android-arm-eabi@4.60.4': + resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.4': + resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.4': + resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.4': + resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.4': + resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.4': + resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.4': + resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.4': + resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.4': + resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.4': + resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.4': + resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.4': + resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.4': + resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.4': + resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.4': + resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.4': + resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.4': + resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.4': + resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.4': + resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.4': + resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.4': + resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.4': + resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.4': + resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.4': + resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} + cpu: [x64] + os: [win32] + '@smithy/chunked-blob-reader-native@4.2.3': resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} engines: {node: '>=18.0.0'} @@ -1887,6 +2080,14 @@ packages: '@vue/shared@3.5.25': resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + '@yao-pkg/pkg-fetch@3.5.15': + resolution: {integrity: sha512-KTM1PszA2zRlJThfDZVDgnXJ5dnPgowiyYa/DT3Y9k7EG6A/xo4+dZEaXV5k3XF/txelxBlBcej8BrKYi59bOQ==} + hasBin: true + + '@yao-pkg/pkg@5.16.0': + resolution: {integrity: sha512-3CwgxegupGB6JHG3ebFA7w2ArCLIp1UihnKh8uFusA0BseFGUPkmloP9srb+DOXdt/ZNWW+ZAFUKFeCK0HKQHw==} + hasBin: true + abs-svg-path@0.1.1: resolution: {integrity: sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==} @@ -1894,6 +2095,15 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -1929,6 +2139,9 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1968,6 +2181,9 @@ packages: bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + body-parser@2.2.2: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} @@ -2003,6 +2219,9 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + bull@4.16.5: resolution: {integrity: sha512-lDsx2BzkKe7gkCYiT5Acj02DpTwDznl/VNN7Psn7M3USPG7Vs/BaClZJJTAG+ufAR9++N1/NiUTdaFBWDIl5TQ==} engines: {node: '>=12'} @@ -2010,6 +2229,12 @@ packages: bundle-n-require@1.1.2: resolution: {integrity: sha512-bEk2jakVK1ytnZ9R2AAiZEeK/GxPUM8jvcRxHZXifZDMcjkI4EG/GlsJ2YGSVYT9y/p/gA9/0yDY8rCGsSU6Tg==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -2052,6 +2277,12 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2089,9 +2320,28 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@14.0.0: + resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} + engines: {node: '>=20'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@1.1.0: resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} engines: {node: '>=18'} @@ -2117,6 +2367,9 @@ packages: core-js-pure@3.49.0: resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} @@ -2157,6 +2410,14 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -2384,6 +2645,10 @@ packages: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} engines: {node: '>=18.0.0'} + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -2448,6 +2713,9 @@ packages: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + fontkit@2.0.4: resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} @@ -2471,6 +2739,12 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@11.3.2: resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} engines: {node: '>=14.14'} @@ -2523,6 +2797,9 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2606,6 +2883,10 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -2617,6 +2898,9 @@ packages: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + imask@7.6.1: resolution: {integrity: sha512-sJlIFM7eathUEMChTh9Mrfw/IgiWgJqBKq2VNbyXvBZ7ev/IlO6/KQTKlV/Fm+viQMLrFLG/zCuudrLIwgK2dg==} engines: {npm: '>=4.0.0'} @@ -2624,9 +2908,16 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + into-stream@6.0.0: + resolution: {integrity: sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==} + engines: {node: '>=10'} + ioredis@5.10.1: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} @@ -2645,6 +2936,10 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -2681,6 +2976,9 @@ packages: is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isbot@5.1.40: resolution: {integrity: sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ==} engines: {node: '>=18'} @@ -2704,12 +3002,21 @@ packages: jose@6.2.3: resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-md5@0.8.3: resolution: {integrity: sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-bigint@1.0.0: resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} @@ -2797,48 +3104,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.32.0: resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.31.1: resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.31.1: resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.31.1: resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.31.1: resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} @@ -2872,9 +3187,20 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + linebreak@1.1.0: resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -2887,6 +3213,9 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} @@ -3054,6 +3383,10 @@ packages: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} @@ -3062,10 +3395,19 @@ packages: resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3076,6 +3418,12 @@ packages: msgpackr@1.11.12: resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} + multistream@4.1.0: + resolution: {integrity: sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3086,10 +3434,17 @@ packages: engines: {node: ^18 || >=20} hasBin: true + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + negotiator@1.0.0: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + node-abi@3.92.0: + resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} + engines: {node: '>=10'} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -3170,6 +3525,10 @@ packages: outdent@0.8.0: resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} + p-is-promise@3.0.0: + resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} + engines: {node: '>=8'} + p-limit@5.0.0: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} engines: {node: '>=18'} @@ -3218,6 +3577,9 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -3242,10 +3604,17 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} @@ -3278,6 +3647,24 @@ packages: peerDependencies: postcss: ^8.4.32 + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postcss-minify-selectors@7.0.5: resolution: {integrity: sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -3315,11 +3702,29 @@ packages: resolution: {integrity: sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw==} engines: {node: '>=12'} + postject@1.0.0-alpha.6: + resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} + engines: {node: '>=14.0.0'} + hasBin: true + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + prettier@3.2.5: resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -3338,6 +3743,13 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + qs@6.15.1: resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} @@ -3356,6 +3768,10 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + react-dom@19.2.6: resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: @@ -3386,6 +3802,9 @@ packages: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3416,9 +3835,18 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + restructure@3.0.2: resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} @@ -3443,6 +3871,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rollup@4.60.4: + resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -3453,6 +3886,9 @@ packages: ruply@1.0.1: resolution: {integrity: sha512-p39LnaaJyuucPGlgaB0KiyifpcuOkn24+Hq5y0ejAD/LlH+mRAbkHn2tckCLgHir+S+nis1WYG+TYEC4zHX0WQ==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -3525,6 +3961,12 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -3543,6 +3985,11 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions + space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -3562,6 +4009,9 @@ packages: stream-events@1.0.5: resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} + stream-meter@1.0.4: + resolution: {integrity: sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==} + stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} @@ -3573,6 +4023,9 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -3587,6 +4040,10 @@ packages: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strnum@2.2.3: resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} @@ -3599,6 +4056,15 @@ packages: style-to-object@1.0.14: resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + svg-arc-to-cubic-bezier@3.2.0: resolution: {integrity: sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==} @@ -3606,16 +4072,33 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + teeny-request@10.1.2: resolution: {integrity: sha512-Xj0ZAQ0CeuQn6UxCDPLbFRlgcSTUEyO3+wiepr2grjIjyL/lMMs1Z4OwXn8kLvn/V1OuaEP0UY7Na6UDNNsYrQ==} engines: {node: '>=18'} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -3639,6 +4122,13 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -3655,6 +4145,9 @@ packages: jsdom: optional: true + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-morph@28.0.0: resolution: {integrity: sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==} @@ -3664,11 +4157,33 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.0: + resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + tsx@4.21.0: resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} hasBin: true + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -3683,6 +4198,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + undici-types@7.19.2: resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} @@ -3858,12 +4376,18 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -3905,10 +4429,18 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -4405,6 +4937,14 @@ snapshots: '@aws/lambda-invoke-store@0.2.4': {} + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -4812,8 +5352,20 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@js-sdsl/ordered-map@4.4.2': {} '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': @@ -5309,6 +5861,81 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.7': {} + '@rollup/rollup-android-arm-eabi@4.60.4': + optional: true + + '@rollup/rollup-android-arm64@4.60.4': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.4': + optional: true + + '@rollup/rollup-darwin-x64@4.60.4': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.4': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.4': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.4': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.4': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.4': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.4': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.4': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.4': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.4': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.4': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.4': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.4': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.4': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.4': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.4': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.4': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.4': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.4': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.4': + optional: true + '@smithy/chunked-blob-reader-native@4.2.3': dependencies: '@smithy/util-base64': 4.3.2 @@ -5890,6 +6517,38 @@ snapshots: '@vue/shared@3.5.25': {} + '@yao-pkg/pkg-fetch@3.5.15': + dependencies: + https-proxy-agent: 5.0.1 + node-fetch: 2.7.0 + picocolors: 1.1.1 + progress: 2.0.3 + semver: 7.7.4 + tar-fs: 2.1.4 + yargs: 16.2.0 + transitivePeerDependencies: + - encoding + - supports-color + + '@yao-pkg/pkg@5.16.0': + dependencies: + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@yao-pkg/pkg-fetch': 3.5.15 + into-stream: 6.0.0 + minimist: 1.2.8 + multistream: 4.1.0 + picocolors: 1.1.1 + picomatch: 4.0.4 + prebuild-install: 7.1.3 + resolve: 1.22.12 + stream-meter: 1.0.4 + tinyglobby: 0.2.16 + transitivePeerDependencies: + - encoding + - supports-color + abs-svg-path@0.1.1: {} accepts@2.0.0: @@ -5897,6 +6556,14 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 + acorn@8.16.0: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} ajv-formats@3.0.1(ajv@8.20.0): @@ -5922,6 +6589,8 @@ snapshots: ansi-styles@6.2.3: {} + any-promise@1.3.0: {} + assertion-error@2.0.1: {} astral-regex@2.0.0: {} @@ -5946,6 +6615,12 @@ snapshots: bignumber.js@9.3.1: {} + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + body-parser@2.2.2: dependencies: bytes: 3.1.2 @@ -5994,6 +6669,11 @@ snapshots: buffer-from@1.1.2: {} + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bull@4.16.5: dependencies: cron-parser: 4.9.0 @@ -6011,6 +6691,11 @@ snapshots: esbuild: 0.25.12 node-eval: 2.0.0 + bundle-require@5.1.0(esbuild@0.25.12): + dependencies: + esbuild: 0.25.12 + load-tsconfig: 0.2.5 + bytes@3.1.2: {} cac@6.7.14: {} @@ -6043,6 +6728,14 @@ snapshots: dependencies: readdirp: 4.1.2 + chownr@1.1.4: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -6073,8 +6766,18 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@14.0.0: {} + + commander@4.1.1: {} + + commander@9.5.0: {} + + confbox@0.1.8: {} + confbox@0.2.4: {} + consola@3.4.2: {} + content-disposition@1.1.0: {} content-type@1.0.5: {} @@ -6089,6 +6792,8 @@ snapshots: core-js-pure@3.49.0: {} + core-util-is@1.0.3: {} + cors@2.8.6: dependencies: object-assign: 4.1.1 @@ -6122,6 +6827,12 @@ snapshots: dependencies: character-entities: 2.0.2 + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-extend@0.6.0: {} + delayed-stream@1.0.0: {} denque@2.1.0: {} @@ -6308,6 +7019,8 @@ snapshots: dependencies: eventsource-parser: 3.0.8 + expand-template@2.0.3: {} + expect-type@1.3.0: {} express-rate-limit@8.5.1(express@5.2.1): @@ -6405,6 +7118,12 @@ snapshots: transitivePeerDependencies: - supports-color + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.2 + rollup: 4.60.4 + fontkit@2.0.4: dependencies: '@swc/helpers': 0.5.21 @@ -6438,6 +7157,13 @@ snapshots: fresh@2.0.0: {} + from2@2.3.0: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + fs-constants@1.0.0: {} + fs-extra@11.3.2: dependencies: graceful-fs: 4.2.11 @@ -6514,6 +7240,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + github-from-package@0.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -6645,6 +7373,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -6658,14 +7393,23 @@ snapshots: dependencies: safer-buffer: 2.1.2 + ieee754@1.2.1: {} + imask@7.6.1: dependencies: '@babel/runtime-corejs3': 7.29.2 inherits@2.0.4: {} + ini@1.3.8: {} + inline-style-parser@0.2.7: {} + into-stream@6.0.0: + dependencies: + from2: 2.3.0 + p-is-promise: 3.0.0 + ioredis@5.10.1: dependencies: '@ioredis/commands': 1.5.1 @@ -6691,6 +7435,10 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + is-core-module@2.16.2: + dependencies: + hasown: 2.0.3 + is-decimal@2.0.1: {} is-extglob@2.1.1: {} @@ -6713,6 +7461,8 @@ snapshots: is-url@1.2.4: {} + isarray@1.0.0: {} + isbot@5.1.40: {} isexe@2.0.0: {} @@ -6734,10 +7484,14 @@ snapshots: jose@6.2.3: {} + joycon@3.1.1: {} + js-md5@0.8.3: {} js-tokens@4.0.0: {} + jsesc@3.1.0: {} + json-bigint@1.0.0: dependencies: bignumber.js: 9.3.1 @@ -6863,11 +7617,17 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + lilconfig@3.1.3: {} + linebreak@1.1.0: dependencies: base64-js: 0.0.8 unicode-trie: 2.0.0 + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + lodash.camelcase@4.3.0: {} lodash.defaults@4.2.0: {} @@ -6876,6 +7636,8 @@ snapshots: lodash.merge@4.6.2: {} + lodash.sortby@4.7.0: {} + lodash.truncate@4.4.2: {} lodash@4.18.1: {} @@ -7169,6 +7931,8 @@ snapshots: dependencies: mime-db: 1.54.0 + mimic-response@3.1.0: {} + minimatch@10.2.5: dependencies: brace-expansion: 5.0.5 @@ -7177,8 +7941,19 @@ snapshots: dependencies: brace-expansion: 2.1.0 + minimist@1.2.8: {} + minipass@7.1.3: {} + mkdirp-classic@0.5.3: {} + + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + ms@2.1.3: {} msgpackr-extract@3.0.3: @@ -7197,12 +7972,29 @@ snapshots: optionalDependencies: msgpackr-extract: 3.0.3 + multistream@4.1.0: + dependencies: + once: 1.4.0 + readable-stream: 3.6.2 + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@3.3.12: {} nanoid@5.1.11: {} + napi-build-utils@2.0.0: {} + negotiator@1.0.0: {} + node-abi@3.92.0: + dependencies: + semver: 7.7.4 + node-domexception@1.0.0: {} node-eval@2.0.0: @@ -7261,6 +8053,8 @@ snapshots: outdent@0.8.0: {} + p-is-promise@3.0.0: {} + p-limit@5.0.0: dependencies: yocto-queue: 1.2.2 @@ -7302,6 +8096,8 @@ snapshots: path-key@3.1.1: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -7319,8 +8115,16 @@ snapshots: picomatch@4.0.4: {} + pirates@4.0.7: {} + pkce-challenge@5.0.1: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + pkg-types@2.3.0: dependencies: confbox: 0.2.4 @@ -7349,6 +8153,14 @@ snapshots: dependencies: postcss: 8.5.6 + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.14 + tsx: 4.21.0 + postcss-minify-selectors@7.0.5(postcss@8.5.6): dependencies: cssesc: 3.0.0 @@ -7386,8 +8198,31 @@ snapshots: postgres@3.4.9: {} + postject@1.0.0-alpha.6: + dependencies: + commander: 9.5.0 + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.92.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + prettier@3.2.5: {} + process-nextick-args@2.0.1: {} + + progress@2.0.3: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -7420,6 +8255,13 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@2.3.1: {} + qs@6.15.1: dependencies: side-channel: 1.1.0 @@ -7439,6 +8281,13 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + react-dom@19.2.6(react@19.2.6): dependencies: react: 19.2.6 @@ -7476,6 +8325,16 @@ snapshots: react@19.2.6: {} + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -7511,8 +8370,17 @@ snapshots: require-from-string@2.0.2: {} + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + restructure@3.0.2: {} retry-request@8.0.2: @@ -7551,6 +8419,37 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + rollup@4.60.4: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.4 + '@rollup/rollup-android-arm64': 4.60.4 + '@rollup/rollup-darwin-arm64': 4.60.4 + '@rollup/rollup-darwin-x64': 4.60.4 + '@rollup/rollup-freebsd-arm64': 4.60.4 + '@rollup/rollup-freebsd-x64': 4.60.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 + '@rollup/rollup-linux-arm-musleabihf': 4.60.4 + '@rollup/rollup-linux-arm64-gnu': 4.60.4 + '@rollup/rollup-linux-arm64-musl': 4.60.4 + '@rollup/rollup-linux-loong64-gnu': 4.60.4 + '@rollup/rollup-linux-loong64-musl': 4.60.4 + '@rollup/rollup-linux-ppc64-gnu': 4.60.4 + '@rollup/rollup-linux-ppc64-musl': 4.60.4 + '@rollup/rollup-linux-riscv64-gnu': 4.60.4 + '@rollup/rollup-linux-riscv64-musl': 4.60.4 + '@rollup/rollup-linux-s390x-gnu': 4.60.4 + '@rollup/rollup-linux-x64-gnu': 4.60.4 + '@rollup/rollup-linux-x64-musl': 4.60.4 + '@rollup/rollup-openbsd-x64': 4.60.4 + '@rollup/rollup-openharmony-arm64': 4.60.4 + '@rollup/rollup-win32-arm64-msvc': 4.60.4 + '@rollup/rollup-win32-ia32-msvc': 4.60.4 + '@rollup/rollup-win32-x64-gnu': 4.60.4 + '@rollup/rollup-win32-x64-msvc': 4.60.4 + fsevents: 2.3.3 + router@2.2.0: dependencies: debug: 4.4.3 @@ -7567,6 +8466,8 @@ snapshots: ruply@1.0.1: {} + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -7650,6 +8551,14 @@ snapshots: signal-exit@4.1.0: {} + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + sisteransi@1.0.5: {} slice-ansi@4.0.0: @@ -7667,6 +8576,10 @@ snapshots: source-map@0.6.1: {} + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + space-separated-tokens@2.0.2: {} stackback@0.0.2: {} @@ -7681,6 +8594,10 @@ snapshots: dependencies: stubs: 3.0.0 + stream-meter@1.0.4: + dependencies: + readable-stream: 2.3.8 + stream-shift@1.0.3: {} string-width@4.2.3: @@ -7695,6 +8612,10 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.2.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -7712,6 +8633,8 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-json-comments@2.0.1: {} + strnum@2.2.3: {} stubs@3.0.0: {} @@ -7724,6 +8647,18 @@ snapshots: dependencies: inline-style-parser: 0.2.7 + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.16 + ts-interface-checker: 0.1.13 + + supports-preserve-symlinks-flag@1.0.0: {} + svg-arc-to-cubic-bezier@3.2.0: {} table@6.9.0: @@ -7734,6 +8669,21 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + teeny-request@10.1.2: dependencies: http-proxy-agent: 7.0.2 @@ -7743,10 +8693,20 @@ snapshots: transitivePeerDependencies: - supports-color + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + tiny-inflate@1.0.3: {} tinybench@2.9.0: {} + tinyexec@0.3.2: {} + tinyexec@1.1.2: {} tinyglobby@0.2.16: @@ -7764,6 +8724,12 @@ snapshots: tr46@0.0.3: {} + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + trim-lines@3.0.1: {} trough@2.2.0: {} @@ -7775,6 +8741,8 @@ snapshots: object-path: 0.11.8 typescript: 6.0.3 + ts-interface-checker@0.1.13: {} + ts-morph@28.0.0: dependencies: '@ts-morph/common': 0.29.0 @@ -7784,6 +8752,34 @@ snapshots: tslib@2.8.1: {} + tsup@8.5.0(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0)(typescript@6.0.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.12) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.25.12 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0) + resolve-from: 5.0.0 + rollup: 4.60.4 + source-map: 0.8.0-beta.0 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.16 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.14 + typescript: 6.0.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsx@4.21.0: dependencies: esbuild: 0.27.7 @@ -7791,6 +8787,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -7801,6 +8801,8 @@ snapshots: typescript@6.0.3: {} + ufo@1.6.4: {} + undici-types@7.19.2: {} undici@6.25.0: {} @@ -7935,6 +8937,8 @@ snapshots: webidl-conversions@3.0.1: {} + webidl-conversions@4.0.2: {} + whatwg-fetch@3.6.20: {} whatwg-url@5.0.0: @@ -7942,6 +8946,12 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + which@2.0.2: dependencies: isexe: 2.0.0 @@ -7971,8 +8981,20 @@ snapshots: y18n@5.0.8: {} + yargs-parser@20.2.9: {} + yargs-parser@21.1.1: {} + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + yargs@17.7.2: dependencies: cliui: 8.0.1 diff --git a/scripts/migrate-handlers.mjs b/scripts/migrate-handlers.mjs new file mode 100644 index 00000000..dd733778 --- /dev/null +++ b/scripts/migrate-handlers.mjs @@ -0,0 +1,115 @@ +/** + * Batch migration script: updates all API handler files to use registerRoute() + * instead of apiFactory.createApp().post(routeDef.path, ...). + * + * Run from the monorepo root: + * node scripts/migrate-handlers.mjs + */ + +import { readFileSync, writeFileSync } from "node:fs" +import { glob } from "node:fs/promises" +import { join } from "node:path" + +const ROOT = new URL("../packages/api/src/routes", import.meta.url).pathname + +let filesUpdated = 0 +let filesSkipped = 0 + +for await (const entry of glob("**/*.ts", { + cwd: ROOT, +})) { + // Skip aggregator route files (they just import + chain sub-routes) + if (entry.endsWith("Routes.ts") || entry.endsWith("Route.ts")) { + filesSkipped++ + continue + } + + const filePath = join(ROOT, entry) + const original = readFileSync(filePath, "utf8") + let updated = original + + // Match: apiFactory.createApp().post(someRouteDefinition.path, async (c) => { + // Replace with: registerRoute(someRouteDefinition, async (c) => { + // Also handles .get(), .patch(), .delete() (idempotent — already migrated) + const methodPattern = + /apiFactory\.createApp\(\)\.(post|get|patch|delete)\((\w+(?:RouteDefinition|route)?)\.path,\s*/g + + if (!methodPattern.test(updated)) { + filesSkipped++ + continue + } + + // Reset lastIndex after test() + updated = original.replace( + /apiFactory\.createApp\(\)\.(post|get|patch|delete)\((\w+(?:RouteDefinition)?)\.path,\s*/g, + "registerRoute($2, ", + ) + + if (updated === original) { + filesSkipped++ + continue + } + + // Replace apiFactory import with registerRoute import (add if missing) + if (!updated.includes("registerRoute")) { + // Should not happen since we just added it above — safety check + filesSkipped++ + continue + } + + // Update import: replace apiFactory.js import with registerRoute.js + // Keep apiFactory import only if still used elsewhere in the file + if (!updated.includes("apiFactory") || updated.match(/apiFactory/g)?.length === 1) { + // Only referenced in remaining import — swap it + updated = updated.replace( + /import \{ apiFactory \} from ["']([^"']+apiFactory\.js)["']/, + 'import { registerRoute } from "$1".replace("apiFactory", "registerRoute")', + ) + } + + // Simpler: just add registerRoute import after the apiFactory import if not present + // (The above regex-in-string replacement won't work — do it properly) + updated = original.replace( + /apiFactory\.createApp\(\)\.(post|get|patch|delete)\((\w+(?:RouteDefinition)?)\.path,\s*/g, + "registerRoute($2, ", + ) + + // Add registerRoute import; replace or augment apiFactory import line + const apiFactoryImportRegex = /import \{ apiFactory \} from "([^"]+apiFactory\.js)"/ + const apiFactoryImportRegexRelative = /import \{ apiFactory \} from '([^']+apiFactory\.js)'/ + const match = updated.match(apiFactoryImportRegex) || updated.match(apiFactoryImportRegexRelative) + + if (match) { + const quote = updated.includes(`import { apiFactory } from "`) ? `"` : `'` + const importPath = match[1] + const registerRoutePath = importPath.replace("apiFactory.js", "registerRoute.js") + + if (updated.includes("apiFactory")) { + // Still used elsewhere — add registerRoute as addtional import + updated = updated.replace( + new RegExp(`import \\{ apiFactory \\} from ${quote}${escapeRegex(importPath)}${quote}`), + `import { apiFactory } from ${quote}${importPath}${quote}\nimport { registerRoute } from ${quote}${registerRoutePath}${quote}`, + ) + } else { + // Not used anymore — replace import + updated = updated.replace( + new RegExp(`import \\{ apiFactory \\} from ${quote}${escapeRegex(importPath)}${quote}`), + `import { registerRoute } from ${quote}${registerRoutePath}${quote}`, + ) + } + } + + if (updated !== original) { + writeFileSync(filePath, updated, "utf8") + filesUpdated++ + console.log(`✓ ${entry}`) + } else { + filesSkipped++ + } +} + +console.log(`\nDone. Updated: ${filesUpdated}, Skipped: ${filesSkipped}`) + +function escapeRegex(str) { + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") +} diff --git a/scripts/migrate-routes.mjs b/scripts/migrate-routes.mjs new file mode 100644 index 00000000..4918ceda --- /dev/null +++ b/scripts/migrate-routes.mjs @@ -0,0 +1,1146 @@ +/** + * Batch migration script: updates all routeDefinition() calls in + * packages/metadata/src/routes/dashboard/ to REST paths + correct HTTP methods. + * + * Run from the monorepo root: + * node scripts/migrate-routes.mjs + */ + +import { readFileSync, writeFileSync } from "node:fs" + +/** Map from OLD path template string to [NEW path, method] */ +const PATH_MAP = new Map([ + // ── Public auth ──────────────────────────────────────────────────────── + [ + "`${routePath.public}/sign-in`", + [ + "`${routePath.v1}/auth/sign-in`", + "POST", + ], + ], + [ + "`${routePath.public}/sign-up`", + [ + "`${routePath.v1}/auth/sign-up`", + "POST", + ], + ], + [ + "`${routePath.public}/sign-out`", + [ + "`${routePath.v1}/auth/sign-out`", + "POST", + ], + ], + [ + "`${routePath.public}/send-magic-link`", + [ + "`${routePath.v1}/auth/magic-link`", + "POST", + ], + ], + [ + "`${routePath.public}/reset-password`", + [ + "`${routePath.v1}/auth/reset-password`", + "POST", + ], + ], + [ + "`${routePath.public}/mollie-webhook`", + [ + "`${routePath.v1}/webhooks/mollie`", + "POST", + ], + ], + + // ── User (me) ─────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-user-session`", + [ + "`${routePath.v1}/users/me`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-user`", + [ + "`${routePath.v1}/users/me`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/update-user-email`", + [ + "`${routePath.v1}/users/me/email`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/update-user-password`", + [ + "`${routePath.v1}/users/me/password`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/validate-user-email`", + [ + "`${routePath.v1}/users/me/email/validate`", + "POST", + ], + ], + [ + "`${routePath.auth}/resend-email-validation`", + [ + "`${routePath.v1}/users/me/email/resend-validation`", + "POST", + ], + ], + [ + "`${routePath.auth}/activate-user`", + [ + "`${routePath.v1}/users/me/activate`", + "POST", + ], + ], + [ + "`${routePath.auth}/delete-user`", + [ + "`${routePath.v1}/users/me`", + "DELETE", + ], + ], + + // ── Organizations ─────────────────────────────────────────────────────── + [ + "`${routePath.auth}/get-all-my-organization`", + [ + "`${routePath.v1}/organizations`", + "GET", + ], + ], + [ + "`${routePath.auth}/add-new-organization`", + [ + "`${routePath.v1}/organizations`", + "POST", + ], + ], + [ + "`${routePath.auth}/activate-organization-membership`", + [ + "`${routePath.v1}/organizations/activate-membership`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-organization`", + [ + "`${routePath.v1}/organizations/:idOrganization`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-organization`", + [ + "`${routePath.v1}/organizations/:idOrganization`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-organization`", + [ + "`${routePath.v1}/organizations/:idOrganization`", + "DELETE", + ], + ], + + // Org users + [ + "`${routePath.auth}/read-all-organization-users`", + [ + "`${routePath.v1}/organizations/:idOrganization/users`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-organization-user`", + [ + "`${routePath.v1}/organizations/:idOrganization/users`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-organization-user`", + [ + "`${routePath.v1}/organizations/:idOrganization/users/:idOrganizationUser`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-organization-user`", + [ + "`${routePath.v1}/organizations/:idOrganization/users/:idOrganizationUser`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-organization-user`", + [ + "`${routePath.v1}/organizations/:idOrganization/users/:idOrganizationUser`", + "DELETE", + ], + ], + + // API keys + [ + "`${routePath.auth}/read-all-api-keys`", + [ + "`${routePath.v1}/organizations/:idOrganization/api-keys`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-api-key`", + [ + "`${routePath.v1}/organizations/:idOrganization/api-keys`", + "POST", + ], + ], + [ + "`${routePath.auth}/delete-one-api-key`", + [ + "`${routePath.v1}/organizations/:idOrganization/api-keys/:idApiKey`", + "DELETE", + ], + ], + + // Payments & billing + [ + "`${routePath.auth}/read-all-organization-payments`", + [ + "`${routePath.v1}/organizations/:idOrganization/payments`", + "GET", + ], + ], + [ + "`${routePath.auth}/read-all-organization-billings`", + [ + "`${routePath.v1}/organizations/:idOrganization/billings`", + "GET", + ], + ], + [ + "`${routePath.auth}/read-organization-billing`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing`", + "GET", + ], + ], + [ + "`${routePath.auth}/read-all-invoices`", + [ + "`${routePath.v1}/organizations/:idOrganization/invoices`", + "GET", + ], + ], + [ + "`${routePath.auth}/read-one-invoice`", + [ + "`${routePath.v1}/organizations/:idOrganization/invoices/:idInvoice`", + "GET", + ], + ], + [ + "`${routePath.auth}/generate-invoice-get-signed-url`", + [ + "`${routePath.v1}/organizations/:idOrganization/invoices/:idInvoice/download-url`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-first-payment`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/first-payment`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-payment-method-checkout`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/payment-method-checkout`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-resource-subscription`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/resource-subscription`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-wallet-top-up-checkout`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/wallet-top-up`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-wallet-withdrawal`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/wallet-withdrawal`", + "POST", + ], + ], + [ + "`${routePath.auth}/update-tokens-subscription`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/tokens-subscription`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/update-ocr-subscription`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/ocr-subscription`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/update-storage-subscription`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/storage-subscription`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/update-licence-subscription`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/licence-subscription`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/cancel-subscription`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing/cancel-subscription`", + "POST", + ], + ], + [ + "`${routePath.auth}/cancel-organization-billing`", + [ + "`${routePath.v1}/organizations/:idOrganization/billing`", + "DELETE", + ], + ], + + // ── Years ──────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-years`", + [ + "`${routePath.v1}/organizations/:idOrganization/years`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-year`", + [ + "`${routePath.v1}/organizations/:idOrganization/years`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-year`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-year`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-year`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear`", + "DELETE", + ], + ], + [ + "`${routePath.auth}/open-year`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/open`", + "POST", + ], + ], + [ + "`${routePath.auth}/close-year`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/close`", + "POST", + ], + ], + [ + "`${routePath.auth}/settle-balance-sheet`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/settle-balance-sheet`", + "POST", + ], + ], + [ + "`${routePath.auth}/settle-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/settle-income-statement`", + "POST", + ], + ], + + // ── Accounts ────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-accounts`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-account`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-accounts`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/generate`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-account`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/:idAccount`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-account`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/:idAccount`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-account`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/accounts/:idAccount`", + "DELETE", + ], + ], + + // ── Journals ────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-journals`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/journals`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-journal`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/journals`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-journals`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/generate`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-journal`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/:idJournal`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-journal`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/:idJournal`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-journal`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/journals/:idJournal`", + "DELETE", + ], + ], + + // ── Balance sheets ──────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-balance-sheets`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-balance-sheet`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-balance-sheets`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/generate`", + "POST", + ], + ], + [ + "`${routePath.auth}/connect-accounts-to-balance-sheets`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/connect-accounts`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-balance-sheet`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/:idBalanceSheet`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-balance-sheet`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/:idBalanceSheet`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-balance-sheet`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/balance-sheets/:idBalanceSheet`", + "DELETE", + ], + ], + + // ── Income statements ───────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-income-statements`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-income-statements`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/generate`", + "POST", + ], + ], + [ + "`${routePath.auth}/connect-accounts-to-income-statements`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/connect-accounts`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/:idIncomeStatement`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/:idIncomeStatement`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/income-statements/:idIncomeStatement`", + "DELETE", + ], + ], + + // ── Computations ────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-computations`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-computation`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-computations`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/generate`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-computation`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-computation`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-computation`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation`", + "DELETE", + ], + ], + + // Computation income statements + [ + "`${routePath.auth}/read-all-computation-income-statements`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-computation-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-computation-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements/:idComputationIncomeStatement`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-computation-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements/:idComputationIncomeStatement`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-computation-income-statement`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/computations/:idComputation/income-statements/:idComputationIncomeStatement`", + "DELETE", + ], + ], + + // ── Tags ────────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-tags`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/tags`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-tag`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/tags`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-tag`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/tags/:idTag`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-tag`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/tags/:idTag`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-tag`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/tags/:idTag`", + "DELETE", + ], + ], + + // ── Entries ─────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-entries`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-one-entry-from-template`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/from-template`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-all-entry-tags`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entry-tags`", + "GET", + ], + ], + [ + "`${routePath.auth}/read-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry`", + "DELETE", + ], + ], + [ + "`${routePath.auth}/reverse-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/reverse`", + "POST", + ], + ], + [ + "`${routePath.auth}/duplicate-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/duplicate`", + "POST", + ], + ], + [ + "`${routePath.auth}/compute-one-entry`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/compute`", + "POST", + ], + ], + + // Entry lines + [ + "`${routePath.auth}/read-all-entry-lines`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-entry-line`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines`", + "POST", + ], + ], + [ + "`${routePath.auth}/update-many-entry-lines`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/read-one-entry-line`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines/:idEntryLine`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-entry-line`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines/:idEntryLine`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-entry-line`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/lines/:idEntryLine`", + "DELETE", + ], + ], + + // Entry tags + [ + "`${routePath.auth}/add-one-entry-tag`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/tags`", + "POST", + ], + ], + [ + "`${routePath.auth}/remove-one-entry-tag`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/entries/:idEntry/tags/:idTag`", + "DELETE", + ], + ], + + // ── Files ───────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-files`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-file`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-file`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-file`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-file`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile`", + "DELETE", + ], + ], + [ + "`${routePath.auth}/ocr-file`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/ocr`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-file-put-signed-url`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/upload-url`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-file-get-signed-url`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/download-url`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-file-delete-signed-url`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/delete-url`", + "POST", + ], + ], + [ + "`${routePath.auth}/finalize-file-upload`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/files/:idFile/finalize`", + "POST", + ], + ], + + // ── Folders ─────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-folders`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/folders`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-folder`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/folders`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-folder`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/folders/:idFolder`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-folder`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/folders/:idFolder`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-folder`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/folders/:idFolder`", + "DELETE", + ], + ], + + // ── Reports ─────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/generate-income-statement-xml`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/reports/income-statement`", + "POST", + ], + ], + [ + "`${routePath.auth}/generate-balance-sheet-xml`", + [ + "`${routePath.v1}/organizations/:idOrganization/years/:idYear/reports/balance-sheet`", + "POST", + ], + ], + + // ── Agent ───────────────────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-agent-sessions`", + [ + "`${routePath.v1}/agent/sessions`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-agent-session`", + [ + "`${routePath.v1}/agent/sessions`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-agent-session`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-agent-session`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/delete-one-agent-session`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession`", + "DELETE", + ], + ], + [ + "`${routePath.auth}/read-all-agent-messages`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession/messages`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-agent-message`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession/messages`", + "POST", + ], + ], + [ + "`${routePath.auth}/get-stream-for-agent-message`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession/messages/:idAgentMessage/stream`", + "GET", + ], + ], + [ + "`${routePath.auth}/get-chat-stream`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession/stream`", + "GET", + ], + ], + [ + "`${routePath.auth}/undo-agent-action`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession/undo`", + "POST", + ], + ], + [ + "`${routePath.auth}/create-one-agent-file`", + [ + "`${routePath.v1}/agent/sessions/:idAgentSession/files`", + "POST", + ], + ], + [ + "`${routePath.auth}/search-referenceable`", + [ + "`${routePath.v1}/agent/search`", + "GET", + ], + ], + + // ── Support / tickets ───────────────────────────────────────────────────── + [ + "`${routePath.auth}/read-all-tickets`", + [ + "`${routePath.v1}/support/tickets`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-ticket`", + [ + "`${routePath.v1}/support/tickets`", + "POST", + ], + ], + [ + "`${routePath.auth}/read-one-ticket`", + [ + "`${routePath.v1}/support/tickets/:idTicket`", + "GET", + ], + ], + [ + "`${routePath.auth}/update-one-ticket`", + [ + "`${routePath.v1}/support/tickets/:idTicket`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/update-one-ticket-status`", + [ + "`${routePath.v1}/support/tickets/:idTicket/status`", + "PATCH", + ], + ], + [ + "`${routePath.auth}/read-all-ticket-messages`", + [ + "`${routePath.v1}/support/tickets/:idTicket/messages`", + "GET", + ], + ], + [ + "`${routePath.auth}/create-one-ticket-message`", + [ + "`${routePath.v1}/support/tickets/:idTicket/messages`", + "POST", + ], + ], +]) + +import { glob } from "node:fs/promises" +import { join } from "node:path" + +const ROOT = new URL("../packages/metadata/src/routes/dashboard", import.meta.url).pathname + +let filesUpdated = 0 +let filesSkipped = 0 + +for await (const entry of glob("**/*.ts", { + cwd: ROOT, +})) { + const filePath = join(ROOT, entry) + const original = readFileSync(filePath, "utf8") + let updated = original + + for (const [oldPath, [newPath, method]] of PATH_MAP.entries()) { + if (!updated.includes(oldPath)) continue + + // Replace path value + updated = updated.replace(oldPath, newPath) + + // Inject method field after `protocol:` line if not already present + if (!updated.includes("method:")) { + updated = updated.replace(/(\s+protocol:\s*"(?:http|ws)",)/, `$1\n method: "${method}",`) + } + + break // each file has one routeDefinition + } + + if (updated !== original) { + writeFileSync(filePath, updated, "utf8") + filesUpdated++ + console.log(`✓ ${entry}`) + } else { + filesSkipped++ + } +} + +console.log(`\nDone. Updated: ${filesUpdated}, Skipped: ${filesSkipped}`) From a81951da1c4a1b7c21cc91ce2396d1ea4e0daa78 Mon Sep 17 00:00:00 2001 From: &mile Date: Tue, 19 May 2026 19:12:23 +0200 Subject: [PATCH 12/14] docs(general): add architecture page with diagram --- packages/website/plugins/DOC_PAGE_MANIFEST.ts | 7 + .../website/src/features/docs/docSections.tsx | 4 + .../architecture/ArchitectureDiagram.tsx | 99 ++ .../ArchitectureGeneralDocPage.tsx | 108 ++ .../website/src/routes/root/docs/docsTree.ts | 2 + .../docs/root/architectureGeneralDocRoute.tsx | 16 + pnpm-lock.yaml | 1006 +---------------- 7 files changed, 238 insertions(+), 1004 deletions(-) create mode 100644 packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx create mode 100644 packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx create mode 100644 packages/website/src/routes/root/docs/root/architectureGeneralDocRoute.tsx diff --git a/packages/website/plugins/DOC_PAGE_MANIFEST.ts b/packages/website/plugins/DOC_PAGE_MANIFEST.ts index c644148e..2c37bff6 100644 --- a/packages/website/plugins/DOC_PAGE_MANIFEST.ts +++ b/packages/website/plugins/DOC_PAGE_MANIFEST.ts @@ -26,6 +26,13 @@ export const DOC_PAGE_MANIFEST: DocPageManifestEntry[] = [ navGroup: "Introduction", navLabel: "Fonctionnalités", }, + { + path: "/documentation/architecture", + file: "src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx", + section: "Général", + navGroup: "Introduction", + navLabel: "Architecture", + }, { path: "/documentation/philosophie", file: "src/features/docs/general/whitepaperGeneralDocPage.tsx", diff --git a/packages/website/src/features/docs/docSections.tsx b/packages/website/src/features/docs/docSections.tsx index c8f4eb2e..187fd252 100644 --- a/packages/website/src/features/docs/docSections.tsx +++ b/packages/website/src/features/docs/docSections.tsx @@ -33,6 +33,10 @@ export const docSections: Record = { path: "/documentation/fonctionnalités", label: "Fonctionnalités", }, + { + path: "/documentation/architecture", + label: "Architecture", + }, { path: "/documentation/philosophie", label: "Philosophie", diff --git a/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx b/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx new file mode 100644 index 00000000..3a60b39e --- /dev/null +++ b/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx @@ -0,0 +1,99 @@ +import { css } from "@arrhes/ui/utilities/cn.js" + +export function ArchitectureDiagram() { + return ( +
+ + + + + + + + {/* ── Layout constants + Total drawable width: x=15..605 (590px) + 1/3 unit = 190px, gap = 10px + Row 1: Utilisateurs(x=15,w=190,cx=110) | Développeurs(x=215,w=390,cx=410) + Row 2: Dashboard(x=15,w=190,cx=110) | [gap 210px] | CLI(x=415,w=190,cx=510) + Row 3: API (x=15, w=590, h=36) + Row 4: Database (x=15, w=590, h=36) + ── */} + + {/* ── Connector lines (drawn first, behind boxes) ───────── */} + + {/* Utilisateurs → Dashboard */} + + {/* Développeurs → API (straight down through the gap in row 2) */} + + {/* Développeurs → CLI */} + + {/* Dashboard → API */} + + {/* CLI → API */} + + {/* API → Database */} + + + {/* ── Row 1 : 1/3 Utilisateurs + 2/3 Développeurs ──────── */} + + {/* Utilisateurs — 1/3 (x=15, w=190, cx=110) */} + + + Utilisateurs + + + Utilisation simple + + + {/* Développeurs — 2/3 (x=215, w=390, cx=410) */} + + + Développeurs + + + Intégrations · Automatisations · IA + + + {/* ── Row 2 : 1/3 Dashboard + gap + 1/3 CLI ────────────── */} + + {/* Dashboard — 1/3 (x=15, w=190, cx=110) */} + + + Dashboard + + + {/* CLI — 1/3 (x=415, w=190, cx=510) */} + + + CLI + + + {/* ── Row 3 : API full width (h=36) ────────────────────── */} + + + API + + + {/* ── Row 4 : Database full width (h=36, same as API) ───── */} + + + Database + + +
+ ) +} diff --git a/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx b/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx new file mode 100644 index 00000000..9fadf008 --- /dev/null +++ b/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx @@ -0,0 +1,108 @@ +import { css } from "@arrhes/ui/utilities/cn.js" +import { DocRoot } from "../../../../components/document/DocRoot.js" +import { DocTextSection } from "../../../../components/document/DocTextSection.js" +import { ArchitectureDiagram } from "./ArchitectureDiagram.js" + +export function ArchitectureGeneralDocPage() { + return ( + + {/* Page header */} +
+

+ Architecture +

+

+ Vue d'ensemble de l'architecture technique d'Arrhes et de ses différents services. +

+
+ + {/* Infogram */} + + + {/* Sections */} + +

+ Arrhes est organisé en plusieurs services distincts qui travaillent ensemble. Chaque service a + un rôle précis : certains sont destinés aux utilisateurs finaux, d'autres aux développeurs qui + souhaitent intégrer Arrhes dans leurs outils. +

+

+ Tous les services passent par l'API, qui est le cœur du système. C'est elle + qui gère les données, les autorisations et la logique métier. Le reste — dashboard, CLI, agent IA + — n'est que la façon dont chacun choisit d'y accéder. +

+
+ + +

+ Le dashboard est l'interface web d'Arrhes. Il permet de gérer ses organisations, saisir ses + écritures comptables, consulter ses documents de synthèse, stocker ses pièces justificatives et + discuter avec l'assistant IA. +

+

+ Pour qui ? Les utilisateurs qui souhaitent gérer leur comptabilité au + quotidien depuis un navigateur, sans installation ni configuration. +

+
+ + +

+ Le CLI est une interface en ligne de commande qui donne accès aux mêmes fonctionnalités que le + dashboard : organisations, exercices, écritures, exports et documents comptables. Il s'utilise + directement depuis un terminal, sur Linux ou macOS. +

+

+ Pour qui ? Les développeurs et équipes techniques qui souhaitent automatiser + des tâches, intégrer Arrhes dans des scripts ou des pipelines CI/CD. +

+
+ + +

+ L'API est le service central d'Arrhes. Elle reçoit toutes les requêtes — qu'elles viennent du + dashboard, du CLI ou d'une intégration tierce — et est responsable de l'authentification, des + données comptables, du stockage des fichiers et de l'assistant IA. +

+

+ Pour qui ? Les développeurs qui souhaitent accéder directement aux données + d'Arrhes depuis leur propre application, via des clés API. +

+
+ + +

+ La base de données stocke l'ensemble des données d'Arrhes : utilisateurs, organisations, + exercices, écritures comptables, fichiers et sessions. Elle est le seul endroit où les données + sont persistées et n'est jamais accessible directement depuis l'extérieur — uniquement via l'API. +

+

+ Le stockage des fichiers (pièces justificatives, documents exportés) est géré séparément, dans + un espace dédié compatible avec le protocole S3. Les emails transactionnels — comme les liens + de connexion — sont envoyés via un service SMTP. +

+

+ Pour qui ? Ce service est entièrement géré par Arrhes. Les utilisateurs et + développeurs n'ont pas à interagir avec lui directement. +

+
+
+ ) +} diff --git a/packages/website/src/routes/root/docs/docsTree.ts b/packages/website/src/routes/root/docs/docsTree.ts index d76ca1a8..c9005f27 100644 --- a/packages/website/src/routes/root/docs/docsTree.ts +++ b/packages/website/src/routes/root/docs/docsTree.ts @@ -42,6 +42,7 @@ import { rootDashboardDocRoute } from "./dashboard/rootDashboardDocRoute.js" import { updatesDashboardDocRoute } from "./dashboard/updatesDashboardDocRoute.js" import { yearsDashboardDocRoute } from "./dashboard/yearsDashboardDocRoute.js" import { docsLayoutRoute } from "./docsLayoutRoute.js" +import { architectureGeneralDocRoute } from "./root/architectureGeneralDocRoute.js" import { featuresGeneralDocRoute } from "./root/featuresGeneralDocRoute.js" import { generalDocLayoutRoute } from "./root/generalDocLayoutRoute.js" import { legalGeneralDocRoute } from "./root/legalGeneralDocRoute.js" @@ -57,6 +58,7 @@ export const docsTree: AnyRoute = docsLayoutRoute.addChildren([ generalDocLayoutRoute.addChildren([ rootGeneralDocRoute, featuresGeneralDocRoute, + architectureGeneralDocRoute, pricingGeneralDocRoute, whitepaperGeneralDocRoute, supportGeneralDocRoute, diff --git a/packages/website/src/routes/root/docs/root/architectureGeneralDocRoute.tsx b/packages/website/src/routes/root/docs/root/architectureGeneralDocRoute.tsx new file mode 100644 index 00000000..2274ec3a --- /dev/null +++ b/packages/website/src/routes/root/docs/root/architectureGeneralDocRoute.tsx @@ -0,0 +1,16 @@ +import { createRoute, lazyRouteComponent } from "@tanstack/react-router" +import { generalDocLayoutRoute } from "./generalDocLayoutRoute.tsx" + +export const architectureGeneralDocRoute = createRoute({ + getParentRoute: () => generalDocLayoutRoute, + path: "/architecture", + beforeLoad: () => ({ + title: "Architecture", + description: + "Vue d'ensemble de l'architecture technique d'Arrhes : Website, API, CLI et infrastructure (PostgreSQL, Stockage S3, SMTP).", + }), + component: lazyRouteComponent( + () => import("../../../../features/docs/general/architecture/ArchitectureGeneralDocPage.tsx"), + "ArchitectureGeneralDocPage", + ), +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6f80838..b2ac5347 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,36 +85,7 @@ importers: specifier: 4.1.5 version: 4.1.5(@types/node@25.6.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)) - packages/cli: - dependencies: - '@arrhes/application-metadata': - specifier: workspace:* - version: link:../metadata - commander: - specifier: 14.0.0 - version: 14.0.0 - valibot: - specifier: 1.4.0 - version: 1.4.0(typescript@6.0.3) - devDependencies: - '@types/node': - specifier: 25.6.0 - version: 25.6.0 - '@yao-pkg/pkg': - specifier: 5.16.0 - version: 5.16.0 - postject: - specifier: 1.0.0-alpha.6 - version: 1.0.0-alpha.6 - tsup: - specifier: 8.5.0 - version: 8.5.0(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0)(typescript@6.0.3) - tsx: - specifier: 4.21.0 - version: 4.21.0 - typescript: - specifier: 6.0.3 - version: 6.0.3 + packages/cli: {} packages/metadata: dependencies: @@ -509,10 +480,6 @@ packages: resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} engines: {node: '>=18.0.0'} - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -1147,19 +1114,9 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} @@ -1508,144 +1465,6 @@ packages: '@rolldown/pluginutils@1.0.0-rc.7': resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} - cpu: [arm] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} - cpu: [arm] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} - cpu: [loong64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} - cpu: [loong64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} - cpu: [ppc64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} - cpu: [x64] - os: [openbsd] - - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} - cpu: [arm64] - os: [openharmony] - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} - cpu: [x64] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} - cpu: [x64] - os: [win32] - '@smithy/chunked-blob-reader-native@4.2.3': resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} engines: {node: '>=18.0.0'} @@ -2080,14 +1899,6 @@ packages: '@vue/shared@3.5.25': resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} - '@yao-pkg/pkg-fetch@3.5.15': - resolution: {integrity: sha512-KTM1PszA2zRlJThfDZVDgnXJ5dnPgowiyYa/DT3Y9k7EG6A/xo4+dZEaXV5k3XF/txelxBlBcej8BrKYi59bOQ==} - hasBin: true - - '@yao-pkg/pkg@5.16.0': - resolution: {integrity: sha512-3CwgxegupGB6JHG3ebFA7w2ArCLIp1UihnKh8uFusA0BseFGUPkmloP9srb+DOXdt/ZNWW+ZAFUKFeCK0HKQHw==} - hasBin: true - abs-svg-path@0.1.1: resolution: {integrity: sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==} @@ -2095,15 +1906,6 @@ packages: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -2139,9 +1941,6 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -2181,9 +1980,6 @@ packages: bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@2.2.2: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} @@ -2219,9 +2015,6 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - bull@4.16.5: resolution: {integrity: sha512-lDsx2BzkKe7gkCYiT5Acj02DpTwDznl/VNN7Psn7M3USPG7Vs/BaClZJJTAG+ufAR9++N1/NiUTdaFBWDIl5TQ==} engines: {node: '>=12'} @@ -2229,12 +2022,6 @@ packages: bundle-n-require@1.1.2: resolution: {integrity: sha512-bEk2jakVK1ytnZ9R2AAiZEeK/GxPUM8jvcRxHZXifZDMcjkI4EG/GlsJ2YGSVYT9y/p/gA9/0yDY8rCGsSU6Tg==} - bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - peerDependencies: - esbuild: '>=0.18' - bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -2277,12 +2064,6 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - - cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -2320,28 +2101,9 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@14.0.0: - resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} - engines: {node: '>=20'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - commander@9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - content-disposition@1.1.0: resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} engines: {node: '>=18'} @@ -2367,9 +2129,6 @@ packages: core-js-pure@3.49.0: resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.6: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} @@ -2410,14 +2169,6 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -2645,10 +2396,6 @@ packages: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} engines: {node: '>=18.0.0'} - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -2713,9 +2460,6 @@ packages: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} - fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} - fontkit@2.0.4: resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} @@ -2739,12 +2483,6 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} - from2@2.3.0: - resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} - - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - fs-extra@11.3.2: resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} engines: {node: '>=14.14'} @@ -2797,9 +2535,6 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2883,10 +2618,6 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -2898,9 +2629,6 @@ packages: resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} engines: {node: '>=0.10.0'} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - imask@7.6.1: resolution: {integrity: sha512-sJlIFM7eathUEMChTh9Mrfw/IgiWgJqBKq2VNbyXvBZ7ev/IlO6/KQTKlV/Fm+viQMLrFLG/zCuudrLIwgK2dg==} engines: {npm: '>=4.0.0'} @@ -2908,16 +2636,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} - into-stream@6.0.0: - resolution: {integrity: sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==} - engines: {node: '>=10'} - ioredis@5.10.1: resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} engines: {node: '>=12.22.0'} @@ -2936,10 +2657,6 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} - is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -2976,9 +2693,6 @@ packages: is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - isbot@5.1.40: resolution: {integrity: sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ==} engines: {node: '>=18'} @@ -3002,21 +2716,12 @@ packages: jose@6.2.3: resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} - joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} - js-md5@0.8.3: resolution: {integrity: sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - json-bigint@1.0.0: resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} @@ -3187,20 +2892,9 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - linebreak@1.1.0: resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -3213,9 +2907,6 @@ packages: lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} @@ -3383,10 +3074,6 @@ packages: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} @@ -3395,19 +3082,10 @@ packages: resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3418,12 +3096,6 @@ packages: msgpackr@1.11.12: resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} - multistream@4.1.0: - resolution: {integrity: sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3434,17 +3106,10 @@ packages: engines: {node: ^18 || >=20} hasBin: true - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - negotiator@1.0.0: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - node-abi@3.92.0: - resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} - engines: {node: '>=10'} - node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -3525,10 +3190,6 @@ packages: outdent@0.8.0: resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} - p-is-promise@3.0.0: - resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} - engines: {node: '>=8'} - p-limit@5.0.0: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} engines: {node: '>=18'} @@ -3577,9 +3238,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -3604,17 +3262,10 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} @@ -3647,24 +3298,6 @@ packages: peerDependencies: postcss: ^8.4.32 - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - postcss-minify-selectors@7.0.5: resolution: {integrity: sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==} engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} @@ -3702,29 +3335,11 @@ packages: resolution: {integrity: sha512-GD3qdB0x1z9xgFI6cdRD6xu2Sp2WCOEoe3mtnyB5Ee0XrrL5Pe+e4CCnJrRMnL1zYtRDZmQQVbvOttLnKDLnaw==} engines: {node: '>=12'} - postject@1.0.0-alpha.6: - resolution: {integrity: sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==} - engines: {node: '>=14.0.0'} - hasBin: true - - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. - hasBin: true - prettier@3.2.5: resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -3743,13 +3358,6 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - qs@6.15.1: resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} engines: {node: '>=0.6'} @@ -3768,10 +3376,6 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - react-dom@19.2.6: resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: @@ -3802,9 +3406,6 @@ packages: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3835,18 +3436,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} - hasBin: true - restructure@3.0.2: resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} @@ -3871,11 +3463,6 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -3886,9 +3473,6 @@ packages: ruply@1.0.1: resolution: {integrity: sha512-p39LnaaJyuucPGlgaB0KiyifpcuOkn24+Hq5y0ejAD/LlH+mRAbkHn2tckCLgHir+S+nis1WYG+TYEC4zHX0WQ==} - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -3961,12 +3545,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -3985,11 +3563,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} - deprecated: The work that was done in this beta branch won't be included in future versions - space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -4009,9 +3582,6 @@ packages: stream-events@1.0.5: resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} - stream-meter@1.0.4: - resolution: {integrity: sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==} - stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} @@ -4023,9 +3593,6 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -4040,10 +3607,6 @@ packages: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - strnum@2.2.3: resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} @@ -4056,15 +3619,6 @@ packages: style-to-object@1.0.14: resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - svg-arc-to-cubic-bezier@3.2.0: resolution: {integrity: sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==} @@ -4072,33 +3626,16 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} - tar-fs@2.1.4: - resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - teeny-request@10.1.2: resolution: {integrity: sha512-Xj0ZAQ0CeuQn6UxCDPLbFRlgcSTUEyO3+wiepr2grjIjyL/lMMs1Z4OwXn8kLvn/V1OuaEP0UY7Na6UDNNsYrQ==} engines: {node: '>=18'} - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -4122,13 +3659,6 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - - tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -4145,9 +3675,6 @@ packages: jsdom: optional: true - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-morph@28.0.0: resolution: {integrity: sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==} @@ -4157,33 +3684,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsup@8.5.0: - resolution: {integrity: sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': ^1 - postcss: ^8.4.12 - typescript: '>=4.5.0' - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@swc/core': - optional: true - postcss: - optional: true - typescript: - optional: true - tsx@4.21.0: resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} hasBin: true - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -4198,9 +3703,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} - undici-types@7.19.2: resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} @@ -4376,18 +3878,12 @@ packages: webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -4429,17 +3925,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} + engines: {node: '>=12'} yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} @@ -4937,14 +4425,6 @@ snapshots: '@aws/lambda-invoke-store@0.2.4': {} - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.3 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -5352,20 +4832,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@js-sdsl/ordered-map@4.4.2': {} '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': @@ -5861,81 +5329,6 @@ snapshots: '@rolldown/pluginutils@1.0.0-rc.7': {} - '@rollup/rollup-android-arm-eabi@4.60.4': - optional: true - - '@rollup/rollup-android-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-arm64@4.60.4': - optional: true - - '@rollup/rollup-darwin-x64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-arm64@4.60.4': - optional: true - - '@rollup/rollup-freebsd-x64@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-loong64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-ppc64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-riscv64-musl@4.60.4': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-linux-x64-musl@4.60.4': - optional: true - - '@rollup/rollup-openbsd-x64@4.60.4': - optional: true - - '@rollup/rollup-openharmony-arm64@4.60.4': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-gnu@4.60.4': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.60.4': - optional: true - '@smithy/chunked-blob-reader-native@4.2.3': dependencies: '@smithy/util-base64': 4.3.2 @@ -6517,38 +5910,6 @@ snapshots: '@vue/shared@3.5.25': {} - '@yao-pkg/pkg-fetch@3.5.15': - dependencies: - https-proxy-agent: 5.0.1 - node-fetch: 2.7.0 - picocolors: 1.1.1 - progress: 2.0.3 - semver: 7.7.4 - tar-fs: 2.1.4 - yargs: 16.2.0 - transitivePeerDependencies: - - encoding - - supports-color - - '@yao-pkg/pkg@5.16.0': - dependencies: - '@babel/generator': 7.29.1 - '@babel/parser': 7.29.3 - '@babel/types': 7.29.0 - '@yao-pkg/pkg-fetch': 3.5.15 - into-stream: 6.0.0 - minimist: 1.2.8 - multistream: 4.1.0 - picocolors: 1.1.1 - picomatch: 4.0.4 - prebuild-install: 7.1.3 - resolve: 1.22.12 - stream-meter: 1.0.4 - tinyglobby: 0.2.16 - transitivePeerDependencies: - - encoding - - supports-color - abs-svg-path@0.1.1: {} accepts@2.0.0: @@ -6556,14 +5917,6 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 - acorn@8.16.0: {} - - agent-base@6.0.2: - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - agent-base@7.1.4: {} ajv-formats@3.0.1(ajv@8.20.0): @@ -6589,8 +5942,6 @@ snapshots: ansi-styles@6.2.3: {} - any-promise@1.3.0: {} - assertion-error@2.0.1: {} astral-regex@2.0.0: {} @@ -6615,12 +5966,6 @@ snapshots: bignumber.js@9.3.1: {} - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - body-parser@2.2.2: dependencies: bytes: 3.1.2 @@ -6669,11 +6014,6 @@ snapshots: buffer-from@1.1.2: {} - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - bull@4.16.5: dependencies: cron-parser: 4.9.0 @@ -6691,11 +6031,6 @@ snapshots: esbuild: 0.25.12 node-eval: 2.0.0 - bundle-require@5.1.0(esbuild@0.25.12): - dependencies: - esbuild: 0.25.12 - load-tsconfig: 0.2.5 - bytes@3.1.2: {} cac@6.7.14: {} @@ -6728,14 +6063,6 @@ snapshots: dependencies: readdirp: 4.1.2 - chownr@1.1.4: {} - - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -6766,18 +6093,8 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@14.0.0: {} - - commander@4.1.1: {} - - commander@9.5.0: {} - - confbox@0.1.8: {} - confbox@0.2.4: {} - consola@3.4.2: {} - content-disposition@1.1.0: {} content-type@1.0.5: {} @@ -6792,8 +6109,6 @@ snapshots: core-js-pure@3.49.0: {} - core-util-is@1.0.3: {} - cors@2.8.6: dependencies: object-assign: 4.1.1 @@ -6827,12 +6142,6 @@ snapshots: dependencies: character-entities: 2.0.2 - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - deep-extend@0.6.0: {} - delayed-stream@1.0.0: {} denque@2.1.0: {} @@ -7019,8 +6328,6 @@ snapshots: dependencies: eventsource-parser: 3.0.8 - expand-template@2.0.3: {} - expect-type@1.3.0: {} express-rate-limit@8.5.1(express@5.2.1): @@ -7118,12 +6425,6 @@ snapshots: transitivePeerDependencies: - supports-color - fix-dts-default-cjs-exports@1.0.1: - dependencies: - magic-string: 0.30.21 - mlly: 1.8.2 - rollup: 4.60.4 - fontkit@2.0.4: dependencies: '@swc/helpers': 0.5.21 @@ -7157,13 +6458,6 @@ snapshots: fresh@2.0.0: {} - from2@2.3.0: - dependencies: - inherits: 2.0.4 - readable-stream: 2.3.8 - - fs-constants@1.0.0: {} - fs-extra@11.3.2: dependencies: graceful-fs: 4.2.11 @@ -7240,8 +6534,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - github-from-package@0.0.0: {} - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -7373,13 +6665,6 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -7393,23 +6678,14 @@ snapshots: dependencies: safer-buffer: 2.1.2 - ieee754@1.2.1: {} - imask@7.6.1: dependencies: '@babel/runtime-corejs3': 7.29.2 inherits@2.0.4: {} - ini@1.3.8: {} - inline-style-parser@0.2.7: {} - into-stream@6.0.0: - dependencies: - from2: 2.3.0 - p-is-promise: 3.0.0 - ioredis@5.10.1: dependencies: '@ioredis/commands': 1.5.1 @@ -7435,10 +6711,6 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-core-module@2.16.2: - dependencies: - hasown: 2.0.3 - is-decimal@2.0.1: {} is-extglob@2.1.1: {} @@ -7461,8 +6733,6 @@ snapshots: is-url@1.2.4: {} - isarray@1.0.0: {} - isbot@5.1.40: {} isexe@2.0.0: {} @@ -7484,14 +6754,10 @@ snapshots: jose@6.2.3: {} - joycon@3.1.1: {} - js-md5@0.8.3: {} js-tokens@4.0.0: {} - jsesc@3.1.0: {} - json-bigint@1.0.0: dependencies: bignumber.js: 9.3.1 @@ -7617,17 +6883,11 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 - lilconfig@3.1.3: {} - linebreak@1.1.0: dependencies: base64-js: 0.0.8 unicode-trie: 2.0.0 - lines-and-columns@1.2.4: {} - - load-tsconfig@0.2.5: {} - lodash.camelcase@4.3.0: {} lodash.defaults@4.2.0: {} @@ -7636,8 +6896,6 @@ snapshots: lodash.merge@4.6.2: {} - lodash.sortby@4.7.0: {} - lodash.truncate@4.4.2: {} lodash@4.18.1: {} @@ -7931,8 +7189,6 @@ snapshots: dependencies: mime-db: 1.54.0 - mimic-response@3.1.0: {} - minimatch@10.2.5: dependencies: brace-expansion: 5.0.5 @@ -7941,19 +7197,8 @@ snapshots: dependencies: brace-expansion: 2.1.0 - minimist@1.2.8: {} - minipass@7.1.3: {} - mkdirp-classic@0.5.3: {} - - mlly@1.8.2: - dependencies: - acorn: 8.16.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.4 - ms@2.1.3: {} msgpackr-extract@3.0.3: @@ -7972,29 +7217,12 @@ snapshots: optionalDependencies: msgpackr-extract: 3.0.3 - multistream@4.1.0: - dependencies: - once: 1.4.0 - readable-stream: 3.6.2 - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - nanoid@3.3.12: {} nanoid@5.1.11: {} - napi-build-utils@2.0.0: {} - negotiator@1.0.0: {} - node-abi@3.92.0: - dependencies: - semver: 7.7.4 - node-domexception@1.0.0: {} node-eval@2.0.0: @@ -8053,8 +7281,6 @@ snapshots: outdent@0.8.0: {} - p-is-promise@3.0.0: {} - p-limit@5.0.0: dependencies: yocto-queue: 1.2.2 @@ -8096,8 +7322,6 @@ snapshots: path-key@3.1.1: {} - path-parse@1.0.7: {} - path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -8115,16 +7339,8 @@ snapshots: picomatch@4.0.4: {} - pirates@4.0.7: {} - pkce-challenge@5.0.1: {} - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 - pkg-types@2.3.0: dependencies: confbox: 0.2.4 @@ -8153,14 +7369,6 @@ snapshots: dependencies: postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0): - dependencies: - lilconfig: 3.1.3 - optionalDependencies: - jiti: 2.6.1 - postcss: 8.5.14 - tsx: 4.21.0 - postcss-minify-selectors@7.0.5(postcss@8.5.6): dependencies: cssesc: 3.0.0 @@ -8198,31 +7406,8 @@ snapshots: postgres@3.4.9: {} - postject@1.0.0-alpha.6: - dependencies: - commander: 9.5.0 - - prebuild-install@7.1.3: - dependencies: - detect-libc: 2.1.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.92.0 - pump: 3.0.4 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.4 - tunnel-agent: 0.6.0 - prettier@3.2.5: {} - process-nextick-args@2.0.1: {} - - progress@2.0.3: {} - prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -8255,13 +7440,6 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - pump@3.0.4: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - - punycode@2.3.1: {} - qs@6.15.1: dependencies: side-channel: 1.1.0 @@ -8281,13 +7459,6 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - react-dom@19.2.6(react@19.2.6): dependencies: react: 19.2.6 @@ -8325,16 +7496,6 @@ snapshots: react@19.2.6: {} - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -8370,17 +7531,8 @@ snapshots: require-from-string@2.0.2: {} - resolve-from@5.0.0: {} - resolve-pkg-maps@1.0.0: {} - resolve@1.22.12: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.2 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - restructure@3.0.2: {} retry-request@8.0.2: @@ -8419,37 +7571,6 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 - rollup@4.60.4: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 - fsevents: 2.3.3 - router@2.2.0: dependencies: debug: 4.4.3 @@ -8466,8 +7587,6 @@ snapshots: ruply@1.0.1: {} - safe-buffer@5.1.2: {} - safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} @@ -8551,14 +7670,6 @@ snapshots: signal-exit@4.1.0: {} - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - sisteransi@1.0.5: {} slice-ansi@4.0.0: @@ -8576,10 +7687,6 @@ snapshots: source-map@0.6.1: {} - source-map@0.8.0-beta.0: - dependencies: - whatwg-url: 7.1.0 - space-separated-tokens@2.0.2: {} stackback@0.0.2: {} @@ -8594,10 +7701,6 @@ snapshots: dependencies: stubs: 3.0.0 - stream-meter@1.0.4: - dependencies: - readable-stream: 2.3.8 - stream-shift@1.0.3: {} string-width@4.2.3: @@ -8612,10 +7715,6 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.2.0 - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -8633,8 +7732,6 @@ snapshots: dependencies: ansi-regex: 6.2.2 - strip-json-comments@2.0.1: {} - strnum@2.2.3: {} stubs@3.0.0: {} @@ -8647,18 +7744,6 @@ snapshots: dependencies: inline-style-parser: 0.2.7 - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.16 - ts-interface-checker: 0.1.13 - - supports-preserve-symlinks-flag@1.0.0: {} - svg-arc-to-cubic-bezier@3.2.0: {} table@6.9.0: @@ -8669,21 +7754,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - tar-fs@2.1.4: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.4 - tar-stream: 2.2.0 - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.5 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - teeny-request@10.1.2: dependencies: http-proxy-agent: 7.0.2 @@ -8693,20 +7763,10 @@ snapshots: transitivePeerDependencies: - supports-color - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - tiny-inflate@1.0.3: {} tinybench@2.9.0: {} - tinyexec@0.3.2: {} - tinyexec@1.1.2: {} tinyglobby@0.2.16: @@ -8724,12 +7784,6 @@ snapshots: tr46@0.0.3: {} - tr46@1.0.1: - dependencies: - punycode: 2.3.1 - - tree-kill@1.2.2: {} - trim-lines@3.0.1: {} trough@2.2.0: {} @@ -8741,8 +7795,6 @@ snapshots: object-path: 0.11.8 typescript: 6.0.3 - ts-interface-checker@0.1.13: {} - ts-morph@28.0.0: dependencies: '@ts-morph/common': 0.29.0 @@ -8752,34 +7804,6 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.0(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0)(typescript@6.0.3): - dependencies: - bundle-require: 5.1.0(esbuild@0.25.12) - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.3 - esbuild: 0.25.12 - fix-dts-default-cjs-exports: 1.0.1 - joycon: 3.1.1 - picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.14)(tsx@4.21.0) - resolve-from: 5.0.0 - rollup: 4.60.4 - source-map: 0.8.0-beta.0 - sucrase: 3.35.1 - tinyexec: 0.3.2 - tinyglobby: 0.2.16 - tree-kill: 1.2.2 - optionalDependencies: - postcss: 8.5.14 - typescript: 6.0.3 - transitivePeerDependencies: - - jiti - - supports-color - - tsx - - yaml - tsx@4.21.0: dependencies: esbuild: 0.27.7 @@ -8787,10 +7811,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -8801,8 +7821,6 @@ snapshots: typescript@6.0.3: {} - ufo@1.6.4: {} - undici-types@7.19.2: {} undici@6.25.0: {} @@ -8937,8 +7955,6 @@ snapshots: webidl-conversions@3.0.1: {} - webidl-conversions@4.0.2: {} - whatwg-fetch@3.6.20: {} whatwg-url@5.0.0: @@ -8946,12 +7962,6 @@ snapshots: tr46: 0.0.3 webidl-conversions: 3.0.1 - whatwg-url@7.1.0: - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - which@2.0.2: dependencies: isexe: 2.0.0 @@ -8981,20 +7991,8 @@ snapshots: y18n@5.0.8: {} - yargs-parser@20.2.9: {} - yargs-parser@21.1.1: {} - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - yargs@17.7.2: dependencies: cliui: 8.0.1 From 0efce7533e7671afabe78438ad4ba95c0d2bb1a1 Mon Sep 17 00:00:00 2001 From: &mile Date: Tue, 19 May 2026 19:22:39 +0200 Subject: [PATCH 13/14] fix: remove unused imports and fix lint warnings --- .../website/plugins/docsSearchIndexPlugin.ts | 7 +- .../layouts/commandPalette/CommandPalette.tsx | 1 + .../contextMenu/ContextMenuContent.tsx | 1 + .../overlays/tooltip/TooltipContent.tsx | 2 + .../src/contexts/tabs/tabsProvider.tsx | 4 +- .../OrganizationServicesPage.tsx | 6 +- .../$idOrganization/years/YearsListTable.tsx | 2 +- .../$idYear/entries/EntriesTable.tsx | 2 +- .../entries/EntriesTableSelectionActions.tsx | 134 +++--- .../dashboard/$idYear/files/FileActions.tsx | 396 +++++++++--------- .../$idYear/files/FileContextMenu.tsx | 202 +++++---- .../files/FilesTableSelectionActions.tsx | 134 +++--- .../dashboard/$idYear/files/FolderActions.tsx | 275 ++++++------ .../$idYear/files/FolderContextMenu.tsx | 174 ++++---- .../dashboard/DashboardDefaultPage.tsx | 4 +- .../architecture/ArchitectureDiagram.tsx | 226 +++++++++- .../ArchitectureGeneralDocPage.tsx | 34 +- packages/website/vite.config.ts | 4 +- 18 files changed, 888 insertions(+), 720 deletions(-) diff --git a/packages/website/plugins/docsSearchIndexPlugin.ts b/packages/website/plugins/docsSearchIndexPlugin.ts index 00847c13..79867051 100644 --- a/packages/website/plugins/docsSearchIndexPlugin.ts +++ b/packages/website/plugins/docsSearchIndexPlugin.ts @@ -1,7 +1,6 @@ -import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" -import { dirname, resolve } from "node:path" -import react from "@vitejs/plugin-react" -import { defineConfig, type Plugin, build as viteBuild } from "vite" +import { readFileSync } from "node:fs" +import { resolve } from "node:path" +import type { Plugin } from "vite" import { DOC_PAGE_MANIFEST } from "./DOC_PAGE_MANIFEST.ts" /** diff --git a/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx b/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx index 1b769f91..daa3f784 100644 --- a/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx +++ b/packages/website/src/components/layouts/commandPalette/CommandPalette.tsx @@ -235,6 +235,7 @@ export function CommandPalette(props: { selectedOrgId: string | null; selectedYe } // Keep selected index in bounds when filtered list changes + // biome-ignore lint/correctness/useExhaustiveDependencies: intentional trigger deps — reset selected when filters change useEffect(() => { setSelected(0) }, [ diff --git a/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx b/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx index 2199c9b4..6817485b 100644 --- a/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx +++ b/packages/website/src/components/overlays/contextMenu/ContextMenuContent.tsx @@ -25,6 +25,7 @@ export function ContextMenuContent({ children, className, ...props }: ComponentP } }, [ ctx?.open, + ctx?.closeMenu, ]) if (!ctx?.open) return null diff --git a/packages/website/src/components/overlays/tooltip/TooltipContent.tsx b/packages/website/src/components/overlays/tooltip/TooltipContent.tsx index 72b1e1e7..724b634b 100644 --- a/packages/website/src/components/overlays/tooltip/TooltipContent.tsx +++ b/packages/website/src/components/overlays/tooltip/TooltipContent.tsx @@ -39,6 +39,8 @@ export function TooltipContent({ sideOffset = 4, children, className, style, ... }, [ ctx?.open, sideOffset, + ctx?.triggerRef?.current?.getBoundingClientRect, + ctx?.triggerRef?.current, ]) if (!ctx?.open) return null diff --git a/packages/website/src/contexts/tabs/tabsProvider.tsx b/packages/website/src/contexts/tabs/tabsProvider.tsx index 7c8bf066..57f69e85 100644 --- a/packages/website/src/contexts/tabs/tabsProvider.tsx +++ b/packages/website/src/contexts/tabs/tabsProvider.tsx @@ -212,7 +212,9 @@ export function TabsProvider({ children }: Props) { ) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [ + activeTabId, + ]) // React to browser back/forward (mouse buttons, keyboard, browser UI). // Parse the destination URL/state and update tab context accordingly. diff --git a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx index 3f178cb1..9c0a6ca6 100644 --- a/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/organizationBilling/OrganizationServicesPage.tsx @@ -307,11 +307,11 @@ export function OrganizationServicesPage({ idOrganization: idOrganizationProp }: {(organization) => { const currentSupportAmountInCents = organization.licenceAmount const currentStorageAmountInCents = getRecurringStorageAmountInCents(organization.storageLimit) - const currentStorageQuantity = getStorageAddonQuantity(organization.storageLimit) - const currentTokenQuantity = getTokenAddonQuantity( + const _currentStorageQuantity = getStorageAddonQuantity(organization.storageLimit) + const _currentTokenQuantity = getTokenAddonQuantity( organization.tokensTotalAvailable + organization.tokensTotalUsed, ) - const currentOcrAddonPages = Math.max( + const _currentOcrAddonPages = Math.max( organization.ocrPagesTotalAvailable + organization.ocrPagesTotalUsed - INCLUDED_OCR_PAGES, 0, ) diff --git a/packages/website/src/features/dashboard/$idOrganization/years/YearsListTable.tsx b/packages/website/src/features/dashboard/$idOrganization/years/YearsListTable.tsx index bcc78fab..35557f30 100644 --- a/packages/website/src/features/dashboard/$idOrganization/years/YearsListTable.tsx +++ b/packages/website/src/features/dashboard/$idOrganization/years/YearsListTable.tsx @@ -7,7 +7,7 @@ import { EmptyState } from "../../../../components/layouts/EmptyState.tsx" import { ListTable } from "../../../../components/layouts/listTable/listTable.tsx" import { YearListTableRow } from "./YearListTableRow.tsx" -export function YearsListTable(props: { idOrganization: v.InferOutput["id"] }) { +export function YearsListTable(_props: { idOrganization: v.InferOutput["id"] }) { return ( - - - + + + + + + + , + ) + } + > } - text={undefined} - /> - - - - - - - - , - ) - } - > - } - text="Supprimer" - color="danger" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> - - - - - + /> + + + + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx index 82e36845..46c17602 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileActions.tsx @@ -93,229 +93,227 @@ export function FileActions(props: { file: v.InferOutput - - - + + + + - - - - - - - + + + + + +
, - ) - }} - > - } - text="Modifier" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> - - - - + + {props.file.storageKey && isOcrSupportedType && ( +
{ + if (!hasOcrAvailable) { + setOcrTooltipOpen(true) } - > - } - text="Déplacer" + }} + onPointerLeave={() => setOcrTooltipOpen(false)} + > + + - - {props.file.storageKey && isOcrSupportedType && ( -
{ - if (!hasOcrAvailable) { - setOcrTooltipOpen(true) - } - }} - onPointerLeave={() => setOcrTooltipOpen(false)} - > - - - - {!hasOcrAvailable && ocrTooltipOpen && ( -
- Aucune page OCR disponible -
- )} -
- )} - - - + + {!hasOcrAvailable && ocrTooltipOpen && ( +
+ Aucune page OCR disponible +
+ )} +
+ )} + + + + + + , + ) + } + > + } + text="Supprimer" + color="danger" className={css({ width: "100%", + justifyContent: "start", })} - onClick={() => - openModal( - deleteModalId, - - - Voulez-vous supprimer ce fichier ? - - - - Cette action supprimera le fichier et toutes les données associées. - Cette action est irréversible. - - - - - - - , - ) - } - > - } - text="Supprimer" - color="danger" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> - - - - - + /> + + + + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx index a5c4303c..0efad7b8 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FileContextMenu.tsx @@ -49,114 +49,112 @@ export function FileContextMenu(props: { } return ( - <> - - {props.children} - - } - onSelect={() => { - applicationRouter.navigate({ - to: "/dashboard/organisations/$idOrganization/stockage/$idFile", - params: { - idOrganization: props.idOrganization, - idFile: props.file.id, - }, - }) - }} - > - Ouvrir - - } - onSelect={() => { - const r = { - current: "", - } - r.current = openPanelTab( - "Modifier le fichier", -
+ {props.children} + + } + onSelect={() => { + applicationRouter.navigate({ + to: "/dashboard/organisations/$idOrganization/stockage/$idFile", + params: { + idOrganization: props.idOrganization, + idFile: props.file.id, + }, + }) + }} + > + Ouvrir + + } + onSelect={() => { + const r = { + current: "", + } + r.current = openPanelTab( + "Modifier le fichier", +
+ closeTab(r.current)} + /> +
, + ) + }} + > + Modifier +
+ } + onSelect={() => + openModal( + moveModalId, + + + Déplacer le fichier + + - closeTab(r.current)} + onSuccess={() => closeModal(moveModalId)} /> -
, - ) - }} - > - Modifier -
- } - onSelect={() => - openModal( - moveModalId, - - - Déplacer le fichier - - + , + ) + } + > + Déplacer + + + } + color="danger" + onSelect={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer ce fichier ? + + + + Cette action supprimera le fichier et toutes les données associées. Cette action + est irréversible. + + + + + - - - , - ) - } - > - Supprimer - -
-
- + + + , + ) + } + > + Supprimer + + + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx index 13a58d83..820ab688 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FilesTableSelectionActions.tsx @@ -108,77 +108,75 @@ export function FilesTableSelectionActions(props: { selectedRows: Array - - - + + + + + + + , + ) + } + > } - text={undefined} - /> - - - - - - - - , - ) - } - > - } - text="Supprimer" - color="danger" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> - - - - - + /> + + + + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx index 85f9055c..0ec24cc0 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderActions.tsx @@ -59,164 +59,161 @@ export function FolderActions(props: { } return ( - <> - - - + + + + - - - - - - - + + + + + +
, - ) - }} - > - } - text="Renommer" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> - - - - + + + + + - - - - - - - , - ) - } - > - } - text="Supprimer" - color="danger" - className={css({ - width: "100%", - justifyContent: "start", - })} - /> - - - - - + /> + + + + ) } diff --git a/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx index 38af5f30..6b02ee7e 100644 --- a/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx +++ b/packages/website/src/features/dashboard/$idYear/files/FolderContextMenu.tsx @@ -51,100 +51,98 @@ export function FolderContextMenu(props: { } return ( - <> - - {props.children} - - } - onSelect={() => { - const r = { - current: "", - } - r.current = openPanelTab( - "Renommer le dossier", -
+ {props.children} + + } + onSelect={() => { + const r = { + current: "", + } + r.current = openPanelTab( + "Renommer le dossier", +
+ closeTab(r.current)} + /> +
, + ) + }} + > + Renommer +
+ } + onSelect={() => + openModal( + moveModalId, + + + Déplacer le dossier + + - closeTab(r.current)} + onSuccess={() => closeModal(moveModalId)} /> -
, - ) - }} - > - Renommer -
- } - onSelect={() => - openModal( - moveModalId, - - - Déplacer le dossier - - + , + ) + } + > + Déplacer + + + } + color="danger" + onSelect={() => + openModal( + deleteModalId, + + + Voulez-vous supprimer ce dossier ? + + + + Cette action supprimera le dossier et tous ses sous-dossiers. Les fichiers + contenus ne seront pas supprimés. Cette action est irréversible. + + + + + - - - , - ) - } - > - Supprimer - -
-
- + + + , + ) + } + > + Supprimer + + + ) } diff --git a/packages/website/src/features/dashboard/DashboardDefaultPage.tsx b/packages/website/src/features/dashboard/DashboardDefaultPage.tsx index 879d9e18..fdab5321 100644 --- a/packages/website/src/features/dashboard/DashboardDefaultPage.tsx +++ b/packages/website/src/features/dashboard/DashboardDefaultPage.tsx @@ -1,7 +1,5 @@ -import { Button, ButtonGhostContent, ButtonOutlineContent, Kbd, LinkButton, LinkContent } from "@arrhes/ui" +import { Kbd } from "@arrhes/ui" import { css } from "@arrhes/ui/utilities/cn.js" -import { IconBook, IconPlus } from "@tabler/icons-react" -import { Link } from "@tanstack/react-router" export function DashboardDefaultPage() { return ( diff --git a/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx b/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx index 3a60b39e..0b5220e8 100644 --- a/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx +++ b/packages/website/src/features/docs/general/architecture/ArchitectureDiagram.tsx @@ -16,11 +16,25 @@ export function ArchitectureDiagram() { xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Diagramme d'architecture d'Arrhes : Utilisateurs et Développeurs/Agent IA vers Dashboard, CLI et API, puis Database" - style={{ width: "100%", height: "auto", display: "block" }} + style={{ + width: "100%", + height: "auto", + display: "block", + }} > - - + + @@ -36,61 +50,227 @@ export function ArchitectureDiagram() { {/* ── Connector lines (drawn first, behind boxes) ───────── */} {/* Utilisateurs → Dashboard */} - + {/* Développeurs → API (straight down through the gap in row 2) */} - + {/* Développeurs → CLI */} - + {/* Dashboard → API */} - + {/* CLI → API */} - + {/* API → Database */} - + {/* ── Row 1 : 1/3 Utilisateurs + 2/3 Développeurs ──────── */} {/* Utilisateurs — 1/3 (x=15, w=190, cx=110) */} - - + + Utilisateurs - + Utilisation simple {/* Développeurs — 2/3 (x=215, w=390, cx=410) */} - - + + Développeurs - + Intégrations · Automatisations · IA {/* ── Row 2 : 1/3 Dashboard + gap + 1/3 CLI ────────────── */} {/* Dashboard — 1/3 (x=15, w=190, cx=110) */} - - + + Dashboard {/* CLI — 1/3 (x=415, w=190, cx=510) */} - - + + CLI {/* ── Row 3 : API full width (h=36) ────────────────────── */} - - + + API {/* ── Row 4 : Database full width (h=36, same as API) ───── */} - - + + Database diff --git a/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx b/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx index 9fadf008..aa301db9 100644 --- a/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx +++ b/packages/website/src/features/docs/general/architecture/ArchitectureGeneralDocPage.tsx @@ -40,14 +40,14 @@ export function ArchitectureGeneralDocPage() { {/* Sections */}

- Arrhes est organisé en plusieurs services distincts qui travaillent ensemble. Chaque service a - un rôle précis : certains sont destinés aux utilisateurs finaux, d'autres aux développeurs qui + Arrhes est organisé en plusieurs services distincts qui travaillent ensemble. Chaque service a un + rôle précis : certains sont destinés aux utilisateurs finaux, d'autres aux développeurs qui souhaitent intégrer Arrhes dans leurs outils.

- Tous les services passent par l'API, qui est le cœur du système. C'est elle - qui gère les données, les autorisations et la logique métier. Le reste — dashboard, CLI, agent IA - — n'est que la façon dont chacun choisit d'y accéder. + Tous les services passent par l'API, qui est le cœur du système. C'est elle qui + gère les données, les autorisations et la logique métier. Le reste — dashboard, CLI, agent IA — + n'est que la façon dont chacun choisit d'y accéder.

@@ -58,8 +58,8 @@ export function ArchitectureGeneralDocPage() { discuter avec l'assistant IA.

- Pour qui ? Les utilisateurs qui souhaitent gérer leur comptabilité au - quotidien depuis un navigateur, sans installation ni configuration. + Pour qui ? Les utilisateurs qui souhaitent gérer leur comptabilité au quotidien + depuis un navigateur, sans installation ni configuration.

@@ -70,8 +70,8 @@ export function ArchitectureGeneralDocPage() { directement depuis un terminal, sur Linux ou macOS.

- Pour qui ? Les développeurs et équipes techniques qui souhaitent automatiser - des tâches, intégrer Arrhes dans des scripts ou des pipelines CI/CD. + Pour qui ? Les développeurs et équipes techniques qui souhaitent automatiser des + tâches, intégrer Arrhes dans des scripts ou des pipelines CI/CD.

@@ -82,21 +82,21 @@ export function ArchitectureGeneralDocPage() { données comptables, du stockage des fichiers et de l'assistant IA.

- Pour qui ? Les développeurs qui souhaitent accéder directement aux données - d'Arrhes depuis leur propre application, via des clés API. + Pour qui ? Les développeurs qui souhaitent accéder directement aux données d'Arrhes + depuis leur propre application, via des clés API.

- La base de données stocke l'ensemble des données d'Arrhes : utilisateurs, organisations, - exercices, écritures comptables, fichiers et sessions. Elle est le seul endroit où les données - sont persistées et n'est jamais accessible directement depuis l'extérieur — uniquement via l'API. + La base de données stocke l'ensemble des données d'Arrhes : utilisateurs, organisations, exercices, + écritures comptables, fichiers et sessions. Elle est le seul endroit où les données sont persistées + et n'est jamais accessible directement depuis l'extérieur — uniquement via l'API.

- Le stockage des fichiers (pièces justificatives, documents exportés) est géré séparément, dans - un espace dédié compatible avec le protocole S3. Les emails transactionnels — comme les liens - de connexion — sont envoyés via un service SMTP. + Le stockage des fichiers (pièces justificatives, documents exportés) est géré séparément, dans un + espace dédié compatible avec le protocole S3. Les emails transactionnels — comme les liens de + connexion — sont envoyés via un service SMTP.

Pour qui ? Ce service est entièrement géré par Arrhes. Les utilisateurs et diff --git a/packages/website/vite.config.ts b/packages/website/vite.config.ts index 4ebb2d8b..cfdcac80 100644 --- a/packages/website/vite.config.ts +++ b/packages/website/vite.config.ts @@ -1,7 +1,5 @@ -import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" -import { dirname, resolve } from "node:path" import react from "@vitejs/plugin-react" -import { defineConfig, type Plugin, build as viteBuild } from "vite" +import { defineConfig } from "vite" import { docsSearchIndexPlugin } from "./plugins/docsSearchIndexPlugin" import { fontPreloadPlugin } from "./plugins/fontPreloadPlugin" import { prerenderPlugin } from "./plugins/prerenderPlugin" From 93e68c76623d0146eb065268692aff2330b2ffc5 Mon Sep 17 00:00:00 2001 From: &mile Date: Tue, 19 May 2026 19:27:38 +0200 Subject: [PATCH 14/14] chore: bump version to v1.3.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 0408c30b..8b3a0227 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.2.0 \ No newline at end of file +v1.3.0 \ No newline at end of file