@burdenoff/fluidgrids-fe-sdk 2026.1109.5 → 2026.1109.6

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.
@@ -1,4 +1,4 @@
1
- import { useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TEMPLATE_STORE_CATEGORIES, TemplateCard, useTemplateSubmissions, usePublishToStore } from './chunk-L3UC5E4J.js';
1
+ import { TEMPLATE_STORE_CATEGORIES, useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TemplateCard, useTemplateSubmissions, usePublishToStore } from './chunk-L3UC5E4J.js';
2
2
  import { QuotaExhaustedDialog } from './chunk-5WUX3DET.js';
3
3
  import { templatesControls } from './chunk-FNZZ5JJL.js';
4
4
  import { useWorkflowDefinitions, useDuplicateWorkflow, useLazyWorkflowDefinition } from './chunk-K7YFK5K2.js';
@@ -873,43 +873,100 @@ function MySubmissionsPanel({ onResubmit }) {
873
873
  );
874
874
  }) });
875
875
  }
876
- var CATEGORIES = [
877
- { value: "all", label: "All", icon: "mdi:view-grid" },
876
+
877
+ // src/modules/templates/utils/gallery-category.ts
878
+ var STORE_CATEGORIES = new Set(
879
+ Object.keys(TEMPLATE_CATEGORY_LABELS)
880
+ );
881
+ function isTemplateStoreCategory(value) {
882
+ return STORE_CATEGORIES.has(value);
883
+ }
884
+ var CATEGORY_ALIASES = /* @__PURE__ */ new Map([
885
+ ["notification", "communication"],
886
+ ["notifications", "communication"],
887
+ ["ai-automation", "ai-ml"],
888
+ ["ai-data", "ai-ml"],
889
+ ["developer-tools", "devops"],
890
+ ["ai", "ai-ml"],
891
+ ["ai/ml", "ai-ml"]
892
+ ]);
893
+ function storedGalleryCategory(category) {
894
+ const value = category?.trim().toLowerCase().replace(/[\s_]+/g, "-");
895
+ if (!value) return void 0;
896
+ if (isTemplateStoreCategory(value)) return value;
897
+ return CATEGORY_ALIASES.get(value);
898
+ }
899
+ var KEYWORD_RULES = [
900
+ {
901
+ category: "ai-ml",
902
+ word: /(?<![a-z0-9])(?:ai|ml)(?![a-z0-9])/,
903
+ // "openai" and "gpt" keep names like "OpenAI summary" here now that "ai"
904
+ // has to be a whole word.
905
+ stems: ["model", "llm", "openai", "gpt"]
906
+ },
907
+ {
908
+ category: "integration",
909
+ word: /(?<![a-z0-9])apis?(?![a-z0-9])/,
910
+ stems: ["integrat", "connect"]
911
+ },
912
+ {
913
+ category: "data-processing",
914
+ word: /(?<![a-z0-9])etl(?![a-z0-9])/,
915
+ stems: ["data", "transform", "process"]
916
+ },
878
917
  {
879
- value: "data-processing",
880
- label: "Data Processing",
881
- icon: "mdi:database-cog"
918
+ category: "communication",
919
+ stems: ["email", "slack", "notify", "message"]
882
920
  },
883
- { value: "integration", label: "Integration", icon: "mdi:connection" },
884
- { value: "automation", label: "Automation", icon: "mdi:robot" },
885
- { value: "ai-ml", label: "AI/ML", icon: "mdi:brain" },
886
- { value: "communication", label: "Communication", icon: "mdi:message-text" }
921
+ {
922
+ category: "automation",
923
+ stems: ["automat", "schedule", "trigger"]
924
+ }
887
925
  ];
888
- var CATEGORY_COLORS = {
889
- "data-processing": "bg-status-info-bg-subtle text-status-info-text border-status-info-border",
890
- integration: "bg-chart-3/10 text-chart-3 border-chart-3/30",
891
- automation: "bg-status-success-bg-subtle text-status-success-text border-status-success-border",
892
- "ai-ml": "bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border",
893
- communication: "bg-status-error-bg-subtle text-status-error-text border-status-error-border"
894
- };
895
- function inferCategory(workflow) {
926
+ var DEFAULT_GALLERY_CATEGORY = "automation";
927
+ function inferGalleryCategory(workflow) {
896
928
  const text = [
897
929
  workflow.name,
898
930
  workflow.description ?? "",
899
931
  ...workflow.tags ?? [],
900
932
  workflow.category ?? ""
901
933
  ].join(" ").toLowerCase();
902
- if (text.includes("ai") || text.includes("ml") || text.includes("model") || text.includes("llm"))
903
- return "ai-ml";
904
- if (text.includes("integrat") || text.includes("api") || text.includes("connect"))
905
- return "integration";
906
- if (text.includes("data") || text.includes("etl") || text.includes("transform") || text.includes("process"))
907
- return "data-processing";
908
- if (text.includes("email") || text.includes("slack") || text.includes("notify") || text.includes("message"))
909
- return "communication";
910
- if (text.includes("automat") || text.includes("schedule") || text.includes("trigger"))
911
- return "automation";
912
- return "automation";
934
+ for (const rule of KEYWORD_RULES) {
935
+ if (rule.word?.test(text) || rule.stems.some((s) => text.includes(s))) {
936
+ return rule.category;
937
+ }
938
+ }
939
+ return DEFAULT_GALLERY_CATEGORY;
940
+ }
941
+ function galleryCategory(workflow) {
942
+ return storedGalleryCategory(workflow.category) ?? inferGalleryCategory(workflow);
943
+ }
944
+ var CATEGORY_FILTERS = ["all", ...TEMPLATE_STORE_CATEGORIES];
945
+ var CATEGORY_FILTER_OPTIONS = CATEGORY_FILTERS.map((value) => ({
946
+ value,
947
+ label: value === "all" ? "All" : TEMPLATE_CATEGORY_LABELS[value]
948
+ }));
949
+ var CATEGORY_COLORS = {
950
+ "data-processing": "bg-status-info-bg-subtle text-status-info-text border-status-info-border",
951
+ integration: "bg-chart-3/10 text-chart-3 border-chart-3/30",
952
+ automation: "bg-status-success-bg-subtle text-status-success-text border-status-success-border",
953
+ "ai-ml": "bg-status-warning-bg-subtle text-status-warning-text border-status-warning-border",
954
+ communication: "bg-status-error-bg-subtle text-status-error-text border-status-error-border",
955
+ devops: "bg-chart-1/10 text-chart-1 border-chart-1/30",
956
+ marketing: "bg-chart-5/10 text-chart-5 border-chart-5/30",
957
+ sales: "bg-chart-4/10 text-chart-4 border-chart-4/30",
958
+ support: "bg-chart-6/10 text-chart-6 border-chart-6/30",
959
+ productivity: "bg-chart-7/10 text-chart-7 border-chart-7/30",
960
+ finance: "bg-chart-12/10 text-chart-12 border-chart-12/30"
961
+ };
962
+ function categoryIcon(value) {
963
+ return value === "all" ? "mdi:view-grid" : TEMPLATE_CATEGORY_ICONS[value];
964
+ }
965
+ function categoryLabel2(tr, value) {
966
+ return value === "all" ? tr("fluidgrids.templates.categories.all", "All") : tr(
967
+ `fluidgrids.templates.categories.${value}`,
968
+ TEMPLATE_CATEGORY_LABELS[value]
969
+ );
913
970
  }
914
971
  function TemplateSkeleton() {
915
972
  return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-52 rounded-lg bg-card-foreground/10" }, i)) });
@@ -975,8 +1032,6 @@ function WorkspaceTemplateCard({
975
1032
  isLoading
976
1033
  }) {
977
1034
  const tr = useTr();
978
- const categoryLabel2 = CATEGORIES.find((c) => c.value === category)?.label ?? tr("fluidgrids.templates.templatesPage.cardDefaultCategory", "Workflow");
979
- const categoryColor = CATEGORY_COLORS[category] ?? "bg-bg-sunken text-text-muted border-border-strong";
980
1035
  return /* @__PURE__ */ jsxs(Card, { className: "group border border-border-secondary bg-background-secondary hover:border-border-primary transition-all duration-200 flex flex-col", children: [
981
1036
  /* @__PURE__ */ jsxs(CardHeader, { className: "flex-1 pb-3", children: [
982
1037
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2 mb-3", children: [
@@ -988,7 +1043,7 @@ function WorkspaceTemplateCard({
988
1043
  className: "text-text-primary"
989
1044
  }
990
1045
  ) }),
991
- /* @__PURE__ */ jsx(Badge, { variant: "outline", className: categoryColor, children: categoryLabel2 })
1046
+ /* @__PURE__ */ jsx(Badge, { variant: "outline", className: CATEGORY_COLORS[category], children: categoryLabel2(tr, category) })
992
1047
  ] }),
993
1048
  /* @__PURE__ */ jsx("h3", { className: "font-semibold text-text-primary text-base leading-tight mb-1.5 line-clamp-2", children: workflow.name }),
994
1049
  /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary line-clamp-2 min-h-[2.5rem]", children: workflow.description || tr(
@@ -1138,7 +1193,7 @@ function TemplatesPage() {
1138
1193
  const categorizedWorkflows = useMemo(() => {
1139
1194
  return workflows.map((w) => ({
1140
1195
  workflow: w,
1141
- category: w.category ? w.category.toLowerCase().replace(/\s+/g, "-") : inferCategory(w)
1196
+ category: galleryCategory(w)
1142
1197
  }));
1143
1198
  }, [workflows]);
1144
1199
  const filtered = useMemo(() => {
@@ -1175,13 +1230,10 @@ function TemplatesPage() {
1175
1230
  { source: "template" }
1176
1231
  );
1177
1232
  if (result?.success && result.workflow) {
1178
- const category = workflow.category ? workflow.category.toLowerCase().replace(/\s+/g, "-") : inferCategory(workflow);
1179
1233
  emitTemplateUsed(bus, {
1180
1234
  workspaceId,
1181
1235
  templateId: workflow.id,
1182
- category: CATEGORIES.some(
1183
- (c) => c.value !== "all" && c.value === category
1184
- ) ? category : void 0
1236
+ category: galleryCategory(workflow)
1185
1237
  });
1186
1238
  toast.success(
1187
1239
  tr(
@@ -1327,20 +1379,14 @@ function TemplatesPage() {
1327
1379
  category: {
1328
1380
  // The chips carry no visible heading; the labels are the page's own.
1329
1381
  label: "Category",
1330
- options: CATEGORIES.map(({ value, label }) => ({ value, label })),
1382
+ options: CATEGORY_FILTER_OPTIONS,
1331
1383
  neutral: "all",
1332
1384
  value: activeCategory,
1333
1385
  set: setActiveCategory
1334
1386
  },
1335
1387
  storeCategory: {
1336
1388
  label: "Category",
1337
- options: [
1338
- { value: "all", label: "All" },
1339
- ...TEMPLATE_STORE_CATEGORIES.map((value) => ({
1340
- value,
1341
- label: TEMPLATE_CATEGORY_LABELS[value]
1342
- }))
1343
- ],
1389
+ options: CATEGORY_FILTER_OPTIONS,
1344
1390
  neutral: "all",
1345
1391
  value: storeCategory,
1346
1392
  set: setStoreCategory
@@ -1469,17 +1515,18 @@ function TemplatesPage() {
1469
1515
  {
1470
1516
  className: "flex flex-wrap gap-2 mb-6",
1471
1517
  "data-tour": "fluidgrids-templates-category-tabs",
1472
- children: CATEGORIES.map((cat) => {
1473
- const count = categoryCounts[cat.value] ?? 0;
1474
- const isActive = activeCategory === cat.value;
1518
+ children: CATEGORY_FILTERS.map((value) => {
1519
+ const count = categoryCounts[value] ?? 0;
1520
+ const isActive = activeCategory === value;
1475
1521
  return /* @__PURE__ */ jsxs(
1476
1522
  "button",
1477
1523
  {
1478
- onClick: () => setActiveCategory(cat.value),
1524
+ onClick: () => setActiveCategory(value),
1525
+ "aria-pressed": isActive,
1479
1526
  className: `inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${isActive ? "bg-background-tertiary text-text-primary border border-border-primary" : "bg-background-secondary text-text-secondary border border-border-secondary hover:text-text-primary hover:border-border-primary"}`,
1480
1527
  children: [
1481
- /* @__PURE__ */ jsx(Icon, { icon: cat.icon, width: 16 }),
1482
- cat.label,
1528
+ /* @__PURE__ */ jsx(Icon, { icon: categoryIcon(value), width: 16 }),
1529
+ categoryLabel2(tr, value),
1483
1530
  /* @__PURE__ */ jsxs(
1484
1531
  "span",
1485
1532
  {
@@ -1493,7 +1540,7 @@ function TemplatesPage() {
1493
1540
  )
1494
1541
  ]
1495
1542
  },
1496
- cat.value
1543
+ value
1497
1544
  );
1498
1545
  })
1499
1546
  }
@@ -1522,7 +1569,7 @@ function TemplatesPage() {
1522
1569
  {
1523
1570
  className: "flex flex-wrap gap-2 mb-6",
1524
1571
  "data-testid": "store-template-categories",
1525
- children: ["all", ...TEMPLATE_STORE_CATEGORIES].map((value) => {
1572
+ children: CATEGORY_FILTERS.map((value) => {
1526
1573
  const isActive = storeCategory === value;
1527
1574
  return /* @__PURE__ */ jsxs(
1528
1575
  "button",
@@ -1531,17 +1578,8 @@ function TemplatesPage() {
1531
1578
  "aria-pressed": isActive,
1532
1579
  className: `inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${isActive ? "bg-background-tertiary text-text-primary border border-border-primary" : "bg-background-secondary text-text-secondary border border-border-secondary hover:text-text-primary hover:border-border-primary"}`,
1533
1580
  children: [
1534
- /* @__PURE__ */ jsx(
1535
- Icon,
1536
- {
1537
- icon: value === "all" ? "mdi:view-grid" : TEMPLATE_CATEGORY_ICONS[value],
1538
- width: 16
1539
- }
1540
- ),
1541
- value === "all" ? tr("fluidgrids.templates.categories.all", "All") : tr(
1542
- `fluidgrids.templates.categories.${value}`,
1543
- TEMPLATE_CATEGORY_LABELS[value]
1544
- )
1581
+ /* @__PURE__ */ jsx(Icon, { icon: categoryIcon(value), width: 16 }),
1582
+ categoryLabel2(tr, value)
1545
1583
  ]
1546
1584
  },
1547
1585
  value
package/dist/index.js CHANGED
@@ -28,8 +28,8 @@ import { useResource, FieldError, StatusPill, RUN_CONTROL_DIALOG_STYLE, NativeSe
28
28
  import './chunk-WZ3EJVS6.js';
29
29
  export { useDataSinkData, useDataSinks, useInsightsData, useLogStreamDestinationActions, useLogStreamDestinations, useRunReplayActions } from './chunk-2SUZKBHB.js';
30
30
  import './chunk-5ERAJC2I.js';
31
- import { ThemeProvider, extractTemplateGraph } from './chunk-NFGRUDTL.js';
32
- export { TemplatePreview, TemplatesPage } from './chunk-NFGRUDTL.js';
31
+ import { ThemeProvider, extractTemplateGraph } from './chunk-4I6BXKKC.js';
32
+ export { TemplatePreview, TemplatesPage } from './chunk-4I6BXKKC.js';
33
33
  import { useAiWorkflowTemplates, AI_DRAFT_MAX_PROMPT_LENGTH, FlowBuilderPage, FluidGridsMark, draftToCanvas, enrichDraftNodes } from './chunk-L3UC5E4J.js';
34
34
  export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, RunsUsageMeter, RunsUsageMeterView, readRunsQuota, runsQuotaLevel, summarizeRunsQuota, useRunsQuota } from './chunk-L3UC5E4J.js';
35
35
  import './chunk-HZ7FQCFU.js';
package/dist/templates.js CHANGED
@@ -1,4 +1,4 @@
1
- export { TemplatePreview, TemplatesPage } from './chunk-NFGRUDTL.js';
1
+ export { TemplatePreview, TemplatesPage } from './chunk-4I6BXKKC.js';
2
2
  import './chunk-L3UC5E4J.js';
3
3
  import './chunk-HZ7FQCFU.js';
4
4
  import './chunk-GEMNVFPK.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fluidgrids-fe-sdk",
3
- "version": "2026.1109.5",
3
+ "version": "2026.1109.6",
4
4
  "description": "FluidGrids Workflow Builder SDK - Embeddable visual workflow automation",
5
5
  "type": "module",
6
6
  "imports": {