@stoker-platform/web-app 0.5.40 → 0.5.42

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @stoker-platform/web-app
2
2
 
3
+ ## 0.5.42
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: add clear button to month picker
8
+
9
+ ## 0.5.41
10
+
11
+ ### Patch Changes
12
+
13
+ - feat: add button group selector to form
14
+ - @stoker-platform/node-client@0.5.26
15
+ - @stoker-platform/utils@0.5.20
16
+ - @stoker-platform/web-client@0.5.22
17
+
3
18
  ## 0.5.40
4
19
 
5
20
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoker-platform/web-app",
3
- "version": "0.5.40",
3
+ "version": "0.5.42",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "scripts": {
@@ -51,9 +51,9 @@
51
51
  "@radix-ui/react-tooltip": "^1.2.8",
52
52
  "@react-google-maps/api": "^2.20.8",
53
53
  "@sentry/react": "^10.38.0",
54
- "@stoker-platform/node-client": "0.5.25",
55
- "@stoker-platform/utils": "0.5.19",
56
- "@stoker-platform/web-client": "0.5.21",
54
+ "@stoker-platform/node-client": "0.5.26",
55
+ "@stoker-platform/utils": "0.5.20",
56
+ "@stoker-platform/web-client": "0.5.22",
57
57
  "@tanstack/react-table": "^8.21.3",
58
58
  "@types/react": "18.3.13",
59
59
  "@types/react-dom": "18.3.1",
package/src/Form.tsx CHANGED
@@ -295,6 +295,7 @@ const RecordFormField = (props: FieldProps) => {
295
295
  const [isLocation, setIsLocation] = useState<LocationFieldAdmin | undefined>(undefined)
296
296
  const [isImage, setIsImage] = useState(false)
297
297
  const [isRadio, setIsRadio] = useState(false)
298
+ const [isButtonGroup, setIsButtonGroup] = useState(false)
298
299
  const [icon, setIcon] = useState<FormFieldIcon | undefined>(undefined)
299
300
 
300
301
  useEffect(() => {
@@ -315,6 +316,7 @@ const RecordFormField = (props: FieldProps) => {
315
316
  image,
316
317
  isLocation,
317
318
  isRadio,
319
+ isButtonGroup,
318
320
  icon,
319
321
  ] = await Promise.all([
320
322
  tryFunction(admin?.label),
@@ -329,6 +331,7 @@ const RecordFormField = (props: FieldProps) => {
329
331
  tryPromise(admin?.image),
330
332
  tryPromise(admin?.location),
331
333
  tryPromise(admin?.radio),
334
+ tryPromise(admin?.buttonGroup),
332
335
  tryPromise(admin?.icon),
333
336
  ])
334
337
 
@@ -346,6 +349,7 @@ const RecordFormField = (props: FieldProps) => {
346
349
  setIsImage(!!image)
347
350
  setIsLocation(isLocation)
348
351
  setIsRadio(!!isRadio)
352
+ setIsButtonGroup(!!isButtonGroup)
349
353
  setIcon(icon)
350
354
  // Prevent button and rich text editor from flickering
351
355
  setTimeout(() => {
@@ -437,6 +441,7 @@ const RecordFormField = (props: FieldProps) => {
437
441
  isTextarea={isTextarea}
438
442
  isDisabled={isDisabled}
439
443
  isRadio={isRadio}
444
+ isButtonGroup={isButtonGroup}
440
445
  isTime={isTime}
441
446
  icon={icon}
442
447
  />
@@ -529,9 +534,10 @@ function StringField({
529
534
  isTextarea,
530
535
  isDisabled,
531
536
  isRadio,
537
+ isButtonGroup,
532
538
  isTime,
533
539
  icon,
534
- }: FieldProps & { isTextarea?: boolean; isRadio?: boolean; isTime?: boolean }) {
540
+ }: FieldProps & { isTextarea?: boolean; isRadio?: boolean; isButtonGroup?: boolean; isTime?: boolean }) {
535
541
  const customization = getCollectionConfigModule(collection.labels.collection)
536
542
  const fieldCustomization = getFieldCustomization(field, customization)
537
543
  if ((field as StringFieldType).values) {
@@ -592,6 +598,61 @@ function StringField({
592
598
  />
593
599
  )
594
600
  }
601
+ if (isButtonGroup) {
602
+ return (
603
+ <FormField
604
+ control={form.control}
605
+ name={field.name}
606
+ defaultValue={
607
+ operation !== "update-many" &&
608
+ field.required &&
609
+ (form.getValues(field.name) === undefined ||
610
+ form.getValues(field.name) === null ||
611
+ form.getValues(field.name) === "")
612
+ ? (field as StringFieldType).values?.[0]
613
+ : undefined
614
+ }
615
+ render={({ field: formField }) => (
616
+ <FormItem>
617
+ <FormLabelWithIcon
618
+ collection={collection}
619
+ label={label}
620
+ field={field}
621
+ operation={operation}
622
+ icon={icon}
623
+ form={form}
624
+ />
625
+ <FormControl>
626
+ <div className="mt-2 flex flex-row gap-2 max-w-[750px] flex-wrap">
627
+ {(field as StringFieldType).values
628
+ ?.filter(
629
+ (option) =>
630
+ !fieldCustomization.admin?.filterValues ||
631
+ fieldCustomization.admin?.filterValues?.(option, collection, record),
632
+ )
633
+ .map((option) => {
634
+ return (
635
+ <Button
636
+ key={option}
637
+ type="button"
638
+ onClick={() => formField.onChange(option)}
639
+ // eslint-disable-next-line security/detect-object-injection
640
+ variant={formField.value === option ? "default" : "outline"}
641
+ className="disabled:opacity-100"
642
+ >
643
+ {option}
644
+ </Button>
645
+ )
646
+ })}
647
+ </div>
648
+ </FormControl>
649
+ {description && <FormDescription>{description}</FormDescription>}
650
+ <FormMessage className="bg-destructive p-4 rounded-md text-background dark:text-primary" />
651
+ </FormItem>
652
+ )}
653
+ />
654
+ )
655
+ }
595
656
  return (
596
657
  <FormField
597
658
  control={form.control}
@@ -1186,20 +1247,33 @@ function TimestampField({
1186
1247
  form={form}
1187
1248
  />
1188
1249
  <FormControl>
1189
- <div className="flex w-fit flex-col gap-2 rounded-md border border-input">
1190
- <MonthPicker
1191
- currentMonth={
1192
- currentValue
1193
- ? keepTimezone(currentValue.toJSDate(), timezone)
1194
- : keepTimezone(new Date(), timezone)
1195
- }
1196
- onMonthChange={(date: Date | undefined) => {
1197
- if (!date) return
1198
- const newDate = DateTime.fromJSDate(date).setZone(timezone)
1199
- formField.onChange(Timestamp.fromDate(newDate.toJSDate()))
1200
- }}
1201
- disabled={isDisabled}
1202
- />
1250
+ <div className="flex flex-col gap-2">
1251
+ <div className="flex w-fit flex-col gap-2 rounded-md border border-input">
1252
+ <MonthPicker
1253
+ currentMonth={
1254
+ currentValue
1255
+ ? keepTimezone(currentValue.toJSDate(), timezone)
1256
+ : keepTimezone(new Date(), timezone)
1257
+ }
1258
+ onMonthChange={(date: Date | undefined) => {
1259
+ if (!date) return
1260
+ const newDate = DateTime.fromJSDate(date).setZone(timezone)
1261
+ formField.onChange(Timestamp.fromDate(newDate.toJSDate()))
1262
+ }}
1263
+ disabled={isDisabled}
1264
+ />
1265
+ </div>
1266
+ {formField.value && (
1267
+ <Button
1268
+ type="button"
1269
+ variant="outline"
1270
+ onClick={() => formField.onChange(null)}
1271
+ disabled={isDisabled}
1272
+ className="w-fit"
1273
+ >
1274
+ Clear
1275
+ </Button>
1276
+ )}
1203
1277
  </div>
1204
1278
  </FormControl>
1205
1279
  {description && <FormDescription>{description}</FormDescription>}