@burdenoff/fluidgrids-fe-sdk 2026.803.4 → 2026.804.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 (55) hide show
  1. package/dist/ExecutionDetailPage-FF2DYKAZ.js +10 -0
  2. package/dist/{ExecutionDetailPage-FCY3S336.js.map → ExecutionDetailPage-FF2DYKAZ.js.map} +1 -1
  3. package/dist/ExecutionsListPage-NKISRFMA.js +9 -0
  4. package/dist/{ExecutionsListPage-IZJPACQV.js.map → ExecutionsListPage-NKISRFMA.js.map} +1 -1
  5. package/dist/MissingNodesInstallModal-HA5L3FK2.js +185 -0
  6. package/dist/MissingNodesInstallModal-HA5L3FK2.js.map +1 -0
  7. package/dist/{TemplateConfigurationModal-MTR7VP6G.js → TemplateConfigurationModal-MXNGZQIC.js} +91 -21
  8. package/dist/TemplateConfigurationModal-MXNGZQIC.js.map +1 -0
  9. package/dist/{TemplateDetailPanel-T3ZHXOHX.js → TemplateDetailPanel-CJ3NPVTP.js} +50 -14
  10. package/dist/TemplateDetailPanel-CJ3NPVTP.js.map +1 -0
  11. package/dist/{WorkflowBuilder-WMAHTZEI.js → WorkflowBuilder-ETVB66U6.js} +9 -9
  12. package/dist/{WorkflowBuilder-WMAHTZEI.js.map → WorkflowBuilder-ETVB66U6.js.map} +1 -1
  13. package/dist/WorkflowsList-TZAN3YBA.js +11 -0
  14. package/dist/{WorkflowsList-BXESQVAH.js.map → WorkflowsList-TZAN3YBA.js.map} +1 -1
  15. package/dist/{chunk-WAVGHDYH.js → chunk-6PNRM3KQ.js} +469 -114
  16. package/dist/chunk-6PNRM3KQ.js.map +1 -0
  17. package/dist/chunk-7VNIEIR6.js +21 -0
  18. package/dist/chunk-7VNIEIR6.js.map +1 -0
  19. package/dist/{chunk-F5ACDIYR.js → chunk-IWKLEFC7.js} +205 -51
  20. package/dist/chunk-IWKLEFC7.js.map +1 -0
  21. package/dist/{chunk-MRVS73S2.js → chunk-OHGXRM6Z.js} +7 -23
  22. package/dist/chunk-OHGXRM6Z.js.map +1 -0
  23. package/dist/chunk-P5PKRQAO.js +25 -0
  24. package/dist/chunk-P5PKRQAO.js.map +1 -0
  25. package/dist/{chunk-CQAHXNT2.js → chunk-SG7Z2IRQ.js} +55 -18
  26. package/dist/chunk-SG7Z2IRQ.js.map +1 -0
  27. package/dist/chunk-WQ4QNHDN.js +29639 -0
  28. package/dist/chunk-WQ4QNHDN.js.map +1 -0
  29. package/dist/{chunk-ZM4SSEVI.js → chunk-Y36DJHU3.js} +211 -3
  30. package/dist/chunk-Y36DJHU3.js.map +1 -0
  31. package/dist/{chunk-CBUOMHGH.js → chunk-YJKZSUNC.js} +140 -47
  32. package/dist/chunk-YJKZSUNC.js.map +1 -0
  33. package/dist/index.d.ts +33 -2
  34. package/dist/index.js +643 -182
  35. package/dist/index.js.map +1 -1
  36. package/package.json +1 -1
  37. package/dist/ExecutionDetailPage-FCY3S336.js +0 -9
  38. package/dist/ExecutionsListPage-IZJPACQV.js +0 -8
  39. package/dist/TemplateConfigurationModal-MTR7VP6G.js.map +0 -1
  40. package/dist/TemplateDetailPanel-T3ZHXOHX.js.map +0 -1
  41. package/dist/WorkflowsList-BXESQVAH.js +0 -11
  42. package/dist/blocks-7KN7ZRE6.js +0 -11
  43. package/dist/blocks-7KN7ZRE6.js.map +0 -1
  44. package/dist/chunk-7LLCYNKY.js +0 -10910
  45. package/dist/chunk-7LLCYNKY.js.map +0 -1
  46. package/dist/chunk-CBUOMHGH.js.map +0 -1
  47. package/dist/chunk-CQAHXNT2.js.map +0 -1
  48. package/dist/chunk-F5ACDIYR.js.map +0 -1
  49. package/dist/chunk-MRVS73S2.js.map +0 -1
  50. package/dist/chunk-OAPYQFQU.js +0 -197
  51. package/dist/chunk-OAPYQFQU.js.map +0 -1
  52. package/dist/chunk-WAVGHDYH.js.map +0 -1
  53. package/dist/chunk-Z3NRSPTV.js +0 -15355
  54. package/dist/chunk-Z3NRSPTV.js.map +0 -1
  55. package/dist/chunk-ZM4SSEVI.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,27 +1,21 @@
1
1
  export { Label } from './chunk-6QCBKN3P.js';
2
- import { FluidGridsProvider, useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TemplateCard, Card } from './chunk-Z3NRSPTV.js';
3
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, EntityTagPicker, FluidGridsProvider, WorkflowBuilder as WorkflowBuilderPage, useFluidGridsContext } from './chunk-Z3NRSPTV.js';
4
- import { Input as Input$1 } from './chunk-MRVS73S2.js';
5
- export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Input } from './chunk-MRVS73S2.js';
6
- import { Button as Button$1 } from './chunk-DBOMRIP5.js';
7
- export { Badge, Button, badgeVariants, buttonVariants } from './chunk-DBOMRIP5.js';
8
- export { ExecutionsListPage } from './chunk-CQAHXNT2.js';
9
- export { ExecutionDetailPage } from './chunk-F5ACDIYR.js';
10
- import './chunk-WAVGHDYH.js';
11
- export { ConfigSchemaForm, ConnectionFormDialog, ConnectionSelector, ProviderPicker, getProviderForm, listCustomBlocks, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useInitiateOAuth, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders } from './chunk-7LLCYNKY.js';
2
+ import { FluidGridsProvider, useImportWorkflowTemplate, FlowBuilderPage, useWorkflowTemplates, TemplateCard, Card } from './chunk-WQ4QNHDN.js';
3
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConfigSchemaForm, ConnectionFormDialog, ConnectionSelector, EntityTagPicker, FluidGridsProvider, ProviderPicker, WorkflowBuilder as WorkflowBuilderPage, getProviderForm, listCustomBlocks, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useFluidGridsContext, useInitiateOAuth, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders } from './chunk-WQ4QNHDN.js';
4
+ import { Input as Input$1 } from './chunk-P5PKRQAO.js';
5
+ export { Input } from './chunk-P5PKRQAO.js';
6
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-OHGXRM6Z.js';
7
+ export { ExecutionsListPage } from './chunk-SG7Z2IRQ.js';
8
+ export { ExecutionDetailPage } from './chunk-IWKLEFC7.js';
9
+ import './chunk-6PNRM3KQ.js';
12
10
  import { createGlobalStoreClient } from './chunk-BQXHJIER.js';
13
11
  export { createGlobalStoreClient, getGlobalStoreClient, resetGlobalStoreClient, setGlobalStoreClient } from './chunk-BQXHJIER.js';
14
12
  import './chunk-PNOA7CQV.js';
15
- export { WorkflowsList } from './chunk-CBUOMHGH.js';
16
- import { QuotaExhaustedDialog } from './chunk-OAPYQFQU.js';
17
- export { FLUIDGRIDS_ENTITY_TYPES, tagLabel, useAvailableTags, useCreateTag, useDraftEntityTags, useEntityTags, useReplaceEntityTags, useSearchTags, useTagEntity, useUntagEntity } from './chunk-OAPYQFQU.js';
13
+ export { WorkflowsList } from './chunk-YJKZSUNC.js';
14
+ import { QuotaExhaustedDialog, useFlowStore } from './chunk-Y36DJHU3.js';
15
+ export { FLUIDGRIDS_ENTITY_TYPES, tagLabel, useAvailableTags, useCreateTag, useDraftEntityTags, useEntityTags, useFlowStore, useReplaceEntityTags, useSearchTags, useTagEntity, useUntagEntity } from './chunk-Y36DJHU3.js';
18
16
  import { useWorkflowDefinition, useWorkflowDefinitions, useDuplicateWorkflow } from './chunk-MH4AHYK3.js';
19
17
  export { useActivateWorkflow, useCreateWorkflow, useCreateWorkflowVersion, useDashboardSummary, useDeactivateWorkflow, useDeleteWorkflow, useDuplicateWorkflow, useLazyWorkflowDefinition, useRestoreWorkflowVersion, useTriggerWorkflow, useUpdateWorkflow, useWorkflowDefinition, useWorkflowDefinitions, useWorkflowRun, useWorkflowRuns, useWorkflowVersions } from './chunk-MH4AHYK3.js';
20
- import { useFlowStore } from './chunk-ZM4SSEVI.js';
21
- export { useFlowStore } from './chunk-ZM4SSEVI.js';
22
18
  export { ALLOW_ALL_PERMISSIONS, FLUIDGRIDS_PERMISSIONS, FluidGridsPermissionsProvider, SdkPermissionButton, SdkPermissionGate, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, evaluatePermissionCheck, useFluidGridsPermission } from './chunk-UIY2HBWA.js';
23
- import { cn } from './chunk-3ZYUGTIT.js';
24
- export { cn } from './chunk-3ZYUGTIT.js';
25
19
  import { NodeEndpointConfigsDocument, NodeEndpointConfigDocument, NodeManifestDocument } from './chunk-V5UEEB74.js';
26
20
  export { ActivateWorkflowDefinitionDocument, ActiveExecutionsDocument, AvailableFluidgridsTagsDocument, CancelExecutionDocument, CreateFluidgridsTagDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, DashboardSummaryDocument, DeactivateWorkflowDefinitionDocument, DeleteWorkflowDefinitionDocument, DuplicateWorkflowDocument, EventRegistrationsDocument, ExecutionDetailDocument, ExecutionLogsDocument, ExecutionStatsDocument, ExecutionsListDocument, FluidgridsAvailableTagFieldsFragmentDoc, FluidgridsEntityTagsDocument, FluidgridsTagAssignmentFieldsFragmentDoc, ImportWorkflowTemplateDocument, NodeEndpointConfigDocument, NodeEndpointConfigsDocument, NodeManifestDocument, NodeSchemaIntrospectionDocument, NodeStatesDocument, NodeUsageStatusDocument, PauseExecutionDocument, RegisterNodeDocument, RemoveNodeFromWorkflowsDocument, ReplaceFluidgridsEntityTagsDocument, RestoreWorkflowVersionDocument, ResumeExecutionDocument, RetryNodeDocument, RunLogAppendedDocument, RunLogLineFieldsFragmentDoc, RunLogsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, TerminateExecutionDocument, TriggerWorkflowDocument, UntagFluidgridsEntityDocument, UpdateWorkflowDefinitionDocument, UsageTimeSeriesDocument, WorkflowDefinitionDocument, WorkflowDefinitionsDocument, WorkflowDefinitionsTagsDocument, WorkflowRunDocument, WorkflowRunsDocument, WorkflowVersionsDocument, describeOperationError, throwIfResultError, useActivateWorkflowDefinitionMutation, useActiveExecutionsLazyQuery, useActiveExecutionsQuery, useActiveExecutionsSuspenseQuery, useAvailableFluidgridsTagsLazyQuery, useAvailableFluidgridsTagsQuery, useAvailableFluidgridsTagsSuspenseQuery, useCancelExecutionMutation, useCreateFluidgridsTagMutation, useCreateWorkflowDefinitionMutation, useCreateWorkflowVersionMutation, useDashboardSummaryLazyQuery, useDashboardSummaryQuery, useDashboardSummarySuspenseQuery, useDeactivateWorkflowDefinitionMutation, useDeleteWorkflowDefinitionMutation, useDuplicateWorkflowMutation, useEventRegistrationsLazyQuery, useEventRegistrationsQuery, useEventRegistrationsSuspenseQuery, useExecutionDetailLazyQuery, useExecutionDetailQuery, useExecutionDetailSuspenseQuery, useExecutionLogsLazyQuery, useExecutionLogsQuery, useExecutionLogsSuspenseQuery, useExecutionStatsLazyQuery, useExecutionStatsQuery, useExecutionStatsSuspenseQuery, useExecutionsListLazyQuery, useExecutionsListQuery, useExecutionsListSuspenseQuery, useFluidgridsEntityTagsLazyQuery, useFluidgridsEntityTagsQuery, useFluidgridsEntityTagsSuspenseQuery, useImportWorkflowTemplateMutation, useNodeEndpointConfigLazyQuery, useNodeEndpointConfigQuery, useNodeEndpointConfigSuspenseQuery, useNodeEndpointConfigsLazyQuery, useNodeEndpointConfigsQuery, useNodeEndpointConfigsSuspenseQuery, useNodeManifestLazyQuery, useNodeManifestQuery, useNodeManifestSuspenseQuery, useNodeSchemaIntrospectionLazyQuery, useNodeSchemaIntrospectionQuery, useNodeSchemaIntrospectionSuspenseQuery, useNodeStatesLazyQuery, useNodeStatesQuery, useNodeStatesSuspenseQuery, useNodeUsageStatusLazyQuery, useNodeUsageStatusQuery, useNodeUsageStatusSuspenseQuery, usePauseExecutionMutation, useRegisterNodeMutation, useRemoveNodeFromWorkflowsMutation, useReplaceFluidgridsEntityTagsMutation, useRestoreWorkflowVersionMutation, useResumeExecutionMutation, useRetryNodeMutation, useRunLogAppendedSubscription, useRunLogsLazyQuery, useRunLogsQuery, useRunLogsSuspenseQuery, useSearchFluidgridsTagsLazyQuery, useSearchFluidgridsTagsQuery, useSearchFluidgridsTagsSuspenseQuery, useTagFluidgridsEntityMutation, useTerminateExecutionMutation, useTriggerWorkflowMutation, useUntagFluidgridsEntityMutation, useUpdateWorkflowDefinitionMutation, useUsageTimeSeriesLazyQuery, useUsageTimeSeriesQuery, useUsageTimeSeriesSuspenseQuery, useWorkflowDefinitionLazyQuery, useWorkflowDefinitionQuery, useWorkflowDefinitionSuspenseQuery, useWorkflowDefinitionsLazyQuery, useWorkflowDefinitionsQuery, useWorkflowDefinitionsSuspenseQuery, useWorkflowDefinitionsTagsLazyQuery, useWorkflowDefinitionsTagsQuery, useWorkflowDefinitionsTagsSuspenseQuery, useWorkflowRunLazyQuery, useWorkflowRunQuery, useWorkflowRunSuspenseQuery, useWorkflowRunsLazyQuery, useWorkflowRunsQuery, useWorkflowRunsSuspenseQuery, useWorkflowVersionsLazyQuery, useWorkflowVersionsQuery, useWorkflowVersionsSuspenseQuery } from './chunk-V5UEEB74.js';
27
21
  import { getFluidGridsClient, createFluidGridsClient } from './chunk-5BDQNSP3.js';
@@ -29,6 +23,12 @@ export { createFluidGridsClient, getFluidGridsClient, getFluidGridsClientSafe, i
29
23
  import { getFluidGridsConfig } from './chunk-WWU2O2SR.js';
30
24
  export { config, getFluidGridsConfig, getGraphQLEndpoint, resetFluidGridsConfig, setFluidGridsConfig } from './chunk-WWU2O2SR.js';
31
25
  import './chunk-XQP33UJR.js';
26
+ import { Button as Button$1 } from './chunk-DBOMRIP5.js';
27
+ export { Badge, Button, badgeVariants, buttonVariants } from './chunk-DBOMRIP5.js';
28
+ import { cn } from './chunk-3ZYUGTIT.js';
29
+ export { cn } from './chunk-3ZYUGTIT.js';
30
+ import { useTr } from './chunk-7VNIEIR6.js';
31
+ export { ENGLISH_FALLBACK_TRANSLATOR, FluidGridsTranslationProvider, useTr } from './chunk-7VNIEIR6.js';
32
32
  import * as React4 from 'react';
33
33
  import { lazy, Suspense, useState, useEffect, useMemo, useCallback, useRef } from 'react';
34
34
  import { Routes, Route, Navigate, useParams, useNavigate } from 'react-router';
@@ -57,20 +57,20 @@ import * as SwitchPrimitives from '@radix-ui/react-switch';
57
57
  import * as PopoverPrimitive from '@radix-ui/react-popover';
58
58
 
59
59
  var WorkflowsList2 = lazy(
60
- () => import('./WorkflowsList-BXESQVAH.js').then((m) => ({ default: m.WorkflowsList }))
60
+ () => import('./WorkflowsList-TZAN3YBA.js').then((m) => ({ default: m.WorkflowsList }))
61
61
  );
62
62
  var WorkflowBuilder2 = lazy(
63
- () => import('./WorkflowBuilder-WMAHTZEI.js').then((m) => ({
63
+ () => import('./WorkflowBuilder-ETVB66U6.js').then((m) => ({
64
64
  default: m.WorkflowBuilder
65
65
  }))
66
66
  );
67
67
  var ExecutionsListPage2 = lazy(
68
- () => import('./ExecutionsListPage-IZJPACQV.js').then((m) => ({
68
+ () => import('./ExecutionsListPage-NKISRFMA.js').then((m) => ({
69
69
  default: m.ExecutionsListPage
70
70
  }))
71
71
  );
72
72
  var ExecutionDetailPage2 = lazy(
73
- () => import('./ExecutionDetailPage-FCY3S336.js').then((m) => ({
73
+ () => import('./ExecutionDetailPage-FF2DYKAZ.js').then((m) => ({
74
74
  default: m.ExecutionDetailPage
75
75
  }))
76
76
  );
@@ -175,20 +175,26 @@ function getNodeColor(type) {
175
175
  return NODE_COLORS[type] ?? NODE_COLORS.default;
176
176
  }
177
177
  function TriggerNode({ data }) {
178
+ const tr = useTr();
178
179
  const label = data.label;
179
180
  return /* @__PURE__ */ jsxs("div", { style: { ...baseNodeStyle, background: getNodeColor("trigger:api") }, children: [
180
- label || "API Trigger",
181
+ label || tr(
182
+ "fluidgrids.components.workflowBuilderCore.triggerNodeLabel",
183
+ "API Trigger"
184
+ ),
181
185
  /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: handleStyle })
182
186
  ] });
183
187
  }
184
188
  function EndNode({ data }) {
189
+ const tr = useTr();
185
190
  const label = data.label;
186
191
  return /* @__PURE__ */ jsxs("div", { style: { ...baseNodeStyle, background: getNodeColor("end") }, children: [
187
192
  /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: handleStyle }),
188
- label || "End"
193
+ label || tr("fluidgrids.components.workflowBuilderCore.endNodeLabel", "End")
189
194
  ] });
190
195
  }
191
196
  function ActionNode({ data, type }) {
197
+ const tr = useTr();
192
198
  const label = data.label;
193
199
  const color = getNodeColor(type || "default");
194
200
  return /* @__PURE__ */ jsxs(
@@ -202,7 +208,10 @@ function ActionNode({ data, type }) {
202
208
  },
203
209
  children: [
204
210
  /* @__PURE__ */ jsx(Handle, { type: "target", position: Position.Top, style: handleStyle }),
205
- label || "Action",
211
+ label || tr(
212
+ "fluidgrids.components.workflowBuilderCore.actionNodeLabel",
213
+ "Action"
214
+ ),
206
215
  /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Bottom, style: handleStyle })
207
216
  ]
208
217
  }
@@ -238,6 +247,7 @@ function FlowBuilderInner({
238
247
  className
239
248
  }) {
240
249
  const reactFlowInstance = useReactFlow();
250
+ const tr = useTr();
241
251
  const setWorkflow = useFlowStore((s) => s.actions.setWorkflow);
242
252
  const resetWorkflow = useFlowStore((s) => s.actions.resetWorkflow);
243
253
  const deleteNode = useFlowStore((s) => s.actions.nodes.deleteNode);
@@ -370,7 +380,10 @@ function FlowBuilderInner({
370
380
  className: "font-semibold max-w-[300px]",
371
381
  value: workflowName,
372
382
  onChange: handleNameChange,
373
- placeholder: "Workflow Name",
383
+ placeholder: tr(
384
+ "fluidgrids.components.workflowBuilderCore.workflowNamePlaceholder",
385
+ "Workflow Name"
386
+ ),
374
387
  disabled: readonly
375
388
  }
376
389
  )
@@ -378,11 +391,11 @@ function FlowBuilderInner({
378
391
  !readonly && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
379
392
  /* @__PURE__ */ jsxs(Button$1, { variant: "outline", size: "sm", onClick: handleSave, children: [
380
393
  /* @__PURE__ */ jsx(Save, { className: "size-4 mr-1" }),
381
- "Save"
394
+ tr("fluidgrids.components.workflowBuilderCore.save", "Save")
382
395
  ] }),
383
396
  /* @__PURE__ */ jsxs(Button$1, { size: "sm", onClick: handleExecute, children: [
384
397
  /* @__PURE__ */ jsx(Play, { className: "size-4 mr-1" }),
385
- "Run"
398
+ tr("fluidgrids.components.workflowBuilderCore.run", "Run")
386
399
  ] })
387
400
  ] })
388
401
  ] }),
@@ -414,14 +427,23 @@ function FlowBuilderInner({
414
427
  }
415
428
  ) }),
416
429
  !hideSidebar && !readonly && /* @__PURE__ */ jsxs("div", { className: "w-60 shrink-0 border-l bg-card overflow-y-auto", children: [
417
- /* @__PURE__ */ jsx("div", { className: "p-4 border-b", children: /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold", children: "Node Properties" }) }),
430
+ /* @__PURE__ */ jsx("div", { className: "p-4 border-b", children: /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold", children: tr(
431
+ "fluidgrids.components.workflowBuilderCore.nodePropertiesHeading",
432
+ "Node Properties"
433
+ ) }) }),
418
434
  selectedNode ? /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-4", children: [
419
435
  /* @__PURE__ */ jsxs("div", { children: [
420
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: "Node ID" }),
436
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: tr(
437
+ "fluidgrids.components.workflowBuilderCore.nodeIdLabel",
438
+ "Node ID"
439
+ ) }),
421
440
  /* @__PURE__ */ jsx("code", { className: "block text-xs bg-muted px-2 py-1 rounded font-mono break-all", children: selectedNode.id })
422
441
  ] }),
423
442
  /* @__PURE__ */ jsxs("div", { children: [
424
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: "Type" }),
443
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: tr(
444
+ "fluidgrids.components.workflowBuilderCore.nodeTypeLabel",
445
+ "Type"
446
+ ) }),
425
447
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
426
448
  /* @__PURE__ */ jsx(
427
449
  "span",
@@ -438,19 +460,28 @@ function FlowBuilderInner({
438
460
  ] })
439
461
  ] }),
440
462
  /* @__PURE__ */ jsxs("div", { children: [
441
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: "Label" }),
463
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: tr(
464
+ "fluidgrids.components.workflowBuilderCore.nodeLabelLabel",
465
+ "Label"
466
+ ) }),
442
467
  /* @__PURE__ */ jsx(
443
468
  Input$1,
444
469
  {
445
470
  value: selectedNode.data?.label ?? "",
446
471
  onChange: (e) => handleSelectedNodeLabelChange(e.target.value),
447
472
  className: "text-sm",
448
- placeholder: "Node label"
473
+ placeholder: tr(
474
+ "fluidgrids.components.workflowBuilderCore.nodeLabelPlaceholder",
475
+ "Node label"
476
+ )
449
477
  }
450
478
  )
451
479
  ] }),
452
480
  /* @__PURE__ */ jsxs("div", { children: [
453
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: "Position" }),
481
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: tr(
482
+ "fluidgrids.components.workflowBuilderCore.positionLabel",
483
+ "Position"
484
+ ) }),
454
485
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 text-xs text-muted-foreground", children: [
455
486
  /* @__PURE__ */ jsxs("div", { children: [
456
487
  "X:",
@@ -465,7 +496,10 @@ function FlowBuilderInner({
465
496
  ] })
466
497
  ] }),
467
498
  /* @__PURE__ */ jsxs("div", { children: [
468
- /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: "Connections" }),
499
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-muted-foreground mb-1", children: tr(
500
+ "fluidgrids.components.workflowBuilderCore.connectionsLabel",
501
+ "Connections"
502
+ ) }),
469
503
  /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: (() => {
470
504
  const inbound = edges.filter(
471
505
  (e) => e.target === selectedNode.id
@@ -490,19 +524,34 @@ function FlowBuilderInner({
490
524
  onClick: handleDeleteSelectedNode,
491
525
  children: [
492
526
  /* @__PURE__ */ jsx(Trash2, { className: "size-4 mr-1" }),
493
- "Delete Node"
527
+ tr(
528
+ "fluidgrids.components.workflowBuilderCore.deleteNode",
529
+ "Delete Node"
530
+ )
494
531
  ]
495
532
  }
496
533
  ) })
497
534
  ] }) : /* @__PURE__ */ jsxs("div", { className: "p-4", children: [
498
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Click a node on the canvas to view and edit its properties." }),
499
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-2", children: "Drag nodes from the palette on the left to add them to the workflow." })
535
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tr(
536
+ "fluidgrids.components.workflowBuilderCore.noSelectionHint",
537
+ "Click a node on the canvas to view and edit its properties."
538
+ ) }),
539
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-2", children: tr(
540
+ "fluidgrids.components.workflowBuilderCore.dragPaletteHint",
541
+ "Drag nodes from the palette on the left to add them to the workflow."
542
+ ) })
500
543
  ] })
501
544
  ] })
502
545
  ] }),
503
546
  !hideLogsPanel && /* @__PURE__ */ jsxs("div", { className: "h-32 border-t bg-card p-2", children: [
504
- /* @__PURE__ */ jsx("div", { className: "text-sm font-medium mb-2", children: "Execution Logs" }),
505
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Execution logs will appear here when you run the workflow" })
547
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium mb-2", children: tr(
548
+ "fluidgrids.components.workflowBuilderCore.executionLogsHeading",
549
+ "Execution Logs"
550
+ ) }),
551
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tr(
552
+ "fluidgrids.components.workflowBuilderCore.executionLogsEmpty",
553
+ "Execution logs will appear here when you run the workflow"
554
+ ) })
506
555
  ] })
507
556
  ]
508
557
  }
@@ -599,6 +648,7 @@ function extractTemplateGraph(content) {
599
648
  function TemplatePreview() {
600
649
  const { productId } = useParams();
601
650
  const navigate = useNavigate();
651
+ const tr = useTr();
602
652
  const { getTemplateDetail, parseTemplateContent, importTemplate } = useImportWorkflowTemplate();
603
653
  const [workflow, setWorkflow] = useState(null);
604
654
  const [template, setTemplate] = useState(null);
@@ -614,7 +664,12 @@ function TemplatePreview() {
614
664
  let mounted = true;
615
665
  const load = async () => {
616
666
  if (!productId) {
617
- setError("No template specified.");
667
+ setError(
668
+ tr(
669
+ "fluidgrids.pages.templatePreview.errorNoTemplateSpecified",
670
+ "No template specified."
671
+ )
672
+ );
618
673
  setLoading(false);
619
674
  return;
620
675
  }
@@ -622,7 +677,12 @@ function TemplatePreview() {
622
677
  const full = await getTemplateDetail(productId);
623
678
  if (!full) {
624
679
  if (mounted) {
625
- setError("Failed to load template.");
680
+ setError(
681
+ tr(
682
+ "fluidgrids.pages.templatePreview.errorLoadFailed",
683
+ "Failed to load template."
684
+ )
685
+ );
626
686
  setLoading(false);
627
687
  }
628
688
  return;
@@ -633,7 +693,12 @@ function TemplatePreview() {
633
693
  const edges = graph?.edges ?? [];
634
694
  if (!nodes.length) {
635
695
  if (mounted) {
636
- setError("This template has no workflow to preview.");
696
+ setError(
697
+ tr(
698
+ "fluidgrids.pages.templatePreview.errorNoWorkflow",
699
+ "This template has no workflow to preview."
700
+ )
701
+ );
637
702
  setLoading(false);
638
703
  }
639
704
  return;
@@ -644,7 +709,10 @@ function TemplatePreview() {
644
709
  id: productId,
645
710
  workflowKey: productId,
646
711
  version: "preview",
647
- name: full.name ?? "Template",
712
+ name: full.name ?? tr(
713
+ "fluidgrids.pages.templatePreview.fallbackTemplateName",
714
+ "Template"
715
+ ),
648
716
  nodes,
649
717
  edges,
650
718
  sidebar: {
@@ -656,7 +724,12 @@ function TemplatePreview() {
656
724
  }
657
725
  } catch (e) {
658
726
  if (mounted) {
659
- setError(e instanceof Error ? e.message : "Failed to load template.");
727
+ setError(
728
+ e instanceof Error ? e.message : tr(
729
+ "fluidgrids.pages.templatePreview.errorLoadFailed",
730
+ "Failed to load template."
731
+ )
732
+ );
660
733
  setLoading(false);
661
734
  }
662
735
  }
@@ -665,31 +738,58 @@ function TemplatePreview() {
665
738
  return () => {
666
739
  mounted = false;
667
740
  };
668
- }, [productId, getTemplateDetail, parseTemplateContent]);
741
+ }, [productId, getTemplateDetail, parseTemplateContent, tr]);
669
742
  const handleUse = async () => {
670
743
  if (!template) return;
671
744
  setImporting(true);
672
- toast.loading("Importing template...", { id: "tpl-preview-import" });
745
+ toast.loading(
746
+ tr(
747
+ "fluidgrids.pages.templatePreview.importingToast",
748
+ "Importing template..."
749
+ ),
750
+ { id: "tpl-preview-import" }
751
+ );
673
752
  try {
674
753
  const result = await importTemplate(template);
675
754
  toast.dismiss("tpl-preview-import");
676
755
  if (result.success && result.workflow) {
677
- toast.success("Workflow created from template!", {
678
- description: `"${result.workflow.name}" is ready to edit`
679
- });
756
+ toast.success(
757
+ tr(
758
+ "fluidgrids.pages.templatePreview.importSuccessToast",
759
+ "Workflow created from template!"
760
+ ),
761
+ {
762
+ description: `"${result.workflow.name}" is ready to edit`
763
+ }
764
+ );
680
765
  navigate(
681
766
  `${workflowsBase}/workflow/${result.workflow.workflowKey}/${result.workflow.version}`
682
767
  );
683
768
  } else if (isQuotaExhaustedError(result.error?.cause ?? result.error)) {
684
769
  setShowQuotaExhausted(true);
685
770
  } else {
686
- toast.error("Failed to use template", { description: result.message });
771
+ toast.error(
772
+ tr(
773
+ "fluidgrids.pages.templatePreview.importErrorToast",
774
+ "Failed to use template"
775
+ ),
776
+ { description: result.message }
777
+ );
687
778
  }
688
779
  } catch (e) {
689
780
  toast.dismiss("tpl-preview-import");
690
- toast.error("Something went wrong", {
691
- description: e instanceof Error ? e.message : "Failed to import template"
692
- });
781
+ toast.error(
782
+ tr(
783
+ "fluidgrids.pages.templatePreview.genericErrorToast",
784
+ "Something went wrong"
785
+ ),
786
+ {
787
+ description: e instanceof Error ? e.message : tr(
788
+ "fluidgrids.pages.templatePreview.importErrorDescription",
789
+ "Failed to import template"
790
+ )
791
+ }
792
+ );
693
793
  } finally {
694
794
  setImporting(false);
695
795
  }
@@ -704,15 +804,24 @@ function TemplatePreview() {
704
804
  {
705
805
  type: "button",
706
806
  onClick: backToTemplates,
707
- title: "Back to templates",
807
+ title: tr(
808
+ "fluidgrids.pages.templatePreview.backTooltip",
809
+ "Back to templates"
810
+ ),
708
811
  className: "flex size-9 shrink-0 items-center justify-center rounded-md text-card-foreground transition-colors hover:bg-card-foreground/10",
709
812
  children: /* @__PURE__ */ jsx(Icon, { icon: "ion:arrow-back-outline", className: "size-5" })
710
813
  }
711
814
  ),
712
815
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
713
816
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
714
- /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-card-foreground", children: workflow?.name ?? template?.name ?? "Template preview" }),
715
- /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-full bg-card-foreground/10 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: "Preview \xB7 read-only" })
817
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-card-foreground", children: workflow?.name ?? template?.name ?? tr(
818
+ "fluidgrids.pages.templatePreview.fallbackHeaderTitle",
819
+ "Template preview"
820
+ ) }),
821
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-full bg-card-foreground/10 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: tr(
822
+ "fluidgrids.pages.templatePreview.readOnlyBadge",
823
+ "Preview \xB7 read-only"
824
+ ) })
716
825
  ] }),
717
826
  template?.description ? /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: template.description }) : null
718
827
  ] })
@@ -731,7 +840,10 @@ function TemplatePreview() {
731
840
  className: "size-4"
732
841
  }
733
842
  ),
734
- "Use this template"
843
+ tr(
844
+ "fluidgrids.pages.templatePreview.useThisTemplate",
845
+ "Use this template"
846
+ )
735
847
  ]
736
848
  }
737
849
  )
@@ -740,12 +852,21 @@ function TemplatePreview() {
740
852
  ErrorBoundary,
741
853
  {
742
854
  fallback: () => /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-8 text-center", children: [
743
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Something went wrong rendering this template preview." }),
744
- /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: backToTemplates, children: "Back to templates" })
855
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: tr(
856
+ "fluidgrids.pages.templatePreview.renderErrorMessage",
857
+ "Something went wrong rendering this template preview."
858
+ ) }),
859
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: backToTemplates, children: tr(
860
+ "fluidgrids.pages.templatePreview.backToTemplates",
861
+ "Back to templates"
862
+ ) })
745
863
  ] }),
746
864
  children: loading ? /* @__PURE__ */ jsxs("div", { className: "flex h-full items-center justify-center gap-2 text-sm text-muted-foreground", children: [
747
865
  /* @__PURE__ */ jsx(Icon, { icon: "svg-spinners:ring-resize", className: "size-4" }),
748
- "Loading preview\u2026"
866
+ tr(
867
+ "fluidgrids.pages.templatePreview.loadingPreview",
868
+ "Loading preview\u2026"
869
+ )
749
870
  ] }) : error ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-3 p-8 text-center", children: [
750
871
  /* @__PURE__ */ jsx(
751
872
  Icon,
@@ -755,7 +876,10 @@ function TemplatePreview() {
755
876
  }
756
877
  ),
757
878
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: error }),
758
- /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: backToTemplates, children: "Back to templates" })
879
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: backToTemplates, children: tr(
880
+ "fluidgrids.pages.templatePreview.backToTemplates",
881
+ "Back to templates"
882
+ ) })
759
883
  ] }) : workflow ? /* @__PURE__ */ jsx(FlowBuilderPage, { workflow, readOnly: true }) : null
760
884
  }
761
885
  ) })
@@ -993,20 +1117,28 @@ function HistoryTableSkeleton() {
993
1117
  )) });
994
1118
  }
995
1119
  function EmptyState() {
1120
+ const tr = useTr();
996
1121
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-20 text-center", children: [
997
1122
  /* @__PURE__ */ jsx("div", { className: "rounded-full bg-background-secondary p-4 mb-4", children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:history", width: 40, className: "text-text-secondary" }) }),
998
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-text-primary mb-2", children: "No version history" }),
999
- /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary max-w-md", children: "Version history will appear here once you create and update workflows." })
1123
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-text-primary mb-2", children: tr("fluidgrids.history.historyPage.emptyTitle", "No version history") }),
1124
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary max-w-md", children: tr(
1125
+ "fluidgrids.history.historyPage.emptyHint",
1126
+ "Version history will appear here once you create and update workflows."
1127
+ ) })
1000
1128
  ] });
1001
1129
  }
1002
1130
  function ErrorState({
1003
1131
  message,
1004
1132
  onRetry
1005
1133
  }) {
1134
+ const tr = useTr();
1006
1135
  return /* @__PURE__ */ jsxs("div", { className: "p-4 bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg", children: [
1007
1136
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[var(--color-status-error-text)]", children: [
1008
1137
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:alert-circle", width: 20 }),
1009
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Error loading history" })
1138
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: tr(
1139
+ "fluidgrids.history.historyPage.errorHeading",
1140
+ "Error loading history"
1141
+ ) })
1010
1142
  ] }),
1011
1143
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-status-error-text)]", children: message }),
1012
1144
  /* @__PURE__ */ jsx(
@@ -1016,7 +1148,7 @@ function ErrorState({
1016
1148
  size: "sm",
1017
1149
  onClick: onRetry,
1018
1150
  className: "mt-3 border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] hover:bg-[var(--color-status-error-bg-subtle)]",
1019
- children: "Retry"
1151
+ children: tr("fluidgrids.history.historyPage.errorRetry", "Retry")
1020
1152
  }
1021
1153
  )
1022
1154
  ] });
@@ -1038,6 +1170,7 @@ function StatCard({
1038
1170
  ] });
1039
1171
  }
1040
1172
  function HistoryPage() {
1173
+ const tr = useTr();
1041
1174
  const navigate = useNavigate();
1042
1175
  const [search, setSearch] = useState("");
1043
1176
  const [workflowFilter, setWorkflowFilter] = useState("all");
@@ -1126,17 +1259,23 @@ function HistoryPage() {
1126
1259
  return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
1127
1260
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6", children: [
1128
1261
  /* @__PURE__ */ jsxs("div", { children: [
1129
- /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: "Version History" }),
1130
- /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: "Track changes and versions across all workflows" })
1262
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: tr("fluidgrids.history.historyPage.title", "Version History") }),
1263
+ /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: tr(
1264
+ "fluidgrids.history.historyPage.subtitle",
1265
+ "Track changes and versions across all workflows"
1266
+ ) })
1131
1267
  ] }),
1132
1268
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1133
1269
  /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => refetch(), children: [
1134
1270
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:refresh", className: "mr-2", width: 16 }),
1135
- "Refresh"
1271
+ tr("fluidgrids.history.historyPage.refreshButton", "Refresh")
1136
1272
  ] }),
1137
1273
  /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => navigate("../list"), children: [
1138
1274
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:arrow-left", className: "mr-2", width: 16 }),
1139
- "Back to Workflows"
1275
+ tr(
1276
+ "fluidgrids.history.historyPage.backToWorkflowsButton",
1277
+ "Back to Workflows"
1278
+ )
1140
1279
  ] })
1141
1280
  ] })
1142
1281
  ] }),
@@ -1153,7 +1292,10 @@ function HistoryPage() {
1153
1292
  /* @__PURE__ */ jsx(
1154
1293
  Input,
1155
1294
  {
1156
- placeholder: "Search by name, version, key, or author...",
1295
+ placeholder: tr(
1296
+ "fluidgrids.history.historyPage.searchPlaceholder",
1297
+ "Search by name, version, key, or author..."
1298
+ ),
1157
1299
  value: search,
1158
1300
  onChange: (e) => {
1159
1301
  setSearch(e.target.value);
@@ -1172,9 +1314,20 @@ function HistoryPage() {
1172
1314
  setPage(0);
1173
1315
  },
1174
1316
  children: [
1175
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-[220px] bg-background-secondary border-border-secondary", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "All Workflows" }) }),
1317
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-[220px] bg-background-secondary border-border-secondary", children: /* @__PURE__ */ jsx(
1318
+ SelectValue,
1319
+ {
1320
+ placeholder: tr(
1321
+ "fluidgrids.history.historyPage.workflowFilterPlaceholder",
1322
+ "All Workflows"
1323
+ )
1324
+ }
1325
+ ) }),
1176
1326
  /* @__PURE__ */ jsxs(SelectContent, { children: [
1177
- /* @__PURE__ */ jsx(SelectItem, { value: "all", children: "All Workflows" }),
1327
+ /* @__PURE__ */ jsx(SelectItem, { value: "all", children: tr(
1328
+ "fluidgrids.history.historyPage.workflowFilterAllOption",
1329
+ "All Workflows"
1330
+ ) }),
1178
1331
  distinctWorkflows.map((w) => /* @__PURE__ */ jsx(SelectItem, { value: w.workflowKey, children: w.name }, w.workflowKey))
1179
1332
  ] })
1180
1333
  ]
@@ -1182,12 +1335,30 @@ function HistoryPage() {
1182
1335
  )
1183
1336
  ] }),
1184
1337
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 sm:grid-cols-5 gap-3 mb-6", children: [
1185
- /* @__PURE__ */ jsx(StatCard, { label: "Total Versions", value: total || allRows.length }),
1186
- /* @__PURE__ */ jsx(StatCard, { label: "Workflows", value: distinctWorkflows.length }),
1187
1338
  /* @__PURE__ */ jsx(
1188
1339
  StatCard,
1189
1340
  {
1190
- label: "Active",
1341
+ label: tr(
1342
+ "fluidgrids.history.historyPage.statTotalVersions",
1343
+ "Total Versions"
1344
+ ),
1345
+ value: total || allRows.length
1346
+ }
1347
+ ),
1348
+ /* @__PURE__ */ jsx(
1349
+ StatCard,
1350
+ {
1351
+ label: tr(
1352
+ "fluidgrids.history.historyPage.statWorkflows",
1353
+ "Workflows"
1354
+ ),
1355
+ value: distinctWorkflows.length
1356
+ }
1357
+ ),
1358
+ /* @__PURE__ */ jsx(
1359
+ StatCard,
1360
+ {
1361
+ label: tr("fluidgrids.history.historyPage.statActive", "Active"),
1191
1362
  value: countByStatus("ACTIVE"),
1192
1363
  valueClassName: "text-[var(--color-status-success-text)]"
1193
1364
  }
@@ -1195,12 +1366,18 @@ function HistoryPage() {
1195
1366
  /* @__PURE__ */ jsx(
1196
1367
  StatCard,
1197
1368
  {
1198
- label: "Draft",
1369
+ label: tr("fluidgrids.history.historyPage.statDraft", "Draft"),
1199
1370
  value: countByStatus("DRAFT"),
1200
1371
  valueClassName: "text-[var(--color-status-warning-text)]"
1201
1372
  }
1202
1373
  ),
1203
- /* @__PURE__ */ jsx(StatCard, { label: "Archived", value: countByStatus("ARCHIVED") })
1374
+ /* @__PURE__ */ jsx(
1375
+ StatCard,
1376
+ {
1377
+ label: tr("fluidgrids.history.historyPage.statArchived", "Archived"),
1378
+ value: countByStatus("ARCHIVED")
1379
+ }
1380
+ )
1204
1381
  ] }),
1205
1382
  hasMore && /* @__PURE__ */ jsxs("p", { className: "text-xs text-text-secondary mb-4", children: [
1206
1383
  "Showing the ",
@@ -1212,12 +1389,27 @@ function HistoryPage() {
1212
1389
  error && /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(ErrorState, { message: error.message, onRetry: refetch }) }),
1213
1390
  loading ? /* @__PURE__ */ jsx(HistoryTableSkeleton, {}) : filteredRows.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {}) : /* @__PURE__ */ jsx("div", { className: "overflow-x-auto rounded-lg border border-border-secondary", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
1214
1391
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b border-border-secondary bg-background-secondary", children: [
1215
- /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: "Workflow Name" }),
1216
- /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: "Version" }),
1217
- /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: "Status" }),
1218
- /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: "Changed By" }),
1219
- /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: "Changed At" }),
1220
- /* @__PURE__ */ jsx("th", { className: "text-right px-4 py-3 font-medium text-text-secondary", children: "Actions" })
1392
+ /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: tr(
1393
+ "fluidgrids.history.historyPage.columnWorkflowName",
1394
+ "Workflow Name"
1395
+ ) }),
1396
+ /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: tr(
1397
+ "fluidgrids.history.historyPage.columnVersion",
1398
+ "Version"
1399
+ ) }),
1400
+ /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: tr("fluidgrids.history.historyPage.columnStatus", "Status") }),
1401
+ /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: tr(
1402
+ "fluidgrids.history.historyPage.columnChangedBy",
1403
+ "Changed By"
1404
+ ) }),
1405
+ /* @__PURE__ */ jsx("th", { className: "text-left px-4 py-3 font-medium text-text-secondary", children: tr(
1406
+ "fluidgrids.history.historyPage.columnChangedAt",
1407
+ "Changed At"
1408
+ ) }),
1409
+ /* @__PURE__ */ jsx("th", { className: "text-right px-4 py-3 font-medium text-text-secondary", children: tr(
1410
+ "fluidgrids.history.historyPage.columnActions",
1411
+ "Actions"
1412
+ ) })
1221
1413
  ] }) }),
1222
1414
  /* @__PURE__ */ jsx("tbody", { children: paginatedRows.map((row) => {
1223
1415
  const statusStyle = STATUS_STYLES[row.status] ?? STATUS_STYLES.DRAFT;
@@ -1270,7 +1462,10 @@ function HistoryPage() {
1270
1462
  children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:open-in-new", width: 16 })
1271
1463
  }
1272
1464
  ) }),
1273
- /* @__PURE__ */ jsx(TooltipContent, { children: "Open in builder" })
1465
+ /* @__PURE__ */ jsx(TooltipContent, { children: tr(
1466
+ "fluidgrids.history.historyPage.openInBuilderTooltip",
1467
+ "Open in builder"
1468
+ ) })
1274
1469
  ] }) }) })
1275
1470
  ]
1276
1471
  },
@@ -1298,7 +1493,10 @@ function HistoryPage() {
1298
1493
  onClick: () => setPage((p) => p - 1),
1299
1494
  children: [
1300
1495
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:chevron-left", width: 16 }),
1301
- "Previous"
1496
+ tr(
1497
+ "fluidgrids.history.historyPage.previousPageButton",
1498
+ "Previous"
1499
+ )
1302
1500
  ]
1303
1501
  }
1304
1502
  ),
@@ -1310,7 +1508,7 @@ function HistoryPage() {
1310
1508
  disabled: page >= totalPages - 1,
1311
1509
  onClick: () => setPage((p) => p + 1),
1312
1510
  children: [
1313
- "Next",
1511
+ tr("fluidgrids.history.historyPage.nextPageButton", "Next"),
1314
1512
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:chevron-right", width: 16 })
1315
1513
  ]
1316
1514
  }
@@ -5449,6 +5647,7 @@ function TemplateSkeleton() {
5449
5647
  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)) });
5450
5648
  }
5451
5649
  function EmptyState2({ hasSearch }) {
5650
+ const tr = useTr();
5452
5651
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-20 text-center", children: [
5453
5652
  /* @__PURE__ */ jsx("div", { className: "rounded-full bg-background-secondary p-4 mb-4", children: /* @__PURE__ */ jsx(
5454
5653
  Icon,
@@ -5458,18 +5657,34 @@ function EmptyState2({ hasSearch }) {
5458
5657
  className: "text-text-secondary"
5459
5658
  }
5460
5659
  ) }),
5461
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-text-primary mb-2", children: hasSearch ? "No matching templates" : "No templates available yet" }),
5462
- /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary max-w-md", children: hasSearch ? "Try adjusting your search or category filter." : "Published workflows will appear here as reusable templates." })
5660
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-text-primary mb-2", children: hasSearch ? tr(
5661
+ "fluidgrids.templates.templatesPage.emptyStateSearchTitle",
5662
+ "No matching templates"
5663
+ ) : tr(
5664
+ "fluidgrids.templates.templatesPage.emptyStateTitle",
5665
+ "No templates available yet"
5666
+ ) }),
5667
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary max-w-md", children: hasSearch ? tr(
5668
+ "fluidgrids.templates.templatesPage.emptyStateSearchHint",
5669
+ "Try adjusting your search or category filter."
5670
+ ) : tr(
5671
+ "fluidgrids.templates.templatesPage.emptyStateHint",
5672
+ "Published workflows will appear here as reusable templates."
5673
+ ) })
5463
5674
  ] });
5464
5675
  }
5465
5676
  function ErrorState2({
5466
5677
  message,
5467
5678
  onRetry
5468
5679
  }) {
5680
+ const tr = useTr();
5469
5681
  return /* @__PURE__ */ jsxs("div", { className: "p-4 bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg", children: [
5470
5682
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[var(--color-status-error-text)]", children: [
5471
5683
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:alert-circle", width: 20 }),
5472
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Error loading templates" })
5684
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: tr(
5685
+ "fluidgrids.templates.templatesPage.errorStateTitle",
5686
+ "Error loading templates"
5687
+ ) })
5473
5688
  ] }),
5474
5689
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-status-error-text)]", children: message }),
5475
5690
  /* @__PURE__ */ jsx(
@@ -5479,7 +5694,7 @@ function ErrorState2({
5479
5694
  size: "sm",
5480
5695
  onClick: onRetry,
5481
5696
  className: "mt-3 border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] hover:bg-[var(--color-status-error-bg-subtle)]",
5482
- children: "Retry"
5697
+ children: tr("fluidgrids.templates.templatesPage.errorStateRetry", "Retry")
5483
5698
  }
5484
5699
  )
5485
5700
  ] });
@@ -5490,7 +5705,8 @@ function WorkspaceTemplateCard({
5490
5705
  onUseTemplate,
5491
5706
  isLoading
5492
5707
  }) {
5493
- const categoryLabel = CATEGORIES.find((c) => c.value === category)?.label ?? "Workflow";
5708
+ const tr = useTr();
5709
+ const categoryLabel = CATEGORIES.find((c) => c.value === category)?.label ?? tr("fluidgrids.templates.templatesPage.cardDefaultCategory", "Workflow");
5494
5710
  const categoryColor = CATEGORY_COLORS[category] ?? "bg-zinc-500/15 text-zinc-400 border-zinc-500/30";
5495
5711
  return /* @__PURE__ */ jsxs(Card$1, { className: "group border border-border-secondary bg-background-secondary hover:border-border-primary transition-all duration-200 flex flex-col", children: [
5496
5712
  /* @__PURE__ */ jsxs(CardHeader, { className: "flex-1 pb-3", children: [
@@ -5506,7 +5722,10 @@ function WorkspaceTemplateCard({
5506
5722
  /* @__PURE__ */ jsx(Badge, { variant: "outline", className: categoryColor, children: categoryLabel })
5507
5723
  ] }),
5508
5724
  /* @__PURE__ */ jsx("h3", { className: "font-semibold text-text-primary text-base leading-tight mb-1.5 line-clamp-2", children: workflow.name }),
5509
- /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary line-clamp-2 min-h-[2.5rem]", children: workflow.description || "No description provided." })
5725
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary line-clamp-2 min-h-[2.5rem]", children: workflow.description || tr(
5726
+ "fluidgrids.templates.templatesPage.cardNoDescription",
5727
+ "No description provided."
5728
+ ) })
5510
5729
  ] }),
5511
5730
  /* @__PURE__ */ jsx("div", { className: "px-6 pb-5 pt-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
5512
5731
  /* @__PURE__ */ jsxs("span", { className: "text-xs text-text-secondary", children: [
@@ -5530,10 +5749,16 @@ function WorkspaceTemplateCard({
5530
5749
  className: "mr-1.5 animate-spin"
5531
5750
  }
5532
5751
  ),
5533
- "Creating..."
5752
+ tr(
5753
+ "fluidgrids.templates.templatesPage.cardCreating",
5754
+ "Creating..."
5755
+ )
5534
5756
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5535
5757
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:plus", width: 14, className: "mr-1.5" }),
5536
- "Use Template"
5758
+ tr(
5759
+ "fluidgrids.templates.templatesPage.cardUseTemplate",
5760
+ "Use Template"
5761
+ )
5537
5762
  ] })
5538
5763
  }
5539
5764
  )
@@ -5542,6 +5767,7 @@ function WorkspaceTemplateCard({
5542
5767
  }
5543
5768
  function TemplatesPage() {
5544
5769
  const navigate = useNavigate();
5770
+ const tr = useTr();
5545
5771
  const [search, setSearch] = useState("");
5546
5772
  const [activeCategory, setActiveCategory] = useState("all");
5547
5773
  const [duplicatingId, setDuplicatingId] = useState(null);
@@ -5610,13 +5836,21 @@ function TemplatesPage() {
5610
5836
  }
5611
5837
  );
5612
5838
  if (result?.success && result.workflow) {
5613
- toast.success("Workflow created from template");
5839
+ toast.success(
5840
+ tr(
5841
+ "fluidgrids.templates.templatesPage.duplicateSuccessToast",
5842
+ "Workflow created from template"
5843
+ )
5844
+ );
5614
5845
  navigate(
5615
5846
  `../workflow/${result.workflow.workflowKey}/${result.workflow.version}`
5616
5847
  );
5617
5848
  } else {
5618
5849
  toast.error(
5619
- result?.message ?? "Failed to create workflow from template"
5850
+ result?.message ?? tr(
5851
+ "fluidgrids.templates.templatesPage.duplicateErrorToast",
5852
+ "Failed to create workflow from template"
5853
+ )
5620
5854
  );
5621
5855
  }
5622
5856
  } catch (err) {
@@ -5624,66 +5858,120 @@ function TemplatesPage() {
5624
5858
  if (isQuotaExhaustedError(cause) || isQuotaExhaustedError(err)) {
5625
5859
  setShowQuotaExhausted(true);
5626
5860
  } else {
5627
- toast.error("Failed to create workflow from template");
5861
+ toast.error(
5862
+ tr(
5863
+ "fluidgrids.templates.templatesPage.duplicateErrorToast",
5864
+ "Failed to create workflow from template"
5865
+ )
5866
+ );
5628
5867
  console.error("[TemplatesPage] Error duplicating workflow:", err);
5629
5868
  }
5630
5869
  } finally {
5631
5870
  setDuplicatingId(null);
5632
5871
  }
5633
5872
  },
5634
- [duplicateWorkflow, navigate]
5873
+ [duplicateWorkflow, navigate, tr]
5635
5874
  );
5636
5875
  const handleUseStoreTemplate = useCallback(
5637
5876
  async (template) => {
5638
5877
  try {
5639
- toast.loading("Loading template...", { id: "store-template-load" });
5878
+ toast.loading(
5879
+ tr(
5880
+ "fluidgrids.templates.templatesPage.storeLoadingToast",
5881
+ "Loading template..."
5882
+ ),
5883
+ { id: "store-template-load" }
5884
+ );
5640
5885
  const fullTemplate = await getTemplateDetail(template.id);
5641
5886
  toast.dismiss("store-template-load");
5642
5887
  if (!fullTemplate) {
5643
- toast.error("Failed to load template details");
5888
+ toast.error(
5889
+ tr(
5890
+ "fluidgrids.templates.templatesPage.storeLoadDetailErrorToast",
5891
+ "Failed to load template details"
5892
+ )
5893
+ );
5644
5894
  return;
5645
5895
  }
5646
5896
  const content = parseTemplateContent(fullTemplate);
5647
5897
  if (!content) {
5648
- toast.error("Template does not contain valid workflow data");
5898
+ toast.error(
5899
+ tr(
5900
+ "fluidgrids.templates.templatesPage.storeInvalidContentToast",
5901
+ "Template does not contain valid workflow data"
5902
+ )
5903
+ );
5649
5904
  return;
5650
5905
  }
5651
- toast.loading("Importing template...", { id: "store-template-import" });
5906
+ toast.loading(
5907
+ tr(
5908
+ "fluidgrids.templates.templatesPage.storeImportingToast",
5909
+ "Importing template..."
5910
+ ),
5911
+ { id: "store-template-import" }
5912
+ );
5652
5913
  const result = await importTemplate(fullTemplate);
5653
5914
  toast.dismiss("store-template-import");
5654
5915
  if (result.success && result.workflow) {
5655
- toast.success("Workflow created from store template!", {
5656
- description: `"${result.workflow.name}" is ready to edit`
5657
- });
5916
+ toast.success(
5917
+ tr(
5918
+ "fluidgrids.templates.templatesPage.storeImportSuccessToast",
5919
+ "Workflow created from store template!"
5920
+ ),
5921
+ {
5922
+ description: `"${result.workflow.name}" is ready to edit`
5923
+ }
5924
+ );
5658
5925
  navigate(
5659
5926
  `../workflow/${result.workflow.workflowKey}/${result.workflow.version}`
5660
5927
  );
5661
5928
  } else if (isQuotaExhaustedError(result.error?.cause ?? result.error)) {
5662
5929
  setShowQuotaExhausted(true);
5663
5930
  } else {
5664
- toast.error("Failed to import template", {
5665
- description: result.message
5666
- });
5931
+ toast.error(
5932
+ tr(
5933
+ "fluidgrids.templates.templatesPage.storeImportErrorToast",
5934
+ "Failed to import template"
5935
+ ),
5936
+ {
5937
+ description: result.message
5938
+ }
5939
+ );
5667
5940
  }
5668
5941
  } catch (err) {
5669
5942
  toast.dismiss("store-template-load");
5670
5943
  toast.dismiss("store-template-import");
5671
- toast.error("Something went wrong", {
5672
- description: err instanceof Error ? err.message : "Failed to process template"
5673
- });
5944
+ toast.error(
5945
+ tr(
5946
+ "fluidgrids.templates.templatesPage.storeGenericErrorToast",
5947
+ "Something went wrong"
5948
+ ),
5949
+ {
5950
+ description: err instanceof Error ? err.message : tr(
5951
+ "fluidgrids.templates.templatesPage.storeProcessErrorDescription",
5952
+ "Failed to process template"
5953
+ )
5954
+ }
5955
+ );
5674
5956
  }
5675
5957
  },
5676
- [getTemplateDetail, parseTemplateContent, importTemplate, navigate]
5958
+ [getTemplateDetail, parseTemplateContent, importTemplate, navigate, tr]
5677
5959
  );
5678
5960
  return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
5679
5961
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6", children: [
5680
5962
  /* @__PURE__ */ jsxs("div", { children: [
5681
- /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: "Templates" }),
5682
- /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: "Start quickly with pre-built workflow templates" })
5963
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: tr("fluidgrids.templates.templatesPage.heading", "Templates") }),
5964
+ /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: tr(
5965
+ "fluidgrids.templates.templatesPage.subheading",
5966
+ "Start quickly with pre-built workflow templates"
5967
+ ) })
5683
5968
  ] }),
5684
5969
  /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => navigate("../list"), children: [
5685
5970
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:arrow-left", className: "mr-2", width: 16 }),
5686
- "Back to Workflows"
5971
+ tr(
5972
+ "fluidgrids.templates.templatesPage.backToWorkflows",
5973
+ "Back to Workflows"
5974
+ )
5687
5975
  ] })
5688
5976
  ] }),
5689
5977
  /* @__PURE__ */ jsxs("div", { className: "flex gap-1 p-1 bg-background-secondary rounded-lg w-fit mb-6", children: [
@@ -5694,7 +5982,7 @@ function TemplatesPage() {
5694
5982
  className: `px-4 py-2 rounded-md text-sm font-medium transition-colors ${activeSource === "store" ? "bg-background-primary text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
5695
5983
  children: [
5696
5984
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:store", className: "inline mr-1.5", width: 16 }),
5697
- "From Store",
5985
+ tr("fluidgrids.templates.templatesPage.tabFromStore", "From Store"),
5698
5986
  storeTotalCount > 0 && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs bg-primary/10 text-primary px-1.5 py-0.5 rounded-full", children: storeTotalCount })
5699
5987
  ]
5700
5988
  }
@@ -5713,7 +6001,10 @@ function TemplatesPage() {
5713
6001
  width: 16
5714
6002
  }
5715
6003
  ),
5716
- "My Templates"
6004
+ tr(
6005
+ "fluidgrids.templates.templatesPage.tabMyTemplates",
6006
+ "My Templates"
6007
+ )
5717
6008
  ]
5718
6009
  }
5719
6010
  )
@@ -5730,7 +6021,13 @@ function TemplatesPage() {
5730
6021
  /* @__PURE__ */ jsx(
5731
6022
  Input,
5732
6023
  {
5733
- placeholder: activeSource === "workspace" ? "Search workspace templates..." : "Search store templates...",
6024
+ placeholder: activeSource === "workspace" ? tr(
6025
+ "fluidgrids.templates.templatesPage.searchWorkspacePlaceholder",
6026
+ "Search workspace templates..."
6027
+ ) : tr(
6028
+ "fluidgrids.templates.templatesPage.searchStorePlaceholder",
6029
+ "Search store templates..."
6030
+ ),
5734
6031
  value: search,
5735
6032
  onChange: (e) => setSearch(e.target.value),
5736
6033
  className: "pl-10 bg-background-secondary border-border-secondary"
@@ -5810,8 +6107,14 @@ function TemplatesPage() {
5810
6107
  className: "mr-2 animate-spin"
5811
6108
  }
5812
6109
  ),
5813
- "Loading..."
5814
- ] }) : "Load More Templates"
6110
+ tr(
6111
+ "fluidgrids.templates.templatesPage.loadingMore",
6112
+ "Loading..."
6113
+ )
6114
+ ] }) : tr(
6115
+ "fluidgrids.templates.templatesPage.loadMoreTemplates",
6116
+ "Load More Templates"
6117
+ )
5815
6118
  }
5816
6119
  ) })
5817
6120
  ] })
@@ -6063,6 +6366,7 @@ function NodesSkeleton() {
6063
6366
  return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4", children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-44 rounded-lg bg-card-foreground/10" }, i)) });
6064
6367
  }
6065
6368
  function EmptyState3({ hasFilters }) {
6369
+ const tr = useTr();
6066
6370
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-20 text-center", children: [
6067
6371
  /* @__PURE__ */ jsx("div", { className: "rounded-full bg-background-secondary p-4 mb-4", children: /* @__PURE__ */ jsx(
6068
6372
  Icon,
@@ -6072,18 +6376,28 @@ function EmptyState3({ hasFilters }) {
6072
6376
  className: "text-text-secondary"
6073
6377
  }
6074
6378
  ) }),
6075
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-text-primary mb-2", children: hasFilters ? "No matching nodes" : "No nodes registered" }),
6076
- /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary max-w-md", children: hasFilters ? "Try adjusting your search or category filter." : "Node endpoint configurations will appear here once registered." })
6379
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-text-primary mb-2", children: hasFilters ? tr(
6380
+ "fluidgrids.nodes.nodesPage.emptyTitleFiltered",
6381
+ "No matching nodes"
6382
+ ) : tr("fluidgrids.nodes.nodesPage.emptyTitle", "No nodes registered") }),
6383
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary max-w-md", children: hasFilters ? tr(
6384
+ "fluidgrids.nodes.nodesPage.emptyHintFiltered",
6385
+ "Try adjusting your search or category filter."
6386
+ ) : tr(
6387
+ "fluidgrids.nodes.nodesPage.emptyHint",
6388
+ "Node endpoint configurations will appear here once registered."
6389
+ ) })
6077
6390
  ] });
6078
6391
  }
6079
6392
  function ErrorState3({
6080
6393
  message,
6081
6394
  onRetry
6082
6395
  }) {
6396
+ const tr = useTr();
6083
6397
  return /* @__PURE__ */ jsxs("div", { className: "p-4 bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)] rounded-lg", children: [
6084
6398
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-[var(--color-status-error-text)]", children: [
6085
6399
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:alert-circle", width: 20 }),
6086
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Error loading nodes" })
6400
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: tr("fluidgrids.nodes.nodesPage.errorHeading", "Error loading nodes") })
6087
6401
  ] }),
6088
6402
  /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-status-error-text)]", children: message }),
6089
6403
  /* @__PURE__ */ jsx(
@@ -6093,15 +6407,16 @@ function ErrorState3({
6093
6407
  size: "sm",
6094
6408
  onClick: onRetry,
6095
6409
  className: "mt-3 border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] hover:bg-[var(--color-status-error-bg-subtle)]",
6096
- children: "Retry"
6410
+ children: tr("fluidgrids.nodes.nodesPage.errorRetry", "Retry")
6097
6411
  }
6098
6412
  )
6099
6413
  ] });
6100
6414
  }
6101
6415
  function NodeCard({ node, category }) {
6416
+ const tr = useTr();
6102
6417
  const status = STATUS_STYLES2[node.status] ?? STATUS_STYLES2.AVAILABLE;
6103
6418
  const catColor = CATEGORY_COLORS2[category] ?? "bg-zinc-500/15 text-zinc-400 border-zinc-500/30";
6104
- const catLabel = NODE_CATEGORIES.find((c) => c.value === category)?.label ?? "Node";
6419
+ const catLabel = NODE_CATEGORIES.find((c) => c.value === category)?.label ?? tr("fluidgrids.nodes.nodeCard.categoryFallback", "Node");
6105
6420
  return /* @__PURE__ */ jsxs(Card$1, { className: "border border-border-secondary bg-background-secondary hover:border-border-primary transition-all duration-200 flex flex-col", children: [
6106
6421
  /* @__PURE__ */ jsxs(CardHeader, { className: "flex-1 pb-3", children: [
6107
6422
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2 mb-3", children: [
@@ -6119,7 +6434,10 @@ function NodeCard({ node, category }) {
6119
6434
  ] })
6120
6435
  ] }),
6121
6436
  /* @__PURE__ */ jsx("h3", { className: "font-semibold text-text-primary text-sm leading-tight mb-1 line-clamp-1", children: node.name }),
6122
- /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary line-clamp-2 min-h-[2rem]", children: node.description ?? "No description available." })
6437
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary line-clamp-2 min-h-[2rem]", children: node.description ?? tr(
6438
+ "fluidgrids.nodes.nodeCard.noDescription",
6439
+ "No description available."
6440
+ ) })
6123
6441
  ] }),
6124
6442
  /* @__PURE__ */ jsx("div", { className: "px-6 pb-4 pt-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
6125
6443
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -6131,12 +6449,16 @@ function NodeCard({ node, category }) {
6131
6449
  ] }),
6132
6450
  /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
6133
6451
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { className: "p-1.5 rounded hover:bg-background-tertiary text-text-secondary hover:text-text-primary transition-colors", children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:cog", width: 16 }) }) }),
6134
- /* @__PURE__ */ jsx(TooltipContent, { children: "Configure node" })
6452
+ /* @__PURE__ */ jsx(TooltipContent, { children: tr(
6453
+ "fluidgrids.nodes.nodeCard.configureTooltip",
6454
+ "Configure node"
6455
+ ) })
6135
6456
  ] }) })
6136
6457
  ] }) })
6137
6458
  ] });
6138
6459
  }
6139
6460
  function NodesPage() {
6461
+ const tr = useTr();
6140
6462
  const navigate = useNavigate();
6141
6463
  const [search, setSearch] = useState("");
6142
6464
  const [activeCategory, setActiveCategory] = useState("all");
@@ -6186,17 +6508,23 @@ function NodesPage() {
6186
6508
  return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
6187
6509
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6", children: [
6188
6510
  /* @__PURE__ */ jsxs("div", { children: [
6189
- /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: "Node Catalog" }),
6190
- /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: "Browse and manage available workflow nodes" })
6511
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: tr("fluidgrids.nodes.nodesPage.title", "Node Catalog") }),
6512
+ /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: tr(
6513
+ "fluidgrids.nodes.nodesPage.subtitle",
6514
+ "Browse and manage available workflow nodes"
6515
+ ) })
6191
6516
  ] }),
6192
6517
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
6193
6518
  /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => refetch(), children: [
6194
6519
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:refresh", className: "mr-2", width: 16 }),
6195
- "Refresh"
6520
+ tr("fluidgrids.nodes.nodesPage.refreshButton", "Refresh")
6196
6521
  ] }),
6197
6522
  /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => navigate("../list"), children: [
6198
6523
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:arrow-left", className: "mr-2", width: 16 }),
6199
- "Back to Workflows"
6524
+ tr(
6525
+ "fluidgrids.nodes.nodesPage.backToWorkflowsButton",
6526
+ "Back to Workflows"
6527
+ )
6200
6528
  ] })
6201
6529
  ] })
6202
6530
  ] }),
@@ -6211,7 +6539,7 @@ function NodesPage() {
6211
6539
  className: "text-text-secondary"
6212
6540
  }
6213
6541
  ),
6214
- /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: "Total Nodes" })
6542
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: tr("fluidgrids.nodes.nodesPage.statTotal", "Total Nodes") })
6215
6543
  ] }),
6216
6544
  /* @__PURE__ */ jsx("p", { className: "text-xl font-bold text-text-primary mt-1", children: loading ? "\u2014" : stats.total })
6217
6545
  ] }),
@@ -6225,14 +6553,14 @@ function NodesPage() {
6225
6553
  className: "text-emerald-400"
6226
6554
  }
6227
6555
  ),
6228
- /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: "Active" })
6556
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: tr("fluidgrids.nodes.nodesPage.statActive", "Active") })
6229
6557
  ] }),
6230
6558
  /* @__PURE__ */ jsx("p", { className: "text-xl font-bold text-emerald-400 mt-1", children: loading ? "\u2014" : stats.active })
6231
6559
  ] }),
6232
6560
  /* @__PURE__ */ jsxs("div", { className: "p-3 rounded-lg bg-background-secondary border border-border-secondary", children: [
6233
6561
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
6234
6562
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:alert", width: 18, className: "text-amber-400" }),
6235
- /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: "Deprecated" })
6563
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: tr("fluidgrids.nodes.nodesPage.statDeprecated", "Deprecated") })
6236
6564
  ] }),
6237
6565
  /* @__PURE__ */ jsx("p", { className: "text-xl font-bold text-amber-400 mt-1", children: loading ? "\u2014" : stats.deprecated })
6238
6566
  ] })
@@ -6249,7 +6577,10 @@ function NodesPage() {
6249
6577
  /* @__PURE__ */ jsx(
6250
6578
  Input,
6251
6579
  {
6252
- placeholder: "Search nodes by name, type, or keyword...",
6580
+ placeholder: tr(
6581
+ "fluidgrids.nodes.nodesPage.searchPlaceholder",
6582
+ "Search nodes by name, type, or keyword..."
6583
+ ),
6253
6584
  value: search,
6254
6585
  onChange: (e) => setSearch(e.target.value),
6255
6586
  className: "pl-10 bg-background-secondary border-border-secondary"
@@ -6316,6 +6647,7 @@ var DEFAULT_SETTINGS = {
6316
6647
  }
6317
6648
  };
6318
6649
  function ReadOnlyBanner() {
6650
+ const tr = useTr();
6319
6651
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 p-3 rounded-lg bg-amber-500/10 border border-amber-500/30 mb-6", children: [
6320
6652
  /* @__PURE__ */ jsx(
6321
6653
  Icon,
@@ -6325,18 +6657,29 @@ function ReadOnlyBanner() {
6325
6657
  className: "text-amber-400 shrink-0"
6326
6658
  }
6327
6659
  ),
6328
- /* @__PURE__ */ jsx("p", { className: "text-sm text-amber-400", children: "Settings are managed at workspace level. Contact your workspace administrator to change these values." })
6660
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-amber-400", children: tr(
6661
+ "fluidgrids.settings.readOnlyBanner.message",
6662
+ "Settings are managed at workspace level. Contact your workspace administrator to change these values."
6663
+ ) })
6329
6664
  ] });
6330
6665
  }
6331
6666
  function CopyButton({ value, label }) {
6667
+ const tr = useTr();
6332
6668
  const handleCopy = useCallback(async () => {
6333
6669
  try {
6334
6670
  await navigator.clipboard.writeText(value);
6335
- toast.success(`${label} copied to clipboard`);
6671
+ toast.success(
6672
+ `${label} ${tr("fluidgrids.settings.copyButton.copiedToast", "copied to clipboard")}`
6673
+ );
6336
6674
  } catch {
6337
- toast.error("Failed to copy to clipboard");
6675
+ toast.error(
6676
+ tr(
6677
+ "fluidgrids.settings.copyButton.copyFailedToast",
6678
+ "Failed to copy to clipboard"
6679
+ )
6680
+ );
6338
6681
  }
6339
- }, [value, label]);
6682
+ }, [value, label, tr]);
6340
6683
  return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
6341
6684
  /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
6342
6685
  "button",
@@ -6347,7 +6690,8 @@ function CopyButton({ value, label }) {
6347
6690
  }
6348
6691
  ) }),
6349
6692
  /* @__PURE__ */ jsxs(TooltipContent, { children: [
6350
- "Copy ",
6693
+ tr("fluidgrids.settings.copyButton.copyTooltipPrefix", "Copy"),
6694
+ " ",
6351
6695
  label
6352
6696
  ] })
6353
6697
  ] }) });
@@ -6366,6 +6710,7 @@ function SettingRow({
6366
6710
  ] });
6367
6711
  }
6368
6712
  function GeneralTab() {
6713
+ const tr = useTr();
6369
6714
  const settings = DEFAULT_SETTINGS.general;
6370
6715
  return /* @__PURE__ */ jsxs("div", { children: [
6371
6716
  /* @__PURE__ */ jsx(ReadOnlyBanner, {}),
@@ -6373,8 +6718,14 @@ function GeneralTab() {
6373
6718
  /* @__PURE__ */ jsx(
6374
6719
  SettingRow,
6375
6720
  {
6376
- label: "Workspace Name",
6377
- description: "The name of your workspace",
6721
+ label: tr(
6722
+ "fluidgrids.settings.general.workspaceNameLabel",
6723
+ "Workspace Name"
6724
+ ),
6725
+ description: tr(
6726
+ "fluidgrids.settings.general.workspaceNameDescription",
6727
+ "The name of your workspace"
6728
+ ),
6378
6729
  children: /* @__PURE__ */ jsx(
6379
6730
  Input,
6380
6731
  {
@@ -6388,8 +6739,14 @@ function GeneralTab() {
6388
6739
  /* @__PURE__ */ jsx(
6389
6740
  SettingRow,
6390
6741
  {
6391
- label: "Default Workflow Prefix",
6392
- description: "Prefix used when generating new workflow keys",
6742
+ label: tr(
6743
+ "fluidgrids.settings.general.workflowPrefixLabel",
6744
+ "Default Workflow Prefix"
6745
+ ),
6746
+ description: tr(
6747
+ "fluidgrids.settings.general.workflowPrefixDescription",
6748
+ "Prefix used when generating new workflow keys"
6749
+ ),
6393
6750
  children: /* @__PURE__ */ jsx(
6394
6751
  Input,
6395
6752
  {
@@ -6403,8 +6760,14 @@ function GeneralTab() {
6403
6760
  /* @__PURE__ */ jsx(
6404
6761
  SettingRow,
6405
6762
  {
6406
- label: "Auto-save Drafts",
6407
- description: "Automatically save draft workflows while editing",
6763
+ label: tr(
6764
+ "fluidgrids.settings.general.autoSaveDraftsLabel",
6765
+ "Auto-save Drafts"
6766
+ ),
6767
+ description: tr(
6768
+ "fluidgrids.settings.general.autoSaveDraftsDescription",
6769
+ "Automatically save draft workflows while editing"
6770
+ ),
6408
6771
  children: /* @__PURE__ */ jsx(Switch, { checked: settings.autoSaveDrafts, disabled: true })
6409
6772
  }
6410
6773
  )
@@ -6412,6 +6775,7 @@ function GeneralTab() {
6412
6775
  ] });
6413
6776
  }
6414
6777
  function ExecutionTab() {
6778
+ const tr = useTr();
6415
6779
  const settings = DEFAULT_SETTINGS.execution;
6416
6780
  return /* @__PURE__ */ jsxs("div", { children: [
6417
6781
  /* @__PURE__ */ jsx(ReadOnlyBanner, {}),
@@ -6419,8 +6783,14 @@ function ExecutionTab() {
6419
6783
  /* @__PURE__ */ jsx(
6420
6784
  SettingRow,
6421
6785
  {
6422
- label: "Default Timeout",
6423
- description: "Maximum time a workflow execution can run (in seconds)",
6786
+ label: tr(
6787
+ "fluidgrids.settings.execution.defaultTimeoutLabel",
6788
+ "Default Timeout"
6789
+ ),
6790
+ description: tr(
6791
+ "fluidgrids.settings.execution.defaultTimeoutDescription",
6792
+ "Maximum time a workflow execution can run (in seconds)"
6793
+ ),
6424
6794
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
6425
6795
  /* @__PURE__ */ jsx(
6426
6796
  Input,
@@ -6430,15 +6800,24 @@ function ExecutionTab() {
6430
6800
  className: "w-[100px] bg-background-secondary border-border-secondary text-text-primary text-right cursor-default"
6431
6801
  }
6432
6802
  ),
6433
- /* @__PURE__ */ jsx("span", { className: "text-xs text-text-secondary", children: "seconds" })
6803
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-text-secondary", children: tr(
6804
+ "fluidgrids.settings.execution.defaultTimeoutUnit",
6805
+ "seconds"
6806
+ ) })
6434
6807
  ] })
6435
6808
  }
6436
6809
  ),
6437
6810
  /* @__PURE__ */ jsx(
6438
6811
  SettingRow,
6439
6812
  {
6440
- label: "Max Retries",
6441
- description: "Number of automatic retries on execution failure",
6813
+ label: tr(
6814
+ "fluidgrids.settings.execution.maxRetriesLabel",
6815
+ "Max Retries"
6816
+ ),
6817
+ description: tr(
6818
+ "fluidgrids.settings.execution.maxRetriesDescription",
6819
+ "Number of automatic retries on execution failure"
6820
+ ),
6442
6821
  children: /* @__PURE__ */ jsx(
6443
6822
  Input,
6444
6823
  {
@@ -6452,8 +6831,14 @@ function ExecutionTab() {
6452
6831
  /* @__PURE__ */ jsx(
6453
6832
  SettingRow,
6454
6833
  {
6455
- label: "Retry Delay",
6456
- description: "Delay between retry attempts (in seconds)",
6834
+ label: tr(
6835
+ "fluidgrids.settings.execution.retryDelayLabel",
6836
+ "Retry Delay"
6837
+ ),
6838
+ description: tr(
6839
+ "fluidgrids.settings.execution.retryDelayDescription",
6840
+ "Delay between retry attempts (in seconds)"
6841
+ ),
6457
6842
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
6458
6843
  /* @__PURE__ */ jsx(
6459
6844
  Input,
@@ -6463,15 +6848,21 @@ function ExecutionTab() {
6463
6848
  className: "w-[100px] bg-background-secondary border-border-secondary text-text-primary text-right cursor-default"
6464
6849
  }
6465
6850
  ),
6466
- /* @__PURE__ */ jsx("span", { className: "text-xs text-text-secondary", children: "seconds" })
6851
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-text-secondary", children: tr("fluidgrids.settings.execution.retryDelayUnit", "seconds") })
6467
6852
  ] })
6468
6853
  }
6469
6854
  ),
6470
6855
  /* @__PURE__ */ jsx(
6471
6856
  SettingRow,
6472
6857
  {
6473
- label: "Concurrent Execution Limit",
6474
- description: "Maximum number of workflow executions running simultaneously",
6858
+ label: tr(
6859
+ "fluidgrids.settings.execution.concurrencyLimitLabel",
6860
+ "Concurrent Execution Limit"
6861
+ ),
6862
+ description: tr(
6863
+ "fluidgrids.settings.execution.concurrencyLimitDescription",
6864
+ "Maximum number of workflow executions running simultaneously"
6865
+ ),
6475
6866
  children: /* @__PURE__ */ jsx(
6476
6867
  Input,
6477
6868
  {
@@ -6486,28 +6877,44 @@ function ExecutionTab() {
6486
6877
  ] });
6487
6878
  }
6488
6879
  function NotificationsTab() {
6880
+ const tr = useTr();
6489
6881
  const settings = DEFAULT_SETTINGS.notifications;
6490
6882
  return /* @__PURE__ */ jsxs("div", { children: [
6491
6883
  /* @__PURE__ */ jsx(ReadOnlyBanner, {}),
6492
6884
  /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
6493
6885
  /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold text-text-primary flex items-center gap-2 mb-3", children: [
6494
6886
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:email-outline", width: 18 }),
6495
- "Email Notifications"
6887
+ tr(
6888
+ "fluidgrids.settings.notifications.emailSectionTitle",
6889
+ "Email Notifications"
6890
+ )
6496
6891
  ] }),
6497
6892
  /* @__PURE__ */ jsxs("div", { className: "divide-y divide-border-secondary rounded-lg border border-border-secondary bg-background-secondary p-1", children: [
6498
6893
  /* @__PURE__ */ jsx(
6499
6894
  SettingRow,
6500
6895
  {
6501
- label: "On Success",
6502
- description: "Send email when a workflow execution completes successfully",
6896
+ label: tr(
6897
+ "fluidgrids.settings.notifications.emailOnSuccessLabel",
6898
+ "On Success"
6899
+ ),
6900
+ description: tr(
6901
+ "fluidgrids.settings.notifications.emailOnSuccessDescription",
6902
+ "Send email when a workflow execution completes successfully"
6903
+ ),
6503
6904
  children: /* @__PURE__ */ jsx(Switch, { checked: settings.emailOnSuccess, disabled: true })
6504
6905
  }
6505
6906
  ),
6506
6907
  /* @__PURE__ */ jsx(
6507
6908
  SettingRow,
6508
6909
  {
6509
- label: "On Failure",
6510
- description: "Send email when a workflow execution fails",
6910
+ label: tr(
6911
+ "fluidgrids.settings.notifications.emailOnFailureLabel",
6912
+ "On Failure"
6913
+ ),
6914
+ description: tr(
6915
+ "fluidgrids.settings.notifications.emailOnFailureDescription",
6916
+ "Send email when a workflow execution fails"
6917
+ ),
6511
6918
  children: /* @__PURE__ */ jsx(Switch, { checked: settings.emailOnFailure, disabled: true })
6512
6919
  }
6513
6920
  )
@@ -6516,22 +6923,37 @@ function NotificationsTab() {
6516
6923
  /* @__PURE__ */ jsxs("div", { children: [
6517
6924
  /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold text-text-primary flex items-center gap-2 mb-3", children: [
6518
6925
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:webhook", width: 18 }),
6519
- "Webhook Notifications"
6926
+ tr(
6927
+ "fluidgrids.settings.notifications.webhookSectionTitle",
6928
+ "Webhook Notifications"
6929
+ )
6520
6930
  ] }),
6521
6931
  /* @__PURE__ */ jsxs("div", { className: "divide-y divide-border-secondary rounded-lg border border-border-secondary bg-background-secondary p-1", children: [
6522
6932
  /* @__PURE__ */ jsx(
6523
6933
  SettingRow,
6524
6934
  {
6525
- label: "On Success",
6526
- description: "Send webhook when a workflow execution completes successfully",
6935
+ label: tr(
6936
+ "fluidgrids.settings.notifications.webhookOnSuccessLabel",
6937
+ "On Success"
6938
+ ),
6939
+ description: tr(
6940
+ "fluidgrids.settings.notifications.webhookOnSuccessDescription",
6941
+ "Send webhook when a workflow execution completes successfully"
6942
+ ),
6527
6943
  children: /* @__PURE__ */ jsx(Switch, { checked: settings.webhookOnSuccess, disabled: true })
6528
6944
  }
6529
6945
  ),
6530
6946
  /* @__PURE__ */ jsx(
6531
6947
  SettingRow,
6532
6948
  {
6533
- label: "On Failure",
6534
- description: "Send webhook when a workflow execution fails",
6949
+ label: tr(
6950
+ "fluidgrids.settings.notifications.webhookOnFailureLabel",
6951
+ "On Failure"
6952
+ ),
6953
+ description: tr(
6954
+ "fluidgrids.settings.notifications.webhookOnFailureDescription",
6955
+ "Send webhook when a workflow execution fails"
6956
+ ),
6535
6957
  children: /* @__PURE__ */ jsx(Switch, { checked: settings.webhookOnFailure, disabled: true })
6536
6958
  }
6537
6959
  )
@@ -6540,17 +6962,33 @@ function NotificationsTab() {
6540
6962
  ] });
6541
6963
  }
6542
6964
  function ApiTab() {
6965
+ const tr = useTr();
6543
6966
  const settings = DEFAULT_SETTINGS.api;
6544
6967
  return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
6545
6968
  /* @__PURE__ */ jsx(Card$1, { className: "border border-border-secondary bg-background-secondary", children: /* @__PURE__ */ jsxs(CardHeader, { className: "pb-3", children: [
6546
6969
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
6547
6970
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:api", width: 20, className: "text-text-secondary" }),
6548
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: "API Gateway URL" })
6971
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: tr(
6972
+ "fluidgrids.settings.api.gatewayUrlTitle",
6973
+ "API Gateway URL"
6974
+ ) })
6549
6975
  ] }),
6550
- /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary mb-3", children: "Base URL for workflow API operations. Use this to trigger, list, and manage workflows programmatically." }),
6976
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary mb-3", children: tr(
6977
+ "fluidgrids.settings.api.gatewayUrlDescription",
6978
+ "Base URL for workflow API operations. Use this to trigger, list, and manage workflows programmatically."
6979
+ ) }),
6551
6980
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg bg-background-tertiary px-3 py-2 border border-border-secondary", children: [
6552
6981
  /* @__PURE__ */ jsx("code", { className: "text-sm text-text-primary flex-1 truncate", children: settings.gatewayUrl }),
6553
- /* @__PURE__ */ jsx(CopyButton, { value: settings.gatewayUrl, label: "API Gateway URL" })
6982
+ /* @__PURE__ */ jsx(
6983
+ CopyButton,
6984
+ {
6985
+ value: settings.gatewayUrl,
6986
+ label: tr(
6987
+ "fluidgrids.settings.api.gatewayUrlCopyLabel",
6988
+ "API Gateway URL"
6989
+ )
6990
+ }
6991
+ )
6554
6992
  ] })
6555
6993
  ] }) }),
6556
6994
  /* @__PURE__ */ jsx(Card$1, { className: "border border-border-secondary bg-background-secondary", children: /* @__PURE__ */ jsxs(CardHeader, { className: "pb-3", children: [
@@ -6563,13 +7001,23 @@ function ApiTab() {
6563
7001
  className: "text-text-secondary"
6564
7002
  }
6565
7003
  ),
6566
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: "Webhook URL Format" })
7004
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: tr(
7005
+ "fluidgrids.settings.api.webhookUrlTitle",
7006
+ "Webhook URL Format"
7007
+ ) })
6567
7008
  ] }),
6568
7009
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-text-secondary mb-3", children: [
6569
- "URL format for triggering workflows via webhook. Replace",
7010
+ tr(
7011
+ "fluidgrids.settings.api.webhookUrlDescriptionPrefix",
7012
+ "URL format for triggering workflows via webhook. Replace"
7013
+ ),
6570
7014
  " ",
6571
7015
  /* @__PURE__ */ jsx("code", { className: "text-text-primary", children: "{workflowKey}" }),
6572
- " with the actual workflow key."
7016
+ " ",
7017
+ tr(
7018
+ "fluidgrids.settings.api.webhookUrlDescriptionSuffix",
7019
+ "with the actual workflow key."
7020
+ )
6573
7021
  ] }),
6574
7022
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg bg-background-tertiary px-3 py-2 border border-border-secondary", children: [
6575
7023
  /* @__PURE__ */ jsx("code", { className: "text-sm text-text-primary flex-1 truncate", children: settings.webhookUrlFormat }),
@@ -6577,7 +7025,10 @@ function ApiTab() {
6577
7025
  CopyButton,
6578
7026
  {
6579
7027
  value: settings.webhookUrlFormat,
6580
- label: "Webhook URL"
7028
+ label: tr(
7029
+ "fluidgrids.settings.api.webhookUrlCopyLabel",
7030
+ "Webhook URL"
7031
+ )
6581
7032
  }
6582
7033
  )
6583
7034
  ] })
@@ -6592,7 +7043,10 @@ function ApiTab() {
6592
7043
  className: "text-text-secondary"
6593
7044
  }
6594
7045
  ),
6595
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: "Example: Trigger via cURL" })
7046
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-text-primary", children: tr(
7047
+ "fluidgrids.settings.api.curlExampleTitle",
7048
+ "Example: Trigger via cURL"
7049
+ ) })
6596
7050
  ] }),
6597
7051
  /* @__PURE__ */ jsxs("div", { className: "relative rounded-lg bg-background-tertiary px-3 py-2 border border-border-secondary", children: [
6598
7052
  /* @__PURE__ */ jsx("pre", { className: "text-xs text-text-primary overflow-x-auto whitespace-pre-wrap", children: `curl -X POST "${settings.webhookUrlFormat}" \\
@@ -6606,7 +7060,10 @@ function ApiTab() {
6606
7060
  -H "Content-Type: application/json" \\
6607
7061
  -H "Authorization: Bearer <token>" \\
6608
7062
  -d '{"input": {}}'`,
6609
- label: "cURL command"
7063
+ label: tr(
7064
+ "fluidgrids.settings.api.curlCopyLabel",
7065
+ "cURL command"
7066
+ )
6610
7067
  }
6611
7068
  ) })
6612
7069
  ] })
@@ -6614,36 +7071,40 @@ function ApiTab() {
6614
7071
  ] }) });
6615
7072
  }
6616
7073
  function SettingsPage() {
7074
+ const tr = useTr();
6617
7075
  const navigate = useNavigate();
6618
7076
  const [activeTab, setActiveTab] = useState("general");
6619
7077
  return /* @__PURE__ */ jsxs("div", { className: "p-4 sm:p-6 bg-background-primary min-h-screen", children: [
6620
7078
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6", children: [
6621
7079
  /* @__PURE__ */ jsxs("div", { children: [
6622
- /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: "Settings" }),
6623
- /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: "Configure workflow execution and notification preferences" })
7080
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl sm:text-3xl font-bold text-text-primary", children: tr("fluidgrids.settings.page.title", "Settings") }),
7081
+ /* @__PURE__ */ jsx("p", { className: "text-text-secondary mt-1", children: tr(
7082
+ "fluidgrids.settings.page.subtitle",
7083
+ "Configure workflow execution and notification preferences"
7084
+ ) })
6624
7085
  ] }),
6625
7086
  /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: () => navigate("../list"), children: [
6626
7087
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:arrow-left", className: "mr-2", width: 16 }),
6627
- "Back to Workflows"
7088
+ tr("fluidgrids.settings.page.backToWorkflows", "Back to Workflows")
6628
7089
  ] })
6629
7090
  ] }),
6630
7091
  /* @__PURE__ */ jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [
6631
7092
  /* @__PURE__ */ jsxs(TabsList, { className: "bg-background-secondary border border-border-secondary mb-6", children: [
6632
7093
  /* @__PURE__ */ jsxs(TabsTrigger, { value: "general", className: "gap-1.5", children: [
6633
7094
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:cog", width: 16 }),
6634
- "General"
7095
+ tr("fluidgrids.settings.page.generalTab", "General")
6635
7096
  ] }),
6636
7097
  /* @__PURE__ */ jsxs(TabsTrigger, { value: "execution", className: "gap-1.5", children: [
6637
7098
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:play-circle", width: 16 }),
6638
- "Execution"
7099
+ tr("fluidgrids.settings.page.executionTab", "Execution")
6639
7100
  ] }),
6640
7101
  /* @__PURE__ */ jsxs(TabsTrigger, { value: "notifications", className: "gap-1.5", children: [
6641
7102
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:bell-outline", width: 16 }),
6642
- "Notifications"
7103
+ tr("fluidgrids.settings.page.notificationsTab", "Notifications")
6643
7104
  ] }),
6644
7105
  /* @__PURE__ */ jsxs(TabsTrigger, { value: "api", className: "gap-1.5", children: [
6645
7106
  /* @__PURE__ */ jsx(Icon, { icon: "mdi:api", width: 16 }),
6646
- "API"
7107
+ tr("fluidgrids.settings.page.apiTab", "API")
6647
7108
  ] })
6648
7109
  ] }),
6649
7110
  /* @__PURE__ */ jsx(TabsContent, { value: "general", children: /* @__PURE__ */ jsx(GeneralTab, {}) }),