@burdenoff/microfe-vibecontrols 2026.520.1 → 2026.520.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.
@@ -3,51 +3,53 @@ import { useVibeNavigate as n } from "../providers/VibeControlsProvider.js";
3
3
  import { PageHeader as r } from "../components/shared/PageHeader.js";
4
4
  import { LoadingState as i } from "../components/shared/LoadingState.js";
5
5
  import { ErrorState as a } from "../components/shared/ErrorState.js";
6
- import { EmptyState as o } from "../components/shared/EmptyState.js";
7
- import { SearchInput as s } from "../components/shared/SearchInput.js";
8
- import { FilterDropdown as c } from "../components/shared/FilterDropdown.js";
9
- import { GetHelpButton as l } from "../components/shared/GetHelpButton.js";
6
+ import { EntityTagPicker as o } from "../components/shared/EntityTagPicker.js";
7
+ import { useDraftEntityTags as s } from "../hooks/useDraftEntityTags.js";
8
+ import { EmptyState as c } from "../components/shared/EmptyState.js";
9
+ import { SearchInput as l } from "../components/shared/SearchInput.js";
10
+ import { FilterDropdown as u } from "../components/shared/FilterDropdown.js";
11
+ import { GetHelpButton as d } from "../components/shared/GetHelpButton.js";
10
12
  import "../components/shared/index.js";
11
- import { VIBE_PERMISSIONS as u } from "../constants/permissions.js";
12
- import { CatalogCard as d } from "../components/catalog/CatalogCard.js";
13
- import { CatalogForm as f } from "../components/catalog/CatalogForm.js";
13
+ import { VIBE_PERMISSIONS as f } from "../constants/permissions.js";
14
+ import { CatalogCard as p } from "../components/catalog/CatalogCard.js";
15
+ import { CatalogForm as m } from "../components/catalog/CatalogForm.js";
14
16
  import "../components/catalog/index.js";
15
- import { useCallback as p, useMemo as m, useState as h } from "react";
16
- import { useI18n as g } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
- import { BookOpen as _, Plus as v, RefreshCw as y } from "lucide-react";
18
- import { usePermissions as b } from "@burdenoff/fe-libs/shared/providers/shell";
19
- import { AnimatePresence as x } from "framer-motion";
20
- import { jsx as S, jsxs as C } from "react/jsx-runtime";
21
- import { MotionItem as w, MotionList as T, MotionPage as E } from "@burdenoff/fe-libs/shared/motion";
17
+ import { useCallback as h, useMemo as g, useState as _ } from "react";
18
+ import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
19
+ import { BookOpen as y, Plus as b, RefreshCw as x } from "lucide-react";
20
+ import { usePermissions as S } from "@burdenoff/fe-libs/shared/providers/shell";
21
+ import { AnimatePresence as C } from "framer-motion";
22
+ import { jsx as w, jsxs as T } from "react/jsx-runtime";
23
+ import { MotionItem as E, MotionList as D, MotionPage as O } from "@burdenoff/fe-libs/shared/motion";
22
24
  //#region src/pages/CatalogPage.tsx
23
- function D() {
24
- let D = n(), { t: O } = g(), { hasPermission: k, isLoading: A } = b(), j = p((e, t, n) => {
25
- let r = O(e, n), i = r === e ? t : r;
25
+ function k() {
26
+ let k = n(), { t: A } = v(), { hasPermission: j, isLoading: M } = S(), N = h((e, t, n) => {
27
+ let r = A(e, n), i = r === e ? t : r;
26
28
  return n ? Object.entries(n).reduce((e, [t, n]) => e.replace(`{{${t}}}`, String(n)), i) : i;
27
- }, [O]), M = [
29
+ }, [A]), P = [
28
30
  {
29
31
  value: "all",
30
- label: j("catalog.allVisibility", "All Visibility")
32
+ label: N("catalog.allVisibility", "All Visibility")
31
33
  },
32
34
  {
33
35
  value: "PRIVATE",
34
- label: j("catalog.visibilityPrivate", "Private")
36
+ label: N("catalog.visibilityPrivate", "Private")
35
37
  },
36
38
  {
37
39
  value: "INTERNAL",
38
- label: j("catalog.visibilityInternal", "Internal")
40
+ label: N("catalog.visibilityInternal", "Internal")
39
41
  },
40
42
  {
41
43
  value: "PUBLIC",
42
- label: j("catalog.visibilityPublic", "Public")
44
+ label: N("catalog.visibilityPublic", "Public")
43
45
  }
44
- ], [N, P] = h(""), [F, I] = h("all"), [L, R] = h(!1), [z, B] = h(null), { data: V, loading: H, error: U, refetch: W } = t({
46
+ ], [F, I] = _(""), [L, R] = _("all"), [z, B] = _(!1), [V, H] = _(null), { data: U, loading: W, error: G, refetch: K } = t({
45
47
  variables: {
46
- filter: { visibility: F === "all" ? void 0 : F },
47
- ...N ? { pagination: { limit: 1e3 } } : {}
48
+ filter: { visibility: L === "all" ? void 0 : L },
49
+ ...F ? { pagination: { limit: 1e3 } } : {}
48
50
  },
49
51
  fetchPolicy: "cache-and-network"
50
- }), [G] = e({ refetchQueries: ["ListCatalogs"] }), K = m(() => (V?.vibecontrolsCatalogs?.items ?? []).map((e) => ({
52
+ }), [q] = e({ refetchQueries: ["ListCatalogs"] }), { setDraftTagIds: J, flushTags: Y } = s("VIBECONTROLS_CATALOG"), X = g(() => (U?.vibecontrolsCatalogs?.items ?? []).map((e) => ({
51
53
  id: e.id,
52
54
  name: e.name,
53
55
  description: e.description || null,
@@ -57,133 +59,141 @@ function D() {
57
59
  tags: e.tags || [],
58
60
  createdAt: e.createdAt,
59
61
  updatedAt: e.updatedAt
60
- })), [V?.vibecontrolsCatalogs?.items]), q = m(() => {
61
- if (!N) return K;
62
- let e = N.toLowerCase();
63
- return K.filter((t) => t.name.toLowerCase().includes(e) || t.description?.toLowerCase().includes(e) || t.tags?.some((t) => t.toLowerCase().includes(e)));
64
- }, [K, N]);
65
- if (A) return /* @__PURE__ */ S("div", {
62
+ })), [U?.vibecontrolsCatalogs?.items]), Z = g(() => {
63
+ if (!F) return X;
64
+ let e = F.toLowerCase();
65
+ return X.filter((t) => t.name.toLowerCase().includes(e) || t.description?.toLowerCase().includes(e) || t.tags?.some((t) => t.toLowerCase().includes(e)));
66
+ }, [X, F]);
67
+ if (M) return /* @__PURE__ */ w("div", {
66
68
  className: "flex items-center justify-center min-h-[400px]",
67
- children: /* @__PURE__ */ S("p", {
69
+ children: /* @__PURE__ */ w("p", {
68
70
  className: "text-text-secondary",
69
71
  children: "Loading permissions..."
70
72
  })
71
73
  });
72
- if (!k(u.VIBE_LIST)) return /* @__PURE__ */ S("div", {
74
+ if (!j(f.VIBE_LIST)) return /* @__PURE__ */ w("div", {
73
75
  className: "flex items-center justify-center min-h-[400px]",
74
- children: /* @__PURE__ */ C("div", {
76
+ children: /* @__PURE__ */ T("div", {
75
77
  className: "text-center space-y-2",
76
- children: [/* @__PURE__ */ S("h2", {
78
+ children: [/* @__PURE__ */ w("h2", {
77
79
  className: "text-lg font-semibold text-foreground",
78
80
  children: "Access Denied"
79
- }), /* @__PURE__ */ S("p", {
81
+ }), /* @__PURE__ */ w("p", {
80
82
  className: "text-sm text-text-secondary",
81
83
  children: "You don't have permission to access this page."
82
84
  })]
83
85
  })
84
86
  });
85
- let J = (e) => {
86
- D(`/catalogs/${e.id}`);
87
+ let Q = (e) => {
88
+ k(`/catalogs/${e.id}`);
87
89
  };
88
- return H && K.length === 0 ? /* @__PURE__ */ S(E, {
90
+ return W && X.length === 0 ? /* @__PURE__ */ w(O, {
89
91
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
90
- children: /* @__PURE__ */ S(i, { message: j("catalog.loading", "Loading catalogs...") })
91
- }) : U && K.length === 0 ? /* @__PURE__ */ S(E, {
92
+ children: /* @__PURE__ */ w(i, { message: N("catalog.loading", "Loading catalogs...") })
93
+ }) : G && X.length === 0 ? /* @__PURE__ */ w(O, {
92
94
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
93
- children: /* @__PURE__ */ S(a, {
94
- title: j("catalog.failedLoad", "Failed to load catalogs"),
95
- message: U.message,
96
- onRetry: () => W()
95
+ children: /* @__PURE__ */ w(a, {
96
+ title: N("catalog.failedLoad", "Failed to load catalogs"),
97
+ message: G.message,
98
+ onRetry: () => K()
97
99
  })
98
- }) : /* @__PURE__ */ C(E, {
100
+ }) : /* @__PURE__ */ T(O, {
99
101
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
100
102
  children: [
101
- /* @__PURE__ */ S(r, {
102
- title: j("catalog.title", "Catalogs"),
103
- description: j("catalog.description", "{{total}} catalogs", { total: K.length }),
104
- actions: /* @__PURE__ */ C("div", {
103
+ /* @__PURE__ */ w(r, {
104
+ title: N("catalog.title", "Catalogs"),
105
+ description: N("catalog.description", "{{total}} catalogs", { total: X.length }),
106
+ actions: /* @__PURE__ */ T("div", {
105
107
  className: "flex items-center gap-2",
106
- children: [/* @__PURE__ */ S("button", {
107
- onClick: () => W(),
108
- disabled: H,
108
+ children: [/* @__PURE__ */ w("button", {
109
+ onClick: () => K(),
110
+ disabled: W,
109
111
  className: "flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50",
110
- title: j("common.refresh", "Refresh"),
111
- children: /* @__PURE__ */ S(y, { className: `w-4 h-4 ${H ? "animate-spin" : ""}` })
112
- }), /* @__PURE__ */ C("button", {
113
- onClick: () => R(!0),
112
+ title: N("common.refresh", "Refresh"),
113
+ children: /* @__PURE__ */ w(x, { className: `w-4 h-4 ${W ? "animate-spin" : ""}` })
114
+ }), /* @__PURE__ */ T("button", {
115
+ onClick: () => B(!0),
114
116
  className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors",
115
- children: [/* @__PURE__ */ S(v, { className: "w-4 h-4" }), j("catalog.createCatalog", "Create Catalog")]
117
+ children: [/* @__PURE__ */ w(b, { className: "w-4 h-4" }), N("catalog.createCatalog", "Create Catalog")]
116
118
  })]
117
119
  })
118
120
  }),
119
- /* @__PURE__ */ C("div", {
121
+ /* @__PURE__ */ T("div", {
120
122
  className: "flex items-center gap-2 sm:gap-3 flex-wrap",
121
- children: [/* @__PURE__ */ S(s, {
122
- value: N,
123
- onChange: P,
124
- placeholder: j("catalog.searchPlaceholder", "Search catalogs..."),
125
- className: "flex-1 sm:w-64 sm:flex-none"
126
- }), /* @__PURE__ */ S(c, {
127
- label: j("catalog.filterVisibility", "Visibility"),
123
+ children: [/* @__PURE__ */ w(l, {
128
124
  value: F,
129
- options: M,
130
- onChange: I
125
+ onChange: I,
126
+ placeholder: N("catalog.searchPlaceholder", "Search catalogs..."),
127
+ className: "flex-1 sm:w-64 sm:flex-none"
128
+ }), /* @__PURE__ */ w(u, {
129
+ label: N("catalog.filterVisibility", "Visibility"),
130
+ value: L,
131
+ options: P,
132
+ onChange: R
131
133
  })]
132
134
  }),
133
- (N || F !== "all") && /* @__PURE__ */ C("p", {
135
+ (F || L !== "all") && /* @__PURE__ */ T("p", {
134
136
  className: "text-sm text-text-secondary",
135
- children: [j("catalog.showingResults", "Showing {{filtered}} of {{total}} catalogs", {
136
- filtered: q.length,
137
- total: K.length
138
- }), H && /* @__PURE__ */ S("span", {
137
+ children: [N("catalog.showingResults", "Showing {{filtered}} of {{total}} catalogs", {
138
+ filtered: Z.length,
139
+ total: X.length
140
+ }), W && /* @__PURE__ */ w("span", {
139
141
  className: "ml-2 text-text-muted",
140
- children: j("common.refreshing", "(refreshing...)")
142
+ children: N("common.refreshing", "(refreshing...)")
141
143
  })]
142
144
  }),
143
- q.length > 0 ? /* @__PURE__ */ S(x, {
145
+ Z.length > 0 ? /* @__PURE__ */ w(C, {
144
146
  mode: "wait",
145
- children: /* @__PURE__ */ S(T, {
147
+ children: /* @__PURE__ */ w(D, {
146
148
  stagger: .04,
147
149
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
148
- children: q.map((e) => /* @__PURE__ */ S(w, { children: /* @__PURE__ */ S(d, {
150
+ children: Z.map((e) => /* @__PURE__ */ w(E, { children: /* @__PURE__ */ w(p, {
149
151
  catalog: e,
150
- onOpen: J
152
+ onOpen: Q
151
153
  }) }, e.id))
152
154
  }, "catalog-grid")
153
- }) : /* @__PURE__ */ S(o, {
154
- icon: /* @__PURE__ */ S(_, { className: "w-8 h-8 text-text-secondary" }),
155
- title: N || F !== "all" ? j("catalog.emptyNoResults", "No catalogs found") : j("catalog.emptyNoCatalogs", "No catalogs yet"),
156
- description: N || F !== "all" ? j("catalog.emptyAdjustSearch", "Try adjusting your search or filters") : j("catalog.emptyCreate", "Create your first catalog to organize components"),
157
- action: !N && F === "all" ? /* @__PURE__ */ C("div", {
155
+ }) : /* @__PURE__ */ w(c, {
156
+ icon: /* @__PURE__ */ w(y, { className: "w-8 h-8 text-text-secondary" }),
157
+ title: F || L !== "all" ? N("catalog.emptyNoResults", "No catalogs found") : N("catalog.emptyNoCatalogs", "No catalogs yet"),
158
+ description: F || L !== "all" ? N("catalog.emptyAdjustSearch", "Try adjusting your search or filters") : N("catalog.emptyCreate", "Create your first catalog to organize components"),
159
+ action: !F && L === "all" ? /* @__PURE__ */ T("div", {
158
160
  className: "flex items-center gap-2",
159
- children: [/* @__PURE__ */ C("button", {
160
- onClick: () => R(!0),
161
+ children: [/* @__PURE__ */ T("button", {
162
+ onClick: () => B(!0),
161
163
  className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors",
162
- children: [/* @__PURE__ */ S(v, { className: "w-4 h-4" }), j("catalog.createCatalog", "Create Catalog")]
163
- }), /* @__PURE__ */ S(l, { prompt: "What is a Catalog in VibeControls and how do I create one?" })]
164
+ children: [/* @__PURE__ */ w(b, { className: "w-4 h-4" }), N("catalog.createCatalog", "Create Catalog")]
165
+ }), /* @__PURE__ */ w(d, { prompt: "What is a Catalog in VibeControls and how do I create one?" })]
164
166
  }) : void 0
165
167
  }),
166
- z && /* @__PURE__ */ S("div", {
168
+ V && /* @__PURE__ */ w("div", {
167
169
  className: "fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-success-bg text-status-success-text rounded-md shadow-lg text-sm",
168
- children: z
170
+ children: V
169
171
  }),
170
- /* @__PURE__ */ S(f, {
171
- isOpen: L,
172
- onClose: () => R(!1),
172
+ /* @__PURE__ */ w(m, {
173
+ isOpen: z,
174
+ onClose: () => B(!1),
173
175
  onSubmit: async (e) => {
174
- await G({ variables: { input: {
176
+ let t = (await q({ variables: { input: {
175
177
  name: e.name,
176
178
  description: e.description || void 0,
177
179
  visibility: e.visibility,
178
180
  ownerName: e.owner || void 0,
179
181
  tags: e.tags.length > 0 ? e.tags : void 0
180
- } } }), B(j("catalog.createdSuccess", "Catalog created successfully")), setTimeout(() => B(null), 3e3);
181
- }
182
+ } } })).data?.createVibecontrolsCatalog?.id;
183
+ t && await Y(t), H(N("catalog.createdSuccess", "Catalog created successfully")), setTimeout(() => H(null), 3e3);
184
+ },
185
+ extraSection: /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("h3", {
186
+ className: "text-sm font-medium text-text-secondary mb-2",
187
+ children: N("catalog.tags", "Tags")
188
+ }), /* @__PURE__ */ w(o, {
189
+ entityType: "VIBECONTROLS_CATALOG",
190
+ onDraftChange: J
191
+ })] })
182
192
  })
183
193
  ]
184
194
  });
185
195
  }
186
196
  //#endregion
187
- export { D as CatalogPage };
197
+ export { k as CatalogPage };
188
198
 
189
199
  //# sourceMappingURL=CatalogPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogPage.js","names":[],"sources":["../../src/pages/CatalogPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { Plus, BookOpen, RefreshCw } from 'lucide-react';\nimport { CatalogCard } from '@/components/catalog';\nimport type { CatalogCardData } from '@/components/catalog';\nimport { CatalogForm } from '@/components/catalog';\nimport type { CatalogFormData } from '@/components/catalog';\nimport {\n PageHeader,\n SearchInput,\n FilterDropdown,\n EmptyState,\n LoadingState,\n ErrorState,\n GetHelpButton,\n} from '@/components/shared';\nimport { MotionPage, MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\nimport { AnimatePresence } from 'framer-motion';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useListCatalogsQuery, useCreateCatalogMutation } from '@/generated/wspace-operations';\n\nexport function CatalogPage() {\n const navigate = useVibeNavigate();\n const { t } = useI18n();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key, params);\n const template = translated === key ? fallback : translated;\n if (!params) return template;\n return Object.entries(params).reduce(\n (acc, [paramKey, paramValue]) => acc.replace(`{{${paramKey}}}`, String(paramValue)),\n template\n );\n },\n [t]\n );\n\n const visibilityOptions = [\n { value: 'all', label: tr('catalog.allVisibility', 'All Visibility') },\n { value: 'PRIVATE', label: tr('catalog.visibilityPrivate', 'Private') },\n { value: 'INTERNAL', label: tr('catalog.visibilityInternal', 'Internal') },\n { value: 'PUBLIC', label: tr('catalog.visibilityPublic', 'Public') },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [visibilityFilter, setVisibilityFilter] = useState('all');\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const { data, loading, error, refetch } = useListCatalogsQuery({\n variables: {\n filter: {\n visibility:\n visibilityFilter !== 'all'\n ? (visibilityFilter as 'PRIVATE' | 'INTERNAL' | 'PUBLIC')\n : undefined,\n },\n ...(searchQuery ? { pagination: { limit: 1000 } } : {}),\n },\n fetchPolicy: 'cache-and-network',\n });\n\n const [createCatalog] = useCreateCatalogMutation({ refetchQueries: ['ListCatalogs'] });\n\n const catalogs: CatalogCardData[] = useMemo(() => {\n const items = data?.vibecontrolsCatalogs?.items ?? [];\n return items.map((item: Record<string, unknown>) => ({\n id: item.id as string,\n name: item.name as string,\n description: (item.description as string) || null,\n visibility: item.visibility as CatalogCardData['visibility'],\n componentCount: (item.componentCount as number) || 0,\n vibeCount: (item.vibeCount as number) || 0,\n tags: (item.tags as string[]) || [],\n createdAt: item.createdAt as string,\n updatedAt: item.updatedAt as string,\n }));\n }, [data?.vibecontrolsCatalogs?.items]);\n\n const filteredCatalogs = useMemo(() => {\n if (!searchQuery) return catalogs;\n const query = searchQuery.toLowerCase();\n return catalogs.filter(\n (c) =>\n c.name.toLowerCase().includes(query) ||\n c.description?.toLowerCase().includes(query) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(query))\n );\n }, [catalogs, searchQuery]);\n\n if (permissionsLoading)\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <p className=\"text-text-secondary\">Loading permissions...</p>\n </div>\n );\n if (!hasPermission(VIBE_PERMISSIONS.VIBE_LIST))\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don't have permission to access this page.\n </p>\n </div>\n </div>\n );\n\n const handleCatalogSelect = (catalog: CatalogCardData) => {\n navigate(`/catalogs/${catalog.id}`);\n };\n\n const handleCreateCatalog = async (formData: CatalogFormData) => {\n await createCatalog({\n variables: {\n input: {\n name: formData.name,\n description: formData.description || undefined,\n visibility: formData.visibility,\n ownerName: formData.owner || undefined,\n tags: formData.tags.length > 0 ? formData.tags : undefined,\n },\n },\n });\n setSuccessMessage(tr('catalog.createdSuccess', 'Catalog created successfully'));\n setTimeout(() => setSuccessMessage(null), 3000);\n };\n\n if (loading && catalogs.length === 0) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <LoadingState message={tr('catalog.loading', 'Loading catalogs...')} />\n </MotionPage>\n );\n }\n\n if (error && catalogs.length === 0) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <ErrorState\n title={tr('catalog.failedLoad', 'Failed to load catalogs')}\n message={error.message}\n onRetry={() => refetch()}\n />\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <PageHeader\n title={tr('catalog.title', 'Catalogs')}\n description={tr('catalog.description', '{{total}} catalogs', {\n total: catalogs.length,\n })}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n title={tr('common.refresh', 'Refresh')}\n >\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <button\n onClick={() => setShowCreateForm(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('catalog.createCatalog', 'Create Catalog')}\n </button>\n </div>\n }\n />\n\n {/* Filters */}\n <div className=\"flex items-center gap-2 sm:gap-3 flex-wrap\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('catalog.searchPlaceholder', 'Search catalogs...')}\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n <FilterDropdown\n label={tr('catalog.filterVisibility', 'Visibility')}\n value={visibilityFilter}\n options={visibilityOptions}\n onChange={setVisibilityFilter}\n />\n </div>\n\n {/* Results count */}\n {(searchQuery || visibilityFilter !== 'all') && (\n <p className=\"text-sm text-text-secondary\">\n {tr('catalog.showingResults', 'Showing {{filtered}} of {{total}} catalogs', {\n filtered: filteredCatalogs.length,\n total: catalogs.length,\n })}\n {loading && (\n <span className=\"ml-2 text-text-muted\">\n {tr('common.refreshing', '(refreshing...)')}\n </span>\n )}\n </p>\n )}\n\n {/* Grid */}\n {filteredCatalogs.length > 0 ? (\n <AnimatePresence mode=\"wait\">\n <MotionList\n key=\"catalog-grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {filteredCatalogs.map((catalog) => (\n <MotionItem key={catalog.id}>\n <CatalogCard catalog={catalog} onOpen={handleCatalogSelect} />\n </MotionItem>\n ))}\n </MotionList>\n </AnimatePresence>\n ) : (\n <EmptyState\n icon={<BookOpen className=\"w-8 h-8 text-text-secondary\" />}\n title={\n searchQuery || visibilityFilter !== 'all'\n ? tr('catalog.emptyNoResults', 'No catalogs found')\n : tr('catalog.emptyNoCatalogs', 'No catalogs yet')\n }\n description={\n searchQuery || visibilityFilter !== 'all'\n ? tr('catalog.emptyAdjustSearch', 'Try adjusting your search or filters')\n : tr('catalog.emptyCreate', 'Create your first catalog to organize components')\n }\n action={\n !searchQuery && visibilityFilter === 'all' ? (\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => setShowCreateForm(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('catalog.createCatalog', 'Create Catalog')}\n </button>\n <GetHelpButton prompt=\"What is a Catalog in VibeControls and how do I create one?\" />\n </div>\n ) : undefined\n }\n />\n )}\n\n {/* Success Toast */}\n {successMessage && (\n <div className=\"fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-success-bg text-status-success-text rounded-md shadow-lg text-sm\">\n {successMessage}\n </div>\n )}\n\n {/* Create Form */}\n <CatalogForm\n isOpen={showCreateForm}\n onClose={() => setShowCreateForm(false)}\n onSubmit={handleCreateCatalog}\n />\n </MotionPage>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CatalogPage.js","names":[],"sources":["../../src/pages/CatalogPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { Plus, BookOpen, RefreshCw } from 'lucide-react';\nimport { CatalogCard } from '@/components/catalog';\nimport type { CatalogCardData } from '@/components/catalog';\nimport { CatalogForm } from '@/components/catalog';\nimport type { CatalogFormData } from '@/components/catalog';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { useDraftEntityTags } from '@/hooks/useDraftEntityTags';\nimport {\n PageHeader,\n SearchInput,\n FilterDropdown,\n EmptyState,\n LoadingState,\n ErrorState,\n GetHelpButton,\n} from '@/components/shared';\nimport { MotionPage, MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\nimport { AnimatePresence } from 'framer-motion';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useListCatalogsQuery, useCreateCatalogMutation } from '@/generated/wspace-operations';\n\nexport function CatalogPage() {\n const navigate = useVibeNavigate();\n const { t } = useI18n();\n const { hasPermission, isLoading: permissionsLoading } = usePermissions();\n\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key, params);\n const template = translated === key ? fallback : translated;\n if (!params) return template;\n return Object.entries(params).reduce(\n (acc, [paramKey, paramValue]) => acc.replace(`{{${paramKey}}}`, String(paramValue)),\n template\n );\n },\n [t]\n );\n\n const visibilityOptions = [\n { value: 'all', label: tr('catalog.allVisibility', 'All Visibility') },\n { value: 'PRIVATE', label: tr('catalog.visibilityPrivate', 'Private') },\n { value: 'INTERNAL', label: tr('catalog.visibilityInternal', 'Internal') },\n { value: 'PUBLIC', label: tr('catalog.visibilityPublic', 'Public') },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [visibilityFilter, setVisibilityFilter] = useState('all');\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n\n const { data, loading, error, refetch } = useListCatalogsQuery({\n variables: {\n filter: {\n visibility:\n visibilityFilter !== 'all'\n ? (visibilityFilter as 'PRIVATE' | 'INTERNAL' | 'PUBLIC')\n : undefined,\n },\n ...(searchQuery ? { pagination: { limit: 1000 } } : {}),\n },\n fetchPolicy: 'cache-and-network',\n });\n\n const [createCatalog] = useCreateCatalogMutation({ refetchQueries: ['ListCatalogs'] });\n const { setDraftTagIds, flushTags } = useDraftEntityTags('VIBECONTROLS_CATALOG');\n\n const catalogs: CatalogCardData[] = useMemo(() => {\n const items = data?.vibecontrolsCatalogs?.items ?? [];\n return items.map((item: Record<string, unknown>) => ({\n id: item.id as string,\n name: item.name as string,\n description: (item.description as string) || null,\n visibility: item.visibility as CatalogCardData['visibility'],\n componentCount: (item.componentCount as number) || 0,\n vibeCount: (item.vibeCount as number) || 0,\n tags: (item.tags as string[]) || [],\n createdAt: item.createdAt as string,\n updatedAt: item.updatedAt as string,\n }));\n }, [data?.vibecontrolsCatalogs?.items]);\n\n const filteredCatalogs = useMemo(() => {\n if (!searchQuery) return catalogs;\n const query = searchQuery.toLowerCase();\n return catalogs.filter(\n (c) =>\n c.name.toLowerCase().includes(query) ||\n c.description?.toLowerCase().includes(query) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(query))\n );\n }, [catalogs, searchQuery]);\n\n if (permissionsLoading)\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <p className=\"text-text-secondary\">Loading permissions...</p>\n </div>\n );\n if (!hasPermission(VIBE_PERMISSIONS.VIBE_LIST))\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-foreground\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don't have permission to access this page.\n </p>\n </div>\n </div>\n );\n\n const handleCatalogSelect = (catalog: CatalogCardData) => {\n navigate(`/catalogs/${catalog.id}`);\n };\n\n const handleCreateCatalog = async (formData: CatalogFormData) => {\n const res = await createCatalog({\n variables: {\n input: {\n name: formData.name,\n description: formData.description || undefined,\n visibility: formData.visibility,\n ownerName: formData.owner || undefined,\n tags: formData.tags.length > 0 ? formData.tags : undefined,\n },\n },\n });\n const newCatalogId = res.data?.createVibecontrolsCatalog?.id;\n if (newCatalogId) await flushTags(newCatalogId);\n setSuccessMessage(tr('catalog.createdSuccess', 'Catalog created successfully'));\n setTimeout(() => setSuccessMessage(null), 3000);\n };\n\n if (loading && catalogs.length === 0) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <LoadingState message={tr('catalog.loading', 'Loading catalogs...')} />\n </MotionPage>\n );\n }\n\n if (error && catalogs.length === 0) {\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <ErrorState\n title={tr('catalog.failedLoad', 'Failed to load catalogs')}\n message={error.message}\n onRetry={() => refetch()}\n />\n </MotionPage>\n );\n }\n\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n <PageHeader\n title={tr('catalog.title', 'Catalogs')}\n description={tr('catalog.description', '{{total}} catalogs', {\n total: catalogs.length,\n })}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n title={tr('common.refresh', 'Refresh')}\n >\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <button\n onClick={() => setShowCreateForm(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('catalog.createCatalog', 'Create Catalog')}\n </button>\n </div>\n }\n />\n\n {/* Filters */}\n <div className=\"flex items-center gap-2 sm:gap-3 flex-wrap\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('catalog.searchPlaceholder', 'Search catalogs...')}\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n <FilterDropdown\n label={tr('catalog.filterVisibility', 'Visibility')}\n value={visibilityFilter}\n options={visibilityOptions}\n onChange={setVisibilityFilter}\n />\n </div>\n\n {/* Results count */}\n {(searchQuery || visibilityFilter !== 'all') && (\n <p className=\"text-sm text-text-secondary\">\n {tr('catalog.showingResults', 'Showing {{filtered}} of {{total}} catalogs', {\n filtered: filteredCatalogs.length,\n total: catalogs.length,\n })}\n {loading && (\n <span className=\"ml-2 text-text-muted\">\n {tr('common.refreshing', '(refreshing...)')}\n </span>\n )}\n </p>\n )}\n\n {/* Grid */}\n {filteredCatalogs.length > 0 ? (\n <AnimatePresence mode=\"wait\">\n <MotionList\n key=\"catalog-grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {filteredCatalogs.map((catalog) => (\n <MotionItem key={catalog.id}>\n <CatalogCard catalog={catalog} onOpen={handleCatalogSelect} />\n </MotionItem>\n ))}\n </MotionList>\n </AnimatePresence>\n ) : (\n <EmptyState\n icon={<BookOpen className=\"w-8 h-8 text-text-secondary\" />}\n title={\n searchQuery || visibilityFilter !== 'all'\n ? tr('catalog.emptyNoResults', 'No catalogs found')\n : tr('catalog.emptyNoCatalogs', 'No catalogs yet')\n }\n description={\n searchQuery || visibilityFilter !== 'all'\n ? tr('catalog.emptyAdjustSearch', 'Try adjusting your search or filters')\n : tr('catalog.emptyCreate', 'Create your first catalog to organize components')\n }\n action={\n !searchQuery && visibilityFilter === 'all' ? (\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => setShowCreateForm(true)}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('catalog.createCatalog', 'Create Catalog')}\n </button>\n <GetHelpButton prompt=\"What is a Catalog in VibeControls and how do I create one?\" />\n </div>\n ) : undefined\n }\n />\n )}\n\n {/* Success Toast */}\n {successMessage && (\n <div className=\"fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-success-bg text-status-success-text rounded-md shadow-lg text-sm\">\n {successMessage}\n </div>\n )}\n\n {/* Create Form */}\n <CatalogForm\n isOpen={showCreateForm}\n onClose={() => setShowCreateForm(false)}\n onSubmit={handleCreateCatalog}\n extraSection={\n <div>\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {tr('catalog.tags', 'Tags')}\n </h3>\n <EntityTagPicker entityType=\"VIBECONTROLS_CATALOG\" onDraftChange={setDraftTagIds} />\n </div>\n }\n />\n </MotionPage>\n );\n}\n"],"mappings":"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"}