@pipe0/react 0.2.0 → 0.2.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 (98) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/components/compound/pipe-form/errors.d.mts.map +1 -1
  3. package/dist/components/compound/pipe-form/errors.mjs +5 -4
  4. package/dist/components/compound/pipe-form/errors.mjs.map +1 -1
  5. package/dist/components/compound/pipe-form/root.d.mts +3 -1
  6. package/dist/components/compound/pipe-form/root.d.mts.map +1 -1
  7. package/dist/components/compound/pipe-form/root.mjs +5 -3
  8. package/dist/components/compound/pipe-form/root.mjs.map +1 -1
  9. package/dist/components/compound/search-form/errors.d.mts.map +1 -1
  10. package/dist/components/compound/search-form/errors.mjs +5 -4
  11. package/dist/components/compound/search-form/errors.mjs.map +1 -1
  12. package/dist/components/compound/search-form/root.d.mts +3 -1
  13. package/dist/components/compound/search-form/root.d.mts.map +1 -1
  14. package/dist/components/compound/search-form/root.mjs +5 -3
  15. package/dist/components/compound/search-form/root.mjs.map +1 -1
  16. package/dist/components/defaults/adapters/context-select-input.mjs +1 -1
  17. package/dist/components/defaults/adapters/context-select-input.mjs.map +1 -1
  18. package/dist/components/defaults/adapters/index.d.mts.map +1 -1
  19. package/dist/components/defaults/adapters/index.mjs +8 -5
  20. package/dist/components/defaults/adapters/index.mjs.map +1 -1
  21. package/dist/components/defaults/adapters/int-input.mjs.map +1 -1
  22. package/dist/components/defaults/adapters/loose-object-input.mjs +111 -0
  23. package/dist/components/defaults/adapters/loose-object-input.mjs.map +1 -0
  24. package/dist/components/defaults/adapters/pipes-run-if-input.mjs +146 -74
  25. package/dist/components/defaults/adapters/pipes-run-if-input.mjs.map +1 -1
  26. package/dist/components/defaults/adapters/providers-input.mjs.map +1 -1
  27. package/dist/components/defaults/adapters/search-payload-input.mjs +18 -0
  28. package/dist/components/defaults/adapters/search-payload-input.mjs.map +1 -0
  29. package/dist/components/defaults/adapters/select-input.mjs +46 -27
  30. package/dist/components/defaults/adapters/select-input.mjs.map +1 -1
  31. package/dist/components/defaults/catalog/card-derived.d.mts +1 -1
  32. package/dist/components/defaults/catalog/card-derived.d.mts.map +1 -1
  33. package/dist/components/defaults/catalog/card-derived.mjs +6 -2
  34. package/dist/components/defaults/catalog/card-derived.mjs.map +1 -1
  35. package/dist/components/defaults/layout/field-wrapper.d.mts.map +1 -1
  36. package/dist/components/defaults/layout/field-wrapper.mjs +11 -5
  37. package/dist/components/defaults/layout/field-wrapper.mjs.map +1 -1
  38. package/dist/components/defaults/layout/group.mjs +1 -1
  39. package/dist/components/internal/LiquidEditor/LiquidEditor.mjs.map +1 -1
  40. package/dist/components/internal/form-level-errors.mjs +4 -3
  41. package/dist/components/internal/form-level-errors.mjs.map +1 -1
  42. package/dist/components/internal/icons.mjs +27 -1
  43. package/dist/components/internal/icons.mjs.map +1 -1
  44. package/dist/components/ui/alert.d.mts +47 -0
  45. package/dist/components/ui/alert.d.mts.map +1 -0
  46. package/dist/components/ui/alert.mjs +66 -0
  47. package/dist/components/ui/alert.mjs.map +1 -0
  48. package/dist/context/form-context.d.mts +21 -0
  49. package/dist/context/form-context.d.mts.map +1 -0
  50. package/dist/context/form-context.mjs +11 -1
  51. package/dist/context/form-context.mjs.map +1 -1
  52. package/dist/context/form-provider.d.mts +3 -1
  53. package/dist/context/form-provider.d.mts.map +1 -1
  54. package/dist/context/form-provider.mjs +8 -2
  55. package/dist/context/form-provider.mjs.map +1 -1
  56. package/dist/hooks/use-effect-catalog-table.d.mts.map +1 -1
  57. package/dist/hooks/use-effect-catalog-table.mjs +2 -2
  58. package/dist/hooks/use-effect-catalog-table.mjs.map +1 -1
  59. package/dist/hooks/use-form-core.mjs +7 -4
  60. package/dist/hooks/use-form-core.mjs.map +1 -1
  61. package/dist/hooks/use-pipe-catalog-table.d.mts +8 -8
  62. package/dist/hooks/use-pipe-catalog-table.d.mts.map +1 -1
  63. package/dist/hooks/use-pipe-catalog-table.mjs +2 -2
  64. package/dist/hooks/use-pipe-catalog-table.mjs.map +1 -1
  65. package/dist/hooks/use-pipe-form.d.mts.map +1 -1
  66. package/dist/hooks/use-pipe-form.mjs +18 -19
  67. package/dist/hooks/use-pipe-form.mjs.map +1 -1
  68. package/dist/hooks/use-search-catalog-table.d.mts +6 -6
  69. package/dist/hooks/use-search-form.d.mts.map +1 -1
  70. package/dist/hooks/use-search-form.mjs +18 -18
  71. package/dist/hooks/use-search-form.mjs.map +1 -1
  72. package/dist/hooks/use-sheet-effect-form.d.mts.map +1 -1
  73. package/dist/hooks/use-sheet-effect-form.mjs +18 -19
  74. package/dist/hooks/use-sheet-effect-form.mjs.map +1 -1
  75. package/dist/index.d.mts +4 -2
  76. package/dist/index.mjs +3 -1
  77. package/dist/styles/pipe0-form.css +1 -1
  78. package/dist/types/adapters.d.mts +22 -1
  79. package/dist/types/adapters.d.mts.map +1 -1
  80. package/dist/types/catalog-adapters.d.mts +1 -1
  81. package/dist/types/field-props.d.mts +23 -13
  82. package/dist/types/field-props.d.mts.map +1 -1
  83. package/dist/types/form-customization.d.mts +2 -25
  84. package/dist/utils/build-section-handlers.mjs +8 -74
  85. package/dist/utils/build-section-handlers.mjs.map +1 -1
  86. package/dist/widgets/token-pricing-badge.d.mts +1 -0
  87. package/dist/widgets/token-pricing-badge.mjs +55 -0
  88. package/dist/widgets/token-pricing-badge.mjs.map +1 -0
  89. package/dist/widgets/widget-strip.d.mts.map +1 -1
  90. package/dist/widgets/widget-strip.mjs +1 -0
  91. package/dist/widgets/widget-strip.mjs.map +1 -1
  92. package/dist/widgets/widget-view.d.mts.map +1 -1
  93. package/dist/widgets/widget-view.mjs +6 -0
  94. package/dist/widgets/widget-view.mjs.map +1 -1
  95. package/package.json +2 -2
  96. package/dist/components/defaults/adapters/key-value-list-input.mjs +0 -102
  97. package/dist/components/defaults/adapters/key-value-list-input.mjs.map +0 -1
  98. package/dist/types/form-customization.d.mts.map +0 -1
@@ -6,6 +6,8 @@ import { IconPlus } from "../../internal/icons.mjs";
6
6
  import { HoverInfo } from "../../hover-info.mjs";
7
7
  import { Badge } from "../../ui/badge.mjs";
8
8
  import { useFieldError } from "../../../hooks/use-field-error.mjs";
9
+ import { FieldLegend } from "../../internal/field-legend.mjs";
10
+ import { LiquidEditor } from "../../internal/LiquidEditor/LiquidEditor.mjs";
9
11
  import { FieldSectionEnumeration } from "../field-section-enumeration.mjs";
10
12
  import { useCallback, useMemo } from "react";
11
13
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -16,7 +18,8 @@ const OPERATORS_BY_TYPE = {
16
18
  string: [
17
19
  "eq",
18
20
  "neq",
19
- "contains"
21
+ "contains",
22
+ "matches"
20
23
  ],
21
24
  number: [
22
25
  "eq",
@@ -37,13 +40,14 @@ const EMPTY_CONDITION = {
37
40
  value: ""
38
41
  };
39
42
  const CONNECTOR_GAP = 32;
40
- function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst, isLast, logic, form, basePath, onUpdate, onRemove, onAddCondition, onLogicChange }) {
41
- const conditionPath = `${basePath}.when.conditions.${index}`;
43
+ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst, isLast, logic, form, conditionsPath, fieldNameMode, fieldNamePlaceholder, showStatusProperty, inputFields, searchSecrets, searchConstants, onUpdate, onRemove, onAddCondition, onLogicChange }) {
44
+ const conditionPath = `${conditionsPath}.${index}`;
42
45
  const valueError = useFieldError(form, `${conditionPath}.value`);
43
46
  const fieldNameError = useFieldError(form, `${conditionPath}.field_name`);
44
47
  const operatorError = useFieldError(form, `${conditionPath}.operator`);
45
48
  const propertyError = useFieldError(form, `${conditionPath}.property`);
46
49
  const showConnector = !(isFirst && isLast);
50
+ const isTextMode = fieldNameMode === "text";
47
51
  const hasEligibleFields = eligibleFields.length > 0;
48
52
  const selectedField = condition.field_name ? fieldsByName.get(condition.field_name) : void 0;
49
53
  const availableOperators = useMemo(() => {
@@ -51,19 +55,52 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
51
55
  value: op,
52
56
  label: RUN_IF_OPERATOR_LABELS[op]
53
57
  }));
54
- if (!selectedField?.type) return [];
55
- return RUN_IF_VALUE_OPERATORS.map((op) => ({
58
+ const valueOperators = RUN_IF_VALUE_OPERATORS.map((op) => ({
56
59
  value: op,
57
60
  label: RUN_IF_OPERATOR_LABELS[op]
58
- })).filter((op) => OPERATORS_BY_TYPE[selectedField.type].includes(op.value));
59
- }, [condition.property, selectedField]);
61
+ }));
62
+ if (isTextMode) return valueOperators;
63
+ if (!selectedField?.type) return [];
64
+ return valueOperators.filter((op) => OPERATORS_BY_TYPE[selectedField.type].includes(op.value));
65
+ }, [
66
+ condition.property,
67
+ selectedField,
68
+ isTextMode
69
+ ]);
60
70
  const renderValueInput = () => {
61
- if (!condition.field_name || !selectedField) return /* @__PURE__ */ jsx(Input, {
71
+ if (!isTextMode && (!condition.field_name || !selectedField)) return /* @__PURE__ */ jsx(Input, {
62
72
  className: "pz:w-32",
63
73
  placeholder: "",
64
74
  disabled: true,
65
75
  "aria-invalid": !!valueError
66
76
  });
77
+ if (isTextMode && condition.property !== "status") {
78
+ if (inputFields) return /* @__PURE__ */ jsx("div", {
79
+ className: cn("pz:w-64 pz:rounded-md pz:border pz:border-input pz:bg-transparent", valueError && "pz:border-destructive"),
80
+ children: /* @__PURE__ */ jsx(LiquidEditor, {
81
+ value: String(condition.value ?? ""),
82
+ onChange: (v) => onUpdate(index, {
83
+ ...condition,
84
+ value: v
85
+ }),
86
+ inputFields,
87
+ searchSecrets,
88
+ searchConstants,
89
+ placeholder: "",
90
+ hideLegend: true
91
+ })
92
+ });
93
+ return /* @__PURE__ */ jsx(Input, {
94
+ className: "pz:w-32",
95
+ "aria-invalid": !!valueError,
96
+ value: String(condition.value ?? ""),
97
+ onChange: (e) => onUpdate(index, {
98
+ ...condition,
99
+ value: e.target.value
100
+ }),
101
+ placeholder: ""
102
+ });
103
+ }
67
104
  if (condition.property === "status") return /* @__PURE__ */ jsxs(Select, {
68
105
  value: String(condition.value) || null,
69
106
  onValueChange: (v) => onUpdate(index, {
@@ -93,7 +130,7 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
93
130
  })
94
131
  ] })]
95
132
  });
96
- if (selectedField.type === "boolean") return /* @__PURE__ */ jsxs(Select, {
133
+ if (selectedField?.type === "boolean") return /* @__PURE__ */ jsxs(Select, {
97
134
  value: String(condition.value),
98
135
  onValueChange: (v) => onUpdate(index, {
99
136
  ...condition,
@@ -111,7 +148,7 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
111
148
  children: "false"
112
149
  })] })]
113
150
  });
114
- if (selectedField.type === "number") return /* @__PURE__ */ jsx(Input, {
151
+ if (selectedField?.type === "number") return /* @__PURE__ */ jsx(Input, {
115
152
  type: "number",
116
153
  className: "pz:w-32",
117
154
  "aria-invalid": !!valueError,
@@ -187,7 +224,16 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
187
224
  index,
188
225
  onRemove
189
226
  }),
190
- /* @__PURE__ */ jsxs(Select, {
227
+ isTextMode ? /* @__PURE__ */ jsx(Input, {
228
+ className: "pz:w-40",
229
+ "aria-invalid": !!fieldNameError,
230
+ value: condition.field_name,
231
+ onChange: (e) => onUpdate(index, {
232
+ ...condition,
233
+ field_name: e.target.value
234
+ }),
235
+ placeholder: fieldNamePlaceholder ?? "column"
236
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Select, {
191
237
  value: condition.field_name || null,
192
238
  disabled: !hasEligibleFields,
193
239
  onValueChange: (v) => {
@@ -207,22 +253,20 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
207
253
  value: f.fieldName,
208
254
  children: f.fieldLabel || f.fieldName
209
255
  }, f.fieldName)) })]
210
- }),
211
- !hasEligibleFields && /* @__PURE__ */ jsxs("span", {
256
+ }), !hasEligibleFields && /* @__PURE__ */ jsxs("span", {
212
257
  className: "pz:text-xs pz:text-muted-foreground",
213
258
  children: [
214
259
  "No fields available",
215
260
  " ",
216
261
  /* @__PURE__ */ jsx(HoverInfo, { children: "Conditions require plain fields. JSON fields are not allowed." })
217
262
  ]
218
- }),
219
- selectedField?.type && /* @__PURE__ */ jsxs(Fragment$1, { children: [
220
- /* @__PURE__ */ jsx(Badge, {
263
+ })] }),
264
+ (isTextMode || selectedField?.type) && /* @__PURE__ */ jsxs(Fragment$1, { children: [
265
+ showStatusProperty && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Badge, {
221
266
  variant: "secondary",
222
267
  className: "pz:bg-accent pz:border pz:border-input pz:font-normal pz:text-muted-foreground pz:h-8",
223
268
  children: "'s"
224
- }),
225
- /* @__PURE__ */ jsxs(Select, {
269
+ }), /* @__PURE__ */ jsxs(Select, {
226
270
  defaultValue: "value",
227
271
  value: condition.property,
228
272
  onValueChange: (v) => {
@@ -245,7 +289,7 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
245
289
  value: "status",
246
290
  children: "status"
247
291
  })] })]
248
- }),
292
+ })] }),
249
293
  /* @__PURE__ */ jsxs(Select, {
250
294
  value: condition.operator,
251
295
  onValueChange: (v) => onUpdate(index, {
@@ -282,100 +326,128 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
282
326
  })
283
327
  })] });
284
328
  }
285
- function PipesRunIfInputAdapter(field) {
286
- const pipeRunIf = field.value;
287
- const meta = field.meta;
288
- const eligibleFields = useMemo(() => meta.fields.filter((f) => OPERATORS_BY_TYPE[f.type].length > 0), [meta.fields]);
289
- const fieldsByName = useMemo(() => new Map(meta.fields.map((f) => [f.fieldName, f])), [meta.fields]);
290
- const addRunIf = useCallback(() => {
291
- field.setValue({
292
- action: "run",
293
- when: {
294
- logic: "and",
295
- conditions: [{ ...EMPTY_CONDITION }]
296
- }
329
+ /**
330
+ * Presentational condition-block editor shared by the pipe run-if gate and by
331
+ * effects that filter rows by a condition (e.g. `rows:remove@1`'s `where`).
332
+ * Operates on a bare `{logic, conditions}` block via `value`/`onChange`; the
333
+ * wrapping adapters own where that block lives in their payload.
334
+ */
335
+ function ConditionBlockEditor({ value, onChange, fields, form, conditionsPath, fieldNameMode = "select", fieldNamePlaceholder, properties, inputFields, searchSecrets, searchConstants }) {
336
+ const eligibleFields = useMemo(() => fields.filter((f) => OPERATORS_BY_TYPE[f.type].length > 0), [fields]);
337
+ const fieldsByName = useMemo(() => new Map(fields.map((f) => [f.fieldName, f])), [fields]);
338
+ const addBlock = useCallback(() => {
339
+ onChange({
340
+ logic: "and",
341
+ conditions: [{ ...EMPTY_CONDITION }]
297
342
  });
298
- }, [field]);
343
+ }, [onChange]);
299
344
  const updateCondition = (index, condition) => {
300
- if (!pipeRunIf) return;
301
- const newConditions = [...pipeRunIf.when.conditions];
345
+ if (!value) return;
346
+ const newConditions = [...value.conditions];
302
347
  newConditions[index] = condition;
303
- field.setValue({
304
- ...pipeRunIf,
305
- when: {
306
- ...pipeRunIf.when,
307
- conditions: newConditions
308
- }
348
+ onChange({
349
+ ...value,
350
+ conditions: newConditions
309
351
  });
310
352
  };
311
353
  const removeCondition = (index) => {
312
- if (!pipeRunIf) return;
313
- if (pipeRunIf.when.conditions.length <= 1) {
314
- field.setValue(null);
354
+ if (!value) return;
355
+ if (value.conditions.length <= 1) {
356
+ onChange(null);
315
357
  return;
316
358
  }
317
- const newConditions = pipeRunIf.when.conditions.filter((_, i) => i !== index);
318
- field.setValue({
319
- ...pipeRunIf,
320
- when: {
321
- ...pipeRunIf.when,
322
- conditions: newConditions
323
- }
359
+ onChange({
360
+ ...value,
361
+ conditions: value.conditions.filter((_, i) => i !== index)
324
362
  });
325
363
  };
326
364
  const addCondition = () => {
327
- if (!pipeRunIf) return;
328
- field.setValue({
329
- ...pipeRunIf,
330
- when: {
331
- ...pipeRunIf.when,
332
- conditions: [...pipeRunIf.when.conditions, { ...EMPTY_CONDITION }]
333
- }
365
+ if (!value) return;
366
+ onChange({
367
+ ...value,
368
+ conditions: [...value.conditions, { ...EMPTY_CONDITION }]
334
369
  });
335
370
  };
336
371
  const changeLogic = (logic) => {
337
- if (!pipeRunIf) return;
338
- field.setValue({
339
- ...pipeRunIf,
340
- when: {
341
- ...pipeRunIf.when,
342
- logic
343
- }
372
+ if (!value) return;
373
+ onChange({
374
+ ...value,
375
+ logic
344
376
  });
345
377
  };
346
378
  return /* @__PURE__ */ jsx("div", {
347
379
  "data-p0": "input",
348
- children: !pipeRunIf ? /* @__PURE__ */ jsx("div", {
380
+ children: !value ? /* @__PURE__ */ jsx("div", {
349
381
  className: "pz:flex pz:items-center",
350
382
  children: /* @__PURE__ */ jsxs(Button, {
351
383
  type: "button",
352
384
  variant: "link",
353
385
  size: "xs",
354
386
  className: "pz:px-0",
355
- onClick: addRunIf,
387
+ onClick: addBlock,
356
388
  children: [/* @__PURE__ */ jsx(IconPlus, {}), "New rule"]
357
389
  })
358
- }) : /* @__PURE__ */ jsx("div", {
390
+ }) : /* @__PURE__ */ jsxs("div", {
359
391
  className: "pz:flex pz:flex-col pz:gap-8",
360
- children: pipeRunIf.when.conditions.map((condition, idx) => /* @__PURE__ */ jsx(ConditionRow, {
392
+ children: [value.conditions.map((condition, idx) => /* @__PURE__ */ jsx(ConditionRow, {
361
393
  condition,
362
394
  index: idx,
363
395
  eligibleFields,
364
396
  fieldsByName,
365
397
  isFirst: idx === 0,
366
- isLast: idx === pipeRunIf.when.conditions.length - 1,
367
- logic: pipeRunIf.when.logic,
368
- form: field.form,
369
- basePath: field.path,
398
+ isLast: idx === value.conditions.length - 1,
399
+ logic: value.logic,
400
+ form,
401
+ conditionsPath,
402
+ fieldNameMode,
403
+ fieldNamePlaceholder,
404
+ showStatusProperty: (properties ?? ["value", "status"]).includes("status"),
405
+ inputFields,
406
+ searchSecrets,
407
+ searchConstants,
370
408
  onUpdate: updateCondition,
371
409
  onRemove: removeCondition,
372
410
  onAddCondition: addCondition,
373
411
  onLogicChange: changeLogic
374
- }, idx))
412
+ }, idx)), fieldNameMode === "text" && inputFields && /* @__PURE__ */ jsx(FieldLegend, { entries: [{
413
+ key: "/",
414
+ label: "to insert a reference"
415
+ }] })]
375
416
  })
376
417
  });
377
418
  }
419
+ function PipesRunIfInputAdapter(field) {
420
+ const pipeRunIf = field.value;
421
+ const meta = field.meta;
422
+ return /* @__PURE__ */ jsx(ConditionBlockEditor, {
423
+ value: pipeRunIf?.when ?? null,
424
+ onChange: (block) => field.setValue(block ? {
425
+ action: "run",
426
+ when: block
427
+ } : null),
428
+ fields: meta.fields,
429
+ form: field.form,
430
+ conditionsPath: `${field.path}.when.conditions`
431
+ });
432
+ }
433
+ function ConditionBlockInputAdapter(field) {
434
+ const block = field.value;
435
+ const meta = field.meta;
436
+ return /* @__PURE__ */ jsx(ConditionBlockEditor, {
437
+ value: block,
438
+ onChange: (next) => field.setValue(next),
439
+ fields: meta.fields,
440
+ form: field.form,
441
+ conditionsPath: `${field.path}.conditions`,
442
+ fieldNameMode: meta.fieldNameMode,
443
+ fieldNamePlaceholder: meta.fieldNamePlaceholder,
444
+ properties: meta.properties,
445
+ inputFields: meta.inputFields,
446
+ searchSecrets: field.searchSecrets,
447
+ searchConstants: field.searchConstants
448
+ });
449
+ }
378
450
 
379
451
  //#endregion
380
- export { PipesRunIfInputAdapter };
452
+ export { ConditionBlockInputAdapter, PipesRunIfInputAdapter };
381
453
  //# sourceMappingURL=pipes-run-if-input.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipes-run-if-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/pipes-run-if-input.tsx"],"sourcesContent":["import {\n type ConditionOperators,\n type PipeRunIf,\n type PipesRunIfMeta,\n type RecordFieldType,\n RUN_IF_OPERATOR_LABELS,\n RUN_IF_STATUS_OPERATORS,\n RUN_IF_VALUE_OPERATORS,\n} from \"@pipe0/base\";\nimport { useCallback, useMemo } from \"react\";\nimport { useFieldError } from \"../../../hooks/use-field-error.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport type { FormHandle } from \"../../../types/form-handle.js\";\nimport { HoverInfo } from \"../../hover-info.js\";\nimport { IconPlus } from \"../../internal/icons.js\";\nimport { Badge } from \"../../ui/badge.js\";\nimport { Button } from \"../../ui/button.js\";\nimport { Input } from \"../../ui/input.js\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../ui/select.js\";\nimport { FieldSectionEnumeration } from \"../field-section-enumeration.js\";\n\n// Use a loose type for internal manipulation since the discriminated union\n// is strict about property/operator/value combinations.\ntype Condition = {\n field_name: string;\n property: string;\n operator: string;\n value: unknown;\n};\n\nconst OPERATORS_BY_TYPE: Record<RecordFieldType, ConditionOperators[]> = {\n string: [\"eq\", \"neq\", \"contains\"],\n number: [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\"],\n boolean: [\"eq\", \"neq\"],\n json: [],\n unknown: [],\n};\n\nconst EMPTY_CONDITION: Condition = {\n field_name: \"\",\n property: \"value\",\n operator: \"eq\",\n value: \"\",\n};\n\nconst CONNECTOR_GAP = 32;\n\ntype MetaField = {\n fieldName: string;\n fieldLabel: string;\n type: RecordFieldType;\n format: string | null;\n};\n\nfunction ConditionRow({\n condition,\n index,\n eligibleFields,\n fieldsByName,\n isFirst,\n isLast,\n logic,\n form,\n basePath,\n onUpdate,\n onRemove,\n onAddCondition,\n onLogicChange,\n}: {\n condition: Condition;\n index: number;\n eligibleFields: MetaField[];\n fieldsByName: ReadonlyMap<string, MetaField>;\n isFirst: boolean;\n isLast: boolean;\n logic: PipeRunIf[\"when\"][\"logic\"];\n form: FormHandle;\n basePath: string;\n onUpdate: (index: number, condition: Condition) => void;\n onRemove: (index: number) => void;\n onAddCondition: () => void;\n onLogicChange: (logic: PipeRunIf[\"when\"][\"logic\"]) => void;\n}) {\n const conditionPath = `${basePath}.when.conditions.${index}`;\n const valueError = useFieldError(form, `${conditionPath}.value`);\n const fieldNameError = useFieldError(form, `${conditionPath}.field_name`);\n const operatorError = useFieldError(form, `${conditionPath}.operator`);\n const propertyError = useFieldError(form, `${conditionPath}.property`);\n\n const showConnector = !(isFirst && isLast);\n const hasEligibleFields = eligibleFields.length > 0;\n const selectedField = condition.field_name ? fieldsByName.get(condition.field_name) : undefined;\n\n const availableOperators = useMemo(() => {\n if (condition.property === \"status\") {\n return RUN_IF_STATUS_OPERATORS.map((op) => ({\n value: op,\n label: RUN_IF_OPERATOR_LABELS[op],\n }));\n }\n if (!selectedField?.type) return [];\n return RUN_IF_VALUE_OPERATORS.map((op) => ({\n value: op,\n label: RUN_IF_OPERATOR_LABELS[op],\n })).filter((op) => OPERATORS_BY_TYPE[selectedField.type].includes(op.value));\n }, [condition.property, selectedField]);\n\n const renderValueInput = () => {\n if (!condition.field_name || !selectedField) {\n return <Input className=\"pz:w-32\" placeholder=\"\" disabled aria-invalid={!!valueError} />;\n }\n\n if (condition.property === \"status\") {\n return (\n <Select\n value={String(condition.value) || null}\n onValueChange={(v) => onUpdate(index, { ...condition, value: v })}\n >\n <SelectTrigger className=\"pz:w-32\" aria-invalid={!!valueError}>\n <SelectValue placeholder=\"--status--\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"completed\">completed</SelectItem>\n <SelectItem value=\"skipped\">skipped</SelectItem>\n <SelectItem value=\"failed\">failed</SelectItem>\n <SelectItem value=\"no_result\">no_result</SelectItem>\n </SelectContent>\n </Select>\n );\n }\n\n if (selectedField.type === \"boolean\") {\n return (\n <Select\n value={String(condition.value)}\n onValueChange={(v) => onUpdate(index, { ...condition, value: v })}\n >\n <SelectTrigger className=\"pz:w-24\" aria-invalid={!!valueError}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">true</SelectItem>\n <SelectItem value=\"false\">false</SelectItem>\n </SelectContent>\n </Select>\n );\n }\n\n if (selectedField.type === \"number\") {\n return (\n <Input\n type=\"number\"\n className=\"pz:w-32\"\n aria-invalid={!!valueError}\n value={String(Number(condition.value ?? 0))}\n onChange={(e) =>\n onUpdate(index, {\n ...condition,\n value: Number(e.target.value) || 0,\n })\n }\n placeholder=\"\"\n />\n );\n }\n\n return (\n <Input\n className=\"pz:w-32\"\n aria-invalid={!!valueError}\n value={String(condition.value ?? \"\")}\n onChange={(e) => onUpdate(index, { ...condition, value: e.target.value })}\n placeholder=\"\"\n />\n );\n };\n\n const errorMessage = valueError || fieldNameError || operatorError || propertyError;\n\n return (\n <div>\n <div className={cn(\"pz:relative\", showConnector && \"pz:pl-17\")}>\n {showConnector && (\n <>\n {isFirst ? (\n <div\n className=\"pz:absolute pz:left-7 pz:w-10 pz:border-l-2 pz:border-t-2 pz:border-input pz:rounded-tl-lg pz:pointer-events-none\"\n style={{ top: \"50%\", bottom: -CONNECTOR_GAP }}\n />\n ) : (\n <div\n className=\"pz:absolute pz:left-7 pz:w-10 pz:border-l-2 pz:border-b-2 pz:border-input pz:rounded-bl-lg pz:pointer-events-none\"\n style={{ top: -CONNECTOR_GAP, bottom: \"50%\" }}\n />\n )}\n {!isFirst && !isLast && (\n <div\n className=\"pz:absolute pz:left-7 pz:border-l-2 pz:border-input pz:pointer-events-none\"\n style={{ top: \"50%\", bottom: -CONNECTOR_GAP }}\n />\n )}\n {!isFirst && (\n <div\n className=\"pz:absolute pz:left-7 pz:z-10\"\n style={{\n top: -CONNECTOR_GAP / 2,\n transform: \"translate(-50%, -50%)\",\n }}\n >\n <Select value={logic} onValueChange={(v) => onLogicChange(v as \"and\" | \"or\")}>\n <SelectTrigger className=\"pz:w-17 pz:h-6 pz:text-xs pz:bg-background pz:hover:bg-accent\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectItem value=\"and\">AND</SelectItem>\n <SelectItem value=\"or\">OR</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n </div>\n )}\n </>\n )}\n <div className=\"pz:flex pz:flex-wrap pz:items-center pz:gap-2\">\n <FieldSectionEnumeration index={index} onRemove={onRemove} />\n <Select\n value={condition.field_name || null}\n disabled={!hasEligibleFields}\n onValueChange={(v) => {\n if (v === null) return;\n onUpdate(index, {\n ...condition,\n field_name: v,\n operator: \"eq\",\n value: \"\",\n });\n }}\n >\n <SelectTrigger className=\"pz:w-40\" aria-invalid={!!fieldNameError}>\n <SelectValue placeholder=\"Select field\" />\n </SelectTrigger>\n <SelectContent>\n {eligibleFields.map((f) => (\n <SelectItem key={f.fieldName} value={f.fieldName}>\n {f.fieldLabel || f.fieldName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {!hasEligibleFields && (\n <span className=\"pz:text-xs pz:text-muted-foreground\">\n No fields available{\" \"}\n <HoverInfo>Conditions require plain fields. JSON fields are not allowed.</HoverInfo>\n </span>\n )}\n\n {selectedField?.type && (\n <>\n <Badge\n variant=\"secondary\"\n className=\"pz:bg-accent pz:border pz:border-input pz:font-normal pz:text-muted-foreground pz:h-8\"\n >\n &apos;s\n </Badge>\n <Select\n defaultValue=\"value\"\n value={condition.property}\n onValueChange={(v) => {\n if (v === null) return;\n onUpdate(index, {\n ...condition,\n property: v,\n operator: \"eq\",\n value: \"\",\n });\n }}\n >\n <SelectTrigger className=\"pz:w-28\" aria-invalid={!!propertyError}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"value\">value</SelectItem>\n <SelectItem value=\"status\">status</SelectItem>\n </SelectContent>\n </Select>\n\n <Select\n value={condition.operator}\n onValueChange={(v) =>\n onUpdate(index, {\n ...condition,\n operator: v as ConditionOperators,\n })\n }\n >\n <SelectTrigger className=\"pz:w-28\" aria-invalid={!!operatorError}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {availableOperators.map((op) => (\n <SelectItem key={op.value} value={op.value}>\n {op.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {renderValueInput()}\n </>\n )}\n </div>\n {errorMessage && (\n <span\n className=\"pz:text-destructive pz:text-xs pz:font-medium pz:mt-1 pz:block\"\n role=\"alert\"\n >\n {errorMessage}\n </span>\n )}\n </div>\n {isLast && (\n <div className=\"pz:flex pz:items-center pz:gap-2\">\n <Button type=\"button\" variant=\"link\" size=\"xs\" onClick={onAddCondition}>\n <IconPlus />\n New rule\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nexport function PipesRunIfInputAdapter(field: FieldHandle<\"pipes_run_if_input\">) {\n const pipeRunIf = field.value as PipeRunIf | null;\n const meta = field.meta as PipesRunIfMeta;\n\n // Built once per render of the adapter and reused across every condition\n // row, instead of each row scanning `meta.fields` linearly. With N rows and\n // M fields this turns O(N·M) lookups into O(N+M).\n const eligibleFields = useMemo(\n () => meta.fields.filter((f) => OPERATORS_BY_TYPE[f.type].length > 0),\n [meta.fields],\n );\n const fieldsByName = useMemo(\n () => new Map(meta.fields.map((f) => [f.fieldName, f])),\n [meta.fields],\n );\n\n const addRunIf = useCallback(() => {\n field.setValue({\n action: \"run\",\n when: {\n logic: \"and\",\n conditions: [{ ...EMPTY_CONDITION }],\n },\n });\n }, [field]);\n\n const updateCondition = (index: number, condition: Condition) => {\n if (!pipeRunIf) return;\n const newConditions = [...pipeRunIf.when.conditions] as Condition[];\n newConditions[index] = condition;\n field.setValue({\n ...pipeRunIf,\n when: { ...pipeRunIf.when, conditions: newConditions },\n });\n };\n\n const removeCondition = (index: number) => {\n if (!pipeRunIf) return;\n if (pipeRunIf.when.conditions.length <= 1) {\n field.setValue(null);\n return;\n }\n const newConditions = pipeRunIf.when.conditions.filter((_, i) => i !== index);\n field.setValue({\n ...pipeRunIf,\n when: { ...pipeRunIf.when, conditions: newConditions },\n });\n };\n\n const addCondition = () => {\n if (!pipeRunIf) return;\n field.setValue({\n ...pipeRunIf,\n when: {\n ...pipeRunIf.when,\n conditions: [...pipeRunIf.when.conditions, { ...EMPTY_CONDITION }],\n },\n });\n };\n\n const changeLogic = (logic: \"and\" | \"or\") => {\n if (!pipeRunIf) return;\n field.setValue({\n ...pipeRunIf,\n when: { ...pipeRunIf.when, logic },\n });\n };\n\n return (\n <div data-p0=\"input\">\n {!pipeRunIf ? (\n <div className=\"pz:flex pz:items-center\">\n <Button type=\"button\" variant=\"link\" size=\"xs\" className=\"pz:px-0\" onClick={addRunIf}>\n <IconPlus />\n New rule\n </Button>\n </div>\n ) : (\n <div className=\"pz:flex pz:flex-col pz:gap-8\">\n {pipeRunIf.when.conditions.map((condition, idx) => (\n <ConditionRow\n key={idx}\n condition={condition}\n index={idx}\n eligibleFields={eligibleFields}\n fieldsByName={fieldsByName}\n isFirst={idx === 0}\n isLast={idx === pipeRunIf.when.conditions.length - 1}\n logic={pipeRunIf.when.logic}\n form={field.form}\n basePath={field.path}\n onUpdate={updateCondition}\n onRemove={removeCondition}\n onAddCondition={addCondition}\n onLogicChange={changeLogic}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pipes-run-if-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/pipes-run-if-input.tsx"],"sourcesContent":["import {\n type ConditionBlockMeta,\n type ConditionOperators,\n type ConstantSuggestion,\n type PipeRunIf,\n type PipesFieldDefinitionWithName,\n type PipesRunIfMeta,\n type RecordFieldType,\n RUN_IF_OPERATOR_LABELS,\n RUN_IF_STATUS_OPERATORS,\n RUN_IF_VALUE_OPERATORS,\n type SecretSuggestion,\n} from \"@pipe0/base\";\nimport { useCallback, useMemo } from \"react\";\nimport { useFieldError } from \"../../../hooks/use-field-error.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport type { FormHandle } from \"../../../types/form-handle.js\";\nimport { HoverInfo } from \"../../hover-info.js\";\nimport { FieldLegend } from \"../../internal/field-legend.js\";\nimport { IconPlus } from \"../../internal/icons.js\";\nimport { LiquidEditor } from \"../../internal/LiquidEditor/LiquidEditor.js\";\nimport { Badge } from \"../../ui/badge.js\";\nimport { Button } from \"../../ui/button.js\";\nimport { Input } from \"../../ui/input.js\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../ui/select.js\";\nimport { FieldSectionEnumeration } from \"../field-section-enumeration.js\";\n\n// Use a loose type for internal manipulation since the discriminated union\n// is strict about property/operator/value combinations.\ntype Condition = {\n field_name: string;\n property: string;\n operator: string;\n value: unknown;\n};\n\n// Loose shape of a bare condition block ({logic, conditions}) — the run-if\n// `when` block, and an effect's `config.where`. The editor below is shared by\n// both; the strict discriminated-union types live in @pipe0/base.\ntype ConditionBlockValue = {\n logic: \"and\" | \"or\";\n conditions: Condition[];\n};\n\nconst OPERATORS_BY_TYPE: Record<RecordFieldType, ConditionOperators[]> = {\n string: [\"eq\", \"neq\", \"contains\", \"matches\"],\n number: [\"eq\", \"neq\", \"gt\", \"gte\", \"lt\", \"lte\"],\n boolean: [\"eq\", \"neq\"],\n json: [],\n unknown: [],\n};\n\nconst EMPTY_CONDITION: Condition = {\n field_name: \"\",\n property: \"value\",\n operator: \"eq\",\n value: \"\",\n};\n\nconst CONNECTOR_GAP = 32;\n\ntype MetaField = {\n fieldName: string;\n fieldLabel: string;\n type: RecordFieldType;\n format: string | null;\n};\n\nfunction ConditionRow({\n condition,\n index,\n eligibleFields,\n fieldsByName,\n isFirst,\n isLast,\n logic,\n form,\n conditionsPath,\n fieldNameMode,\n fieldNamePlaceholder,\n showStatusProperty,\n inputFields,\n searchSecrets,\n searchConstants,\n onUpdate,\n onRemove,\n onAddCondition,\n onLogicChange,\n}: {\n condition: Condition;\n index: number;\n eligibleFields: MetaField[];\n fieldsByName: ReadonlyMap<string, MetaField>;\n isFirst: boolean;\n isLast: boolean;\n logic: PipeRunIf[\"when\"][\"logic\"];\n form: FormHandle;\n conditionsPath: string;\n fieldNameMode: \"select\" | \"text\";\n fieldNamePlaceholder?: string;\n showStatusProperty: boolean;\n inputFields?: PipesFieldDefinitionWithName[];\n searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;\n searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;\n onUpdate: (index: number, condition: Condition) => void;\n onRemove: (index: number) => void;\n onAddCondition: () => void;\n onLogicChange: (logic: PipeRunIf[\"when\"][\"logic\"]) => void;\n}) {\n const conditionPath = `${conditionsPath}.${index}`;\n const valueError = useFieldError(form, `${conditionPath}.value`);\n const fieldNameError = useFieldError(form, `${conditionPath}.field_name`);\n const operatorError = useFieldError(form, `${conditionPath}.operator`);\n const propertyError = useFieldError(form, `${conditionPath}.property`);\n\n const showConnector = !(isFirst && isLast);\n const isTextMode = fieldNameMode === \"text\";\n const hasEligibleFields = eligibleFields.length > 0;\n const selectedField = condition.field_name ? fieldsByName.get(condition.field_name) : undefined;\n\n const availableOperators = useMemo(() => {\n if (condition.property === \"status\") {\n return RUN_IF_STATUS_OPERATORS.map((op) => ({\n value: op,\n label: RUN_IF_OPERATOR_LABELS[op],\n }));\n }\n const valueOperators = RUN_IF_VALUE_OPERATORS.map((op) => ({\n value: op,\n label: RUN_IF_OPERATOR_LABELS[op],\n }));\n // Free-text field names target a sheet whose column types are unknown —\n // offer the full operator set.\n if (isTextMode) return valueOperators;\n if (!selectedField?.type) return [];\n return valueOperators.filter((op) => OPERATORS_BY_TYPE[selectedField.type].includes(op.value));\n }, [condition.property, selectedField, isTextMode]);\n\n const renderValueInput = () => {\n if (!isTextMode && (!condition.field_name || !selectedField)) {\n return <Input className=\"pz:w-32\" placeholder=\"\" disabled aria-invalid={!!valueError} />;\n }\n\n if (isTextMode && condition.property !== \"status\") {\n if (inputFields) {\n return (\n <div\n className={cn(\n \"pz:w-64 pz:rounded-md pz:border pz:border-input pz:bg-transparent\",\n valueError && \"pz:border-destructive\",\n )}\n >\n <LiquidEditor\n value={String(condition.value ?? \"\")}\n onChange={(v) => onUpdate(index, { ...condition, value: v })}\n inputFields={inputFields}\n searchSecrets={searchSecrets}\n searchConstants={searchConstants}\n placeholder=\"\"\n hideLegend\n />\n </div>\n );\n }\n return (\n <Input\n className=\"pz:w-32\"\n aria-invalid={!!valueError}\n value={String(condition.value ?? \"\")}\n onChange={(e) => onUpdate(index, { ...condition, value: e.target.value })}\n placeholder=\"\"\n />\n );\n }\n\n if (condition.property === \"status\") {\n return (\n <Select\n value={String(condition.value) || null}\n onValueChange={(v) => onUpdate(index, { ...condition, value: v })}\n >\n <SelectTrigger className=\"pz:w-32\" aria-invalid={!!valueError}>\n <SelectValue placeholder=\"--status--\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"completed\">completed</SelectItem>\n <SelectItem value=\"skipped\">skipped</SelectItem>\n <SelectItem value=\"failed\">failed</SelectItem>\n <SelectItem value=\"no_result\">no_result</SelectItem>\n </SelectContent>\n </Select>\n );\n }\n\n if (selectedField?.type === \"boolean\") {\n return (\n <Select\n value={String(condition.value)}\n onValueChange={(v) => onUpdate(index, { ...condition, value: v })}\n >\n <SelectTrigger className=\"pz:w-24\" aria-invalid={!!valueError}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"true\">true</SelectItem>\n <SelectItem value=\"false\">false</SelectItem>\n </SelectContent>\n </Select>\n );\n }\n\n if (selectedField?.type === \"number\") {\n return (\n <Input\n type=\"number\"\n className=\"pz:w-32\"\n aria-invalid={!!valueError}\n value={String(Number(condition.value ?? 0))}\n onChange={(e) =>\n onUpdate(index, {\n ...condition,\n value: Number(e.target.value) || 0,\n })\n }\n placeholder=\"\"\n />\n );\n }\n\n return (\n <Input\n className=\"pz:w-32\"\n aria-invalid={!!valueError}\n value={String(condition.value ?? \"\")}\n onChange={(e) => onUpdate(index, { ...condition, value: e.target.value })}\n placeholder=\"\"\n />\n );\n };\n\n const errorMessage = valueError || fieldNameError || operatorError || propertyError;\n\n return (\n <div>\n <div className={cn(\"pz:relative\", showConnector && \"pz:pl-17\")}>\n {showConnector && (\n <>\n {isFirst ? (\n <div\n className=\"pz:absolute pz:left-7 pz:w-10 pz:border-l-2 pz:border-t-2 pz:border-input pz:rounded-tl-lg pz:pointer-events-none\"\n style={{ top: \"50%\", bottom: -CONNECTOR_GAP }}\n />\n ) : (\n <div\n className=\"pz:absolute pz:left-7 pz:w-10 pz:border-l-2 pz:border-b-2 pz:border-input pz:rounded-bl-lg pz:pointer-events-none\"\n style={{ top: -CONNECTOR_GAP, bottom: \"50%\" }}\n />\n )}\n {!isFirst && !isLast && (\n <div\n className=\"pz:absolute pz:left-7 pz:border-l-2 pz:border-input pz:pointer-events-none\"\n style={{ top: \"50%\", bottom: -CONNECTOR_GAP }}\n />\n )}\n {!isFirst && (\n <div\n className=\"pz:absolute pz:left-7 pz:z-10\"\n style={{\n top: -CONNECTOR_GAP / 2,\n transform: \"translate(-50%, -50%)\",\n }}\n >\n <Select value={logic} onValueChange={(v) => onLogicChange(v as \"and\" | \"or\")}>\n <SelectTrigger className=\"pz:w-17 pz:h-6 pz:text-xs pz:bg-background pz:hover:bg-accent\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n <SelectItem value=\"and\">AND</SelectItem>\n <SelectItem value=\"or\">OR</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n </div>\n )}\n </>\n )}\n <div className=\"pz:flex pz:flex-wrap pz:items-center pz:gap-2\">\n <FieldSectionEnumeration index={index} onRemove={onRemove} />\n {isTextMode ? (\n <Input\n className=\"pz:w-40\"\n aria-invalid={!!fieldNameError}\n value={condition.field_name}\n onChange={(e) => onUpdate(index, { ...condition, field_name: e.target.value })}\n placeholder={fieldNamePlaceholder ?? \"column\"}\n />\n ) : (\n <>\n <Select\n value={condition.field_name || null}\n disabled={!hasEligibleFields}\n onValueChange={(v) => {\n if (v === null) return;\n onUpdate(index, {\n ...condition,\n field_name: v,\n operator: \"eq\",\n value: \"\",\n });\n }}\n >\n <SelectTrigger className=\"pz:w-40\" aria-invalid={!!fieldNameError}>\n <SelectValue placeholder=\"Select field\" />\n </SelectTrigger>\n <SelectContent>\n {eligibleFields.map((f) => (\n <SelectItem key={f.fieldName} value={f.fieldName}>\n {f.fieldLabel || f.fieldName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {!hasEligibleFields && (\n <span className=\"pz:text-xs pz:text-muted-foreground\">\n No fields available{\" \"}\n <HoverInfo>\n Conditions require plain fields. JSON fields are not allowed.\n </HoverInfo>\n </span>\n )}\n </>\n )}\n\n {(isTextMode || selectedField?.type) && (\n <>\n {showStatusProperty && (\n <>\n <Badge\n variant=\"secondary\"\n className=\"pz:bg-accent pz:border pz:border-input pz:font-normal pz:text-muted-foreground pz:h-8\"\n >\n &apos;s\n </Badge>\n <Select\n defaultValue=\"value\"\n value={condition.property}\n onValueChange={(v) => {\n if (v === null) return;\n onUpdate(index, {\n ...condition,\n property: v,\n operator: \"eq\",\n value: \"\",\n });\n }}\n >\n <SelectTrigger className=\"pz:w-28\" aria-invalid={!!propertyError}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"value\">value</SelectItem>\n <SelectItem value=\"status\">status</SelectItem>\n </SelectContent>\n </Select>\n </>\n )}\n\n <Select\n value={condition.operator}\n onValueChange={(v) =>\n onUpdate(index, {\n ...condition,\n operator: v as ConditionOperators,\n })\n }\n >\n <SelectTrigger className=\"pz:w-28\" aria-invalid={!!operatorError}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {availableOperators.map((op) => (\n <SelectItem key={op.value} value={op.value}>\n {op.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {renderValueInput()}\n </>\n )}\n </div>\n {errorMessage && (\n <span\n className=\"pz:text-destructive pz:text-xs pz:font-medium pz:mt-1 pz:block\"\n role=\"alert\"\n >\n {errorMessage}\n </span>\n )}\n </div>\n {isLast && (\n <div className=\"pz:flex pz:items-center pz:gap-2\">\n <Button type=\"button\" variant=\"link\" size=\"xs\" onClick={onAddCondition}>\n <IconPlus />\n New rule\n </Button>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Presentational condition-block editor shared by the pipe run-if gate and by\n * effects that filter rows by a condition (e.g. `rows:remove@1`'s `where`).\n * Operates on a bare `{logic, conditions}` block via `value`/`onChange`; the\n * wrapping adapters own where that block lives in their payload.\n */\nexport function ConditionBlockEditor({\n value,\n onChange,\n fields,\n form,\n conditionsPath,\n fieldNameMode = \"select\",\n fieldNamePlaceholder,\n properties,\n inputFields,\n searchSecrets,\n searchConstants,\n}: {\n value: ConditionBlockValue | null;\n onChange: (value: ConditionBlockValue | null) => void;\n fields: MetaField[];\n form: FormHandle;\n // Field-error path of the conditions array (e.g. `run_if.when.conditions` or\n // `config.where.conditions`).\n conditionsPath: string;\n // \"text\" renders field_name as a free-form column name (the condition\n // targets a sheet whose columns are unknown at config time).\n fieldNameMode?: \"select\" | \"text\";\n fieldNamePlaceholder?: string;\n // Which condition properties are offered; defaults to value + status.\n properties?: (\"value\" | \"status\")[];\n // When present, string values render a LiquidEditor with the `/` picker.\n inputFields?: PipesFieldDefinitionWithName[];\n searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;\n searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;\n}) {\n // Built once and reused across every condition row, instead of each row\n // scanning `fields` linearly. With N rows and M fields this turns O(N·M)\n // lookups into O(N+M).\n const eligibleFields = useMemo(\n () => fields.filter((f) => OPERATORS_BY_TYPE[f.type].length > 0),\n [fields],\n );\n const fieldsByName = useMemo(() => new Map(fields.map((f) => [f.fieldName, f])), [fields]);\n\n const addBlock = useCallback(() => {\n onChange({ logic: \"and\", conditions: [{ ...EMPTY_CONDITION }] });\n }, [onChange]);\n\n const updateCondition = (index: number, condition: Condition) => {\n if (!value) return;\n const newConditions = [...value.conditions];\n newConditions[index] = condition;\n onChange({ ...value, conditions: newConditions });\n };\n\n const removeCondition = (index: number) => {\n if (!value) return;\n if (value.conditions.length <= 1) {\n onChange(null);\n return;\n }\n onChange({ ...value, conditions: value.conditions.filter((_, i) => i !== index) });\n };\n\n const addCondition = () => {\n if (!value) return;\n onChange({ ...value, conditions: [...value.conditions, { ...EMPTY_CONDITION }] });\n };\n\n const changeLogic = (logic: \"and\" | \"or\") => {\n if (!value) return;\n onChange({ ...value, logic });\n };\n\n return (\n <div data-p0=\"input\">\n {!value ? (\n <div className=\"pz:flex pz:items-center\">\n <Button type=\"button\" variant=\"link\" size=\"xs\" className=\"pz:px-0\" onClick={addBlock}>\n <IconPlus />\n New rule\n </Button>\n </div>\n ) : (\n <div className=\"pz:flex pz:flex-col pz:gap-8\">\n {value.conditions.map((condition, idx) => (\n <ConditionRow\n key={idx}\n condition={condition}\n index={idx}\n eligibleFields={eligibleFields}\n fieldsByName={fieldsByName}\n isFirst={idx === 0}\n isLast={idx === value.conditions.length - 1}\n logic={value.logic}\n form={form}\n conditionsPath={conditionsPath}\n fieldNameMode={fieldNameMode}\n fieldNamePlaceholder={fieldNamePlaceholder}\n showStatusProperty={(properties ?? [\"value\", \"status\"]).includes(\"status\")}\n inputFields={inputFields}\n searchSecrets={searchSecrets}\n searchConstants={searchConstants}\n onUpdate={updateCondition}\n onRemove={removeCondition}\n onAddCondition={addCondition}\n onLogicChange={changeLogic}\n />\n ))}\n {fieldNameMode === \"text\" && inputFields && (\n <FieldLegend entries={[{ key: \"/\", label: \"to insert a reference\" }]} />\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport function PipesRunIfInputAdapter(field: FieldHandle<\"pipes_run_if_input\">) {\n const pipeRunIf = field.value as PipeRunIf | null;\n const meta = field.meta as PipesRunIfMeta;\n\n return (\n <ConditionBlockEditor\n value={(pipeRunIf?.when as ConditionBlockValue | undefined) ?? null}\n onChange={(block) => field.setValue(block ? { action: \"run\", when: block } : null)}\n fields={meta.fields}\n form={field.form}\n conditionsPath={`${field.path}.when.conditions`}\n />\n );\n}\n\nexport function ConditionBlockInputAdapter(field: FieldHandle<\"condition_block_input\">) {\n const block = field.value as ConditionBlockValue | null;\n const meta = field.meta as ConditionBlockMeta;\n\n return (\n <ConditionBlockEditor\n value={block}\n onChange={(next) => field.setValue(next)}\n fields={meta.fields}\n form={field.form}\n conditionsPath={`${field.path}.conditions`}\n fieldNameMode={meta.fieldNameMode}\n fieldNamePlaceholder={meta.fieldNamePlaceholder}\n properties={meta.properties}\n inputFields={meta.inputFields}\n searchSecrets={field.searchSecrets}\n searchConstants={field.searchConstants}\n />\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"providers-input.mjs","names":["XIcon","SearchIcon"],"sources":["../../../../src/components/defaults/adapters/providers-input.tsx"],"sourcesContent":["import {\n closestCenter,\n DndContext,\n type DragEndEvent,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport { SortableContext, useSortable, verticalListSortingStrategy } from \"@dnd-kit/sortable\";\nimport type { ProviderName, WidgetsByKind } from \"@pipe0/base\";\nimport { Search as SearchIcon, X as XIcon } from \"lucide-react\";\nimport { type CSSProperties, useMemo, useState } from \"react\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { AvatarGroup } from \"../../../widgets/avatar-group.js\";\nimport { PricingBadge } from \"../../../widgets/pricing-badge.js\";\nimport { WidgetStrip } from \"../../../widgets/widget-strip.js\";\nimport { IconGripVertical, IconPlus } from \"../../internal/icons.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../ui/popover.js\";\n\ntype ProviderOption = {\n value: string;\n label: string;\n widgets?: WidgetsByKind;\n};\n\nfunction splitWidgets(widgets: WidgetsByKind | undefined): {\n providerName: ProviderName | undefined;\n leading: WidgetsByKind | undefined;\n pricing: WidgetsByKind[\"pricing\"] | undefined;\n} {\n if (!widgets) return { providerName: undefined, leading: undefined, pricing: undefined };\n const { pricing, provider_logo, ...rest } = widgets;\n const hasLeading = Object.values(rest).some((v) => v != null);\n return {\n providerName: provider_logo?.provider,\n leading: hasLeading ? rest : undefined,\n pricing,\n };\n}\n\nfunction LeadingAvatar({\n providerName,\n leading,\n}: {\n providerName: ProviderName | undefined;\n leading: WidgetsByKind | undefined;\n}) {\n if (providerName) {\n return <AvatarGroup providers={[providerName]} size=\"sm\" className=\"pz:shrink-0\" />;\n }\n if (leading) {\n return (\n <span className=\"pz:flex pz:items-center pz:shrink-0\">\n <WidgetStrip widgets={leading} size={18} />\n </span>\n );\n }\n return null;\n}\n\n/**\n * Provider waterfall — vertical, ordered list of providers tried sequentially\n * until a valid result is returned. The list makes the running order legible\n * (numeric badge per row, drag-to-reorder), and the credit widget per\n * provider stays visible.\n */\nexport function ProvidersInputAdapter(field: FieldHandle<\"providers_input\">) {\n const selected: string[] = useMemo(\n () => (field.value ?? []).map((p: { provider: string }) => p.provider),\n [field.value],\n );\n\n const options = field.options ?? [];\n const optionByValue = useMemo(() => {\n const map = new Map<string, ProviderOption>();\n for (const o of options) map.set(o.value, o);\n return map;\n }, [options]);\n\n const maxItems = field.meta.maxItems;\n const atMax = maxItems !== undefined && selected.length >= maxItems;\n\n const setValue = (next: string[]) =>\n field.setValue(next.map((provider) => ({ provider })));\n\n const handleRemove = (value: string) => setValue(selected.filter((v) => v !== value));\n const handleAdd = (value: string) => {\n if (selected.includes(value)) return;\n setValue([...selected, value]);\n };\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor),\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n const from = selected.indexOf(String(active.id));\n const to = selected.indexOf(String(over.id));\n if (from === -1 || to === -1) return;\n const next = [...selected];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n setValue(next);\n };\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-1\">\n {selected.length > 0 && (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext items={selected} strategy={verticalListSortingStrategy}>\n <ul className=\"pz:flex pz:flex-col pz:gap-0.5 pz:list-none pz:m-0 pz:p-0\">\n {selected.map((value, index) => {\n const option = optionByValue.get(value);\n return (\n <ProviderRow\n key={value}\n value={value}\n index={index}\n label={option?.label ?? value}\n widgets={option?.widgets}\n onRemove={() => handleRemove(value)}\n />\n );\n })}\n </ul>\n </SortableContext>\n </DndContext>\n )}\n {!atMax && (\n <AddProviderControl\n options={options}\n excluded={selected}\n onAdd={handleAdd}\n ariaInvalid={!!field.error}\n />\n )}\n </div>\n );\n}\n\nfunction ProviderRow({\n value,\n index,\n label,\n widgets,\n onRemove,\n}: {\n value: string;\n index: number;\n label: string;\n widgets?: WidgetsByKind;\n onRemove: () => void;\n}) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n });\n const style: CSSProperties = {\n transform: transform\n ? `translate3d(${Math.round(transform.x)}px, ${Math.round(transform.y)}px, 0)`\n : undefined,\n transition,\n opacity: isDragging ? 0.6 : 1,\n };\n\n const { providerName, leading, pricing } = splitWidgets(widgets);\n const orderLabel = String(index + 1);\n\n return (\n <li\n ref={setNodeRef}\n style={style}\n className={cn(\n \"pz:group/prov pz:flex pz:items-center pz:gap-2.5 pz:rounded-md pz:px-1.5 pz:py-1.5\",\n \"pz:hover:bg-muted/60 pz:transition-colors\",\n )}\n {...attributes}\n >\n <button\n type=\"button\"\n aria-label=\"Drag to reorder\"\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-4 pz:cursor-grab pz:touch-none\",\n \"pz:text-muted-foreground/60 pz:hover:text-foreground pz:transition-colors\",\n )}\n {...listeners}\n >\n <IconGripVertical width={11} height={14} />\n </button>\n <LeadingAvatar providerName={providerName} leading={leading} />\n <span className=\"pz:text-sm pz:font-medium pz:text-foreground pz:flex-1 pz:truncate\">\n {label}\n </span>\n {pricing && <PricingBadge credits={pricing.credits} />}\n <span\n aria-hidden\n className={cn(\n \"pz:inline-flex pz:items-center pz:justify-center pz:min-w-7 pz:h-5 pz:px-1.5\",\n \"pz:rounded-full pz:bg-muted pz:text-muted-foreground pz:text-[10.5px]\",\n \"pz:font-medium pz:tabular-nums\",\n )}\n >\n {orderLabel}\n </span>\n <button\n type=\"button\"\n aria-label={`Remove ${label}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-5 pz:rounded\",\n \"pz:text-muted-foreground/70\",\n \"pz:hover:bg-destructive/10 pz:hover:text-destructive pz:transition-colors\",\n )}\n >\n <XIcon className=\"pz:size-3\" />\n </button>\n </li>\n );\n}\n\nfunction AddProviderControl({\n options,\n excluded,\n onAdd,\n ariaInvalid,\n}: {\n options: ProviderOption[];\n excluded: string[];\n onAdd: (value: string) => void;\n ariaInvalid?: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const excludedSet = useMemo(() => new Set(excluded), [excluded]);\n const available = useMemo(\n () => options.filter((o) => !excludedSet.has(o.value)),\n [options, excludedSet],\n );\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return available;\n return available.filter(\n (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q),\n );\n }, [available, query]);\n\n if (available.length === 0 && excluded.length === 0) {\n return (\n <div className=\"pz:text-xs pz:text-muted-foreground pz:px-1.5 pz:py-2\">\n No providers available\n </div>\n );\n }\n\n if (available.length === 0) return null;\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) setQuery(\"\");\n }}\n >\n <PopoverTrigger\n aria-invalid={ariaInvalid || undefined}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:gap-1.5 pz:w-full\",\n \"pz:px-2.5 pz:py-1.5 pz:mt-1 pz:rounded-md\",\n \"pz:border pz:border-dashed pz:border-input pz:bg-transparent\",\n \"pz:text-xs pz:text-muted-foreground\",\n \"pz:hover:bg-muted/60 pz:hover:text-foreground pz:hover:border-muted-foreground/40\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <IconPlus width={12} height={12} />\n Add provider\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"pz:w-(--anchor-width) pz:p-0 pz:gap-0\">\n <div className=\"pz:flex pz:items-center pz:gap-1.5 pz:px-2.5 pz:py-2 pz:border-b pz:border-border\">\n <SearchIcon className=\"pz:size-3.5 pz:text-muted-foreground pz:shrink-0\" />\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search providers…\"\n // biome-ignore lint/a11y/noAutofocus: popover-scoped picker\n autoFocus\n className=\"pz:flex-1 pz:bg-transparent pz:outline-none pz:text-sm pz:placeholder:text-muted-foreground/70\"\n />\n </div>\n <ul className=\"pz:flex pz:flex-col pz:p-1 pz:max-h-72 pz:overflow-auto pz:list-none pz:m-0\">\n {filtered.length === 0 && (\n <li className=\"pz:px-2 pz:py-3 pz:text-center pz:text-xs pz:text-muted-foreground\">\n No providers\n </li>\n )}\n {filtered.map((option) => {\n const { providerName, leading, pricing } = splitWidgets(option.widgets);\n return (\n <li key={option.value} className=\"pz:contents\">\n <button\n type=\"button\"\n onClick={() => {\n onAdd(option.value);\n setOpen(false);\n setQuery(\"\");\n }}\n className={cn(\n \"pz:flex pz:items-center pz:gap-2 pz:w-full pz:text-left\",\n \"pz:px-2 pz:py-1.5 pz:rounded-md pz:text-sm\",\n \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <LeadingAvatar providerName={providerName} leading={leading} />\n <span className=\"pz:flex-1 pz:truncate\">{option.label}</span>\n {pricing && <PricingBadge credits={pricing.credits} />}\n </button>\n </li>\n );\n })}\n </ul>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"providers-input.mjs","names":["XIcon","SearchIcon"],"sources":["../../../../src/components/defaults/adapters/providers-input.tsx"],"sourcesContent":["import {\n closestCenter,\n DndContext,\n type DragEndEvent,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport { SortableContext, useSortable, verticalListSortingStrategy } from \"@dnd-kit/sortable\";\nimport type { ProviderName, WidgetsByKind } from \"@pipe0/base\";\nimport { Search as SearchIcon, X as XIcon } from \"lucide-react\";\nimport { type CSSProperties, useMemo, useState } from \"react\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { AvatarGroup } from \"../../../widgets/avatar-group.js\";\nimport { PricingBadge } from \"../../../widgets/pricing-badge.js\";\nimport { WidgetStrip } from \"../../../widgets/widget-strip.js\";\nimport { IconGripVertical, IconPlus } from \"../../internal/icons.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../../ui/popover.js\";\n\ntype ProviderOption = {\n value: string;\n label: string;\n widgets?: WidgetsByKind;\n};\n\nfunction splitWidgets(widgets: WidgetsByKind | undefined): {\n providerName: ProviderName | undefined;\n leading: WidgetsByKind | undefined;\n pricing: WidgetsByKind[\"pricing\"] | undefined;\n} {\n if (!widgets) return { providerName: undefined, leading: undefined, pricing: undefined };\n const { pricing, provider_logo, ...rest } = widgets;\n const hasLeading = Object.values(rest).some((v) => v != null);\n return {\n providerName: provider_logo?.provider,\n leading: hasLeading ? rest : undefined,\n pricing,\n };\n}\n\nfunction LeadingAvatar({\n providerName,\n leading,\n}: {\n providerName: ProviderName | undefined;\n leading: WidgetsByKind | undefined;\n}) {\n if (providerName) {\n return <AvatarGroup providers={[providerName]} size=\"sm\" className=\"pz:shrink-0\" />;\n }\n if (leading) {\n return (\n <span className=\"pz:flex pz:items-center pz:shrink-0\">\n <WidgetStrip widgets={leading} size={18} />\n </span>\n );\n }\n return null;\n}\n\n/**\n * Provider waterfall — vertical, ordered list of providers tried sequentially\n * until a valid result is returned. The list makes the running order legible\n * (numeric badge per row, drag-to-reorder), and the credit widget per\n * provider stays visible.\n */\nexport function ProvidersInputAdapter(field: FieldHandle<\"providers_input\">) {\n const selected: string[] = useMemo(\n () => (field.value ?? []).map((p: { provider: string }) => p.provider),\n [field.value],\n );\n\n const options = field.options ?? [];\n const optionByValue = useMemo(() => {\n const map = new Map<string, ProviderOption>();\n for (const o of options) map.set(o.value, o);\n return map;\n }, [options]);\n\n const maxItems = field.meta.maxItems;\n const atMax = maxItems !== undefined && selected.length >= maxItems;\n\n const setValue = (next: string[]) => field.setValue(next.map((provider) => ({ provider })));\n\n const handleRemove = (value: string) => setValue(selected.filter((v) => v !== value));\n const handleAdd = (value: string) => {\n if (selected.includes(value)) return;\n setValue([...selected, value]);\n };\n\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor),\n );\n\n const handleDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n const from = selected.indexOf(String(active.id));\n const to = selected.indexOf(String(over.id));\n if (from === -1 || to === -1) return;\n const next = [...selected];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n setValue(next);\n };\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-1\">\n {selected.length > 0 && (\n <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>\n <SortableContext items={selected} strategy={verticalListSortingStrategy}>\n <ul className=\"pz:flex pz:flex-col pz:gap-0.5 pz:list-none pz:m-0 pz:p-0\">\n {selected.map((value, index) => {\n const option = optionByValue.get(value);\n return (\n <ProviderRow\n key={value}\n value={value}\n index={index}\n label={option?.label ?? value}\n widgets={option?.widgets}\n onRemove={() => handleRemove(value)}\n />\n );\n })}\n </ul>\n </SortableContext>\n </DndContext>\n )}\n {!atMax && (\n <AddProviderControl\n options={options}\n excluded={selected}\n onAdd={handleAdd}\n ariaInvalid={!!field.error}\n />\n )}\n </div>\n );\n}\n\nfunction ProviderRow({\n value,\n index,\n label,\n widgets,\n onRemove,\n}: {\n value: string;\n index: number;\n label: string;\n widgets?: WidgetsByKind;\n onRemove: () => void;\n}) {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n });\n const style: CSSProperties = {\n transform: transform\n ? `translate3d(${Math.round(transform.x)}px, ${Math.round(transform.y)}px, 0)`\n : undefined,\n transition,\n opacity: isDragging ? 0.6 : 1,\n };\n\n const { providerName, leading, pricing } = splitWidgets(widgets);\n const orderLabel = String(index + 1);\n\n return (\n <li\n ref={setNodeRef}\n style={style}\n className={cn(\n \"pz:group/prov pz:flex pz:items-center pz:gap-2.5 pz:rounded-md pz:px-1.5 pz:py-1.5\",\n \"pz:hover:bg-muted/60 pz:transition-colors\",\n )}\n {...attributes}\n >\n <button\n type=\"button\"\n aria-label=\"Drag to reorder\"\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-4 pz:cursor-grab pz:touch-none\",\n \"pz:text-muted-foreground/60 pz:hover:text-foreground pz:transition-colors\",\n )}\n {...listeners}\n >\n <IconGripVertical width={11} height={14} />\n </button>\n <LeadingAvatar providerName={providerName} leading={leading} />\n <span className=\"pz:text-sm pz:font-medium pz:text-foreground pz:flex-1 pz:truncate\">\n {label}\n </span>\n {pricing && <PricingBadge credits={pricing.credits} />}\n <span\n aria-hidden\n className={cn(\n \"pz:inline-flex pz:items-center pz:justify-center pz:min-w-7 pz:h-5 pz:px-1.5\",\n \"pz:rounded-full pz:bg-muted pz:text-muted-foreground pz:text-[10.5px]\",\n \"pz:font-medium pz:tabular-nums\",\n )}\n >\n {orderLabel}\n </span>\n <button\n type=\"button\"\n aria-label={`Remove ${label}`}\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:size-5 pz:rounded\",\n \"pz:text-muted-foreground/70\",\n \"pz:hover:bg-destructive/10 pz:hover:text-destructive pz:transition-colors\",\n )}\n >\n <XIcon className=\"pz:size-3\" />\n </button>\n </li>\n );\n}\n\nfunction AddProviderControl({\n options,\n excluded,\n onAdd,\n ariaInvalid,\n}: {\n options: ProviderOption[];\n excluded: string[];\n onAdd: (value: string) => void;\n ariaInvalid?: boolean;\n}) {\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n\n const excludedSet = useMemo(() => new Set(excluded), [excluded]);\n const available = useMemo(\n () => options.filter((o) => !excludedSet.has(o.value)),\n [options, excludedSet],\n );\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return available;\n return available.filter(\n (o) => o.label.toLowerCase().includes(q) || o.value.toLowerCase().includes(q),\n );\n }, [available, query]);\n\n if (available.length === 0 && excluded.length === 0) {\n return (\n <div className=\"pz:text-xs pz:text-muted-foreground pz:px-1.5 pz:py-2\">\n No providers available\n </div>\n );\n }\n\n if (available.length === 0) return null;\n\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n setOpen(next);\n if (!next) setQuery(\"\");\n }}\n >\n <PopoverTrigger\n aria-invalid={ariaInvalid || undefined}\n className={cn(\n \"pz:flex pz:items-center pz:justify-center pz:gap-1.5 pz:w-full\",\n \"pz:px-2.5 pz:py-1.5 pz:mt-1 pz:rounded-md\",\n \"pz:border pz:border-dashed pz:border-input pz:bg-transparent\",\n \"pz:text-xs pz:text-muted-foreground\",\n \"pz:hover:bg-muted/60 pz:hover:text-foreground pz:hover:border-muted-foreground/40\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <IconPlus width={12} height={12} />\n Add provider\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"pz:w-(--anchor-width) pz:p-0 pz:gap-0\">\n <div className=\"pz:flex pz:items-center pz:gap-1.5 pz:px-2.5 pz:py-2 pz:border-b pz:border-border\">\n <SearchIcon className=\"pz:size-3.5 pz:text-muted-foreground pz:shrink-0\" />\n <input\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder=\"Search providers…\"\n // biome-ignore lint/a11y/noAutofocus: popover-scoped picker\n autoFocus\n className=\"pz:flex-1 pz:bg-transparent pz:outline-none pz:text-sm pz:placeholder:text-muted-foreground/70\"\n />\n </div>\n <ul className=\"pz:flex pz:flex-col pz:p-1 pz:max-h-72 pz:overflow-auto pz:list-none pz:m-0\">\n {filtered.length === 0 && (\n <li className=\"pz:px-2 pz:py-3 pz:text-center pz:text-xs pz:text-muted-foreground\">\n No providers\n </li>\n )}\n {filtered.map((option) => {\n const { providerName, leading, pricing } = splitWidgets(option.widgets);\n return (\n <li key={option.value} className=\"pz:contents\">\n <button\n type=\"button\"\n onClick={() => {\n onAdd(option.value);\n setOpen(false);\n setQuery(\"\");\n }}\n className={cn(\n \"pz:flex pz:items-center pz:gap-2 pz:w-full pz:text-left\",\n \"pz:px-2 pz:py-1.5 pz:rounded-md pz:text-sm\",\n \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n \"pz:transition-colors pz:cursor-pointer\",\n )}\n >\n <LeadingAvatar providerName={providerName} leading={leading} />\n <span className=\"pz:flex-1 pz:truncate\">{option.label}</span>\n {pricing && <PricingBadge credits={pricing.credits} />}\n </button>\n </li>\n );\n })}\n </ul>\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ //#region src/components/defaults/adapters/search-payload-input.tsx
2
+ /**
3
+ * Default adapter for the opaque `search_payload_input` slot.
4
+ *
5
+ * The shared library intentionally renders nothing for this kind — configuring
6
+ * a `SearchPayload` requires the full search catalog + search form UI, which
7
+ * lives in the consuming app (`apps/dash`), not in `@pipe0/react`. Consumers
8
+ * override this adapter via `<FormProvider adapters={...}>` / the `adapters`
9
+ * prop to render a real control (e.g. a button that opens the pick → configure
10
+ * flow). See `FieldExtras["search_payload_input"]`.
11
+ */
12
+ function SearchPayloadInputAdapter(_field) {
13
+ return null;
14
+ }
15
+
16
+ //#endregion
17
+ export { SearchPayloadInputAdapter };
18
+ //# sourceMappingURL=search-payload-input.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-payload-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/search-payload-input.tsx"],"sourcesContent":["import type { FieldHandle } from \"../../../types/field-handle.js\";\n\n/**\n * Default adapter for the opaque `search_payload_input` slot.\n *\n * The shared library intentionally renders nothing for this kind — configuring\n * a `SearchPayload` requires the full search catalog + search form UI, which\n * lives in the consuming app (`apps/dash`), not in `@pipe0/react`. Consumers\n * override this adapter via `<FormProvider adapters={...}>` / the `adapters`\n * prop to render a real control (e.g. a button that opens the pick → configure\n * flow). See `FieldExtras[\"search_payload_input\"]`.\n */\nexport function SearchPayloadInputAdapter(_field: FieldHandle<\"search_payload_input\">) {\n return null;\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,0BAA0B,QAA6C;AACrF,QAAO"}