From 036925bf78ec50afe8455efdc270ee4e503a0e03 Mon Sep 17 00:00:00 2001 From: Meier Lukas Date: Mon, 29 Apr 2024 21:46:30 +0200 Subject: [PATCH] feat: add user groups (#376) * feat: add user groups * wip: add unit tests * wip: add more tests and normalized name for creation and update * test: add unit tests for group router * fix: type issues, missing mysql schema, rename column creator_id to owner_id * fix: lint and format issues * fix: deepsource issues * fix: forgot to add log message * fix: build not working * chore: address pull request feedback * feat: add mysql migration and fix merge conflicts * fix: format issue and test issue --- .../boards/[name]/settings/_access.tsx | 35 +- .../nextjs/src/app/[locale]/manage/layout.tsx | 6 + .../users/groups/[id]/_delete-group.tsx | 80 +++ .../manage/users/groups/[id]/_navigation.tsx | 26 + .../users/groups/[id]/_rename-group-form.tsx | 83 +++ .../groups/[id]/_transfer-group-ownership.tsx | 95 +++ .../manage/users/groups/[id]/layout.tsx | 76 ++ .../groups/[id]/members/_add-group-member.tsx | 51 ++ .../[id]/members/_remove-group-member.tsx | 59 ++ .../manage/users/groups/[id]/members/page.tsx | 99 +++ .../manage/users/groups/[id]/page.tsx | 75 ++ .../permissions/_group-permission-form.tsx | 131 ++++ .../users/groups/[id]/permissions/page.tsx | 129 ++++ .../manage/users/groups/_add-group.tsx | 81 +++ .../app/[locale]/manage/users/groups/page.tsx | 102 +++ package.json | 3 +- packages/api/src/root.ts | 2 + packages/api/src/router/group.ts | 232 ++++++ packages/api/src/router/test/group.spec.ts | 664 ++++++++++++++++++ packages/db/migrate.ts | 2 +- .../db/migrations/0001_sparkling_zaran.sql | 9 - packages/db/migrations/meta/_journal.json | 20 - .../migrations/mysql/0000_chubby_darkhawk.sql | 168 +++++ .../{ => mysql}/meta/0000_snapshot.json | 362 ++++++++-- .../db/migrations/mysql/meta/_journal.json | 13 + .../0000_abnormal_kree.sql} | 30 + .../meta/0000_snapshot.json} | 124 +++- .../db/migrations/sqlite/meta/_journal.json | 13 + packages/db/mysql.config.ts | 17 + packages/db/package.json | 3 +- packages/db/schema/mysql.ts | 65 ++ packages/db/schema/sqlite.ts | 65 ++ .../{drizzle.config.ts => sqlite.config.ts} | 2 +- packages/db/test/db-mock.ts | 2 +- packages/definitions/src/permissions.ts | 66 ++ packages/modals/src/confirm-modal.tsx | 12 +- packages/translation/src/client.ts | 4 +- packages/translation/src/lang/en.ts | 187 ++++- packages/translation/src/server.ts | 4 +- packages/ui/package.json | 3 + packages/ui/src/components/index.tsx | 4 + packages/ui/src/components/search-input.tsx | 59 ++ .../ui/src/components/table-pagination.tsx | 80 +++ .../ui/src/components/user-avatar-group.tsx | 48 ++ packages/ui/src/components/user-avatar.tsx | 28 + packages/validation/src/group.ts | 37 + packages/validation/src/index.ts | 2 + pnpm-lock.yaml | 4 + scripts/docker-run.cmd | 1 + scripts/run.sh | 2 +- 50 files changed, 3333 insertions(+), 132 deletions(-) create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/_delete-group.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/_navigation.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/_rename-group-form.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/_transfer-group-ownership.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/layout.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/members/_add-group-member.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/members/_remove-group-member.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/members/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/permissions/_group-permission-form.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/[id]/permissions/page.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/_add-group.tsx create mode 100644 apps/nextjs/src/app/[locale]/manage/users/groups/page.tsx create mode 100644 packages/api/src/router/group.ts create mode 100644 packages/api/src/router/test/group.spec.ts delete mode 100644 packages/db/migrations/0001_sparkling_zaran.sql delete mode 100644 packages/db/migrations/meta/_journal.json create mode 100644 packages/db/migrations/mysql/0000_chubby_darkhawk.sql rename packages/db/migrations/{ => mysql}/meta/0000_snapshot.json (70%) create mode 100644 packages/db/migrations/mysql/meta/_journal.json rename packages/db/migrations/{0000_productive_changeling.sql => sqlite/0000_abnormal_kree.sql} (79%) rename packages/db/migrations/{meta/0001_snapshot.json => sqlite/meta/0000_snapshot.json} (87%) create mode 100644 packages/db/migrations/sqlite/meta/_journal.json create mode 100644 packages/db/mysql.config.ts rename packages/db/{drizzle.config.ts => sqlite.config.ts} (89%) create mode 100644 packages/ui/src/components/search-input.tsx create mode 100644 packages/ui/src/components/table-pagination.tsx create mode 100644 packages/ui/src/components/user-avatar-group.tsx create mode 100644 packages/ui/src/components/user-avatar.tsx create mode 100644 packages/validation/src/group.ts create mode 100644 scripts/docker-run.cmd diff --git a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx index 1874d43eb..46a18d881 100644 --- a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx +++ b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_access.tsx @@ -1,11 +1,12 @@ "use client"; -import { useCallback } from "react"; +import { useCallback, useState } from "react"; import type { SelectProps } from "@mantine/core"; import { Button, Flex, Group, + Loader, Select, Stack, Table, @@ -241,7 +242,8 @@ interface FormType { interface InnerProps { presentUserIds: string[]; - onSelect: (props: { id: string; name: string }) => void; + onSelect: (props: { id: string; name: string }) => void | Promise; + confirmLabel?: string; } interface UserSelectFormType { @@ -251,40 +253,45 @@ interface UserSelectFormType { export const UserSelectModal = createModal( ({ actions, innerProps }) => { const t = useI18n(); - const { data: users } = clientApi.user.selectable.useQuery(); + const { data: users, isPending } = clientApi.user.selectable.useQuery(); + const [loading, setLoading] = useState(false); const form = useForm(); - const handleSubmit = (values: UserSelectFormType) => { + const handleSubmit = async (values: UserSelectFormType) => { const currentUser = users?.find((user) => user.id === values.userId); if (!currentUser) return; - innerProps.onSelect({ + setLoading(true); + await innerProps.onSelect({ id: currentUser.id, name: currentUser.name ?? "", }); + + setLoading(false); actions.closeModal(); }; + const confirmLabel = innerProps.confirmLabel ?? t("common.action.add"); + return ( -
+ void handleSubmit(values))}>