@sustaina/shared-ui 1.13.0 → 1.13.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.
package/dist/index.mjs CHANGED
@@ -604,7 +604,7 @@ var OPERATOR_MAP = {
604
604
  dropdown: ["is", "isNot"],
605
605
  lookup: ["containsAny", "containsOnly", "containsAll", "notContains"],
606
606
  uuid: ["equals", "notEquals", "gt", "gte", "lt", "lte"],
607
- json: ["contains", "equals", "beginsWith", "endsWith"]
607
+ json: ["equals", "notEquals", "containsAny"]
608
608
  };
609
609
 
610
610
  // src/components/advanceSearch/hooks/useAdvanceSearch.ts
@@ -629,7 +629,19 @@ function makeNewRow(field) {
629
629
  value: "",
630
630
  value2: "",
631
631
  multiTableSearch: field.multiTableSearch,
632
- jsonPath: field.jsonPath
632
+ lookupFieldName: field.lookupFieldName
633
+ };
634
+ }
635
+ if (field.type === "json") {
636
+ return {
637
+ id: crypto.randomUUID(),
638
+ fieldName: field.name,
639
+ fieldType: field.type,
640
+ operator: op,
641
+ value: "",
642
+ multiTableSearch: field.multiTableSearch,
643
+ jsonPath: field.jsonPath,
644
+ lookupFieldName: field.lookupFieldName
633
645
  };
634
646
  }
635
647
  return {
@@ -639,7 +651,7 @@ function makeNewRow(field) {
639
651
  operator: op,
640
652
  value: "",
641
653
  multiTableSearch: field.multiTableSearch,
642
- jsonPath: field.jsonPath
654
+ lookupFieldName: field.lookupFieldName
643
655
  };
644
656
  }
645
657
  function useAdvanceSearch({ fields, limitRows }) {
@@ -681,7 +693,8 @@ function useAdvanceSearch({ fields, limitRows }) {
681
693
  value: "",
682
694
  value2: "",
683
695
  multiTableSearch: r.multiTableSearch,
684
- jsonPath: r.jsonPath
696
+ jsonPath: r.jsonPath,
697
+ lookupFieldName: r.lookupFieldName
685
698
  } : {
686
699
  id: r.id,
687
700
  fieldName: r.fieldName,
@@ -689,7 +702,8 @@ function useAdvanceSearch({ fields, limitRows }) {
689
702
  operator: nextOp,
690
703
  value: "",
691
704
  multiTableSearch: r.multiTableSearch,
692
- jsonPath: r.jsonPath
705
+ jsonPath: r.jsonPath,
706
+ lookupFieldName: r.lookupFieldName
693
707
  };
694
708
  })
695
709
  );
@@ -722,6 +736,7 @@ function useAdvanceSearch({ fields, limitRows }) {
722
736
  fieldName: r.fieldName,
723
737
  fieldType: r.fieldType,
724
738
  multiTableSearch: r.multiTableSearch,
739
+ lookupFieldName: r.lookupFieldName,
725
740
  jsonPath: r.jsonPath,
726
741
  operator,
727
742
  value: "",
@@ -733,6 +748,7 @@ function useAdvanceSearch({ fields, limitRows }) {
733
748
  fieldName: r.fieldName,
734
749
  fieldType: r.fieldType,
735
750
  multiTableSearch: r.multiTableSearch,
751
+ lookupFieldName: r.lookupFieldName,
736
752
  jsonPath: r.jsonPath,
737
753
  operator,
738
754
  value: ""
@@ -2438,6 +2454,7 @@ var LookupSelect = ({
2438
2454
  dropdownPortalId
2439
2455
  }) => {
2440
2456
  const [inputValue, setInputValue] = useState("");
2457
+ const inputRef = useRef(null);
2441
2458
  const [suggestions, setSuggestions] = useState([]);
2442
2459
  const [optionLabels, setOptionLabels] = useState({});
2443
2460
  const [loading, setLoading] = useState(false);
@@ -2516,6 +2533,10 @@ var LookupSelect = ({
2516
2533
  (option) => {
2517
2534
  upsertOptionLabels([option]);
2518
2535
  addTag(option.value);
2536
+ inputRef.current?.focus();
2537
+ setTimeout(() => {
2538
+ inputRef.current?.scrollIntoView({ behavior: "smooth" });
2539
+ }, 100);
2519
2540
  },
2520
2541
  [addTag, upsertOptionLabels]
2521
2542
  );
@@ -2657,9 +2678,10 @@ var LookupSelect = ({
2657
2678
  `${tag}-${i}`
2658
2679
  );
2659
2680
  }),
2660
- /* @__PURE__ */ jsx(
2681
+ !limitReached && /* @__PURE__ */ jsx(
2661
2682
  "input",
2662
2683
  {
2684
+ ref: inputRef,
2663
2685
  type: "text",
2664
2686
  value: inputValue,
2665
2687
  onChange: (e) => setInputValue(e.target.value),
@@ -2675,7 +2697,7 @@ var LookupSelect = ({
2675
2697
  }
2676
2698
  )
2677
2699
  ] }),
2678
- /* @__PURE__ */ jsx("div", { className: "flex justify-end absolute inset-y-1 right-2 items-center gap-2 pointer-events-auto", children: value.length === 0 ? /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 items-center justify-center text-inherit", children: /* @__PURE__ */ jsx(Search, { className: "h-4 w-4" }) }) : /* @__PURE__ */ jsx(
2700
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end items-center gap-2 pointer-events-auto h-fit", children: value.length === 0 ? /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 items-center justify-center text-inherit", children: /* @__PURE__ */ jsx(Search, { className: "h-4 w-4" }) }) : /* @__PURE__ */ jsx(
2679
2701
  ClearButton,
2680
2702
  {
2681
2703
  onClick: handleClear,
@@ -2688,7 +2710,7 @@ var LookupSelect = ({
2688
2710
  ),
2689
2711
  renderDropdown(),
2690
2712
  fetchError && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-red-600", children: fetchError }),
2691
- limitReached && !fetchError && /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-inherit", children: [
2713
+ limitReached && !fetchError && maxTags !== 1 && /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-inherit", children: [
2692
2714
  "Maximum ",
2693
2715
  maxTags,
2694
2716
  " tags reached."
@@ -2738,6 +2760,58 @@ var ConditionLookupInput = ({
2738
2760
  }
2739
2761
  }
2740
2762
  );
2763
+ var ConditionJSONInput = ({
2764
+ row,
2765
+ control,
2766
+ onClear,
2767
+ fieldSchema,
2768
+ dropdownPortalId
2769
+ }) => /* @__PURE__ */ jsx(
2770
+ FormField,
2771
+ {
2772
+ control,
2773
+ name: `value_${row.id}`,
2774
+ rules: { required: "This field is required." },
2775
+ render: ({ field, fieldState }) => {
2776
+ const value = Array.isArray(field.value) ? field.value : [];
2777
+ const handleChange = (tags) => {
2778
+ field.onChange(tags);
2779
+ };
2780
+ const handleClear = () => {
2781
+ field.onChange([]);
2782
+ onClear("value");
2783
+ };
2784
+ return /* @__PURE__ */ jsxs(FormItem, { className: "relative w-full overflow-x-hidden", children: [
2785
+ /* @__PURE__ */ jsx(FormControl, { children: fieldSchema?.fetchSuggestions ? /* @__PURE__ */ jsx(
2786
+ LookupSelect,
2787
+ {
2788
+ value,
2789
+ onChange: handleChange,
2790
+ onClear: handleClear,
2791
+ error: Boolean(fieldState.error),
2792
+ placeholder: fieldSchema?.placeholder,
2793
+ maxTags: row.operator === "containsAny" ? fieldSchema?.maxTags : 1,
2794
+ fetchSuggestions: fieldSchema?.fetchSuggestions,
2795
+ suggestionDebounce: fieldSchema?.suggestionDebounce,
2796
+ noOptionsMessage: fieldSchema?.noOptionsMessage,
2797
+ loadingMessage: fieldSchema?.loadingMessage,
2798
+ dropdownPortalId
2799
+ }
2800
+ ) : /* @__PURE__ */ jsx(
2801
+ Input,
2802
+ {
2803
+ ...field,
2804
+ value: field.value ?? "",
2805
+ autoComplete: "off",
2806
+ inputMode: "text",
2807
+ className: "w-full h-9 rounded-md bg-white pr-8 text-sm text-gray-700 shadow-none focus-visible:ring-0 focus-visible:ring-offset-0"
2808
+ }
2809
+ ) }),
2810
+ /* @__PURE__ */ jsx(FormMessage, { className: "absolute left-0 top-full mt-1 text-xs text-red-600" })
2811
+ ] });
2812
+ }
2813
+ }
2814
+ );
2741
2815
  var ConditionValue = ({ row, fields, onClearValue, dropdownPortalId }) => {
2742
2816
  const { control } = useFormContext();
2743
2817
  const fieldSchema = fields.find((f) => f.name === row.fieldName);
@@ -2773,6 +2847,18 @@ var ConditionValue = ({ row, fields, onClearValue, dropdownPortalId }) => {
2773
2847
  dropdownPortalId
2774
2848
  }
2775
2849
  );
2850
+ case "json": {
2851
+ return /* @__PURE__ */ jsx(
2852
+ ConditionJSONInput,
2853
+ {
2854
+ row,
2855
+ control,
2856
+ onClear: onClearValue,
2857
+ fieldSchema,
2858
+ dropdownPortalId
2859
+ }
2860
+ );
2861
+ }
2776
2862
  default:
2777
2863
  return /* @__PURE__ */ jsx(ConditionTextInput, { row, control, onClear: onClearValue });
2778
2864
  }
@@ -2988,23 +3074,20 @@ var DropdownBuilder = class {
2988
3074
  // src/components/advanceSearch/builder/json.ts
2989
3075
  var JSONBuilder = class {
2990
3076
  build(row) {
3077
+ const isArray = Array.isArray(row.value);
2991
3078
  switch (row.operator) {
2992
- case "contains":
2993
- return { [row.fieldName]: { path: row.jsonPath, string_contains: row.value } };
2994
3079
  case "equals":
2995
- return { [row.fieldName]: { path: row.jsonPath, equals: row.value } };
2996
- case "beginsWith":
2997
- return { [row.fieldName]: { path: row.jsonPath, string_starts_with: row.value } };
2998
- case "endsWith":
2999
- return { [row.fieldName]: { path: row.jsonPath, string_ends_with: row.value } };
3000
- case "notContains":
3001
- return { [row.fieldName]: { path: row.jsonPath, not: { string_contains: row.value } } };
3080
+ return { [row.fieldName]: { path: row.jsonPath, equals: isArray ? row.value[0] : row.value } };
3002
3081
  case "notEquals":
3003
- return { [row.fieldName]: { path: row.jsonPath, not: { equals: row.value } } };
3004
- case "notBeginsWith":
3005
- return { [row.fieldName]: { path: row.jsonPath, not: { string_starts_with: row.value } } };
3006
- case "notEndsWith":
3007
- return { [row.fieldName]: { path: row.jsonPath, not: { string_ends_with: row.value } } };
3082
+ return {
3083
+ NOT: { [row.fieldName]: { path: row.jsonPath, equals: isArray ? row.value[0] : row.value } }
3084
+ };
3085
+ case "containsAny":
3086
+ if (!isArray)
3087
+ return { [row.fieldName]: { path: row.jsonPath, equals: isArray ? row.value[0] : row.value } };
3088
+ return {
3089
+ OR: row.value.map((v) => ({ [row.fieldName]: { path: row.jsonPath, equals: v } }))
3090
+ };
3008
3091
  default:
3009
3092
  return {};
3010
3093
  }
@@ -3014,40 +3097,29 @@ var JSONBuilder = class {
3014
3097
  // src/components/advanceSearch/builder/lookup.ts
3015
3098
  var LookupBuilder = class {
3016
3099
  build(row) {
3100
+ if (!Array.isArray(row.value)) {
3101
+ return {};
3102
+ }
3103
+ const lookupField = row.lookupFieldName ?? "id";
3017
3104
  switch (row.operator) {
3018
3105
  case "containsAny":
3019
3106
  return {
3020
- [row.fieldName]: helper(
3021
- { hasSome: String(row.value).split(",") },
3022
- { multiTableSearch: row.multiTableSearch }
3023
- )
3107
+ OR: row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } }))
3024
3108
  };
3025
- case "containsAll":
3109
+ case "containsOnly":
3026
3110
  return {
3027
- [row.fieldName]: helper(
3028
- { hasEvery: String(row.value).split(",") },
3029
- { multiTableSearch: row.multiTableSearch }
3030
- )
3111
+ AND: row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } }))
3031
3112
  };
3032
- case "containsOnly":
3113
+ case "containsAll": {
3114
+ const includes = row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } }));
3115
+ const excludes = { [row.fieldName]: { none: { [lookupField]: { notIn: row.value } } } };
3033
3116
  return {
3034
- [row.fieldName]: helper(
3035
- { equals: String(row.value).split(",") },
3036
- {
3037
- multiTableSearch: row.multiTableSearch,
3038
- insensitive: true
3039
- }
3040
- )
3117
+ AND: [...includes, excludes]
3041
3118
  };
3119
+ }
3042
3120
  case "notContains":
3043
3121
  return {
3044
- [row.fieldName]: helper(
3045
- { not: { contains: row.value } },
3046
- {
3047
- multiTableSearch: row.multiTableSearch,
3048
- insensitive: true
3049
- }
3050
- )
3122
+ NOT: { OR: row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } })) }
3051
3123
  };
3052
3124
  default:
3053
3125
  return {};
@@ -5718,9 +5790,9 @@ var InfoIcon = (props) => {
5718
5790
  {
5719
5791
  d: "M10.0013 18.3327C14.6037 18.3327 18.3346 14.6017 18.3346 9.99935C18.3346 5.39698 14.6037 1.66602 10.0013 1.66602C5.39893 1.66602 1.66797 5.39698 1.66797 9.99935C1.66797 14.6017 5.39893 18.3327 10.0013 18.3327Z",
5720
5792
  stroke: "white",
5721
- "stroke-width": "1.5",
5722
- "stroke-linecap": "round",
5723
- "stroke-linejoin": "round"
5793
+ strokeWidth: "1.5",
5794
+ strokeLinecap: "round",
5795
+ strokeLinejoin: "round"
5724
5796
  }
5725
5797
  ),
5726
5798
  /* @__PURE__ */ jsx(
@@ -5728,9 +5800,9 @@ var InfoIcon = (props) => {
5728
5800
  {
5729
5801
  d: "M10 13.3333V10",
5730
5802
  stroke: "white",
5731
- "stroke-width": "1.5",
5732
- "stroke-linecap": "round",
5733
- "stroke-linejoin": "round"
5803
+ strokeWidth: "1.5",
5804
+ strokeLinecap: "round",
5805
+ strokeLinejoin: "round"
5734
5806
  }
5735
5807
  ),
5736
5808
  /* @__PURE__ */ jsx(
@@ -5738,9 +5810,9 @@ var InfoIcon = (props) => {
5738
5810
  {
5739
5811
  d: "M10 6.66602H10.0083",
5740
5812
  stroke: "white",
5741
- "stroke-width": "1.5",
5742
- "stroke-linecap": "round",
5743
- "stroke-linejoin": "round"
5813
+ strokeWidth: "1.5",
5814
+ strokeLinecap: "round",
5815
+ strokeLinejoin: "round"
5744
5816
  }
5745
5817
  )
5746
5818
  ]