@sustaina/shared-ui 1.13.1 → 1.14.0

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
@@ -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: ""
@@ -3081,40 +3097,29 @@ var JSONBuilder = class {
3081
3097
  // src/components/advanceSearch/builder/lookup.ts
3082
3098
  var LookupBuilder = class {
3083
3099
  build(row) {
3100
+ if (!Array.isArray(row.value)) {
3101
+ return {};
3102
+ }
3103
+ const lookupField = row.lookupFieldName ?? "id";
3084
3104
  switch (row.operator) {
3085
3105
  case "containsAny":
3086
3106
  return {
3087
- [row.fieldName]: helper(
3088
- { hasSome: String(row.value).split(",") },
3089
- { multiTableSearch: row.multiTableSearch }
3090
- )
3107
+ OR: row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } }))
3091
3108
  };
3092
- case "containsAll":
3109
+ case "containsOnly":
3093
3110
  return {
3094
- [row.fieldName]: helper(
3095
- { hasEvery: String(row.value).split(",") },
3096
- { multiTableSearch: row.multiTableSearch }
3097
- )
3111
+ AND: row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } }))
3098
3112
  };
3099
- 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 } } } };
3100
3116
  return {
3101
- [row.fieldName]: helper(
3102
- { equals: String(row.value).split(",") },
3103
- {
3104
- multiTableSearch: row.multiTableSearch,
3105
- insensitive: true
3106
- }
3107
- )
3117
+ AND: [...includes, excludes]
3108
3118
  };
3119
+ }
3109
3120
  case "notContains":
3110
3121
  return {
3111
- [row.fieldName]: helper(
3112
- { not: { contains: row.value } },
3113
- {
3114
- multiTableSearch: row.multiTableSearch,
3115
- insensitive: true
3116
- }
3117
- )
3122
+ NOT: { OR: row.value.map((v) => ({ [row.fieldName]: { some: { [lookupField]: v } } })) }
3118
3123
  };
3119
3124
  default:
3120
3125
  return {};
@@ -8133,6 +8138,31 @@ function SidebarLayout({
8133
8138
  ] }) });
8134
8139
  }
8135
8140
 
8141
+ // src/components/cropperModal/type.ts
8142
+ var CropperModalError = class extends Error {
8143
+ constructor(errorType, message) {
8144
+ super(message);
8145
+ this.error = errorType;
8146
+ }
8147
+ };
8148
+ var ErrorGeneratingBlob = new CropperModalError(
8149
+ "ERROR_GENERATE_BLOB",
8150
+ "failed to generate a valid Blob"
8151
+ );
8152
+ var ErrorCreateCanvas = new CropperModalError("ERROR_CREATE_CANVAS", "Failed to create canvas");
8153
+ var ErrorInvalidSVG = new CropperModalError(
8154
+ "ERROR_INVALID_SVG",
8155
+ "The file is not a valid SVG document root"
8156
+ );
8157
+ var ErrorCompression = new CropperModalError(
8158
+ "ERROR_COMPRESSION",
8159
+ "Compression failed to generate a valid Blob"
8160
+ );
8161
+ var ErrorSVGExceedSize = new CropperModalError(
8162
+ "ERROR_SVG_EXCEED_SIZE",
8163
+ "The SVG file is too large"
8164
+ );
8165
+
8136
8166
  // src/components/cropperModal/helper.ts
8137
8167
  var createImage = (url) => new Promise((resolve, reject) => {
8138
8168
  const image = new Image();
@@ -8141,12 +8171,38 @@ var createImage = (url) => new Promise((resolve, reject) => {
8141
8171
  image.setAttribute("crossOrigin", "anonymous");
8142
8172
  image.src = url;
8143
8173
  });
8144
- async function getCroppedImg(imageSrc, pixelCrop, desiredDimension) {
8174
+ function toBlobPromise(canvas, quality) {
8175
+ return new Promise((resolve) => {
8176
+ canvas.toBlob((blob) => resolve(blob), "image/jpeg", quality);
8177
+ });
8178
+ }
8179
+ async function resizeImage(canvas, targetSizeKB) {
8180
+ const targetSizeBytes = targetSizeKB * 1024;
8181
+ let quality = 1;
8182
+ const qualityStep = 0.05;
8183
+ let compressedBlob = null;
8184
+ let currentSize = Infinity;
8185
+ while (currentSize > targetSizeBytes && quality > 0) {
8186
+ compressedBlob = await toBlobPromise(canvas, quality);
8187
+ if (compressedBlob === null) {
8188
+ throw ErrorCompression;
8189
+ }
8190
+ currentSize = compressedBlob.size;
8191
+ if (currentSize > targetSizeBytes) {
8192
+ quality = Math.max(0, quality - qualityStep);
8193
+ }
8194
+ }
8195
+ if (compressedBlob && currentSize <= targetSizeBytes) {
8196
+ return URL.createObjectURL(compressedBlob);
8197
+ }
8198
+ throw ErrorCompression;
8199
+ }
8200
+ async function getCroppedImg(imageSrc, pixelCrop, desiredDimension, targetSizeKB = Infinity) {
8145
8201
  const image = await createImage(imageSrc);
8146
8202
  const canvas = document.createElement("canvas");
8147
8203
  const ctx = canvas.getContext("2d");
8148
8204
  if (!ctx) {
8149
- throw new Error("can not create canvas");
8205
+ throw ErrorCreateCanvas;
8150
8206
  }
8151
8207
  canvas.width = image.width;
8152
8208
  canvas.height = image.height;
@@ -8154,7 +8210,7 @@ async function getCroppedImg(imageSrc, pixelCrop, desiredDimension) {
8154
8210
  const croppedCanvas = document.createElement("canvas");
8155
8211
  const croppedCtx = croppedCanvas.getContext("2d");
8156
8212
  if (!croppedCtx) {
8157
- throw new Error("can not create canvas");
8213
+ throw ErrorCreateCanvas;
8158
8214
  }
8159
8215
  croppedCanvas.width = desiredDimension?.width ?? pixelCrop.width;
8160
8216
  croppedCanvas.height = desiredDimension?.height ?? pixelCrop.height;
@@ -8169,17 +8225,9 @@ async function getCroppedImg(imageSrc, pixelCrop, desiredDimension) {
8169
8225
  desiredDimension?.width ?? pixelCrop.width,
8170
8226
  desiredDimension?.height ?? pixelCrop.height
8171
8227
  );
8172
- return new Promise((resolve, reject) => {
8173
- croppedCanvas.toBlob((file) => {
8174
- if (file) {
8175
- resolve(URL.createObjectURL(file));
8176
- } else {
8177
- reject("croppedCanvas gave null object");
8178
- }
8179
- }, "image/png");
8180
- });
8228
+ return resizeImage(croppedCanvas, targetSizeKB);
8181
8229
  }
8182
- async function getCroppedSVG(imageSrc, pixelCrop, desiredDimension) {
8230
+ async function getCroppedSVG(imageSrc, pixelCrop, desiredDimension, targetSizeKB = Infinity) {
8183
8231
  let svgString;
8184
8232
  const parts = imageSrc.split(",");
8185
8233
  const meta = parts[0];
@@ -8193,7 +8241,7 @@ async function getCroppedSVG(imageSrc, pixelCrop, desiredDimension) {
8193
8241
  const svgDoc = parser.parseFromString(svgString, "image/svg+xml");
8194
8242
  const svgElement = svgDoc.documentElement;
8195
8243
  if (svgElement.tagName.toLowerCase() !== "svg") {
8196
- throw new Error("The file is not a valid SVG document root.");
8244
+ throw ErrorInvalidSVG;
8197
8245
  }
8198
8246
  const newViewBox = `${pixelCrop.x} ${pixelCrop.y} ${pixelCrop.width} ${pixelCrop.height}`;
8199
8247
  svgElement.setAttribute("viewBox", newViewBox);
@@ -8204,6 +8252,10 @@ async function getCroppedSVG(imageSrc, pixelCrop, desiredDimension) {
8204
8252
  const serializer = new XMLSerializer();
8205
8253
  const croppedSvgString = serializer.serializeToString(svgElement);
8206
8254
  const blob = new Blob([croppedSvgString], { type: "image/svg+xml" });
8255
+ const targetSizeBytes = targetSizeKB * 1024;
8256
+ if (blob.size > targetSizeBytes) {
8257
+ throw ErrorSVGExceedSize;
8258
+ }
8207
8259
  return URL.createObjectURL(blob);
8208
8260
  }
8209
8261
  var CropperModal = ({
@@ -8216,6 +8268,7 @@ var CropperModal = ({
8216
8268
  onError,
8217
8269
  cropSize,
8218
8270
  outputExactCropSize,
8271
+ targetFileSizeKB,
8219
8272
  generateBlobUrlOutput,
8220
8273
  title,
8221
8274
  props
@@ -8252,7 +8305,7 @@ var CropperModal = ({
8252
8305
  setIsLoading(true);
8253
8306
  try {
8254
8307
  const desiredDimension = outputExactCropSize ? cropSize : void 0;
8255
- const croppedImage = isSVG ? await getCroppedSVG(imageSrc, croppedAreaPixels, desiredDimension) : await getCroppedImg(imageSrc, croppedAreaPixels, desiredDimension);
8308
+ const croppedImage = isSVG ? await getCroppedSVG(imageSrc, croppedAreaPixels, desiredDimension, targetFileSizeKB) : await getCroppedImg(imageSrc, croppedAreaPixels, desiredDimension, targetFileSizeKB);
8256
8309
  onConfirm({ crop, croppedAreaPixels, croppedImageBlobUrl: croppedImage });
8257
8310
  } catch (e) {
8258
8311
  if (onError) {
@@ -8328,6 +8381,6 @@ var CropperModal = ({
8328
8381
  );
8329
8382
  };
8330
8383
 
8331
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AdvanceSearch_default as AdvanceSearch, arrow_default as ArrowIcon, Button, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CropperModal, DIALOG_ALERT_I18N_NAMESPACE, DataTable_default as DataTable, DatePicker2 as DatePicker, Dialog, DialogAlert, DialogAlertProvider, DialogContent, DialogDescription, DialogFooter, DialogTitle, DialogTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GridSettingsModal_default as GridSettingsModal, HeaderCell_default as HeaderCell, Input, Label2 as Label, List_default as List, container_default as ListContainer, header_default as ListHeader, table_default as ListTable, LookupSelect, MonthPicker2 as MonthPicker, navbar_default as Navbar, not_found_default as NotFoundIcon, Popover, PopoverAnchor, PopoverArrow, PopoverContent, PopoverTrigger, PreventPageLeave_default as PreventPageLeave, RadioGroupItem, RadioGroupRoot, RadioLabel, RichText, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarLayout, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, calendar_default as SuiCalendarIcon, check_default as SuiCheckIcon, dots_vertical_default as SuiDotsVerticalIcon, empty_data_default as SuiEmptyDataIcon, expand_default as SuiExpandIcon, filter_default as SuiFilterIcon, setting_default as SuiSettingIcon, triangle_down_default as SuiTriangleDownIcon, warning_default as SuiWarningIcon, Switch, Textarea, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipTrigger, ui_exports as UI, booleanToSelectValue, buttonVariants, cn, compareAlphanumeric, debounce, getDialogAlertControls, getDialogTemplates, inputVariants, isDefined, isEmptyObject, selectValueToBoolean, stripNullishObject, throttle, useFormField, useGridSettingsStore_default as useGridSettingsStore, useHover_default as useHover, useIntersectionObserver_default as useIntersectionObserver, useMediaQuery_default as useMediaQuery, usePreventPageLeave_default as usePreventPageLeave, usePreventPageLeaveStore_default as usePreventPageLeaveStore, useScreenSize_default as useScreenSize, useSidebar, useTruncated_default as useTruncated };
8384
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AdvanceSearch_default as AdvanceSearch, arrow_default as ArrowIcon, Button, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CropperModal, CropperModalError, DIALOG_ALERT_I18N_NAMESPACE, DataTable_default as DataTable, DatePicker2 as DatePicker, Dialog, DialogAlert, DialogAlertProvider, DialogContent, DialogDescription, DialogFooter, DialogTitle, DialogTrigger, ErrorCompression, ErrorCreateCanvas, ErrorGeneratingBlob, ErrorInvalidSVG, ErrorSVGExceedSize, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GridSettingsModal_default as GridSettingsModal, HeaderCell_default as HeaderCell, Input, Label2 as Label, List_default as List, container_default as ListContainer, header_default as ListHeader, table_default as ListTable, LookupSelect, MonthPicker2 as MonthPicker, navbar_default as Navbar, not_found_default as NotFoundIcon, Popover, PopoverAnchor, PopoverArrow, PopoverContent, PopoverTrigger, PreventPageLeave_default as PreventPageLeave, RadioGroupItem, RadioGroupRoot, RadioLabel, RichText, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarLayout, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Spinner, calendar_default as SuiCalendarIcon, check_default as SuiCheckIcon, dots_vertical_default as SuiDotsVerticalIcon, empty_data_default as SuiEmptyDataIcon, expand_default as SuiExpandIcon, filter_default as SuiFilterIcon, setting_default as SuiSettingIcon, triangle_down_default as SuiTriangleDownIcon, warning_default as SuiWarningIcon, Switch, Textarea, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipTrigger, ui_exports as UI, booleanToSelectValue, buttonVariants, cn, compareAlphanumeric, debounce, getDialogAlertControls, getDialogTemplates, inputVariants, isDefined, isEmptyObject, selectValueToBoolean, spinnerVariants, stripNullishObject, throttle, useFormField, useGridSettingsStore_default as useGridSettingsStore, useHover_default as useHover, useIntersectionObserver_default as useIntersectionObserver, useMediaQuery_default as useMediaQuery, usePreventPageLeave_default as usePreventPageLeave, usePreventPageLeaveStore_default as usePreventPageLeaveStore, useScreenSize_default as useScreenSize, useSidebar, useTruncated_default as useTruncated };
8332
8385
  //# sourceMappingURL=index.mjs.map
8333
8386
  //# sourceMappingURL=index.mjs.map