@burdenoff/microfe-organization 2026.1026.1 → 2026.1101.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generated/global-operations.js +57 -58
- package/dist/generated/global-operations.js.map +1 -1
- package/dist/generated/global-types.js +1 -2
- package/dist/generated/global-types.js.map +1 -1
- package/dist/node_modules/sonner/dist/index.js +2 -3
- package/dist/node_modules/sonner/dist/index.js.map +1 -1
- package/dist/node_modules/zod/v4/classic/errors.js +44 -0
- package/dist/node_modules/zod/v4/classic/errors.js.map +1 -0
- package/dist/node_modules/zod/v4/classic/parse.js +7 -0
- package/dist/node_modules/zod/v4/classic/parse.js.map +1 -0
- package/dist/node_modules/zod/v4/classic/schemas.js +652 -0
- package/dist/node_modules/zod/v4/classic/schemas.js.map +1 -0
- package/dist/node_modules/zod/v4/core/api.js +429 -0
- package/dist/node_modules/zod/v4/core/api.js.map +1 -0
- package/dist/node_modules/zod/v4/core/checks.js +143 -0
- package/dist/node_modules/zod/v4/core/checks.js.map +1 -0
- package/dist/node_modules/zod/v4/core/core.js +84 -0
- package/dist/node_modules/zod/v4/core/core.js.map +1 -0
- package/dist/node_modules/zod/v4/core/doc.js +29 -0
- package/dist/node_modules/zod/v4/core/doc.js.map +1 -0
- package/dist/node_modules/zod/v4/core/errors.js +90 -0
- package/dist/node_modules/zod/v4/core/errors.js.map +1 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.js +285 -0
- package/dist/node_modules/zod/v4/core/json-schema-processors.js.map +1 -0
- package/dist/node_modules/zod/v4/core/memoizer.js +188 -0
- package/dist/node_modules/zod/v4/core/memoizer.js.map +1 -0
- package/dist/node_modules/zod/v4/core/parse.js +159 -0
- package/dist/node_modules/zod/v4/core/parse.js.map +1 -0
- package/dist/node_modules/zod/v4/core/regexes.js +34 -0
- package/dist/node_modules/zod/v4/core/regexes.js.map +1 -0
- package/dist/node_modules/zod/v4/core/registries.js +41 -0
- package/dist/node_modules/zod/v4/core/registries.js.map +1 -0
- package/dist/node_modules/zod/v4/core/schemas.js +979 -0
- package/dist/node_modules/zod/v4/core/schemas.js.map +1 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.js +330 -0
- package/dist/node_modules/zod/v4/core/to-json-schema.js.map +1 -0
- package/dist/node_modules/zod/v4/core/util.js +417 -0
- package/dist/node_modules/zod/v4/core/util.js.map +1 -0
- package/dist/node_modules/zod/v4/core/versions.js +9 -0
- package/dist/node_modules/zod/v4/core/versions.js.map +1 -0
- package/dist/node_modules/zod/v4/locales/en.js +96 -0
- package/dist/node_modules/zod/v4/locales/en.js.map +1 -0
- package/dist/organization-management/AdminOrganizationRoot.js +13 -10
- package/dist/organization-management/AdminOrganizationRoot.js.map +1 -1
- package/dist/organization-management/AdminOrganizationRoutes.js +8 -9
- package/dist/organization-management/AdminOrganizationRoutes.js.map +1 -1
- package/dist/organization-management/UserOrganizationRoot.js +13 -10
- package/dist/organization-management/UserOrganizationRoot.js.map +1 -1
- package/dist/organization-management/UserOrganizationRoutes.js +1 -2
- package/dist/organization-management/UserOrganizationRoutes.js.map +1 -1
- package/dist/organization-management/constants/permissions.js +1 -2
- package/dist/organization-management/constants/permissions.js.map +1 -1
- package/dist/organization-management/hooks/useOrganizationEventEmitter.js +1 -2
- package/dist/organization-management/hooks/useOrganizationEventEmitter.js.map +1 -1
- package/dist/organization-management/hooks/useOrganizationPageView.js +1 -2
- package/dist/organization-management/hooks/useOrganizationPageView.js.map +1 -1
- package/dist/organization-management/modules/members/components/BulkInviteForm.js +3 -3
- package/dist/organization-management/modules/members/components/BulkInviteForm.js.map +1 -1
- package/dist/organization-management/modules/members/components/InviteMemberForm.js +1 -2
- package/dist/organization-management/modules/members/components/InviteMemberForm.js.map +1 -1
- package/dist/organization-management/modules/members/components/InviteStatusBadge.js +1 -2
- package/dist/organization-management/modules/members/components/InviteStatusBadge.js.map +1 -1
- package/dist/organization-management/modules/members/components/MemberRoleBadge.js +1 -2
- package/dist/organization-management/modules/members/components/MemberRoleBadge.js.map +1 -1
- package/dist/organization-management/modules/members/components/MyInviteCard.js +5 -6
- package/dist/organization-management/modules/members/components/MyInviteCard.js.map +1 -1
- package/dist/organization-management/modules/members/components/PendingInvitesList.js +8 -9
- package/dist/organization-management/modules/members/components/PendingInvitesList.js.map +1 -1
- package/dist/organization-management/modules/members/hooks/useInvites.js +2 -3
- package/dist/organization-management/modules/members/hooks/useInvites.js.map +1 -1
- package/dist/organization-management/modules/members/hooks/useMembers.js +1 -2
- package/dist/organization-management/modules/members/hooks/useMembers.js.map +1 -1
- package/dist/organization-management/modules/members/hooks/useWorkspaceInvites.js +1 -2
- package/dist/organization-management/modules/members/hooks/useWorkspaceInvites.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js +16 -17
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +14 -15
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js +18 -19
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MembersListPage.js +142 -143
- package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js +168 -169
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +13 -14
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
- package/dist/organization-management/modules/members/utils/bulkInviteCsv.js +4 -10
- package/dist/organization-management/modules/members/utils/bulkInviteCsv.js.map +1 -1
- package/dist/organization-management/modules/members/utils/workspaceInvitationDisplay.js +1 -2
- package/dist/organization-management/modules/members/utils/workspaceInvitationDisplay.js.map +1 -1
- package/dist/organization-management/modules/organizations/components/OrganizationForm.js +14 -15
- package/dist/organization-management/modules/organizations/components/OrganizationForm.js.map +1 -1
- package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js +1 -2
- package/dist/organization-management/modules/organizations/components/OrganizationStatusBadge.js.map +1 -1
- package/dist/organization-management/modules/organizations/hooks/useOrganizations.js +2 -3
- package/dist/organization-management/modules/organizations/hooks/useOrganizations.js.map +1 -1
- package/dist/organization-management/modules/organizations/hooks/useOrgsWithPermission.js +22 -21
- package/dist/organization-management/modules/organizations/hooks/useOrgsWithPermission.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +18 -19
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +29 -30
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +14 -15
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +33 -34
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/schemas/index.js +11 -12
- package/dist/organization-management/modules/organizations/schemas/index.js.map +1 -1
- package/dist/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.js +16 -24
- package/dist/organization-management/modules/workspaces/components/AddWorkspaceMemberDialog.js.map +1 -1
- package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js +5 -6
- package/dist/organization-management/modules/workspaces/components/WorkspaceCard.js.map +1 -1
- package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js +31 -32
- package/dist/organization-management/modules/workspaces/components/WorkspaceForm.js.map +1 -1
- package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js +1 -2
- package/dist/organization-management/modules/workspaces/components/WorkspaceStatusBadge.js.map +1 -1
- package/dist/organization-management/modules/workspaces/hooks/useWorkspaceMembers.js +1 -2
- package/dist/organization-management/modules/workspaces/hooks/useWorkspaceMembers.js.map +1 -1
- package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js +11 -12
- package/dist/organization-management/modules/workspaces/hooks/useWorkspaces.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +18 -19
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +43 -44
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +19 -20
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +240 -241
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/schemas/index.js +6 -7
- package/dist/organization-management/modules/workspaces/schemas/index.js.map +1 -1
- package/dist/organization-management/providers/OrgConsoleProvider.js +1 -2
- package/dist/organization-management/providers/OrgConsoleProvider.js.map +1 -1
- package/dist/organization-management/providers/OrgScopedPermissions.js +1 -2
- package/dist/organization-management/providers/OrgScopedPermissions.js.map +1 -1
- package/dist/organization-management/shared/components/dialog/ConfirmDialog.js +1 -2
- package/dist/organization-management/shared/components/dialog/ConfirmDialog.js.map +1 -1
- package/dist/organization-management/shared/components/dialog/ConfirmDialogView.js +1 -2
- package/dist/organization-management/shared/components/dialog/ConfirmDialogView.js.map +1 -1
- package/dist/organization-management/shared/components/feedback/ErrorState.js +1 -2
- package/dist/organization-management/shared/components/feedback/ErrorState.js.map +1 -1
- package/dist/organization-management/shared/components/feedback/LoadingState.js +1 -2
- package/dist/organization-management/shared/components/feedback/LoadingState.js.map +1 -1
- package/dist/organization-management/shared/components/input/SearchInput.js +1 -2
- package/dist/organization-management/shared/components/input/SearchInput.js.map +1 -1
- package/dist/organization-management/shared/components/input/SelectionCheckbox.js +1 -2
- package/dist/organization-management/shared/components/input/SelectionCheckbox.js.map +1 -1
- package/dist/organization-management/shared/hooks/useDebouncedValue.js +1 -2
- package/dist/organization-management/shared/hooks/useDebouncedValue.js.map +1 -1
- package/dist/organization-management/shared/hooks/useTr.js +1 -2
- package/dist/organization-management/shared/hooks/useTr.js.map +1 -1
- package/dist/organization-management/shared/logger.js +1 -2
- package/dist/organization-management/shared/logger.js.map +1 -1
- package/dist/organization-management/shared/recaptcha.js +1 -2
- package/dist/organization-management/shared/recaptcha.js.map +1 -1
- package/dist/organization-management/shared/types/graphql.js +1 -2
- package/dist/organization-management/shared/types/graphql.js.map +1 -1
- package/dist/utils/nativeBridge.js +1 -2
- package/package.json +8 -6
- package/dist/node_modules/zod/v3/ZodError.js +0 -82
- package/dist/node_modules/zod/v3/ZodError.js.map +0 -1
- package/dist/node_modules/zod/v3/errors.js +0 -10
- package/dist/node_modules/zod/v3/errors.js.map +0 -1
- package/dist/node_modules/zod/v3/helpers/errorUtil.js +0 -9
- package/dist/node_modules/zod/v3/helpers/errorUtil.js.map +0 -1
- package/dist/node_modules/zod/v3/helpers/parseUtil.js +0 -93
- package/dist/node_modules/zod/v3/helpers/parseUtil.js.map +0 -1
- package/dist/node_modules/zod/v3/helpers/util.js +0 -76
- package/dist/node_modules/zod/v3/helpers/util.js.map +0 -1
- package/dist/node_modules/zod/v3/locales/en.js +0 -62
- package/dist/node_modules/zod/v3/locales/en.js.map +0 -1
- package/dist/node_modules/zod/v3/types.js +0 -2441
- package/dist/node_modules/zod/v3/types.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspacesListPage.js","names":[],"sources":["../../../../../src/organization-management/modules/workspaces/pages/WorkspacesListPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Eye, Plus, RefreshCw, SquarePen, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useDeleteWorkspace, useWorkspaces } from '../hooks/useWorkspaces';\nimport { WorkspaceStatusBadge } from '../components/WorkspaceStatusBadge';\nimport { SearchInput } from '../../../shared/components/input/SearchInput';\nimport { SelectionCheckbox } from '../../../shared/components/input/SelectionCheckbox';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { useDebouncedValue } from '../../../shared/hooks/useDebouncedValue';\nimport { useConfirmDialog } from '../../../shared/components/dialog/ConfirmDialog';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport type { WorkspaceFilterInput } from '../types';\nimport { WorkspaceStatus } from '../types';\nimport {\n isNative,\n nativeConfirm,\n nativeImpact,\n nativeNotify,\n nativeToast,\n} from '../../../../utils/nativeBridge';\n\nfunction formatDate(date: string) {\n return new Date(date).toLocaleDateString();\n}\n\n/**\n * `mode` controls the scope of the listing:\n * - `'my'` — membership-scoped (`myWorkspaces`); the default for user-facing\n * app shells. A regular user only sees workspaces they belong to.\n * - `'admin'` — platform-wide (`allWorkspaces`, super-admin only); the admin app.\n */\nexport interface WorkspacesListPageProps {\n mode?: 'my' | 'admin';\n}\n\nexport function WorkspacesListPage({ mode = 'my' }: WorkspacesListPageProps = {}) {\n const tr = useTr();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const [searchQuery, setSearchQuery] = useState('');\n const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);\n const [filter, setFilter] = useState<WorkspaceFilterInput>({});\n const [selectedWorkspaceIds, setSelectedWorkspaceIds] = useState<Set<string>>(new Set());\n const { openConfirmDialog, ConfirmDialog } = useConfirmDialog();\n\n // 'my' shells call the self-scoped `myWorkspaces` (no server-side filter arg),\n // so we over-fetch a page and filter client-side below. The admin app keeps\n // the server-filtered, paginated `allWorkspaces`.\n const scope = mode === 'admin' ? 'all' : 'my';\n const {\n workspaces: fetchedWorkspaces,\n loading,\n error,\n refetch,\n } = useWorkspaces(\n { ...filter, search: debouncedSearchQuery || undefined },\n scope === 'my' ? 100 : 20,\n 0,\n scope\n );\n\n const workspaces = useMemo(() => {\n if (scope !== 'my') return fetchedWorkspaces;\n const query = debouncedSearchQuery.trim().toLowerCase();\n return fetchedWorkspaces.filter((workspace) => {\n const matchesSearch =\n !query ||\n workspace.name.toLowerCase().includes(query) ||\n (workspace.slug?.toLowerCase().includes(query) ?? false);\n const matchesStatus = !filter.status || workspace.status === filter.status;\n return matchesSearch && matchesStatus;\n });\n }, [fetchedWorkspaces, scope, debouncedSearchQuery, filter.status]);\n\n const { deleteWorkspace, loading: deleteLoading } = useDeleteWorkspace();\n\n useEffect(() => {\n setSelectedWorkspaceIds((previousSelection) => {\n const visibleIds = new Set(workspaces.map((workspace) => workspace.id));\n const nextSelection = new Set(\n [...previousSelection].filter((workspaceId) => visibleIds.has(workspaceId))\n );\n\n if (nextSelection.size === previousSelection.size) {\n return previousSelection;\n }\n\n return nextSelection;\n });\n }, [workspaces]);\n\n const selectedWorkspaces = useMemo(\n () => workspaces.filter((workspace) => selectedWorkspaceIds.has(workspace.id)),\n [selectedWorkspaceIds, workspaces]\n );\n\n const allVisibleSelected =\n workspaces.length > 0 &&\n workspaces.every((workspace) => selectedWorkspaceIds.has(workspace.id));\n const partiallySelected =\n workspaces.some((workspace) => selectedWorkspaceIds.has(workspace.id)) && !allVisibleSelected;\n\n const executeSuspend = async (workspaceIds: string[]) => {\n try {\n const results = await Promise.allSettled(\n workspaceIds.map(async (workspaceId) => {\n const result = await deleteWorkspace(workspaceId);\n if (result.errors?.length) {\n throw new Error(\n result.errors[0]?.message ??\n tr('workspaces.suspend.failed', 'Failed to suspend workspace')\n );\n }\n })\n );\n\n const rejectedResult = results.find((result) => result.status === 'rejected');\n if (rejectedResult?.status === 'rejected') {\n throw rejectedResult.reason;\n }\n\n setSelectedWorkspaceIds(new Set());\n await refetch();\n const successMsg =\n workspaceIds.length === 1\n ? tr('workspaces.suspend.successSingle', 'Workspace suspended successfully')\n : `${workspaceIds.length} ${tr('workspaces.suspend.successMany', 'workspaces suspended successfully')}`;\n toast.success(successMsg);\n void nativeNotify('success');\n if (isNative()) void nativeToast(successMsg);\n } catch (suspendError) {\n const errorMsg =\n suspendError instanceof Error\n ? suspendError.message\n : tr('workspaces.suspend.failed', 'Failed to suspend workspace');\n toast.error(errorMsg);\n void nativeNotify('error');\n if (isNative()) void nativeToast(errorMsg);\n }\n };\n\n const handleDelete = (workspaceId: string, workspaceName: string) => {\n nativeImpact('medium');\n const title = tr('workspaces.suspend.title', 'Suspend workspace');\n const description = `${tr('workspaces.suspend.prefix', 'Suspend')} ${workspaceName}? ${tr(\n 'workspaces.suspend.suffix',\n 'Workspace members will lose access until it is reactivated.'\n )}`;\n void nativeConfirm({\n title,\n message: description,\n okButtonTitle: tr('workspaces.suspend.confirm', 'Suspend'),\n }).then((nativeResult) => {\n if (nativeResult === null) {\n openConfirmDialog({\n title,\n description,\n confirmText: tr('workspaces.suspend.confirm', 'Suspend'),\n variant: 'warning',\n onConfirm: () => {\n void executeSuspend([workspaceId]);\n },\n });\n } else if (nativeResult) {\n void executeSuspend([workspaceId]);\n }\n });\n };\n\n const handleBulkDelete = () => {\n if (selectedWorkspaces.length === 0) return;\n\n openConfirmDialog({\n title: tr('workspaces.suspend.bulkTitle', 'Suspend selected workspaces'),\n description: `${tr('workspaces.suspend.prefix', 'Suspend')} ${selectedWorkspaces.length} ${tr(\n selectedWorkspaces.length === 1\n ? 'workspaces.suspend.bulkSuffixSingle'\n : 'workspaces.suspend.bulkSuffixMany',\n selectedWorkspaces.length === 1 ? 'selected workspace?' : 'selected workspaces?'\n )}`,\n confirmText: `${tr('workspaces.suspend.confirm', 'Suspend')} ${selectedWorkspaces.length}`,\n variant: 'warning',\n onConfirm: () => {\n void executeSuspend(selectedWorkspaces.map((workspace) => workspace.id));\n },\n });\n };\n\n const toggleWorkspaceSelection = (workspaceId: string, checked: boolean) => {\n setSelectedWorkspaceIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n if (checked) {\n nextSelection.add(workspaceId);\n } else {\n nextSelection.delete(workspaceId);\n }\n return nextSelection;\n });\n };\n\n const toggleAllWorkspaces = (checked: boolean) => {\n setSelectedWorkspaceIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n workspaces.forEach((workspace) => {\n if (checked) {\n nextSelection.add(workspace.id);\n } else {\n nextSelection.delete(workspace.id);\n }\n });\n return nextSelection;\n });\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.WORKSPACE_LIST)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.noPermission', \"You don't have permission to view workspaces.\")}\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('workspaces.list.loading', 'Loading workspaces...')} />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetch();\n },\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n {tr('workspaces.list.title', 'Workspaces')}\n </h1>\n <p className=\"max-w-2xl text-[var(--color-text-secondary)]\">\n {tr(\n 'workspaces.list.subtitle',\n 'Manage organization workspaces, review their status, and open the workspace detail flow.'\n )}\n </p>\n <PagePurpose className=\"max-w-2xl\">\n {tr(\n 'workspaces.list.purpose',\n 'A workspace is where a team actually does its work — it holds the members, settings, and collaboration for one project or department. Create a workspace to give a group its own space, add the right people, and keep its status (active, inactive, archived) under control.'\n )}\n </PagePurpose>\n </div>\n\n {hasPermission(PERMISSIONS.WORKSPACE_CREATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/new`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <Plus size={18} aria-hidden=\"true\" />\n <span className=\"font-medium\">\n {tr('workspaces.create.button', 'Create Workspace')}\n </span>\n </button>\n )}\n </div>\n\n {fetchedWorkspaces.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('workspaces.list.title', 'Workspaces')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {fetchedWorkspaces.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('workspaces.status.active', 'Active')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {fetchedWorkspaces.filter((w) => w.status === WorkspaceStatus.ACTIVE).length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"col-span-2 p-4 sm:col-span-1\">\n <p className=\"text-sm text-text-secondary\">\n {tr('workspaces.list.members', 'Members')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {fetchedWorkspaces.reduce((sum, w) => sum + (w.memberCount ?? 0), 0)}\n </p>\n </GlassCard>\n </div>\n ) : null}\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('workspaces.list.searchPlaceholder', 'Search workspaces...')}\n label={tr('workspaces.list.searchLabel', 'Search workspaces')}\n inputId=\"workspaces-search\"\n className=\"flex-1\"\n />\n\n <label className=\"flex min-h-11 min-w-[180px] flex-col justify-center rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-3 py-2 text-sm text-[var(--color-text-secondary)]\">\n <span className=\"sr-only\">\n {tr('workspaces.list.filterByStatus', 'Filter by workspace status')}\n </span>\n <select\n value={filter.status || ''}\n onChange={(event) =>\n setFilter({\n ...filter,\n status: event.target.value\n ? (event.target.value as WorkspaceStatus)\n : undefined,\n })\n }\n className=\"bg-transparent text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n aria-label={tr('workspaces.list.filterByStatus', 'Filter by workspace status')}\n >\n <option value=\"\">{tr('workspaces.list.allStatuses', 'All statuses')}</option>\n <option value={WorkspaceStatus.ACTIVE}>\n {tr('workspaces.status.active', 'Active')}\n </option>\n <option value={WorkspaceStatus.INACTIVE}>\n {tr('workspaces.status.inactive', 'Inactive')}\n </option>\n <option value={WorkspaceStatus.ARCHIVED}>\n {tr('workspaces.status.archived', 'Archived')}\n </option>\n </select>\n </label>\n\n <button\n type=\"button\"\n onClick={() => {\n void refetch();\n }}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-4 py-2 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n aria-label={tr('workspaces.list.refresh', 'Refresh workspaces')}\n title={tr('workspaces.list.refresh', 'Refresh workspaces')}\n >\n <RefreshCw size={18} aria-hidden=\"true\" />\n </button>\n </div>\n\n {workspaces.length > 0 ? (\n <div className=\"mt-4 flex flex-col gap-3 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-[var(--color-text-primary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllWorkspaces}\n ariaLabel={tr('workspaces.list.selectAll', 'Select all workspaces')}\n />\n <span>{tr('common.selectAllVisible', 'Select all visible')}</span>\n </label>\n\n {selectedWorkspaceIds.size > 0 ? (\n <button\n type=\"button\"\n onClick={() => setSelectedWorkspaceIds(new Set())}\n className=\"text-sm text-[var(--color-text-secondary)] transition-colors hover:text-[var(--color-text-primary)]\"\n >\n {tr('common.clearSelection', 'Clear selection')}\n </button>\n ) : null}\n </div>\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <span className=\"text-sm text-[var(--color-text-secondary)]\">\n {selectedWorkspaceIds.size} {tr('common.selected', 'selected')}\n </span>\n {hasPermission(PERMISSIONS.WORKSPACE_DELETE) && (\n <button\n type=\"button\"\n onClick={handleBulkDelete}\n disabled={selectedWorkspaces.length === 0 || deleteLoading}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-status-warning-border)] px-3 py-2 text-[var(--color-status-warning-text)] transition-all duration-200 hover:bg-[var(--color-status-warning-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.list.suspendSelected', 'Suspend Selected')}</span>\n {selectedWorkspaces.length > 0 ? (\n <span>({selectedWorkspaces.length})</span>\n ) : null}\n </button>\n )}\n </div>\n </div>\n ) : null}\n </GlassCard>\n\n {workspaces.length === 0 ? (\n <GlassCard\n treatment=\"glass\"\n glow={fetchedWorkspaces.length === 0}\n className=\"border-border-seam p-6\"\n >\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tr('workspaces.list.emptyNoneTitle', 'No workspaces found')}\n description={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE)\n ? tr(\n 'workspaces.list.emptyNoneDescription',\n 'Create a workspace to start mapping members, organization ownership, and collaboration settings.'\n )\n : tr(\n 'workspaces.list.emptyNoneDescriptionViewer',\n 'No workspaces have been created yet.'\n )\n }\n action={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE) ? (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/new`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:bg-[var(--color-action-primary-bgHover)]\"\n >\n <Plus size={18} aria-hidden=\"true\" />\n {tr('workspaces.create.button', 'Create Workspace')}\n </button>\n ) : undefined\n }\n />\n </GlassCard>\n ) : (\n <>\n <div className=\"grid gap-4 md:hidden\">\n {workspaces.map((workspace) => (\n <GlassCard\n key={workspace.id}\n treatment=\"insight\"\n className=\"border-border-seam p-4\"\n >\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={selectedWorkspaceIds.has(workspace.id)}\n onChange={(checked) => toggleWorkspaceSelection(workspace.id, checked)}\n ariaLabel={`${tr('workspaces.list.selectOne', 'Select workspace')} ${workspace.name}`}\n />\n\n <div className=\"min-w-0 flex-1 space-y-3\">\n <div>\n <div className=\"flex flex-wrap items-start gap-2\">\n <h2 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {workspace.name}\n </h2>\n <WorkspaceStatusBadge status={workspace.status} />\n </div>\n <p className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{workspace.slug}\n </p>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-3 text-sm\">\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.members', 'Members')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {workspace.memberCount ?? 0}\n </dd>\n </div>\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {formatDate(workspace.createdAt)}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-wrap gap-2 border-t border-[var(--color-border-default)] pt-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${workspace.id}`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <Eye size={16} aria-hidden=\"true\" />\n {tr('common.view', 'View')}\n </button>\n {hasPermission(PERMISSIONS.WORKSPACE_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${workspace.id}/edit`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <SquarePen size={16} aria-hidden=\"true\" />\n {tr('common.edit', 'Edit')}\n </button>\n )}\n {hasPermission(PERMISSIONS.WORKSPACE_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(workspace.id, workspace.name)}\n disabled={deleteLoading}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-status-warning-border)] px-3 py-2 text-sm text-[var(--color-status-warning-text)] transition-all duration-200 hover:bg-[var(--color-status-warning-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n {tr('workspaces.suspend.confirm', 'Suspend')}\n </button>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n\n <GlassCard\n treatment=\"plain\"\n className=\"hidden overflow-hidden border-border-seam p-0 md:block\"\n >\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full\">\n <thead className=\"bg-[var(--color-bg-subtle)]\">\n <tr>\n <th className=\"w-12 px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllWorkspaces}\n ariaLabel={tr('workspaces.list.selectAll', 'Select all workspaces')}\n />\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.column.workspace', 'Workspace')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </th>\n <th className=\"px-6 py-3 text-right text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-[var(--color-border-seam)]\">\n {workspaces.map((workspace) => (\n <tr\n key={workspace.id}\n className=\"transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <td className=\"px-6 py-4 align-top\">\n <SelectionCheckbox\n checked={selectedWorkspaceIds.has(workspace.id)}\n onChange={(checked) => toggleWorkspaceSelection(workspace.id, checked)}\n ariaLabel={`${tr('workspaces.list.selectOne', 'Select workspace')} ${workspace.name}`}\n />\n </td>\n <td className=\"px-6 py-4\">\n <div>\n <p className=\"font-medium text-[var(--color-text-primary)]\">\n {workspace.name}\n </p>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{workspace.slug}\n </p>\n </div>\n </td>\n <td className=\"px-6 py-4 align-top\">\n <WorkspaceStatusBadge status={workspace.status} />\n </td>\n <td className=\"px-6 py-4 align-top text-sm text-[var(--color-text-secondary)]\">\n {formatDate(workspace.createdAt)}\n </td>\n <td className=\"px-6 py-4 align-top\">\n <div className=\"flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${workspace.id}`)}\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.view', 'View')} ${workspace.name}`}\n aria-label={`${tr('common.view', 'View')} ${workspace.name}`}\n >\n <Eye size={18} aria-hidden=\"true\" />\n </button>\n {hasPermission(PERMISSIONS.WORKSPACE_UPDATE) && (\n <button\n type=\"button\"\n onClick={() =>\n navigate(`${basePath}/workspaces/${workspace.id}/edit`)\n }\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.edit', 'Edit')} ${workspace.name}`}\n aria-label={`${tr('common.edit', 'Edit')} ${workspace.name}`}\n >\n <SquarePen size={18} aria-hidden=\"true\" />\n </button>\n )}\n {hasPermission(PERMISSIONS.WORKSPACE_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(workspace.id, workspace.name)}\n disabled={deleteLoading}\n className=\"rounded-lg p-2 text-[var(--color-status-warning-text)] transition-all duration-200 hover:bg-[var(--color-status-warning-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n title={`${tr('workspaces.suspend.confirm', 'Suspend')} ${workspace.name}`}\n aria-label={`${tr('workspaces.suspend.confirm', 'Suspend')} ${workspace.name}`}\n >\n <Trash2 size={18} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n </>\n )}\n </div>\n\n {ConfirmDialog}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WorkspacesListPage.js","names":["_Fragment","formatDate","date","WorkspacesListPage","tr","useTr","useOrgConsole","permissionsLoading","usePermissions","searchQuery","setSearchQuery","useState","debouncedSearchQuery","useDebouncedValue","filter","setFilter","selectedWorkspaceIds","setSelectedWorkspaceIds","useConfirmDialog","scope","mode","fetchedWorkspaces","useWorkspaces","workspaces","useMemo","query","matchesSearch","workspace","matchesStatus","deleteLoading","useDeleteWorkspace","visibleIds","nextSelection","previousSelection","workspaceId","selectedWorkspaces","allVisibleSelected","partiallySelected","executeSuspend","rejectedResult","workspaceIds","result","deleteWorkspace","refetch","successMsg","toast","nativeNotify","isNative","nativeToast","suspendError","errorMsg","handleDelete","title","description","workspaceName","nativeResult","openConfirmDialog","handleBulkDelete","toggleWorkspaceSelection","checked","toggleAllWorkspaces","LoadingState","hasPermission","PERMISSIONS","loading","error","ErrorState","PagePurpose","navigate","basePath","Plus","GlassCard","w","WorkspaceStatus","sum","SearchInput","event","RefreshCw","SelectionCheckbox","Trash2","IllustratedEmptyState","Fragment","WorkspaceStatusBadge","Eye","SquarePen","ConfirmDialog"],"sources":["../../../../../src/organization-management/modules/workspaces/pages/WorkspacesListPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { Eye, Plus, RefreshCw, SquarePen, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport { useDeleteWorkspace, useWorkspaces } from '../hooks/useWorkspaces';\nimport { WorkspaceStatusBadge } from '../components/WorkspaceStatusBadge';\nimport { SearchInput } from '../../../shared/components/input/SearchInput';\nimport { SelectionCheckbox } from '../../../shared/components/input/SelectionCheckbox';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { ErrorState } from '../../../shared/components/feedback/ErrorState';\nimport { useDebouncedValue } from '../../../shared/hooks/useDebouncedValue';\nimport { useConfirmDialog } from '../../../shared/components/dialog/ConfirmDialog';\nimport { PERMISSIONS } from '../../../constants/permissions';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport type { WorkspaceFilterInput } from '../types';\nimport { WorkspaceStatus } from '../types';\nimport {\n isNative,\n nativeConfirm,\n nativeImpact,\n nativeNotify,\n nativeToast,\n} from '../../../../utils/nativeBridge';\n\nfunction formatDate(date: string) {\n return new Date(date).toLocaleDateString();\n}\n\n/**\n * `mode` controls the scope of the listing:\n * - `'my'` — membership-scoped (`myWorkspaces`); the default for user-facing\n * app shells. A regular user only sees workspaces they belong to.\n * - `'admin'` — platform-wide (`allWorkspaces`, super-admin only); the admin app.\n */\nexport interface WorkspacesListPageProps {\n mode?: 'my' | 'admin';\n}\n\nexport function WorkspacesListPage({ mode = 'my' }: WorkspacesListPageProps = {}) {\n const tr = useTr();\n const { navigate, basePath = '/organizations' } = useOrgConsole();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n const [searchQuery, setSearchQuery] = useState('');\n const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);\n const [filter, setFilter] = useState<WorkspaceFilterInput>({});\n const [selectedWorkspaceIds, setSelectedWorkspaceIds] = useState<Set<string>>(new Set());\n const { openConfirmDialog, ConfirmDialog } = useConfirmDialog();\n\n // 'my' shells call the self-scoped `myWorkspaces` (no server-side filter arg),\n // so we over-fetch a page and filter client-side below. The admin app keeps\n // the server-filtered, paginated `allWorkspaces`.\n const scope = mode === 'admin' ? 'all' : 'my';\n const {\n workspaces: fetchedWorkspaces,\n loading,\n error,\n refetch,\n } = useWorkspaces(\n { ...filter, search: debouncedSearchQuery || undefined },\n scope === 'my' ? 100 : 20,\n 0,\n scope\n );\n\n const workspaces = useMemo(() => {\n if (scope !== 'my') return fetchedWorkspaces;\n const query = debouncedSearchQuery.trim().toLowerCase();\n return fetchedWorkspaces.filter((workspace) => {\n const matchesSearch =\n !query ||\n workspace.name.toLowerCase().includes(query) ||\n (workspace.slug?.toLowerCase().includes(query) ?? false);\n const matchesStatus = !filter.status || workspace.status === filter.status;\n return matchesSearch && matchesStatus;\n });\n }, [fetchedWorkspaces, scope, debouncedSearchQuery, filter.status]);\n\n const { deleteWorkspace, loading: deleteLoading } = useDeleteWorkspace();\n\n useEffect(() => {\n setSelectedWorkspaceIds((previousSelection) => {\n const visibleIds = new Set(workspaces.map((workspace) => workspace.id));\n const nextSelection = new Set(\n [...previousSelection].filter((workspaceId) => visibleIds.has(workspaceId))\n );\n\n if (nextSelection.size === previousSelection.size) {\n return previousSelection;\n }\n\n return nextSelection;\n });\n }, [workspaces]);\n\n const selectedWorkspaces = useMemo(\n () => workspaces.filter((workspace) => selectedWorkspaceIds.has(workspace.id)),\n [selectedWorkspaceIds, workspaces]\n );\n\n const allVisibleSelected =\n workspaces.length > 0 &&\n workspaces.every((workspace) => selectedWorkspaceIds.has(workspace.id));\n const partiallySelected =\n workspaces.some((workspace) => selectedWorkspaceIds.has(workspace.id)) && !allVisibleSelected;\n\n const executeSuspend = async (workspaceIds: string[]) => {\n try {\n const results = await Promise.allSettled(\n workspaceIds.map(async (workspaceId) => {\n const result = await deleteWorkspace(workspaceId);\n if (result.errors?.length) {\n throw new Error(\n result.errors[0]?.message ??\n tr('workspaces.suspend.failed', 'Failed to suspend workspace')\n );\n }\n })\n );\n\n const rejectedResult = results.find((result) => result.status === 'rejected');\n if (rejectedResult?.status === 'rejected') {\n throw rejectedResult.reason;\n }\n\n setSelectedWorkspaceIds(new Set());\n await refetch();\n const successMsg =\n workspaceIds.length === 1\n ? tr('workspaces.suspend.successSingle', 'Workspace suspended successfully')\n : `${workspaceIds.length} ${tr('workspaces.suspend.successMany', 'workspaces suspended successfully')}`;\n toast.success(successMsg);\n void nativeNotify('success');\n if (isNative()) void nativeToast(successMsg);\n } catch (suspendError) {\n const errorMsg =\n suspendError instanceof Error\n ? suspendError.message\n : tr('workspaces.suspend.failed', 'Failed to suspend workspace');\n toast.error(errorMsg);\n void nativeNotify('error');\n if (isNative()) void nativeToast(errorMsg);\n }\n };\n\n const handleDelete = (workspaceId: string, workspaceName: string) => {\n nativeImpact('medium');\n const title = tr('workspaces.suspend.title', 'Suspend workspace');\n const description = `${tr('workspaces.suspend.prefix', 'Suspend')} ${workspaceName}? ${tr(\n 'workspaces.suspend.suffix',\n 'Workspace members will lose access until it is reactivated.'\n )}`;\n void nativeConfirm({\n title,\n message: description,\n okButtonTitle: tr('workspaces.suspend.confirm', 'Suspend'),\n }).then((nativeResult) => {\n if (nativeResult === null) {\n openConfirmDialog({\n title,\n description,\n confirmText: tr('workspaces.suspend.confirm', 'Suspend'),\n variant: 'warning',\n onConfirm: () => {\n void executeSuspend([workspaceId]);\n },\n });\n } else if (nativeResult) {\n void executeSuspend([workspaceId]);\n }\n });\n };\n\n const handleBulkDelete = () => {\n if (selectedWorkspaces.length === 0) return;\n\n openConfirmDialog({\n title: tr('workspaces.suspend.bulkTitle', 'Suspend selected workspaces'),\n description: `${tr('workspaces.suspend.prefix', 'Suspend')} ${selectedWorkspaces.length} ${tr(\n selectedWorkspaces.length === 1\n ? 'workspaces.suspend.bulkSuffixSingle'\n : 'workspaces.suspend.bulkSuffixMany',\n selectedWorkspaces.length === 1 ? 'selected workspace?' : 'selected workspaces?'\n )}`,\n confirmText: `${tr('workspaces.suspend.confirm', 'Suspend')} ${selectedWorkspaces.length}`,\n variant: 'warning',\n onConfirm: () => {\n void executeSuspend(selectedWorkspaces.map((workspace) => workspace.id));\n },\n });\n };\n\n const toggleWorkspaceSelection = (workspaceId: string, checked: boolean) => {\n setSelectedWorkspaceIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n if (checked) {\n nextSelection.add(workspaceId);\n } else {\n nextSelection.delete(workspaceId);\n }\n return nextSelection;\n });\n };\n\n const toggleAllWorkspaces = (checked: boolean) => {\n setSelectedWorkspaceIds((previousSelection) => {\n const nextSelection = new Set(previousSelection);\n workspaces.forEach((workspace) => {\n if (checked) {\n nextSelection.add(workspace.id);\n } else {\n nextSelection.delete(workspace.id);\n }\n });\n return nextSelection;\n });\n };\n\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (!hasPermission(PERMISSIONS.WORKSPACE_LIST)) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <div className=\"p-8 text-center text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.noPermission', \"You don't have permission to view workspaces.\")}\n </div>\n </div>\n );\n }\n\n if (loading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <LoadingState message={tr('workspaces.list.loading', 'Loading workspaces...')} />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <ErrorState\n message={error.message}\n action={{\n label: tr('common.retry', 'Retry'),\n onClick: () => {\n void refetch();\n },\n }}\n />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6 animate-in fade-in duration-200\">\n <div className=\"mx-auto flex w-full max-w-7xl flex-col gap-6\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\">\n <h1 className=\"text-3xl font-bold text-[var(--color-text-primary)]\">\n {tr('workspaces.list.title', 'Workspaces')}\n </h1>\n <p className=\"max-w-2xl text-[var(--color-text-secondary)]\">\n {tr(\n 'workspaces.list.subtitle',\n 'Manage organization workspaces, review their status, and open the workspace detail flow.'\n )}\n </p>\n <PagePurpose className=\"max-w-2xl\">\n {tr(\n 'workspaces.list.purpose',\n 'A workspace is where a team actually does its work — it holds the members, settings, and collaboration for one project or department. Create a workspace to give a group its own space, add the right people, and keep its status (active, inactive, archived) under control.'\n )}\n </PagePurpose>\n </div>\n\n {hasPermission(PERMISSIONS.WORKSPACE_CREATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/new`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2.5 text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90\"\n >\n <Plus size={18} aria-hidden=\"true\" />\n <span className=\"font-medium\">\n {tr('workspaces.create.button', 'Create Workspace')}\n </span>\n </button>\n )}\n </div>\n\n {fetchedWorkspaces.length > 0 ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('workspaces.list.title', 'Workspaces')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {fetchedWorkspaces.length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr('workspaces.status.active', 'Active')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {fetchedWorkspaces.filter((w) => w.status === WorkspaceStatus.ACTIVE).length}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"col-span-2 p-4 sm:col-span-1\">\n <p className=\"text-sm text-text-secondary\">\n {tr('workspaces.list.members', 'Members')}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums text-text-primary\">\n {fetchedWorkspaces.reduce((sum, w) => sum + (w.memberCount ?? 0), 0)}\n </p>\n </GlassCard>\n </div>\n ) : null}\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('workspaces.list.searchPlaceholder', 'Search workspaces...')}\n label={tr('workspaces.list.searchLabel', 'Search workspaces')}\n inputId=\"workspaces-search\"\n className=\"flex-1\"\n />\n\n <label className=\"flex min-h-11 min-w-[180px] flex-col justify-center rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-3 py-2 text-sm text-[var(--color-text-secondary)]\">\n <span className=\"sr-only\">\n {tr('workspaces.list.filterByStatus', 'Filter by workspace status')}\n </span>\n <select\n value={filter.status || ''}\n onChange={(event) =>\n setFilter({\n ...filter,\n status: event.target.value\n ? (event.target.value as WorkspaceStatus)\n : undefined,\n })\n }\n className=\"bg-transparent text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n aria-label={tr('workspaces.list.filterByStatus', 'Filter by workspace status')}\n >\n <option value=\"\">{tr('workspaces.list.allStatuses', 'All statuses')}</option>\n <option value={WorkspaceStatus.ACTIVE}>\n {tr('workspaces.status.active', 'Active')}\n </option>\n <option value={WorkspaceStatus.INACTIVE}>\n {tr('workspaces.status.inactive', 'Inactive')}\n </option>\n <option value={WorkspaceStatus.ARCHIVED}>\n {tr('workspaces.status.archived', 'Archived')}\n </option>\n </select>\n </label>\n\n <button\n type=\"button\"\n onClick={() => {\n void refetch();\n }}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] px-4 py-2 text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n aria-label={tr('workspaces.list.refresh', 'Refresh workspaces')}\n title={tr('workspaces.list.refresh', 'Refresh workspaces')}\n >\n <RefreshCw size={18} aria-hidden=\"true\" />\n </button>\n </div>\n\n {workspaces.length > 0 ? (\n <div className=\"mt-4 flex flex-col gap-3 rounded-lg border border-[var(--color-border-default)] bg-[var(--color-bg-canvas)] p-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-2 text-sm text-[var(--color-text-primary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllWorkspaces}\n ariaLabel={tr('workspaces.list.selectAll', 'Select all workspaces')}\n />\n <span>{tr('common.selectAllVisible', 'Select all visible')}</span>\n </label>\n\n {selectedWorkspaceIds.size > 0 ? (\n <button\n type=\"button\"\n onClick={() => setSelectedWorkspaceIds(new Set())}\n className=\"text-sm text-[var(--color-text-secondary)] transition-colors hover:text-[var(--color-text-primary)]\"\n >\n {tr('common.clearSelection', 'Clear selection')}\n </button>\n ) : null}\n </div>\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <span className=\"text-sm text-[var(--color-text-secondary)]\">\n {selectedWorkspaceIds.size} {tr('common.selected', 'selected')}\n </span>\n {hasPermission(PERMISSIONS.WORKSPACE_DELETE) && (\n <button\n type=\"button\"\n onClick={handleBulkDelete}\n disabled={selectedWorkspaces.length === 0 || deleteLoading}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg border border-[var(--color-status-warning-border)] px-3 py-2 text-[var(--color-status-warning-text)] transition-all duration-200 hover:bg-[var(--color-status-warning-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n <span>{tr('workspaces.list.suspendSelected', 'Suspend Selected')}</span>\n {selectedWorkspaces.length > 0 ? (\n <span>({selectedWorkspaces.length})</span>\n ) : null}\n </button>\n )}\n </div>\n </div>\n ) : null}\n </GlassCard>\n\n {workspaces.length === 0 ? (\n <GlassCard\n treatment=\"glass\"\n glow={fetchedWorkspaces.length === 0}\n className=\"border-border-seam p-6\"\n >\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tr('workspaces.list.emptyNoneTitle', 'No workspaces found')}\n description={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE)\n ? tr(\n 'workspaces.list.emptyNoneDescription',\n 'Create a workspace to start mapping members, organization ownership, and collaboration settings.'\n )\n : tr(\n 'workspaces.list.emptyNoneDescriptionViewer',\n 'No workspaces have been created yet.'\n )\n }\n action={\n hasPermission(PERMISSIONS.WORKSPACE_CREATE) ? (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/new`)}\n className=\"inline-flex min-h-11 items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-4 py-2 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:bg-[var(--color-action-primary-bgHover)]\"\n >\n <Plus size={18} aria-hidden=\"true\" />\n {tr('workspaces.create.button', 'Create Workspace')}\n </button>\n ) : undefined\n }\n />\n </GlassCard>\n ) : (\n <>\n <div className=\"grid gap-4 md:hidden\">\n {workspaces.map((workspace) => (\n <GlassCard\n key={workspace.id}\n treatment=\"insight\"\n className=\"border-border-seam p-4\"\n >\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={selectedWorkspaceIds.has(workspace.id)}\n onChange={(checked) => toggleWorkspaceSelection(workspace.id, checked)}\n ariaLabel={`${tr('workspaces.list.selectOne', 'Select workspace')} ${workspace.name}`}\n />\n\n <div className=\"min-w-0 flex-1 space-y-3\">\n <div>\n <div className=\"flex flex-wrap items-start gap-2\">\n <h2 className=\"text-base font-semibold text-[var(--color-text-primary)]\">\n {workspace.name}\n </h2>\n <WorkspaceStatusBadge status={workspace.status} />\n </div>\n <p className=\"mt-1 break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{workspace.slug}\n </p>\n </div>\n\n <dl className=\"grid grid-cols-2 gap-3 text-sm\">\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.members', 'Members')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {workspace.memberCount ?? 0}\n </dd>\n </div>\n <div>\n <dt className=\"text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </dt>\n <dd className=\"font-medium text-[var(--color-text-primary)]\">\n {formatDate(workspace.createdAt)}\n </dd>\n </div>\n </dl>\n </div>\n </div>\n\n <div className=\"mt-4 flex flex-wrap gap-2 border-t border-[var(--color-border-default)] pt-4\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${workspace.id}`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <Eye size={16} aria-hidden=\"true\" />\n {tr('common.view', 'View')}\n </button>\n {hasPermission(PERMISSIONS.WORKSPACE_UPDATE) && (\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${workspace.id}/edit`)}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-border-default)] px-3 py-2 text-sm text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]\"\n >\n <SquarePen size={16} aria-hidden=\"true\" />\n {tr('common.edit', 'Edit')}\n </button>\n )}\n {hasPermission(PERMISSIONS.WORKSPACE_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(workspace.id, workspace.name)}\n disabled={deleteLoading}\n className=\"inline-flex min-h-10 items-center gap-2 rounded-lg border border-[var(--color-status-warning-border)] px-3 py-2 text-sm text-[var(--color-status-warning-text)] transition-all duration-200 hover:bg-[var(--color-status-warning-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <Trash2 size={16} aria-hidden=\"true\" />\n {tr('workspaces.suspend.confirm', 'Suspend')}\n </button>\n )}\n </div>\n </GlassCard>\n ))}\n </div>\n\n <GlassCard\n treatment=\"plain\"\n className=\"hidden overflow-hidden border-border-seam p-0 md:block\"\n >\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full\">\n <thead className=\"bg-[var(--color-bg-subtle)]\">\n <tr>\n <th className=\"w-12 px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllWorkspaces}\n ariaLabel={tr('workspaces.list.selectAll', 'Select all workspaces')}\n />\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('workspaces.list.column.workspace', 'Workspace')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.status', 'Status')}\n </th>\n <th className=\"px-6 py-3 text-left text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.created', 'Created')}\n </th>\n <th className=\"px-6 py-3 text-right text-xs font-semibold uppercase tracking-wide text-[var(--color-text-secondary)]\">\n {tr('common.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-[var(--color-border-seam)]\">\n {workspaces.map((workspace) => (\n <tr\n key={workspace.id}\n className=\"transition-colors hover:bg-[var(--color-bg-subtle)]\"\n >\n <td className=\"px-6 py-4 align-top\">\n <SelectionCheckbox\n checked={selectedWorkspaceIds.has(workspace.id)}\n onChange={(checked) => toggleWorkspaceSelection(workspace.id, checked)}\n ariaLabel={`${tr('workspaces.list.selectOne', 'Select workspace')} ${workspace.name}`}\n />\n </td>\n <td className=\"px-6 py-4\">\n <div>\n <p className=\"font-medium text-[var(--color-text-primary)]\">\n {workspace.name}\n </p>\n <p className=\"break-all font-mono text-sm text-[var(--color-text-muted)]\">\n /{workspace.slug}\n </p>\n </div>\n </td>\n <td className=\"px-6 py-4 align-top\">\n <WorkspaceStatusBadge status={workspace.status} />\n </td>\n <td className=\"px-6 py-4 align-top text-sm text-[var(--color-text-secondary)]\">\n {formatDate(workspace.createdAt)}\n </td>\n <td className=\"px-6 py-4 align-top\">\n <div className=\"flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => navigate(`${basePath}/workspaces/${workspace.id}`)}\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.view', 'View')} ${workspace.name}`}\n aria-label={`${tr('common.view', 'View')} ${workspace.name}`}\n >\n <Eye size={18} aria-hidden=\"true\" />\n </button>\n {hasPermission(PERMISSIONS.WORKSPACE_UPDATE) && (\n <button\n type=\"button\"\n onClick={() =>\n navigate(`${basePath}/workspaces/${workspace.id}/edit`)\n }\n className=\"rounded-lg p-2 text-[var(--color-text-secondary)] transition-all duration-200 hover:bg-[var(--color-bg-muted)] hover:text-[var(--color-text-primary)]\"\n title={`${tr('common.edit', 'Edit')} ${workspace.name}`}\n aria-label={`${tr('common.edit', 'Edit')} ${workspace.name}`}\n >\n <SquarePen size={18} aria-hidden=\"true\" />\n </button>\n )}\n {hasPermission(PERMISSIONS.WORKSPACE_DELETE) && (\n <button\n type=\"button\"\n onClick={() => handleDelete(workspace.id, workspace.name)}\n disabled={deleteLoading}\n className=\"rounded-lg p-2 text-[var(--color-status-warning-text)] transition-all duration-200 hover:bg-[var(--color-status-warning-bgSubtle)] disabled:cursor-not-allowed disabled:opacity-50\"\n title={`${tr('workspaces.suspend.confirm', 'Suspend')} ${workspace.name}`}\n aria-label={`${tr('workspaces.suspend.confirm', 'Suspend')} ${workspace.name}`}\n >\n <Trash2 size={18} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n </>\n )}\n </div>\n\n {ConfirmDialog}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { WorkspaceStatus as e } from "../../../shared/types/graphql.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { enum as t, object as n, record as r, string as i, unknown as a } from "../../../../node_modules/zod/v4/classic/schemas.js";
|
|
3
|
+
// src/organization-management/modules/workspaces/schemas/index.ts
|
|
4
4
|
function o(e) {
|
|
5
5
|
return {
|
|
6
|
-
name: i().min(2, e("workspaces.validation.nameMin", "Name must be at least 2 characters")).max(100, e("workspaces.validation.nameMax", "Name must not exceed 100 characters"))
|
|
7
|
-
slug: i().min(2, e("workspaces.validation.slugMin", "Slug must be at least 2 characters")).max(50, e("workspaces.validation.slugMax", "Slug must not exceed 50 characters")).regex(/^[a-z0-9-]+$/, e("workspaces.validation.slugPattern", "Slug must contain only lowercase letters, numbers, and hyphens"))
|
|
6
|
+
name: i().trim().min(2, e("workspaces.validation.nameMin", "Name must be at least 2 characters")).max(100, e("workspaces.validation.nameMax", "Name must not exceed 100 characters")),
|
|
7
|
+
slug: i().trim().min(2, e("workspaces.validation.slugMin", "Slug must be at least 2 characters")).max(50, e("workspaces.validation.slugMax", "Slug must not exceed 50 characters")).regex(/^[a-z0-9-]+$/, e("workspaces.validation.slugPattern", "Slug must contain only lowercase letters, numbers, and hyphens")),
|
|
8
8
|
type: i().optional(),
|
|
9
9
|
metadata: r(i(), a()).optional()
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
function s(r) {
|
|
13
13
|
return n({
|
|
14
|
-
tenantId: i().min(1, r("workspaces.validation.tenantRequired", "Tenant is required")),
|
|
15
|
-
organizationId: i().min(1, r("workspaces.validation.organizationRequired", "Organization is required")),
|
|
14
|
+
tenantId: i().trim().min(1, r("workspaces.validation.tenantRequired", "Tenant is required")),
|
|
15
|
+
organizationId: i().trim().min(1, r("workspaces.validation.organizationRequired", "Organization is required")),
|
|
16
16
|
...o(r),
|
|
17
17
|
status: t(e).optional()
|
|
18
18
|
});
|
|
@@ -25,7 +25,6 @@ function c(e) {
|
|
|
25
25
|
metadata: t.metadata
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
-
//#endregion
|
|
29
28
|
export { s as createWorkspaceSchema, c as updateWorkspaceSchema };
|
|
30
29
|
|
|
31
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../src/organization-management/modules/workspaces/schemas/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { WorkspaceStatus } from '../types';\nimport type { TranslationFn } from '../../../shared/hooks/useTr';\n\n/**\n * Workspace Validation Schemas\n * Zod schemas for validating workspace form inputs.\n *\n * Exported as factory functions so validation messages can be translated\n * via the same `tr()` helper used by components.\n *\n * Schema Changes:\n * - Removed description, iconUrl, visibility fields (not in backend schema)\n * - Added type field\n */\n\nfunction baseWorkspaceSchema(tr: TranslationFn) {\n return {\n name: z\n .string()\n .min(2, tr('workspaces.validation.nameMin', 'Name must be at least 2 characters'))\n .max(100, tr('workspaces.validation.nameMax', 'Name must not exceed 100 characters'))
|
|
1
|
+
{"version":3,"file":"index.js","names":["z.string","z.record","z.unknown","z.object","z.enum","_enum","baseWorkspaceSchema","string","tr","record","unknown","createWorkspaceSchema","object","WorkspaceStatus","updateWorkspaceSchema","base"],"sources":["../../../../../src/organization-management/modules/workspaces/schemas/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { WorkspaceStatus } from '../types';\nimport type { TranslationFn } from '../../../shared/hooks/useTr';\n\n/**\n * Workspace Validation Schemas\n * Zod schemas for validating workspace form inputs.\n *\n * Exported as factory functions so validation messages can be translated\n * via the same `tr()` helper used by components.\n *\n * Schema Changes:\n * - Removed description, iconUrl, visibility fields (not in backend schema)\n * - Added type field\n */\n\nfunction baseWorkspaceSchema(tr: TranslationFn) {\n return {\n name: z\n .string()\n .trim()\n .min(2, tr('workspaces.validation.nameMin', 'Name must be at least 2 characters'))\n .max(100, tr('workspaces.validation.nameMax', 'Name must not exceed 100 characters')),\n slug: z\n .string()\n .trim()\n .min(2, tr('workspaces.validation.slugMin', 'Slug must be at least 2 characters'))\n .max(50, tr('workspaces.validation.slugMax', 'Slug must not exceed 50 characters'))\n .regex(\n /^[a-z0-9-]+$/,\n tr(\n 'workspaces.validation.slugPattern',\n 'Slug must contain only lowercase letters, numbers, and hyphens'\n )\n ),\n type: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n };\n}\n\n// Create Workspace Schema\nexport function createWorkspaceSchema(tr: TranslationFn) {\n return z.object({\n tenantId: z\n .string()\n .trim()\n .min(1, tr('workspaces.validation.tenantRequired', 'Tenant is required')),\n organizationId: z\n .string()\n .trim()\n .min(1, tr('workspaces.validation.organizationRequired', 'Organization is required')),\n ...baseWorkspaceSchema(tr),\n status: z.enum(WorkspaceStatus).optional(),\n });\n}\n\n// Update Workspace Schema\nexport function updateWorkspaceSchema(tr: TranslationFn) {\n const base = baseWorkspaceSchema(tr);\n return z.object({\n name: base.name.optional(),\n type: base.type,\n metadata: base.metadata,\n });\n}\n\n// Type exports\nexport type CreateWorkspaceFormData = z.infer<ReturnType<typeof createWorkspaceSchema>>;\nexport type UpdateWorkspaceFormData = z.infer<ReturnType<typeof updateWorkspaceSchema>>;\n"],"mappings":";;;AAgBA,SAASM,EAAoB,GAAmB;CAC9C,OAAO;EACL,MAAMN,EACI,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGQ,EAAG,iCAAiC,oCAAoC,CAAC,CAAC,CACjF,IAAI,KAAKA,EAAG,iCAAiC,qCAAqC,CAAC;EACtF,MAAMR,EACI,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGQ,EAAG,iCAAiC,oCAAoC,CAAC,CAAC,CACjF,IAAI,IAAIA,EAAG,iCAAiC,oCAAoC,CAAC,CAAC,CAClF,MACC,gBACAA,EACE,qCACA,gEACF,CACF;EACF,MAAMR,EAAS,CAAC,CAAC,SAAS;EAC1B,UAAUC,EAASD,EAAS,GAAGE,EAAU,CAAC,CAAC,CAAC,SAAS;CACvD;AACF;AAGA,SAAgBS,EAAsB,GAAmB;CACvD,OAAOR,EAAS;EACd,UAAUH,EACA,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGQ,EAAG,wCAAwC,oBAAoB,CAAC;EAC1E,gBAAgBR,EACN,CAAC,CACR,KAAK,CAAC,CACN,IAAI,GAAGQ,EAAG,8CAA8C,0BAA0B,CAAC;EACtF,GAAGF,EAAoBE,CAAE;EACzB,QAAQJ,EAAOS,CAAe,CAAC,CAAC,SAAS;CAC3C,CAAC;AACH;AAGA,SAAgBC,EAAsB,GAAmB;CACvD,IAAMC,IAAOT,EAAoBE,CAAE;CACnC,OAAOL,EAAS;EACd,MAAMY,EAAK,KAAK,SAAS;EACzB,MAAMA,EAAK;EACX,UAAUA,EAAK;CACjB,CAAC;AACH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createContext as e, use as t } from "react";
|
|
2
2
|
import { PermissionProvider as n } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
3
3
|
import { jsx as r } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/organization-management/providers/OrgConsoleProvider.tsx
|
|
5
5
|
var i = e(null);
|
|
6
6
|
function a({ children: e, ...t }) {
|
|
7
7
|
return /* @__PURE__ */ r(i.Provider, {
|
|
@@ -18,7 +18,6 @@ function o() {
|
|
|
18
18
|
if (!e) throw Error("useOrgConsole must be used within OrgConsoleProvider");
|
|
19
19
|
return e;
|
|
20
20
|
}
|
|
21
|
-
//#endregion
|
|
22
21
|
export { a as OrgConsoleProvider, o as useOrgConsole };
|
|
23
22
|
|
|
24
23
|
//# sourceMappingURL=OrgConsoleProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrgConsoleProvider.js","names":[],"sources":["../../../src/organization-management/providers/OrgConsoleProvider.tsx"],"sourcesContent":["import { createContext, use, type ReactNode } from 'react';\nimport { PermissionProvider } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { OrganizationRootProps } from '../types';\n\ntype OrgConsoleContextValue = OrganizationRootProps;\n\nconst OrgConsoleContext = createContext<OrgConsoleContextValue | null>(null);\n\nexport interface OrgConsoleProviderProps extends OrganizationRootProps {\n children: ReactNode;\n}\n\n/**\n * OrgConsoleProvider\n * Provides global console context to all child components\n */\nexport function OrgConsoleProvider({ children, ...props }: OrgConsoleProviderProps) {\n return (\n <OrgConsoleContext.Provider value={props}>\n <PermissionProvider scopeId={props.tenantId ?? null} gateway=\"global\">\n {children}\n </PermissionProvider>\n </OrgConsoleContext.Provider>\n );\n}\n\n/**\n * Hook to access global console context\n * @throws Error if used outside OrgConsoleProvider\n */\nexport function useOrgConsole(): OrgConsoleContextValue {\n const context = use(OrgConsoleContext);\n if (!context) {\n throw new Error('useOrgConsole must be used within OrgConsoleProvider');\n }\n return context;\n}\n"],"mappings":";;;;AAMA,
|
|
1
|
+
{"version":3,"file":"OrgConsoleProvider.js","names":["OrgConsoleContext","createContext","OrgConsoleProvider","props","PermissionProvider","useOrgConsole","context","use"],"sources":["../../../src/organization-management/providers/OrgConsoleProvider.tsx"],"sourcesContent":["import { createContext, use, type ReactNode } from 'react';\nimport { PermissionProvider } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { OrganizationRootProps } from '../types';\n\ntype OrgConsoleContextValue = OrganizationRootProps;\n\nconst OrgConsoleContext = createContext<OrgConsoleContextValue | null>(null);\n\nexport interface OrgConsoleProviderProps extends OrganizationRootProps {\n children: ReactNode;\n}\n\n/**\n * OrgConsoleProvider\n * Provides global console context to all child components\n */\nexport function OrgConsoleProvider({ children, ...props }: OrgConsoleProviderProps) {\n return (\n <OrgConsoleContext.Provider value={props}>\n <PermissionProvider scopeId={props.tenantId ?? null} gateway=\"global\">\n {children}\n </PermissionProvider>\n </OrgConsoleContext.Provider>\n );\n}\n\n/**\n * Hook to access global console context\n * @throws Error if used outside OrgConsoleProvider\n */\nexport function useOrgConsole(): OrgConsoleContextValue {\n const context = use(OrgConsoleContext);\n if (!context) {\n throw new Error('useOrgConsole must be used within OrgConsoleProvider');\n }\n return context;\n}\n"],"mappings":";;;;AAMA,IAAMA,IAAoBC,EAA6C,IAAI;AAU3E,SAAgBC,EAAmB,EAAE,aAAU,GAAGC,KAAkC;CAClF,OACE,kBAACH,EAAkB,UAAnB;EAA4B,OAAOG;EACjC,UAAA,kBAACC,GAAD;GAAoB,SAASD,EAAM,YAAY;GAAM,SAAQ;GAC1D;EACiB,CAAA;CACM,CAAA;AAEhC;AAMA,SAAgBE,IAAwC;CACtD,IAAMC,IAAUC,EAAIP,CAAiB;CACrC,IAAI,CAACM,GACH,MAAU,MAAM,sDAAsD;CAExE,OAAOA;AACT"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PermissionProvider as e } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
|
-
|
|
3
|
+
// src/organization-management/providers/OrgScopedPermissions.tsx
|
|
4
4
|
function n({ organizationId: n, children: r }) {
|
|
5
5
|
return /* @__PURE__ */ t(e, {
|
|
6
6
|
scopeId: n,
|
|
@@ -8,7 +8,6 @@ function n({ organizationId: n, children: r }) {
|
|
|
8
8
|
children: r
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
|
-
//#endregion
|
|
12
11
|
export { n as OrgScopedPermissions };
|
|
13
12
|
|
|
14
13
|
//# sourceMappingURL=OrgScopedPermissions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrgScopedPermissions.js","names":[],"sources":["../../../src/organization-management/providers/OrgScopedPermissions.tsx"],"sourcesContent":["import { PermissionProvider } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { ReactNode } from 'react';\n\n/**\n * Wrap a per-organization route's content with a `PermissionProvider`\n * scoped to that organization's id.\n *\n * The outer `OrgConsoleProvider` mounts a tenant-scoped `PermissionProvider`,\n * which is correct for tenant-wide pages (org list, create). On org-specific\n * pages (detail, edit, members, workspaces) we need scope = the org's id so\n * `hasPermission(...)` reflects the user's per-org role (Owner / Admin /\n * Editor / Viewer) — assignments which live at the org's scope and would\n * otherwise be invisible in a tenant-scoped query.\n *\n * Nested `PermissionProvider`s override the outer one for any consumer\n * inside this subtree; global-scope roles (e.g. Authenticated User) still\n * flow in via the rbac service's `[scopeId, 'global']` merge.\n */\nexport function OrgScopedPermissions({\n organizationId,\n children,\n}: {\n organizationId: string;\n children: ReactNode;\n}) {\n return (\n <PermissionProvider scopeId={organizationId} gateway=\"global\">\n {children}\n </PermissionProvider>\n );\n}\n"],"mappings":";;;AAkBA,
|
|
1
|
+
{"version":3,"file":"OrgScopedPermissions.js","names":["OrgScopedPermissions","PermissionProvider","organizationId"],"sources":["../../../src/organization-management/providers/OrgScopedPermissions.tsx"],"sourcesContent":["import { PermissionProvider } from '@burdenoff/fe-libs/shared/providers/shell';\nimport type { ReactNode } from 'react';\n\n/**\n * Wrap a per-organization route's content with a `PermissionProvider`\n * scoped to that organization's id.\n *\n * The outer `OrgConsoleProvider` mounts a tenant-scoped `PermissionProvider`,\n * which is correct for tenant-wide pages (org list, create). On org-specific\n * pages (detail, edit, members, workspaces) we need scope = the org's id so\n * `hasPermission(...)` reflects the user's per-org role (Owner / Admin /\n * Editor / Viewer) — assignments which live at the org's scope and would\n * otherwise be invisible in a tenant-scoped query.\n *\n * Nested `PermissionProvider`s override the outer one for any consumer\n * inside this subtree; global-scope roles (e.g. Authenticated User) still\n * flow in via the rbac service's `[scopeId, 'global']` merge.\n */\nexport function OrgScopedPermissions({\n organizationId,\n children,\n}: {\n organizationId: string;\n children: ReactNode;\n}) {\n return (\n <PermissionProvider scopeId={organizationId} gateway=\"global\">\n {children}\n </PermissionProvider>\n );\n}\n"],"mappings":";;;AAkBA,SAAgBA,EAAqB,EACnC,mBACA,eAIC;CACD,OACE,kBAACC,GAAD;EAAoB,SAASC;EAAgB,SAAQ;EAClD;CACiB,CAAA;AAExB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConfirmDialog as e } from "./ConfirmDialogView.js";
|
|
2
2
|
import { useCallback as t, useMemo as n, useState as r } from "react";
|
|
3
3
|
import { jsx as i } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/organization-management/shared/components/dialog/ConfirmDialog.tsx
|
|
5
5
|
function a() {
|
|
6
6
|
let [a, o] = r({
|
|
7
7
|
open: !1,
|
|
@@ -38,7 +38,6 @@ function a() {
|
|
|
38
38
|
])
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
//#endregion
|
|
42
41
|
export { a as useConfirmDialog };
|
|
43
42
|
|
|
44
43
|
//# sourceMappingURL=ConfirmDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../../../src/organization-management/shared/components/dialog/ConfirmDialog.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { ConfirmDialog, type ConfirmDialogVariant } from './ConfirmDialogView';\n\ninterface ConfirmDialogState {\n open: boolean;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmDialogVariant;\n}\n\nexport function useConfirmDialog() {\n const [state, setState] = useState<ConfirmDialogState>({\n open: false,\n title: '',\n description: '',\n });\n const [onConfirm, setOnConfirm] = useState<(() => void) | null>(null);\n\n const openConfirmDialog = useCallback(\n (config: Omit<ConfirmDialogState, 'open'> & { onConfirm: () => void }) => {\n setState({ ...config, open: true });\n setOnConfirm(() => config.onConfirm);\n },\n []\n );\n\n const handleOpenChange = useCallback((open: boolean) => {\n setState((previousState) => ({ ...previousState, open }));\n if (!open) {\n setOnConfirm(null);\n }\n }, []);\n\n const dialog = useMemo(\n () => (\n <ConfirmDialog\n open={state.open}\n onOpenChange={handleOpenChange}\n title={state.title}\n description={state.description}\n confirmText={state.confirmText}\n cancelText={state.cancelText}\n variant={state.variant}\n onConfirm={() => {\n onConfirm?.();\n handleOpenChange(false);\n }}\n />\n ),\n [handleOpenChange, onConfirm, state]\n );\n\n return { openConfirmDialog, ConfirmDialog: dialog };\n}\n"],"mappings":";;;;AAYA,
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.js","names":["useConfirmDialog","state","setState","useState","onConfirm","setOnConfirm","openConfirmDialog","useCallback","config","handleOpenChange","previousState","open","useMemo","ConfirmDialog"],"sources":["../../../../../src/organization-management/shared/components/dialog/ConfirmDialog.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { ConfirmDialog, type ConfirmDialogVariant } from './ConfirmDialogView';\n\ninterface ConfirmDialogState {\n open: boolean;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmDialogVariant;\n}\n\nexport function useConfirmDialog() {\n const [state, setState] = useState<ConfirmDialogState>({\n open: false,\n title: '',\n description: '',\n });\n const [onConfirm, setOnConfirm] = useState<(() => void) | null>(null);\n\n const openConfirmDialog = useCallback(\n (config: Omit<ConfirmDialogState, 'open'> & { onConfirm: () => void }) => {\n setState({ ...config, open: true });\n setOnConfirm(() => config.onConfirm);\n },\n []\n );\n\n const handleOpenChange = useCallback((open: boolean) => {\n setState((previousState) => ({ ...previousState, open }));\n if (!open) {\n setOnConfirm(null);\n }\n }, []);\n\n const dialog = useMemo(\n () => (\n <ConfirmDialog\n open={state.open}\n onOpenChange={handleOpenChange}\n title={state.title}\n description={state.description}\n confirmText={state.confirmText}\n cancelText={state.cancelText}\n variant={state.variant}\n onConfirm={() => {\n onConfirm?.();\n handleOpenChange(false);\n }}\n />\n ),\n [handleOpenChange, onConfirm, state]\n );\n\n return { openConfirmDialog, ConfirmDialog: dialog };\n}\n"],"mappings":";;;;AAYA,SAAgBA,IAAmB;CACjC,IAAM,CAACC,GAAOC,KAAYC,EAA6B;EACrD,MAAM;EACN,OAAO;EACP,aAAa;CACf,CAAC,GACK,CAACC,GAAWC,KAAgBF,EAA8B,IAAI,GAE9DG,IAAoBC,GACvB,MAAyE;EAExE,AADAL,EAAS;GAAE,GAAGM;GAAQ,MAAM;EAAK,CAAC,GAClCH,QAAmBG,EAAO,SAAS;CACrC,GACA,CAAC,CACH,GAEMC,IAAmBF,GAAa,MAAkB;EAEtD,AADAL,GAAU,OAAmB;GAAE,GAAGQ;GAAe;EAAK,EAAE,GACnDC,KACHN,EAAa,IAAI;CAErB,GAAG,CAAC,CAAC;CAqBL,OAAO;EAAE;EAAmB,eAnBbO,QAEX,kBAACC,GAAD;GACE,MAAMZ,EAAM;GACZ,cAAcQ;GACd,OAAOR,EAAM;GACb,aAAaA,EAAM;GACnB,aAAaA,EAAM;GACnB,YAAYA,EAAM;GAClB,SAASA,EAAM;GACf,iBAAiB;IAEf,AADAG,IAAY,GACZK,EAAiB,EAAK;GACxB;EACD,CAAA,GAEH;GAACA;GAAkBL;GAAWH;EAAK,CAGM;CAAO;AACpD"}
|
|
@@ -3,7 +3,7 @@ import { AlertCircle as t, AlertTriangle as n, Info as r } from "lucide-react";
|
|
|
3
3
|
import { AlertDialog as i, AlertDialogAction as a, AlertDialogCancel as o, AlertDialogContent as s, AlertDialogDescription as c, AlertDialogFooter as l, AlertDialogHeader as u, AlertDialogTitle as d } from "@burdenoff/fe-libs/ui";
|
|
4
4
|
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
5
5
|
import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
6
|
-
|
|
6
|
+
// src/organization-management/shared/components/dialog/ConfirmDialogView.tsx
|
|
7
7
|
var h = {
|
|
8
8
|
default: {
|
|
9
9
|
icon: r,
|
|
@@ -63,7 +63,6 @@ function g({ open: t, onOpenChange: n, title: r, description: g, confirmText: _,
|
|
|
63
63
|
})
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
|
-
//#endregion
|
|
67
66
|
export { g as ConfirmDialog };
|
|
68
67
|
|
|
69
68
|
//# sourceMappingURL=ConfirmDialogView.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmDialogView.js","names":[],"sources":["../../../../../src/organization-management/shared/components/dialog/ConfirmDialogView.tsx"],"sourcesContent":["import { AlertCircle, AlertTriangle, Info } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\n\nexport type ConfirmDialogVariant = 'default' | 'warning' | 'danger';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmDialogVariant;\n onConfirm: () => void;\n}\n\nconst VARIANT_STYLES: Record<\n ConfirmDialogVariant,\n {\n icon: typeof Info;\n iconContainerClassName: string;\n iconClassName: string;\n actionClassName: string;\n }\n> = {\n default: {\n icon: Info,\n iconContainerClassName: 'bg-[var(--color-status-info-bgSubtle)]',\n iconClassName: 'text-[var(--color-status-info-text)]',\n actionClassName:\n 'bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90',\n },\n warning: {\n icon: AlertTriangle,\n iconContainerClassName: 'bg-[var(--color-status-warning-bgSubtle)]',\n iconClassName: 'text-[var(--color-status-warning-text)]',\n actionClassName:\n 'bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90',\n },\n danger: {\n icon: AlertCircle,\n iconContainerClassName: 'bg-[var(--color-status-error-bgSubtle)]',\n iconClassName: 'text-[var(--color-status-error-text)]',\n actionClassName:\n 'bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90',\n },\n};\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmText,\n cancelText,\n variant = 'default',\n onConfirm,\n}: ConfirmDialogProps) {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const styles = VARIANT_STYLES[variant];\n const Icon = styles.icon;\n const resolvedConfirmText = confirmText ?? tr('common.confirm', 'Confirm');\n const resolvedCancelText = cancelText ?? tr('common.cancel', 'Cancel');\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"max-w-md border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)]\">\n <AlertDialogHeader>\n <div className=\"flex items-start gap-4\">\n <div\n className={`flex h-10 w-10 items-center justify-center rounded-full ${styles.iconContainerClassName}`}\n >\n <Icon className={`h-5 w-5 ${styles.iconClassName}`} />\n </div>\n <div className=\"flex-1\">\n <AlertDialogTitle className=\"text-lg text-[var(--color-text-primary)]\">\n {title}\n </AlertDialogTitle>\n <AlertDialogDescription className=\"mt-2 text-sm text-[var(--color-text-secondary)]\">\n {description}\n </AlertDialogDescription>\n </div>\n </div>\n </AlertDialogHeader>\n\n <AlertDialogFooter className=\"mt-6\">\n <AlertDialogCancel className=\"border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-subtle)]\">\n {resolvedCancelText}\n </AlertDialogCancel>\n <AlertDialogAction onClick={onConfirm} className={styles.actionClassName}>\n {resolvedConfirmText}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"],"mappings":";;;;;;AA2BA,
|
|
1
|
+
{"version":3,"file":"ConfirmDialogView.js","names":["VARIANT_STYLES","Info","AlertTriangle","AlertCircle","ConfirmDialog","useI18n","tr","useCallback","translated","t","key","fallback","styles","variant","Icon","resolvedConfirmText","confirmText","resolvedCancelText","cancelText","AlertDialog","AlertDialogContent","AlertDialogHeader","AlertDialogTitle","title","AlertDialogDescription","description","AlertDialogFooter","AlertDialogCancel","AlertDialogAction","onConfirm"],"sources":["../../../../../src/organization-management/shared/components/dialog/ConfirmDialogView.tsx"],"sourcesContent":["import { AlertCircle, AlertTriangle, Info } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '@burdenoff/fe-libs/ui';\n\nexport type ConfirmDialogVariant = 'default' | 'warning' | 'danger';\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n description: string;\n confirmText?: string;\n cancelText?: string;\n variant?: ConfirmDialogVariant;\n onConfirm: () => void;\n}\n\nconst VARIANT_STYLES: Record<\n ConfirmDialogVariant,\n {\n icon: typeof Info;\n iconContainerClassName: string;\n iconClassName: string;\n actionClassName: string;\n }\n> = {\n default: {\n icon: Info,\n iconContainerClassName: 'bg-[var(--color-status-info-bgSubtle)]',\n iconClassName: 'text-[var(--color-status-info-text)]',\n actionClassName:\n 'bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)] hover:opacity-90',\n },\n warning: {\n icon: AlertTriangle,\n iconContainerClassName: 'bg-[var(--color-status-warning-bgSubtle)]',\n iconClassName: 'text-[var(--color-status-warning-text)]',\n actionClassName:\n 'bg-[var(--color-status-warning-bg)] text-[var(--color-text-inverse)] hover:opacity-90',\n },\n danger: {\n icon: AlertCircle,\n iconContainerClassName: 'bg-[var(--color-status-error-bgSubtle)]',\n iconClassName: 'text-[var(--color-status-error-text)]',\n actionClassName:\n 'bg-[var(--color-status-error-bg)] text-[var(--color-text-inverse)] hover:opacity-90',\n },\n};\n\nexport function ConfirmDialog({\n open,\n onOpenChange,\n title,\n description,\n confirmText,\n cancelText,\n variant = 'default',\n onConfirm,\n}: ConfirmDialogProps) {\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n },\n [t]\n );\n const styles = VARIANT_STYLES[variant];\n const Icon = styles.icon;\n const resolvedConfirmText = confirmText ?? tr('common.confirm', 'Confirm');\n const resolvedCancelText = cancelText ?? tr('common.cancel', 'Cancel');\n\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent className=\"max-w-md border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)]\">\n <AlertDialogHeader>\n <div className=\"flex items-start gap-4\">\n <div\n className={`flex h-10 w-10 items-center justify-center rounded-full ${styles.iconContainerClassName}`}\n >\n <Icon className={`h-5 w-5 ${styles.iconClassName}`} />\n </div>\n <div className=\"flex-1\">\n <AlertDialogTitle className=\"text-lg text-[var(--color-text-primary)]\">\n {title}\n </AlertDialogTitle>\n <AlertDialogDescription className=\"mt-2 text-sm text-[var(--color-text-secondary)]\">\n {description}\n </AlertDialogDescription>\n </div>\n </div>\n </AlertDialogHeader>\n\n <AlertDialogFooter className=\"mt-6\">\n <AlertDialogCancel className=\"border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-subtle)]\">\n {resolvedCancelText}\n </AlertDialogCancel>\n <AlertDialogAction onClick={onConfirm} className={styles.actionClassName}>\n {resolvedConfirmText}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n"],"mappings":";;;;;;AA2BA,IAAMA,IAQF;CACF,SAAS;EACP,MAAMC;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;CACJ;CACA,SAAS;EACP,MAAMC;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;CACJ;CACA,QAAQ;EACN,MAAMC;EACN,wBAAwB;EACxB,eAAe;EACf,iBACE;CACJ;AACF;AAEA,SAAgBC,EAAc,EAC5B,SACA,iBACA,UACA,gBACA,gBACA,eACA,aAAU,WACV,gBACqB;CACrB,IAAM,EAAE,SAAMC,EAAQ,GAChBC,IAAKC,GACR,GAAa,MAAqB;EACjC,IAAMC,IAAaC,EAAEC,CAAG;EACxB,OAAOF,MAAeE,IAAMC,IAAWH;CACzC,GACA,CAACC,CAAC,CACJ,GACMG,IAASZ,EAAea,IACxBC,IAAOF,EAAO,MACdG,IAAsBC,KAAeV,EAAG,kBAAkB,SAAS,GACnEW,IAAqBC,KAAcZ,EAAG,iBAAiB,QAAQ;CAErE,OACE,kBAACa,GAAD;EAAmB;EAAoB;EACrC,UAAA,kBAACC,GAAD;GAAoB,WAAU;GAA9B,UAAA,CACE,kBAACC,GAAD,EAAA,UACE,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,OAAD;KACE,WAAW,2DAA2DT,EAAO;KAE7E,UAAA,kBAACE,GAAD,EAAM,WAAW,WAAWF,EAAO,gBAAkB,CAAA;IAClD,CAAA,GACL,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAACU,GAAD;MAAkB,WAAU;MACzB,UAAAC;KACe,CAAA,GAClB,kBAACC,GAAD;MAAwB,WAAU;MAC/B,UAAAC;KACqB,CAAA,CACrB;IACF,CAAA,CAAA;GACY,CAAA,EAAA,CAAA,GAEnB,kBAACC,GAAD;IAAmB,WAAU;IAA7B,UAAA,CACE,kBAACC,GAAD;KAAmB,WAAU;KAC1B,UAAAV;IACgB,CAAA,GACnB,kBAACW,GAAD;KAAmB,SAASC;KAAW,WAAWjB,EAAO;KACtD,UAAAG;IACgB,CAAA,CACF;GACD,CAAA,CAAA;;CACT,CAAA;AAEjB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTr as e } from "../../hooks/useTr.js";
|
|
2
2
|
import { AlertCircle as t } from "lucide-react";
|
|
3
3
|
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/organization-management/shared/components/feedback/ErrorState.tsx
|
|
5
5
|
function i({ title: i, message: a, action: o }) {
|
|
6
6
|
let s = e(), c = i ?? s("common.error.title", "Something went wrong");
|
|
7
7
|
return /* @__PURE__ */ r("div", {
|
|
@@ -32,7 +32,6 @@ function i({ title: i, message: a, action: o }) {
|
|
|
32
32
|
]
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
//#endregion
|
|
36
35
|
export { i as ErrorState };
|
|
37
36
|
|
|
38
37
|
//# sourceMappingURL=ErrorState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorState.js","names":[],"sources":["../../../../../src/organization-management/shared/components/feedback/ErrorState.tsx"],"sourcesContent":["import { AlertCircle } from 'lucide-react';\nimport { useTr } from '../../hooks/useTr';\n\ninterface ErrorStateProps {\n title?: string;\n message: string;\n action?: {\n label: string;\n onClick: () => void;\n };\n}\n\nexport function ErrorState({ title, message, action }: ErrorStateProps) {\n const tr = useTr();\n const resolvedTitle = title ?? tr('common.error.title', 'Something went wrong');\n return (\n <div\n className=\"flex flex-col items-center justify-center py-12 text-center animate-in fade-in duration-200\"\n role=\"alert\"\n >\n <div className=\"size-16 rounded-full bg-[var(--color-status-error-muted)] flex items-center justify-center mb-4\">\n <AlertCircle size={32} className=\"text-[var(--color-status-error)]\" />\n </div>\n <h3 className=\"text-lg font-semibold text-[var(--color-text-primary)] mb-2\">\n {resolvedTitle}\n </h3>\n <p className=\"text-sm text-[var(--color-text-muted)] mb-6 max-w-md\">{message}</p>\n {action && (\n <button\n type=\"button\"\n onClick={action.onClick}\n className=\"\n inline-flex items-center gap-2 px-4 py-2\n bg-[var(--color-action-primary-bg)]\n text-[var(--color-action-primary-text)]\n rounded-lg\n hover:opacity-90\n \n transition-all duration-200\n font-medium\n \"\n >\n {action.label}\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAYA,
|
|
1
|
+
{"version":3,"file":"ErrorState.js","names":["ErrorState","tr","useTr","resolvedTitle","title","AlertCircle","message","action"],"sources":["../../../../../src/organization-management/shared/components/feedback/ErrorState.tsx"],"sourcesContent":["import { AlertCircle } from 'lucide-react';\nimport { useTr } from '../../hooks/useTr';\n\ninterface ErrorStateProps {\n title?: string;\n message: string;\n action?: {\n label: string;\n onClick: () => void;\n };\n}\n\nexport function ErrorState({ title, message, action }: ErrorStateProps) {\n const tr = useTr();\n const resolvedTitle = title ?? tr('common.error.title', 'Something went wrong');\n return (\n <div\n className=\"flex flex-col items-center justify-center py-12 text-center animate-in fade-in duration-200\"\n role=\"alert\"\n >\n <div className=\"size-16 rounded-full bg-[var(--color-status-error-muted)] flex items-center justify-center mb-4\">\n <AlertCircle size={32} className=\"text-[var(--color-status-error)]\" />\n </div>\n <h3 className=\"text-lg font-semibold text-[var(--color-text-primary)] mb-2\">\n {resolvedTitle}\n </h3>\n <p className=\"text-sm text-[var(--color-text-muted)] mb-6 max-w-md\">{message}</p>\n {action && (\n <button\n type=\"button\"\n onClick={action.onClick}\n className=\"\n inline-flex items-center gap-2 px-4 py-2\n bg-[var(--color-action-primary-bg)]\n text-[var(--color-action-primary-text)]\n rounded-lg\n hover:opacity-90\n \n transition-all duration-200\n font-medium\n \"\n >\n {action.label}\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAYA,SAAgBA,EAAW,EAAE,UAAO,YAAS,aAA2B;CACtE,IAAMC,IAAKC,EAAM,GACXC,IAAgBC,KAASH,EAAG,sBAAsB,sBAAsB;CAC9E,OACE,kBAAC,OAAD;EACE,WAAU;EACV,MAAK;EAFP,UAAA;GAIE,kBAAC,OAAD;IAAK,WAAU;IACb,UAAA,kBAACI,GAAD;KAAa,MAAM;KAAI,WAAU;IAAoC,CAAA;GAClE,CAAA;GACL,kBAAC,MAAD;IAAI,WAAU;IACX,UAAAF;GACC,CAAA;GACJ,kBAAC,KAAD;IAAG,WAAU;IAAwD,UAAAG;GAAW,CAAA;GAC/EC,KACC,kBAAC,UAAD;IACE,MAAK;IACL,SAASA,EAAO;IAChB,WAAU;IAWT,UAAAA,EAAO;GACF,CAAA;EAEP;;AAET"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTr as e } from "../../hooks/useTr.js";
|
|
2
2
|
import { Loader2 as t } from "lucide-react";
|
|
3
3
|
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/organization-management/shared/components/feedback/LoadingState.tsx
|
|
5
5
|
function i({ message: i }) {
|
|
6
6
|
let a = e(), o = i ?? a("common.loading", "Loading...");
|
|
7
7
|
return /* @__PURE__ */ r("output", {
|
|
@@ -17,7 +17,6 @@ function i({ message: i }) {
|
|
|
17
17
|
})]
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
|
-
//#endregion
|
|
21
20
|
export { i as LoadingState };
|
|
22
21
|
|
|
23
22
|
//# sourceMappingURL=LoadingState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadingState.js","names":[],"sources":["../../../../../src/organization-management/shared/components/feedback/LoadingState.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\nimport { useTr } from '../../hooks/useTr';\n\ninterface LoadingStateProps {\n message?: string;\n}\n\nexport function LoadingState({ message }: LoadingStateProps) {\n const tr = useTr();\n const resolvedMessage = message ?? tr('common.loading', 'Loading...');\n return (\n <output\n className=\"flex flex-col items-center justify-center py-12 animate-in fade-in duration-200\"\n aria-live=\"polite\"\n aria-busy=\"true\"\n >\n <Loader2 size={48} className=\"text-[var(--color-status-info)] animate-spin mb-4\" />\n <p className=\"text-sm text-[var(--color-text-muted)]\">{resolvedMessage}</p>\n </output>\n );\n}\n"],"mappings":";;;;AAOA,
|
|
1
|
+
{"version":3,"file":"LoadingState.js","names":["LoadingState","tr","useTr","resolvedMessage","message","Loader2"],"sources":["../../../../../src/organization-management/shared/components/feedback/LoadingState.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\nimport { useTr } from '../../hooks/useTr';\n\ninterface LoadingStateProps {\n message?: string;\n}\n\nexport function LoadingState({ message }: LoadingStateProps) {\n const tr = useTr();\n const resolvedMessage = message ?? tr('common.loading', 'Loading...');\n return (\n <output\n className=\"flex flex-col items-center justify-center py-12 animate-in fade-in duration-200\"\n aria-live=\"polite\"\n aria-busy=\"true\"\n >\n <Loader2 size={48} className=\"text-[var(--color-status-info)] animate-spin mb-4\" />\n <p className=\"text-sm text-[var(--color-text-muted)]\">{resolvedMessage}</p>\n </output>\n );\n}\n"],"mappings":";;;;AAOA,SAAgBA,EAAa,EAAE,cAA8B;CAC3D,IAAMC,IAAKC,EAAM,GACXC,IAAkBC,KAAWH,EAAG,kBAAkB,YAAY;CACpE,OACE,kBAAC,UAAD;EACE,WAAU;EACV,aAAU;EACV,aAAU;EAHZ,UAAA,CAKE,kBAACI,GAAD;GAAS,MAAM;GAAI,WAAU;EAAqD,CAAA,GAClF,kBAAC,KAAD;GAAG,WAAU;GAA0C,UAAAF;EAAmB,CAAA,CACpE;;AAEZ"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTr as e } from "../../hooks/useTr.js";
|
|
2
2
|
import { Search as t, X as n } from "lucide-react";
|
|
3
3
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
4
|
-
|
|
4
|
+
// src/organization-management/shared/components/input/SearchInput.tsx
|
|
5
5
|
function a({ value: a, onChange: o, placeholder: s, className: c = "", label: l, inputId: u }) {
|
|
6
6
|
let d = e(), f = s ?? d("common.search.placeholder", "Search...");
|
|
7
7
|
return /* @__PURE__ */ i("div", {
|
|
@@ -35,7 +35,6 @@ function a({ value: a, onChange: o, placeholder: s, className: c = "", label: l,
|
|
|
35
35
|
]
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
-
//#endregion
|
|
39
38
|
export { a as SearchInput };
|
|
40
39
|
|
|
41
40
|
//# sourceMappingURL=SearchInput.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchInput.js","names":[],"sources":["../../../../../src/organization-management/shared/components/input/SearchInput.tsx"],"sourcesContent":["import { Search, X } from 'lucide-react';\nimport { useTr } from '../../hooks/useTr';\n\ninterface SearchInputProps {\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n className?: string;\n label?: string;\n inputId?: string;\n}\n\n/**\n * SearchInput\n * Reusable search input component with clear button\n */\nexport function SearchInput({\n value,\n onChange,\n placeholder,\n className = '',\n label,\n inputId,\n}: SearchInputProps) {\n const tr = useTr();\n const resolvedPlaceholder = placeholder ?? tr('common.search.placeholder', 'Search...');\n return (\n <div className={`relative ${className}`}>\n {label ? (\n <label htmlFor={inputId} className=\"sr-only\">\n {label}\n </label>\n ) : null}\n <Search\n size={18}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-muted)]\"\n />\n <input\n id={inputId}\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={resolvedPlaceholder}\n aria-label={label ?? resolvedPlaceholder}\n className=\"\n w-full pl-[3.25rem] pr-10 py-2\n bg-[var(--color-bg-surface)]\n border border-[var(--color-border-default)]\n rounded-lg\n text-[var(--color-text-primary)]\n placeholder:text-[var(--color-text-muted)]\n focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]\n transition-all duration-200\n \"\n />\n {value && (\n <button\n type=\"button\"\n onClick={() => onChange('')}\n className=\"\n absolute right-3 top-1/2 -translate-y-1/2\n p-1 rounded-md\n text-[var(--color-text-muted)]\n hover:text-[var(--color-text-primary)]\n hover:bg-[var(--color-bg-subtle)]\n \n transition-all duration-200\n \"\n aria-label={tr('common.clearSearch', 'Clear search')}\n >\n <X size={16} />\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAgBA,
|
|
1
|
+
{"version":3,"file":"SearchInput.js","names":["SearchInput","tr","useTr","resolvedPlaceholder","placeholder","className","label","inputId","Search","onChange","value","X"],"sources":["../../../../../src/organization-management/shared/components/input/SearchInput.tsx"],"sourcesContent":["import { Search, X } from 'lucide-react';\nimport { useTr } from '../../hooks/useTr';\n\ninterface SearchInputProps {\n value: string;\n onChange: (value: string) => void;\n placeholder?: string;\n className?: string;\n label?: string;\n inputId?: string;\n}\n\n/**\n * SearchInput\n * Reusable search input component with clear button\n */\nexport function SearchInput({\n value,\n onChange,\n placeholder,\n className = '',\n label,\n inputId,\n}: SearchInputProps) {\n const tr = useTr();\n const resolvedPlaceholder = placeholder ?? tr('common.search.placeholder', 'Search...');\n return (\n <div className={`relative ${className}`}>\n {label ? (\n <label htmlFor={inputId} className=\"sr-only\">\n {label}\n </label>\n ) : null}\n <Search\n size={18}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-muted)]\"\n />\n <input\n id={inputId}\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={resolvedPlaceholder}\n aria-label={label ?? resolvedPlaceholder}\n className=\"\n w-full pl-[3.25rem] pr-10 py-2\n bg-[var(--color-bg-surface)]\n border border-[var(--color-border-default)]\n rounded-lg\n text-[var(--color-text-primary)]\n placeholder:text-[var(--color-text-muted)]\n focus:outline-none focus:ring-2 focus:ring-[var(--color-border-focus)]\n transition-all duration-200\n \"\n />\n {value && (\n <button\n type=\"button\"\n onClick={() => onChange('')}\n className=\"\n absolute right-3 top-1/2 -translate-y-1/2\n p-1 rounded-md\n text-[var(--color-text-muted)]\n hover:text-[var(--color-text-primary)]\n hover:bg-[var(--color-bg-subtle)]\n \n transition-all duration-200\n \"\n aria-label={tr('common.clearSearch', 'Clear search')}\n >\n <X size={16} />\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAgBA,SAAgBA,EAAY,EAC1B,UACA,aACA,gBACA,eAAY,IACZ,UACA,cACmB;CACnB,IAAMC,IAAKC,EAAM,GACXC,IAAsBC,KAAeH,EAAG,6BAA6B,WAAW;CACtF,OACE,kBAAC,OAAD;EAAK,WAAW,YAAYI;EAA5B,UAAA;GACGC,IACC,kBAAC,SAAD;IAAO,SAASC;IAAS,WAAU;IAChC,UAAAD;GACI,CAAA,IACL;GACJ,kBAACE,GAAD;IACE,MAAM;IACN,WAAU;GACX,CAAA;GACD,kBAAC,SAAD;IACE,IAAID;IACJ,MAAK;IACE;IACP,WAAW,MAAME,EAAS,EAAE,OAAO,KAAK;IACxC,aAAaN;IACb,cAAYG,KAASH;IACrB,WAAU;GAUX,CAAA;GACAO,KACC,kBAAC,UAAD;IACE,MAAK;IACL,eAAeD,EAAS,EAAE;IAC1B,WAAU;IASV,cAAYR,EAAG,sBAAsB,cAAc;IAEnD,UAAA,kBAACU,GAAD,EAAG,MAAM,GAAK,CAAA;GACR,CAAA;EAEP;;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect as e, useRef as t } from "react";
|
|
2
2
|
import { jsx as n } from "react/jsx-runtime";
|
|
3
|
-
|
|
3
|
+
// src/organization-management/shared/components/input/SelectionCheckbox.tsx
|
|
4
4
|
function r({ checked: r, indeterminate: i = !1, disabled: a = !1, onChange: o, ariaLabel: s }) {
|
|
5
5
|
let c = t(null);
|
|
6
6
|
return e(() => {
|
|
@@ -15,7 +15,6 @@ function r({ checked: r, indeterminate: i = !1, disabled: a = !1, onChange: o, a
|
|
|
15
15
|
className: "size-4 rounded border-[var(--color-border-default)] text-[var(--color-action-primary-bg)] focus:ring-2 focus:ring-[var(--color-border-focus)]"
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
//#endregion
|
|
19
18
|
export { r as SelectionCheckbox };
|
|
20
19
|
|
|
21
20
|
//# sourceMappingURL=SelectionCheckbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectionCheckbox.js","names":[],"sources":["../../../../../src/organization-management/shared/components/input/SelectionCheckbox.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\ninterface SelectionCheckboxProps {\n checked: boolean;\n indeterminate?: boolean;\n disabled?: boolean;\n onChange: (checked: boolean) => void;\n ariaLabel: string;\n}\n\nexport function SelectionCheckbox({\n checked,\n indeterminate = false,\n disabled = false,\n onChange,\n ariaLabel,\n}: SelectionCheckboxProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.indeterminate = indeterminate && !checked;\n }\n }, [checked, indeterminate]);\n\n return (\n <input\n ref={inputRef}\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n aria-label={ariaLabel}\n onChange={(event) => onChange(event.target.checked)}\n className=\"size-4 rounded border-[var(--color-border-default)] text-[var(--color-action-primary-bg)] focus:ring-2 focus:ring-[var(--color-border-focus)]\"\n />\n );\n}\n"],"mappings":";;;AAUA,
|
|
1
|
+
{"version":3,"file":"SelectionCheckbox.js","names":["SelectionCheckbox","inputRef","useRef","useEffect","indeterminate","checked","ariaLabel","onChange","event"],"sources":["../../../../../src/organization-management/shared/components/input/SelectionCheckbox.tsx"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\ninterface SelectionCheckboxProps {\n checked: boolean;\n indeterminate?: boolean;\n disabled?: boolean;\n onChange: (checked: boolean) => void;\n ariaLabel: string;\n}\n\nexport function SelectionCheckbox({\n checked,\n indeterminate = false,\n disabled = false,\n onChange,\n ariaLabel,\n}: SelectionCheckboxProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.indeterminate = indeterminate && !checked;\n }\n }, [checked, indeterminate]);\n\n return (\n <input\n ref={inputRef}\n type=\"checkbox\"\n checked={checked}\n disabled={disabled}\n aria-label={ariaLabel}\n onChange={(event) => onChange(event.target.checked)}\n className=\"size-4 rounded border-[var(--color-border-default)] text-[var(--color-action-primary-bg)] focus:ring-2 focus:ring-[var(--color-border-focus)]\"\n />\n );\n}\n"],"mappings":";;;AAUA,SAAgBA,EAAkB,EAChC,YACA,mBAAgB,IAChB,cAAW,IACX,aACA,gBACyB;CACzB,IAAMC,IAAWC,EAAyB,IAAI;CAQ9C,OANAC,QAAgB;EACd,AAAIF,EAAS,YACX,EAAS,QAAQ,gBAAgBG,KAAiB,CAACC;CAEvD,GAAG,CAACA,GAASD,CAAa,CAAC,GAGzB,kBAAC,SAAD;EACE,KAAKH;EACL,MAAK;EACI;EACC;EACV,cAAYK;EACZ,WAAW,MAAUC,EAASC,EAAM,OAAO,OAAO;EAClD,WAAU;CACX,CAAA;AAEL"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect as e, useState as t } from "react";
|
|
2
|
-
|
|
2
|
+
// src/organization-management/shared/hooks/useDebouncedValue.ts
|
|
3
3
|
function n(n, r = 300) {
|
|
4
4
|
let [i, a] = t(n);
|
|
5
5
|
return e(() => {
|
|
@@ -11,7 +11,6 @@ function n(n, r = 300) {
|
|
|
11
11
|
};
|
|
12
12
|
}, [r, n]), i;
|
|
13
13
|
}
|
|
14
|
-
//#endregion
|
|
15
14
|
export { n as useDebouncedValue };
|
|
16
15
|
|
|
17
16
|
//# sourceMappingURL=useDebouncedValue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDebouncedValue.js","names":[],"sources":["../../../../src/organization-management/shared/hooks/useDebouncedValue.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport function useDebouncedValue<T>(value: T, delay = 300): T {\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n window.clearTimeout(timeoutId);\n };\n }, [delay, value]);\n\n return debouncedValue;\n}\n"],"mappings":";;AAEA,
|
|
1
|
+
{"version":3,"file":"useDebouncedValue.js","names":["useDebouncedValue","debouncedValue","setDebouncedValue","useState","value","useEffect","timeoutId","delay"],"sources":["../../../../src/organization-management/shared/hooks/useDebouncedValue.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport function useDebouncedValue<T>(value: T, delay = 300): T {\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(() => {\n const timeoutId = window.setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n window.clearTimeout(timeoutId);\n };\n }, [delay, value]);\n\n return debouncedValue;\n}\n"],"mappings":";;AAEA,SAAgBA,EAAqB,GAAU,IAAQ,KAAQ;CAC7D,IAAM,CAACC,GAAgBC,KAAqBC,EAASC,CAAK;CAY1D,OAVAC,QAAgB;EACd,IAAMC,IAAY,OAAO,iBAAiB;GACxC,EAAkBF,CAAK;EACzB,GAAGG,CAAK;EAER,aAAa;GACX,OAAO,aAAaD,CAAS;EAC/B;CACF,GAAG,CAACC,GAAOH,CAAK,CAAC,GAEVH;AACT"}
|