@burdenoff/microfe-vibecontrols 2026.522.3 → 2026.522.5
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/vibe/VibeAgentEmptyState.js +126 -18
- package/dist/components/vibe/VibeAgentEmptyState.js.map +1 -1
- package/dist/node_modules/@apollo/client/errors/ServerError.js +17 -0
- package/dist/node_modules/@apollo/client/errors/ServerError.js.map +1 -0
- package/dist/node_modules/@apollo/client/errors/ServerParseError.js +17 -0
- package/dist/node_modules/@apollo/client/errors/ServerParseError.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/batch/batchLink.js +28 -0
- package/dist/node_modules/@apollo/client/link/batch/batchLink.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/batch/batching.js +70 -0
- package/dist/node_modules/@apollo/client/link/batch/batching.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/batch-http/BaseBatchHttpLink.js +74 -0
- package/dist/node_modules/@apollo/client/link/batch-http/BaseBatchHttpLink.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/batch-http/batchHttpLink.js +17 -0
- package/dist/node_modules/@apollo/client/link/batch-http/batchHttpLink.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/client-awareness/ClientAwarenessLink.js +32 -0
- package/dist/node_modules/@apollo/client/link/client-awareness/ClientAwarenessLink.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js +52 -0
- package/dist/node_modules/@apollo/client/link/core/ApolloLink.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/http/checkFetcher.js +9 -0
- package/dist/node_modules/@apollo/client/link/http/checkFetcher.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/http/parseAndCheckHttpResponse.js +45 -0
- package/dist/node_modules/@apollo/client/link/http/parseAndCheckHttpResponse.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/http/selectHttpOptionsAndBody.js +60 -0
- package/dist/node_modules/@apollo/client/link/http/selectHttpOptionsAndBody.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/http/selectURI.js +6 -0
- package/dist/node_modules/@apollo/client/link/http/selectURI.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js +34 -0
- package/dist/node_modules/@apollo/client/link/utils/createOperation.js.map +1 -0
- package/dist/node_modules/@apollo/client/link/utils/filterOperationVariables.js +14 -0
- package/dist/node_modules/@apollo/client/link/utils/filterOperationVariables.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js +6 -0
- package/dist/node_modules/@apollo/client/utilities/caching/sizes.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js +16 -0
- package/dist/node_modules/@apollo/client/utilities/graphql/print.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js +19 -0
- package/dist/node_modules/@apollo/client/utilities/internal/caches.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js +21 -0
- package/dist/node_modules/@apollo/client/utilities/internal/checkDocument.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/compact.js +14 -0
- package/dist/node_modules/@apollo/client/utilities/internal/compact.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js +9 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getMemoryInternals.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js +9 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationDefinition.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js +8 -0
- package/dist/node_modules/@apollo/client/utilities/internal/getOperationName.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js +9 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/global.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js +10 -0
- package/dist/node_modules/@apollo/client/utilities/internal/globals/maybe.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js +10 -0
- package/dist/node_modules/@apollo/client/utilities/internal/makeUniqueId.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js +23 -0
- package/dist/node_modules/@apollo/client/utilities/internal/memoize.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js +10 -0
- package/dist/node_modules/@apollo/client/utilities/internal/stringifyForDisplay.js.map +1 -0
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js +57 -0
- package/dist/node_modules/@apollo/client/utilities/invariant/index.js.map +1 -0
- package/dist/node_modules/@apollo/client/version.js +6 -0
- package/dist/node_modules/@apollo/client/version.js.map +1 -0
- package/dist/node_modules/@wry/caches/lib/weak.js +67 -0
- package/dist/node_modules/@wry/caches/lib/weak.js.map +1 -0
- package/dist/node_modules/@wry/trie/lib/index.js +53 -0
- package/dist/node_modules/@wry/trie/lib/index.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js +21 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/NotificationFactories.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js +78 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Observable.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js +117 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscriber.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js +93 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/Subscription.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js +12 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/config.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js +9 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/empty.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/throwError.js +17 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/observable/throwError.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js +16 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js +8 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/symbol/observable.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js +13 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js +11 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/arrRemove.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js +11 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js +22 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/errorContext.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js +8 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/identity.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js +8 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/isFunction.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js +6 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/noop.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js +13 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/pipe.js.map +1 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js +14 -0
- package/dist/node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js.map +1 -0
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js +52 -0
- package/dist/node_modules/rxjs/node_modules/tslib/tslib.es6.js.map +1 -0
- package/dist/pages/AgentsPage.js +242 -239
- package/dist/pages/AgentsPage.js.map +1 -1
- package/dist/pages/CatalogPage.js +146 -98
- package/dist/pages/CatalogPage.js.map +1 -1
- package/dist/pages/ComponentsPage.js +163 -117
- package/dist/pages/ComponentsPage.js.map +1 -1
- package/dist/pages/TemplatesPage.js +74 -26
- package/dist/pages/TemplatesPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js +449 -396
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js +1 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
- package/dist/providers/VibeControlsProvider.js +35 -30
- package/dist/providers/VibeControlsProvider.js.map +1 -1
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ import { VIBE_PERMISSIONS as c } from "../constants/permissions.js";
|
|
|
11
11
|
import { PageSkeleton as l } from "../components/shared/PageSkeleton.js";
|
|
12
12
|
import { TemplateCard as u } from "../components/templates/TemplateCard.js";
|
|
13
13
|
import "../components/templates/index.js";
|
|
14
|
-
import { useCallback as d,
|
|
14
|
+
import { useCallback as d, useEffect as f, useState as p } from "react";
|
|
15
15
|
import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
16
16
|
import { FileCode as h, RefreshCw as g } from "lucide-react";
|
|
17
17
|
import { usePermissions as _ } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
@@ -60,13 +60,20 @@ function w() {
|
|
|
60
60
|
value: "CUSTOM",
|
|
61
61
|
label: O("template.categoryCustom", "Custom")
|
|
62
62
|
}
|
|
63
|
-
], [A, j] = p(""), [M, N] = p("all"), { data:
|
|
63
|
+
], [A, j] = p(""), [M, N] = p("all"), [P, F] = p([]), [I, L] = p(!1), { data: R, loading: z, error: B, refetch: V, fetchMore: H } = e({
|
|
64
64
|
variables: {
|
|
65
|
-
filter: {
|
|
66
|
-
|
|
65
|
+
filter: {
|
|
66
|
+
category: M === "all" ? void 0 : M,
|
|
67
|
+
search: A || void 0
|
|
68
|
+
},
|
|
69
|
+
pagination: {
|
|
70
|
+
limit: 50,
|
|
71
|
+
offset: 0
|
|
72
|
+
}
|
|
67
73
|
},
|
|
68
|
-
fetchPolicy: "cache-and-network"
|
|
69
|
-
|
|
74
|
+
fetchPolicy: "cache-and-network",
|
|
75
|
+
notifyOnNetworkStatusChange: !0
|
|
76
|
+
}), U = d((e) => e.map((e) => ({
|
|
70
77
|
id: e.id,
|
|
71
78
|
name: e.name,
|
|
72
79
|
description: e.description || null,
|
|
@@ -75,11 +82,43 @@ function w() {
|
|
|
75
82
|
tags: e.tags || [],
|
|
76
83
|
createdAt: e.createdAt,
|
|
77
84
|
updatedAt: e.updatedAt
|
|
78
|
-
})), [
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
})), []);
|
|
86
|
+
f(() => {
|
|
87
|
+
F(U(R?.vibecontrolsTemplates?.items ?? []));
|
|
88
|
+
}, [R?.vibecontrolsTemplates?.items, U]);
|
|
89
|
+
let W = R?.vibecontrolsTemplates?.total ?? 0, G = P.length < W, K = P, q = P, J = d(async () => {
|
|
90
|
+
if (!(I || !G)) {
|
|
91
|
+
L(!0);
|
|
92
|
+
try {
|
|
93
|
+
await H({
|
|
94
|
+
variables: { pagination: {
|
|
95
|
+
limit: 50,
|
|
96
|
+
offset: P.length
|
|
97
|
+
} },
|
|
98
|
+
updateQuery: (e, { fetchMoreResult: t }) => {
|
|
99
|
+
if (!t?.vibecontrolsTemplates) return e;
|
|
100
|
+
let n = e.vibecontrolsTemplates, r = t.vibecontrolsTemplates;
|
|
101
|
+
return {
|
|
102
|
+
...e,
|
|
103
|
+
vibecontrolsTemplates: {
|
|
104
|
+
...r,
|
|
105
|
+
items: [...n?.items ?? [], ...r.items],
|
|
106
|
+
total: r.total,
|
|
107
|
+
hasMore: r.hasMore
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
} finally {
|
|
113
|
+
L(!1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}, [
|
|
117
|
+
H,
|
|
118
|
+
P.length,
|
|
119
|
+
I,
|
|
120
|
+
G
|
|
121
|
+
]), Y = (e) => {
|
|
83
122
|
w(`/templates/${e.id}`);
|
|
84
123
|
};
|
|
85
124
|
return D ? /* @__PURE__ */ y("div", {
|
|
@@ -88,25 +127,25 @@ function w() {
|
|
|
88
127
|
className: "text-text-secondary",
|
|
89
128
|
children: "Loading permissions..."
|
|
90
129
|
})
|
|
91
|
-
}) : E(c.VIBE_LIST) ?
|
|
130
|
+
}) : E(c.VIBE_LIST) ? B && K.length === 0 ? /* @__PURE__ */ y(C, {
|
|
92
131
|
className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
|
|
93
132
|
children: /* @__PURE__ */ y(r, {
|
|
94
133
|
title: O("template.failedLoad", "Failed to load templates"),
|
|
95
|
-
message:
|
|
96
|
-
onRetry: () =>
|
|
134
|
+
message: B.message,
|
|
135
|
+
onRetry: () => V()
|
|
97
136
|
})
|
|
98
137
|
}) : /* @__PURE__ */ b(C, {
|
|
99
138
|
className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
|
|
100
139
|
children: [
|
|
101
140
|
/* @__PURE__ */ y(n, {
|
|
102
141
|
title: O("template.title", "Templates"),
|
|
103
|
-
description: O("template.description", "{{total}} templates available", { total:
|
|
142
|
+
description: O("template.description", "{{total}} templates available", { total: K.length }),
|
|
104
143
|
actions: /* @__PURE__ */ y("button", {
|
|
105
|
-
onClick: () =>
|
|
106
|
-
disabled:
|
|
144
|
+
onClick: () => V(),
|
|
145
|
+
disabled: z,
|
|
107
146
|
className: "flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50",
|
|
108
147
|
title: O("common.refresh", "Refresh"),
|
|
109
|
-
children: /* @__PURE__ */ y(g, { className: `w-4 h-4 ${
|
|
148
|
+
children: /* @__PURE__ */ y(g, { className: `w-4 h-4 ${z ? "animate-spin" : ""}` })
|
|
110
149
|
})
|
|
111
150
|
}),
|
|
112
151
|
/* @__PURE__ */ b("div", {
|
|
@@ -123,27 +162,27 @@ function w() {
|
|
|
123
162
|
onChange: N
|
|
124
163
|
})]
|
|
125
164
|
}),
|
|
126
|
-
|
|
165
|
+
/* @__PURE__ */ b("p", {
|
|
127
166
|
className: "text-sm text-text-secondary",
|
|
128
167
|
children: [O("template.showingResults", "Showing {{filtered}} of {{total}} templates", {
|
|
129
|
-
filtered:
|
|
130
|
-
total:
|
|
131
|
-
}),
|
|
168
|
+
filtered: q.length,
|
|
169
|
+
total: W
|
|
170
|
+
}), z && /* @__PURE__ */ y("span", {
|
|
132
171
|
className: "ml-2 text-text-muted",
|
|
133
172
|
children: O("common.refreshing", "(refreshing...)")
|
|
134
173
|
})]
|
|
135
174
|
}),
|
|
136
|
-
|
|
175
|
+
z && K.length === 0 ? /* @__PURE__ */ y(l, {
|
|
137
176
|
variant: "cards",
|
|
138
177
|
count: 6
|
|
139
|
-
}) :
|
|
178
|
+
}) : q.length > 0 ? /* @__PURE__ */ y(v, {
|
|
140
179
|
mode: "wait",
|
|
141
180
|
children: /* @__PURE__ */ y(S, {
|
|
142
181
|
stagger: .04,
|
|
143
182
|
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
144
|
-
children:
|
|
183
|
+
children: q.map((e) => /* @__PURE__ */ y(x, { children: /* @__PURE__ */ y(u, {
|
|
145
184
|
template: e,
|
|
146
|
-
onOpen:
|
|
185
|
+
onOpen: Y
|
|
147
186
|
}) }, e.id))
|
|
148
187
|
}, "template-grid")
|
|
149
188
|
}) : /* @__PURE__ */ y(i, {
|
|
@@ -151,6 +190,15 @@ function w() {
|
|
|
151
190
|
title: A || M !== "all" ? O("template.emptyNoResults", "No templates found") : O("template.emptyNoTemplates", "No templates yet"),
|
|
152
191
|
description: A || M !== "all" ? O("template.emptyAdjustSearch", "Try adjusting your search or filters") : O("template.emptyCreate", "Templates will appear here when components are published as templates"),
|
|
153
192
|
action: !A && M === "all" ? /* @__PURE__ */ y(s, { prompt: "What is a Template in VibeControls and how do I create one?" }) : void 0
|
|
193
|
+
}),
|
|
194
|
+
G && q.length > 0 && /* @__PURE__ */ y("div", {
|
|
195
|
+
className: "flex justify-center pt-2",
|
|
196
|
+
children: /* @__PURE__ */ y("button", {
|
|
197
|
+
onClick: J,
|
|
198
|
+
disabled: I,
|
|
199
|
+
className: "flex items-center gap-2 px-4 py-2 bg-bg-sunken text-text-primary rounded-md hover:bg-bg-sunken-hover transition-colors disabled:opacity-50",
|
|
200
|
+
children: I ? O("common.loading", "Loading...") : O("common.loadMore", "Load more")
|
|
201
|
+
})
|
|
154
202
|
})
|
|
155
203
|
]
|
|
156
204
|
}) : /* @__PURE__ */ y("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplatesPage.js","names":[],"sources":["../../src/pages/TemplatesPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { FileCode, RefreshCw } from 'lucide-react';\nimport { TemplateCard } from '@/components/templates';\nimport { PageSkeleton } from '@/components/shared/PageSkeleton';\nimport type { TemplateCardData } from '@/components/templates';\nimport {\n PageHeader,\n SearchInput,\n FilterDropdown,\n EmptyState,\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 { useListTemplatesQuery } from '@/generated/wspace-operations';\n\nexport function TemplatesPage() {\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 categoryOptions = [\n { value: 'all', label: tr('template.allCategories', 'All Categories') },\n { value: 'STARTER', label: tr('template.categoryStarter', 'Starter') },\n { value: 'MICROSERVICE', label: tr('template.categoryMicroservice', 'Microservice') },\n { value: 'FRONTEND', label: tr('template.categoryFrontend', 'Frontend') },\n { value: 'BACKEND', label: tr('template.categoryBackend', 'Backend') },\n { value: 'FULLSTACK', label: tr('template.categoryFullstack', 'Fullstack') },\n { value: 'INFRASTRUCTURE', label: tr('template.categoryInfrastructure', 'Infrastructure') },\n { value: 'LIBRARY', label: tr('template.categoryLibrary', 'Library') },\n { value: 'CUSTOM', label: tr('template.categoryCustom', 'Custom') },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState('all');\n\n const { data, loading, error, refetch } = useListTemplatesQuery({\n variables: {\n filter: {\n category: categoryFilter !== 'all' ? categoryFilter : undefined,\n },\n ...(searchQuery ? { pagination: { limit: 1000 } } : {}),\n },\n fetchPolicy: 'cache-and-network',\n });\n\n const templates: TemplateCardData[] = useMemo(() => {\n const items = data?.vibecontrolsTemplates?.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 category: (item.category as string) || null,\n cloneCount: (item.cloneCount as number) || 0,\n tags: (item.tags as string[]) || [],\n createdAt: item.createdAt as string,\n updatedAt: item.updatedAt as string,\n }));\n }, [data?.vibecontrolsTemplates?.items]);\n\n const filteredTemplates = useMemo(() => {\n if (!searchQuery) return templates;\n const query = searchQuery.toLowerCase();\n return templates.filter(\n (tmpl) =>\n tmpl.name.toLowerCase().includes(query) ||\n tmpl.description?.toLowerCase().includes(query) ||\n tmpl.tags?.some((tag) => tag.toLowerCase().includes(query))\n );\n }, [templates, searchQuery]);\n\n const handleTemplateSelect = (tmpl: TemplateCardData) => {\n navigate(`/templates/${tmpl.id}`);\n };\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 if (error && templates.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('template.failedLoad', 'Failed to load templates')}\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('template.title', 'Templates')}\n description={tr('template.description', '{{total}} templates available', {\n total: templates.length,\n })}\n actions={\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 }\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('template.searchPlaceholder', 'Search templates...')}\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n <FilterDropdown\n label={tr('template.filterCategory', 'Category')}\n value={categoryFilter}\n options={categoryOptions}\n onChange={setCategoryFilter}\n />\n </div>\n\n {/* Results count */}\n {(searchQuery || categoryFilter !== 'all') && (\n <p className=\"text-sm text-text-secondary\">\n {tr('template.showingResults', 'Showing {{filtered}} of {{total}} templates', {\n filtered: filteredTemplates.length,\n total: templates.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 {loading && templates.length === 0 ? (\n <PageSkeleton variant=\"cards\" count={6} />\n ) : filteredTemplates.length > 0 ? (\n <AnimatePresence mode=\"wait\">\n <MotionList\n key=\"template-grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {filteredTemplates.map((tmpl) => (\n <MotionItem key={tmpl.id}>\n <TemplateCard template={tmpl} onOpen={handleTemplateSelect} />\n </MotionItem>\n ))}\n </MotionList>\n </AnimatePresence>\n ) : (\n <EmptyState\n icon={<FileCode className=\"w-8 h-8 text-text-secondary\" />}\n title={\n searchQuery || categoryFilter !== 'all'\n ? tr('template.emptyNoResults', 'No templates found')\n : tr('template.emptyNoTemplates', 'No templates yet')\n }\n description={\n searchQuery || categoryFilter !== 'all'\n ? tr('template.emptyAdjustSearch', 'Try adjusting your search or filters')\n : tr(\n 'template.emptyCreate',\n 'Templates will appear here when components are published as templates'\n )\n }\n action={\n !searchQuery && categoryFilter === 'all' ? (\n <GetHelpButton prompt=\"What is a Template in VibeControls and how do I create one?\" />\n ) : undefined\n }\n />\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TemplatesPage.js","names":[],"sources":["../../src/pages/TemplatesPage.tsx"],"sourcesContent":["import { useState, useCallback, useEffect } from 'react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { VIBE_PERMISSIONS } from '../constants/permissions';\nimport { FileCode, RefreshCw } from 'lucide-react';\nimport { TemplateCard } from '@/components/templates';\nimport { PageSkeleton } from '@/components/shared/PageSkeleton';\nimport type { TemplateCardData } from '@/components/templates';\nimport {\n PageHeader,\n SearchInput,\n FilterDropdown,\n EmptyState,\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 { useListTemplatesQuery } from '@/generated/wspace-operations';\n\nexport function TemplatesPage() {\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 categoryOptions = [\n { value: 'all', label: tr('template.allCategories', 'All Categories') },\n { value: 'STARTER', label: tr('template.categoryStarter', 'Starter') },\n { value: 'MICROSERVICE', label: tr('template.categoryMicroservice', 'Microservice') },\n { value: 'FRONTEND', label: tr('template.categoryFrontend', 'Frontend') },\n { value: 'BACKEND', label: tr('template.categoryBackend', 'Backend') },\n { value: 'FULLSTACK', label: tr('template.categoryFullstack', 'Fullstack') },\n { value: 'INFRASTRUCTURE', label: tr('template.categoryInfrastructure', 'Infrastructure') },\n { value: 'LIBRARY', label: tr('template.categoryLibrary', 'Library') },\n { value: 'CUSTOM', label: tr('template.categoryCustom', 'Custom') },\n ];\n\n const PAGE_SIZE = 50;\n const [searchQuery, setSearchQuery] = useState('');\n const [categoryFilter, setCategoryFilter] = useState('all');\n const [accumulated, setAccumulated] = useState<TemplateCardData[]>([]);\n const [loadingMore, setLoadingMore] = useState(false);\n\n const { data, loading, error, refetch, fetchMore } = useListTemplatesQuery({\n variables: {\n filter: {\n category: categoryFilter !== 'all' ? categoryFilter : undefined,\n search: searchQuery || undefined,\n },\n pagination: { limit: PAGE_SIZE, offset: 0 },\n },\n fetchPolicy: 'cache-and-network',\n notifyOnNetworkStatusChange: true,\n });\n\n const mapItems = useCallback(\n (items: ReadonlyArray<Record<string, unknown>>): TemplateCardData[] =>\n items.map((item) => ({\n id: item.id as string,\n name: item.name as string,\n description: (item.description as string) || null,\n category: (item.category as string) || null,\n cloneCount: (item.cloneCount as number) || 0,\n tags: (item.tags as string[]) || [],\n createdAt: item.createdAt as string,\n updatedAt: item.updatedAt as string,\n })),\n []\n );\n\n useEffect(() => {\n const items = data?.vibecontrolsTemplates?.items ?? [];\n setAccumulated(mapItems(items as ReadonlyArray<Record<string, unknown>>));\n }, [data?.vibecontrolsTemplates?.items, mapItems]);\n\n const total = data?.vibecontrolsTemplates?.total ?? 0;\n const hasMore = accumulated.length < total;\n const templates = accumulated;\n const filteredTemplates = accumulated;\n\n const handleLoadMore = useCallback(async () => {\n if (loadingMore || !hasMore) return;\n setLoadingMore(true);\n try {\n await fetchMore({\n variables: { pagination: { limit: PAGE_SIZE, offset: accumulated.length } },\n updateQuery: (prev, { fetchMoreResult }) => {\n if (!fetchMoreResult?.vibecontrolsTemplates) return prev;\n const prevList = prev.vibecontrolsTemplates;\n const nextList = fetchMoreResult.vibecontrolsTemplates;\n return {\n ...prev,\n vibecontrolsTemplates: {\n ...nextList,\n items: [...(prevList?.items ?? []), ...nextList.items],\n total: nextList.total,\n hasMore: nextList.hasMore,\n },\n };\n },\n });\n } finally {\n setLoadingMore(false);\n }\n }, [fetchMore, accumulated.length, loadingMore, hasMore]);\n\n const handleTemplateSelect = (tmpl: TemplateCardData) => {\n navigate(`/templates/${tmpl.id}`);\n };\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 if (error && templates.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('template.failedLoad', 'Failed to load templates')}\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('template.title', 'Templates')}\n description={tr('template.description', '{{total}} templates available', {\n total: templates.length,\n })}\n actions={\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 }\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('template.searchPlaceholder', 'Search templates...')}\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n <FilterDropdown\n label={tr('template.filterCategory', 'Category')}\n value={categoryFilter}\n options={categoryOptions}\n onChange={setCategoryFilter}\n />\n </div>\n\n {/* Results count */}\n <p className=\"text-sm text-text-secondary\">\n {tr('template.showingResults', 'Showing {{filtered}} of {{total}} templates', {\n filtered: filteredTemplates.length,\n total,\n })}\n {loading && (\n <span className=\"ml-2 text-text-muted\">{tr('common.refreshing', '(refreshing...)')}</span>\n )}\n </p>\n\n {/* Grid */}\n {loading && templates.length === 0 ? (\n <PageSkeleton variant=\"cards\" count={6} />\n ) : filteredTemplates.length > 0 ? (\n <AnimatePresence mode=\"wait\">\n <MotionList\n key=\"template-grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {filteredTemplates.map((tmpl) => (\n <MotionItem key={tmpl.id}>\n <TemplateCard template={tmpl} onOpen={handleTemplateSelect} />\n </MotionItem>\n ))}\n </MotionList>\n </AnimatePresence>\n ) : (\n <EmptyState\n icon={<FileCode className=\"w-8 h-8 text-text-secondary\" />}\n title={\n searchQuery || categoryFilter !== 'all'\n ? tr('template.emptyNoResults', 'No templates found')\n : tr('template.emptyNoTemplates', 'No templates yet')\n }\n description={\n searchQuery || categoryFilter !== 'all'\n ? tr('template.emptyAdjustSearch', 'Try adjusting your search or filters')\n : tr(\n 'template.emptyCreate',\n 'Templates will appear here when components are published as templates'\n )\n }\n action={\n !searchQuery && categoryFilter === 'all' ? (\n <GetHelpButton prompt=\"What is a Template in VibeControls and how do I create one?\" />\n ) : undefined\n }\n />\n )}\n\n {/* Load more */}\n {hasMore && filteredTemplates.length > 0 && (\n <div className=\"flex justify-center pt-2\">\n <button\n onClick={handleLoadMore}\n disabled={loadingMore}\n className=\"flex items-center gap-2 px-4 py-2 bg-bg-sunken text-text-primary rounded-md hover:bg-bg-sunken-hover transition-colors disabled:opacity-50\"\n >\n {loadingMore\n ? tr('common.loading', 'Loading...')\n : tr('common.loadMore', 'Load more')}\n </button>\n </div>\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}
|