@burdenoff/microfe-workspaces 2026.830.1 → 2026.830.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/components/CreateProjectDialog.js +65 -61
- package/dist/components/CreateProjectDialog.js.map +1 -1
- package/dist/components/CreateWorkspaceDialog.js +93 -90
- package/dist/components/CreateWorkspaceDialog.js.map +1 -1
- package/dist/components/InviteMemberDialog.js +122 -111
- package/dist/components/InviteMemberDialog.js.map +1 -1
- package/dist/components/MemberListItem.js +55 -58
- package/dist/components/MemberListItem.js.map +1 -1
- package/dist/components/ProjectCard.js +93 -92
- package/dist/components/ProjectCard.js.map +1 -1
- package/dist/components/ProjectMemberPickerDialog.js +78 -93
- package/dist/components/ProjectMemberPickerDialog.js.map +1 -1
- package/dist/components/RenameProjectDialog.js +47 -44
- package/dist/components/RenameProjectDialog.js.map +1 -1
- package/dist/components/WorkspaceCard.js +42 -43
- package/dist/components/WorkspaceCard.js.map +1 -1
- package/dist/components/WorkspacesErrorBoundary.js +43 -34
- package/dist/components/WorkspacesErrorBoundary.js.map +1 -1
- package/dist/components/tags/ProjectTagsWidget.js +75 -77
- package/dist/components/tags/ProjectTagsWidget.js.map +1 -1
- package/dist/hooks/useTr.js +14 -0
- package/dist/hooks/useTr.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/pages/ActivityListPage.js +3 -3
- package/dist/pages/CreateWorkspacePage.js +10 -10
- package/dist/pages/InviteAcceptancePage.js +49 -49
- package/dist/pages/InviteAcceptancePage.js.map +1 -1
- package/dist/pages/MembersListPage.js +6 -6
- package/dist/pages/PendingInvitesPage.js +3 -3
- package/dist/pages/ProjectDetailPage.js +4 -4
- package/dist/pages/ProjectDetailPage.js.map +1 -1
- package/dist/pages/ProjectMembersPage.js +3 -3
- package/dist/pages/ProjectsListPage.js +5 -5
- package/dist/pages/WorkspaceDetailPage.js +4 -4
- package/dist/pages/WorkspaceInvitePage.js +4 -4
- package/dist/pages/WorkspaceSettingsPage.js +7 -7
- package/dist/pages/WorkspacesListPage.js +9 -9
- package/dist/pages/dashboard/widgets/RecentActivityWidget.js +4 -4
- package/dist/pages/dashboard/widgets/StorageWidget.js +3 -3
- package/dist/translations/en.js +908 -0
- package/dist/translations/en.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,106 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { useTr as e } from "../hooks/useTr.js";
|
|
2
|
+
import { useWorkspacesStore as t } from "../store/workspacesStore.js";
|
|
3
|
+
import { useCreateProject as n } from "../hooks/useProjectMutations.js";
|
|
4
|
+
import { useMemo as r } from "react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
import { Button as o, ResponsiveDialog as s, ResponsiveDialogContent as c, ResponsiveDialogDescription as l, ResponsiveDialogHeader as u, ResponsiveDialogTitle as d } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
import { FormControl as f, FormDescription as p, FormField as m, FormItem as h, FormLabel as g, FormMessage as _, FormProvider as v, Input as y, Textarea as b, useForm as x, z as S } from "@burdenoff/fe-libs/form";
|
|
6
8
|
//#region src/components/CreateProjectDialog.tsx
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
function C(e) {
|
|
10
|
+
return S.object({
|
|
11
|
+
name: S.string().min(2, e("createProjectDialog.validation.nameMin", "Name must be at least 2 characters")).max(100, e("createProjectDialog.validation.nameMax", "Name must be less than 100 characters")),
|
|
12
|
+
key: S.string().min(2, e("createProjectDialog.validation.keyMin", "Key must be at least 2 characters")).max(10, e("createProjectDialog.validation.keyMax", "Key must be less than 10 characters")).regex(/^[A-Z0-9_-]+$/, e("createProjectDialog.validation.keyFormat", "Key must be uppercase letters, numbers, underscores, or hyphens")),
|
|
13
|
+
description: S.string().optional()
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function w({ workspaceId: S }) {
|
|
17
|
+
let w = e(), { isCreateProjectDialogOpen: T, closeCreateProjectDialog: E } = t(), { mutate: D, isPending: O } = n(S), k = x({
|
|
18
|
+
schema: r(() => C(w), [w]),
|
|
15
19
|
defaultValues: {
|
|
16
20
|
name: "",
|
|
17
21
|
key: "",
|
|
18
22
|
description: ""
|
|
19
23
|
}
|
|
20
|
-
}),
|
|
21
|
-
|
|
24
|
+
}), A = (e) => {
|
|
25
|
+
D({
|
|
22
26
|
name: e.name,
|
|
23
27
|
key: e.key,
|
|
24
28
|
config: e.description ? { description: e.description } : void 0
|
|
25
29
|
}, {
|
|
26
30
|
onSuccess: () => {
|
|
27
|
-
|
|
31
|
+
E(), k.reset();
|
|
28
32
|
},
|
|
29
33
|
onError: (e) => {
|
|
30
34
|
console.error("Failed to create project:", e);
|
|
31
35
|
}
|
|
32
36
|
});
|
|
33
|
-
},
|
|
34
|
-
e || (
|
|
35
|
-
},
|
|
37
|
+
}, j = (e) => {
|
|
38
|
+
e || (E(), k.reset());
|
|
39
|
+
}, M = (e) => {
|
|
36
40
|
let t = e.toUpperCase().replace(/[^A-Z0-9\s]/g, "").replace(/\s+/g, "_").slice(0, 10);
|
|
37
|
-
|
|
41
|
+
k.getValues("key") || k.setValue("key", t);
|
|
38
42
|
};
|
|
39
|
-
return /* @__PURE__ */
|
|
40
|
-
open:
|
|
41
|
-
onOpenChange:
|
|
42
|
-
children: /* @__PURE__ */
|
|
43
|
+
return /* @__PURE__ */ i(s, {
|
|
44
|
+
open: T,
|
|
45
|
+
onOpenChange: j,
|
|
46
|
+
children: /* @__PURE__ */ a(c, {
|
|
43
47
|
className: "sm:max-w-[500px]",
|
|
44
|
-
children: [/* @__PURE__ */
|
|
45
|
-
...
|
|
46
|
-
children: /* @__PURE__ */
|
|
47
|
-
onSubmit:
|
|
48
|
+
children: [/* @__PURE__ */ a(u, { children: [/* @__PURE__ */ i(d, { children: w("createProjectDialog.title", "Create Project") }), /* @__PURE__ */ i(l, { children: w("createProjectDialog.description", "Create a new project in your workspace. Projects help organize your work.") })] }), /* @__PURE__ */ i(v, {
|
|
49
|
+
...k,
|
|
50
|
+
children: /* @__PURE__ */ a("form", {
|
|
51
|
+
onSubmit: k.handleSubmit(A),
|
|
48
52
|
className: "space-y-4",
|
|
49
53
|
children: [
|
|
50
|
-
/* @__PURE__ */
|
|
51
|
-
control:
|
|
54
|
+
/* @__PURE__ */ i(m, {
|
|
55
|
+
control: k.control,
|
|
52
56
|
name: "name",
|
|
53
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
54
|
-
/* @__PURE__ */
|
|
55
|
-
/* @__PURE__ */
|
|
57
|
+
render: ({ field: e }) => /* @__PURE__ */ a(h, { children: [
|
|
58
|
+
/* @__PURE__ */ i(g, { children: w("createProjectDialog.nameLabel", "Project Name") }),
|
|
59
|
+
/* @__PURE__ */ i(f, { children: /* @__PURE__ */ i(y, {
|
|
56
60
|
...e,
|
|
57
|
-
placeholder: "My Project",
|
|
61
|
+
placeholder: w("createProjectDialog.namePlaceholder", "My Project"),
|
|
58
62
|
onChange: (t) => {
|
|
59
|
-
e.onChange(t),
|
|
63
|
+
e.onChange(t), M(t.target.value);
|
|
60
64
|
}
|
|
61
65
|
}) }),
|
|
62
|
-
/* @__PURE__ */
|
|
63
|
-
/* @__PURE__ */
|
|
66
|
+
/* @__PURE__ */ i(p, { children: w("createProjectDialog.nameHint", "A descriptive name for your project") }),
|
|
67
|
+
/* @__PURE__ */ i(_, {})
|
|
64
68
|
] })
|
|
65
69
|
}),
|
|
66
|
-
/* @__PURE__ */
|
|
67
|
-
control:
|
|
70
|
+
/* @__PURE__ */ i(m, {
|
|
71
|
+
control: k.control,
|
|
68
72
|
name: "key",
|
|
69
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
70
|
-
/* @__PURE__ */
|
|
71
|
-
/* @__PURE__ */
|
|
73
|
+
render: ({ field: e }) => /* @__PURE__ */ a(h, { children: [
|
|
74
|
+
/* @__PURE__ */ i(g, { children: w("createProjectDialog.keyLabel", "Project Key") }),
|
|
75
|
+
/* @__PURE__ */ i(f, { children: /* @__PURE__ */ i(y, {
|
|
72
76
|
...e,
|
|
73
|
-
placeholder: "MYPROJ"
|
|
77
|
+
placeholder: w("createProjectDialog.keyPlaceholder", "MYPROJ")
|
|
74
78
|
}) }),
|
|
75
|
-
/* @__PURE__ */
|
|
76
|
-
/* @__PURE__ */
|
|
79
|
+
/* @__PURE__ */ i(p, { children: w("createProjectDialog.keyHint", "Short identifier (uppercase letters, numbers, underscores)") }),
|
|
80
|
+
/* @__PURE__ */ i(_, {})
|
|
77
81
|
] })
|
|
78
82
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
80
|
-
control:
|
|
83
|
+
/* @__PURE__ */ i(m, {
|
|
84
|
+
control: k.control,
|
|
81
85
|
name: "description",
|
|
82
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
83
|
-
/* @__PURE__ */
|
|
84
|
-
/* @__PURE__ */
|
|
86
|
+
render: ({ field: e }) => /* @__PURE__ */ a(h, { children: [
|
|
87
|
+
/* @__PURE__ */ i(g, { children: w("createProjectDialog.descriptionLabel", "Description (Optional)") }),
|
|
88
|
+
/* @__PURE__ */ i(f, { children: /* @__PURE__ */ i(b, {
|
|
85
89
|
...e,
|
|
86
|
-
placeholder: "Brief description of the project",
|
|
90
|
+
placeholder: w("createProjectDialog.descriptionPlaceholder", "Brief description of the project"),
|
|
87
91
|
rows: 3
|
|
88
92
|
}) }),
|
|
89
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ i(_, {})
|
|
90
94
|
] })
|
|
91
95
|
}),
|
|
92
|
-
/* @__PURE__ */
|
|
96
|
+
/* @__PURE__ */ a("div", {
|
|
93
97
|
className: "flex justify-end gap-3 pt-4",
|
|
94
|
-
children: [/* @__PURE__ */
|
|
98
|
+
children: [/* @__PURE__ */ i(o, {
|
|
95
99
|
type: "button",
|
|
96
100
|
variant: "outline",
|
|
97
|
-
onClick: () =>
|
|
98
|
-
disabled:
|
|
99
|
-
children: "Cancel"
|
|
100
|
-
}), /* @__PURE__ */
|
|
101
|
+
onClick: () => j(!1),
|
|
102
|
+
disabled: O,
|
|
103
|
+
children: w("common.cancel", "Cancel")
|
|
104
|
+
}), /* @__PURE__ */ i(o, {
|
|
101
105
|
type: "submit",
|
|
102
|
-
disabled:
|
|
103
|
-
children:
|
|
106
|
+
disabled: O,
|
|
107
|
+
children: O ? w("createProjectDialog.creating", "Creating...") : w("createProjectDialog.submit", "Create Project")
|
|
104
108
|
})]
|
|
105
109
|
})
|
|
106
110
|
]
|
|
@@ -110,6 +114,6 @@ function S({ workspaceId: b }) {
|
|
|
110
114
|
});
|
|
111
115
|
}
|
|
112
116
|
//#endregion
|
|
113
|
-
export {
|
|
117
|
+
export { w as CreateProjectDialog };
|
|
114
118
|
|
|
115
119
|
//# sourceMappingURL=CreateProjectDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateProjectDialog.js","names":[],"sources":["../../src/components/CreateProjectDialog.tsx"],"sourcesContent":["import {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Button,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Textarea,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateProject } from '../hooks/useProjectMutations';\n\
|
|
1
|
+
{"version":3,"file":"CreateProjectDialog.js","names":[],"sources":["../../src/components/CreateProjectDialog.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Button,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Textarea,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateProject } from '../hooks/useProjectMutations';\nimport { useTr } from '../hooks/useTr';\n\nfunction createProjectSchema(tr: ReturnType<typeof useTr>) {\n return z.object({\n name: z\n .string()\n .min(2, tr('createProjectDialog.validation.nameMin', 'Name must be at least 2 characters'))\n .max(\n 100,\n tr('createProjectDialog.validation.nameMax', 'Name must be less than 100 characters')\n ),\n key: z\n .string()\n .min(2, tr('createProjectDialog.validation.keyMin', 'Key must be at least 2 characters'))\n .max(10, tr('createProjectDialog.validation.keyMax', 'Key must be less than 10 characters'))\n .regex(\n /^[A-Z0-9_-]+$/,\n tr(\n 'createProjectDialog.validation.keyFormat',\n 'Key must be uppercase letters, numbers, underscores, or hyphens'\n )\n ),\n description: z.string().optional(),\n });\n}\n\ntype CreateProjectFormData = z.infer<ReturnType<typeof createProjectSchema>>;\n\ninterface CreateProjectDialogProps {\n workspaceId?: string;\n}\n\nexport function CreateProjectDialog({ workspaceId }: CreateProjectDialogProps) {\n const tr = useTr();\n const { isCreateProjectDialogOpen, closeCreateProjectDialog } = useWorkspacesStore();\n const { mutate: createProject, isPending } = useCreateProject(workspaceId);\n\n const schema = useMemo(() => createProjectSchema(tr), [tr]);\n\n const form = useForm({\n schema,\n defaultValues: {\n name: '',\n key: '',\n description: '',\n },\n });\n\n const onSubmit = (data: CreateProjectFormData) => {\n const input = {\n name: data.name,\n key: data.key,\n config: data.description ? { description: data.description } : undefined,\n };\n\n createProject(input, {\n onSuccess: () => {\n closeCreateProjectDialog();\n form.reset();\n },\n onError: (error) => {\n console.error('Failed to create project:', error);\n },\n });\n };\n\n const handleOpenChange = (open: boolean) => {\n if (!open) {\n closeCreateProjectDialog();\n form.reset();\n }\n };\n\n // Auto-generate key from name\n const handleNameChange = (name: string) => {\n const autoKey = name\n .toUpperCase()\n .replace(/[^A-Z0-9\\s]/g, '')\n .replace(/\\s+/g, '_')\n .slice(0, 10);\n\n if (!form.getValues('key')) {\n form.setValue('key', autoKey);\n }\n };\n\n return (\n <ResponsiveDialog open={isCreateProjectDialogOpen} onOpenChange={handleOpenChange}>\n <ResponsiveDialogContent className=\"sm:max-w-[500px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {tr('createProjectDialog.title', 'Create Project')}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {tr(\n 'createProjectDialog.description',\n 'Create a new project in your workspace. Projects help organize your work.'\n )}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{tr('createProjectDialog.nameLabel', 'Project Name')}</FormLabel>\n <FormControl>\n <Input\n {...field}\n placeholder={tr('createProjectDialog.namePlaceholder', 'My Project')}\n onChange={(e) => {\n field.onChange(e);\n handleNameChange(e.target.value);\n }}\n />\n </FormControl>\n <FormDescription>\n {tr('createProjectDialog.nameHint', 'A descriptive name for your project')}\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"key\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{tr('createProjectDialog.keyLabel', 'Project Key')}</FormLabel>\n <FormControl>\n <Input\n {...field}\n placeholder={tr('createProjectDialog.keyPlaceholder', 'MYPROJ')}\n />\n </FormControl>\n <FormDescription>\n {tr(\n 'createProjectDialog.keyHint',\n 'Short identifier (uppercase letters, numbers, underscores)'\n )}\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"description\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>\n {tr('createProjectDialog.descriptionLabel', 'Description (Optional)')}\n </FormLabel>\n <FormControl>\n <Textarea\n {...field}\n placeholder={tr(\n 'createProjectDialog.descriptionPlaceholder',\n 'Brief description of the project'\n )}\n rows={3}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <div className=\"flex justify-end gap-3 pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => handleOpenChange(false)}\n disabled={isPending}\n >\n {tr('common.cancel', 'Cancel')}\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending\n ? tr('createProjectDialog.creating', 'Creating...')\n : tr('createProjectDialog.submit', 'Create Project')}\n </Button>\n </div>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,145 +1,148 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import { useTr as e } from "../hooks/useTr.js";
|
|
2
|
+
import { useWorkspacesStore as t } from "../store/workspacesStore.js";
|
|
3
|
+
import { useCreateWorkspace as n } from "../hooks/useWorkspaceMutations.js";
|
|
4
|
+
import { useMyOrganizations as r, useMyTenants as i } from "../hooks/useTenants.js";
|
|
5
|
+
import { generateSlug as a } from "../utils/slug.js";
|
|
6
|
+
import { useEffect as o, useMemo as s } from "react";
|
|
7
|
+
import { AlertCircle as c } from "lucide-react";
|
|
8
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
9
|
+
import { Button as d, ResponsiveDialog as f, ResponsiveDialogContent as p, ResponsiveDialogFooter as m, ResponsiveDialogHeader as h, ResponsiveDialogTitle as g, Skeleton as _ } from "@burdenoff/fe-libs/ui";
|
|
10
|
+
import { FormControl as v, FormDescription as y, FormField as b, FormItem as x, FormLabel as S, FormMessage as C, FormProvider as w, Input as T, Select as E, SelectContent as D, SelectItem as O, SelectTrigger as k, SelectValue as A, useForm as j, z as M } from "@burdenoff/fe-libs/form";
|
|
10
11
|
//#region src/components/CreateWorkspaceDialog.tsx
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
function N(e) {
|
|
13
|
+
return M.object({
|
|
14
|
+
name: M.string().min(2, e("createWorkspaceDialog.validation.nameMin", "Name must be at least 2 characters")).max(100),
|
|
15
|
+
slug: M.string().min(2, e("createWorkspaceDialog.validation.slugMin", "Slug must be at least 2 characters")).max(50).regex(/^[a-z0-9-]+$/, e("createWorkspaceDialog.validation.slugFormat", "Slug can only contain lowercase letters, numbers, and hyphens")),
|
|
16
|
+
tenantId: M.string().min(1, e("createWorkspaceDialog.validation.tenantRequired", "Please select a tenant")),
|
|
17
|
+
organizationId: M.string().min(1, e("createWorkspaceDialog.validation.organizationRequired", "Please select an organization"))
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function P() {
|
|
21
|
+
let M = e(), { isCreateWorkspaceDialogOpen: P, closeCreateWorkspaceDialog: F } = t(), { mutate: I, isPending: L } = n(), { data: R, isLoading: z, error: B } = i(), { data: V, isLoading: H, error: U } = r(), W = s(() => N(M), [M]), G = s(() => R?.items ?? [], [R]), K = s(() => V?.items ?? [], [V]), q = s(() => G.find((e) => e.type === "SHARED" || e.slug === "burdenoff-shared")?.id ?? G[0]?.id ?? "", [G]), J = j({
|
|
22
|
+
schema: W,
|
|
20
23
|
defaultValues: {
|
|
21
24
|
name: "",
|
|
22
25
|
slug: "",
|
|
23
26
|
tenantId: "",
|
|
24
27
|
organizationId: ""
|
|
25
28
|
}
|
|
26
|
-
}),
|
|
27
|
-
|
|
28
|
-
!
|
|
29
|
-
}, [
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}, [
|
|
34
|
-
|
|
35
|
-
}, [
|
|
36
|
-
let
|
|
37
|
-
|
|
29
|
+
}), Y = J.watch("tenantId"), X = J.watch("name");
|
|
30
|
+
o(() => {
|
|
31
|
+
!J.getValues("tenantId") && q && J.setValue("tenantId", q, { shouldValidate: !0 });
|
|
32
|
+
}, [q, J]);
|
|
33
|
+
let Z = s(() => Y ? K.filter((e) => e.tenantId === Y) : [], [Y, K]);
|
|
34
|
+
o(() => {
|
|
35
|
+
J.setValue("slug", X ? a(X) : "");
|
|
36
|
+
}, [X, J]), o(() => {
|
|
37
|
+
J.setValue("organizationId", "");
|
|
38
|
+
}, [Y, J]);
|
|
39
|
+
let Q = (e) => {
|
|
40
|
+
I({
|
|
38
41
|
name: e.name,
|
|
39
42
|
slug: e.slug,
|
|
40
43
|
tenantId: e.tenantId,
|
|
41
44
|
organizationId: e.organizationId
|
|
42
45
|
}, { onSuccess: () => {
|
|
43
|
-
|
|
46
|
+
F(), J.reset();
|
|
44
47
|
} });
|
|
45
48
|
};
|
|
46
|
-
return /* @__PURE__ */
|
|
47
|
-
open:
|
|
48
|
-
onOpenChange:
|
|
49
|
-
children: /* @__PURE__ */
|
|
49
|
+
return /* @__PURE__ */ l(f, {
|
|
50
|
+
open: P,
|
|
51
|
+
onOpenChange: F,
|
|
52
|
+
children: /* @__PURE__ */ u(p, {
|
|
50
53
|
className: "sm:max-w-[500px]",
|
|
51
|
-
children: [/* @__PURE__ */
|
|
52
|
-
...
|
|
53
|
-
children: /* @__PURE__ */
|
|
54
|
-
onSubmit:
|
|
54
|
+
children: [/* @__PURE__ */ l(h, { children: /* @__PURE__ */ l(g, { children: M("createWorkspaceDialog.title", "Create Workspace") }) }), /* @__PURE__ */ l(w, {
|
|
55
|
+
...J,
|
|
56
|
+
children: /* @__PURE__ */ u("form", {
|
|
57
|
+
onSubmit: J.handleSubmit(Q),
|
|
55
58
|
className: "space-y-4",
|
|
56
59
|
children: [
|
|
57
|
-
/* @__PURE__ */
|
|
58
|
-
control:
|
|
60
|
+
/* @__PURE__ */ l(b, {
|
|
61
|
+
control: J.control,
|
|
59
62
|
name: "name",
|
|
60
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
-
/* @__PURE__ */
|
|
63
|
-
placeholder: "My Workspace",
|
|
63
|
+
render: ({ field: e }) => /* @__PURE__ */ u(x, { children: [
|
|
64
|
+
/* @__PURE__ */ l(S, { children: M("createWorkspaceDialog.nameLabel", "Workspace Name *") }),
|
|
65
|
+
/* @__PURE__ */ l(v, { children: /* @__PURE__ */ l(T, {
|
|
66
|
+
placeholder: M("createWorkspaceDialog.namePlaceholder", "My Workspace"),
|
|
64
67
|
...e
|
|
65
68
|
}) }),
|
|
66
|
-
/* @__PURE__ */
|
|
67
|
-
/* @__PURE__ */
|
|
69
|
+
/* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.nameHint", "A descriptive name for your workspace") }),
|
|
70
|
+
/* @__PURE__ */ l(C, {})
|
|
68
71
|
] })
|
|
69
72
|
}),
|
|
70
|
-
/* @__PURE__ */
|
|
71
|
-
control:
|
|
73
|
+
/* @__PURE__ */ l(b, {
|
|
74
|
+
control: J.control,
|
|
72
75
|
name: "slug",
|
|
73
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
74
|
-
/* @__PURE__ */
|
|
75
|
-
/* @__PURE__ */
|
|
76
|
-
placeholder: "my-workspace",
|
|
76
|
+
render: ({ field: e }) => /* @__PURE__ */ u(x, { children: [
|
|
77
|
+
/* @__PURE__ */ l(S, { children: M("createWorkspaceDialog.slugLabel", "Slug *") }),
|
|
78
|
+
/* @__PURE__ */ l(v, { children: /* @__PURE__ */ l(T, {
|
|
79
|
+
placeholder: M("createWorkspaceDialog.slugPlaceholder", "my-workspace"),
|
|
77
80
|
...e
|
|
78
81
|
}) }),
|
|
79
|
-
/* @__PURE__ */
|
|
80
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.slugHint", "URL-friendly identifier (auto-generated)") }),
|
|
83
|
+
/* @__PURE__ */ l(C, {})
|
|
81
84
|
] })
|
|
82
85
|
}),
|
|
83
|
-
|
|
84
|
-
control:
|
|
86
|
+
G.length === 1 ? null : /* @__PURE__ */ l(b, {
|
|
87
|
+
control: J.control,
|
|
85
88
|
name: "tenantId",
|
|
86
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
87
|
-
/* @__PURE__ */
|
|
88
|
-
|
|
89
|
+
render: ({ field: e }) => /* @__PURE__ */ u(x, { children: [
|
|
90
|
+
/* @__PURE__ */ l(S, { children: M("createWorkspaceDialog.tenantLabel", "Tenant *") }),
|
|
91
|
+
z ? /* @__PURE__ */ l(_, { className: "h-10 w-full" }) : B ? /* @__PURE__ */ u("div", {
|
|
89
92
|
className: "flex items-center gap-2 text-status-error-text text-sm",
|
|
90
|
-
children: [/* @__PURE__ */ c
|
|
91
|
-
}) :
|
|
93
|
+
children: [/* @__PURE__ */ l(c, { size: 16 }), M("createWorkspaceDialog.failedToLoadTenants", "Failed to load tenants")]
|
|
94
|
+
}) : G.length === 0 ? /* @__PURE__ */ l("div", {
|
|
92
95
|
className: "text-text-secondary text-sm",
|
|
93
|
-
children: "No tenants available. Contact your administrator."
|
|
94
|
-
}) : /* @__PURE__ */
|
|
96
|
+
children: M("createWorkspaceDialog.noTenantsAvailable", "No tenants available. Contact your administrator.")
|
|
97
|
+
}) : /* @__PURE__ */ u(E, {
|
|
95
98
|
onValueChange: e.onChange,
|
|
96
99
|
value: e.value,
|
|
97
|
-
children: [/* @__PURE__ */
|
|
100
|
+
children: [/* @__PURE__ */ l(v, { children: /* @__PURE__ */ l(k, { children: /* @__PURE__ */ l(A, { placeholder: M("createWorkspaceDialog.selectTenantPlaceholder", "Select a tenant") }) }) }), /* @__PURE__ */ l(D, { children: G.map((e) => /* @__PURE__ */ l(O, {
|
|
98
101
|
value: e.id,
|
|
99
102
|
children: e.name
|
|
100
103
|
}, e.id)) })]
|
|
101
104
|
}),
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
-
/* @__PURE__ */
|
|
105
|
+
/* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.tenantHint", "Select which tenant this workspace belongs to") }),
|
|
106
|
+
/* @__PURE__ */ l(C, {})
|
|
104
107
|
] })
|
|
105
108
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
control:
|
|
109
|
+
/* @__PURE__ */ l(b, {
|
|
110
|
+
control: J.control,
|
|
108
111
|
name: "organizationId",
|
|
109
|
-
render: ({ field: e }) => /* @__PURE__ */
|
|
110
|
-
/* @__PURE__ */
|
|
111
|
-
|
|
112
|
+
render: ({ field: e }) => /* @__PURE__ */ u(x, { children: [
|
|
113
|
+
/* @__PURE__ */ l(S, { children: M("createWorkspaceDialog.organizationLabel", "Organization *") }),
|
|
114
|
+
H ? /* @__PURE__ */ l(_, { className: "h-10 w-full" }) : U ? /* @__PURE__ */ u("div", {
|
|
112
115
|
className: "flex items-center gap-2 text-status-error-text text-sm",
|
|
113
|
-
children: [/* @__PURE__ */ c
|
|
114
|
-
}) :
|
|
116
|
+
children: [/* @__PURE__ */ l(c, { size: 16 }), M("createWorkspaceDialog.failedToLoadOrganizations", "Failed to load organizations")]
|
|
117
|
+
}) : Y ? Z.length === 0 ? /* @__PURE__ */ l("div", {
|
|
115
118
|
className: "text-text-secondary text-sm",
|
|
116
|
-
children: "No organizations found for this tenant"
|
|
117
|
-
}) : /* @__PURE__ */
|
|
119
|
+
children: M("createWorkspaceDialog.noOrganizationsFound", "No organizations found for this tenant")
|
|
120
|
+
}) : /* @__PURE__ */ u(E, {
|
|
118
121
|
onValueChange: e.onChange,
|
|
119
122
|
value: e.value,
|
|
120
|
-
disabled: !
|
|
121
|
-
children: [/* @__PURE__ */
|
|
123
|
+
disabled: !Y,
|
|
124
|
+
children: [/* @__PURE__ */ l(v, { children: /* @__PURE__ */ l(k, { children: /* @__PURE__ */ l(A, { placeholder: M("createWorkspaceDialog.selectOrganizationPlaceholder", "Select an organization") }) }) }), /* @__PURE__ */ l(D, { children: Z.map((e) => /* @__PURE__ */ l(O, {
|
|
122
125
|
value: e.id,
|
|
123
126
|
children: e.name
|
|
124
127
|
}, e.id)) })]
|
|
125
|
-
}) : /* @__PURE__ */
|
|
128
|
+
}) : /* @__PURE__ */ l("div", {
|
|
126
129
|
className: "text-text-secondary text-sm",
|
|
127
|
-
children: "Please select a tenant first"
|
|
130
|
+
children: M("createWorkspaceDialog.selectTenantFirst", "Please select a tenant first")
|
|
128
131
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
130
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.organizationHint", "Select which organization owns this workspace") }),
|
|
133
|
+
/* @__PURE__ */ l(C, {})
|
|
131
134
|
] })
|
|
132
135
|
}),
|
|
133
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ u(m, { children: [/* @__PURE__ */ l(d, {
|
|
134
137
|
type: "button",
|
|
135
138
|
variant: "outline",
|
|
136
|
-
onClick:
|
|
137
|
-
disabled:
|
|
138
|
-
children: "Cancel"
|
|
139
|
-
}), /* @__PURE__ */
|
|
139
|
+
onClick: F,
|
|
140
|
+
disabled: L,
|
|
141
|
+
children: M("common.cancel", "Cancel")
|
|
142
|
+
}), /* @__PURE__ */ l(d, {
|
|
140
143
|
type: "submit",
|
|
141
|
-
disabled:
|
|
142
|
-
children:
|
|
144
|
+
disabled: L || z || H,
|
|
145
|
+
children: L ? M("createWorkspaceDialog.creating", "Creating...") : M("createWorkspaceDialog.submit", "Create Workspace")
|
|
143
146
|
})] })
|
|
144
147
|
]
|
|
145
148
|
})
|
|
@@ -148,6 +151,6 @@ function N() {
|
|
|
148
151
|
});
|
|
149
152
|
}
|
|
150
153
|
//#endregion
|
|
151
|
-
export {
|
|
154
|
+
export { P as CreateWorkspaceDialog };
|
|
152
155
|
|
|
153
156
|
//# sourceMappingURL=CreateWorkspaceDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateWorkspaceDialog.js","names":[],"sources":["../../src/components/CreateWorkspaceDialog.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n Button,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateWorkspace } from '../hooks/useWorkspaceMutations';\nimport { useMyTenants, useMyOrganizations } from '../hooks/useTenants';\nimport { generateSlug } from '../utils/slug';\n\nconst createWorkspaceSchema = z.object({\n name: z.string().min(2, 'Name must be at least 2 characters').max(100),\n slug: z\n .string()\n .min(2, 'Slug must be at least 2 characters')\n .max(50)\n .regex(/^[a-z0-9-]+$/, 'Slug can only contain lowercase letters, numbers, and hyphens'),\n tenantId: z.string().min(1, 'Please select a tenant'),\n organizationId: z.string().min(1, 'Please select an organization'),\n});\n\ntype CreateWorkspaceFormData = z.infer<typeof createWorkspaceSchema>;\n\nexport function CreateWorkspaceDialog() {\n const { isCreateWorkspaceDialogOpen, closeCreateWorkspaceDialog } = useWorkspacesStore();\n const { mutate: createWorkspace, isPending } = useCreateWorkspace();\n const { data: tenantsData, isLoading: isLoadingTenants, error: tenantsError } = useMyTenants();\n const {\n data: organizationsData,\n isLoading: isLoadingOrganizations,\n error: organizationsError,\n } = useMyOrganizations();\n\n const tenants = useMemo(() => tenantsData?.items ?? [], [tenantsData]);\n const allOrganizations = useMemo(() => organizationsData?.items ?? [], [organizationsData]);\n\n // Prefer the shared tenant (or the only one) — with a single shared tenant\n // there is nothing to choose, so we auto-select it and hide the picker.\n const defaultTenantId = useMemo(() => {\n const sharedTenant = tenants.find(\n (tenant) => tenant.type === 'SHARED' || tenant.slug === 'burdenoff-shared'\n );\n return sharedTenant?.id ?? tenants[0]?.id ?? '';\n }, [tenants]);\n\n const form = useForm<CreateWorkspaceFormData>({\n schema: createWorkspaceSchema,\n defaultValues: {\n name: '',\n slug: '',\n tenantId: '',\n organizationId: '',\n },\n });\n\n const selectedTenantId = form.watch('tenantId');\n const workspaceName = form.watch('name');\n\n // Auto-select the default tenant when the user has no real choice.\n useEffect(() => {\n if (!form.getValues('tenantId') && defaultTenantId) {\n form.setValue('tenantId', defaultTenantId, { shouldValidate: true });\n }\n }, [defaultTenantId, form]);\n\n // Filter organizations by selected tenant\n const filteredOrganizations = useMemo(() => {\n if (!selectedTenantId) return [];\n return allOrganizations.filter((org) => org.tenantId === selectedTenantId);\n }, [selectedTenantId, allOrganizations]);\n\n // Auto-generate slug from name (clear when name is empty)\n useEffect(() => {\n form.setValue('slug', workspaceName ? generateSlug(workspaceName) : '');\n }, [workspaceName, form]);\n\n // Reset organizationId when tenant changes\n useEffect(() => {\n form.setValue('organizationId', '');\n }, [selectedTenantId, form]);\n\n const onSubmit = (data: CreateWorkspaceFormData) => {\n createWorkspace(\n {\n name: data.name,\n slug: data.slug,\n tenantId: data.tenantId,\n organizationId: data.organizationId,\n },\n {\n onSuccess: () => {\n closeCreateWorkspaceDialog();\n form.reset();\n },\n }\n );\n };\n\n return (\n <ResponsiveDialog open={isCreateWorkspaceDialogOpen} onOpenChange={closeCreateWorkspaceDialog}>\n <ResponsiveDialogContent className=\"sm:max-w-[500px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Create Workspace</ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {/* Workspace Name */}\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Workspace Name *</FormLabel>\n <FormControl>\n <Input placeholder=\"My Workspace\" {...field} />\n </FormControl>\n <FormDescription>A descriptive name for your workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Slug */}\n <FormField\n control={form.control}\n name=\"slug\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Slug *</FormLabel>\n <FormControl>\n <Input placeholder=\"my-workspace\" {...field} />\n </FormControl>\n <FormDescription>URL-friendly identifier (auto-generated)</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Tenant Selection — shown only when the user has more than one\n tenant to choose between. With a single shared tenant it is\n auto-selected and hidden (loading/error/empty still surface). */}\n {tenants.length !== 1 ? (\n <FormField\n control={form.control}\n name=\"tenantId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Tenant *</FormLabel>\n {isLoadingTenants ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : tenantsError ? (\n <div className=\"flex items-center gap-2 text-status-error-text text-sm\">\n <AlertCircle size={16} />\n Failed to load tenants\n </div>\n ) : tenants.length === 0 ? (\n <div className=\"text-text-secondary text-sm\">\n No tenants available. Contact your administrator.\n </div>\n ) : (\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select a tenant\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {tenants.map((tenant) => (\n <SelectItem key={tenant.id} value={tenant.id}>\n {tenant.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which tenant this workspace belongs to</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n ) : null}\n\n {/* Organization Selection */}\n <FormField\n control={form.control}\n name=\"organizationId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Organization *</FormLabel>\n {isLoadingOrganizations ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : organizationsError ? (\n <div className=\"flex items-center gap-2 text-status-error-text text-sm\">\n <AlertCircle size={16} />\n Failed to load organizations\n </div>\n ) : !selectedTenantId ? (\n <div className=\"text-text-secondary text-sm\">Please select a tenant first</div>\n ) : filteredOrganizations.length === 0 ? (\n <div className=\"text-text-secondary text-sm\">\n No organizations found for this tenant\n </div>\n ) : (\n <Select\n onValueChange={field.onChange}\n value={field.value}\n disabled={!selectedTenantId}\n >\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an organization\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {filteredOrganizations.map((org) => (\n <SelectItem key={org.id} value={org.id}>\n {org.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>Select which organization owns this workspace</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={closeCreateWorkspaceDialog}\n disabled={isPending}\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n disabled={isPending || isLoadingTenants || isLoadingOrganizations}\n >\n {isPending ? 'Creating...' : 'Create Workspace'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CreateWorkspaceDialog.js","names":[],"sources":["../../src/components/CreateWorkspaceDialog.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { AlertCircle } from 'lucide-react';\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n Button,\n Skeleton,\n} from '@burdenoff/fe-libs/ui';\nimport {\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n useForm,\n FormProvider,\n z,\n} from '@burdenoff/fe-libs/form';\nimport { useWorkspacesStore } from '../store/workspacesStore';\nimport { useCreateWorkspace } from '../hooks/useWorkspaceMutations';\nimport { useMyTenants, useMyOrganizations } from '../hooks/useTenants';\nimport { generateSlug } from '../utils/slug';\nimport { useTr } from '../hooks/useTr';\n\ntype CreateWorkspaceFormData = z.infer<ReturnType<typeof createWorkspaceSchema>>;\n\nfunction createWorkspaceSchema(tr: ReturnType<typeof useTr>) {\n return z.object({\n name: z\n .string()\n .min(2, tr('createWorkspaceDialog.validation.nameMin', 'Name must be at least 2 characters'))\n .max(100),\n slug: z\n .string()\n .min(2, tr('createWorkspaceDialog.validation.slugMin', 'Slug must be at least 2 characters'))\n .max(50)\n .regex(\n /^[a-z0-9-]+$/,\n tr(\n 'createWorkspaceDialog.validation.slugFormat',\n 'Slug can only contain lowercase letters, numbers, and hyphens'\n )\n ),\n tenantId: z\n .string()\n .min(1, tr('createWorkspaceDialog.validation.tenantRequired', 'Please select a tenant')),\n organizationId: z\n .string()\n .min(\n 1,\n tr('createWorkspaceDialog.validation.organizationRequired', 'Please select an organization')\n ),\n });\n}\n\nexport function CreateWorkspaceDialog() {\n const tr = useTr();\n const { isCreateWorkspaceDialogOpen, closeCreateWorkspaceDialog } = useWorkspacesStore();\n const { mutate: createWorkspace, isPending } = useCreateWorkspace();\n const { data: tenantsData, isLoading: isLoadingTenants, error: tenantsError } = useMyTenants();\n const {\n data: organizationsData,\n isLoading: isLoadingOrganizations,\n error: organizationsError,\n } = useMyOrganizations();\n\n const schema = useMemo(() => createWorkspaceSchema(tr), [tr]);\n\n const tenants = useMemo(() => tenantsData?.items ?? [], [tenantsData]);\n const allOrganizations = useMemo(() => organizationsData?.items ?? [], [organizationsData]);\n\n // Prefer the shared tenant (or the only one) — with a single shared tenant\n // there is nothing to choose, so we auto-select it and hide the picker.\n const defaultTenantId = useMemo(() => {\n const sharedTenant = tenants.find(\n (tenant) => tenant.type === 'SHARED' || tenant.slug === 'burdenoff-shared'\n );\n return sharedTenant?.id ?? tenants[0]?.id ?? '';\n }, [tenants]);\n\n const form = useForm<CreateWorkspaceFormData>({\n schema,\n defaultValues: {\n name: '',\n slug: '',\n tenantId: '',\n organizationId: '',\n },\n });\n\n const selectedTenantId = form.watch('tenantId');\n const workspaceName = form.watch('name');\n\n // Auto-select the default tenant when the user has no real choice.\n useEffect(() => {\n if (!form.getValues('tenantId') && defaultTenantId) {\n form.setValue('tenantId', defaultTenantId, { shouldValidate: true });\n }\n }, [defaultTenantId, form]);\n\n // Filter organizations by selected tenant\n const filteredOrganizations = useMemo(() => {\n if (!selectedTenantId) return [];\n return allOrganizations.filter((org) => org.tenantId === selectedTenantId);\n }, [selectedTenantId, allOrganizations]);\n\n // Auto-generate slug from name (clear when name is empty)\n useEffect(() => {\n form.setValue('slug', workspaceName ? generateSlug(workspaceName) : '');\n }, [workspaceName, form]);\n\n // Reset organizationId when tenant changes\n useEffect(() => {\n form.setValue('organizationId', '');\n }, [selectedTenantId, form]);\n\n const onSubmit = (data: CreateWorkspaceFormData) => {\n createWorkspace(\n {\n name: data.name,\n slug: data.slug,\n tenantId: data.tenantId,\n organizationId: data.organizationId,\n },\n {\n onSuccess: () => {\n closeCreateWorkspaceDialog();\n form.reset();\n },\n }\n );\n };\n\n return (\n <ResponsiveDialog open={isCreateWorkspaceDialogOpen} onOpenChange={closeCreateWorkspaceDialog}>\n <ResponsiveDialogContent className=\"sm:max-w-[500px]\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {tr('createWorkspaceDialog.title', 'Create Workspace')}\n </ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n\n <FormProvider {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-4\">\n {/* Workspace Name */}\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{tr('createWorkspaceDialog.nameLabel', 'Workspace Name *')}</FormLabel>\n <FormControl>\n <Input\n placeholder={tr('createWorkspaceDialog.namePlaceholder', 'My Workspace')}\n {...field}\n />\n </FormControl>\n <FormDescription>\n {tr('createWorkspaceDialog.nameHint', 'A descriptive name for your workspace')}\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Slug */}\n <FormField\n control={form.control}\n name=\"slug\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{tr('createWorkspaceDialog.slugLabel', 'Slug *')}</FormLabel>\n <FormControl>\n <Input\n placeholder={tr('createWorkspaceDialog.slugPlaceholder', 'my-workspace')}\n {...field}\n />\n </FormControl>\n <FormDescription>\n {tr(\n 'createWorkspaceDialog.slugHint',\n 'URL-friendly identifier (auto-generated)'\n )}\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n {/* Tenant Selection — shown only when the user has more than one\n tenant to choose between. With a single shared tenant it is\n auto-selected and hidden (loading/error/empty still surface). */}\n {tenants.length !== 1 ? (\n <FormField\n control={form.control}\n name=\"tenantId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>{tr('createWorkspaceDialog.tenantLabel', 'Tenant *')}</FormLabel>\n {isLoadingTenants ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : tenantsError ? (\n <div className=\"flex items-center gap-2 text-status-error-text text-sm\">\n <AlertCircle size={16} />\n {tr('createWorkspaceDialog.failedToLoadTenants', 'Failed to load tenants')}\n </div>\n ) : tenants.length === 0 ? (\n <div className=\"text-text-secondary text-sm\">\n {tr(\n 'createWorkspaceDialog.noTenantsAvailable',\n 'No tenants available. Contact your administrator.'\n )}\n </div>\n ) : (\n <Select onValueChange={field.onChange} value={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={tr(\n 'createWorkspaceDialog.selectTenantPlaceholder',\n 'Select a tenant'\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {tenants.map((tenant) => (\n <SelectItem key={tenant.id} value={tenant.id}>\n {tenant.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>\n {tr(\n 'createWorkspaceDialog.tenantHint',\n 'Select which tenant this workspace belongs to'\n )}\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n ) : null}\n\n {/* Organization Selection */}\n <FormField\n control={form.control}\n name=\"organizationId\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>\n {tr('createWorkspaceDialog.organizationLabel', 'Organization *')}\n </FormLabel>\n {isLoadingOrganizations ? (\n <Skeleton className=\"h-10 w-full\" />\n ) : organizationsError ? (\n <div className=\"flex items-center gap-2 text-status-error-text text-sm\">\n <AlertCircle size={16} />\n {tr(\n 'createWorkspaceDialog.failedToLoadOrganizations',\n 'Failed to load organizations'\n )}\n </div>\n ) : !selectedTenantId ? (\n <div className=\"text-text-secondary text-sm\">\n {tr(\n 'createWorkspaceDialog.selectTenantFirst',\n 'Please select a tenant first'\n )}\n </div>\n ) : filteredOrganizations.length === 0 ? (\n <div className=\"text-text-secondary text-sm\">\n {tr(\n 'createWorkspaceDialog.noOrganizationsFound',\n 'No organizations found for this tenant'\n )}\n </div>\n ) : (\n <Select\n onValueChange={field.onChange}\n value={field.value}\n disabled={!selectedTenantId}\n >\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={tr(\n 'createWorkspaceDialog.selectOrganizationPlaceholder',\n 'Select an organization'\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {filteredOrganizations.map((org) => (\n <SelectItem key={org.id} value={org.id}>\n {org.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <FormDescription>\n {tr(\n 'createWorkspaceDialog.organizationHint',\n 'Select which organization owns this workspace'\n )}\n </FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={closeCreateWorkspaceDialog}\n disabled={isPending}\n >\n {tr('common.cancel', 'Cancel')}\n </Button>\n <Button\n type=\"submit\"\n disabled={isPending || isLoadingTenants || isLoadingOrganizations}\n >\n {isPending\n ? tr('createWorkspaceDialog.creating', 'Creating...')\n : tr('createWorkspaceDialog.submit', 'Create Workspace')}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
|