@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.
Files changed (42) hide show
  1. package/dist/components/CreateProjectDialog.js +65 -61
  2. package/dist/components/CreateProjectDialog.js.map +1 -1
  3. package/dist/components/CreateWorkspaceDialog.js +93 -90
  4. package/dist/components/CreateWorkspaceDialog.js.map +1 -1
  5. package/dist/components/InviteMemberDialog.js +122 -111
  6. package/dist/components/InviteMemberDialog.js.map +1 -1
  7. package/dist/components/MemberListItem.js +55 -58
  8. package/dist/components/MemberListItem.js.map +1 -1
  9. package/dist/components/ProjectCard.js +93 -92
  10. package/dist/components/ProjectCard.js.map +1 -1
  11. package/dist/components/ProjectMemberPickerDialog.js +78 -93
  12. package/dist/components/ProjectMemberPickerDialog.js.map +1 -1
  13. package/dist/components/RenameProjectDialog.js +47 -44
  14. package/dist/components/RenameProjectDialog.js.map +1 -1
  15. package/dist/components/WorkspaceCard.js +42 -43
  16. package/dist/components/WorkspaceCard.js.map +1 -1
  17. package/dist/components/WorkspacesErrorBoundary.js +43 -34
  18. package/dist/components/WorkspacesErrorBoundary.js.map +1 -1
  19. package/dist/components/tags/ProjectTagsWidget.js +75 -77
  20. package/dist/components/tags/ProjectTagsWidget.js.map +1 -1
  21. package/dist/hooks/useTr.js +14 -0
  22. package/dist/hooks/useTr.js.map +1 -0
  23. package/dist/index.js +2 -1
  24. package/dist/pages/ActivityListPage.js +3 -3
  25. package/dist/pages/CreateWorkspacePage.js +10 -10
  26. package/dist/pages/InviteAcceptancePage.js +49 -49
  27. package/dist/pages/InviteAcceptancePage.js.map +1 -1
  28. package/dist/pages/MembersListPage.js +6 -6
  29. package/dist/pages/PendingInvitesPage.js +3 -3
  30. package/dist/pages/ProjectDetailPage.js +4 -4
  31. package/dist/pages/ProjectDetailPage.js.map +1 -1
  32. package/dist/pages/ProjectMembersPage.js +3 -3
  33. package/dist/pages/ProjectsListPage.js +5 -5
  34. package/dist/pages/WorkspaceDetailPage.js +4 -4
  35. package/dist/pages/WorkspaceInvitePage.js +4 -4
  36. package/dist/pages/WorkspaceSettingsPage.js +7 -7
  37. package/dist/pages/WorkspacesListPage.js +9 -9
  38. package/dist/pages/dashboard/widgets/RecentActivityWidget.js +4 -4
  39. package/dist/pages/dashboard/widgets/StorageWidget.js +3 -3
  40. package/dist/translations/en.js +908 -0
  41. package/dist/translations/en.js.map +1 -0
  42. package/package.json +1 -1
@@ -1,106 +1,110 @@
1
- import { useWorkspacesStore as e } from "../store/workspacesStore.js";
2
- import { useCreateProject as t } from "../hooks/useProjectMutations.js";
3
- import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
- import { Button as i, ResponsiveDialog as a, ResponsiveDialogContent as o, ResponsiveDialogDescription as s, ResponsiveDialogHeader as c, ResponsiveDialogTitle as l } from "@burdenoff/fe-libs/ui";
5
- import { FormControl as u, FormDescription as d, FormField as f, FormItem as p, FormLabel as m, FormMessage as h, FormProvider as g, Input as _, Textarea as v, useForm as y, z as b } from "@burdenoff/fe-libs/form";
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
- var x = b.object({
8
- name: b.string().min(2, "Name must be at least 2 characters").max(100, "Name must be less than 100 characters"),
9
- key: b.string().min(2, "Key must be at least 2 characters").max(10, "Key must be less than 10 characters").regex(/^[A-Z0-9_-]+$/, "Key must be uppercase letters, numbers, underscores, or hyphens"),
10
- description: b.string().optional()
11
- });
12
- function S({ workspaceId: b }) {
13
- let { isCreateProjectDialogOpen: S, closeCreateProjectDialog: C } = e(), { mutate: w, isPending: T } = t(b), E = y({
14
- schema: x,
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
- }), D = (e) => {
21
- w({
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
- C(), E.reset();
31
+ E(), k.reset();
28
32
  },
29
33
  onError: (e) => {
30
34
  console.error("Failed to create project:", e);
31
35
  }
32
36
  });
33
- }, O = (e) => {
34
- e || (C(), E.reset());
35
- }, k = (e) => {
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
- E.getValues("key") || E.setValue("key", t);
41
+ k.getValues("key") || k.setValue("key", t);
38
42
  };
39
- return /* @__PURE__ */ n(a, {
40
- open: S,
41
- onOpenChange: O,
42
- children: /* @__PURE__ */ r(o, {
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__ */ r(c, { children: [/* @__PURE__ */ n(l, { children: "Create Project" }), /* @__PURE__ */ n(s, { children: "Create a new project in your workspace. Projects help organize your work." })] }), /* @__PURE__ */ n(g, {
45
- ...E,
46
- children: /* @__PURE__ */ r("form", {
47
- onSubmit: E.handleSubmit(D),
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__ */ n(f, {
51
- control: E.control,
54
+ /* @__PURE__ */ i(m, {
55
+ control: k.control,
52
56
  name: "name",
53
- render: ({ field: e }) => /* @__PURE__ */ r(p, { children: [
54
- /* @__PURE__ */ n(m, { children: "Project Name" }),
55
- /* @__PURE__ */ n(u, { children: /* @__PURE__ */ n(_, {
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), k(t.target.value);
63
+ e.onChange(t), M(t.target.value);
60
64
  }
61
65
  }) }),
62
- /* @__PURE__ */ n(d, { children: "A descriptive name for your project" }),
63
- /* @__PURE__ */ n(h, {})
66
+ /* @__PURE__ */ i(p, { children: w("createProjectDialog.nameHint", "A descriptive name for your project") }),
67
+ /* @__PURE__ */ i(_, {})
64
68
  ] })
65
69
  }),
66
- /* @__PURE__ */ n(f, {
67
- control: E.control,
70
+ /* @__PURE__ */ i(m, {
71
+ control: k.control,
68
72
  name: "key",
69
- render: ({ field: e }) => /* @__PURE__ */ r(p, { children: [
70
- /* @__PURE__ */ n(m, { children: "Project Key" }),
71
- /* @__PURE__ */ n(u, { children: /* @__PURE__ */ n(_, {
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__ */ n(d, { children: "Short identifier (uppercase letters, numbers, underscores)" }),
76
- /* @__PURE__ */ n(h, {})
79
+ /* @__PURE__ */ i(p, { children: w("createProjectDialog.keyHint", "Short identifier (uppercase letters, numbers, underscores)") }),
80
+ /* @__PURE__ */ i(_, {})
77
81
  ] })
78
82
  }),
79
- /* @__PURE__ */ n(f, {
80
- control: E.control,
83
+ /* @__PURE__ */ i(m, {
84
+ control: k.control,
81
85
  name: "description",
82
- render: ({ field: e }) => /* @__PURE__ */ r(p, { children: [
83
- /* @__PURE__ */ n(m, { children: "Description (Optional)" }),
84
- /* @__PURE__ */ n(u, { children: /* @__PURE__ */ n(v, {
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__ */ n(h, {})
93
+ /* @__PURE__ */ i(_, {})
90
94
  ] })
91
95
  }),
92
- /* @__PURE__ */ r("div", {
96
+ /* @__PURE__ */ a("div", {
93
97
  className: "flex justify-end gap-3 pt-4",
94
- children: [/* @__PURE__ */ n(i, {
98
+ children: [/* @__PURE__ */ i(o, {
95
99
  type: "button",
96
100
  variant: "outline",
97
- onClick: () => O(!1),
98
- disabled: T,
99
- children: "Cancel"
100
- }), /* @__PURE__ */ n(i, {
101
+ onClick: () => j(!1),
102
+ disabled: O,
103
+ children: w("common.cancel", "Cancel")
104
+ }), /* @__PURE__ */ i(o, {
101
105
  type: "submit",
102
- disabled: T,
103
- children: T ? "Creating..." : "Create Project"
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 { S as CreateProjectDialog };
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\nconst createProjectSchema = z.object({\n name: z\n .string()\n .min(2, 'Name must be at least 2 characters')\n .max(100, 'Name must be less than 100 characters'),\n key: z\n .string()\n .min(2, 'Key must be at least 2 characters')\n .max(10, 'Key must be less than 10 characters')\n .regex(/^[A-Z0-9_-]+$/, 'Key must be uppercase letters, numbers, underscores, or hyphens'),\n description: z.string().optional(),\n});\n\ntype CreateProjectFormData = z.infer<typeof createProjectSchema>;\n\ninterface CreateProjectDialogProps {\n workspaceId?: string;\n}\n\nexport function CreateProjectDialog({ workspaceId }: CreateProjectDialogProps) {\n const { isCreateProjectDialogOpen, closeCreateProjectDialog } = useWorkspacesStore();\n const { mutate: createProject, isPending } = useCreateProject(workspaceId);\n\n const form = useForm({\n schema: createProjectSchema,\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>Create Project</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Create a new project in your workspace. Projects help organize your work.\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>Project Name</FormLabel>\n <FormControl>\n <Input\n {...field}\n placeholder=\"My Project\"\n onChange={(e) => {\n field.onChange(e);\n handleNameChange(e.target.value);\n }}\n />\n </FormControl>\n <FormDescription>A descriptive name for your project</FormDescription>\n <FormMessage />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"key\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Project Key</FormLabel>\n <FormControl>\n <Input {...field} placeholder=\"MYPROJ\" />\n </FormControl>\n <FormDescription>\n Short identifier (uppercase letters, numbers, underscores)\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>Description (Optional)</FormLabel>\n <FormControl>\n <Textarea {...field} placeholder=\"Brief description of the project\" rows={3} />\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 Cancel\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Creating...' : 'Create Project'}\n </Button>\n </div>\n </form>\n </FormProvider>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
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 { useWorkspacesStore as e } from "../store/workspacesStore.js";
2
- import { useCreateWorkspace as t } from "../hooks/useWorkspaceMutations.js";
3
- import { useMyOrganizations as n, useMyTenants as r } from "../hooks/useTenants.js";
4
- import { generateSlug as i } from "../utils/slug.js";
5
- import { useEffect as a, useMemo as o } from "react";
6
- import { AlertCircle as s } from "lucide-react";
7
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
- import { Button as u, ResponsiveDialog as d, ResponsiveDialogContent as f, ResponsiveDialogFooter as p, ResponsiveDialogHeader as m, ResponsiveDialogTitle as h, Skeleton as g } from "@burdenoff/fe-libs/ui";
9
- import { FormControl as _, FormDescription as v, FormField as y, FormItem as b, FormLabel as x, FormMessage as S, FormProvider as C, Input as w, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k, useForm as A, z as j } from "@burdenoff/fe-libs/form";
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
- var M = j.object({
12
- name: j.string().min(2, "Name must be at least 2 characters").max(100),
13
- slug: j.string().min(2, "Slug must be at least 2 characters").max(50).regex(/^[a-z0-9-]+$/, "Slug can only contain lowercase letters, numbers, and hyphens"),
14
- tenantId: j.string().min(1, "Please select a tenant"),
15
- organizationId: j.string().min(1, "Please select an organization")
16
- });
17
- function N() {
18
- let { isCreateWorkspaceDialogOpen: j, closeCreateWorkspaceDialog: N } = e(), { mutate: P, isPending: F } = t(), { data: I, isLoading: L, error: R } = r(), { data: z, isLoading: B, error: V } = n(), H = o(() => I?.items ?? [], [I]), U = o(() => z?.items ?? [], [z]), W = o(() => H.find((e) => e.type === "SHARED" || e.slug === "burdenoff-shared")?.id ?? H[0]?.id ?? "", [H]), G = A({
19
- schema: M,
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
- }), K = G.watch("tenantId"), q = G.watch("name");
27
- a(() => {
28
- !G.getValues("tenantId") && W && G.setValue("tenantId", W, { shouldValidate: !0 });
29
- }, [W, G]);
30
- let J = o(() => K ? U.filter((e) => e.tenantId === K) : [], [K, U]);
31
- a(() => {
32
- G.setValue("slug", q ? i(q) : "");
33
- }, [q, G]), a(() => {
34
- G.setValue("organizationId", "");
35
- }, [K, G]);
36
- let Y = (e) => {
37
- P({
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
- N(), G.reset();
46
+ F(), J.reset();
44
47
  } });
45
48
  };
46
- return /* @__PURE__ */ c(d, {
47
- open: j,
48
- onOpenChange: N,
49
- children: /* @__PURE__ */ l(f, {
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__ */ c(m, { children: /* @__PURE__ */ c(h, { children: "Create Workspace" }) }), /* @__PURE__ */ c(C, {
52
- ...G,
53
- children: /* @__PURE__ */ l("form", {
54
- onSubmit: G.handleSubmit(Y),
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__ */ c(y, {
58
- control: G.control,
60
+ /* @__PURE__ */ l(b, {
61
+ control: J.control,
59
62
  name: "name",
60
- render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
61
- /* @__PURE__ */ c(x, { children: "Workspace Name *" }),
62
- /* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(w, {
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__ */ c(v, { children: "A descriptive name for your workspace" }),
67
- /* @__PURE__ */ c(S, {})
69
+ /* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.nameHint", "A descriptive name for your workspace") }),
70
+ /* @__PURE__ */ l(C, {})
68
71
  ] })
69
72
  }),
70
- /* @__PURE__ */ c(y, {
71
- control: G.control,
73
+ /* @__PURE__ */ l(b, {
74
+ control: J.control,
72
75
  name: "slug",
73
- render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
74
- /* @__PURE__ */ c(x, { children: "Slug *" }),
75
- /* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(w, {
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__ */ c(v, { children: "URL-friendly identifier (auto-generated)" }),
80
- /* @__PURE__ */ c(S, {})
82
+ /* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.slugHint", "URL-friendly identifier (auto-generated)") }),
83
+ /* @__PURE__ */ l(C, {})
81
84
  ] })
82
85
  }),
83
- H.length === 1 ? null : /* @__PURE__ */ c(y, {
84
- control: G.control,
86
+ G.length === 1 ? null : /* @__PURE__ */ l(b, {
87
+ control: J.control,
85
88
  name: "tenantId",
86
- render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
87
- /* @__PURE__ */ c(x, { children: "Tenant *" }),
88
- L ? /* @__PURE__ */ c(g, { className: "h-10 w-full" }) : R ? /* @__PURE__ */ l("div", {
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(s, { size: 16 }), "Failed to load tenants"]
91
- }) : H.length === 0 ? /* @__PURE__ */ c("div", {
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__ */ l(T, {
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__ */ c(_, { children: /* @__PURE__ */ c(O, { children: /* @__PURE__ */ c(k, { placeholder: "Select a tenant" }) }) }), /* @__PURE__ */ c(E, { children: H.map((e) => /* @__PURE__ */ c(D, {
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__ */ c(v, { children: "Select which tenant this workspace belongs to" }),
103
- /* @__PURE__ */ c(S, {})
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__ */ c(y, {
107
- control: G.control,
109
+ /* @__PURE__ */ l(b, {
110
+ control: J.control,
108
111
  name: "organizationId",
109
- render: ({ field: e }) => /* @__PURE__ */ l(b, { children: [
110
- /* @__PURE__ */ c(x, { children: "Organization *" }),
111
- B ? /* @__PURE__ */ c(g, { className: "h-10 w-full" }) : V ? /* @__PURE__ */ l("div", {
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(s, { size: 16 }), "Failed to load organizations"]
114
- }) : K ? J.length === 0 ? /* @__PURE__ */ c("div", {
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__ */ l(T, {
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: !K,
121
- children: [/* @__PURE__ */ c(_, { children: /* @__PURE__ */ c(O, { children: /* @__PURE__ */ c(k, { placeholder: "Select an organization" }) }) }), /* @__PURE__ */ c(E, { children: J.map((e) => /* @__PURE__ */ c(D, {
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__ */ c("div", {
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__ */ c(v, { children: "Select which organization owns this workspace" }),
130
- /* @__PURE__ */ c(S, {})
132
+ /* @__PURE__ */ l(y, { children: M("createWorkspaceDialog.organizationHint", "Select which organization owns this workspace") }),
133
+ /* @__PURE__ */ l(C, {})
131
134
  ] })
132
135
  }),
133
- /* @__PURE__ */ l(p, { children: [/* @__PURE__ */ c(u, {
136
+ /* @__PURE__ */ u(m, { children: [/* @__PURE__ */ l(d, {
134
137
  type: "button",
135
138
  variant: "outline",
136
- onClick: N,
137
- disabled: F,
138
- children: "Cancel"
139
- }), /* @__PURE__ */ c(u, {
139
+ onClick: F,
140
+ disabled: L,
141
+ children: M("common.cancel", "Cancel")
142
+ }), /* @__PURE__ */ l(d, {
140
143
  type: "submit",
141
- disabled: F || L || B,
142
- children: F ? "Creating..." : "Create Workspace"
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 { N as CreateWorkspaceDialog };
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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"}