From df56eeab9531203029bfc24965de007360f1bba5 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Mon, 18 May 2026 20:31:33 +0000 Subject: [PATCH 01/11] chore(deps): update mantine monorepo to v9 --- pnpm-lock.yaml | 430 ++++++++++++++++++++------------------------ pnpm-workspace.yaml | 22 +-- 2 files changed, 210 insertions(+), 242 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5af90c4d6..80cfe4037 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -64,38 +64,38 @@ catalogs: specifier: ^1.4.0 version: 1.4.0 '@mantine/charts': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/colors-generator': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/core': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/dates': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/dropzone': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/form': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/hooks': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/modals': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/notifications': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/spotlight': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@mantine/tiptap': - specifier: ^8.3.18 - version: 8.3.18 + specifier: ^9.2.0 + version: 9.2.1 '@next/eslint-plugin-next': specifier: 16.2.6 version: 16.2.6 @@ -777,22 +777,22 @@ importers: version: link:../../packages/widgets '@mantine/colors-generator': specifier: 'catalog:' - version: 8.3.18(chroma-js@3.2.0) + version: 9.2.1(chroma-js@3.2.0) '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/dropzone': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) '@mantine/modals': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/tiptap': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tiptap/extension-link@3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4))(@tiptap/react@3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tiptap/extension-link@3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4))(@tiptap/react@3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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-dom@19.2.6(react@19.2.6))(react@19.2.6) '@tabler/icons-react': specifier: 'catalog:' version: 3.44.0(react@19.2.6) @@ -855,7 +855,7 @@ importers: version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.6) mantine-react-table: specifier: 'catalog:' - version: 2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next: specifier: 'catalog:' version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.59.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) @@ -1651,7 +1651,7 @@ importers: version: link:../server-settings '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@paralleldrive/cuid2': specifier: 'catalog:' version: 3.3.0 @@ -1795,10 +1795,10 @@ importers: version: link:../validation '@mantine/form': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) mantine-form-zod-resolver: specifier: 'catalog:' - version: 1.3.0(@mantine/form@8.3.18(react@19.2.6))(zod@4.4.3) + version: 1.3.0(@mantine/form@9.2.1(react@19.2.6))(zod@4.4.3) zod: specifier: 'catalog:' version: 4.4.3 @@ -1847,7 +1847,7 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: specifier: 'catalog:' version: 19.2.6 @@ -2043,10 +2043,10 @@ importers: version: link:../ui '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) react: specifier: 'catalog:' version: 19.2.6 @@ -2104,7 +2104,7 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@tabler/icons-react': specifier: 'catalog:' version: 3.44.0(react@19.2.6) @@ -2147,7 +2147,7 @@ importers: version: link:../ui '@mantine/notifications': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@tabler/icons-react': specifier: 'catalog:' version: 3.44.0(react@19.2.6) @@ -2205,10 +2205,10 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) adm-zip: specifier: 'catalog:' version: 0.5.17 @@ -2430,7 +2430,7 @@ importers: version: link:../server-settings '@mantine/dates': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next: specifier: 'catalog:' version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.59.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) @@ -2491,13 +2491,13 @@ importers: version: link:../ui '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) '@mantine/spotlight': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@tabler/icons-react': specifier: 'catalog:' version: 3.44.0(react@19.2.6) @@ -2549,7 +2549,7 @@ importers: version: 4.3.1 mantine-react-table: specifier: 'catalog:' - version: 2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next: specifier: 'catalog:' version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.59.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) @@ -2598,13 +2598,13 @@ importers: version: link:../validation '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/dates': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) '@tabler/icons-react': specifier: 'catalog:' version: 3.44.0(react@19.2.6) @@ -2613,7 +2613,7 @@ importers: version: 4.2.0 mantine-react-table: specifier: 'catalog:' - version: 2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next: specifier: 'catalog:' version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.59.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) @@ -2753,13 +2753,13 @@ importers: version: link:../validation '@mantine/charts': specifier: 'catalog:' - version: 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1)) + version: 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1)) '@mantine/core': specifier: 'catalog:' - version: 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' - version: 8.3.18(react@19.2.6) + version: 9.2.1(react@19.2.6) '@tabler/icons-react': specifier: 'catalog:' version: 3.44.0(react@19.2.6) @@ -2807,7 +2807,7 @@ importers: version: 3.23.2(@tiptap/core@3.23.4(@tiptap/pm@3.23.4)) '@tiptap/react': specifier: 'catalog:' - version: 3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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) + version: 3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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) '@tiptap/starter-kit': specifier: 'catalog:' version: 3.23.4 @@ -2819,10 +2819,10 @@ importers: version: 1.11.20 mantine-form-zod-resolver: specifier: 'catalog:' - version: 1.3.0(@mantine/form@8.3.18(react@19.2.6))(zod@4.4.3) + version: 1.3.0(@mantine/form@9.2.1(react@19.2.6))(zod@4.4.3) mantine-react-table: specifier: 'catalog:' - version: 2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next: specifier: 'catalog:' version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.59.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) @@ -3749,17 +3749,23 @@ packages: '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + '@floating-ui/dom@1.7.4': resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} - '@floating-ui/react-dom@2.1.6': - resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + '@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/react@0.27.16': - resolution: {integrity: sha512-9O8N4SeG2z++TSM8QA/KTeKFBVCNEz/AGS7gWPJf6KFRzmRWixFRnCnkPHRDwSVZW6QPDO6uT0P2SpWNKCc9/g==} + '@floating-ui/react@0.27.19': + resolution: {integrity: sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==} peerDependencies: react: '>=17.0.0' react-dom: '>=17.0.0' @@ -3767,6 +3773,9 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@formatjs/ecma402-abstract@3.1.0': resolution: {integrity: sha512-CjP1sUzM7XiQW6YluDreN+dMvcKZysO/J4ikvuDjDyd6nSOoSqAK9gvD1s75ZFaJVXtYOsz+y3CUXPZ1sKxcxw==} @@ -4208,92 +4217,92 @@ packages: '@libsql/core@0.14.0': resolution: {integrity: sha512-nhbuXf7GP3PSZgdCY2Ecj8vz187ptHlZQ0VRc751oB2C1W8jQUXKKklvt7t1LJiUTQBVJuadF628eUk+3cRi4Q==} - '@mantine/charts@8.3.18': - resolution: {integrity: sha512-oudif3EUH7Nb9DPm0abAPxpFYDWWjR3k2S5ll0/CcB+pJzlhwaBG19QwpOJaRA6VAvAXDDKOXCO4mi9XCEN78g==} + '@mantine/charts@9.2.1': + resolution: {integrity: sha512-AVP0VEfcsbWwLBeU8rbEsN2gz3GebQECTreRq5AJ0Z5V1eWmTO7XFkRP9C5C6oHnkY4Vppa1x8cRYgyTsc/YbQ==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x - recharts: '>=2.13.3' + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 + react: ^19.2.0 + react-dom: ^19.2.0 + recharts: '>=3.2.1' - '@mantine/colors-generator@8.3.18': - resolution: {integrity: sha512-u7gNAuVD/WPvB49uNszfkn7lQr85OXTI0Ijkbutcymhv0/utqlapQvZlQAYHwdrrWpQgqPNLsDBt3VSheVe9jw==} + '@mantine/colors-generator@9.2.1': + resolution: {integrity: sha512-kfO8uxxBbHGJdrZtcpfsJ/K6+9xeNMsGa01o2IgOGOU2fOIn8wCkbGL9sdcfkurwVhipmf8LNQJiPHHfmbmBpQ==} peerDependencies: chroma-js: '>=2.4.2' - '@mantine/core@8.3.18': - resolution: {integrity: sha512-9tph1lTVogKPjTx02eUxDUOdXacPzK62UuSqb4TdGliI54/Xgxftq0Dfqu6XuhCxn9J5MDJaNiLDvL/1KRkYqA==} + '@mantine/core@9.2.1': + resolution: {integrity: sha512-CicPg9i2dM2pGp1jj+dMiR/63OFDsPjgJke4v5+0nbfJ+C7gn4C+7ltrp4RIETDMZHcj0fFuDRG0qtbiyBxvWA==} peerDependencies: - '@mantine/hooks': 8.3.18 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/hooks': 9.2.1 + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/dates@8.3.18': - resolution: {integrity: sha512-FHx5teJOhupI0gO2o5evtVYQEdqOjayOkLRhEQfB5Nc5DvcysfPfmNILGkc1Nrp9ZQeQWKLT9qr+CkcCXwHOaw==} + '@mantine/dates@9.2.1': + resolution: {integrity: sha512-cyRC8bnZ6W+SzQf/RM+/eDeWhZTZF148z+OcgqiERdkAujh0q88Ddybv/Hshv1EOf0rCe6oiHSZWxIxmUf7KAg==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 dayjs: '>=1.0.0' - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/dropzone@8.3.18': - resolution: {integrity: sha512-GaYUUl/382R7hl1g6heTCZ5a6T5x6qYPg0oID6ik/J0j7e5+XMZyTH5ITpaqpsBQ09GKKsF5y3iNehpSby8Kew==} + '@mantine/dropzone@9.2.1': + resolution: {integrity: sha512-rgebEz2bUubqA5jQpsh0SZ9/4DJFnUSF+a4p8uzAVlgNfo6aU/r+I4lEsD8gzLKuxrfN0TgkwR1qmAjLWIy0yQ==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/form@8.3.18': - resolution: {integrity: sha512-r5OGLJWTkmIruFjRZRZy9oA7maNYlyt50jB4Pmd2X5360WOmJLd4KH8MFhHZQC7vN+z8/rmBl3t3XGAR2I8xig==} + '@mantine/form@9.2.1': + resolution: {integrity: sha512-PV0dcbmsKhZkn3Ryztqp8Kb1N16v2nWXO71p4utTmN7E/lHWHO1ccj7Y72sIteWJo1YeNHzzkssaYRSnxgOvYA==} peerDependencies: - react: ^18.x || ^19.x + react: ^19.2.0 - '@mantine/hooks@8.3.18': - resolution: {integrity: sha512-QoWr9+S8gg5050TQ06aTSxtlpGjYOpIllRbjYYXlRvZeTsUqiTbVfvQROLexu4rEaK+yy9Wwriwl9PMRgbLqPw==} + '@mantine/hooks@9.2.1': + resolution: {integrity: sha512-IX/ztVG9eWmQTRsN7G8odyW4JckNvN8qv5A2ULzXyazjtAKLuaUpuMz0c6XhRp10J0g4bVfV3rhrTgWeImqxqg==} peerDependencies: - react: ^18.x || ^19.x + react: ^19.2.0 - '@mantine/modals@8.3.18': - resolution: {integrity: sha512-JfPDS4549L314SxFPC1x6CbKwzh82OdnIzwgMxPCVNsWLKV2vEHHUH/fzUYj4Wli6IBrsW4cufjMj9BTj3hm3Q==} + '@mantine/modals@9.2.1': + resolution: {integrity: sha512-YvZ85ZtMg6arFserkmmP18gJRD9ztLLT3vz8UrkwCdVwTGGr14X93hhS0UtR5X96ANXUzC8fU/S2ncQmNqw+NQ==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/notifications@8.3.18': - resolution: {integrity: sha512-IpQ0lmwbigTBbZCR6iSYWqIOKEx1tlcd7PcEJ5M5X1qeVSY/N3mmDQt1eJmObvcyDeL5cTJMbSA9UPqhRqo9jw==} + '@mantine/notifications@9.2.1': + resolution: {integrity: sha512-H6lSsKUPdWPYcXFeOcqqcegUl72Iua9yD369s/gchfDvI+PrL4IM5UuWNHTeABJ1eb9FbTOw8B5RDSMZjTZNSA==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/spotlight@8.3.18': - resolution: {integrity: sha512-yFoEYG0wKduxbnv6+1CUOXc91lmQ5DN4QvEShYO2ftDm0kXhxeOvJFtGOBYK80tpmSCsaT253p9E3J3DcaOt2w==} + '@mantine/spotlight@9.2.1': + resolution: {integrity: sha512-D6/BJ8/ftUBwiSFGTtYUM/LqlBk40XZqZFlmEFRM8chDPzEId1O+5FU7mj8KapPR9zRgoAcdT4LMI6JaLp0c0A==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 + react: ^19.2.0 + react-dom: ^19.2.0 - '@mantine/store@8.3.18': - resolution: {integrity: sha512-i+QRTLmZzLldea0egtUVnGALd6UMIu8jd44nrNWBSNIXJU/8B6rMlC6gyX+l4szopZSuOaaNJIXkqRdC1gQsVg==} + '@mantine/store@9.2.1': + resolution: {integrity: sha512-sBTHt9ilfSZAeXQlqFkm8nRm22RunhevxuOUtdSwS9HhuMuS8T27dRRgbdKH2oEFUbaccdQSy5bHbmGbEgVO8w==} peerDependencies: - react: ^18.x || ^19.x + react: ^19.2.0 - '@mantine/tiptap@8.3.18': - resolution: {integrity: sha512-CrV5E0ELJmegyq+iF4g6PkEeC95wGY9QjWjb+JS1KE4UbxJONxRxGhpjQMp1t/Ir2aFVu9Gbf/fQ0qSnD6Lmqw==} + '@mantine/tiptap@9.2.1': + resolution: {integrity: sha512-UzztgwqIknJheF39cqG2AgPI1qEvXIa7jNFuij8iB6GLd0UMmCjKnW42Px0WAaHuNfMjweml9IyTLBTSvIK0uA==} peerDependencies: - '@mantine/core': 8.3.18 - '@mantine/hooks': 8.3.18 - '@tiptap/extension-link': '>=2.1.12' - '@tiptap/react': '>=2.1.12' - react: ^18.x || ^19.x - react-dom: ^18.x || ^19.x + '@mantine/core': 9.2.1 + '@mantine/hooks': 9.2.1 + '@tiptap/extension-link': '>=3.3.0' + '@tiptap/react': '>=3.3.0' + react: ^19.2.0 + react-dom: ^19.2.0 '@next/env@16.2.6': resolution: {integrity: sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==} @@ -9186,8 +9195,8 @@ packages: '@types/react': '>=18' react: '>=18' - react-number-format@5.4.4: - resolution: {integrity: sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==} + react-number-format@5.4.5: + resolution: {integrity: sha512-y8O2yHHj3w0aE9XO8d2BCcUOOdQTRSVq+WIuMlLVucAm5XNjJAy+BoOJiuQMldVYVOKTMyvVNfnbl2Oqp+YxGw==} peerDependencies: react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -9225,8 +9234,8 @@ packages: '@types/react': optional: true - react-remove-scroll@2.7.1: - resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} engines: {node: '>=10'} peerDependencies: '@types/react': '*' @@ -9257,12 +9266,6 @@ packages: peerDependencies: react: '>= 0.14.0' - react-textarea-autosize@8.5.9: - resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==} - engines: {node: '>=10'} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-transition-group@4.4.5: resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: @@ -10301,11 +10304,6 @@ packages: '@types/react': optional: true - use-composed-ref@1.3.0: - resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - use-deep-compare-effect@1.8.1: resolution: {integrity: sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==} engines: {node: '>=10', npm: '>=6'} @@ -10317,24 +10315,6 @@ packages: peerDependencies: react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 - use-isomorphic-layout-effect@1.1.2: - resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - - use-latest@1.2.1: - resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} - peerDependencies: - '@types/react': '*' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - use-sidecar@1.1.3: resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} engines: {node: '>=10'} @@ -11355,27 +11335,41 @@ snapshots: '@floating-ui/core@1.7.3': dependencies: '@floating-ui/utils': 0.2.10 + optional: true + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 '@floating-ui/dom@1.7.4': dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 + optional: true - '@floating-ui/react-dom@2.1.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@floating-ui/dom@1.7.6': dependencies: - '@floating-ui/dom': 1.7.4 + '@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/react@0.27.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@floating-ui/react@0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@floating-ui/utils': 0.2.10 + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/utils': 0.2.11 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) tabbable: 6.2.0 - '@floating-ui/utils@0.2.10': {} + '@floating-ui/utils@0.2.10': + optional: true + + '@floating-ui/utils@0.2.11': {} '@formatjs/ecma402-abstract@3.1.0': dependencies: @@ -11799,93 +11793,93 @@ snapshots: js-base64: 3.7.8 optional: true - '@mantine/charts@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1))': + '@mantine/charts@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(recharts@3.8.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1))': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) recharts: 3.8.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.6)(react@19.2.6)(redux@5.0.1) - '@mantine/colors-generator@8.3.18(chroma-js@3.2.0)': + '@mantine/colors-generator@9.2.1(chroma-js@3.2.0)': dependencies: chroma-js: 3.2.0 - '@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@floating-ui/react': 0.27.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@floating-ui/react': 0.27.19(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) clsx: 2.1.1 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - react-number-format: 5.4.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react-remove-scroll: 2.7.1(@types/react@19.2.14)(react@19.2.6) - react-textarea-autosize: 8.5.9(@types/react@19.2.14)(react@19.2.6) - type-fest: 4.41.0 + react-number-format: 5.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) + type-fest: 5.6.0 transitivePeerDependencies: - '@types/react' - '@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) clsx: 2.1.1 dayjs: 1.11.20 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - '@mantine/dropzone@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/dropzone@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) react-dropzone: 15.0.0(react@19.2.6) - '@mantine/form@8.3.18(react@19.2.6)': + '@mantine/form@9.2.1(react@19.2.6)': dependencies: + '@standard-schema/spec': 1.1.0 fast-deep-equal: 3.1.3 klona: 2.0.6 react: 19.2.6 - '@mantine/hooks@8.3.18(react@19.2.6)': + '@mantine/hooks@9.2.1(react@19.2.6)': dependencies: react: 19.2.6 - '@mantine/modals@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/modals@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - '@mantine/notifications@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/notifications@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) - '@mantine/store': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) + '@mantine/store': 9.2.1(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/spotlight@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/spotlight@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) - '@mantine/store': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) + '@mantine/store': 9.2.1(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - '@mantine/store@8.3.18(react@19.2.6)': + '@mantine/store@9.2.1(react@19.2.6)': dependencies: react: 19.2.6 - '@mantine/tiptap@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tiptap/extension-link@3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4))(@tiptap/react@3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mantine/tiptap@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tiptap/extension-link@3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4))(@tiptap/react@3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) '@tiptap/extension-link': 3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4) - '@tiptap/react': 3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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) + '@tiptap/react': 3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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) @@ -13025,9 +13019,9 @@ snapshots: dependencies: '@tiptap/extensions': 3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4) - '@tiptap/extension-floating-menu@3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)': + '@tiptap/extension-floating-menu@3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)': dependencies: - '@floating-ui/dom': 1.7.4 + '@floating-ui/dom': 1.7.6 '@tiptap/core': 3.23.4(@tiptap/pm@3.23.4) '@tiptap/pm': 3.23.4 optional: true @@ -13166,7 +13160,7 @@ snapshots: prosemirror-transform: 1.10.2 prosemirror-view: 1.41.4 - '@tiptap/react@3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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)': + '@tiptap/react@3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4)(@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: '@tiptap/core': 3.23.4(@tiptap/pm@3.23.4) '@tiptap/pm': 3.23.4 @@ -13179,7 +13173,7 @@ snapshots: use-sync-external-store: 1.4.0(react@19.2.6) optionalDependencies: '@tiptap/extension-bubble-menu': 3.23.4(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4) - '@tiptap/extension-floating-menu': 3.23.4(@floating-ui/dom@1.7.4)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4) + '@tiptap/extension-floating-menu': 3.23.4(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.4(@tiptap/pm@3.23.4))(@tiptap/pm@3.23.4) transitivePeerDependencies: - '@floating-ui/dom' @@ -16220,16 +16214,16 @@ snapshots: dependencies: semver: 7.7.4 - mantine-form-zod-resolver@1.3.0(@mantine/form@8.3.18(react@19.2.6))(zod@4.4.3): + mantine-form-zod-resolver@1.3.0(@mantine/form@9.2.1(react@19.2.6))(zod@4.4.3): dependencies: - '@mantine/form': 8.3.18(react@19.2.6) + '@mantine/form': 9.2.1(react@19.2.6) zod: 4.4.3 - mantine-react-table@2.0.0-beta.9(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + mantine-react-table@2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/dates': 8.3.18(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/dates': 9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) '@tabler/icons-react': 3.44.0(react@19.2.6) '@tanstack/match-sorter-utils': 8.19.4 '@tanstack/react-table': 8.20.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -17366,7 +17360,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-number-format@5.4.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-number-format@5.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) @@ -17398,7 +17392,7 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - react-remove-scroll@2.7.1(@types/react@19.2.14)(react@19.2.6): + 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) @@ -17432,15 +17426,6 @@ snapshots: react: 19.2.6 refractor: 5.0.0 - react-textarea-autosize@8.5.9(@types/react@19.2.14)(react@19.2.6): - dependencies: - '@babel/runtime': 7.29.2 - react: 19.2.6 - use-composed-ref: 1.3.0(react@19.2.6) - use-latest: 1.2.1(@types/react@19.2.14)(react@19.2.6) - transitivePeerDependencies: - - '@types/react' - react-transition-group@4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 @@ -18711,10 +18696,6 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 - use-composed-ref@1.3.0(react@19.2.6): - dependencies: - react: 19.2.6 - use-deep-compare-effect@1.8.1(react@19.2.6): dependencies: '@babel/runtime': 7.29.2 @@ -18729,19 +18710,6 @@ snapshots: intl-messageformat: 11.1.1 react: 19.2.6 - use-isomorphic-layout-effect@1.1.2(@types/react@19.2.14)(react@19.2.6): - dependencies: - react: 19.2.6 - optionalDependencies: - '@types/react': 19.2.14 - - use-latest@1.2.1(@types/react@19.2.14)(react@19.2.6): - dependencies: - react: 19.2.6 - use-isomorphic-layout-effect: 1.1.2(@types/react@19.2.14)(react@19.2.6) - 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 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7223dda65..fa6afe4b6 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -22,17 +22,17 @@ catalog: "@immich/sdk": ^2.7.5 "@jellyfin/sdk": ^0.13.0 "@kubernetes/client-node": ^1.4.0 - "@mantine/charts": ^8.3.18 - "@mantine/colors-generator": ^8.3.18 - "@mantine/core": ^8.3.18 - "@mantine/dates": ^8.3.18 - "@mantine/dropzone": ^8.3.18 - "@mantine/form": ^8.3.18 - "@mantine/hooks": ^8.3.18 - "@mantine/modals": ^8.3.18 - "@mantine/notifications": ^8.3.18 - "@mantine/spotlight": ^8.3.18 - "@mantine/tiptap": ^8.3.18 + "@mantine/charts": ^9.2.0 + "@mantine/colors-generator": ^9.2.0 + "@mantine/core": ^9.2.0 + "@mantine/dates": ^9.2.0 + "@mantine/dropzone": ^9.2.0 + "@mantine/form": ^9.2.0 + "@mantine/hooks": ^9.2.0 + "@mantine/modals": ^9.2.0 + "@mantine/notifications": ^9.2.0 + "@mantine/spotlight": ^9.2.0 + "@mantine/tiptap": ^9.2.0 "@next/eslint-plugin-next": 16.2.6 "@octokit/auth-app": ^8.2.0 "@paralleldrive/cuid2": ^3.3.0 From cb5b73ddbd04520be1bc58a5ee1a081f782c7dd6 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Tue, 19 May 2026 14:58:51 +0200 Subject: [PATCH 02/11] chore: migrate to mantine v9 Followed the migration guide --- .../[locale]/_client-providers/mantine.tsx | 1 + .../app/[locale]/auth/login/_login-form.tsx | 2 +- .../app/[locale]/boards/(content)/_theme.tsx | 1 + .../boards/[name]/settings/_appereance.tsx | 2 +- apps/nextjs/src/app/[locale]/layout.tsx | 2 +- .../secrets/integration-secret-card.tsx | 2 +- .../new/_integration-new-form.tsx | 2 +- .../board/sections/category-section.tsx | 2 +- packages/form/package.json | 1 - packages/form/src/index.ts | 5 ++-- .../forms-collection/src/new-app/_form.tsx | 2 +- packages/ui/src/theme.ts | 1 + packages/widgets/package.json | 2 +- packages/widgets/src/downloads/component.tsx | 2 +- packages/widgets/src/firewall/component.tsx | 4 ++-- .../src/media-requests/stats/component.tsx | 2 +- .../widgets/src/modals/widget-edit-modal.tsx | 5 ++-- pnpm-lock.yaml | 24 +++---------------- pnpm-workspace.yaml | 1 - 19 files changed, 23 insertions(+), 40 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx b/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx index d81b828f3..dc240d764 100644 --- a/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx +++ b/apps/nextjs/src/app/[locale]/_client-providers/mantine.tsx @@ -23,6 +23,7 @@ export const CustomMantineProvider = ({ theme={createTheme({ primaryColor: "red", autoContrast: true, + defaultRadius: "sm", })} > {children} diff --git a/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx b/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx index 71d249cf5..10a2f7c58 100644 --- a/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx +++ b/apps/nextjs/src/app/[locale]/auth/login/_login-form.tsx @@ -198,7 +198,7 @@ const PasswordForgottenCollapse = ({ username }: PasswordForgottenCollapseProps) {tForgotPassword("label")} - + {tForgotPassword("description")} diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx index 27f3e9152..8fa031ad0 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_theme.tsx @@ -24,6 +24,7 @@ export const BoardMantineProvider = ({ }, primaryColor: "primaryColor", autoContrast: true, + defaultRadius: "sm", fontSizes: { "2xl": rem(24), "3xl": rem(28), diff --git a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_appereance.tsx b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_appereance.tsx index 95b3602e6..4af4af15f 100644 --- a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_appereance.tsx +++ b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_appereance.tsx @@ -83,7 +83,7 @@ export const ColorSettingsContent = ({ board }: Props) => { {showPreview ? t("common.preview.hide") : t("common.preview.show")} - + diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx index 5449e1252..9342e0d30 100644 --- a/apps/nextjs/src/app/[locale]/layout.tsx +++ b/apps/nextjs/src/app/[locale]/layout.tsx @@ -142,7 +142,7 @@ export default async function Layout(props: { - + {props.children} diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx index 06c4baff3..cc6a0a752 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/_components/secrets/integration-secret-card.tsx @@ -79,7 +79,7 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => { - {children} + {children} ); diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx index 016b9336c..b7fbf3291 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/new/_integration-new-form.tsx @@ -226,7 +226,7 @@ const AppForm = ({ form, canCreateApps }: { form: UseFormReturnType; c description={t("integration.field.createApp.description")} /> - +
{canCreateApps && ( diff --git a/apps/nextjs/src/components/board/sections/category-section.tsx b/apps/nextjs/src/components/board/sections/category-section.tsx index df204998b..81f49fa3e 100644 --- a/apps/nextjs/src/components/board/sections/category-section.tsx +++ b/apps/nextjs/src/components/board/sections/category-section.tsx @@ -44,7 +44,7 @@ export const BoardCategorySection = ({ section }: Props) => { - + diff --git a/packages/form/package.json b/packages/form/package.json index fcb7754ea..8fc2d7dac 100644 --- a/packages/form/package.json +++ b/packages/form/package.json @@ -27,7 +27,6 @@ "@homarr/translation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0", "@mantine/form": "catalog:", - "mantine-form-zod-resolver": "catalog:", "zod": "catalog:" }, "devDependencies": { diff --git a/packages/form/src/index.ts b/packages/form/src/index.ts index f1d34f193..af8e4198e 100644 --- a/packages/form/src/index.ts +++ b/packages/form/src/index.ts @@ -1,5 +1,4 @@ -import { useForm } from "@mantine/form"; -import { zod4Resolver } from "mantine-form-zod-resolver"; +import { schemaResolver, useForm } from "@mantine/form"; import type { ZodDiscriminatedUnion, ZodIntersection, ZodObject, ZodPipe } from "zod/v4"; import { z } from "zod/v4"; @@ -34,6 +33,6 @@ export const useZodForm = < ...options, validateInputOnBlur: true, validateInputOnChange: true, - validate: zod4Resolver(schema), + validate: schemaResolver(schema, { sync: true }), }); }; diff --git a/packages/forms-collection/src/new-app/_form.tsx b/packages/forms-collection/src/new-app/_form.tsx index 82f5a7caa..05c7e3f6f 100644 --- a/packages/forms-collection/src/new-app/_form.tsx +++ b/packages/forms-collection/src/new-app/_form.tsx @@ -114,7 +114,7 @@ export const AppForm = ({ mt="md" /> - + diff --git a/packages/ui/src/theme.ts b/packages/ui/src/theme.ts index e1e928d57..7439ae440 100644 --- a/packages/ui/src/theme.ts +++ b/packages/ui/src/theme.ts @@ -9,4 +9,5 @@ export const theme = createTheme({ secondaryColor, }, primaryColor: "primaryColor", + defaultRadius: "sm", }); diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 4ee4834f8..b4ce610a6 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -50,6 +50,7 @@ "@homarr/validation": "workspace:^0.1.0", "@mantine/charts": "catalog:", "@mantine/core": "catalog:", + "@mantine/form": "catalog:", "@mantine/hooks": "catalog:", "@tabler/icons-react": "catalog:", "@tiptap/extension-color": "catalog:", @@ -70,7 +71,6 @@ "@tiptap/starter-kit": "catalog:", "clsx": "catalog:", "dayjs": "catalog:", - "mantine-form-zod-resolver": "catalog:", "mantine-react-table": "catalog:", "next": "catalog:", "react": "catalog:", diff --git a/packages/widgets/src/downloads/component.tsx b/packages/widgets/src/downloads/component.tsx index 9af29da6d..8e27d702f 100644 --- a/packages/widgets/src/downloads/component.tsx +++ b/packages/widgets/src/downloads/component.tsx @@ -805,7 +805,7 @@ const ClientsControl = ({ clients, filters, setFilters, availableStatuses }: Cli setFilters({ ...filters, statuses: statuses as typeof filters.statuses })} + onChange={(statuses) => setFilters({ ...filters, statuses: statuses })} > {availableStatuses.map((status) => ( diff --git a/packages/widgets/src/firewall/component.tsx b/packages/widgets/src/firewall/component.tsx index 111ab85fa..cf5ac2b0e 100644 --- a/packages/widgets/src/firewall/component.tsx +++ b/packages/widgets/src/firewall/component.tsx @@ -153,7 +153,7 @@ export default function FirewallWidget({ integrationIds, width, itemId }: Widget style={{ justifyContent: "flex-start" }} > - + {formatBitsPerSec(transmit, 2)} @@ -164,7 +164,7 @@ export default function FirewallWidget({ integrationIds, width, itemId }: Widget style={{ justifyContent: "flex-start" }} > - + {formatBitsPerSec(receive, 2)} diff --git a/packages/widgets/src/media-requests/stats/component.tsx b/packages/widgets/src/media-requests/stats/component.tsx index ea6ca302d..e3696ef47 100644 --- a/packages/widgets/src/media-requests/stats/component.tsx +++ b/packages/widgets/src/media-requests/stats/component.tsx @@ -103,7 +103,7 @@ export default function MediaServerWidget({ {t("titles.stats.main")} - + {data.map((stat) => ( >(({ actions, i const form = useForm({ mode: "controlled", initialValues: innerProps.value, - validate: zod4Resolver( + validate: schemaResolver( z.object({ options: z.object( objectEntries(options).reduce( @@ -70,6 +70,7 @@ export const WidgetEditModal = createModal>(({ actions, i borderColor: z.string(), }), }), + { sync: true }, ), validateInputOnBlur: true, validateInputOnChange: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80cfe4037..de088b38a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -417,9 +417,6 @@ catalogs: lodash.clonedeep: specifier: ^4.5.0 version: 4.5.0 - mantine-form-zod-resolver: - specifier: ^1.3.0 - version: 1.3.0 mantine-react-table: specifier: 2.0.0-beta.9 version: 2.0.0-beta.9 @@ -1796,9 +1793,6 @@ importers: '@mantine/form': specifier: 'catalog:' version: 9.2.1(react@19.2.6) - mantine-form-zod-resolver: - specifier: 'catalog:' - version: 1.3.0(@mantine/form@9.2.1(react@19.2.6))(zod@4.4.3) zod: specifier: 'catalog:' version: 4.4.3 @@ -2757,6 +2751,9 @@ importers: '@mantine/core': specifier: 'catalog:' version: 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/form': + specifier: 'catalog:' + version: 9.2.1(react@19.2.6) '@mantine/hooks': specifier: 'catalog:' version: 9.2.1(react@19.2.6) @@ -2817,9 +2814,6 @@ importers: dayjs: specifier: 'catalog:' version: 1.11.20 - mantine-form-zod-resolver: - specifier: 'catalog:' - version: 1.3.0(@mantine/form@9.2.1(react@19.2.6))(zod@4.4.3) mantine-react-table: specifier: 'catalog:' version: 2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -8149,13 +8143,6 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - mantine-form-zod-resolver@1.3.0: - resolution: {integrity: sha512-XlXXkJCYuUuOllW0zedYW+m/lbdFQ/bso1Vz+pJOYkxgjhoGvzN2EXWCS2+0iTOT9Q7WnOwWvHmvpTJN3PxSXw==} - engines: {node: '>=16.6.0'} - peerDependencies: - '@mantine/form': '>=7.0.0' - zod: '>=3.25.0' - mantine-react-table@2.0.0-beta.9: resolution: {integrity: sha512-ZdfcwebWaPERoDvAuk43VYcBCzamohARVclnbuepT0PHZ0wRcDPMBR+zgaocL+pFy8EXUGwvWTOKNh25ITpjNQ==} engines: {node: '>=16'} @@ -16214,11 +16201,6 @@ snapshots: dependencies: semver: 7.7.4 - mantine-form-zod-resolver@1.3.0(@mantine/form@9.2.1(react@19.2.6))(zod@4.4.3): - dependencies: - '@mantine/form': 9.2.1(react@19.2.6) - zod: 4.4.3 - mantine-react-table@2.0.0-beta.9(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.20)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index fa6afe4b6..615ee2570 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -140,7 +140,6 @@ catalog: json5: ^2.2.3 ldapts: 8.1.7 lodash.clonedeep: ^4.5.0 - mantine-form-zod-resolver: ^1.3.0 mantine-react-table: 2.0.0-beta.9 maria2: ^0.4.1 mysql2: 3.22.3 From f773b4a15e7d39dab06a16d4e3354bcc005581cb Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Tue, 19 May 2026 16:21:32 +0200 Subject: [PATCH 03/11] wip --- apps/nextjs/package.json | 1 + .../boards/(content)/_header-actions.tsx | 6 +- .../app/[locale]/boards/_layout-creator.tsx | 24 +- apps/nextjs/src/app/[locale]/layout.tsx | 1 + .../nextjs/src/app/[locale]/manage/layout.tsx | 17 +- .../general/_components/_reset-tours.tsx | 57 + .../manage/users/[userId]/general/page.tsx | 11 + apps/nextjs/src/components/layout/header.tsx | 10 +- .../src/components/layout/navigation-link.tsx | 5 + .../src/components/layout/navigation.tsx | 10 +- .../src/components/onboarding/board-tour.tsx | 97 + .../src/components/onboarding/manage-tour.tsx | 144 + .../onboarding/skip-hold-button.tsx | 64 + .../components/onboarding/tour-fork-step.tsx | 41 + .../onboarding/tour-step-content.tsx | 28 + packages/api/src/router/user.ts | 40 + .../migrations/mysql/0039_strong_lizard.sql | 2 + .../migrations/mysql/meta/0039_snapshot.json | 2380 +++++++++++++++++ .../db/migrations/mysql/meta/_journal.json | 9 +- .../migrations/postgresql/0005_same_manta.sql | 2 + .../postgresql/meta/0005_snapshot.json | 2230 +++++++++++++++ .../migrations/postgresql/meta/_journal.json | 9 +- .../sqlite/0037_equal_retro_girl.sql | 2 + .../migrations/sqlite/meta/0037_snapshot.json | 2259 ++++++++++++++++ .../db/migrations/sqlite/meta/_journal.json | 9 +- packages/db/schema/mysql.ts | 2 + packages/db/schema/postgresql.ts | 2 + packages/db/schema/sqlite.ts | 2 + packages/translation/src/lang/en.json | 93 +- pnpm-lock.yaml | 23 + pnpm-workspace.yaml | 1 + 31 files changed, 7559 insertions(+), 22 deletions(-) create mode 100644 apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx create mode 100644 apps/nextjs/src/components/onboarding/board-tour.tsx create mode 100644 apps/nextjs/src/components/onboarding/manage-tour.tsx create mode 100644 apps/nextjs/src/components/onboarding/skip-hold-button.tsx create mode 100644 apps/nextjs/src/components/onboarding/tour-fork-step.tsx create mode 100644 apps/nextjs/src/components/onboarding/tour-step-content.tsx create mode 100644 packages/db/migrations/mysql/0039_strong_lizard.sql create mode 100644 packages/db/migrations/mysql/meta/0039_snapshot.json create mode 100644 packages/db/migrations/postgresql/0005_same_manta.sql create mode 100644 packages/db/migrations/postgresql/meta/0005_snapshot.json create mode 100644 packages/db/migrations/sqlite/0037_equal_retro_girl.sql create mode 100644 packages/db/migrations/sqlite/meta/0037_snapshot.json diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 409845f4e..04093c716 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -19,6 +19,7 @@ "@dnd-kit/modifiers": "catalog:", "@dnd-kit/sortable": "catalog:", "@dnd-kit/utilities": "catalog:", + "@gfazioli/mantine-onboarding-tour": "catalog:", "@homarr/analytics": "workspace:^0.1.0", "@homarr/api": "workspace:^0.1.0", "@homarr/auth": "workspace:^0.1.0", diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx index f1185430c..18c0fe241 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx @@ -53,7 +53,7 @@ export const BoardContentHeaderActions = () => { - + @@ -173,7 +173,7 @@ const EditModeMenu = () => { usePreventLeaveWithDirty(isEditMode); return ( - + {isEditMode ? : } ); @@ -185,7 +185,7 @@ const SelectBoardsMenu = () => { return ( - + diff --git a/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx b/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx index f377c932e..972577ed7 100644 --- a/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx +++ b/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx @@ -11,6 +11,7 @@ import { createLogger } from "@homarr/core/infrastructure/logs"; import { MainHeader } from "~/components/layout/header"; import { BoardLogoWithTitle } from "~/components/layout/logo/board-logo"; import { ClientShell } from "~/components/layout/shell"; +import { BoardTourProvider } from "~/components/onboarding/board-tour"; import { getCurrentColorSchemeAsync } from "~/theme/color-scheme"; import type { Board } from "./_types"; import type { Params } from "./(content)/_creator"; @@ -20,6 +21,11 @@ import { BoardMantineProvider } from "./(content)/_theme"; const logger = createLogger({ module: "createBoardLayout" }); +const BoardTourWrapper = ({ hasSession, children }: PropsWithChildren<{ hasSession: boolean }>) => { + if (!hasSession) return <>{children}; + return {children}; +}; + interface CreateBoardLayoutProps { headerActions: JSX.Element; getInitialBoardAsync: (params: TParams) => Promise; @@ -61,14 +67,16 @@ export const createBoardLayout = ({ - - } - actions={headerActions} - hasNavigation={false} - /> - {children} - + + + } + actions={headerActions} + hasNavigation={false} + /> + {children} + + diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx index 5449e1252..091e3a3f2 100644 --- a/apps/nextjs/src/app/[locale]/layout.tsx +++ b/apps/nextjs/src/app/[locale]/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata, Viewport } from "next"; import { Inter } from "next/font/google"; +import "@gfazioli/mantine-onboarding-tour/styles.css"; import "@homarr/notifications/styles.css"; import "@homarr/spotlight/styles.css"; import "@homarr/ui/styles.css"; diff --git a/apps/nextjs/src/app/[locale]/manage/layout.tsx b/apps/nextjs/src/app/[locale]/manage/layout.tsx index 32013221c..368d0b2f7 100644 --- a/apps/nextjs/src/app/[locale]/manage/layout.tsx +++ b/apps/nextjs/src/app/[locale]/manage/layout.tsx @@ -36,6 +36,7 @@ import { homarrLogoPath } from "~/components/layout/logo/homarr-logo"; import type { NavigationLink } from "~/components/layout/navigation"; import { MainNavigation } from "~/components/layout/navigation"; import { ClientShell } from "~/components/layout/shell"; +import { ManageTourProvider } from "~/components/onboarding/manage-tour"; export default async function ManageLayout({ children }: PropsWithChildren) { const t = await getScopedI18n("management.navbar"); @@ -45,11 +46,13 @@ export default async function ManageLayout({ children }: PropsWithChildren) { label: t("items.home"), icon: IconHomeFilled, href: "/manage", + "data-onboarding-tour-id": "manage-welcome", }, { icon: IconLayoutDashboardFilled, href: "/manage/boards", label: t("items.boards"), + "data-onboarding-tour-id": "manage-boards", }, { icon: IconBox, @@ -59,12 +62,14 @@ export default async function ManageLayout({ children }: PropsWithChildren) { iconProps: { strokeWidth: 2.5, }, + "data-onboarding-tour-id": "manage-apps", }, { icon: IconAffiliateFilled, href: "/manage/integrations", label: t("items.integrations"), hidden: !session, + "data-onboarding-tour-id": "manage-integrations", }, { icon: IconSearch, @@ -74,17 +79,20 @@ export default async function ManageLayout({ children }: PropsWithChildren) { iconProps: { strokeWidth: 2.5, }, + "data-onboarding-tour-id": "manage-search-engines", }, { icon: IconPhotoFilled, href: "/manage/medias", label: t("items.medias"), hidden: !session, + "data-onboarding-tour-id": "manage-medias", }, { icon: IconUserFilled, label: t("items.users.label"), hidden: !session?.user.permissions.includes("admin"), + "data-onboarding-tour-id": "manage-users", items: [ { label: t("items.users.items.manage"), @@ -153,6 +161,7 @@ export default async function ManageLayout({ children }: PropsWithChildren) { href: "/manage/settings", icon: IconSettingsFilled, hidden: !session?.user.permissions.includes("admin"), + "data-onboarding-tour-id": "manage-settings", }, { label: t("items.help.label"), @@ -191,11 +200,17 @@ export default async function ManageLayout({ children }: PropsWithChildren) { }, ]; - return ( + const isAdmin = session?.user.permissions.includes("admin") ?? false; + + const shell = ( {children} ); + + if (!session) return shell; + + return {shell}; } diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx new file mode 100644 index 000000000..d638b624e --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx @@ -0,0 +1,57 @@ +"use client"; + +import { Badge, Button, Group, Stack, Text } from "@mantine/core"; +import { IconRefresh } from "@tabler/icons-react"; + +import { clientApi } from "@homarr/api/client"; +import { showSuccessNotification } from "@homarr/notifications"; +import { useScopedI18n } from "@homarr/translation/client"; + +interface ResetToursProps { + completedManageTour: boolean; + completedBoardTour: boolean; +} + +export const ResetTours = ({ completedManageTour, completedBoardTour }: ResetToursProps) => { + const t = useScopedI18n("management.page.user.setting.general.item.onboardingTours"); + const utils = clientApi.useUtils(); + const { mutate: resetTours, isPending } = clientApi.user.resetTours.useMutation({ + onSuccess() { + showSuccessNotification({ + title: t("resetSuccess.title"), + message: t("resetSuccess.message"), + }); + void utils.user.getTourStatus.invalidate(); + }, + }); + + const tourStatusMap: Record = { + management: { key: "management", completed: completedManageTour }, + dashboard: { key: "dashboard", completed: completedBoardTour }, + }; + + return ( + + + {Object.values(tourStatusMap).map(({ key, completed }) => ( + + {t(`name.${key}`)}: {completed ? t("status.completed") : t("status.notStarted")} + + ))} + + + {t("description")} + + + + ); +}; diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx index ee960b0f5..665ab7d6c 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx @@ -18,6 +18,7 @@ import { FirstDayOfWeek } from "./_components/_first-day-of-week"; import { PingIconsEnabled } from "./_components/_ping-icons-enabled"; import { UserProfileAvatarForm } from "./_components/_profile-avatar-form"; import { UserProfileForm } from "./_components/_profile-form"; +import { ResetTours } from "./_components/_reset-tours"; interface Props { params: Promise<{ @@ -118,6 +119,16 @@ export default async function EditUserPage(props: Props) { + {session?.user.id === user.id && ( + + {tGeneral("item.onboardingTours.title")} + + + )} + { {logo ?? } - + + + {actions} - + + + diff --git a/apps/nextjs/src/components/layout/navigation-link.tsx b/apps/nextjs/src/components/layout/navigation-link.tsx index dd6949682..848f7d691 100644 --- a/apps/nextjs/src/components/layout/navigation-link.tsx +++ b/apps/nextjs/src/components/layout/navigation-link.tsx @@ -11,6 +11,7 @@ export const CommonNavLink = (props: ClientNavigationLink) => const NavLinkHref = (props: NavigationLinkHref) => { const pathname = usePathname(); + const tourId = props["data-onboarding-tour-id"]; return props.external ? ( { borderRadius: 5, }} target="_blank" + data-onboarding-tour-id={tourId} /> ) : ( { style={{ borderRadius: 5, }} + data-onboarding-tour-id={tourId} /> ); }; @@ -47,6 +50,7 @@ const NavLinkWithItems = (props: NavigationLinkWithItems) => { label={props.label} leftSection={props.icon} defaultOpened={isActive} + data-onboarding-tour-id={props["data-onboarding-tour-id"]} > {props.items.map((item) => ( @@ -58,6 +62,7 @@ const NavLinkWithItems = (props: NavigationLinkWithItems) => { interface CommonNavigationLinkProps { label: string; icon: ReactNode; + "data-onboarding-tour-id"?: string; } interface NavigationLinkHref extends CommonNavigationLinkProps { diff --git a/apps/nextjs/src/components/layout/navigation.tsx b/apps/nextjs/src/components/layout/navigation.tsx index 47f0db1b3..692c54c51 100644 --- a/apps/nextjs/src/components/layout/navigation.tsx +++ b/apps/nextjs/src/components/layout/navigation.tsx @@ -27,7 +27,7 @@ export const MainNavigation = ({ headerSection, footerSection, links }: MainNavi return null; } - const { icon: TablerIcon, iconProps, ...props } = link; + const { icon: TablerIcon, iconProps, "data-onboarding-tour-id": tourId, ...props } = link; const Icon = typeof TablerIcon === "string" ? ( @@ -38,17 +38,20 @@ export const MainNavigation = ({ headerSection, footerSection, links }: MainNavi if ("items" in props) { clientLink = { ...props, + "data-onboarding-tour-id": tourId, items: props.items .filter((item) => !item.hidden) .map((item) => { + const { "data-onboarding-tour-id": itemTourId, ...rest } = item; return { - ...item, + ...rest, + "data-onboarding-tour-id": itemTourId, icon: , }; }), } as ClientNavigationLink; } else { - clientLink = props as ClientNavigationLink; + clientLink = { ...props, "data-onboarding-tour-id": tourId } as ClientNavigationLink; } return ; })} @@ -63,6 +66,7 @@ interface CommonNavigationLinkProps { icon: TablerIcon | string; iconProps?: TablerIconProps; hidden?: boolean; + "data-onboarding-tour-id"?: string; } interface NavigationLinkHref extends CommonNavigationLinkProps { diff --git a/apps/nextjs/src/components/onboarding/board-tour.tsx b/apps/nextjs/src/components/onboarding/board-tour.tsx new file mode 100644 index 000000000..b7a9d76da --- /dev/null +++ b/apps/nextjs/src/components/onboarding/board-tour.tsx @@ -0,0 +1,97 @@ +"use client"; + +import type { PropsWithChildren } from "react"; +import { useMemo } from "react"; +import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; +import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; + +import { clientApi } from "@homarr/api/client"; +import { useRequiredBoard } from "@homarr/boards/context"; +import { useScopedI18n } from "@homarr/translation/client"; + +import { useBoardPermissions } from "~/components/board/permissions/client"; +import { SkipHoldButton } from "./skip-hold-button"; +import { TourStepContent } from "./tour-step-content"; + +export const BoardTourProvider = ({ children }: PropsWithChildren) => { + const t = useScopedI18n("onboardingTour.board"); + const board = useRequiredBoard(); + const { hasChangeAccess } = useBoardPermissions(board); + const { data: tourStatus } = clientApi.user.getTourStatus.useQuery(); + const { mutate: completeTour } = clientApi.user.completeTour.useMutation(); + + const started = tourStatus !== undefined && !tourStatus.completedBoardTour; + + const handleEnd = () => { + completeTour({ tour: "board" }); + }; + + const steps = useMemo(() => { + const allSteps: (OnboardingTourStep & { requiresChangeAccess?: boolean })[] = [ + { + id: "board-search", + title: t("welcome.title"), + content: ( + + ), + footer: (controller: { skipTour: () => void }) => ( + controller.skipTour()} /> + ), + }, + { + id: "board-edit-mode", + title: t("editMode.title"), + requiresChangeAccess: true, + content: ( + + ), + }, + { + id: "board-settings", + title: t("settings.title"), + requiresChangeAccess: true, + content: ( + + ), + }, + { + id: "board-switcher", + title: t("switcher.title"), + content: ( + + ), + }, + { + id: "board-user-menu", + title: t("userMenu.title"), + content: ( + + ), + }, + ]; + + return allSteps.filter( + (step) => !step.requiresChangeAccess || hasChangeAccess, + ) as OnboardingTourStep[]; + }, [hasChangeAccess, t]); + + return ( + + {children} + + ); +}; diff --git a/apps/nextjs/src/components/onboarding/manage-tour.tsx b/apps/nextjs/src/components/onboarding/manage-tour.tsx new file mode 100644 index 000000000..5da9959a5 --- /dev/null +++ b/apps/nextjs/src/components/onboarding/manage-tour.tsx @@ -0,0 +1,144 @@ +"use client"; + +import type { PropsWithChildren } from "react"; +import { useMemo } from "react"; +import { useRouter } from "next/navigation"; +import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; +import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; +import { Box } from "@mantine/core"; + +import { clientApi } from "@homarr/api/client"; +import { useScopedI18n } from "@homarr/translation/client"; + +import { SkipHoldButton } from "./skip-hold-button"; +import { TourForkStep } from "./tour-fork-step"; +import { TourStepContent } from "./tour-step-content"; + +interface ManageTourProviderProps extends PropsWithChildren { + isAdmin: boolean; +} + +export const ManageTourProvider = ({ children, isAdmin }: ManageTourProviderProps) => { + const router = useRouter(); + const t = useScopedI18n("onboardingTour.manage"); + const { data: tourStatus } = clientApi.user.getTourStatus.useQuery(); + const { mutate: completeTour } = clientApi.user.completeTour.useMutation(); + + const started = tourStatus !== undefined && !tourStatus.completedManageTour; + + const handleEnd = () => { + completeTour({ tour: "manage" }); + }; + + const steps = useMemo(() => { + const allSteps: (OnboardingTourStep & { adminOnly?: boolean })[] = [ + { + id: "manage-welcome", + title: t("welcome.title"), + content: ( + + ), + footer: (controller: { skipTour: () => void }) => ( + controller.skipTour()} /> + ), + }, + { + id: "manage-boards", + title: t("boards.title"), + content: ( + + ), + }, + { + id: "manage-apps", + title: t("apps.title"), + content: ( + + ), + }, + { + id: "manage-integrations", + title: t("integrations.title"), + content: (controller: { endTour: () => void; nextStep: () => void }) => ( + { + controller.endTour(); + router.push("/manage/integrations/new"); + }} + onNo={() => controller.nextStep()} + /> + ), + }, + { + id: "manage-search-engines", + title: t("searchEngines.title"), + content: ( + + ), + }, + { + id: "manage-medias", + title: t("medias.title"), + content: ( + + ), + }, + { + id: "manage-users", + title: t("users.title"), + adminOnly: true, + content: (controller: { endTour: () => void; nextStep: () => void }) => ( + { + controller.endTour(); + router.push("/manage/users/create"); + }} + onNo={() => controller.nextStep()} + /> + ), + }, + { + id: "manage-settings", + title: t("settings.title"), + adminOnly: true, + content: ( + + ), + }, + { + id: "manage-complete", + title: t("complete.title"), + content: ( + + ), + }, + ]; + + return allSteps.filter((step) => !step.adminOnly || isAdmin) as OnboardingTourStep[]; + }, [isAdmin, router, t]); + + return ( + + + {children} + + ); +}; diff --git a/apps/nextjs/src/components/onboarding/skip-hold-button.tsx b/apps/nextjs/src/components/onboarding/skip-hold-button.tsx new file mode 100644 index 000000000..f512744b5 --- /dev/null +++ b/apps/nextjs/src/components/onboarding/skip-hold-button.tsx @@ -0,0 +1,64 @@ +"use client"; + +import { useCallback, useEffect, useRef, useState } from "react"; +import { Button, Progress, Stack, Text } from "@mantine/core"; + +import { useI18n } from "@homarr/translation/client"; + +const HOLD_DURATION_MS = 2000; +const TICK_INTERVAL_MS = 50; + +interface SkipHoldButtonProps { + onSkip: () => void; +} + +export const SkipHoldButton = ({ onSkip }: SkipHoldButtonProps) => { + const t = useI18n(); + const [progress, setProgress] = useState(0); + const intervalRef = useRef | null>(null); + + const clearHoldInterval = useCallback(() => { + if (intervalRef.current) { + clearInterval(intervalRef.current); + intervalRef.current = null; + } + }, []); + + useEffect(() => clearHoldInterval, [clearHoldInterval]); + + const handlePointerDown = useCallback(() => { + clearHoldInterval(); + setProgress(0); + let elapsed = 0; + intervalRef.current = setInterval(() => { + elapsed += TICK_INTERVAL_MS; + const pct = Math.min((elapsed / HOLD_DURATION_MS) * 100, 100); + setProgress(pct); + if (elapsed >= HOLD_DURATION_MS) { + clearHoldInterval(); + onSkip(); + } + }, TICK_INTERVAL_MS); + }, [onSkip, clearHoldInterval]); + + const handlePointerUp = useCallback(() => { + clearHoldInterval(); + setProgress(0); + }, [clearHoldInterval]); + + return ( + + + {progress > 0 && } + + ); +}; diff --git a/apps/nextjs/src/components/onboarding/tour-fork-step.tsx b/apps/nextjs/src/components/onboarding/tour-fork-step.tsx new file mode 100644 index 000000000..4a1ce4ffe --- /dev/null +++ b/apps/nextjs/src/components/onboarding/tour-fork-step.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { Anchor, Button, Group, Stack, Text } from "@mantine/core"; +import { IconExternalLink } from "@tabler/icons-react"; + +import type { HomarrDocumentationPath } from "@homarr/definitions"; +import { createDocumentationLink } from "@homarr/definitions"; +import { useI18n } from "@homarr/translation/client"; + +interface TourForkStepProps { + question: string; + description?: string; + docPath: HomarrDocumentationPath; + onYes: () => void; + onNo: () => void; +} + +export const TourForkStep = ({ question, description, docPath, onYes, onNo }: TourForkStepProps) => { + const t = useI18n(); + + return ( + + {description && {description}} + + {question} + + + + + + + + {t("onboardingTour.learnMore")} + + + ); +}; diff --git a/apps/nextjs/src/components/onboarding/tour-step-content.tsx b/apps/nextjs/src/components/onboarding/tour-step-content.tsx new file mode 100644 index 000000000..8c8248594 --- /dev/null +++ b/apps/nextjs/src/components/onboarding/tour-step-content.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { Anchor, Stack, Text } from "@mantine/core"; +import { IconExternalLink } from "@tabler/icons-react"; + +import type { HomarrDocumentationPath } from "@homarr/definitions"; +import { createDocumentationLink } from "@homarr/definitions"; +import { useI18n } from "@homarr/translation/client"; + +interface TourStepContentProps { + description: string; + docPath: HomarrDocumentationPath; + docHash?: `#${string}`; +} + +export const TourStepContent = ({ description, docPath, docHash }: TourStepContentProps) => { + const t = useI18n(); + + return ( + + {description} + + + {t("onboardingTour.learnMore")} + + + ); +}; diff --git a/packages/api/src/router/user.ts b/packages/api/src/router/user.ts index 9c4f16c80..d29801842 100644 --- a/packages/api/src/router/user.ts +++ b/packages/api/src/router/user.ts @@ -278,6 +278,8 @@ export const userRouter = createTRPCRouter({ defaultSearchEngineId: true, openSearchInNewTab: true, ddgBangs: true, + completedManageTour: true, + completedBoardTour: true, }), ) .meta({ openapi: { method: "GET", path: "/api/users/{userId}", tags: ["users"], protect: true } }) @@ -304,6 +306,8 @@ export const userRouter = createTRPCRouter({ defaultSearchEngineId: true, openSearchInNewTab: true, ddgBangs: true, + completedManageTour: true, + completedBoardTour: true, }, where: eq(users.id, input.userId), }); @@ -605,6 +609,42 @@ export const userRouter = createTRPCRouter({ }) .where(eq(users.id, ctx.session.user.id)); }), + completeTour: protectedProcedure + .input(z.object({ tour: z.enum(["manage", "board"]) })) + .mutation(async ({ input, ctx }) => { + const columnMap: Record> = { + manage: { completedManageTour: true }, + board: { completedBoardTour: true }, + }; + + await ctx.db + .update(users) + .set(columnMap[input.tour]!) + .where(eq(users.id, ctx.session.user.id)); + }), + resetTours: protectedProcedure.mutation(async ({ ctx }) => { + await ctx.db + .update(users) + .set({ + completedManageTour: false, + completedBoardTour: false, + }) + .where(eq(users.id, ctx.session.user.id)); + }), + getTourStatus: protectedProcedure.query(async ({ ctx }) => { + const user = await ctx.db.query.users.findFirst({ + columns: { + completedManageTour: true, + completedBoardTour: true, + }, + where: eq(users.id, ctx.session.user.id), + }); + + return { + completedManageTour: user?.completedManageTour ?? false, + completedBoardTour: user?.completedBoardTour ?? false, + }; + }), }); const createUserAsync = async (db: Database, input: Omit, "groupIds">) => { diff --git a/packages/db/migrations/mysql/0039_strong_lizard.sql b/packages/db/migrations/mysql/0039_strong_lizard.sql new file mode 100644 index 000000000..356540dc7 --- /dev/null +++ b/packages/db/migrations/mysql/0039_strong_lizard.sql @@ -0,0 +1,2 @@ +ALTER TABLE `user` ADD `completed_manage_tour` boolean DEFAULT false NOT NULL;--> statement-breakpoint +ALTER TABLE `user` ADD `completed_board_tour` boolean DEFAULT false NOT NULL; \ No newline at end of file diff --git a/packages/db/migrations/mysql/meta/0039_snapshot.json b/packages/db/migrations/mysql/meta/0039_snapshot.json new file mode 100644 index 000000000..0c4e725f6 --- /dev/null +++ b/packages/db/migrations/mysql/meta/0039_snapshot.json @@ -0,0 +1,2380 @@ +{ + "version": "5", + "dialect": "mysql", + "id": "e7c06822-4b94-49ea-b685-acb08ee6b63e", + "prevId": "ddg-bangs-mysql-0038", + "tables": { + "account": { + "name": "account", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "userId_idx": { + "name": "userId_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_provider_account_id_pk": { + "name": "account_provider_provider_account_id_pk", + "columns": [ + "provider", + "provider_account_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "apiKey": { + "name": "apiKey", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "apiKey_user_id_user_id_fk": { + "name": "apiKey_user_id_user_id_fk", + "tableFrom": "apiKey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "apiKey_id": { + "name": "apiKey_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "app": { + "name": "app", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "href": { + "name": "href", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ping_url": { + "name": "ping_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "app_id": { + "name": "app_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "boardGroupPermission": { + "name": "boardGroupPermission", + "columns": { + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "boardGroupPermission_board_id_board_id_fk": { + "name": "boardGroupPermission_board_id_board_id_fk", + "tableFrom": "boardGroupPermission", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "boardGroupPermission_group_id_group_id_fk": { + "name": "boardGroupPermission_group_id_group_id_fk", + "tableFrom": "boardGroupPermission", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "boardGroupPermission_board_id_group_id_permission_pk": { + "name": "boardGroupPermission_board_id_group_id_permission_pk", + "columns": [ + "board_id", + "group_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "boardUserPermission": { + "name": "boardUserPermission", + "columns": { + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "boardUserPermission_board_id_board_id_fk": { + "name": "boardUserPermission_board_id_board_id_fk", + "tableFrom": "boardUserPermission", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "boardUserPermission_user_id_user_id_fk": { + "name": "boardUserPermission_user_id_user_id_fk", + "tableFrom": "boardUserPermission", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "boardUserPermission_board_id_user_id_permission_pk": { + "name": "boardUserPermission_board_id_user_id_permission_pk", + "columns": [ + "board_id", + "user_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "board": { + "name": "board", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_title": { + "name": "page_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "meta_title": { + "name": "meta_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "logo_image_url": { + "name": "logo_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "favicon_image_url": { + "name": "favicon_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "background_image_url": { + "name": "background_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "background_image_attachment": { + "name": "background_image_attachment", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('fixed')" + }, + "background_image_repeat": { + "name": "background_image_repeat", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('no-repeat')" + }, + "background_image_size": { + "name": "background_image_size", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('cover')" + }, + "primary_color": { + "name": "primary_color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('#fa5252')" + }, + "secondary_color": { + "name": "secondary_color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('#fd7e14')" + }, + "opacity": { + "name": "opacity", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 100 + }, + "custom_css": { + "name": "custom_css", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_color": { + "name": "icon_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "item_radius": { + "name": "item_radius", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('lg')" + }, + "disable_status": { + "name": "disable_status", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "board_creator_id_user_id_fk": { + "name": "board_creator_id_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "board_id": { + "name": "board_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "board_name_unique": { + "name": "board_name_unique", + "columns": [ + "name" + ] + } + }, + "checkConstraint": {} + }, + "cron_job_configuration": { + "name": "cron_job_configuration", + "columns": { + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cron_expression": { + "name": "cron_expression", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "cron_job_configuration_name": { + "name": "cron_job_configuration_name", + "columns": [ + "name" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "groupMember": { + "name": "groupMember", + "columns": { + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "groupMember_group_id_group_id_fk": { + "name": "groupMember_group_id_group_id_fk", + "tableFrom": "groupMember", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "groupMember_user_id_user_id_fk": { + "name": "groupMember_user_id_user_id_fk", + "tableFrom": "groupMember", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "groupMember_group_id_user_id_pk": { + "name": "groupMember_group_id_user_id_pk", + "columns": [ + "group_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "groupPermission": { + "name": "groupPermission", + "columns": { + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "groupPermission_group_id_group_id_fk": { + "name": "groupPermission_group_id_group_id_fk", + "tableFrom": "groupPermission", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "group": { + "name": "group", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "owner_id": { + "name": "owner_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "home_board_id": { + "name": "home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mobile_home_board_id": { + "name": "mobile_home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "group_owner_id_user_id_fk": { + "name": "group_owner_id_user_id_fk", + "tableFrom": "group", + "tableTo": "user", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "group_home_board_id_board_id_fk": { + "name": "group_home_board_id_board_id_fk", + "tableFrom": "group", + "tableTo": "board", + "columnsFrom": [ + "home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "group_mobile_home_board_id_board_id_fk": { + "name": "group_mobile_home_board_id_board_id_fk", + "tableFrom": "group", + "tableTo": "board", + "columnsFrom": [ + "mobile_home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "group_id": { + "name": "group_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "group_name_unique": { + "name": "group_name_unique", + "columns": [ + "name" + ] + } + }, + "checkConstraint": {} + }, + "iconRepository": { + "name": "iconRepository", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "varchar(150)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "iconRepository_id": { + "name": "iconRepository_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "icon": { + "name": "icon", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(250)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "checksum": { + "name": "checksum", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon_repository_id": { + "name": "icon_repository_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "icon_icon_repository_id_iconRepository_id_fk": { + "name": "icon_icon_repository_id_iconRepository_id_fk", + "tableFrom": "icon", + "tableTo": "iconRepository", + "columnsFrom": [ + "icon_repository_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "icon_id": { + "name": "icon_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "integrationGroupPermissions": { + "name": "integrationGroupPermissions", + "columns": { + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "integrationGroupPermissions_integration_id_integration_id_fk": { + "name": "integrationGroupPermissions_integration_id_integration_id_fk", + "tableFrom": "integrationGroupPermissions", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integrationGroupPermissions_group_id_group_id_fk": { + "name": "integrationGroupPermissions_group_id_group_id_fk", + "tableFrom": "integrationGroupPermissions", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_group_permission__pk": { + "name": "integration_group_permission__pk", + "columns": [ + "integration_id", + "group_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "integration_item": { + "name": "integration_item", + "columns": { + "item_id": { + "name": "item_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "integration_item_item_id_item_id_fk": { + "name": "integration_item_item_id_item_id_fk", + "tableFrom": "integration_item", + "tableTo": "item", + "columnsFrom": [ + "item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integration_item_integration_id_integration_id_fk": { + "name": "integration_item_integration_id_integration_id_fk", + "tableFrom": "integration_item", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_item_item_id_integration_id_pk": { + "name": "integration_item_item_id_integration_id_pk", + "columns": [ + "item_id", + "integration_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "integrationSecret": { + "name": "integrationSecret", + "columns": { + "kind": { + "name": "kind", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "integration_secret__kind_idx": { + "name": "integration_secret__kind_idx", + "columns": [ + "kind" + ], + "isUnique": false + }, + "integration_secret__updated_at_idx": { + "name": "integration_secret__updated_at_idx", + "columns": [ + "updated_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "integrationSecret_integration_id_integration_id_fk": { + "name": "integrationSecret_integration_id_integration_id_fk", + "tableFrom": "integrationSecret", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationSecret_integration_id_kind_pk": { + "name": "integrationSecret_integration_id_kind_pk", + "columns": [ + "integration_id", + "kind" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "integrationUserPermission": { + "name": "integrationUserPermission", + "columns": { + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "integrationUserPermission_integration_id_integration_id_fk": { + "name": "integrationUserPermission_integration_id_integration_id_fk", + "tableFrom": "integrationUserPermission", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integrationUserPermission_user_id_user_id_fk": { + "name": "integrationUserPermission_user_id_user_id_fk", + "tableFrom": "integrationUserPermission", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationUserPermission_integration_id_user_id_permission_pk": { + "name": "integrationUserPermission_integration_id_user_id_permission_pk", + "columns": [ + "integration_id", + "user_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "integration": { + "name": "integration", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "app_id": { + "name": "app_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "integration__kind_idx": { + "name": "integration__kind_idx", + "columns": [ + "kind" + ], + "isUnique": false + } + }, + "foreignKeys": { + "integration_app_id_app_id_fk": { + "name": "integration_app_id_app_id_fk", + "tableFrom": "integration", + "tableTo": "app", + "columnsFrom": [ + "app_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_id": { + "name": "integration_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "invite": { + "name": "invite", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expiration_date": { + "name": "expiration_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "invite_creator_id_user_id_fk": { + "name": "invite_creator_id_user_id_fk", + "tableFrom": "invite", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "invite_id": { + "name": "invite_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "invite_token_unique": { + "name": "invite_token_unique", + "columns": [ + "token" + ] + } + }, + "checkConstraint": {} + }, + "item_layout": { + "name": "item_layout", + "columns": { + "item_id": { + "name": "item_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "section_id": { + "name": "section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout_id": { + "name": "layout_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "x_offset": { + "name": "x_offset", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "y_offset": { + "name": "y_offset", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "item_layout_item_id_item_id_fk": { + "name": "item_layout_item_id_item_id_fk", + "tableFrom": "item_layout", + "tableTo": "item", + "columnsFrom": [ + "item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "item_layout_section_id_section_id_fk": { + "name": "item_layout_section_id_section_id_fk", + "tableFrom": "item_layout", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "item_layout_layout_id_layout_id_fk": { + "name": "item_layout_layout_id_layout_id_fk", + "tableFrom": "item_layout", + "tableTo": "layout", + "columnsFrom": [ + "layout_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "item_layout_item_id_section_id_layout_id_pk": { + "name": "item_layout_item_id_section_id_layout_id_pk", + "columns": [ + "item_id", + "section_id", + "layout_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "item": { + "name": "item", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{\"json\": {}}')" + }, + "advanced_options": { + "name": "advanced_options", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{\"json\": {}}')" + } + }, + "indexes": {}, + "foreignKeys": { + "item_board_id_board_id_fk": { + "name": "item_board_id_board_id_fk", + "tableFrom": "item", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "item_id": { + "name": "item_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "layout": { + "name": "layout", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "column_count": { + "name": "column_count", + "type": "tinyint", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "breakpoint": { + "name": "breakpoint", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "layout_board_id_board_id_fk": { + "name": "layout_board_id_board_id_fk", + "tableFrom": "layout", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "layout_id": { + "name": "layout_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "media": { + "name": "media", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "LONGBLOB", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "size": { + "name": "size", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(now())" + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_creator_id_user_id_fk": { + "name": "media_creator_id_user_id_fk", + "tableFrom": "media", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "media_id": { + "name": "media_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "onboarding": { + "name": "onboarding", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "step": { + "name": "step", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "previous_step": { + "name": "previous_step", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "onboarding_id": { + "name": "onboarding_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "search_engine": { + "name": "search_engine", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "short": { + "name": "short", + "type": "varchar(8)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url_template": { + "name": "url_template", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'generic'" + }, + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "search_engine_integration_id_integration_id_fk": { + "name": "search_engine_integration_id_integration_id_fk", + "tableFrom": "search_engine", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "search_engine_id": { + "name": "search_engine_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": { + "search_engine_short_unique": { + "name": "search_engine_short_unique", + "columns": [ + "short" + ] + } + }, + "checkConstraint": {} + }, + "section_collapse_state": { + "name": "section_collapse_state", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "section_id": { + "name": "section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "collapsed": { + "name": "collapsed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "section_collapse_state_user_id_user_id_fk": { + "name": "section_collapse_state_user_id_user_id_fk", + "tableFrom": "section_collapse_state", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_collapse_state_section_id_section_id_fk": { + "name": "section_collapse_state_section_id_section_id_fk", + "tableFrom": "section_collapse_state", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_collapse_state_user_id_section_id_pk": { + "name": "section_collapse_state_user_id_section_id_pk", + "columns": [ + "user_id", + "section_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "section_layout": { + "name": "section_layout", + "columns": { + "section_id": { + "name": "section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout_id": { + "name": "layout_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "parent_section_id": { + "name": "parent_section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "x_offset": { + "name": "x_offset", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "y_offset": { + "name": "y_offset", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "int", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "section_layout_section_id_section_id_fk": { + "name": "section_layout_section_id_section_id_fk", + "tableFrom": "section_layout", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_layout_layout_id_layout_id_fk": { + "name": "section_layout_layout_id_layout_id_fk", + "tableFrom": "section_layout", + "tableTo": "layout", + "columnsFrom": [ + "layout_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_layout_parent_section_id_section_id_fk": { + "name": "section_layout_parent_section_id_section_id_fk", + "tableFrom": "section_layout", + "tableTo": "section", + "columnsFrom": [ + "parent_section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_layout_section_id_layout_id_pk": { + "name": "section_layout_section_id_layout_id_pk", + "columns": [ + "section_id", + "layout_id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "section": { + "name": "section", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "x_offset": { + "name": "x_offset", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "y_offset": { + "name": "y_offset", + "type": "int", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "('{\"json\": {}}')" + } + }, + "indexes": {}, + "foreignKeys": { + "section_board_id_board_id_fk": { + "name": "section_board_id_board_id_fk", + "tableFrom": "section", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_id": { + "name": "section_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "serverSetting": { + "name": "serverSetting", + "columns": { + "setting_key": { + "name": "setting_key", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "('{\"json\": {}}')" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "serverSetting_setting_key": { + "name": "serverSetting_setting_key", + "columns": [ + "setting_key" + ] + } + }, + "uniqueConstraints": { + "serverSetting_settingKey_unique": { + "name": "serverSetting_settingKey_unique", + "columns": [ + "setting_key" + ] + } + }, + "checkConstraint": {} + }, + "session": { + "name": "session", + "columns": { + "session_token": { + "name": "session_token", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "user_id_idx": { + "name": "user_id_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "session_session_token": { + "name": "session_session_token", + "columns": [ + "session_token" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email_verified": { + "name": "email_verified", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'credentials'" + }, + "home_board_id": { + "name": "home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mobile_home_board_id": { + "name": "mobile_home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_search_engine_id": { + "name": "default_search_engine_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "open_search_in_new_tab": { + "name": "open_search_in_new_tab", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "ddg_bangs": { + "name": "ddg_bangs", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "color_scheme": { + "name": "color_scheme", + "type": "varchar(5)", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'dark'" + }, + "first_day_of_week": { + "name": "first_day_of_week", + "type": "tinyint", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "ping_icons_enabled": { + "name": "ping_icons_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "completed_manage_tour": { + "name": "completed_manage_tour", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "completed_board_tour": { + "name": "completed_board_tour", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_home_board_id_board_id_fk": { + "name": "user_home_board_id_board_id_fk", + "tableFrom": "user", + "tableTo": "board", + "columnsFrom": [ + "home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_mobile_home_board_id_board_id_fk": { + "name": "user_mobile_home_board_id_board_id_fk", + "tableFrom": "user", + "tableTo": "board", + "columnsFrom": [ + "mobile_home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_default_search_engine_id_search_engine_id_fk": { + "name": "user_default_search_engine_id_search_engine_id_fk", + "tableFrom": "user", + "tableTo": "search_engine", + "columnsFrom": [ + "default_search_engine_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_id": { + "name": "user_id", + "columns": [ + "id" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "verificationToken": { + "name": "verificationToken", + "columns": { + "identifier": { + "name": "identifier", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verificationToken_identifier_token_pk": { + "name": "verificationToken_identifier_token_pk", + "columns": [ + "identifier", + "token" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + }, + "trusted_certificate_hostname": { + "name": "trusted_certificate_hostname", + "columns": { + "hostname": { + "name": "hostname", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thumbprint": { + "name": "thumbprint", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "certificate": { + "name": "certificate", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "trusted_certificate_hostname_hostname_thumbprint_pk": { + "name": "trusted_certificate_hostname_hostname_thumbprint_pk", + "columns": [ + "hostname", + "thumbprint" + ] + } + }, + "uniqueConstraints": {}, + "checkConstraint": {} + } + }, + "views": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "tables": {}, + "indexes": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/mysql/meta/_journal.json b/packages/db/migrations/mysql/meta/_journal.json index 421c81699..09f166814 100644 --- a/packages/db/migrations/mysql/meta/_journal.json +++ b/packages/db/migrations/mysql/meta/_journal.json @@ -274,6 +274,13 @@ "when": 1775400000000, "tag": "0038_add_user_ddg_bangs", "breakpoints": true + }, + { + "idx": 39, + "version": "5", + "when": 1779199104477, + "tag": "0039_strong_lizard", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/packages/db/migrations/postgresql/0005_same_manta.sql b/packages/db/migrations/postgresql/0005_same_manta.sql new file mode 100644 index 000000000..dda51181e --- /dev/null +++ b/packages/db/migrations/postgresql/0005_same_manta.sql @@ -0,0 +1,2 @@ +ALTER TABLE "user" ADD COLUMN "completed_manage_tour" boolean DEFAULT false NOT NULL;--> statement-breakpoint +ALTER TABLE "user" ADD COLUMN "completed_board_tour" boolean DEFAULT false NOT NULL; \ No newline at end of file diff --git a/packages/db/migrations/postgresql/meta/0005_snapshot.json b/packages/db/migrations/postgresql/meta/0005_snapshot.json new file mode 100644 index 000000000..b95f85be5 --- /dev/null +++ b/packages/db/migrations/postgresql/meta/0005_snapshot.json @@ -0,0 +1,2230 @@ +{ + "id": "2869b3b7-af54-4fbc-a953-766387ec2e3d", + "prevId": "ddg-bangs-pg-0004", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "userId_idx": { + "name": "userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_provider_account_id_pk": { + "name": "account_provider_provider_account_id_pk", + "columns": [ + "provider", + "provider_account_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apiKey": { + "name": "apiKey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "apiKey_user_id_user_id_fk": { + "name": "apiKey_user_id_user_id_fk", + "tableFrom": "apiKey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.app": { + "name": "app", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "href": { + "name": "href", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ping_url": { + "name": "ping_url", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.boardGroupPermission": { + "name": "boardGroupPermission", + "schema": "", + "columns": { + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "boardGroupPermission_board_id_board_id_fk": { + "name": "boardGroupPermission_board_id_board_id_fk", + "tableFrom": "boardGroupPermission", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "boardGroupPermission_group_id_group_id_fk": { + "name": "boardGroupPermission_group_id_group_id_fk", + "tableFrom": "boardGroupPermission", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "boardGroupPermission_board_id_group_id_permission_pk": { + "name": "boardGroupPermission_board_id_group_id_permission_pk", + "columns": [ + "board_id", + "group_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.boardUserPermission": { + "name": "boardUserPermission", + "schema": "", + "columns": { + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "boardUserPermission_board_id_board_id_fk": { + "name": "boardUserPermission_board_id_board_id_fk", + "tableFrom": "boardUserPermission", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "boardUserPermission_user_id_user_id_fk": { + "name": "boardUserPermission_user_id_user_id_fk", + "tableFrom": "boardUserPermission", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "boardUserPermission_board_id_user_id_permission_pk": { + "name": "boardUserPermission_board_id_user_id_permission_pk", + "columns": [ + "board_id", + "user_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.board": { + "name": "board", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "page_title": { + "name": "page_title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "meta_title": { + "name": "meta_title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logo_image_url": { + "name": "logo_image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "favicon_image_url": { + "name": "favicon_image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "background_image_url": { + "name": "background_image_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "background_image_attachment": { + "name": "background_image_attachment", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'fixed'" + }, + "background_image_repeat": { + "name": "background_image_repeat", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'no-repeat'" + }, + "background_image_size": { + "name": "background_image_size", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'cover'" + }, + "primary_color": { + "name": "primary_color", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'#fa5252'" + }, + "secondary_color": { + "name": "secondary_color", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'#fd7e14'" + }, + "opacity": { + "name": "opacity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 100 + }, + "custom_css": { + "name": "custom_css", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon_color": { + "name": "icon_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "item_radius": { + "name": "item_radius", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'lg'" + }, + "disable_status": { + "name": "disable_status", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "board_creator_id_user_id_fk": { + "name": "board_creator_id_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "board_name_unique": { + "name": "board_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.cron_job_configuration": { + "name": "cron_job_configuration", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "varchar(256)", + "primaryKey": true, + "notNull": true + }, + "cron_expression": { + "name": "cron_expression", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "is_enabled": { + "name": "is_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.groupMember": { + "name": "groupMember", + "schema": "", + "columns": { + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "groupMember_group_id_group_id_fk": { + "name": "groupMember_group_id_group_id_fk", + "tableFrom": "groupMember", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "groupMember_user_id_user_id_fk": { + "name": "groupMember_user_id_user_id_fk", + "tableFrom": "groupMember", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "groupMember_group_id_user_id_pk": { + "name": "groupMember_group_id_user_id_pk", + "columns": [ + "group_id", + "user_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.groupPermission": { + "name": "groupPermission", + "schema": "", + "columns": { + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "groupPermission_group_id_group_id_fk": { + "name": "groupPermission_group_id_group_id_fk", + "tableFrom": "groupPermission", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.group": { + "name": "group", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "owner_id": { + "name": "owner_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "home_board_id": { + "name": "home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "mobile_home_board_id": { + "name": "mobile_home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "position": { + "name": "position", + "type": "smallint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "group_owner_id_user_id_fk": { + "name": "group_owner_id_user_id_fk", + "tableFrom": "group", + "tableTo": "user", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "group_home_board_id_board_id_fk": { + "name": "group_home_board_id_board_id_fk", + "tableFrom": "group", + "tableTo": "board", + "columnsFrom": [ + "home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "group_mobile_home_board_id_board_id_fk": { + "name": "group_mobile_home_board_id_board_id_fk", + "tableFrom": "group", + "tableTo": "board", + "columnsFrom": [ + "mobile_home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "group_name_unique": { + "name": "group_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.iconRepository": { + "name": "iconRepository", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(150)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.icon": { + "name": "icon", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(250)", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "checksum": { + "name": "checksum", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "icon_repository_id": { + "name": "icon_repository_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "icon_icon_repository_id_iconRepository_id_fk": { + "name": "icon_icon_repository_id_iconRepository_id_fk", + "tableFrom": "icon", + "tableTo": "iconRepository", + "columnsFrom": [ + "icon_repository_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.integrationGroupPermissions": { + "name": "integrationGroupPermissions", + "schema": "", + "columns": { + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "integrationGroupPermissions_integration_id_integration_id_fk": { + "name": "integrationGroupPermissions_integration_id_integration_id_fk", + "tableFrom": "integrationGroupPermissions", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integrationGroupPermissions_group_id_group_id_fk": { + "name": "integrationGroupPermissions_group_id_group_id_fk", + "tableFrom": "integrationGroupPermissions", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_group_permission__pk": { + "name": "integration_group_permission__pk", + "columns": [ + "integration_id", + "group_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.integration_item": { + "name": "integration_item", + "schema": "", + "columns": { + "item_id": { + "name": "item_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "integration_item_item_id_item_id_fk": { + "name": "integration_item_item_id_item_id_fk", + "tableFrom": "integration_item", + "tableTo": "item", + "columnsFrom": [ + "item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integration_item_integration_id_integration_id_fk": { + "name": "integration_item_integration_id_integration_id_fk", + "tableFrom": "integration_item", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_item_item_id_integration_id_pk": { + "name": "integration_item_item_id_integration_id_pk", + "columns": [ + "item_id", + "integration_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.integrationSecret": { + "name": "integrationSecret", + "schema": "", + "columns": { + "kind": { + "name": "kind", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "integration_secret__kind_idx": { + "name": "integration_secret__kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "integration_secret__updated_at_idx": { + "name": "integration_secret__updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "integrationSecret_integration_id_integration_id_fk": { + "name": "integrationSecret_integration_id_integration_id_fk", + "tableFrom": "integrationSecret", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationSecret_integration_id_kind_pk": { + "name": "integrationSecret_integration_id_kind_pk", + "columns": [ + "integration_id", + "kind" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.integrationUserPermission": { + "name": "integrationUserPermission", + "schema": "", + "columns": { + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "integrationUserPermission_integration_id_integration_id_fk": { + "name": "integrationUserPermission_integration_id_integration_id_fk", + "tableFrom": "integrationUserPermission", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integrationUserPermission_user_id_user_id_fk": { + "name": "integrationUserPermission_user_id_user_id_fk", + "tableFrom": "integrationUserPermission", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationUserPermission_integration_id_user_id_permission_pk": { + "name": "integrationUserPermission_integration_id_user_id_permission_pk", + "columns": [ + "integration_id", + "user_id", + "permission" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.integration": { + "name": "integration", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "app_id": { + "name": "app_id", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "integration__kind_idx": { + "name": "integration__kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "integration_app_id_app_id_fk": { + "name": "integration_app_id_app_id_fk", + "tableFrom": "integration", + "tableTo": "app", + "columnsFrom": [ + "app_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invite": { + "name": "invite", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true + }, + "expiration_date": { + "name": "expiration_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "invite_creator_id_user_id_fk": { + "name": "invite_creator_id_user_id_fk", + "tableFrom": "invite", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "invite_token_unique": { + "name": "invite_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.item_layout": { + "name": "item_layout", + "schema": "", + "columns": { + "item_id": { + "name": "item_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "section_id": { + "name": "section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "layout_id": { + "name": "layout_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "x_offset": { + "name": "x_offset", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "y_offset": { + "name": "y_offset", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "item_layout_item_id_item_id_fk": { + "name": "item_layout_item_id_item_id_fk", + "tableFrom": "item_layout", + "tableTo": "item", + "columnsFrom": [ + "item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "item_layout_section_id_section_id_fk": { + "name": "item_layout_section_id_section_id_fk", + "tableFrom": "item_layout", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "item_layout_layout_id_layout_id_fk": { + "name": "item_layout_layout_id_layout_id_fk", + "tableFrom": "item_layout", + "tableTo": "layout", + "columnsFrom": [ + "layout_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "item_layout_item_id_section_id_layout_id_pk": { + "name": "item_layout_item_id_section_id_layout_id_pk", + "columns": [ + "item_id", + "section_id", + "layout_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.item": { + "name": "item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{\"json\": {}}'" + }, + "advanced_options": { + "name": "advanced_options", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{\"json\": {}}'" + } + }, + "indexes": {}, + "foreignKeys": { + "item_board_id_board_id_fk": { + "name": "item_board_id_board_id_fk", + "tableFrom": "item", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.layout": { + "name": "layout", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(32)", + "primaryKey": false, + "notNull": true + }, + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "column_count": { + "name": "column_count", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "breakpoint": { + "name": "breakpoint", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "layout_board_id_board_id_fk": { + "name": "layout_board_id_board_id_fk", + "tableFrom": "layout", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.media": { + "name": "media", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "creator_id": { + "name": "creator_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_creator_id_user_id_fk": { + "name": "media_creator_id_user_id_fk", + "tableFrom": "media", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.onboarding": { + "name": "onboarding", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "step": { + "name": "step", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "previous_step": { + "name": "previous_step", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.search_engine": { + "name": "search_engine", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "short": { + "name": "short", + "type": "varchar(8)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url_template": { + "name": "url_template", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "default": "'generic'" + }, + "integration_id": { + "name": "integration_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "search_engine_integration_id_integration_id_fk": { + "name": "search_engine_integration_id_integration_id_fk", + "tableFrom": "search_engine", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "search_engine_short_unique": { + "name": "search_engine_short_unique", + "nullsNotDistinct": false, + "columns": [ + "short" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.section_collapse_state": { + "name": "section_collapse_state", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "section_id": { + "name": "section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "collapsed": { + "name": "collapsed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "section_collapse_state_user_id_user_id_fk": { + "name": "section_collapse_state_user_id_user_id_fk", + "tableFrom": "section_collapse_state", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_collapse_state_section_id_section_id_fk": { + "name": "section_collapse_state_section_id_section_id_fk", + "tableFrom": "section_collapse_state", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_collapse_state_user_id_section_id_pk": { + "name": "section_collapse_state_user_id_section_id_pk", + "columns": [ + "user_id", + "section_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.section_layout": { + "name": "section_layout", + "schema": "", + "columns": { + "section_id": { + "name": "section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "layout_id": { + "name": "layout_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "parent_section_id": { + "name": "parent_section_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "x_offset": { + "name": "x_offset", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "y_offset": { + "name": "y_offset", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "section_layout_section_id_section_id_fk": { + "name": "section_layout_section_id_section_id_fk", + "tableFrom": "section_layout", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_layout_layout_id_layout_id_fk": { + "name": "section_layout_layout_id_layout_id_fk", + "tableFrom": "section_layout", + "tableTo": "layout", + "columnsFrom": [ + "layout_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_layout_parent_section_id_section_id_fk": { + "name": "section_layout_parent_section_id_section_id_fk", + "tableFrom": "section_layout", + "tableTo": "section", + "columnsFrom": [ + "parent_section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_layout_section_id_layout_id_pk": { + "name": "section_layout_section_id_layout_id_pk", + "columns": [ + "section_id", + "layout_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.section": { + "name": "section", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "board_id": { + "name": "board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "x_offset": { + "name": "x_offset", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "y_offset": { + "name": "y_offset", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "'{\"json\": {}}'" + } + }, + "indexes": {}, + "foreignKeys": { + "section_board_id_board_id_fk": { + "name": "section_board_id_board_id_fk", + "tableFrom": "section", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.serverSetting": { + "name": "serverSetting", + "schema": "", + "columns": { + "setting_key": { + "name": "setting_key", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'{\"json\": {}}'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "serverSetting_settingKey_unique": { + "name": "serverSetting_settingKey_unique", + "nullsNotDistinct": false, + "columns": [ + "setting_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "session_token": { + "name": "session_token", + "type": "varchar(512)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "user_id_idx": { + "name": "user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_verified": { + "name": "email_verified", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true, + "default": "'credentials'" + }, + "home_board_id": { + "name": "home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "mobile_home_board_id": { + "name": "mobile_home_board_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "default_search_engine_id": { + "name": "default_search_engine_id", + "type": "varchar(64)", + "primaryKey": false, + "notNull": false + }, + "open_search_in_new_tab": { + "name": "open_search_in_new_tab", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "ddg_bangs": { + "name": "ddg_bangs", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "color_scheme": { + "name": "color_scheme", + "type": "varchar(5)", + "primaryKey": false, + "notNull": true, + "default": "'dark'" + }, + "first_day_of_week": { + "name": "first_day_of_week", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "ping_icons_enabled": { + "name": "ping_icons_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "completed_manage_tour": { + "name": "completed_manage_tour", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "completed_board_tour": { + "name": "completed_board_tour", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_home_board_id_board_id_fk": { + "name": "user_home_board_id_board_id_fk", + "tableFrom": "user", + "tableTo": "board", + "columnsFrom": [ + "home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_mobile_home_board_id_board_id_fk": { + "name": "user_mobile_home_board_id_board_id_fk", + "tableFrom": "user", + "tableTo": "board", + "columnsFrom": [ + "mobile_home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_default_search_engine_id_search_engine_id_fk": { + "name": "user_default_search_engine_id_search_engine_id_fk", + "tableFrom": "user", + "tableTo": "search_engine", + "columnsFrom": [ + "default_search_engine_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verificationToken": { + "name": "verificationToken", + "schema": "", + "columns": { + "identifier": { + "name": "identifier", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(512)", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verificationToken_identifier_token_pk": { + "name": "verificationToken_identifier_token_pk", + "columns": [ + "identifier", + "token" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.trusted_certificate_hostname": { + "name": "trusted_certificate_hostname", + "schema": "", + "columns": { + "hostname": { + "name": "hostname", + "type": "varchar(256)", + "primaryKey": false, + "notNull": true + }, + "thumbprint": { + "name": "thumbprint", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "certificate": { + "name": "certificate", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "trusted_certificate_hostname_hostname_thumbprint_pk": { + "name": "trusted_certificate_hostname_hostname_thumbprint_pk", + "columns": [ + "hostname", + "thumbprint" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/postgresql/meta/_journal.json b/packages/db/migrations/postgresql/meta/_journal.json index d0a3f7683..0dc466c14 100644 --- a/packages/db/migrations/postgresql/meta/_journal.json +++ b/packages/db/migrations/postgresql/meta/_journal.json @@ -36,6 +36,13 @@ "when": 1775400000000, "tag": "0004_add_user_ddg_bangs", "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1779199097716, + "tag": "0005_same_manta", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/packages/db/migrations/sqlite/0037_equal_retro_girl.sql b/packages/db/migrations/sqlite/0037_equal_retro_girl.sql new file mode 100644 index 000000000..292ce4ece --- /dev/null +++ b/packages/db/migrations/sqlite/0037_equal_retro_girl.sql @@ -0,0 +1,2 @@ +ALTER TABLE `user` ADD `completed_manage_tour` integer DEFAULT false NOT NULL;--> statement-breakpoint +ALTER TABLE `user` ADD `completed_board_tour` integer DEFAULT false NOT NULL; \ No newline at end of file diff --git a/packages/db/migrations/sqlite/meta/0037_snapshot.json b/packages/db/migrations/sqlite/meta/0037_snapshot.json new file mode 100644 index 000000000..dcfa96012 --- /dev/null +++ b/packages/db/migrations/sqlite/meta/0037_snapshot.json @@ -0,0 +1,2259 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "f30b6535-b4d5-4501-8370-7a7605e28bbd", + "prevId": "ddg-bangs-sqlite-0036", + "tables": { + "account": { + "name": "account", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "userId_idx": { + "name": "userId_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_provider_account_id_pk": { + "columns": [ + "provider", + "provider_account_id" + ], + "name": "account_provider_provider_account_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "apiKey": { + "name": "apiKey", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "apiKey_user_id_user_id_fk": { + "name": "apiKey_user_id_user_id_fk", + "tableFrom": "apiKey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "app": { + "name": "app", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "href": { + "name": "href", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ping_url": { + "name": "ping_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "boardGroupPermission": { + "name": "boardGroupPermission", + "columns": { + "board_id": { + "name": "board_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "boardGroupPermission_board_id_board_id_fk": { + "name": "boardGroupPermission_board_id_board_id_fk", + "tableFrom": "boardGroupPermission", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "boardGroupPermission_group_id_group_id_fk": { + "name": "boardGroupPermission_group_id_group_id_fk", + "tableFrom": "boardGroupPermission", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "boardGroupPermission_board_id_group_id_permission_pk": { + "columns": [ + "board_id", + "group_id", + "permission" + ], + "name": "boardGroupPermission_board_id_group_id_permission_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "boardUserPermission": { + "name": "boardUserPermission", + "columns": { + "board_id": { + "name": "board_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "boardUserPermission_board_id_board_id_fk": { + "name": "boardUserPermission_board_id_board_id_fk", + "tableFrom": "boardUserPermission", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "boardUserPermission_user_id_user_id_fk": { + "name": "boardUserPermission_user_id_user_id_fk", + "tableFrom": "boardUserPermission", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "boardUserPermission_board_id_user_id_permission_pk": { + "columns": [ + "board_id", + "user_id", + "permission" + ], + "name": "boardUserPermission_board_id_user_id_permission_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "board": { + "name": "board", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_public": { + "name": "is_public", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "page_title": { + "name": "page_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "meta_title": { + "name": "meta_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "logo_image_url": { + "name": "logo_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "favicon_image_url": { + "name": "favicon_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "background_image_url": { + "name": "background_image_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "background_image_attachment": { + "name": "background_image_attachment", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'fixed'" + }, + "background_image_repeat": { + "name": "background_image_repeat", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'no-repeat'" + }, + "background_image_size": { + "name": "background_image_size", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'cover'" + }, + "primary_color": { + "name": "primary_color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'#fa5252'" + }, + "secondary_color": { + "name": "secondary_color", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'#fd7e14'" + }, + "opacity": { + "name": "opacity", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 100 + }, + "custom_css": { + "name": "custom_css", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon_color": { + "name": "icon_color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "item_radius": { + "name": "item_radius", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'lg'" + }, + "disable_status": { + "name": "disable_status", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": { + "board_name_unique": { + "name": "board_name_unique", + "columns": [ + "name" + ], + "isUnique": true + } + }, + "foreignKeys": { + "board_creator_id_user_id_fk": { + "name": "board_creator_id_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "cron_job_configuration": { + "name": "cron_job_configuration", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "cron_expression": { + "name": "cron_expression", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_enabled": { + "name": "is_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "groupMember": { + "name": "groupMember", + "columns": { + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "groupMember_group_id_group_id_fk": { + "name": "groupMember_group_id_group_id_fk", + "tableFrom": "groupMember", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "groupMember_user_id_user_id_fk": { + "name": "groupMember_user_id_user_id_fk", + "tableFrom": "groupMember", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "groupMember_group_id_user_id_pk": { + "columns": [ + "group_id", + "user_id" + ], + "name": "groupMember_group_id_user_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "groupPermission": { + "name": "groupPermission", + "columns": { + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "groupPermission_group_id_group_id_fk": { + "name": "groupPermission_group_id_group_id_fk", + "tableFrom": "groupPermission", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "group": { + "name": "group", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "owner_id": { + "name": "owner_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "home_board_id": { + "name": "home_board_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mobile_home_board_id": { + "name": "mobile_home_board_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "group_name_unique": { + "name": "group_name_unique", + "columns": [ + "name" + ], + "isUnique": true + } + }, + "foreignKeys": { + "group_owner_id_user_id_fk": { + "name": "group_owner_id_user_id_fk", + "tableFrom": "group", + "tableTo": "user", + "columnsFrom": [ + "owner_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "group_home_board_id_board_id_fk": { + "name": "group_home_board_id_board_id_fk", + "tableFrom": "group", + "tableTo": "board", + "columnsFrom": [ + "home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "group_mobile_home_board_id_board_id_fk": { + "name": "group_mobile_home_board_id_board_id_fk", + "tableFrom": "group", + "tableTo": "board", + "columnsFrom": [ + "mobile_home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "iconRepository": { + "name": "iconRepository", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "icon": { + "name": "icon", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "checksum": { + "name": "checksum", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon_repository_id": { + "name": "icon_repository_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "icon_icon_repository_id_iconRepository_id_fk": { + "name": "icon_icon_repository_id_iconRepository_id_fk", + "tableFrom": "icon", + "tableTo": "iconRepository", + "columnsFrom": [ + "icon_repository_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integrationGroupPermissions": { + "name": "integrationGroupPermissions", + "columns": { + "integration_id": { + "name": "integration_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "integrationGroupPermissions_integration_id_integration_id_fk": { + "name": "integrationGroupPermissions_integration_id_integration_id_fk", + "tableFrom": "integrationGroupPermissions", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integrationGroupPermissions_group_id_group_id_fk": { + "name": "integrationGroupPermissions_group_id_group_id_fk", + "tableFrom": "integrationGroupPermissions", + "tableTo": "group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationGroupPermissions_integration_id_group_id_permission_pk": { + "columns": [ + "integration_id", + "group_id", + "permission" + ], + "name": "integrationGroupPermissions_integration_id_group_id_permission_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integration_item": { + "name": "integration_item", + "columns": { + "item_id": { + "name": "item_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "integration_id": { + "name": "integration_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "integration_item_item_id_item_id_fk": { + "name": "integration_item_item_id_item_id_fk", + "tableFrom": "integration_item", + "tableTo": "item", + "columnsFrom": [ + "item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integration_item_integration_id_integration_id_fk": { + "name": "integration_item_integration_id_integration_id_fk", + "tableFrom": "integration_item", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_item_item_id_integration_id_pk": { + "columns": [ + "item_id", + "integration_id" + ], + "name": "integration_item_item_id_integration_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integrationSecret": { + "name": "integrationSecret", + "columns": { + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "integration_id": { + "name": "integration_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "integration_secret__kind_idx": { + "name": "integration_secret__kind_idx", + "columns": [ + "kind" + ], + "isUnique": false + }, + "integration_secret__updated_at_idx": { + "name": "integration_secret__updated_at_idx", + "columns": [ + "updated_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "integrationSecret_integration_id_integration_id_fk": { + "name": "integrationSecret_integration_id_integration_id_fk", + "tableFrom": "integrationSecret", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationSecret_integration_id_kind_pk": { + "columns": [ + "integration_id", + "kind" + ], + "name": "integrationSecret_integration_id_kind_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integrationUserPermission": { + "name": "integrationUserPermission", + "columns": { + "integration_id": { + "name": "integration_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "integrationUserPermission_integration_id_integration_id_fk": { + "name": "integrationUserPermission_integration_id_integration_id_fk", + "tableFrom": "integrationUserPermission", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "integrationUserPermission_user_id_user_id_fk": { + "name": "integrationUserPermission_user_id_user_id_fk", + "tableFrom": "integrationUserPermission", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integrationUserPermission_integration_id_user_id_permission_pk": { + "columns": [ + "integration_id", + "user_id", + "permission" + ], + "name": "integrationUserPermission_integration_id_user_id_permission_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "integration": { + "name": "integration", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "app_id": { + "name": "app_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "integration__kind_idx": { + "name": "integration__kind_idx", + "columns": [ + "kind" + ], + "isUnique": false + } + }, + "foreignKeys": { + "integration_app_id_app_id_fk": { + "name": "integration_app_id_app_id_fk", + "tableFrom": "integration", + "tableTo": "app", + "columnsFrom": [ + "app_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "invite": { + "name": "invite", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expiration_date": { + "name": "expiration_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "invite_token_unique": { + "name": "invite_token_unique", + "columns": [ + "token" + ], + "isUnique": true + } + }, + "foreignKeys": { + "invite_creator_id_user_id_fk": { + "name": "invite_creator_id_user_id_fk", + "tableFrom": "invite", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "item_layout": { + "name": "item_layout", + "columns": { + "item_id": { + "name": "item_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "section_id": { + "name": "section_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout_id": { + "name": "layout_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "x_offset": { + "name": "x_offset", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "y_offset": { + "name": "y_offset", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "item_layout_item_id_item_id_fk": { + "name": "item_layout_item_id_item_id_fk", + "tableFrom": "item_layout", + "tableTo": "item", + "columnsFrom": [ + "item_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "item_layout_section_id_section_id_fk": { + "name": "item_layout_section_id_section_id_fk", + "tableFrom": "item_layout", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "item_layout_layout_id_layout_id_fk": { + "name": "item_layout_layout_id_layout_id_fk", + "tableFrom": "item_layout", + "tableTo": "layout", + "columnsFrom": [ + "layout_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "item_layout_item_id_section_id_layout_id_pk": { + "columns": [ + "item_id", + "section_id", + "layout_id" + ], + "name": "item_layout_item_id_section_id_layout_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "item": { + "name": "item", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "board_id": { + "name": "board_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{\"json\": {}}'" + }, + "advanced_options": { + "name": "advanced_options", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{\"json\": {}}'" + } + }, + "indexes": {}, + "foreignKeys": { + "item_board_id_board_id_fk": { + "name": "item_board_id_board_id_fk", + "tableFrom": "item", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "layout": { + "name": "layout", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "board_id": { + "name": "board_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "column_count": { + "name": "column_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "breakpoint": { + "name": "breakpoint", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "layout_board_id_board_id_fk": { + "name": "layout_board_id_board_id_fk", + "tableFrom": "layout", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "media": { + "name": "media", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content": { + "name": "content", + "type": "blob", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "(unixepoch())" + }, + "creator_id": { + "name": "creator_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_creator_id_user_id_fk": { + "name": "media_creator_id_user_id_fk", + "tableFrom": "media", + "tableTo": "user", + "columnsFrom": [ + "creator_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "onboarding": { + "name": "onboarding", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "step": { + "name": "step", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "previous_step": { + "name": "previous_step", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "search_engine": { + "name": "search_engine", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "icon_url": { + "name": "icon_url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "short": { + "name": "short", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url_template": { + "name": "url_template", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'generic'" + }, + "integration_id": { + "name": "integration_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "search_engine_short_unique": { + "name": "search_engine_short_unique", + "columns": [ + "short" + ], + "isUnique": true + } + }, + "foreignKeys": { + "search_engine_integration_id_integration_id_fk": { + "name": "search_engine_integration_id_integration_id_fk", + "tableFrom": "search_engine", + "tableTo": "integration", + "columnsFrom": [ + "integration_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "section_collapse_state": { + "name": "section_collapse_state", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "section_id": { + "name": "section_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "collapsed": { + "name": "collapsed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "section_collapse_state_user_id_user_id_fk": { + "name": "section_collapse_state_user_id_user_id_fk", + "tableFrom": "section_collapse_state", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_collapse_state_section_id_section_id_fk": { + "name": "section_collapse_state_section_id_section_id_fk", + "tableFrom": "section_collapse_state", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_collapse_state_user_id_section_id_pk": { + "columns": [ + "user_id", + "section_id" + ], + "name": "section_collapse_state_user_id_section_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "section_layout": { + "name": "section_layout", + "columns": { + "section_id": { + "name": "section_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "layout_id": { + "name": "layout_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "parent_section_id": { + "name": "parent_section_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "x_offset": { + "name": "x_offset", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "y_offset": { + "name": "y_offset", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "section_layout_section_id_section_id_fk": { + "name": "section_layout_section_id_section_id_fk", + "tableFrom": "section_layout", + "tableTo": "section", + "columnsFrom": [ + "section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_layout_layout_id_layout_id_fk": { + "name": "section_layout_layout_id_layout_id_fk", + "tableFrom": "section_layout", + "tableTo": "layout", + "columnsFrom": [ + "layout_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "section_layout_parent_section_id_section_id_fk": { + "name": "section_layout_parent_section_id_section_id_fk", + "tableFrom": "section_layout", + "tableTo": "section", + "columnsFrom": [ + "parent_section_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "section_layout_section_id_layout_id_pk": { + "columns": [ + "section_id", + "layout_id" + ], + "name": "section_layout_section_id_layout_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "section": { + "name": "section", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "board_id": { + "name": "board_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "x_offset": { + "name": "x_offset", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "y_offset": { + "name": "y_offset", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "options": { + "name": "options", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'{\"json\": {}}'" + } + }, + "indexes": {}, + "foreignKeys": { + "section_board_id_board_id_fk": { + "name": "section_board_id_board_id_fk", + "tableFrom": "section", + "tableTo": "board", + "columnsFrom": [ + "board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "serverSetting": { + "name": "serverSetting", + "columns": { + "setting_key": { + "name": "setting_key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'{\"json\": {}}'" + } + }, + "indexes": { + "serverSetting_settingKey_unique": { + "name": "serverSetting_settingKey_unique", + "columns": [ + "setting_key" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "session": { + "name": "session", + "columns": { + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "user_id_idx": { + "name": "user_id_idx", + "columns": [ + "user_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "trusted_certificate_hostname": { + "name": "trusted_certificate_hostname", + "columns": { + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thumbprint": { + "name": "thumbprint", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "certificate": { + "name": "certificate", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "trusted_certificate_hostname_hostname_thumbprint_pk": { + "columns": [ + "hostname", + "thumbprint" + ], + "name": "trusted_certificate_hostname_hostname_thumbprint_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email_verified": { + "name": "email_verified", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'credentials'" + }, + "home_board_id": { + "name": "home_board_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "mobile_home_board_id": { + "name": "mobile_home_board_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default_search_engine_id": { + "name": "default_search_engine_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "open_search_in_new_tab": { + "name": "open_search_in_new_tab", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "ddg_bangs": { + "name": "ddg_bangs", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "color_scheme": { + "name": "color_scheme", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'dark'" + }, + "first_day_of_week": { + "name": "first_day_of_week", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 1 + }, + "ping_icons_enabled": { + "name": "ping_icons_enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "completed_manage_tour": { + "name": "completed_manage_tour", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "completed_board_tour": { + "name": "completed_board_tour", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_home_board_id_board_id_fk": { + "name": "user_home_board_id_board_id_fk", + "tableFrom": "user", + "tableTo": "board", + "columnsFrom": [ + "home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_mobile_home_board_id_board_id_fk": { + "name": "user_mobile_home_board_id_board_id_fk", + "tableFrom": "user", + "tableTo": "board", + "columnsFrom": [ + "mobile_home_board_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_default_search_engine_id_search_engine_id_fk": { + "name": "user_default_search_engine_id_search_engine_id_fk", + "tableFrom": "user", + "tableTo": "search_engine", + "columnsFrom": [ + "default_search_engine_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "verificationToken": { + "name": "verificationToken", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verificationToken_identifier_token_pk": { + "columns": [ + "identifier", + "token" + ], + "name": "verificationToken_identifier_token_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/sqlite/meta/_journal.json b/packages/db/migrations/sqlite/meta/_journal.json index 5543bbde0..879c64363 100644 --- a/packages/db/migrations/sqlite/meta/_journal.json +++ b/packages/db/migrations/sqlite/meta/_journal.json @@ -260,6 +260,13 @@ "when": 1775400000000, "tag": "0036_add_user_ddg_bangs", "breakpoints": true + }, + { + "idx": 37, + "version": "6", + "when": 1779199046805, + "tag": "0037_equal_retro_girl", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/packages/db/schema/mysql.ts b/packages/db/schema/mysql.ts index 84c5325ed..7e2897c46 100644 --- a/packages/db/schema/mysql.ts +++ b/packages/db/schema/mysql.ts @@ -80,6 +80,8 @@ export const users = mysqlTable("user", { colorScheme: varchar({ length: 5 }).$type().default("dark").notNull(), firstDayOfWeek: tinyint().$type().default(1).notNull(), // Defaults to Monday pingIconsEnabled: boolean().default(false).notNull(), + completedManageTour: boolean().default(false).notNull(), + completedBoardTour: boolean().default(false).notNull(), }); export const accounts = mysqlTable( diff --git a/packages/db/schema/postgresql.ts b/packages/db/schema/postgresql.ts index 412916013..8ea445325 100644 --- a/packages/db/schema/postgresql.ts +++ b/packages/db/schema/postgresql.ts @@ -79,6 +79,8 @@ export const users = pgTable("user", { colorScheme: varchar({ length: 5 }).$type().default("dark").notNull(), firstDayOfWeek: smallint().$type().default(1).notNull(), // Defaults to Monday pingIconsEnabled: boolean().default(false).notNull(), + completedManageTour: boolean().default(false).notNull(), + completedBoardTour: boolean().default(false).notNull(), }); export const accounts = pgTable( diff --git a/packages/db/schema/sqlite.ts b/packages/db/schema/sqlite.ts index 50671db85..b4fe5bbe0 100644 --- a/packages/db/schema/sqlite.ts +++ b/packages/db/schema/sqlite.ts @@ -62,6 +62,8 @@ export const users = sqliteTable("user", { colorScheme: text().$type().default("dark").notNull(), firstDayOfWeek: int().$type().default(1).notNull(), // Defaults to Monday pingIconsEnabled: int({ mode: "boolean" }).default(false).notNull(), + completedManageTour: int({ mode: "boolean" }).default(false).notNull(), + completedBoardTour: int({ mode: "boolean" }).default(false).notNull(), }); export const accounts = sqliteTable( diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 29e86458e..066c54098 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -3482,7 +3482,24 @@ }, "search": "Search", "firstDayOfWeek": "First day of the week", - "accessibility": "Accessibility" + "accessibility": "Accessibility", + "onboardingTours": { + "title": "Onboarding Tours", + "description": "Reset the onboarding tours to see them again on your next visit to the management area or dashboard.", + "reset": "Reset onboarding tours", + "resetSuccess": { + "title": "Tours reset", + "message": "Onboarding tours will show again on your next visit" + }, + "status": { + "completed": "Completed", + "notStarted": "Not started" + }, + "name": { + "management": "Management", + "dashboard": "Dashboard" + } + } } }, "security": { @@ -4931,5 +4948,79 @@ "error": "Error" } } + }, + "onboardingTour": { + "skipHold": "Hold to skip — I know what I'm doing", + "learnMore": "Learn more in the docs", + "forkYes": "Yes, let's go!", + "forkNo": "Not now", + "manage": { + "welcome": { + "title": "Welcome to Management", + "description": "This is the management area where you configure everything in Homarr — boards, apps, integrations, users, and server settings. Let's walk through what each section does." + }, + "boards": { + "title": "Boards", + "description": "Boards are your dashboards. Each board has a unique name that becomes part of its URL. Boards can be public or private and support responsive layouts, background images, custom CSS, and per-user access control." + }, + "apps": { + "title": "Apps", + "description": "Apps represent links to your services. Each app needs a name and icon (choose from 11K+ built-in icons). You can set a separate ping URL for health checks and add apps to boards as widgets or bookmarks." + }, + "integrations": { + "title": "Integrations", + "description": "Integrations connect Homarr to third-party apps you run — like Sonarr, Radarr, Plex, and 50+ more. Secrets are encrypted and never exposed to the client. Connections are validated before saving." + }, + "integrationsFork": { + "title": "Try it now?", + "question": "Would you like to add your first integration?" + }, + "searchEngines": { + "title": "Search Engines", + "description": "Configure custom search providers accessible via the search bar or Ctrl+K. Define a name, shortcut prefix, and URL template. Supports integration-based search for apps like Jellyseerr and Overseerr." + }, + "medias": { + "title": "Media", + "description": "Upload custom images for app icons or board branding. Media is stored in the database and available in the icon picker when creating apps." + }, + "users": { + "title": "Users & Groups", + "description": "Manage users, groups, and permissions. Users can belong to multiple groups. Groups control board access, integration permissions, and admin privileges. You can also create invite links for self-onboarding." + }, + "usersFork": { + "title": "Try it now?", + "question": "Would you like to create a new user?" + }, + "settings": { + "title": "Server Settings", + "description": "Configure global defaults — analytics, SEO/crawling directives, default home boards, color scheme, language, and app status behavior. These apply across the entire Homarr instance." + }, + "complete": { + "title": "You're all set!", + "description": "You've seen everything in the management area. Next, head to your board to start adding apps and widgets, or explore the docs for advanced topics like the API, certificates, and background tasks." + } + }, + "board": { + "welcome": { + "title": "Welcome to your Board", + "description": "This is your dashboard — a drag-and-drop canvas where you organize apps and widgets. Use the search bar or Ctrl+K to quickly find apps, integrations, boards, and actions." + }, + "editMode": { + "title": "Edit Mode", + "description": "Toggle edit mode to add, move, and resize items. In edit mode you can add widgets, apps, categories, and dynamic sections. Drag items to reposition, use the corner handle to resize. Don't forget to exit edit mode to save!" + }, + "settings": { + "title": "Board Settings", + "description": "Customize this board's name, layout columns, background image, colors, custom CSS, and access control. You can set boards as public or private and control who can view or modify them." + }, + "switcher": { + "title": "Board Switcher", + "description": "Switch between your boards. You can create multiple boards for different purposes — one for media, one for networking, or one per user." + }, + "userMenu": { + "title": "Your Profile", + "description": "Quick access to your preferences — change color scheme, language, home board, and search settings. You can also navigate to the management area from here." + } + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 005916bdb..28c0d6bf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,6 +42,9 @@ catalogs: '@extractus/feed-extractor': specifier: 7.2.1 version: 7.2.1 + '@gfazioli/mantine-onboarding-tour': + specifier: ^4.0.1 + version: 4.0.1 '@gitbeaker/rest': specifier: ^43.8.0 version: 43.8.0 @@ -682,6 +685,9 @@ importers: '@dnd-kit/utilities': specifier: 'catalog:' version: 3.2.2(react@19.2.6) + '@gfazioli/mantine-onboarding-tour': + specifier: 'catalog:' + version: 4.0.1(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@homarr/analytics': specifier: workspace:^0.1.0 version: link:../../packages/analytics @@ -3785,6 +3791,15 @@ packages: '@formatjs/intl-localematcher@0.8.1': resolution: {integrity: sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA==} + '@gfazioli/mantine-onboarding-tour@4.0.1': + resolution: {integrity: sha512-LaeUlA1mgRFLwIuH7BQ66NffdGEhvKdPMKov6dDIDT97fp7+DCmQk++oAZkxPWey5GRUJ7+Sf+GbjFLkT6dHCA==} + peerDependencies: + '@mantine/core': '>=7.0.0' + '@mantine/hooks': '>=7.0.0' + '@tabler/icons-react': ^3.30.0 + react: ^18.x || ^19.x + react-dom: ^18.x || ^19.x + '@gitbeaker/core@43.8.0': resolution: {integrity: sha512-H+LfKuf4dExBinb79c+CXViRBvTVQNf5BYLNSizm2SiqdED5JruhKX88payefleY0szp7G/mySlFSXPyGRH1dQ==} engines: {node: '>=18.20.0'} @@ -11401,6 +11416,14 @@ snapshots: '@formatjs/fast-memoize': 3.1.0 tslib: 2.8.1 + '@gfazioli/mantine-onboarding-tour@4.0.1(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 8.3.18(react@19.2.6) + '@tabler/icons-react': 3.44.0(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + '@gitbeaker/core@43.8.0': dependencies: '@gitbeaker/requester-utils': 43.8.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4a1b6ff6e..3bfeb7e08 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -15,6 +15,7 @@ catalog: "@drizzle-team/brocli": ^0.12.0 "@eslint/js": 10.0.1 "@extractus/feed-extractor": 7.2.1 + '@gfazioli/mantine-onboarding-tour': ^4.0.1 "@gitbeaker/rest": ^43.8.0 "@homarr/gridstack": ^1.12.0 "@homarr/node-unifi": ^2.6.0 From 2190436d9fb645f4e8fbe95104bfc0283ab65d39 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:42:36 +0200 Subject: [PATCH 04/11] feat(db): add user onboarding tour completion columns Persist completedManageTour and completedBoardTour on the user table with renamed migrations across sqlite, mysql, and postgresql. --- ... 0039_add_user_onboarding_tour_status.sql} | 0 .../migrations/mysql/meta/0039_snapshot.json | 504 +++++------------- .../db/migrations/mysql/meta/_journal.json | 4 +- ... 0005_add_user_onboarding_tour_status.sql} | 0 .../postgresql/meta/0005_snapshot.json | 412 ++++---------- .../migrations/postgresql/meta/_journal.json | 4 +- ... 0037_add_user_onboarding_tour_status.sql} | 0 .../migrations/sqlite/meta/0037_snapshot.json | 432 ++++----------- .../db/migrations/sqlite/meta/_journal.json | 4 +- 9 files changed, 331 insertions(+), 1029 deletions(-) rename packages/db/migrations/mysql/{0039_strong_lizard.sql => 0039_add_user_onboarding_tour_status.sql} (100%) rename packages/db/migrations/postgresql/{0005_same_manta.sql => 0005_add_user_onboarding_tour_status.sql} (100%) rename packages/db/migrations/sqlite/{0037_equal_retro_girl.sql => 0037_add_user_onboarding_tour_status.sql} (100%) diff --git a/packages/db/migrations/mysql/0039_strong_lizard.sql b/packages/db/migrations/mysql/0039_add_user_onboarding_tour_status.sql similarity index 100% rename from packages/db/migrations/mysql/0039_strong_lizard.sql rename to packages/db/migrations/mysql/0039_add_user_onboarding_tour_status.sql diff --git a/packages/db/migrations/mysql/meta/0039_snapshot.json b/packages/db/migrations/mysql/meta/0039_snapshot.json index 0c4e725f6..6630bd286 100644 --- a/packages/db/migrations/mysql/meta/0039_snapshot.json +++ b/packages/db/migrations/mysql/meta/0039_snapshot.json @@ -88,9 +88,7 @@ "indexes": { "userId_idx": { "name": "userId_idx", - "columns": [ - "user_id" - ], + "columns": ["user_id"], "isUnique": false } }, @@ -99,12 +97,8 @@ "name": "account_user_id_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -112,10 +106,7 @@ "compositePrimaryKeys": { "account_provider_provider_account_id_pk": { "name": "account_provider_provider_account_id_pk", - "columns": [ - "provider", - "provider_account_id" - ] + "columns": ["provider", "provider_account_id"] } }, "uniqueConstraints": {}, @@ -152,12 +143,8 @@ "name": "apiKey_user_id_user_id_fk", "tableFrom": "apiKey", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -165,9 +152,7 @@ "compositePrimaryKeys": { "apiKey_id": { "name": "apiKey_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -224,9 +209,7 @@ "compositePrimaryKeys": { "app_id": { "name": "app_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -263,12 +246,8 @@ "name": "boardGroupPermission_board_id_board_id_fk", "tableFrom": "boardGroupPermission", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -276,12 +255,8 @@ "name": "boardGroupPermission_group_id_group_id_fk", "tableFrom": "boardGroupPermission", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -289,11 +264,7 @@ "compositePrimaryKeys": { "boardGroupPermission_board_id_group_id_permission_pk": { "name": "boardGroupPermission_board_id_group_id_permission_pk", - "columns": [ - "board_id", - "group_id", - "permission" - ] + "columns": ["board_id", "group_id", "permission"] } }, "uniqueConstraints": {}, @@ -330,12 +301,8 @@ "name": "boardUserPermission_board_id_board_id_fk", "tableFrom": "boardUserPermission", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -343,12 +310,8 @@ "name": "boardUserPermission_user_id_user_id_fk", "tableFrom": "boardUserPermission", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -356,11 +319,7 @@ "compositePrimaryKeys": { "boardUserPermission_board_id_user_id_permission_pk": { "name": "boardUserPermission_board_id_user_id_permission_pk", - "columns": [ - "board_id", - "user_id", - "permission" - ] + "columns": ["board_id", "user_id", "permission"] } }, "uniqueConstraints": {}, @@ -518,12 +477,8 @@ "name": "board_creator_id_user_id_fk", "tableFrom": "board", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -531,17 +486,13 @@ "compositePrimaryKeys": { "board_id": { "name": "board_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": { "board_name_unique": { "name": "board_name_unique", - "columns": [ - "name" - ] + "columns": ["name"] } }, "checkConstraint": {} @@ -577,9 +528,7 @@ "compositePrimaryKeys": { "cron_job_configuration_name": { "name": "cron_job_configuration_name", - "columns": [ - "name" - ] + "columns": ["name"] } }, "uniqueConstraints": {}, @@ -609,12 +558,8 @@ "name": "groupMember_group_id_group_id_fk", "tableFrom": "groupMember", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -622,12 +567,8 @@ "name": "groupMember_user_id_user_id_fk", "tableFrom": "groupMember", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -635,10 +576,7 @@ "compositePrimaryKeys": { "groupMember_group_id_user_id_pk": { "name": "groupMember_group_id_user_id_pk", - "columns": [ - "group_id", - "user_id" - ] + "columns": ["group_id", "user_id"] } }, "uniqueConstraints": {}, @@ -668,12 +606,8 @@ "name": "groupPermission_group_id_group_id_fk", "tableFrom": "groupPermission", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -734,12 +668,8 @@ "name": "group_owner_id_user_id_fk", "tableFrom": "group", "tableTo": "user", - "columnsFrom": [ - "owner_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -747,12 +677,8 @@ "name": "group_home_board_id_board_id_fk", "tableFrom": "group", "tableTo": "board", - "columnsFrom": [ - "home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -760,12 +686,8 @@ "name": "group_mobile_home_board_id_board_id_fk", "tableFrom": "group", "tableTo": "board", - "columnsFrom": [ - "mobile_home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["mobile_home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -773,17 +695,13 @@ "compositePrimaryKeys": { "group_id": { "name": "group_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": { "group_name_unique": { "name": "group_name_unique", - "columns": [ - "name" - ] + "columns": ["name"] } }, "checkConstraint": {} @@ -811,9 +729,7 @@ "compositePrimaryKeys": { "iconRepository_id": { "name": "iconRepository_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -864,12 +780,8 @@ "name": "icon_icon_repository_id_iconRepository_id_fk", "tableFrom": "icon", "tableTo": "iconRepository", - "columnsFrom": [ - "icon_repository_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["icon_repository_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -877,9 +789,7 @@ "compositePrimaryKeys": { "icon_id": { "name": "icon_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -916,12 +826,8 @@ "name": "integrationGroupPermissions_integration_id_integration_id_fk", "tableFrom": "integrationGroupPermissions", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -929,12 +835,8 @@ "name": "integrationGroupPermissions_group_id_group_id_fk", "tableFrom": "integrationGroupPermissions", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -942,11 +844,7 @@ "compositePrimaryKeys": { "integration_group_permission__pk": { "name": "integration_group_permission__pk", - "columns": [ - "integration_id", - "group_id", - "permission" - ] + "columns": ["integration_id", "group_id", "permission"] } }, "uniqueConstraints": {}, @@ -976,12 +874,8 @@ "name": "integration_item_item_id_item_id_fk", "tableFrom": "integration_item", "tableTo": "item", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["item_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -989,12 +883,8 @@ "name": "integration_item_integration_id_integration_id_fk", "tableFrom": "integration_item", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1002,10 +892,7 @@ "compositePrimaryKeys": { "integration_item_item_id_integration_id_pk": { "name": "integration_item_item_id_integration_id_pk", - "columns": [ - "item_id", - "integration_id" - ] + "columns": ["item_id", "integration_id"] } }, "uniqueConstraints": {}, @@ -1046,16 +933,12 @@ "indexes": { "integration_secret__kind_idx": { "name": "integration_secret__kind_idx", - "columns": [ - "kind" - ], + "columns": ["kind"], "isUnique": false }, "integration_secret__updated_at_idx": { "name": "integration_secret__updated_at_idx", - "columns": [ - "updated_at" - ], + "columns": ["updated_at"], "isUnique": false } }, @@ -1064,12 +947,8 @@ "name": "integrationSecret_integration_id_integration_id_fk", "tableFrom": "integrationSecret", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1077,10 +956,7 @@ "compositePrimaryKeys": { "integrationSecret_integration_id_kind_pk": { "name": "integrationSecret_integration_id_kind_pk", - "columns": [ - "integration_id", - "kind" - ] + "columns": ["integration_id", "kind"] } }, "uniqueConstraints": {}, @@ -1117,12 +993,8 @@ "name": "integrationUserPermission_integration_id_integration_id_fk", "tableFrom": "integrationUserPermission", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1130,12 +1002,8 @@ "name": "integrationUserPermission_user_id_user_id_fk", "tableFrom": "integrationUserPermission", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1143,11 +1011,7 @@ "compositePrimaryKeys": { "integrationUserPermission_integration_id_user_id_permission_pk": { "name": "integrationUserPermission_integration_id_user_id_permission_pk", - "columns": [ - "integration_id", - "user_id", - "permission" - ] + "columns": ["integration_id", "user_id", "permission"] } }, "uniqueConstraints": {}, @@ -1195,9 +1059,7 @@ "indexes": { "integration__kind_idx": { "name": "integration__kind_idx", - "columns": [ - "kind" - ], + "columns": ["kind"], "isUnique": false } }, @@ -1206,12 +1068,8 @@ "name": "integration_app_id_app_id_fk", "tableFrom": "integration", "tableTo": "app", - "columnsFrom": [ - "app_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["app_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1219,9 +1077,7 @@ "compositePrimaryKeys": { "integration_id": { "name": "integration_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -1265,12 +1121,8 @@ "name": "invite_creator_id_user_id_fk", "tableFrom": "invite", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1278,17 +1130,13 @@ "compositePrimaryKeys": { "invite_id": { "name": "invite_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": { "invite_token_unique": { "name": "invite_token_unique", - "columns": [ - "token" - ] + "columns": ["token"] } }, "checkConstraint": {} @@ -1352,12 +1200,8 @@ "name": "item_layout_item_id_item_id_fk", "tableFrom": "item_layout", "tableTo": "item", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["item_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1365,12 +1209,8 @@ "name": "item_layout_section_id_section_id_fk", "tableFrom": "item_layout", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1378,12 +1218,8 @@ "name": "item_layout_layout_id_layout_id_fk", "tableFrom": "item_layout", "tableTo": "layout", - "columnsFrom": [ - "layout_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["layout_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1391,11 +1227,7 @@ "compositePrimaryKeys": { "item_layout_item_id_section_id_layout_id_pk": { "name": "item_layout_item_id_section_id_layout_id_pk", - "columns": [ - "item_id", - "section_id", - "layout_id" - ] + "columns": ["item_id", "section_id", "layout_id"] } }, "uniqueConstraints": {}, @@ -1448,12 +1280,8 @@ "name": "item_board_id_board_id_fk", "tableFrom": "item", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1461,9 +1289,7 @@ "compositePrimaryKeys": { "item_id": { "name": "item_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -1515,12 +1341,8 @@ "name": "layout_board_id_board_id_fk", "tableFrom": "layout", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1528,9 +1350,7 @@ "compositePrimaryKeys": { "layout_id": { "name": "layout_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -1596,12 +1416,8 @@ "name": "media_creator_id_user_id_fk", "tableFrom": "media", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1609,9 +1425,7 @@ "compositePrimaryKeys": { "media_id": { "name": "media_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -1647,9 +1461,7 @@ "compositePrimaryKeys": { "onboarding_id": { "name": "onboarding_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -1722,12 +1534,8 @@ "name": "search_engine_integration_id_integration_id_fk", "tableFrom": "search_engine", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1735,17 +1543,13 @@ "compositePrimaryKeys": { "search_engine_id": { "name": "search_engine_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": { "search_engine_short_unique": { "name": "search_engine_short_unique", - "columns": [ - "short" - ] + "columns": ["short"] } }, "checkConstraint": {} @@ -1782,12 +1586,8 @@ "name": "section_collapse_state_user_id_user_id_fk", "tableFrom": "section_collapse_state", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1795,12 +1595,8 @@ "name": "section_collapse_state_section_id_section_id_fk", "tableFrom": "section_collapse_state", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1808,10 +1604,7 @@ "compositePrimaryKeys": { "section_collapse_state_user_id_section_id_pk": { "name": "section_collapse_state_user_id_section_id_pk", - "columns": [ - "user_id", - "section_id" - ] + "columns": ["user_id", "section_id"] } }, "uniqueConstraints": {}, @@ -1876,12 +1669,8 @@ "name": "section_layout_section_id_section_id_fk", "tableFrom": "section_layout", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1889,12 +1678,8 @@ "name": "section_layout_layout_id_layout_id_fk", "tableFrom": "section_layout", "tableTo": "layout", - "columnsFrom": [ - "layout_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["layout_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1902,12 +1687,8 @@ "name": "section_layout_parent_section_id_section_id_fk", "tableFrom": "section_layout", "tableTo": "section", - "columnsFrom": [ - "parent_section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["parent_section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1915,10 +1696,7 @@ "compositePrimaryKeys": { "section_layout_section_id_layout_id_pk": { "name": "section_layout_section_id_layout_id_pk", - "columns": [ - "section_id", - "layout_id" - ] + "columns": ["section_id", "layout_id"] } }, "uniqueConstraints": {}, @@ -1984,12 +1762,8 @@ "name": "section_board_id_board_id_fk", "tableFrom": "section", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1997,9 +1771,7 @@ "compositePrimaryKeys": { "section_id": { "name": "section_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -2029,17 +1801,13 @@ "compositePrimaryKeys": { "serverSetting_setting_key": { "name": "serverSetting_setting_key", - "columns": [ - "setting_key" - ] + "columns": ["setting_key"] } }, "uniqueConstraints": { "serverSetting_settingKey_unique": { "name": "serverSetting_settingKey_unique", - "columns": [ - "setting_key" - ] + "columns": ["setting_key"] } }, "checkConstraint": {} @@ -2072,9 +1840,7 @@ "indexes": { "user_id_idx": { "name": "user_id_idx", - "columns": [ - "user_id" - ], + "columns": ["user_id"], "isUnique": false } }, @@ -2083,12 +1849,8 @@ "name": "session_user_id_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2096,9 +1858,7 @@ "compositePrimaryKeys": { "session_session_token": { "name": "session_session_token", - "columns": [ - "session_token" - ] + "columns": ["session_token"] } }, "uniqueConstraints": {}, @@ -2241,12 +2001,8 @@ "name": "user_home_board_id_board_id_fk", "tableFrom": "user", "tableTo": "board", - "columnsFrom": [ - "home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2254,12 +2010,8 @@ "name": "user_mobile_home_board_id_board_id_fk", "tableFrom": "user", "tableTo": "board", - "columnsFrom": [ - "mobile_home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["mobile_home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2267,12 +2019,8 @@ "name": "user_default_search_engine_id_search_engine_id_fk", "tableFrom": "user", "tableTo": "search_engine", - "columnsFrom": [ - "default_search_engine_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["default_search_engine_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -2280,9 +2028,7 @@ "compositePrimaryKeys": { "user_id": { "name": "user_id", - "columns": [ - "id" - ] + "columns": ["id"] } }, "uniqueConstraints": {}, @@ -2318,10 +2064,7 @@ "compositePrimaryKeys": { "verificationToken_identifier_token_pk": { "name": "verificationToken_identifier_token_pk", - "columns": [ - "identifier", - "token" - ] + "columns": ["identifier", "token"] } }, "uniqueConstraints": {}, @@ -2357,10 +2100,7 @@ "compositePrimaryKeys": { "trusted_certificate_hostname_hostname_thumbprint_pk": { "name": "trusted_certificate_hostname_hostname_thumbprint_pk", - "columns": [ - "hostname", - "thumbprint" - ] + "columns": ["hostname", "thumbprint"] } }, "uniqueConstraints": {}, @@ -2377,4 +2117,4 @@ "tables": {}, "indexes": {} } -} \ No newline at end of file +} diff --git a/packages/db/migrations/mysql/meta/_journal.json b/packages/db/migrations/mysql/meta/_journal.json index 09f166814..f420759ec 100644 --- a/packages/db/migrations/mysql/meta/_journal.json +++ b/packages/db/migrations/mysql/meta/_journal.json @@ -279,8 +279,8 @@ "idx": 39, "version": "5", "when": 1779199104477, - "tag": "0039_strong_lizard", + "tag": "0039_add_user_onboarding_tour_status", "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/packages/db/migrations/postgresql/0005_same_manta.sql b/packages/db/migrations/postgresql/0005_add_user_onboarding_tour_status.sql similarity index 100% rename from packages/db/migrations/postgresql/0005_same_manta.sql rename to packages/db/migrations/postgresql/0005_add_user_onboarding_tour_status.sql diff --git a/packages/db/migrations/postgresql/meta/0005_snapshot.json b/packages/db/migrations/postgresql/meta/0005_snapshot.json index b95f85be5..759659315 100644 --- a/packages/db/migrations/postgresql/meta/0005_snapshot.json +++ b/packages/db/migrations/postgresql/meta/0005_snapshot.json @@ -97,12 +97,8 @@ "name": "account_user_id_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -110,10 +106,7 @@ "compositePrimaryKeys": { "account_provider_provider_account_id_pk": { "name": "account_provider_provider_account_id_pk", - "columns": [ - "provider", - "provider_account_id" - ] + "columns": ["provider", "provider_account_id"] } }, "uniqueConstraints": {}, @@ -150,12 +143,8 @@ "name": "apiKey_user_id_user_id_fk", "tableFrom": "apiKey", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -244,12 +233,8 @@ "name": "boardGroupPermission_board_id_board_id_fk", "tableFrom": "boardGroupPermission", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -257,12 +242,8 @@ "name": "boardGroupPermission_group_id_group_id_fk", "tableFrom": "boardGroupPermission", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -270,11 +251,7 @@ "compositePrimaryKeys": { "boardGroupPermission_board_id_group_id_permission_pk": { "name": "boardGroupPermission_board_id_group_id_permission_pk", - "columns": [ - "board_id", - "group_id", - "permission" - ] + "columns": ["board_id", "group_id", "permission"] } }, "uniqueConstraints": {}, @@ -311,12 +288,8 @@ "name": "boardUserPermission_board_id_board_id_fk", "tableFrom": "boardUserPermission", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -324,12 +297,8 @@ "name": "boardUserPermission_user_id_user_id_fk", "tableFrom": "boardUserPermission", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -337,11 +306,7 @@ "compositePrimaryKeys": { "boardUserPermission_board_id_user_id_permission_pk": { "name": "boardUserPermission_board_id_user_id_permission_pk", - "columns": [ - "board_id", - "user_id", - "permission" - ] + "columns": ["board_id", "user_id", "permission"] } }, "uniqueConstraints": {}, @@ -483,12 +448,8 @@ "name": "board_creator_id_user_id_fk", "tableFrom": "board", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -498,9 +459,7 @@ "board_name_unique": { "name": "board_name_unique", "nullsNotDistinct": false, - "columns": [ - "name" - ] + "columns": ["name"] } }, "policies": {}, @@ -562,12 +521,8 @@ "name": "groupMember_group_id_group_id_fk", "tableFrom": "groupMember", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -575,12 +530,8 @@ "name": "groupMember_user_id_user_id_fk", "tableFrom": "groupMember", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -588,10 +539,7 @@ "compositePrimaryKeys": { "groupMember_group_id_user_id_pk": { "name": "groupMember_group_id_user_id_pk", - "columns": [ - "group_id", - "user_id" - ] + "columns": ["group_id", "user_id"] } }, "uniqueConstraints": {}, @@ -622,12 +570,8 @@ "name": "groupPermission_group_id_group_id_fk", "tableFrom": "groupPermission", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -685,12 +629,8 @@ "name": "group_owner_id_user_id_fk", "tableFrom": "group", "tableTo": "user", - "columnsFrom": [ - "owner_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -698,12 +638,8 @@ "name": "group_home_board_id_board_id_fk", "tableFrom": "group", "tableTo": "board", - "columnsFrom": [ - "home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -711,12 +647,8 @@ "name": "group_mobile_home_board_id_board_id_fk", "tableFrom": "group", "tableTo": "board", - "columnsFrom": [ - "mobile_home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["mobile_home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -726,9 +658,7 @@ "group_name_unique": { "name": "group_name_unique", "nullsNotDistinct": false, - "columns": [ - "name" - ] + "columns": ["name"] } }, "policies": {}, @@ -801,12 +731,8 @@ "name": "icon_icon_repository_id_iconRepository_id_fk", "tableFrom": "icon", "tableTo": "iconRepository", - "columnsFrom": [ - "icon_repository_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["icon_repository_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -846,12 +772,8 @@ "name": "integrationGroupPermissions_integration_id_integration_id_fk", "tableFrom": "integrationGroupPermissions", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -859,12 +781,8 @@ "name": "integrationGroupPermissions_group_id_group_id_fk", "tableFrom": "integrationGroupPermissions", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -872,11 +790,7 @@ "compositePrimaryKeys": { "integration_group_permission__pk": { "name": "integration_group_permission__pk", - "columns": [ - "integration_id", - "group_id", - "permission" - ] + "columns": ["integration_id", "group_id", "permission"] } }, "uniqueConstraints": {}, @@ -907,12 +821,8 @@ "name": "integration_item_item_id_item_id_fk", "tableFrom": "integration_item", "tableTo": "item", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["item_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -920,12 +830,8 @@ "name": "integration_item_integration_id_integration_id_fk", "tableFrom": "integration_item", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -933,10 +839,7 @@ "compositePrimaryKeys": { "integration_item_item_id_integration_id_pk": { "name": "integration_item_item_id_integration_id_pk", - "columns": [ - "item_id", - "integration_id" - ] + "columns": ["item_id", "integration_id"] } }, "uniqueConstraints": {}, @@ -1010,12 +913,8 @@ "name": "integrationSecret_integration_id_integration_id_fk", "tableFrom": "integrationSecret", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1023,10 +922,7 @@ "compositePrimaryKeys": { "integrationSecret_integration_id_kind_pk": { "name": "integrationSecret_integration_id_kind_pk", - "columns": [ - "integration_id", - "kind" - ] + "columns": ["integration_id", "kind"] } }, "uniqueConstraints": {}, @@ -1063,12 +959,8 @@ "name": "integrationUserPermission_integration_id_integration_id_fk", "tableFrom": "integrationUserPermission", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1076,12 +968,8 @@ "name": "integrationUserPermission_user_id_user_id_fk", "tableFrom": "integrationUserPermission", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1089,11 +977,7 @@ "compositePrimaryKeys": { "integrationUserPermission_integration_id_user_id_permission_pk": { "name": "integrationUserPermission_integration_id_user_id_permission_pk", - "columns": [ - "integration_id", - "user_id", - "permission" - ] + "columns": ["integration_id", "user_id", "permission"] } }, "uniqueConstraints": {}, @@ -1158,12 +1042,8 @@ "name": "integration_app_id_app_id_fk", "tableFrom": "integration", "tableTo": "app", - "columnsFrom": [ - "app_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["app_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1209,12 +1089,8 @@ "name": "invite_creator_id_user_id_fk", "tableFrom": "invite", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1224,9 +1100,7 @@ "invite_token_unique": { "name": "invite_token_unique", "nullsNotDistinct": false, - "columns": [ - "token" - ] + "columns": ["token"] } }, "policies": {}, @@ -1286,12 +1160,8 @@ "name": "item_layout_item_id_item_id_fk", "tableFrom": "item_layout", "tableTo": "item", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["item_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1299,12 +1169,8 @@ "name": "item_layout_section_id_section_id_fk", "tableFrom": "item_layout", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1312,12 +1178,8 @@ "name": "item_layout_layout_id_layout_id_fk", "tableFrom": "item_layout", "tableTo": "layout", - "columnsFrom": [ - "layout_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["layout_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1325,11 +1187,7 @@ "compositePrimaryKeys": { "item_layout_item_id_section_id_layout_id_pk": { "name": "item_layout_item_id_section_id_layout_id_pk", - "columns": [ - "item_id", - "section_id", - "layout_id" - ] + "columns": ["item_id", "section_id", "layout_id"] } }, "uniqueConstraints": {}, @@ -1380,12 +1238,8 @@ "name": "item_board_id_board_id_fk", "tableFrom": "item", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1438,12 +1292,8 @@ "name": "layout_board_id_board_id_fk", "tableFrom": "layout", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1508,12 +1358,8 @@ "name": "media_creator_id_user_id_fk", "tableFrom": "media", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1615,12 +1461,8 @@ "name": "search_engine_integration_id_integration_id_fk", "tableFrom": "search_engine", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1630,9 +1472,7 @@ "search_engine_short_unique": { "name": "search_engine_short_unique", "nullsNotDistinct": false, - "columns": [ - "short" - ] + "columns": ["short"] } }, "policies": {}, @@ -1669,12 +1509,8 @@ "name": "section_collapse_state_user_id_user_id_fk", "tableFrom": "section_collapse_state", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1682,12 +1518,8 @@ "name": "section_collapse_state_section_id_section_id_fk", "tableFrom": "section_collapse_state", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1695,10 +1527,7 @@ "compositePrimaryKeys": { "section_collapse_state_user_id_section_id_pk": { "name": "section_collapse_state_user_id_section_id_pk", - "columns": [ - "user_id", - "section_id" - ] + "columns": ["user_id", "section_id"] } }, "uniqueConstraints": {}, @@ -1759,12 +1588,8 @@ "name": "section_layout_section_id_section_id_fk", "tableFrom": "section_layout", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1772,12 +1597,8 @@ "name": "section_layout_layout_id_layout_id_fk", "tableFrom": "section_layout", "tableTo": "layout", - "columnsFrom": [ - "layout_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["layout_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1785,12 +1606,8 @@ "name": "section_layout_parent_section_id_section_id_fk", "tableFrom": "section_layout", "tableTo": "section", - "columnsFrom": [ - "parent_section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["parent_section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1798,10 +1615,7 @@ "compositePrimaryKeys": { "section_layout_section_id_layout_id_pk": { "name": "section_layout_section_id_layout_id_pk", - "columns": [ - "section_id", - "layout_id" - ] + "columns": ["section_id", "layout_id"] } }, "uniqueConstraints": {}, @@ -1863,12 +1677,8 @@ "name": "section_board_id_board_id_fk", "tableFrom": "section", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1904,9 +1714,7 @@ "serverSetting_settingKey_unique": { "name": "serverSetting_settingKey_unique", "nullsNotDistinct": false, - "columns": [ - "setting_key" - ] + "columns": ["setting_key"] } }, "policies": {}, @@ -1958,12 +1766,8 @@ "name": "session_user_id_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2095,12 +1899,8 @@ "name": "user_home_board_id_board_id_fk", "tableFrom": "user", "tableTo": "board", - "columnsFrom": [ - "home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2108,12 +1908,8 @@ "name": "user_mobile_home_board_id_board_id_fk", "tableFrom": "user", "tableTo": "board", - "columnsFrom": [ - "mobile_home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["mobile_home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2121,12 +1917,8 @@ "name": "user_default_search_engine_id_search_engine_id_fk", "tableFrom": "user", "tableTo": "search_engine", - "columnsFrom": [ - "default_search_engine_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["default_search_engine_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -2165,10 +1957,7 @@ "compositePrimaryKeys": { "verificationToken_identifier_token_pk": { "name": "verificationToken_identifier_token_pk", - "columns": [ - "identifier", - "token" - ] + "columns": ["identifier", "token"] } }, "uniqueConstraints": {}, @@ -2204,10 +1993,7 @@ "compositePrimaryKeys": { "trusted_certificate_hostname_hostname_thumbprint_pk": { "name": "trusted_certificate_hostname_hostname_thumbprint_pk", - "columns": [ - "hostname", - "thumbprint" - ] + "columns": ["hostname", "thumbprint"] } }, "uniqueConstraints": {}, @@ -2227,4 +2013,4 @@ "schemas": {}, "tables": {} } -} \ No newline at end of file +} diff --git a/packages/db/migrations/postgresql/meta/_journal.json b/packages/db/migrations/postgresql/meta/_journal.json index 0dc466c14..b6ecf835f 100644 --- a/packages/db/migrations/postgresql/meta/_journal.json +++ b/packages/db/migrations/postgresql/meta/_journal.json @@ -41,8 +41,8 @@ "idx": 5, "version": "7", "when": 1779199097716, - "tag": "0005_same_manta", + "tag": "0005_add_user_onboarding_tour_status", "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/packages/db/migrations/sqlite/0037_equal_retro_girl.sql b/packages/db/migrations/sqlite/0037_add_user_onboarding_tour_status.sql similarity index 100% rename from packages/db/migrations/sqlite/0037_equal_retro_girl.sql rename to packages/db/migrations/sqlite/0037_add_user_onboarding_tour_status.sql diff --git a/packages/db/migrations/sqlite/meta/0037_snapshot.json b/packages/db/migrations/sqlite/meta/0037_snapshot.json index dcfa96012..74827789c 100644 --- a/packages/db/migrations/sqlite/meta/0037_snapshot.json +++ b/packages/db/migrations/sqlite/meta/0037_snapshot.json @@ -88,9 +88,7 @@ "indexes": { "userId_idx": { "name": "userId_idx", - "columns": [ - "user_id" - ], + "columns": ["user_id"], "isUnique": false } }, @@ -99,22 +97,15 @@ "name": "account_user_id_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "account_provider_provider_account_id_pk": { - "columns": [ - "provider", - "provider_account_id" - ], + "columns": ["provider", "provider_account_id"], "name": "account_provider_provider_account_id_pk" } }, @@ -152,12 +143,8 @@ "name": "apiKey_user_id_user_id_fk", "tableFrom": "apiKey", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -249,12 +236,8 @@ "name": "boardGroupPermission_board_id_board_id_fk", "tableFrom": "boardGroupPermission", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -262,23 +245,15 @@ "name": "boardGroupPermission_group_id_group_id_fk", "tableFrom": "boardGroupPermission", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "boardGroupPermission_board_id_group_id_permission_pk": { - "columns": [ - "board_id", - "group_id", - "permission" - ], + "columns": ["board_id", "group_id", "permission"], "name": "boardGroupPermission_board_id_group_id_permission_pk" } }, @@ -316,12 +291,8 @@ "name": "boardUserPermission_board_id_board_id_fk", "tableFrom": "boardUserPermission", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -329,23 +300,15 @@ "name": "boardUserPermission_user_id_user_id_fk", "tableFrom": "boardUserPermission", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "boardUserPermission_board_id_user_id_permission_pk": { - "columns": [ - "board_id", - "user_id", - "permission" - ], + "columns": ["board_id", "user_id", "permission"], "name": "boardUserPermission_board_id_user_id_permission_pk" } }, @@ -501,9 +464,7 @@ "indexes": { "board_name_unique": { "name": "board_name_unique", - "columns": [ - "name" - ], + "columns": ["name"], "isUnique": true } }, @@ -512,12 +473,8 @@ "name": "board_creator_id_user_id_fk", "tableFrom": "board", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -582,12 +539,8 @@ "name": "groupMember_group_id_group_id_fk", "tableFrom": "groupMember", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -595,22 +548,15 @@ "name": "groupMember_user_id_user_id_fk", "tableFrom": "groupMember", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "groupMember_group_id_user_id_pk": { - "columns": [ - "group_id", - "user_id" - ], + "columns": ["group_id", "user_id"], "name": "groupMember_group_id_user_id_pk" } }, @@ -641,12 +587,8 @@ "name": "groupPermission_group_id_group_id_fk", "tableFrom": "groupPermission", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -704,9 +646,7 @@ "indexes": { "group_name_unique": { "name": "group_name_unique", - "columns": [ - "name" - ], + "columns": ["name"], "isUnique": true } }, @@ -715,12 +655,8 @@ "name": "group_owner_id_user_id_fk", "tableFrom": "group", "tableTo": "user", - "columnsFrom": [ - "owner_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["owner_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -728,12 +664,8 @@ "name": "group_home_board_id_board_id_fk", "tableFrom": "group", "tableTo": "board", - "columnsFrom": [ - "home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -741,12 +673,8 @@ "name": "group_mobile_home_board_id_board_id_fk", "tableFrom": "group", "tableTo": "board", - "columnsFrom": [ - "mobile_home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["mobile_home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -824,12 +752,8 @@ "name": "icon_icon_repository_id_iconRepository_id_fk", "tableFrom": "icon", "tableTo": "iconRepository", - "columnsFrom": [ - "icon_repository_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["icon_repository_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -869,12 +793,8 @@ "name": "integrationGroupPermissions_integration_id_integration_id_fk", "tableFrom": "integrationGroupPermissions", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -882,23 +802,15 @@ "name": "integrationGroupPermissions_group_id_group_id_fk", "tableFrom": "integrationGroupPermissions", "tableTo": "group", - "columnsFrom": [ - "group_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["group_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "integrationGroupPermissions_integration_id_group_id_permission_pk": { - "columns": [ - "integration_id", - "group_id", - "permission" - ], + "columns": ["integration_id", "group_id", "permission"], "name": "integrationGroupPermissions_integration_id_group_id_permission_pk" } }, @@ -929,12 +841,8 @@ "name": "integration_item_item_id_item_id_fk", "tableFrom": "integration_item", "tableTo": "item", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["item_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -942,22 +850,15 @@ "name": "integration_item_integration_id_integration_id_fk", "tableFrom": "integration_item", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "integration_item_item_id_integration_id_pk": { - "columns": [ - "item_id", - "integration_id" - ], + "columns": ["item_id", "integration_id"], "name": "integration_item_item_id_integration_id_pk" } }, @@ -999,16 +900,12 @@ "indexes": { "integration_secret__kind_idx": { "name": "integration_secret__kind_idx", - "columns": [ - "kind" - ], + "columns": ["kind"], "isUnique": false }, "integration_secret__updated_at_idx": { "name": "integration_secret__updated_at_idx", - "columns": [ - "updated_at" - ], + "columns": ["updated_at"], "isUnique": false } }, @@ -1017,22 +914,15 @@ "name": "integrationSecret_integration_id_integration_id_fk", "tableFrom": "integrationSecret", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "integrationSecret_integration_id_kind_pk": { - "columns": [ - "integration_id", - "kind" - ], + "columns": ["integration_id", "kind"], "name": "integrationSecret_integration_id_kind_pk" } }, @@ -1070,12 +960,8 @@ "name": "integrationUserPermission_integration_id_integration_id_fk", "tableFrom": "integrationUserPermission", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1083,23 +969,15 @@ "name": "integrationUserPermission_user_id_user_id_fk", "tableFrom": "integrationUserPermission", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "integrationUserPermission_integration_id_user_id_permission_pk": { - "columns": [ - "integration_id", - "user_id", - "permission" - ], + "columns": ["integration_id", "user_id", "permission"], "name": "integrationUserPermission_integration_id_user_id_permission_pk" } }, @@ -1148,9 +1026,7 @@ "indexes": { "integration__kind_idx": { "name": "integration__kind_idx", - "columns": [ - "kind" - ], + "columns": ["kind"], "isUnique": false } }, @@ -1159,12 +1035,8 @@ "name": "integration_app_id_app_id_fk", "tableFrom": "integration", "tableTo": "app", - "columnsFrom": [ - "app_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["app_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1208,9 +1080,7 @@ "indexes": { "invite_token_unique": { "name": "invite_token_unique", - "columns": [ - "token" - ], + "columns": ["token"], "isUnique": true } }, @@ -1219,12 +1089,8 @@ "name": "invite_creator_id_user_id_fk", "tableFrom": "invite", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1292,12 +1158,8 @@ "name": "item_layout_item_id_item_id_fk", "tableFrom": "item_layout", "tableTo": "item", - "columnsFrom": [ - "item_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["item_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1305,12 +1167,8 @@ "name": "item_layout_section_id_section_id_fk", "tableFrom": "item_layout", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1318,23 +1176,15 @@ "name": "item_layout_layout_id_layout_id_fk", "tableFrom": "item_layout", "tableTo": "layout", - "columnsFrom": [ - "layout_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["layout_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "item_layout_item_id_section_id_layout_id_pk": { - "columns": [ - "item_id", - "section_id", - "layout_id" - ], + "columns": ["item_id", "section_id", "layout_id"], "name": "item_layout_item_id_section_id_layout_id_pk" } }, @@ -1388,12 +1238,8 @@ "name": "item_board_id_board_id_fk", "tableFrom": "item", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1448,12 +1294,8 @@ "name": "layout_board_id_board_id_fk", "tableFrom": "layout", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1522,12 +1364,8 @@ "name": "media_creator_id_user_id_fk", "tableFrom": "media", "tableTo": "user", - "columnsFrom": [ - "creator_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["creator_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1631,9 +1469,7 @@ "indexes": { "search_engine_short_unique": { "name": "search_engine_short_unique", - "columns": [ - "short" - ], + "columns": ["short"], "isUnique": true } }, @@ -1642,12 +1478,8 @@ "name": "search_engine_integration_id_integration_id_fk", "tableFrom": "search_engine", "tableTo": "integration", - "columnsFrom": [ - "integration_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["integration_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1688,12 +1520,8 @@ "name": "section_collapse_state_user_id_user_id_fk", "tableFrom": "section_collapse_state", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1701,22 +1529,15 @@ "name": "section_collapse_state_section_id_section_id_fk", "tableFrom": "section_collapse_state", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "section_collapse_state_user_id_section_id_pk": { - "columns": [ - "user_id", - "section_id" - ], + "columns": ["user_id", "section_id"], "name": "section_collapse_state_user_id_section_id_pk" } }, @@ -1782,12 +1603,8 @@ "name": "section_layout_section_id_section_id_fk", "tableFrom": "section_layout", "tableTo": "section", - "columnsFrom": [ - "section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1795,12 +1612,8 @@ "name": "section_layout_layout_id_layout_id_fk", "tableFrom": "section_layout", "tableTo": "layout", - "columnsFrom": [ - "layout_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["layout_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1808,22 +1621,15 @@ "name": "section_layout_parent_section_id_section_id_fk", "tableFrom": "section_layout", "tableTo": "section", - "columnsFrom": [ - "parent_section_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["parent_section_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } }, "compositePrimaryKeys": { "section_layout_section_id_layout_id_pk": { - "columns": [ - "section_id", - "layout_id" - ], + "columns": ["section_id", "layout_id"], "name": "section_layout_section_id_layout_id_pk" } }, @@ -1890,12 +1696,8 @@ "name": "section_board_id_board_id_fk", "tableFrom": "section", "tableTo": "board", - "columnsFrom": [ - "board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["board_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1926,9 +1728,7 @@ "indexes": { "serverSetting_settingKey_unique": { "name": "serverSetting_settingKey_unique", - "columns": [ - "setting_key" - ], + "columns": ["setting_key"], "isUnique": true } }, @@ -1965,9 +1765,7 @@ "indexes": { "user_id_idx": { "name": "user_id_idx", - "columns": [ - "user_id" - ], + "columns": ["user_id"], "isUnique": false } }, @@ -1976,12 +1774,8 @@ "name": "session_user_id_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2019,10 +1813,7 @@ "foreignKeys": {}, "compositePrimaryKeys": { "trusted_certificate_hostname_hostname_thumbprint_pk": { - "columns": [ - "hostname", - "thumbprint" - ], + "columns": ["hostname", "thumbprint"], "name": "trusted_certificate_hostname_hostname_thumbprint_pk" } }, @@ -2166,12 +1957,8 @@ "name": "user_home_board_id_board_id_fk", "tableFrom": "user", "tableTo": "board", - "columnsFrom": [ - "home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2179,12 +1966,8 @@ "name": "user_mobile_home_board_id_board_id_fk", "tableFrom": "user", "tableTo": "board", - "columnsFrom": [ - "mobile_home_board_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["mobile_home_board_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2192,12 +1975,8 @@ "name": "user_default_search_engine_id_search_engine_id_fk", "tableFrom": "user", "tableTo": "search_engine", - "columnsFrom": [ - "default_search_engine_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["default_search_engine_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -2235,10 +2014,7 @@ "foreignKeys": {}, "compositePrimaryKeys": { "verificationToken_identifier_token_pk": { - "columns": [ - "identifier", - "token" - ], + "columns": ["identifier", "token"], "name": "verificationToken_identifier_token_pk" } }, @@ -2256,4 +2032,4 @@ "internal": { "indexes": {} } -} \ No newline at end of file +} diff --git a/packages/db/migrations/sqlite/meta/_journal.json b/packages/db/migrations/sqlite/meta/_journal.json index 879c64363..2f4866c79 100644 --- a/packages/db/migrations/sqlite/meta/_journal.json +++ b/packages/db/migrations/sqlite/meta/_journal.json @@ -265,8 +265,8 @@ "idx": 37, "version": "6", "when": 1779199046805, - "tag": "0037_equal_retro_girl", + "tag": "0037_add_user_onboarding_tour_status", "breakpoints": true } ] -} \ No newline at end of file +} From acd248cca2907c6ba64486369d47628d3d772476 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:42:42 +0200 Subject: [PATCH 05/11] feat(api): add onboarding tour status tRPC endpoints Expose getTourStatus, completeTour, and resetTours for persisting per-user management and board tour completion. --- packages/api/src/router/user.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/api/src/router/user.ts b/packages/api/src/router/user.ts index d29801842..114aa9a7d 100644 --- a/packages/api/src/router/user.ts +++ b/packages/api/src/router/user.ts @@ -612,15 +612,12 @@ export const userRouter = createTRPCRouter({ completeTour: protectedProcedure .input(z.object({ tour: z.enum(["manage", "board"]) })) .mutation(async ({ input, ctx }) => { - const columnMap: Record> = { + const columnByTour = { manage: { completedManageTour: true }, board: { completedBoardTour: true }, - }; + } as const; - await ctx.db - .update(users) - .set(columnMap[input.tour]!) - .where(eq(users.id, ctx.session.user.id)); + await ctx.db.update(users).set(columnByTour[input.tour]).where(eq(users.id, ctx.session.user.id)); }), resetTours: protectedProcedure.mutation(async ({ ctx }) => { await ctx.db From 8e6f31e92ad4037f9ce1a9f8f7b746c06da12b78 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:42:42 +0200 Subject: [PATCH 06/11] chore(ui): import mantine onboarding tour styles Register onboarding tour stylesheet and align lockfile with Mantine v9. --- packages/ui/src/styles.css | 1 + pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/styles.css b/packages/ui/src/styles.css index e4072e1d0..07a86f6a3 100644 --- a/packages/ui/src/styles.css +++ b/packages/ui/src/styles.css @@ -1,4 +1,5 @@ @import "@mantine/core/styles.css"; @import "@mantine/charts/styles.css"; @import "@mantine/dates/styles.css"; +@import "@gfazioli/mantine-onboarding-tour/styles.css"; @import "mantine-react-table/styles.css"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f585c8ff9..0ce165eaa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -684,7 +684,7 @@ importers: version: 3.2.2(react@19.2.6) '@gfazioli/mantine-onboarding-tour': specifier: 'catalog:' - version: 4.0.1(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 4.0.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@homarr/analytics': specifier: workspace:^0.1.0 version: link:../../packages/analytics @@ -11397,10 +11397,10 @@ snapshots: '@formatjs/fast-memoize': 3.1.0 tslib: 2.8.1 - '@gfazioli/mantine-onboarding-tour@4.0.1(@mantine/core@8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@8.3.18(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@gfazioli/mantine-onboarding-tour@4.0.1(@mantine/core@9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.1(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@mantine/core': 8.3.18(@mantine/hooks@8.3.18(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@mantine/hooks': 8.3.18(react@19.2.6) + '@mantine/core': 9.2.1(@mantine/hooks@9.2.1(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mantine/hooks': 9.2.1(react@19.2.6) '@tabler/icons-react': 3.44.0(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) From 97e9c3258e61ad4b6702a9ea0c9fd8b89c67a32c Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:42:42 +0200 Subject: [PATCH 07/11] feat(onboarding): add shared tour shell with keyboard navigation Introduce TourShell with step counter, Enter key support, route-aware advancement, and TourTarget wrappers. Remove unused fork and hold-skip steps. --- .../components/layout/header/tour-target.tsx | 11 + .../onboarding/skip-hold-button.tsx | 64 ------ .../components/onboarding/tour-fork-step.tsx | 41 ---- .../src/components/onboarding/tour-shell.tsx | 190 ++++++++++++++++++ .../onboarding/tour-step-content.tsx | 33 ++- 5 files changed, 223 insertions(+), 116 deletions(-) create mode 100644 apps/nextjs/src/components/layout/header/tour-target.tsx delete mode 100644 apps/nextjs/src/components/onboarding/skip-hold-button.tsx delete mode 100644 apps/nextjs/src/components/onboarding/tour-fork-step.tsx create mode 100644 apps/nextjs/src/components/onboarding/tour-shell.tsx diff --git a/apps/nextjs/src/components/layout/header/tour-target.tsx b/apps/nextjs/src/components/layout/header/tour-target.tsx new file mode 100644 index 000000000..b23572d1e --- /dev/null +++ b/apps/nextjs/src/components/layout/header/tour-target.tsx @@ -0,0 +1,11 @@ +"use client"; + +import type { ReactNode } from "react"; +import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; +import { Box } from "@mantine/core"; + +export const TourTarget = ({ id, children }: { id: string; children: ReactNode }) => ( + + {children} + +); diff --git a/apps/nextjs/src/components/onboarding/skip-hold-button.tsx b/apps/nextjs/src/components/onboarding/skip-hold-button.tsx deleted file mode 100644 index f512744b5..000000000 --- a/apps/nextjs/src/components/onboarding/skip-hold-button.tsx +++ /dev/null @@ -1,64 +0,0 @@ -"use client"; - -import { useCallback, useEffect, useRef, useState } from "react"; -import { Button, Progress, Stack, Text } from "@mantine/core"; - -import { useI18n } from "@homarr/translation/client"; - -const HOLD_DURATION_MS = 2000; -const TICK_INTERVAL_MS = 50; - -interface SkipHoldButtonProps { - onSkip: () => void; -} - -export const SkipHoldButton = ({ onSkip }: SkipHoldButtonProps) => { - const t = useI18n(); - const [progress, setProgress] = useState(0); - const intervalRef = useRef | null>(null); - - const clearHoldInterval = useCallback(() => { - if (intervalRef.current) { - clearInterval(intervalRef.current); - intervalRef.current = null; - } - }, []); - - useEffect(() => clearHoldInterval, [clearHoldInterval]); - - const handlePointerDown = useCallback(() => { - clearHoldInterval(); - setProgress(0); - let elapsed = 0; - intervalRef.current = setInterval(() => { - elapsed += TICK_INTERVAL_MS; - const pct = Math.min((elapsed / HOLD_DURATION_MS) * 100, 100); - setProgress(pct); - if (elapsed >= HOLD_DURATION_MS) { - clearHoldInterval(); - onSkip(); - } - }, TICK_INTERVAL_MS); - }, [onSkip, clearHoldInterval]); - - const handlePointerUp = useCallback(() => { - clearHoldInterval(); - setProgress(0); - }, [clearHoldInterval]); - - return ( - - - {progress > 0 && } - - ); -}; diff --git a/apps/nextjs/src/components/onboarding/tour-fork-step.tsx b/apps/nextjs/src/components/onboarding/tour-fork-step.tsx deleted file mode 100644 index 4a1ce4ffe..000000000 --- a/apps/nextjs/src/components/onboarding/tour-fork-step.tsx +++ /dev/null @@ -1,41 +0,0 @@ -"use client"; - -import { Anchor, Button, Group, Stack, Text } from "@mantine/core"; -import { IconExternalLink } from "@tabler/icons-react"; - -import type { HomarrDocumentationPath } from "@homarr/definitions"; -import { createDocumentationLink } from "@homarr/definitions"; -import { useI18n } from "@homarr/translation/client"; - -interface TourForkStepProps { - question: string; - description?: string; - docPath: HomarrDocumentationPath; - onYes: () => void; - onNo: () => void; -} - -export const TourForkStep = ({ question, description, docPath, onYes, onNo }: TourForkStepProps) => { - const t = useI18n(); - - return ( - - {description && {description}} - - {question} - - - - - - - - {t("onboardingTour.learnMore")} - - - ); -}; diff --git a/apps/nextjs/src/components/onboarding/tour-shell.tsx b/apps/nextjs/src/components/onboarding/tour-shell.tsx new file mode 100644 index 000000000..702c28634 --- /dev/null +++ b/apps/nextjs/src/components/onboarding/tour-shell.tsx @@ -0,0 +1,190 @@ +"use client"; + +import type { PropsWithChildren } from "react"; +import { useCallback, useEffect, useRef } from "react"; +import { useRouter } from "next/navigation"; +import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; +import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; +import { Button, Center, Group, Image, Kbd, Text } from "@mantine/core"; +import type { FloatingPosition } from "@mantine/core"; + +import { useI18n } from "@homarr/translation/client"; + +import { homarrLogoPath } from "~/components/layout/logo/homarr-logo"; + +interface TourShellProps extends PropsWithChildren { + steps: OnboardingTourStep[]; + started: boolean; + onEnd: () => void; + stepRoutes?: Record; + position?: FloatingPosition | Record; +} + +type TourController = Parameters["nextStepNavigation"]>>[0]; + +const pollForElement = (targetId: string, callback: () => void) => { + const interval = setInterval(() => { + const targetElement = document.querySelector(`[data-tour-target="${targetId}"]`); + if (targetElement) { + clearInterval(interval); + callback(); + } + }, 50); + const timeout = setTimeout(() => clearInterval(interval), 5000); + return () => { + clearInterval(interval); + clearTimeout(timeout); + }; +}; + +const isTypingTarget = (target: EventTarget | null) => { + if (!(target instanceof HTMLElement)) return false; + const tag = target.tagName; + return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || target.isContentEditable; +}; + +interface TourForwardButtonProps { + label: string; + onClick: () => void; +} + +const TourForwardButton = ({ label, onClick }: TourForwardButtonProps) => { + return ( + + ); +}; + +interface TourDoneButtonProps { + label: string; + onClick: () => void; +} + +const TourDoneButton = ({ label, onClick }: TourDoneButtonProps) => { + return ( + + ); +}; + +export const TourShell = ({ steps, started, onEnd, stepRoutes, position, children }: TourShellProps) => { + const t = useI18n(); + const router = useRouter(); + const forwardActionRef = useRef<(() => void) | null>(null); + + const navigateAndAdvance = useCallback( + (currentStepId: string | undefined, targetStepId: string | undefined, advance: () => void) => { + if (!stepRoutes || !targetStepId) { + advance(); + return; + } + + const currentRoute = currentStepId ? stepRoutes[currentStepId] : undefined; + const targetRoute = stepRoutes[targetStepId]; + + if (targetRoute && targetRoute !== currentRoute) { + router.push(targetRoute); + pollForElement(targetStepId, advance); + } else { + advance(); + } + }, + [router, stepRoutes], + ); + + const bindForwardAction = useCallback((controller: TourController, action: () => void) => { + forwardActionRef.current = action; + return action; + }, []); + + useEffect(() => { + if (!started) { + forwardActionRef.current = null; + return; + } + + const onKeyDown = (event: KeyboardEvent) => { + if (event.key !== "Enter" || event.shiftKey || event.ctrlKey || event.metaKey || event.altKey) return; + if (isTypingTarget(event.target)) return; + event.preventDefault(); + forwardActionRef.current?.(); + }; + + window.addEventListener("keydown", onKeyDown); + return () => window.removeEventListener("keydown", onKeyDown); + }, [started]); + + return ( + ( + <> + + + {(controller.currentStepIndex ?? 0) + 1} + + + / + + + {controller.tour.length} + + + {controller.currentStepIndex === 0 && ( +
+ Homarr +
+ )} + + )} + nextStepNavigation={(controller) => { + const nextStep = controller.tour[controller.currentStepIndex + 1]; + const action = bindForwardAction(controller, () => { + navigateAndAdvance(controller.currentStep?.id, nextStep?.id, () => controller.nextStep()); + }); + return ; + }} + endStepNavigation={(controller) => { + const action = bindForwardAction(controller, () => controller.endTour()); + return ; + }} + prevStepNavigation={(controller) => ( + + )} + skipNavigation={(controller) => ( + + )} + withPrevButton + focusRevealProps={{ + disableTargetInteraction: true, + popoverProps: { + position: position ?? { base: "bottom", sm: "right" }, + width: 420, + shadow: "xl", + radius: "lg", + middlewares: { shift: { padding: 16 }, flip: true }, + }, + }} + cutoutPadding={12} + cutoutRadius={12} + > + {children} +
+ ); +}; diff --git a/apps/nextjs/src/components/onboarding/tour-step-content.tsx b/apps/nextjs/src/components/onboarding/tour-step-content.tsx index 8c8248594..05b7b4bd3 100644 --- a/apps/nextjs/src/components/onboarding/tour-step-content.tsx +++ b/apps/nextjs/src/components/onboarding/tour-step-content.tsx @@ -1,27 +1,38 @@ "use client"; -import { Anchor, Stack, Text } from "@mantine/core"; +import type { ReactNode } from "react"; +import { Anchor, Divider, Group, Stack, Text, ThemeIcon } from "@mantine/core"; import { IconExternalLink } from "@tabler/icons-react"; -import type { HomarrDocumentationPath } from "@homarr/definitions"; -import { createDocumentationLink } from "@homarr/definitions"; import { useI18n } from "@homarr/translation/client"; interface TourStepContentProps { description: string; - docPath: HomarrDocumentationPath; - docHash?: `#${string}`; + documentationHref: string; + icon?: ReactNode; } -export const TourStepContent = ({ description, docPath, docHash }: TourStepContentProps) => { +export const TourStepContent = ({ description, documentationHref, icon }: TourStepContentProps) => { const t = useI18n(); return ( - - {description} - - - {t("onboardingTour.learnMore")} + + + {icon && ( + + {icon} + + )} + + {description} + + + + + + + {t("onboardingTour.learnMore")} + ); From 12791685380468f0d27c7e01432a4c98fa347a05 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:42:54 +0200 Subject: [PATCH 08/11] feat(onboarding): add management tour with multi-page navigation Guide admins through boards, apps, integrations, and users with per-page steps, TourTarget highlights, optimistic completion, and reset in settings. --- .../src/app/[locale]/manage/apps/page.tsx | 15 +- .../src/app/[locale]/manage/boards/page.tsx | 23 +- .../app/[locale]/manage/integrations/page.tsx | 21 +- .../general/_components/_reset-tours.tsx | 18 +- .../manage/users/[userId]/general/page.tsx | 5 +- .../manage/users/_components/user-list.tsx | 21 +- apps/nextjs/src/components/layout/header.tsx | 11 +- .../src/components/layout/navigation-link.tsx | 32 +- .../src/components/onboarding/manage-tour.tsx | 274 +++++++++++------- 9 files changed, 253 insertions(+), 167 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx index 27ab01fb5..4801a3275 100644 --- a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx @@ -11,6 +11,7 @@ import type { inferSearchParamsFromSchema } from "@homarr/common/types"; import { getI18n, getScopedI18n } from "@homarr/translation/server"; import { Link, SearchInput, TablePagination } from "@homarr/ui"; +import { TourTarget } from "~/components/layout/header/tour-target"; import { ManageContainer } from "~/components/manage/manage-container"; import { MobileAffixButton } from "~/components/manage/mobile-affix-button"; import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; @@ -47,19 +48,21 @@ export default async function AppsPage(props: AppsPageProps) { {session.user.permissions.includes("app-create") && ( - - {t("page.create.title")} - + + + {t("page.create.title")} + + )} - {apps.length === 0 && } - {apps.length > 0 && ( + + {apps.length === 0 && } {apps.map((app) => ( ))} - )} + {/* Added margin to not hide pagination behind affix-button */} diff --git a/apps/nextjs/src/app/[locale]/manage/boards/page.tsx b/apps/nextjs/src/app/[locale]/manage/boards/page.tsx index 9c0a28344..7452cf3df 100644 --- a/apps/nextjs/src/app/[locale]/manage/boards/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/boards/page.tsx @@ -23,6 +23,7 @@ import { getScopedI18n } from "@homarr/translation/server"; import { Link, UserAvatar } from "@homarr/ui"; import { getBoardPermissionsAsync } from "~/components/board/permissions/server"; +import { TourTarget } from "~/components/layout/header/tour-target"; import { ManageContainer } from "~/components/manage/manage-container"; import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; import { BoardCardMenuDropdown } from "./_components/board-card-menu-dropdown"; @@ -40,16 +41,22 @@ export default async function ManageBoardsPage() { {t("title")} - {canCreateBoards && } + {canCreateBoards && ( + + + + )} - - {boards.map((board) => ( - - - - ))} - + + + {boards.map((board) => ( + + + + ))} + + ); diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx index 1fe3a83e2..8b976cb45 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx @@ -37,6 +37,7 @@ import { getIntegrationName } from "@homarr/definitions"; import { getScopedI18n } from "@homarr/translation/server"; import { CountBadge, IntegrationAvatar, Link } from "@homarr/ui"; +import { TourTarget } from "~/components/layout/header/tour-target"; import { ManageContainer } from "~/components/manage/manage-container"; import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; import { NoResults } from "~/components/no-results"; @@ -84,18 +85,22 @@ export default async function IntegrationsPage(props: IntegrationsPageProps) { - - - - - - - + + + + + + + + + )} - + + + ); diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx index d638b624e..76f33a8db 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_reset-tours.tsx @@ -7,14 +7,10 @@ import { clientApi } from "@homarr/api/client"; import { showSuccessNotification } from "@homarr/notifications"; import { useScopedI18n } from "@homarr/translation/client"; -interface ResetToursProps { - completedManageTour: boolean; - completedBoardTour: boolean; -} - -export const ResetTours = ({ completedManageTour, completedBoardTour }: ResetToursProps) => { +export const ResetTours = () => { const t = useScopedI18n("management.page.user.setting.general.item.onboardingTours"); const utils = clientApi.useUtils(); + const { data: tourStatus } = clientApi.user.getTourStatus.useQuery(); const { mutate: resetTours, isPending } = clientApi.user.resetTours.useMutation({ onSuccess() { showSuccessNotification({ @@ -25,15 +21,15 @@ export const ResetTours = ({ completedManageTour, completedBoardTour }: ResetTou }, }); - const tourStatusMap: Record = { - management: { key: "management", completed: completedManageTour }, - dashboard: { key: "dashboard", completed: completedBoardTour }, - }; + const tours = [ + { key: "management" as const, completed: tourStatus?.completedManageTour ?? false }, + { key: "dashboard" as const, completed: tourStatus?.completedBoardTour ?? false }, + ]; return ( - {Object.values(tourStatusMap).map(({ key, completed }) => ( + {tours.map(({ key, completed }) => ( {t(`name.${key}`)}: {completed ? t("status.completed") : t("status.notStarted")} diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx index 665ab7d6c..453c2c486 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/page.tsx @@ -122,10 +122,7 @@ export default async function EditUserPage(props: Props) { {session?.user.id === user.id && ( {tGeneral("item.onboardingTours.title")} - + )} diff --git a/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx b/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx index 22f4d1b88..881aec980 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx @@ -12,6 +12,8 @@ import { useI18n, useScopedI18n } from "@homarr/translation/client"; import { Link, UserAvatar } from "@homarr/ui"; import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; +import { TourTarget } from "~/components/layout/header/tour-target"; + interface UserListComponentProps { initialUserList: RouterOutputs["user"]["getAll"]; credentialsProviderEnabled: boolean; @@ -69,12 +71,6 @@ export const UserListComponent = ({ initialUserList, credentialsProviderEnabled enableFullScreenToggle: false, layoutMode: "grid-no-grow", getRowId: (row) => row.id, - renderTopToolbarCustomActions: () => - credentialsProviderEnabled ? ( - - ) : null, state: { isLoading, }, @@ -82,7 +78,18 @@ export const UserListComponent = ({ initialUserList, credentialsProviderEnabled return ( <> - {tUserList("title")} + + + {tUserList("title")} + + {credentialsProviderEnabled && ( + + + + )} + ); diff --git a/apps/nextjs/src/components/layout/header.tsx b/apps/nextjs/src/components/layout/header.tsx index 53a1ed2dd..32ffa81d7 100644 --- a/apps/nextjs/src/components/layout/header.tsx +++ b/apps/nextjs/src/components/layout/header.tsx @@ -1,11 +1,12 @@ import type { ReactNode } from "react"; -import { AppShellHeader, Box, Group, UnstyledButton } from "@mantine/core"; +import { AppShellHeader, Group, UnstyledButton } from "@mantine/core"; import { Spotlight } from "@homarr/spotlight"; import { Link } from "@homarr/ui"; import { ClientBurger } from "./header/burger"; import { DesktopSearchInput, MobileSearchButton } from "./header/search"; +import { TourTarget } from "./header/tour-target"; import { UserButton } from "./header/user"; import { HomarrLogoWithTitle } from "./logo/homarr-logo"; @@ -25,15 +26,15 @@ export const MainHeader = ({ logo, actions, hasNavigation = true }: Props) => { {logo ?? } - + - + {actions} - + - + diff --git a/apps/nextjs/src/components/layout/navigation-link.tsx b/apps/nextjs/src/components/layout/navigation-link.tsx index 848f7d691..dcd8e5573 100644 --- a/apps/nextjs/src/components/layout/navigation-link.tsx +++ b/apps/nextjs/src/components/layout/navigation-link.tsx @@ -2,6 +2,7 @@ import type { ReactNode } from "react"; import { usePathname } from "next/navigation"; +import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; import { NavLink } from "@mantine/core"; import { Link } from "@homarr/ui"; @@ -9,20 +10,22 @@ import { Link } from "@homarr/ui"; export const CommonNavLink = (props: ClientNavigationLink) => "href" in props ? : ; +const TourTarget = ({ id, children }: { id?: string; children: ReactNode }) => { + if (!id) return <>{children}; + return {children}; +}; + const NavLinkHref = (props: NavigationLinkHref) => { const pathname = usePathname(); const tourId = props["data-onboarding-tour-id"]; - return props.external ? ( + const link = props.external ? ( ) : ( { leftSection={props.icon} href={props.href} active={pathname === props.href} - style={{ - borderRadius: 5, - }} - data-onboarding-tour-id={tourId} + style={{ borderRadius: 5 }} /> ); + return {link}; }; const NavLinkWithItems = (props: NavigationLinkWithItems) => { const pathname = usePathname(); const isActive = props.items.some((item) => item.href === pathname); - return ( - + const nav = ( + {props.items.map((item) => ( ))} ); + return {nav}; }; interface CommonNavigationLinkProps { diff --git a/apps/nextjs/src/components/onboarding/manage-tour.tsx b/apps/nextjs/src/components/onboarding/manage-tour.tsx index 5da9959a5..361a183dd 100644 --- a/apps/nextjs/src/components/onboarding/manage-tour.tsx +++ b/apps/nextjs/src/components/onboarding/manage-tour.tsx @@ -1,34 +1,101 @@ "use client"; import type { PropsWithChildren } from "react"; -import { useMemo } from "react"; -import { useRouter } from "next/navigation"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { usePathname, useRouter } from "next/navigation"; import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; -import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; -import { Box } from "@mantine/core"; +import { useMediaQuery } from "@mantine/hooks"; +import { + IconAffiliateFilled, + IconAppsFilled, + IconLayoutDashboardFilled, + IconPlus, + IconUserFilled, +} from "@tabler/icons-react"; import { clientApi } from "@homarr/api/client"; +import { createDocumentationLink } from "@homarr/definitions"; import { useScopedI18n } from "@homarr/translation/client"; -import { SkipHoldButton } from "./skip-hold-button"; -import { TourForkStep } from "./tour-fork-step"; +import { TourShell } from "./tour-shell"; import { TourStepContent } from "./tour-step-content"; interface ManageTourProviderProps extends PropsWithChildren { isAdmin: boolean; } +const stepRoutes: Record = { + "manage-welcome": "/manage", + "manage-boards-list": "/manage/boards", + "manage-boards-create": "/manage/boards", + "manage-apps-list": "/manage/apps", + "manage-apps-create": "/manage/apps", + "manage-integrations-list": "/manage/integrations", + "manage-integrations-create": "/manage/integrations", + "manage-users-list": "/manage/users", + "manage-users-create": "/manage/users", +}; + +const usersStepFocusRevealProps = { + withReveal: false, + popoverProps: { + position: "bottom", + middlewares: { shift: { padding: 16 }, flip: true }, + }, +}; + export const ManageTourProvider = ({ children, isAdmin }: ManageTourProviderProps) => { - const router = useRouter(); const t = useScopedI18n("onboardingTour.manage"); + const utils = clientApi.useUtils(); const { data: tourStatus } = clientApi.user.getTourStatus.useQuery(); - const { mutate: completeTour } = clientApi.user.completeTour.useMutation(); + const { mutate: completeTour } = clientApi.user.completeTour.useMutation({ + onSuccess() { + void utils.user.getTourStatus.invalidate(); + }, + }); + const isMobile = useMediaQuery("(max-width: 48em)"); + const pathname = usePathname(); + const router = useRouter(); - const started = tourStatus !== undefined && !tourStatus.completedManageTour; + const isManageHome = /^(\/[^/]+)?\/manage\/?$/.test(pathname); + const isManageSection = /^(\/[^/]+)?\/manage(\/.*)?$/.test(pathname); - const handleEnd = () => { + const [tourActive, setTourActive] = useState(false); + const [tourDismissed, setTourDismissed] = useState(false); + const wasManageTourCompletedRef = useRef(tourStatus?.completedManageTour); + + useEffect(() => { + if (tourDismissed) return; + if (isManageHome && tourStatus !== undefined && !tourStatus.completedManageTour && !isMobile) { + setTourActive(true); + } + }, [isManageHome, tourStatus, isMobile, tourDismissed]); + + useEffect(() => { + if (!isManageSection) { + setTourActive(false); + } + }, [isManageSection]); + + useEffect(() => { + const wasCompleted = wasManageTourCompletedRef.current; + const isCompleted = tourStatus?.completedManageTour; + if (wasCompleted === true && isCompleted === false) { + setTourDismissed(false); + } + wasManageTourCompletedRef.current = isCompleted; + }, [tourStatus?.completedManageTour]); + + const handleEnd = useCallback(() => { + setTourDismissed(true); + setTourActive(false); + utils.user.getTourStatus.setData(undefined, { + completedManageTour: true, + completedBoardTour: tourStatus?.completedBoardTour ?? false, + }); completeTour({ tour: "manage" }); - }; + router.push("/manage"); + }, [completeTour, router, tourStatus?.completedBoardTour, utils.user.getTourStatus]); const steps = useMemo(() => { const allSteps: (OnboardingTourStep & { adminOnly?: boolean })[] = [ @@ -36,109 +103,118 @@ export const ManageTourProvider = ({ children, isAdmin }: ManageTourProviderProp id: "manage-welcome", title: t("welcome.title"), content: ( - - ), - footer: (controller: { skipTour: () => void }) => ( - controller.skipTour()} /> - ), - }, - { - id: "manage-boards", - title: t("boards.title"), - content: ( - - ), - }, - { - id: "manage-apps", - title: t("apps.title"), - content: ( - - ), - }, - { - id: "manage-integrations", - title: t("integrations.title"), - content: (controller: { endTour: () => void; nextStep: () => void }) => ( - { - controller.endTour(); - router.push("/manage/integrations/new"); - }} - onNo={() => controller.nextStep()} + ), }, { - id: "manage-search-engines", - title: t("searchEngines.title"), - content: ( - - ), - }, - { - id: "manage-medias", - title: t("medias.title"), - content: ( - - ), - }, - { - id: "manage-users", - title: t("users.title"), - adminOnly: true, - content: (controller: { endTour: () => void; nextStep: () => void }) => ( - { - controller.endTour(); - router.push("/manage/users/create"); - }} - onNo={() => controller.nextStep()} - /> - ), - }, - { - id: "manage-settings", - title: t("settings.title"), - adminOnly: true, - content: ( - - ), - }, - { - id: "manage-complete", - title: t("complete.title"), + id: "manage-boards-list", + title: t("boardsList.title"), content: ( } + /> + ), + }, + { + id: "manage-boards-create", + title: t("boardsCreate.title"), + content: ( + } + /> + ), + }, + { + id: "manage-apps-list", + title: t("appsList.title"), + content: ( + } + /> + ), + }, + { + id: "manage-apps-create", + title: t("appsCreate.title"), + content: ( + } + /> + ), + }, + { + id: "manage-integrations-list", + title: t("integrationsList.title"), + content: ( + } + /> + ), + }, + { + id: "manage-integrations-create", + title: t("integrationsCreate.title"), + content: ( + } + /> + ), + }, + { + id: "manage-users-list", + title: t("usersList.title"), + adminOnly: true, + focusRevealProps: usersStepFocusRevealProps, + content: ( + } + /> + ), + }, + { + id: "manage-users-create", + title: t("usersCreate.title"), + adminOnly: true, + focusRevealProps: usersStepFocusRevealProps, + content: ( + } /> ), }, ]; return allSteps.filter((step) => !step.adminOnly || isAdmin) as OnboardingTourStep[]; - }, [isAdmin, router, t]); + }, [isAdmin, t]); return ( - - {children} - + ); }; From 60bf8672039c6b547ad7bdf6d8df329468e3fc48 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:43:00 +0200 Subject: [PATCH 09/11] feat(onboarding): add board tour on dashboard pages Scope the board tour to content pages, target header actions, remove the loading overlay, and persist completion with optimistic cache updates. --- .../app/[locale]/boards/(content)/_client.tsx | 13 +--- .../[locale]/boards/(content)/_creator.tsx | 1 + .../boards/(content)/_header-actions.tsx | 65 +++++++++++-------- .../app/[locale]/boards/_layout-creator.tsx | 4 +- .../src/components/onboarding/board-tour.tsx | 59 ++++++++++------- 5 files changed, 78 insertions(+), 64 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx index e9551af52..649aa867b 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_client.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useRef } from "react"; -import { Box, LoadingOverlay, Stack } from "@mantine/core"; +import { Box, Stack } from "@mantine/core"; import type { RouterOutputs } from "@homarr/api"; import { clientApi } from "@homarr/api/client"; @@ -10,8 +10,6 @@ import { useCurrentLayout, useRequiredBoard } from "@homarr/boards/context"; import { BoardCategorySection } from "~/components/board/sections/category-section"; import { BoardEmptySection } from "~/components/board/sections/empty-section"; import { BoardBackgroundVideo } from "~/components/layout/background"; -import { fullHeightWithoutHeaderAndFooter } from "~/constants"; -import { useIsBoardReady } from "./_ready-context"; let boardName: string | null = null; @@ -44,7 +42,6 @@ export const useUpdateBoard = () => { export const ClientBoard = () => { const board = useRequiredBoard(); const currentLayoutId = useCurrentLayout(); - const isReady = useIsBoardReady(); const fullWidthSortedSections = board.sections .filter((section) => section.kind === "empty" || section.kind === "category") @@ -55,13 +52,7 @@ export const ClientBoard = () => { return ( - - + {fullWidthSortedSections.map((section) => section.kind === "empty" ? ( // Unique keys per layout to always reinitialize the gridstack diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx index 64c9289e3..0ad398608 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_creator.tsx @@ -38,6 +38,7 @@ export const createBoardContentPage = >( layout: createBoardLayout({ headerActions: , getInitialBoardAsync: getInitialBoard, + withTour: true, }), // eslint-disable-next-line no-restricted-syntax page: async ({ params }: { params: Promise }) => { diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx index 18c0fe241..c76d29ea0 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx @@ -2,7 +2,8 @@ import { useCallback, useEffect } from "react"; import { useRouter } from "next/navigation"; -import { Group, Menu, ScrollArea } from "@mantine/core"; +import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; +import { Box, Group, Menu, ScrollArea } from "@mantine/core"; import { useHotkeys } from "@mantine/hooks"; import { IconBox, @@ -53,9 +54,11 @@ export const BoardContentHeaderActions = () => { - - - + + + + + @@ -173,9 +176,11 @@ const EditModeMenu = () => { usePreventLeaveWithDirty(isEditMode); return ( - - {isEditMode ? : } - + + + {isEditMode ? : } + + ); }; @@ -183,27 +188,31 @@ const SelectBoardsMenu = () => { const { data: boards = [] } = clientApi.board.getAllBoards.useQuery(); return ( - - - - - - - - - {boards.map((board) => ( - } - > - {board.name} - - ))} - - - + + + + + + + + + + + {boards.map((board) => ( + } + > + {board.name} + + ))} + + + + + ); }; diff --git a/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx b/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx index 972577ed7..3cddc6685 100644 --- a/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx +++ b/apps/nextjs/src/app/[locale]/boards/_layout-creator.tsx @@ -29,11 +29,13 @@ const BoardTourWrapper = ({ hasSession, children }: PropsWithChildren<{ hasSessi interface CreateBoardLayoutProps { headerActions: JSX.Element; getInitialBoardAsync: (params: TParams) => Promise; + withTour?: boolean; } export const createBoardLayout = ({ headerActions, getInitialBoardAsync: getInitialBoard, + withTour = false, }: CreateBoardLayoutProps) => { const Layout = async ({ params, @@ -67,7 +69,7 @@ export const createBoardLayout = ({ - + } diff --git a/apps/nextjs/src/components/onboarding/board-tour.tsx b/apps/nextjs/src/components/onboarding/board-tour.tsx index b7a9d76da..d7f5d2765 100644 --- a/apps/nextjs/src/components/onboarding/board-tour.tsx +++ b/apps/nextjs/src/components/onboarding/board-tour.tsx @@ -3,26 +3,35 @@ import type { PropsWithChildren } from "react"; import { useMemo } from "react"; import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; -import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; import { clientApi } from "@homarr/api/client"; import { useRequiredBoard } from "@homarr/boards/context"; +import { createDocumentationLink } from "@homarr/definitions"; import { useScopedI18n } from "@homarr/translation/client"; import { useBoardPermissions } from "~/components/board/permissions/client"; -import { SkipHoldButton } from "./skip-hold-button"; +import { TourShell } from "./tour-shell"; import { TourStepContent } from "./tour-step-content"; export const BoardTourProvider = ({ children }: PropsWithChildren) => { const t = useScopedI18n("onboardingTour.board"); const board = useRequiredBoard(); const { hasChangeAccess } = useBoardPermissions(board); + const utils = clientApi.useUtils(); const { data: tourStatus } = clientApi.user.getTourStatus.useQuery(); - const { mutate: completeTour } = clientApi.user.completeTour.useMutation(); + const { mutate: completeTour } = clientApi.user.completeTour.useMutation({ + onSuccess() { + void utils.user.getTourStatus.invalidate(); + }, + }); const started = tourStatus !== undefined && !tourStatus.completedBoardTour; const handleEnd = () => { + utils.user.getTourStatus.setData(undefined, { + completedManageTour: tourStatus?.completedManageTour ?? false, + completedBoardTour: true, + }); completeTour({ tour: "board" }); }; @@ -34,13 +43,12 @@ export const BoardTourProvider = ({ children }: PropsWithChildren) => { content: ( ), - footer: (controller: { skipTour: () => void }) => ( - controller.skipTour()} /> - ), }, { id: "board-edit-mode", @@ -49,8 +57,10 @@ export const BoardTourProvider = ({ children }: PropsWithChildren) => { content: ( ), }, @@ -59,39 +69,40 @@ export const BoardTourProvider = ({ children }: PropsWithChildren) => { title: t("settings.title"), requiresChangeAccess: true, content: ( - + ), }, { id: "board-switcher", title: t("switcher.title"), content: ( - + ), }, { id: "board-user-menu", title: t("userMenu.title"), content: ( - + ), }, ]; - return allSteps.filter( - (step) => !step.requiresChangeAccess || hasChangeAccess, - ) as OnboardingTourStep[]; + return allSteps.filter((step) => !step.requiresChangeAccess || hasChangeAccess) as OnboardingTourStep[]; }, [hasChangeAccess, t]); return ( - + {children} - + ); }; From 3da104256fc5c8ffd80e8bf0e4dec8ab7315bb98 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:43:00 +0200 Subject: [PATCH 10/11] feat(i18n): add onboarding tour copy for manage and board flows Add per-page management tour strings and update board tour descriptions. --- packages/translation/src/lang/en.json | 83 ++++++++++++--------------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 066c54098..cba1e31ff 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -4950,76 +4950,69 @@ } }, "onboardingTour": { - "skipHold": "Hold to skip — I know what I'm doing", - "learnMore": "Learn more in the docs", - "forkYes": "Yes, let's go!", - "forkNo": "Not now", + "learnMore": "Read the docs", + "next": "Next", + "prev": "Back", + "done": "Done", + "skip": "Skip tour", "manage": { "welcome": { - "title": "Welcome to Management", - "description": "This is the management area where you configure everything in Homarr — boards, apps, integrations, users, and server settings. Let's walk through what each section does." + "title": "Welcome to Homarr!", + "description": "This is your control center. From here you manage boards, apps, integrations, users, and server settings. Let's take a tour of each section." }, - "boards": { - "title": "Boards", - "description": "Boards are your dashboards. Each board has a unique name that becomes part of its URL. Boards can be public or private and support responsive layouts, background images, custom CSS, and per-user access control." + "boardsList": { + "title": "Your Boards", + "description": "Here are all your dashboards. Each board has its own layout, background, and access settings. You can see who created each one and whether it's public or private." }, - "apps": { - "title": "Apps", - "description": "Apps represent links to your services. Each app needs a name and icon (choose from 11K+ built-in icons). You can set a separate ping URL for health checks and add apps to boards as widgets or bookmarks." + "boardsCreate": { + "title": "Create a Board", + "description": "Click here to create a new dashboard or import one from a previous Homarr installation. Each board gets its own URL you can share." }, - "integrations": { - "title": "Integrations", - "description": "Integrations connect Homarr to third-party apps you run — like Sonarr, Radarr, Plex, and 50+ more. Secrets are encrypted and never exposed to the client. Connections are validated before saving." + "appsList": { + "title": "Your Apps", + "description": "These are all the apps you've added — links to your self-hosted services. Each app has an icon, optional health check, and a status badge on the dashboard." }, - "integrationsFork": { - "title": "Try it now?", - "question": "Would you like to add your first integration?" + "appsCreate": { + "title": "Add an App", + "description": "Register a new service here. Give it a name, URL, and icon — it will appear as a tile on your boards with live status monitoring." }, - "searchEngines": { - "title": "Search Engines", - "description": "Configure custom search providers accessible via the search bar or Ctrl+K. Define a name, shortcut prefix, and URL template. Supports integration-based search for apps like Jellyseerr and Overseerr." + "integrationsList": { + "title": "Your Integrations", + "description": "These are the services connected to Homarr — Sonarr, Radarr, Plex, Jellyfin, and 50+ more. All credentials are encrypted at rest." }, - "medias": { - "title": "Media", - "description": "Upload custom images for app icons or board branding. Media is stored in the database and available in the icon picker when creating apps." + "integrationsCreate": { + "title": "Add an Integration", + "description": "Connect a new service here. Pick the type, enter the URL and API key — Homarr validates the connection before saving." }, - "users": { - "title": "Users & Groups", - "description": "Manage users, groups, and permissions. Users can belong to multiple groups. Groups control board access, integration permissions, and admin privileges. You can also create invite links for self-onboarding." + "usersList": { + "title": "Your Users", + "description": "See everyone who has access. Organize users into groups and control who can view or edit each board." }, - "usersFork": { - "title": "Try it now?", - "question": "Would you like to create a new user?" - }, - "settings": { - "title": "Server Settings", - "description": "Configure global defaults — analytics, SEO/crawling directives, default home boards, color scheme, language, and app status behavior. These apply across the entire Homarr instance." - }, - "complete": { - "title": "You're all set!", - "description": "You've seen everything in the management area. Next, head to your board to start adding apps and widgets, or explore the docs for advanced topics like the API, certificates, and background tasks." + "usersCreate": { + "title": "Create a User", + "description": "Add a new user account here. You can also use invite links for easy onboarding. That's the tour — you're all set!" } }, "board": { "welcome": { - "title": "Welcome to your Board", - "description": "This is your dashboard — a drag-and-drop canvas where you organize apps and widgets. Use the search bar or Ctrl+K to quickly find apps, integrations, boards, and actions." + "title": "This is your board", + "description": "A drag-and-drop dashboard where you arrange apps and widgets. Press Ctrl+K anytime to search for apps, boards, and actions." }, "editMode": { "title": "Edit Mode", - "description": "Toggle edit mode to add, move, and resize items. In edit mode you can add widgets, apps, categories, and dynamic sections. Drag items to reposition, use the corner handle to resize. Don't forget to exit edit mode to save!" + "description": "Click here to enter edit mode. You can then add widgets, apps, and sections — drag to reposition, resize with the corner handle. Click again to save your changes." }, "settings": { "title": "Board Settings", - "description": "Customize this board's name, layout columns, background image, colors, custom CSS, and access control. You can set boards as public or private and control who can view or modify them." + "description": "Change this board's name, columns, background, colors, and who can access it. Each board can be public or private." }, "switcher": { - "title": "Board Switcher", - "description": "Switch between your boards. You can create multiple boards for different purposes — one for media, one for networking, or one per user." + "title": "Switch Boards", + "description": "Jump between boards. Create separate dashboards for different purposes — media, networking, per-user, or anything you like." }, "userMenu": { "title": "Your Profile", - "description": "Quick access to your preferences — change color scheme, language, home board, and search settings. You can also navigate to the management area from here." + "description": "Change your color scheme, language, home board, and preferences. You can also jump to the management area from here." } } } From 1220fbf6adb7987ef6b3df6f42de404fb41e3706 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Wed, 20 May 2026 09:55:41 +0200 Subject: [PATCH 11/11] fix(onboarding): resolve tour shell and manage tour type errors Use OnboardingTourController and guard optional step index. Type users step focus reveal props for FloatingPosition compatibility. --- .../src/components/onboarding/manage-tour.tsx | 4 ++-- .../src/components/onboarding/tour-shell.tsx | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/apps/nextjs/src/components/onboarding/manage-tour.tsx b/apps/nextjs/src/components/onboarding/manage-tour.tsx index 361a183dd..70ca61084 100644 --- a/apps/nextjs/src/components/onboarding/manage-tour.tsx +++ b/apps/nextjs/src/components/onboarding/manage-tour.tsx @@ -3,7 +3,7 @@ import type { PropsWithChildren } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { usePathname, useRouter } from "next/navigation"; -import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; +import type { OnboardingTourFocusRevealProps, OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; import { useMediaQuery } from "@mantine/hooks"; import { IconAffiliateFilled, @@ -36,7 +36,7 @@ const stepRoutes: Record = { "manage-users-create": "/manage/users", }; -const usersStepFocusRevealProps = { +const usersStepFocusRevealProps: OnboardingTourFocusRevealProps = { withReveal: false, popoverProps: { position: "bottom", diff --git a/apps/nextjs/src/components/onboarding/tour-shell.tsx b/apps/nextjs/src/components/onboarding/tour-shell.tsx index 702c28634..5387c2176 100644 --- a/apps/nextjs/src/components/onboarding/tour-shell.tsx +++ b/apps/nextjs/src/components/onboarding/tour-shell.tsx @@ -3,7 +3,7 @@ import type { PropsWithChildren } from "react"; import { useCallback, useEffect, useRef } from "react"; import { useRouter } from "next/navigation"; -import type { OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; +import type { OnboardingTourController, OnboardingTourStep } from "@gfazioli/mantine-onboarding-tour"; import { OnboardingTour } from "@gfazioli/mantine-onboarding-tour"; import { Button, Center, Group, Image, Kbd, Text } from "@mantine/core"; import type { FloatingPosition } from "@mantine/core"; @@ -20,7 +20,14 @@ interface TourShellProps extends PropsWithChildren { position?: FloatingPosition | Record; } -type TourController = Parameters["nextStepNavigation"]>>[0]; +type TourController = OnboardingTourController; + +const stepIndexFromController = (controller: TourController) => controller.currentStepIndex ?? 0; + +const stepAtOffset = (controller: TourController, offset: number) => { + const index = stepIndexFromController(controller) + offset; + return controller.tour[index]; +}; const pollForElement = (targetId: string, callback: () => void) => { const interval = setInterval(() => { @@ -126,7 +133,7 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre <> - {(controller.currentStepIndex ?? 0) + 1} + {stepIndexFromController(controller) + 1} / @@ -135,7 +142,7 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre {controller.tour.length} - {controller.currentStepIndex === 0 && ( + {stepIndexFromController(controller) === 0 && (
Homarr
@@ -143,7 +150,7 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre )} nextStepNavigation={(controller) => { - const nextStep = controller.tour[controller.currentStepIndex + 1]; + const nextStep = stepAtOffset(controller, 1); const action = bindForwardAction(controller, () => { navigateAndAdvance(controller.currentStep?.id, nextStep?.id, () => controller.nextStep()); }); @@ -158,7 +165,7 @@ export const TourShell = ({ steps, started, onEnd, stepRoutes, position, childre size="sm" variant="default" onClick={() => { - const prevStep = controller.tour[controller.currentStepIndex - 1]; + const prevStep = stepAtOffset(controller, -1); navigateAndAdvance(controller.currentStep?.id, prevStep?.id, () => controller.prevStep()); }} >