@pipe0/react 0.1.7 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/components/compound/effect-catalog/card.d.mts +22 -0
- package/dist/components/compound/effect-catalog/card.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/card.mjs +82 -0
- package/dist/components/compound/effect-catalog/card.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/category-filter.d.mts +27 -0
- package/dist/components/compound/effect-catalog/category-filter.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/category-filter.mjs +61 -0
- package/dist/components/compound/effect-catalog/category-filter.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/empty.d.mts +17 -0
- package/dist/components/compound/effect-catalog/empty.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/empty.mjs +29 -0
- package/dist/components/compound/effect-catalog/empty.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/index.d.mts +6 -0
- package/dist/components/compound/effect-catalog/list.d.mts +19 -0
- package/dist/components/compound/effect-catalog/list.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/list.mjs +33 -0
- package/dist/components/compound/effect-catalog/list.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/root.d.mts +31 -0
- package/dist/components/compound/effect-catalog/root.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/root.mjs +67 -0
- package/dist/components/compound/effect-catalog/root.mjs.map +1 -0
- package/dist/components/compound/effect-catalog/search-filter.d.mts +21 -0
- package/dist/components/compound/effect-catalog/search-filter.d.mts.map +1 -0
- package/dist/components/compound/effect-catalog/search-filter.mjs +47 -0
- package/dist/components/compound/effect-catalog/search-filter.mjs.map +1 -0
- package/dist/components/compound/pipe-catalog/card.mjs +1 -1
- package/dist/components/compound/pipe-catalog/category-filter.mjs +1 -1
- package/dist/components/compound/pipe-catalog/provider-filter.mjs +1 -1
- package/dist/components/compound/pipe-catalog/root.mjs +1 -1
- package/dist/components/compound/pipe-form/content.d.mts +6 -1
- package/dist/components/compound/pipe-form/content.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/content.mjs +3 -2
- package/dist/components/compound/pipe-form/content.mjs.map +1 -1
- package/dist/components/compound/pipe-form/errors.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/errors.mjs +5 -4
- package/dist/components/compound/pipe-form/errors.mjs.map +1 -1
- package/dist/components/compound/pipe-form/root.d.mts +3 -1
- package/dist/components/compound/pipe-form/root.d.mts.map +1 -1
- package/dist/components/compound/pipe-form/root.mjs +5 -3
- package/dist/components/compound/pipe-form/root.mjs.map +1 -1
- package/dist/components/compound/search-catalog/active-filters.mjs +1 -1
- package/dist/components/compound/search-catalog/category-filter.mjs +1 -1
- package/dist/components/compound/search-catalog/provider-filter.mjs +1 -1
- package/dist/components/compound/search-form/content.d.mts +6 -1
- package/dist/components/compound/search-form/content.d.mts.map +1 -1
- package/dist/components/compound/search-form/content.mjs +3 -2
- package/dist/components/compound/search-form/content.mjs.map +1 -1
- package/dist/components/compound/search-form/errors.d.mts.map +1 -1
- package/dist/components/compound/search-form/errors.mjs +5 -4
- package/dist/components/compound/search-form/errors.mjs.map +1 -1
- package/dist/components/compound/search-form/root.d.mts +3 -1
- package/dist/components/compound/search-form/root.d.mts.map +1 -1
- package/dist/components/compound/search-form/root.mjs +5 -3
- package/dist/components/compound/search-form/root.mjs.map +1 -1
- package/dist/components/compound/searches-catalog/active-filters.mjs +1 -1
- package/dist/components/compound/searches-catalog/category-filter.mjs +1 -1
- package/dist/components/compound/searches-catalog/provider-filter.mjs +1 -1
- package/dist/components/defaults/adapters/context-select-input.mjs +1 -1
- package/dist/components/defaults/adapters/context-select-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/exact-range-input.mjs +1 -1
- package/dist/components/defaults/adapters/index.d.mts.map +1 -1
- package/dist/components/defaults/adapters/index.mjs +8 -5
- package/dist/components/defaults/adapters/index.mjs.map +1 -1
- package/dist/components/defaults/adapters/int-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/json-extraction-input.mjs +1 -1
- package/dist/components/defaults/adapters/loose-object-input.mjs +111 -0
- package/dist/components/defaults/adapters/loose-object-input.mjs.map +1 -0
- package/dist/components/defaults/adapters/pipes-run-if-input.mjs +69 -56
- package/dist/components/defaults/adapters/pipes-run-if-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/providers-input.mjs.map +1 -1
- package/dist/components/defaults/adapters/search-payload-input.mjs +18 -0
- package/dist/components/defaults/adapters/search-payload-input.mjs.map +1 -0
- package/dist/components/defaults/adapters/select-input.mjs +46 -27
- package/dist/components/defaults/adapters/select-input.mjs.map +1 -1
- package/dist/components/defaults/catalog/card-derived.d.mts +1 -1
- package/dist/components/defaults/catalog/card-derived.d.mts.map +1 -1
- package/dist/components/defaults/catalog/card-derived.mjs +12 -6
- package/dist/components/defaults/catalog/card-derived.mjs.map +1 -1
- package/dist/components/defaults/catalog/provider-avatars.mjs +3 -3
- package/dist/components/defaults/catalog/provider-avatars.mjs.map +1 -1
- package/dist/components/defaults/form/form-empty-state.mjs +23 -0
- package/dist/components/defaults/form/form-empty-state.mjs.map +1 -0
- package/dist/components/defaults/layout/field-wrapper.d.mts.map +1 -1
- package/dist/components/defaults/layout/field-wrapper.mjs +11 -5
- package/dist/components/defaults/layout/field-wrapper.mjs.map +1 -1
- package/dist/components/defaults/layout/group.mjs +1 -1
- package/dist/components/internal/LiquidEditor/LiquidEditor.mjs +2 -2
- package/dist/components/internal/LiquidEditor/LiquidEditor.mjs.map +1 -1
- package/dist/components/internal/form-level-errors.mjs +4 -3
- package/dist/components/internal/form-level-errors.mjs.map +1 -1
- package/dist/components/internal/icons.mjs +27 -1
- package/dist/components/internal/icons.mjs.map +1 -1
- package/dist/components/ui/alert.d.mts +47 -0
- package/dist/components/ui/alert.d.mts.map +1 -0
- package/dist/components/ui/alert.mjs +66 -0
- package/dist/components/ui/alert.mjs.map +1 -0
- package/dist/context/catalog-card-context.mjs +4 -2
- package/dist/context/catalog-card-context.mjs.map +1 -1
- package/dist/context/effect-catalog-card-context.d.mts +20 -0
- package/dist/context/effect-catalog-card-context.d.mts.map +1 -0
- package/dist/context/effect-catalog-card-context.mjs +13 -0
- package/dist/context/effect-catalog-card-context.mjs.map +1 -0
- package/dist/context/effect-catalog-context.d.mts +20 -0
- package/dist/context/effect-catalog-context.d.mts.map +1 -0
- package/dist/context/effect-catalog-context.mjs +13 -0
- package/dist/context/effect-catalog-context.mjs.map +1 -0
- package/dist/context/form-context.d.mts +21 -0
- package/dist/context/form-context.d.mts.map +1 -0
- package/dist/context/form-context.mjs +11 -1
- package/dist/context/form-context.mjs.map +1 -1
- package/dist/context/form-provider.d.mts +3 -1
- package/dist/context/form-provider.d.mts.map +1 -1
- package/dist/context/form-provider.mjs +8 -2
- package/dist/context/form-provider.mjs.map +1 -1
- package/dist/hooks/use-effect-catalog-table.d.mts +33 -0
- package/dist/hooks/use-effect-catalog-table.d.mts.map +1 -0
- package/dist/hooks/use-effect-catalog-table.mjs +104 -0
- package/dist/hooks/use-effect-catalog-table.mjs.map +1 -0
- package/dist/hooks/use-form-core.mjs +8 -5
- package/dist/hooks/use-form-core.mjs.map +1 -1
- package/dist/hooks/use-pipe-catalog-table.d.mts +8 -8
- package/dist/hooks/use-pipe-catalog-table.d.mts.map +1 -1
- package/dist/hooks/use-pipe-catalog-table.mjs +2 -2
- package/dist/hooks/use-pipe-catalog-table.mjs.map +1 -1
- package/dist/hooks/use-pipe-form.d.mts.map +1 -1
- package/dist/hooks/use-pipe-form.mjs +18 -19
- package/dist/hooks/use-pipe-form.mjs.map +1 -1
- package/dist/hooks/use-search-catalog-table.d.mts +6 -6
- package/dist/hooks/use-search-form.d.mts.map +1 -1
- package/dist/hooks/use-search-form.mjs +18 -18
- package/dist/hooks/use-search-form.mjs.map +1 -1
- package/dist/hooks/use-sheet-effect-form.d.mts +35 -0
- package/dist/hooks/use-sheet-effect-form.d.mts.map +1 -0
- package/dist/hooks/use-sheet-effect-form.mjs +103 -0
- package/dist/hooks/use-sheet-effect-form.mjs.map +1 -0
- package/dist/index.d.mts +15 -3
- package/dist/index.mjs +16 -4
- package/dist/styles/pipe0-form.css +1 -1
- package/dist/types/adapters.d.mts +22 -1
- package/dist/types/adapters.d.mts.map +1 -1
- package/dist/types/catalog-adapters.d.mts +23 -3
- package/dist/types/catalog-adapters.d.mts.map +1 -1
- package/dist/types/field-props.d.mts +15 -13
- package/dist/types/field-props.d.mts.map +1 -1
- package/dist/types/form-customization.d.mts +2 -25
- package/dist/utils/build-section-handlers.mjs +9 -75
- package/dist/utils/build-section-handlers.mjs.map +1 -1
- package/dist/utils/catalog-helpers.d.mts +1 -1
- package/dist/widgets/token-pricing-badge.d.mts +1 -0
- package/dist/widgets/token-pricing-badge.mjs +55 -0
- package/dist/widgets/token-pricing-badge.mjs.map +1 -0
- package/dist/widgets/widget-strip.d.mts.map +1 -1
- package/dist/widgets/widget-strip.mjs +1 -0
- package/dist/widgets/widget-strip.mjs.map +1 -1
- package/dist/widgets/widget-view.d.mts.map +1 -1
- package/dist/widgets/widget-view.mjs +6 -0
- package/dist/widgets/widget-view.mjs.map +1 -1
- package/package.json +15 -25
- package/dist/components/defaults/adapters/key-value-list-input.mjs +0 -102
- package/dist/components/defaults/adapters/key-value-list-input.mjs.map +0 -1
- package/dist/types/form-customization.d.mts.map +0 -1
|
@@ -12,19 +12,20 @@ import { IncludeExcludeSelectInputAdapter } from "./include-exclude-select-input
|
|
|
12
12
|
import { IntInputAdapter } from "./int-input.mjs";
|
|
13
13
|
import { JsonExtractionInputAdapter } from "./json-extraction-input.mjs";
|
|
14
14
|
import { JsonSchemaInputAdapter } from "./json-schema-input.mjs";
|
|
15
|
-
import {
|
|
15
|
+
import { LooseObjectInputAdapter } from "./loose-object-input.mjs";
|
|
16
16
|
import { MinMaxIntInputAdapter } from "./min-max-int-input.mjs";
|
|
17
17
|
import { MultiCreateInputAdapter } from "./multi-create-input.mjs";
|
|
18
18
|
import { MultiSelectInputAdapter } from "./multi-select-input.mjs";
|
|
19
19
|
import { NumberInputAdapter } from "./number-input.mjs";
|
|
20
20
|
import { OrderedMultiCreateInputAdapter } from "./ordered-multi-create-input.mjs";
|
|
21
|
-
import { TaggedOrderedMultiCreateInputAdapter } from "./tagged-ordered-multi-create-input.mjs";
|
|
22
21
|
import { OutputFieldInputAdapter } from "./output-field-input.mjs";
|
|
23
|
-
import { PipesRunIfInputAdapter } from "./pipes-run-if-input.mjs";
|
|
22
|
+
import { ConditionBlockInputAdapter, PipesRunIfInputAdapter } from "./pipes-run-if-input.mjs";
|
|
24
23
|
import { PromptInputAdapter } from "./prompt-input.mjs";
|
|
25
24
|
import { ProvidersInputAdapter } from "./providers-input.mjs";
|
|
26
25
|
import { RangeInputAdapter } from "./range-input.mjs";
|
|
26
|
+
import { SearchPayloadInputAdapter } from "./search-payload-input.mjs";
|
|
27
27
|
import { SelectInputAdapter } from "./select-input.mjs";
|
|
28
|
+
import { TaggedOrderedMultiCreateInputAdapter } from "./tagged-ordered-multi-create-input.mjs";
|
|
28
29
|
import { TaggedTextInputAdapter } from "./tagged-text-input.mjs";
|
|
29
30
|
import { TemplateInputAdapter } from "./template-input.mjs";
|
|
30
31
|
import { TextInputAdapter } from "./text-input.mjs";
|
|
@@ -59,15 +60,17 @@ const defaultAdapters = {
|
|
|
59
60
|
prompt_input: PromptInputAdapter,
|
|
60
61
|
template_input: TemplateInputAdapter,
|
|
61
62
|
tagged_text_input: TaggedTextInputAdapter,
|
|
62
|
-
|
|
63
|
+
loose_object_input: LooseObjectInputAdapter,
|
|
63
64
|
json_schema_input: JsonSchemaInputAdapter,
|
|
64
65
|
json_extraction_input: JsonExtractionInputAdapter,
|
|
65
66
|
pipes_run_if_input: PipesRunIfInputAdapter,
|
|
67
|
+
condition_block_input: ConditionBlockInputAdapter,
|
|
66
68
|
connector_input: ConnectorInputAdapter,
|
|
67
69
|
providers_input: ProvidersInputAdapter,
|
|
68
70
|
fields_select_input: FieldsSelectInputAdapter,
|
|
69
71
|
output_field_input: OutputFieldInputAdapter,
|
|
70
|
-
cursor_pagination_metadata: CursorPaginationInputAdapter
|
|
72
|
+
cursor_pagination_metadata: CursorPaginationInputAdapter,
|
|
73
|
+
search_payload_input: SearchPayloadInputAdapter
|
|
71
74
|
};
|
|
72
75
|
|
|
73
76
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/index.ts"],"sourcesContent":["import type { FieldAdapterMap } from \"../../../types/adapters.js\";\nimport { AsyncIncludeExcludeSelectInputAdapter } from \"./async-include-exclude-select-input.js\";\nimport { AsyncMultiSelectInputAdapter } from \"./async-multi-select-input.js\";\nimport { BooleanInputAdapter } from \"./boolean-input.js\";\nimport { ConnectorInputAdapter } from \"./connector-input.js\";\nimport { ContextSelectInputAdapter } from \"./context-select-input.js\";\nimport { CursorPaginationInputAdapter } from \"./cursor-pagination-input.js\";\nimport { DateRangeInputAdapter } from \"./date-range-input.js\";\nimport { ExactRangeInputAdapter } from \"./exact-range-input.js\";\nimport { FieldsSelectInputAdapter } from \"./fields-select-input.js\";\nimport { IncludeExcludeInputAdapter } from \"./include-exclude-input.js\";\nimport { IncludeExcludeSelectInputAdapter } from \"./include-exclude-select-input.js\";\nimport { IntInputAdapter } from \"./int-input.js\";\nimport { JsonExtractionInputAdapter } from \"./json-extraction-input.js\";\nimport { JsonSchemaInputAdapter } from \"./json-schema-input.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/index.ts"],"sourcesContent":["import type { FieldAdapterMap } from \"../../../types/adapters.js\";\nimport { AsyncIncludeExcludeSelectInputAdapter } from \"./async-include-exclude-select-input.js\";\nimport { AsyncMultiSelectInputAdapter } from \"./async-multi-select-input.js\";\nimport { BooleanInputAdapter } from \"./boolean-input.js\";\nimport { ConnectorInputAdapter } from \"./connector-input.js\";\nimport { ContextSelectInputAdapter } from \"./context-select-input.js\";\nimport { CursorPaginationInputAdapter } from \"./cursor-pagination-input.js\";\nimport { DateRangeInputAdapter } from \"./date-range-input.js\";\nimport { ExactRangeInputAdapter } from \"./exact-range-input.js\";\nimport { FieldsSelectInputAdapter } from \"./fields-select-input.js\";\nimport { IncludeExcludeInputAdapter } from \"./include-exclude-input.js\";\nimport { IncludeExcludeSelectInputAdapter } from \"./include-exclude-select-input.js\";\nimport { IntInputAdapter } from \"./int-input.js\";\nimport { JsonExtractionInputAdapter } from \"./json-extraction-input.js\";\nimport { JsonSchemaInputAdapter } from \"./json-schema-input.js\";\nimport { LooseObjectInputAdapter } from \"./loose-object-input.js\";\nimport { MinMaxIntInputAdapter } from \"./min-max-int-input.js\";\nimport { MultiCreateInputAdapter } from \"./multi-create-input.js\";\nimport { MultiSelectInputAdapter } from \"./multi-select-input.js\";\nimport { NumberInputAdapter } from \"./number-input.js\";\nimport { OrderedMultiCreateInputAdapter } from \"./ordered-multi-create-input.js\";\nimport { OutputFieldInputAdapter } from \"./output-field-input.js\";\nimport { ConditionBlockInputAdapter, PipesRunIfInputAdapter } from \"./pipes-run-if-input.js\";\nimport { PromptInputAdapter } from \"./prompt-input.js\";\nimport { ProvidersInputAdapter } from \"./providers-input.js\";\nimport { RangeInputAdapter } from \"./range-input.js\";\nimport { SearchPayloadInputAdapter } from \"./search-payload-input.js\";\nimport { SelectInputAdapter } from \"./select-input.js\";\nimport { TaggedOrderedMultiCreateInputAdapter } from \"./tagged-ordered-multi-create-input.js\";\nimport { TaggedTextInputAdapter } from \"./tagged-text-input.js\";\nimport { TemplateInputAdapter } from \"./template-input.js\";\nimport { TextInputAdapter } from \"./text-input.js\";\nimport { TextareaInputAdapter } from \"./textarea-input.js\";\n\n/**\n * Default field adapters for all known field kinds.\n * Users can override any of these via `<FormProvider adapters={...}>`.\n */\nexport const defaultAdapters = {\n text_input: TextInputAdapter,\n textarea_input: TextareaInputAdapter,\n int_input: IntInputAdapter,\n number_input: NumberInputAdapter,\n select_input: SelectInputAdapter,\n boolean_input: BooleanInputAdapter,\n nullable_boolean_input: BooleanInputAdapter,\n range_input: RangeInputAdapter,\n date_range_input: DateRangeInputAdapter,\n multi_select_input: MultiSelectInputAdapter,\n include_exclude_input: IncludeExcludeInputAdapter,\n multi_create_input: MultiCreateInputAdapter,\n context_select_input: ContextSelectInputAdapter,\n async_multi_select_input: AsyncMultiSelectInputAdapter,\n async_include_exclude_select_input: AsyncIncludeExcludeSelectInputAdapter,\n include_exclude_select_input: IncludeExcludeSelectInputAdapter,\n exact_range_input: ExactRangeInputAdapter,\n min_max_int_input: MinMaxIntInputAdapter,\n ordered_multi_create_input: OrderedMultiCreateInputAdapter,\n tagged_ordered_multi_create_input: TaggedOrderedMultiCreateInputAdapter,\n prompt_input: PromptInputAdapter,\n template_input: TemplateInputAdapter,\n tagged_text_input: TaggedTextInputAdapter,\n loose_object_input: LooseObjectInputAdapter,\n json_schema_input: JsonSchemaInputAdapter,\n json_extraction_input: JsonExtractionInputAdapter,\n pipes_run_if_input: PipesRunIfInputAdapter,\n condition_block_input: ConditionBlockInputAdapter,\n connector_input: ConnectorInputAdapter,\n providers_input: ProvidersInputAdapter,\n fields_select_input: FieldsSelectInputAdapter,\n output_field_input: OutputFieldInputAdapter,\n cursor_pagination_metadata: CursorPaginationInputAdapter,\n // Renders nothing by default — consumers (e.g. apps/dash) override this.\n search_payload_input: SearchPayloadInputAdapter,\n} satisfies Partial<FieldAdapterMap> as Partial<FieldAdapterMap>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,MAAa,kBAAkB;CAC7B,YAAY;CACZ,gBAAgB;CAChB,WAAW;CACX,cAAc;CACd,cAAc;CACd,eAAe;CACf,wBAAwB;CACxB,aAAa;CACb,kBAAkB;CAClB,oBAAoB;CACpB,uBAAuB;CACvB,oBAAoB;CACpB,sBAAsB;CACtB,0BAA0B;CAC1B,oCAAoC;CACpC,8BAA8B;CAC9B,mBAAmB;CACnB,mBAAmB;CACnB,4BAA4B;CAC5B,mCAAmC;CACnC,cAAc;CACd,gBAAgB;CAChB,mBAAmB;CACnB,oBAAoB;CACpB,mBAAmB;CACnB,uBAAuB;CACvB,oBAAoB;CACpB,uBAAuB;CACvB,iBAAiB;CACjB,iBAAiB;CACjB,qBAAqB;CACrB,oBAAoB;CACpB,4BAA4B;CAE5B,sBAAsB;CACvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"int-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/int-input.tsx"],"sourcesContent":["import type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { Input } from \"../../ui/input.js\";\n\nexport function IntInputAdapter(field: FieldHandle<\"int_input\">) {\n return <Input {...field.inputProps} step={1} data-p0=\"input\" aria-invalid={!!field.error} />;\n}\n"],"mappings":";;;;AAGA,SAAgB,gBAAgB,OAAiC;
|
|
1
|
+
{"version":3,"file":"int-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/int-input.tsx"],"sourcesContent":["import type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { Input } from \"../../ui/input.js\";\n\nexport function IntInputAdapter(field: FieldHandle<\"int_input\">) {\n // Optional ints (`sheetEffectsOptionalIntInput`) clear themselves: the int\n // handle maps an empty input to `null`, so no extra affordance is needed.\n return <Input {...field.inputProps} step={1} data-p0=\"input\" aria-invalid={!!field.error} />;\n}\n"],"mappings":";;;;AAGA,SAAgB,gBAAgB,OAAiC;AAG/D,QAAO,oBAAC,OAAD;EAAO,GAAI,MAAM;EAAY,MAAM;EAAG,WAAQ;EAAQ,gBAAc,CAAC,CAAC,MAAM;EAAS"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.mjs";
|
|
2
2
|
import { Button } from "../../ui/button.mjs";
|
|
3
|
-
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/select.mjs";
|
|
4
3
|
import { Input } from "../../ui/input.mjs";
|
|
4
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../ui/select.mjs";
|
|
5
5
|
import { IconChevronDown, IconEye, IconEyeOff, IconPlus, IconRefresh, IconTrash } from "../../internal/icons.mjs";
|
|
6
6
|
import { HoverInfo } from "../../hover-info.mjs";
|
|
7
7
|
import { useFieldError } from "../../../hooks/use-field-error.mjs";
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Button } from "../../ui/button.mjs";
|
|
2
|
+
import { Input } from "../../ui/input.mjs";
|
|
3
|
+
import { FieldLegend } from "../../internal/field-legend.mjs";
|
|
4
|
+
import { LiquidEditor } from "../../internal/LiquidEditor/LiquidEditor.mjs";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Plus, X } from "lucide-react";
|
|
7
|
+
|
|
8
|
+
//#region src/components/defaults/adapters/loose-object-input.tsx
|
|
9
|
+
/**
|
|
10
|
+
* Adapter for `pipesLooseObjectInput`. The form value is a plain
|
|
11
|
+
* `Record<string, string>`; each entry renders as a row. The key is the
|
|
12
|
+
* object key, so it's a literal text input (committed on blur, which is when
|
|
13
|
+
* the row's React key — the object key — changes). The value cell uses
|
|
14
|
+
* `LiquidEditor` so it supports `/` references (input fields + secrets +
|
|
15
|
+
* constants). Empty and duplicate keys aren't meaningful for an object and
|
|
16
|
+
* aren't supported; `maxKeys` bounds the number of entries.
|
|
17
|
+
*
|
|
18
|
+
* The per-cell legend would otherwise render once per value cell — too noisy.
|
|
19
|
+
* The value editors run with `hideLegend`; a single legend renders below the
|
|
20
|
+
* list.
|
|
21
|
+
*/
|
|
22
|
+
function LooseObjectInputAdapter(field) {
|
|
23
|
+
const { value, setObject, searchSecrets, searchConstants, meta } = field;
|
|
24
|
+
const entries = Object.entries(value);
|
|
25
|
+
const maxKeys = meta.maxKeys ?? 50;
|
|
26
|
+
const canAdd = entries.length < maxKeys;
|
|
27
|
+
const renameKey = (oldKey, newKey) => {
|
|
28
|
+
if (newKey === oldKey) return;
|
|
29
|
+
const next = {};
|
|
30
|
+
for (const [k, v] of Object.entries(value)) next[k === oldKey ? newKey : k] = v;
|
|
31
|
+
setObject(next);
|
|
32
|
+
};
|
|
33
|
+
const setEntryValue = (key, v) => setObject({
|
|
34
|
+
...value,
|
|
35
|
+
[key]: v
|
|
36
|
+
});
|
|
37
|
+
const removeKey = (key) => {
|
|
38
|
+
const { [key]: _removed, ...rest } = value;
|
|
39
|
+
setObject(rest);
|
|
40
|
+
};
|
|
41
|
+
const addEntry = () => {
|
|
42
|
+
if (Object.hasOwn(value, "")) return;
|
|
43
|
+
setObject({
|
|
44
|
+
...value,
|
|
45
|
+
"": ""
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
49
|
+
"data-p0": "input",
|
|
50
|
+
className: "pz:flex pz:flex-col pz:gap-2",
|
|
51
|
+
children: [
|
|
52
|
+
entries.length === 0 && /* @__PURE__ */ jsx("p", {
|
|
53
|
+
className: "pz:text-xs pz:text-muted-foreground",
|
|
54
|
+
children: meta.keyLabel ? `No ${meta.keyLabel.toLowerCase()}s yet.` : "No entries yet."
|
|
55
|
+
}),
|
|
56
|
+
entries.map(([key, val]) => /* @__PURE__ */ jsxs("div", {
|
|
57
|
+
className: "pz:flex pz:items-start pz:gap-2",
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsx("div", {
|
|
60
|
+
className: "pz:basis-1/3",
|
|
61
|
+
children: /* @__PURE__ */ jsx(Input, {
|
|
62
|
+
defaultValue: key,
|
|
63
|
+
onBlur: (e) => renameKey(key, e.target.value),
|
|
64
|
+
placeholder: meta.keyPlaceholder ?? meta.keyLabel ?? "Key"
|
|
65
|
+
})
|
|
66
|
+
}),
|
|
67
|
+
/* @__PURE__ */ jsx("div", {
|
|
68
|
+
className: "pz:flex-1 pz:rounded-md pz:border pz:border-input pz:bg-transparent",
|
|
69
|
+
children: /* @__PURE__ */ jsx(LiquidEditor, {
|
|
70
|
+
value: val,
|
|
71
|
+
onChange: (v) => setEntryValue(key, v),
|
|
72
|
+
inputFields: meta.inputFields ?? [],
|
|
73
|
+
searchSecrets,
|
|
74
|
+
searchConstants,
|
|
75
|
+
placeholder: meta.valuePlaceholder ?? meta.valueLabel ?? "Value",
|
|
76
|
+
hideLegend: true
|
|
77
|
+
})
|
|
78
|
+
}),
|
|
79
|
+
/* @__PURE__ */ jsx(Button, {
|
|
80
|
+
type: "button",
|
|
81
|
+
variant: "ghost",
|
|
82
|
+
size: "icon",
|
|
83
|
+
"aria-label": "Remove row",
|
|
84
|
+
onClick: () => removeKey(key),
|
|
85
|
+
children: /* @__PURE__ */ jsx(X, { className: "pz:size-4" })
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
}, key)),
|
|
89
|
+
entries.length > 0 && /* @__PURE__ */ jsx(FieldLegend, { entries: [{
|
|
90
|
+
key: "/",
|
|
91
|
+
label: "to insert a reference"
|
|
92
|
+
}] }),
|
|
93
|
+
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Button, {
|
|
94
|
+
type: "button",
|
|
95
|
+
variant: "outline",
|
|
96
|
+
size: "sm",
|
|
97
|
+
onClick: addEntry,
|
|
98
|
+
disabled: !canAdd,
|
|
99
|
+
children: [
|
|
100
|
+
/* @__PURE__ */ jsx(Plus, { className: "pz:size-4 pz:mr-1" }),
|
|
101
|
+
"Add ",
|
|
102
|
+
meta.keyLabel ?? "row"
|
|
103
|
+
]
|
|
104
|
+
}) })
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
export { LooseObjectInputAdapter };
|
|
111
|
+
//# sourceMappingURL=loose-object-input.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loose-object-input.mjs","names":[],"sources":["../../../../src/components/defaults/adapters/loose-object-input.tsx"],"sourcesContent":["import { Plus, X } from \"lucide-react\";\nimport type { FieldHandle } from \"../../../types/field-handle.js\";\nimport { FieldLegend } from \"../../internal/field-legend.js\";\nimport { LiquidEditor } from \"../../internal/LiquidEditor/LiquidEditor.js\";\nimport { Button } from \"../../ui/button.js\";\nimport { Input } from \"../../ui/input.js\";\n\n/**\n * Adapter for `pipesLooseObjectInput`. The form value is a plain\n * `Record<string, string>`; each entry renders as a row. The key is the\n * object key, so it's a literal text input (committed on blur, which is when\n * the row's React key — the object key — changes). The value cell uses\n * `LiquidEditor` so it supports `/` references (input fields + secrets +\n * constants). Empty and duplicate keys aren't meaningful for an object and\n * aren't supported; `maxKeys` bounds the number of entries.\n *\n * The per-cell legend would otherwise render once per value cell — too noisy.\n * The value editors run with `hideLegend`; a single legend renders below the\n * list.\n */\nexport function LooseObjectInputAdapter(field: FieldHandle<\"loose_object_input\">) {\n const { value, setObject, searchSecrets, searchConstants, meta } = field;\n const entries = Object.entries(value);\n const maxKeys = meta.maxKeys ?? 50;\n const canAdd = entries.length < maxKeys;\n\n // Rebuild the object, renaming `oldKey`→`newKey` in place (order preserved).\n const renameKey = (oldKey: string, newKey: string) => {\n if (newKey === oldKey) return;\n const next: Record<string, string> = {};\n for (const [k, v] of Object.entries(value)) next[k === oldKey ? newKey : k] = v;\n setObject(next);\n };\n const setEntryValue = (key: string, v: string) => setObject({ ...value, [key]: v });\n const removeKey = (key: string) => {\n const { [key]: _removed, ...rest } = value;\n setObject(rest);\n };\n // One blank slot at a time — fill its key before adding another.\n const addEntry = () => {\n if (Object.hasOwn(value, \"\")) return;\n setObject({ ...value, \"\": \"\" });\n };\n\n return (\n <div data-p0=\"input\" className=\"pz:flex pz:flex-col pz:gap-2\">\n {entries.length === 0 && (\n <p className=\"pz:text-xs pz:text-muted-foreground\">\n {meta.keyLabel ? `No ${meta.keyLabel.toLowerCase()}s yet.` : \"No entries yet.\"}\n </p>\n )}\n {entries.map(([key, val]) => (\n <div key={key} className=\"pz:flex pz:items-start pz:gap-2\">\n <div className=\"pz:basis-1/3\">\n <Input\n defaultValue={key}\n onBlur={(e) => renameKey(key, e.target.value)}\n placeholder={meta.keyPlaceholder ?? meta.keyLabel ?? \"Key\"}\n />\n </div>\n <div className=\"pz:flex-1 pz:rounded-md pz:border pz:border-input pz:bg-transparent\">\n <LiquidEditor\n value={val}\n onChange={(v) => setEntryValue(key, v)}\n inputFields={meta.inputFields ?? []}\n searchSecrets={searchSecrets}\n searchConstants={searchConstants}\n placeholder={meta.valuePlaceholder ?? meta.valueLabel ?? \"Value\"}\n hideLegend\n />\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Remove row\"\n onClick={() => removeKey(key)}\n >\n <X className=\"pz:size-4\" />\n </Button>\n </div>\n ))}\n {entries.length > 0 && (\n <FieldLegend entries={[{ key: \"/\", label: \"to insert a reference\" }]} />\n )}\n <div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addEntry} disabled={!canAdd}>\n <Plus className=\"pz:size-4 pz:mr-1\" />\n Add {meta.keyLabel ?? \"row\"}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,wBAAwB,OAA0C;CAChF,MAAM,EAAE,OAAO,WAAW,eAAe,iBAAiB,SAAS;CACnE,MAAM,UAAU,OAAO,QAAQ,MAAM;CACrC,MAAM,UAAU,KAAK,WAAW;CAChC,MAAM,SAAS,QAAQ,SAAS;CAGhC,MAAM,aAAa,QAAgB,WAAmB;AACpD,MAAI,WAAW,OAAQ;EACvB,MAAM,OAA+B,EAAE;AACvC,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,MAAM,CAAE,MAAK,MAAM,SAAS,SAAS,KAAK;AAC9E,YAAU,KAAK;;CAEjB,MAAM,iBAAiB,KAAa,MAAc,UAAU;EAAE,GAAG;GAAQ,MAAM;EAAG,CAAC;CACnF,MAAM,aAAa,QAAgB;EACjC,MAAM,GAAG,MAAM,UAAU,GAAG,SAAS;AACrC,YAAU,KAAK;;CAGjB,MAAM,iBAAiB;AACrB,MAAI,OAAO,OAAO,OAAO,GAAG,CAAE;AAC9B,YAAU;GAAE,GAAG;GAAO,IAAI;GAAI,CAAC;;AAGjC,QACE,qBAAC,OAAD;EAAK,WAAQ;EAAQ,WAAU;YAA/B;GACG,QAAQ,WAAW,KAClB,oBAAC,KAAD;IAAG,WAAU;cACV,KAAK,WAAW,MAAM,KAAK,SAAS,aAAa,CAAC,UAAU;IAC3D;GAEL,QAAQ,KAAK,CAAC,KAAK,SAClB,qBAAC,OAAD;IAAe,WAAU;cAAzB;KACE,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,OAAD;OACE,cAAc;OACd,SAAS,MAAM,UAAU,KAAK,EAAE,OAAO,MAAM;OAC7C,aAAa,KAAK,kBAAkB,KAAK,YAAY;OACrD;MACE;KACN,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,cAAD;OACE,OAAO;OACP,WAAW,MAAM,cAAc,KAAK,EAAE;OACtC,aAAa,KAAK,eAAe,EAAE;OACpB;OACE;OACjB,aAAa,KAAK,oBAAoB,KAAK,cAAc;OACzD;OACA;MACE;KACN,oBAAC,QAAD;MACE,MAAK;MACL,SAAQ;MACR,MAAK;MACL,cAAW;MACX,eAAe,UAAU,IAAI;gBAE7B,oBAAC,GAAD,EAAG,WAAU,aAAc;MACpB;KACL;MA5BI,IA4BJ,CACN;GACD,QAAQ,SAAS,KAChB,oBAAC,aAAD,EAAa,SAAS,CAAC;IAAE,KAAK;IAAK,OAAO;IAAyB,CAAC,EAAI;GAE1E,oBAAC,OAAD,YACE,qBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAU,MAAK;IAAK,SAAS;IAAU,UAAU,CAAC;cAAhF;KACE,oBAAC,MAAD,EAAM,WAAU,qBAAsB;;KACjC,KAAK,YAAY;KACf;OACL;GACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.mjs";
|
|
2
2
|
import { Button } from "../../ui/button.mjs";
|
|
3
|
-
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "../../ui/select.mjs";
|
|
4
3
|
import { Input } from "../../ui/input.mjs";
|
|
4
|
+
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "../../ui/select.mjs";
|
|
5
5
|
import { IconPlus } from "../../internal/icons.mjs";
|
|
6
6
|
import { HoverInfo } from "../../hover-info.mjs";
|
|
7
7
|
import { Badge } from "../../ui/badge.mjs";
|
|
@@ -37,8 +37,8 @@ const EMPTY_CONDITION = {
|
|
|
37
37
|
value: ""
|
|
38
38
|
};
|
|
39
39
|
const CONNECTOR_GAP = 32;
|
|
40
|
-
function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst, isLast, logic, form,
|
|
41
|
-
const conditionPath = `${
|
|
40
|
+
function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst, isLast, logic, form, conditionsPath, onUpdate, onRemove, onAddCondition, onLogicChange }) {
|
|
41
|
+
const conditionPath = `${conditionsPath}.${index}`;
|
|
42
42
|
const valueError = useFieldError(form, `${conditionPath}.value`);
|
|
43
43
|
const fieldNameError = useFieldError(form, `${conditionPath}.field_name`);
|
|
44
44
|
const operatorError = useFieldError(form, `${conditionPath}.operator`);
|
|
@@ -282,91 +282,79 @@ function ConditionRow({ condition, index, eligibleFields, fieldsByName, isFirst,
|
|
|
282
282
|
})
|
|
283
283
|
})] });
|
|
284
284
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
285
|
+
/**
|
|
286
|
+
* Presentational condition-block editor shared by the pipe run-if gate and by
|
|
287
|
+
* effects that filter rows by a condition (e.g. `rows:remove@1`'s `where`).
|
|
288
|
+
* Operates on a bare `{logic, conditions}` block via `value`/`onChange`; the
|
|
289
|
+
* wrapping adapters own where that block lives in their payload.
|
|
290
|
+
*/
|
|
291
|
+
function ConditionBlockEditor({ value, onChange, fields, form, conditionsPath }) {
|
|
292
|
+
const eligibleFields = useMemo(() => fields.filter((f) => OPERATORS_BY_TYPE[f.type].length > 0), [fields]);
|
|
293
|
+
const fieldsByName = useMemo(() => new Map(fields.map((f) => [f.fieldName, f])), [fields]);
|
|
294
|
+
const addBlock = useCallback(() => {
|
|
295
|
+
onChange({
|
|
296
|
+
logic: "and",
|
|
297
|
+
conditions: [{ ...EMPTY_CONDITION }]
|
|
297
298
|
});
|
|
298
|
-
}, [
|
|
299
|
+
}, [onChange]);
|
|
299
300
|
const updateCondition = (index, condition) => {
|
|
300
|
-
if (!
|
|
301
|
-
const newConditions = [...
|
|
301
|
+
if (!value) return;
|
|
302
|
+
const newConditions = [...value.conditions];
|
|
302
303
|
newConditions[index] = condition;
|
|
303
|
-
|
|
304
|
-
...
|
|
305
|
-
|
|
306
|
-
...pipeRunIf.when,
|
|
307
|
-
conditions: newConditions
|
|
308
|
-
}
|
|
304
|
+
onChange({
|
|
305
|
+
...value,
|
|
306
|
+
conditions: newConditions
|
|
309
307
|
});
|
|
310
308
|
};
|
|
311
309
|
const removeCondition = (index) => {
|
|
312
|
-
if (!
|
|
313
|
-
if (
|
|
314
|
-
|
|
310
|
+
if (!value) return;
|
|
311
|
+
if (value.conditions.length <= 1) {
|
|
312
|
+
onChange(null);
|
|
315
313
|
return;
|
|
316
314
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
when: {
|
|
321
|
-
...pipeRunIf.when,
|
|
322
|
-
conditions: newConditions
|
|
323
|
-
}
|
|
315
|
+
onChange({
|
|
316
|
+
...value,
|
|
317
|
+
conditions: value.conditions.filter((_, i) => i !== index)
|
|
324
318
|
});
|
|
325
319
|
};
|
|
326
320
|
const addCondition = () => {
|
|
327
|
-
if (!
|
|
328
|
-
|
|
329
|
-
...
|
|
330
|
-
|
|
331
|
-
...pipeRunIf.when,
|
|
332
|
-
conditions: [...pipeRunIf.when.conditions, { ...EMPTY_CONDITION }]
|
|
333
|
-
}
|
|
321
|
+
if (!value) return;
|
|
322
|
+
onChange({
|
|
323
|
+
...value,
|
|
324
|
+
conditions: [...value.conditions, { ...EMPTY_CONDITION }]
|
|
334
325
|
});
|
|
335
326
|
};
|
|
336
327
|
const changeLogic = (logic) => {
|
|
337
|
-
if (!
|
|
338
|
-
|
|
339
|
-
...
|
|
340
|
-
|
|
341
|
-
...pipeRunIf.when,
|
|
342
|
-
logic
|
|
343
|
-
}
|
|
328
|
+
if (!value) return;
|
|
329
|
+
onChange({
|
|
330
|
+
...value,
|
|
331
|
+
logic
|
|
344
332
|
});
|
|
345
333
|
};
|
|
346
334
|
return /* @__PURE__ */ jsx("div", {
|
|
347
335
|
"data-p0": "input",
|
|
348
|
-
children: !
|
|
336
|
+
children: !value ? /* @__PURE__ */ jsx("div", {
|
|
349
337
|
className: "pz:flex pz:items-center",
|
|
350
338
|
children: /* @__PURE__ */ jsxs(Button, {
|
|
351
339
|
type: "button",
|
|
352
340
|
variant: "link",
|
|
353
341
|
size: "xs",
|
|
354
342
|
className: "pz:px-0",
|
|
355
|
-
onClick:
|
|
343
|
+
onClick: addBlock,
|
|
356
344
|
children: [/* @__PURE__ */ jsx(IconPlus, {}), "New rule"]
|
|
357
345
|
})
|
|
358
346
|
}) : /* @__PURE__ */ jsx("div", {
|
|
359
347
|
className: "pz:flex pz:flex-col pz:gap-8",
|
|
360
|
-
children:
|
|
348
|
+
children: value.conditions.map((condition, idx) => /* @__PURE__ */ jsx(ConditionRow, {
|
|
361
349
|
condition,
|
|
362
350
|
index: idx,
|
|
363
351
|
eligibleFields,
|
|
364
352
|
fieldsByName,
|
|
365
353
|
isFirst: idx === 0,
|
|
366
|
-
isLast: idx ===
|
|
367
|
-
logic:
|
|
368
|
-
form
|
|
369
|
-
|
|
354
|
+
isLast: idx === value.conditions.length - 1,
|
|
355
|
+
logic: value.logic,
|
|
356
|
+
form,
|
|
357
|
+
conditionsPath,
|
|
370
358
|
onUpdate: updateCondition,
|
|
371
359
|
onRemove: removeCondition,
|
|
372
360
|
onAddCondition: addCondition,
|
|
@@ -375,7 +363,32 @@ function PipesRunIfInputAdapter(field) {
|
|
|
375
363
|
})
|
|
376
364
|
});
|
|
377
365
|
}
|
|
366
|
+
function PipesRunIfInputAdapter(field) {
|
|
367
|
+
const pipeRunIf = field.value;
|
|
368
|
+
const meta = field.meta;
|
|
369
|
+
return /* @__PURE__ */ jsx(ConditionBlockEditor, {
|
|
370
|
+
value: pipeRunIf?.when ?? null,
|
|
371
|
+
onChange: (block) => field.setValue(block ? {
|
|
372
|
+
action: "run",
|
|
373
|
+
when: block
|
|
374
|
+
} : null),
|
|
375
|
+
fields: meta.fields,
|
|
376
|
+
form: field.form,
|
|
377
|
+
conditionsPath: `${field.path}.when.conditions`
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
function ConditionBlockInputAdapter(field) {
|
|
381
|
+
const block = field.value;
|
|
382
|
+
const meta = field.meta;
|
|
383
|
+
return /* @__PURE__ */ jsx(ConditionBlockEditor, {
|
|
384
|
+
value: block,
|
|
385
|
+
onChange: (next) => field.setValue(next),
|
|
386
|
+
fields: meta.fields,
|
|
387
|
+
form: field.form,
|
|
388
|
+
conditionsPath: `${field.path}.conditions`
|
|
389
|
+
});
|
|
390
|
+
}
|
|
378
391
|
|
|
379
392
|
//#endregion
|
|
380
|
-
export { PipesRunIfInputAdapter };
|
|
393
|
+
export { ConditionBlockInputAdapter, PipesRunIfInputAdapter };
|
|
381
394
|
//# 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 '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":";;;;;;;;;;;;;;AAsCA,MAAM,oBAAmE;CACvE,QAAQ;EAAC;EAAM;EAAO;EAAW;CACjC,QAAQ;EAAC;EAAM;EAAO;EAAM;EAAO;EAAM;EAAM;CAC/C,SAAS,CAAC,MAAM,MAAM;CACtB,MAAM,EAAE;CACR,SAAS,EAAE;CACZ;AAED,MAAM,kBAA6B;CACjC,YAAY;CACZ,UAAU;CACV,UAAU;CACV,OAAO;CACR;AAED,MAAM,gBAAgB;AAStB,SAAS,aAAa,EACpB,WACA,OACA,gBACA,cACA,SACA,QACA,OACA,MACA,UACA,UACA,UACA,gBACA,iBAeC;CACD,MAAM,gBAAgB,GAAG,SAAS,mBAAmB;CACrD,MAAM,aAAa,cAAc,MAAM,GAAG,cAAc,QAAQ;CAChE,MAAM,iBAAiB,cAAc,MAAM,GAAG,cAAc,aAAa;CACzE,MAAM,gBAAgB,cAAc,MAAM,GAAG,cAAc,WAAW;CACtE,MAAM,gBAAgB,cAAc,MAAM,GAAG,cAAc,WAAW;CAEtE,MAAM,gBAAgB,EAAE,WAAW;CACnC,MAAM,oBAAoB,eAAe,SAAS;CAClD,MAAM,gBAAgB,UAAU,aAAa,aAAa,IAAI,UAAU,WAAW,GAAG;CAEtF,MAAM,qBAAqB,cAAc;AACvC,MAAI,UAAU,aAAa,SACzB,QAAO,wBAAwB,KAAK,QAAQ;GAC1C,OAAO;GACP,OAAO,uBAAuB;GAC/B,EAAE;AAEL,MAAI,CAAC,eAAe,KAAM,QAAO,EAAE;AACnC,SAAO,uBAAuB,KAAK,QAAQ;GACzC,OAAO;GACP,OAAO,uBAAuB;GAC/B,EAAE,CAAC,QAAQ,OAAO,kBAAkB,cAAc,MAAM,SAAS,GAAG,MAAM,CAAC;IAC3E,CAAC,UAAU,UAAU,cAAc,CAAC;CAEvC,MAAM,yBAAyB;AAC7B,MAAI,CAAC,UAAU,cAAc,CAAC,cAC5B,QAAO,oBAAC,OAAD;GAAO,WAAU;GAAU,aAAY;GAAG;GAAS,gBAAc,CAAC,CAAC;GAAc;AAG1F,MAAI,UAAU,aAAa,SACzB,QACE,qBAAC,QAAD;GACE,OAAO,OAAO,UAAU,MAAM,IAAI;GAClC,gBAAgB,MAAM,SAAS,OAAO;IAAE,GAAG;IAAW,OAAO;IAAG,CAAC;aAFnE,CAIE,oBAAC,eAAD;IAAe,WAAU;IAAU,gBAAc,CAAC,CAAC;cACjD,oBAAC,aAAD,EAAa,aAAY,cAAe;IAC1B,GAChB,qBAAC,eAAD;IACE,oBAAC,YAAD;KAAY,OAAM;eAAY;KAAsB;IACpD,oBAAC,YAAD;KAAY,OAAM;eAAU;KAAoB;IAChD,oBAAC,YAAD;KAAY,OAAM;eAAS;KAAmB;IAC9C,oBAAC,YAAD;KAAY,OAAM;eAAY;KAAsB;IACtC,IACT;;AAIb,MAAI,cAAc,SAAS,UACzB,QACE,qBAAC,QAAD;GACE,OAAO,OAAO,UAAU,MAAM;GAC9B,gBAAgB,MAAM,SAAS,OAAO;IAAE,GAAG;IAAW,OAAO;IAAG,CAAC;aAFnE,CAIE,oBAAC,eAAD;IAAe,WAAU;IAAU,gBAAc,CAAC,CAAC;cACjD,oBAAC,aAAD,EAAe;IACD,GAChB,qBAAC,eAAD,aACE,oBAAC,YAAD;IAAY,OAAM;cAAO;IAAiB,GAC1C,oBAAC,YAAD;IAAY,OAAM;cAAQ;IAAkB,EAC9B,IACT;;AAIb,MAAI,cAAc,SAAS,SACzB,QACE,oBAAC,OAAD;GACE,MAAK;GACL,WAAU;GACV,gBAAc,CAAC,CAAC;GAChB,OAAO,OAAO,OAAO,UAAU,SAAS,EAAE,CAAC;GAC3C,WAAW,MACT,SAAS,OAAO;IACd,GAAG;IACH,OAAO,OAAO,EAAE,OAAO,MAAM,IAAI;IAClC,CAAC;GAEJ,aAAY;GACZ;AAIN,SACE,oBAAC,OAAD;GACE,WAAU;GACV,gBAAc,CAAC,CAAC;GAChB,OAAO,OAAO,UAAU,SAAS,GAAG;GACpC,WAAW,MAAM,SAAS,OAAO;IAAE,GAAG;IAAW,OAAO,EAAE,OAAO;IAAO,CAAC;GACzE,aAAY;GACZ;;CAIN,MAAM,eAAe,cAAc,kBAAkB,iBAAiB;AAEtE,QACE,qBAAC,OAAD,aACE,qBAAC,OAAD;EAAK,WAAW,GAAG,eAAe,iBAAiB,WAAW;YAA9D;GACG,iBACC;IACG,UACC,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;MAAE,KAAK;MAAO,QAAQ,CAAC;MAAe;KAC7C,IAEF,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;MAAE,KAAK,CAAC;MAAe,QAAQ;MAAO;KAC7C;IAEH,CAAC,WAAW,CAAC,UACZ,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;MAAE,KAAK;MAAO,QAAQ,CAAC;MAAe;KAC7C;IAEH,CAAC,WACA,oBAAC,OAAD;KACE,WAAU;KACV,OAAO;MACL,KAAK,CAAC,gBAAgB;MACtB,WAAW;MACZ;eAED,qBAAC,QAAD;MAAQ,OAAO;MAAO,gBAAgB,MAAM,cAAc,EAAkB;gBAA5E,CACE,oBAAC,eAAD;OAAe,WAAU;iBACvB,oBAAC,aAAD,EAAe;OACD,GAChB,oBAAC,eAAD,YACE,qBAAC,aAAD,aACE,oBAAC,YAAD;OAAY,OAAM;iBAAM;OAAgB,GACxC,oBAAC,YAAD;OAAY,OAAM;iBAAK;OAAe,EAC1B,KACA,EACT;;KACL;IAEP;GAEL,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,yBAAD;MAAgC;MAAiB;MAAY;KAC7D,qBAAC,QAAD;MACE,OAAO,UAAU,cAAc;MAC/B,UAAU,CAAC;MACX,gBAAgB,MAAM;AACpB,WAAI,MAAM,KAAM;AAChB,gBAAS,OAAO;QACd,GAAG;QACH,YAAY;QACZ,UAAU;QACV,OAAO;QACR,CAAC;;gBAVN,CAaE,oBAAC,eAAD;OAAe,WAAU;OAAU,gBAAc,CAAC,CAAC;iBACjD,oBAAC,aAAD,EAAa,aAAY,gBAAiB;OAC5B,GAChB,oBAAC,eAAD,YACG,eAAe,KAAK,MACnB,oBAAC,YAAD;OAA8B,OAAO,EAAE;iBACpC,EAAE,cAAc,EAAE;OACR,EAFI,EAAE,UAEN,CACb,EACY,EACT;;KACR,CAAC,qBACA,qBAAC,QAAD;MAAM,WAAU;gBAAhB;OAAsD;OAChC;OACpB,oBAAC,WAAD,YAAW,iEAAyE;OAC/E;;KAGR,eAAe,QACd;MACE,oBAAC,OAAD;OACE,SAAQ;OACR,WAAU;iBACX;OAEO;MACR,qBAAC,QAAD;OACE,cAAa;OACb,OAAO,UAAU;OACjB,gBAAgB,MAAM;AACpB,YAAI,MAAM,KAAM;AAChB,iBAAS,OAAO;SACd,GAAG;SACH,UAAU;SACV,UAAU;SACV,OAAO;SACR,CAAC;;iBAVN,CAaE,oBAAC,eAAD;QAAe,WAAU;QAAU,gBAAc,CAAC,CAAC;kBACjD,oBAAC,aAAD,EAAe;QACD,GAChB,qBAAC,eAAD,aACE,oBAAC,YAAD;QAAY,OAAM;kBAAQ;QAAkB,GAC5C,oBAAC,YAAD;QAAY,OAAM;kBAAS;QAAmB,EAChC,IACT;;MAET,qBAAC,QAAD;OACE,OAAO,UAAU;OACjB,gBAAgB,MACd,SAAS,OAAO;QACd,GAAG;QACH,UAAU;QACX,CAAC;iBANN,CASE,oBAAC,eAAD;QAAe,WAAU;QAAU,gBAAc,CAAC,CAAC;kBACjD,oBAAC,aAAD,EAAe;QACD,GAChB,oBAAC,eAAD,YACG,mBAAmB,KAAK,OACvB,oBAAC,YAAD;QAA2B,OAAO,GAAG;kBAClC,GAAG;QACO,EAFI,GAAG,MAEP,CACb,EACY,EACT;;MAER,kBAAkB;MAClB;KAED;;GACL,gBACC,oBAAC,QAAD;IACE,WAAU;IACV,MAAK;cAEJ;IACI;GAEL;KACL,UACC,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,QAAD;GAAQ,MAAK;GAAS,SAAQ;GAAO,MAAK;GAAK,SAAS;aAAxD,CACE,oBAAC,UAAD,EAAY,cAEL;;EACL,EAEJ;;AAIV,SAAgB,uBAAuB,OAA0C;CAC/E,MAAM,YAAY,MAAM;CACxB,MAAM,OAAO,MAAM;CAKnB,MAAM,iBAAiB,cACf,KAAK,OAAO,QAAQ,MAAM,kBAAkB,EAAE,MAAM,SAAS,EAAE,EACrE,CAAC,KAAK,OAAO,CACd;CACD,MAAM,eAAe,cACb,IAAI,IAAI,KAAK,OAAO,KAAK,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EACvD,CAAC,KAAK,OAAO,CACd;CAED,MAAM,WAAW,kBAAkB;AACjC,QAAM,SAAS;GACb,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,YAAY,CAAC,EAAE,GAAG,iBAAiB,CAAC;IACrC;GACF,CAAC;IACD,CAAC,MAAM,CAAC;CAEX,MAAM,mBAAmB,OAAe,cAAyB;AAC/D,MAAI,CAAC,UAAW;EAChB,MAAM,gBAAgB,CAAC,GAAG,UAAU,KAAK,WAAW;AACpD,gBAAc,SAAS;AACvB,QAAM,SAAS;GACb,GAAG;GACH,MAAM;IAAE,GAAG,UAAU;IAAM,YAAY;IAAe;GACvD,CAAC;;CAGJ,MAAM,mBAAmB,UAAkB;AACzC,MAAI,CAAC,UAAW;AAChB,MAAI,UAAU,KAAK,WAAW,UAAU,GAAG;AACzC,SAAM,SAAS,KAAK;AACpB;;EAEF,MAAM,gBAAgB,UAAU,KAAK,WAAW,QAAQ,GAAG,MAAM,MAAM,MAAM;AAC7E,QAAM,SAAS;GACb,GAAG;GACH,MAAM;IAAE,GAAG,UAAU;IAAM,YAAY;IAAe;GACvD,CAAC;;CAGJ,MAAM,qBAAqB;AACzB,MAAI,CAAC,UAAW;AAChB,QAAM,SAAS;GACb,GAAG;GACH,MAAM;IACJ,GAAG,UAAU;IACb,YAAY,CAAC,GAAG,UAAU,KAAK,YAAY,EAAE,GAAG,iBAAiB,CAAC;IACnE;GACF,CAAC;;CAGJ,MAAM,eAAe,UAAwB;AAC3C,MAAI,CAAC,UAAW;AAChB,QAAM,SAAS;GACb,GAAG;GACH,MAAM;IAAE,GAAG,UAAU;IAAM;IAAO;GACnC,CAAC;;AAGJ,QACE,oBAAC,OAAD;EAAK,WAAQ;YACV,CAAC,YACA,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,QAAD;IAAQ,MAAK;IAAS,SAAQ;IAAO,MAAK;IAAK,WAAU;IAAU,SAAS;cAA5E,CACE,oBAAC,UAAD,EAAY,cAEL;;GACL,IAEN,oBAAC,OAAD;GAAK,WAAU;aACZ,UAAU,KAAK,WAAW,KAAK,WAAW,QACzC,oBAAC,cAAD;IAEa;IACX,OAAO;IACS;IACF;IACd,SAAS,QAAQ;IACjB,QAAQ,QAAQ,UAAU,KAAK,WAAW,SAAS;IACnD,OAAO,UAAU,KAAK;IACtB,MAAM,MAAM;IACZ,UAAU,MAAM;IAChB,UAAU;IACV,UAAU;IACV,gBAAgB;IAChB,eAAe;IACf,EAdK,IAcL,CACF;GACE;EAEJ"}
|
|
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 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\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\"],\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 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 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 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 '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\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}: {\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}) {\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 onUpdate={updateCondition}\n onRemove={removeCondition}\n onAddCondition={addCondition}\n onLogicChange={changeLogic}\n />\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 />\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"}
|