@stoker-platform/web-app 0.5.239 → 0.5.241

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,23 @@
1
1
  # @stoker-platform/web-app
2
2
 
3
+ ## 0.5.241
4
+
5
+ ### Patch Changes
6
+
7
+ - @stoker-platform/node-client@0.5.100
8
+ - @stoker-platform/utils@0.5.87
9
+ - @stoker-platform/web-client@0.5.104
10
+
11
+ ## 0.5.240
12
+
13
+ ### Patch Changes
14
+
15
+ - chore: update dependencies
16
+ - Updated dependencies
17
+ - @stoker-platform/node-client@0.5.99
18
+ - @stoker-platform/utils@0.5.86
19
+ - @stoker-platform/web-client@0.5.103
20
+
3
21
  ## 0.5.239
4
22
 
5
23
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoker-platform/web-app",
3
- "version": "0.5.239",
3
+ "version": "0.5.241",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "scripts": {
@@ -15,57 +15,57 @@
15
15
  "@assistant-ui/react": "^0.10.50",
16
16
  "@assistant-ui/react-ai-sdk": "^0.11.5",
17
17
  "@assistant-ui/react-markdown": "^0.10.9",
18
- "@fullcalendar/adaptive": "^6.1.20",
19
- "@fullcalendar/core": "^6.1.20",
20
- "@fullcalendar/daygrid": "^6.1.20",
21
- "@fullcalendar/interaction": "^6.1.20",
22
- "@fullcalendar/list": "^6.1.20",
23
- "@fullcalendar/luxon3": "^6.1.20",
24
- "@fullcalendar/multimonth": "^6.1.20",
25
- "@fullcalendar/react": "^6.1.20",
26
- "@fullcalendar/resource": "^6.1.20",
27
- "@fullcalendar/resource-daygrid": "^6.1.20",
28
- "@fullcalendar/resource-timegrid": "^6.1.20",
29
- "@fullcalendar/resource-timeline": "^6.1.20",
30
- "@fullcalendar/timegrid": "^6.1.20",
31
- "@hookform/resolvers": "^5.4.0",
32
- "@radix-ui/react-alert-dialog": "^1.1.15",
33
- "@radix-ui/react-checkbox": "^1.3.3",
18
+ "@fullcalendar/adaptive": "^6.1.21",
19
+ "@fullcalendar/core": "^6.1.21",
20
+ "@fullcalendar/daygrid": "^6.1.21",
21
+ "@fullcalendar/interaction": "^6.1.21",
22
+ "@fullcalendar/list": "^6.1.21",
23
+ "@fullcalendar/luxon3": "^6.1.21",
24
+ "@fullcalendar/multimonth": "^6.1.21",
25
+ "@fullcalendar/react": "^6.1.21",
26
+ "@fullcalendar/resource": "^6.1.21",
27
+ "@fullcalendar/resource-daygrid": "^6.1.21",
28
+ "@fullcalendar/resource-timegrid": "^6.1.21",
29
+ "@fullcalendar/resource-timeline": "^6.1.21",
30
+ "@fullcalendar/timegrid": "^6.1.21",
31
+ "@hookform/resolvers": "^5.9.1",
32
+ "@radix-ui/react-alert-dialog": "^1.1.23",
33
+ "@radix-ui/react-checkbox": "^1.3.11",
34
34
  "@radix-ui/react-dialog": "^1.1.14",
35
- "@radix-ui/react-dropdown-menu": "^2.1.16",
35
+ "@radix-ui/react-dropdown-menu": "^2.1.24",
36
36
  "@radix-ui/react-icons": "^1.3.2",
37
- "@radix-ui/react-label": "^2.1.8",
38
- "@radix-ui/react-popover": "^1.1.15",
39
- "@radix-ui/react-progress": "^1.1.8",
40
- "@radix-ui/react-radio-group": "^1.3.8",
41
- "@radix-ui/react-scroll-area": "^1.2.10",
42
- "@radix-ui/react-select": "^2.2.6",
43
- "@radix-ui/react-separator": "^1.1.8",
44
- "@radix-ui/react-slider": "^1.3.6",
37
+ "@radix-ui/react-label": "^2.1.15",
38
+ "@radix-ui/react-popover": "^1.1.23",
39
+ "@radix-ui/react-progress": "^1.1.16",
40
+ "@radix-ui/react-radio-group": "^1.4.7",
41
+ "@radix-ui/react-scroll-area": "^1.2.18",
42
+ "@radix-ui/react-select": "^2.3.7",
43
+ "@radix-ui/react-separator": "^1.1.15",
44
+ "@radix-ui/react-slider": "^1.4.7",
45
45
  "@radix-ui/react-slot": "^1.2.3",
46
- "@radix-ui/react-switch": "^1.2.6",
47
- "@radix-ui/react-tabs": "^1.1.13",
48
- "@radix-ui/react-toast": "^1.2.15",
46
+ "@radix-ui/react-switch": "^1.3.7",
47
+ "@radix-ui/react-tabs": "^1.1.21",
48
+ "@radix-ui/react-toast": "^1.2.23",
49
49
  "@radix-ui/react-toggle": "^1.1.2",
50
- "@radix-ui/react-toggle-group": "^1.1.11",
51
- "@radix-ui/react-tooltip": "^1.2.8",
50
+ "@radix-ui/react-toggle-group": "^1.1.19",
51
+ "@radix-ui/react-tooltip": "^1.2.16",
52
52
  "@react-google-maps/api": "^2.20.8",
53
- "@sentry/react": "^10.56.0",
54
- "@stoker-platform/node-client": "0.5.98",
55
- "@stoker-platform/utils": "0.5.85",
56
- "@stoker-platform/web-client": "0.5.102",
53
+ "@sentry/react": "^10.70.0",
54
+ "@stoker-platform/node-client": "0.5.100",
55
+ "@stoker-platform/utils": "0.5.87",
56
+ "@stoker-platform/web-client": "0.5.104",
57
57
  "@tanstack/react-table": "^8.21.3",
58
58
  "@types/react": "18.3.13",
59
59
  "@types/react-dom": "18.3.1",
60
- "@vitejs/plugin-react": "^5.2.0",
60
+ "@vitejs/plugin-react": "^6.1.0",
61
61
  "ai": "^5.0.44",
62
- "algoliasearch": "^5.53.0",
62
+ "algoliasearch": "^5.57.0",
63
63
  "class-variance-authority": "^0.7.1",
64
64
  "clsx": "^2.1.1",
65
65
  "cmdk": "^1.1.1",
66
66
  "date-fns": "^3.6.0",
67
- "firebase": "^12.14.0",
68
- "lucide-react": "^1.17.0",
67
+ "firebase": "^12.18.0",
68
+ "lucide-react": "^1.33.0",
69
69
  "minisearch": "^7.2.0",
70
70
  "moment-timezone": "latest",
71
71
  "qrcode.react": "^4.2.0",
@@ -78,13 +78,14 @@
78
78
  "react-dnd-html5-backend": "^16.0.1",
79
79
  "react-dom": "18.3.1",
80
80
  "react-helmet": "^6.1.0",
81
- "react-hook-form": "^7.77.0",
81
+ "react-hook-form": "^7.85.0",
82
82
  "react-resizable-panels": "^3.0.6",
83
- "react-router": "^7.16.0",
83
+ "react-router": "^7.18.2",
84
84
  "react-window": "^1.8.11",
85
85
  "react-window-infinite-loader": "^1.0.10",
86
86
  "recharts": "^2.15.4",
87
87
  "remark-gfm": "^4.0.1",
88
+ "set-cookie-parser": "^2.7.2",
88
89
  "tailwind-merge": "^2.6.1",
89
90
  "tailwindcss-animate": "^1.0.7",
90
91
  "vite-plugin-eslint": "^1.8.1",
@@ -104,8 +105,8 @@
104
105
  "@types/react-window": "^1.8.8",
105
106
  "@types/react-window-infinite-loader": "^1.0.9",
106
107
  "@vite-pwa/assets-generator": "^1.0.2",
107
- "autoprefixer": "^10.5.0",
108
- "postcss": "^8.5.15",
108
+ "autoprefixer": "^10.5.4",
109
+ "postcss": "^8.5.26",
109
110
  "tailwindcss": "^3.4.19",
110
111
  "vite-plugin-pwa": "^1.3.0"
111
112
  },
@@ -962,24 +962,19 @@ function Collection({
962
962
  setIcon(icon)
963
963
 
964
964
  const listConfig = (await getCachedConfigValue(customization, [...collectionAdminPath, "list"])) as
965
- | ListConfig
966
- | undefined
965
+ ListConfig | undefined
967
966
  setListConfig(listConfig)
968
967
  const cardsConfig = (await getCachedConfigValue(customization, [...collectionAdminPath, "cards"])) as
969
- | CardsConfig
970
- | undefined
968
+ CardsConfig | undefined
971
969
  setCardsConfig(cardsConfig)
972
970
  const imagesConfig = (await getCachedConfigValue(customization, [...collectionAdminPath, "images"])) as
973
- | ImagesConfig
974
- | undefined
971
+ ImagesConfig | undefined
975
972
  setImagesConfig(imagesConfig)
976
973
  const mapConfig = (await getCachedConfigValue(customization, [...collectionAdminPath, "map"])) as
977
- | MapConfig
978
- | undefined
974
+ MapConfig | undefined
979
975
  setMapConfig(mapConfig)
980
976
  const calendarConfig = (await getCachedConfigValue(customization, [...collectionAdminPath, "calendar"])) as
981
- | CalendarConfig
982
- | undefined
977
+ CalendarConfig | undefined
983
978
  setCalendarConfig(calendarConfig)
984
979
 
985
980
  if (calendarConfig?.additionalCollections) {
@@ -1283,8 +1278,7 @@ function Collection({
1283
1278
  }
1284
1279
 
1285
1280
  const rangeFilter = filtersClone.find((filter: Filter) => filter.type === "range") as
1286
- | RangeFilter
1287
- | undefined
1281
+ RangeFilter | undefined
1288
1282
  if (!rangeSelectorState) {
1289
1283
  const customization = getCollectionConfigModule(labels.collection)
1290
1284
  const preloadCacheRangeSelector =
@@ -1952,8 +1946,7 @@ function Collection({
1952
1946
  // TODO: subcollection support
1953
1947
  const data = await getSome([labels.collection], {
1954
1948
  constraints: (isServerReadOnly ? serverConstraints : webConstraints) as
1955
- | [string, WhereFilterOp, unknown][]
1956
- | QueryConstraint[],
1949
+ [string, WhereFilterOp, unknown][] | QueryConstraint[],
1957
1950
  only: isPreloadCacheEnabled ? "cache" : undefined,
1958
1951
  pagination: isPreloadCacheEnabled || (isServerReadOnly && query) ? undefined : { number: 10 },
1959
1952
  noEmbeddingFields: true,
package/src/Dashboard.tsx CHANGED
@@ -92,13 +92,10 @@ export const Dashboard = () => {
92
92
  // eslint-disable-next-line security/detect-object-injection
93
93
  const collectionSchema = schema.collections[dashboardItem.collection]
94
94
  const isPreloadCacheEnabled = preloadCacheEnabled(collectionSchema)
95
- if (
96
- !(
97
- permissions?.Role &&
98
- (!dashboardItem.roles ||
99
- dashboardItem.roles.includes(permissions?.Role))
100
- )
101
- )
95
+ if (!(
96
+ permissions?.Role &&
97
+ (!dashboardItem.roles || dashboardItem.roles.includes(permissions?.Role))
98
+ ))
102
99
  return null
103
100
  let cols = ""
104
101
  if (dashboardItem.kind === "metric") cols = "md:col-span-1"
@@ -236,11 +236,9 @@ export const DashboardReminder = ({ reminder, title, collection }: DashboardRemi
236
236
  let rawB: string
237
237
  if (titleField) {
238
238
  const recordA = Object.values(a[sortingField.name] ?? {})[0] as
239
- | StokerRecord
240
- | undefined
239
+ StokerRecord | undefined
241
240
  const recordB = Object.values(b[sortingField.name] ?? {})[0] as
242
- | StokerRecord
243
- | undefined
241
+ StokerRecord | undefined
244
242
  // eslint-disable-next-line security/detect-object-injection
245
243
  rawA = recordA?.[titleField]?.toString().toLowerCase() ?? ""
246
244
  // eslint-disable-next-line security/detect-object-injection
package/src/Form.tsx CHANGED
@@ -2590,8 +2590,7 @@ function RecordForm({
2590
2590
  const role = permissions.Role
2591
2591
  return convert.filter((convertConfig) => {
2592
2592
  const targetPermissions = permissions.collections?.[convertConfig.collection] as
2593
- | CollectionPermissions
2594
- | undefined
2593
+ CollectionPermissions | undefined
2595
2594
  if (!collectionAccess("Create", targetPermissions as CollectionPermissions)) return false
2596
2595
  if (convertConfig.roles && convertConfig.roles.length > 0) {
2597
2596
  return convertConfig.roles.includes(role)
@@ -4519,7 +4518,19 @@ function RecordForm({
4519
4518
  if (onSuccess) onSuccess()
4520
4519
  }
4521
4520
  },
4522
- [form, formValues, prevState, originalRecord, id, isServerReadOnly, rowSelection],
4521
+ [
4522
+ form,
4523
+ formValues,
4524
+ prevState,
4525
+ originalRecord,
4526
+ id,
4527
+ isServerReadOnly,
4528
+ rowSelection,
4529
+ queuedUploads,
4530
+ queuedImageUploads,
4531
+ uploadFilesToRecord,
4532
+ computeBasePath,
4533
+ ],
4523
4534
  )
4524
4535
 
4525
4536
  const handleDelete = useCallback(async () => {
@@ -4687,8 +4698,7 @@ function RecordForm({
4687
4698
  async (targetCollection: CollectionSchema) => {
4688
4699
  if (!formValues || !originalRecord) return
4689
4700
  const targetPermissions = permissions?.collections?.[targetCollection.labels.collection] as
4690
- | CollectionPermissions
4691
- | undefined
4701
+ CollectionPermissions | undefined
4692
4702
  if (!collectionAccess("Create", targetPermissions as CollectionPermissions)) return
4693
4703
  const record = cloneDeep(originalRecord) as Partial<StokerRecord>
4694
4704
 
@@ -4972,10 +4982,7 @@ function RecordForm({
4972
4982
  if (
4973
4983
  !permissionsCollection.access.operations[
4974
4984
  operation.toLowerCase() as
4975
- | "read"
4976
- | "create"
4977
- | "update"
4978
- | "delete"
4985
+ "read" | "create" | "update" | "delete"
4979
4986
  ]?.includes(role)
4980
4987
  ) {
4981
4988
  return null
@@ -4984,10 +4991,7 @@ function RecordForm({
4984
4991
  collectionPermissionWriteRestrictions &&
4985
4992
  !collectionPermissionWriteRestrictions.operations.includes(
4986
4993
  operation as
4987
- | "Read"
4988
- | "Create"
4989
- | "Update"
4990
- | "Delete",
4994
+ "Read" | "Create" | "Update" | "Delete",
4991
4995
  )
4992
4996
  ) {
4993
4997
  return null
@@ -5232,8 +5236,7 @@ function RecordForm({
5232
5236
  )
5233
5237
  return null
5234
5238
  let parentCollection:
5235
- | CollectionSchema
5236
- | undefined
5239
+ CollectionSchema | undefined
5237
5240
  if (
5238
5241
  restriction.type === "Parent" ||
5239
5242
  restriction.type ===
package/src/List.tsx CHANGED
@@ -549,14 +549,12 @@ export function List({
549
549
  const label = tryFunction(fieldCustomization.admin?.label)
550
550
  const listLabel = tryFunction(fieldCustomization.admin?.listLabel)
551
551
  let className = "whitespace-nowrap text-left"
552
- if (
553
- !(
554
- ((isPreloadCacheEnabled || isServerReadOnly) &&
555
- !["ManyToOne", "ManyToMany"].includes(field.type)) ||
556
- (isSortingEnabled(field, permissions) && field.type !== "Computed") ||
557
- field.name === recordTitleField
558
- )
559
- ) {
552
+ if (!(
553
+ ((isPreloadCacheEnabled || isServerReadOnly) &&
554
+ !["ManyToOne", "ManyToMany"].includes(field.type)) ||
555
+ (isSortingEnabled(field, permissions) && field.type !== "Computed") ||
556
+ field.name === recordTitleField
557
+ )) {
560
558
  className = cn(className, "cursor-default")
561
559
  }
562
560
  if (field.name === recordTitleField) className = cn(className, "text-primary")
@@ -665,11 +663,11 @@ export function List({
665
663
  enableHiding: true,
666
664
  }
667
665
  const field = getField(fields.concat(systemFields), secondarySort.field)
668
- if (field.type === "String") {
666
+ if (field?.type === "String") {
669
667
  hiddenColumn.sortingFn = "stringSortingFn"
670
- } else if (isRelationField(field)) {
668
+ } else if (field && isRelationField(field)) {
671
669
  hiddenColumn.sortingFn = "relationSortingFn"
672
- } else if (field.type === "Timestamp") {
670
+ } else if (field?.type === "Timestamp") {
673
671
  hiddenColumn.sortingFn = "dateSortingFn"
674
672
  } else {
675
673
  hiddenColumn.sortingFn = "rawSortingFn"
@@ -678,7 +676,14 @@ export function List({
678
676
  }
679
677
 
680
678
  return allColumns
681
- }, [fields, isPreloadCacheEnabled, isServerReadOnly, recordTitleField, connectionStatus])
679
+ }, [fields, isPreloadCacheEnabled, isServerReadOnly, recordTitleField, connectionStatus, secondarySort])
680
+
681
+ const columnVisibility = useMemo(() => {
682
+ if (!secondarySort) return {}
683
+ const isListField = fields.some((field) => field.name === secondarySort.field)
684
+ if (isListField) return {}
685
+ return { [secondarySort.field]: false }
686
+ }, [secondarySort, fields])
682
687
 
683
688
  const isServerFullTextSearchActive = isServerFullTextSearch(
684
689
  search,
@@ -769,6 +774,7 @@ export function List({
769
774
  sorting: disableSortingForSearch ? [] : sorting,
770
775
  columnFilters,
771
776
  rowSelection,
777
+ columnVisibility,
772
778
  pagination: {
773
779
  pageSize: tablePageSize,
774
780
  pageIndex: isServerFullTextSearchActive ? 0 : pageIndex,
package/src/Record.tsx CHANGED
@@ -122,12 +122,10 @@ export const Record = ({ collection }: { collection: CollectionSchema }) => {
122
122
  const breadcrumbs = await getCachedConfigValue(customization, [...collectionAdminPath, "breadcrumbs"])
123
123
  setBreadcrumbs(breadcrumbs)
124
124
  const pages = (await getCachedConfigValue(customization, [...collectionAdminPath, "customRecordPages"])) as
125
- | CustomRecordPage[]
126
- | undefined
125
+ CustomRecordPage[] | undefined
127
126
  setCustomRecordPages(pages || [])
128
127
  const assignable = (await getCachedConfigValue(customization, [...collectionAdminPath, "assignable"])) as
129
- | Assignable[]
130
- | undefined
128
+ Assignable[] | undefined
131
129
  setAssignable(assignable)
132
130
 
133
131
  setIsRouteLoading("+", location.pathname)
package/vite.config.ts CHANGED
@@ -8,7 +8,7 @@ import { tryPromise } from "@stoker-platform/node-client"
8
8
  import { watch } from "fs"
9
9
 
10
10
  export default defineConfig(async ({ mode }) => {
11
- const env = loadEnv(mode, __dirname, "")
11
+ const env = loadEnv(mode, import.meta.dirname, "")
12
12
  const skipEslintDisable = (env.SKIP_ESLINT_DISABLE || process.env.SKIP_ESLINT_DISABLE) === "true"
13
13
  const path = join(process.cwd(), "src", "assets", "system-custom", "main.js")
14
14
  const url = pathToFileURL(path).href
@@ -63,7 +63,7 @@ export default defineConfig(async ({ mode }) => {
63
63
  {
64
64
  name: "watch-config",
65
65
  configureServer(server) {
66
- const targetPath = join(__dirname, "src", "assets", "system-custom")
66
+ const targetPath = join(import.meta.dirname, "src", "assets", "system-custom")
67
67
  watch(targetPath, { recursive: true }, (eventType, filename) => {
68
68
  if (filename && (filename.endsWith(".ts") || filename.endsWith(".js"))) {
69
69
  server.moduleGraph.invalidateAll()
@@ -78,9 +78,9 @@ export default defineConfig(async ({ mode }) => {
78
78
  envPrefix: "STOKER_",
79
79
  resolve: {
80
80
  alias: {
81
- "@": resolve(__dirname, "./src"),
82
- react: skipEslintDisable ? resolve(__dirname, "./node_modules/react") : "react",
83
- "react-dom": skipEslintDisable ? resolve(__dirname, "./node_modules/react-dom") : "react-dom",
81
+ "@": resolve(import.meta.dirname, "./src"),
82
+ react: skipEslintDisable ? resolve(import.meta.dirname, "./node_modules/react") : "react",
83
+ "react-dom": skipEslintDisable ? resolve(import.meta.dirname, "./node_modules/react-dom") : "react-dom",
84
84
  },
85
85
  },
86
86
  optimizeDeps: {