@stoker-platform/web-app 0.5.164 → 0.5.166
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 +15 -0
- package/package.json +4 -4
- package/src/Collection.tsx +18 -0
- package/src/List.tsx +122 -68
- package/src/utils/getSortingValue.ts +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @stoker-platform/web-app
|
|
2
2
|
|
|
3
|
+
## 0.5.166
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat: improve secondary sort feature
|
|
8
|
+
|
|
9
|
+
## 0.5.165
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- feat: add secondary sort feature
|
|
14
|
+
- @stoker-platform/node-client@0.5.66
|
|
15
|
+
- @stoker-platform/utils@0.5.57
|
|
16
|
+
- @stoker-platform/web-client@0.5.67
|
|
17
|
+
|
|
3
18
|
## 0.5.164
|
|
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.
|
|
3
|
+
"version": "0.5.166",
|
|
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.56.0",
|
|
54
|
-
"@stoker-platform/node-client": "0.5.
|
|
55
|
-
"@stoker-platform/utils": "0.5.
|
|
56
|
-
"@stoker-platform/web-client": "0.5.
|
|
54
|
+
"@stoker-platform/node-client": "0.5.66",
|
|
55
|
+
"@stoker-platform/utils": "0.5.57",
|
|
56
|
+
"@stoker-platform/web-client": "0.5.67",
|
|
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/Collection.tsx
CHANGED
|
@@ -183,6 +183,13 @@ function Collection({
|
|
|
183
183
|
}
|
|
184
184
|
| undefined
|
|
185
185
|
>(undefined)
|
|
186
|
+
const [secondarySort, setSecondarySort] = useState<
|
|
187
|
+
| {
|
|
188
|
+
field: string
|
|
189
|
+
direction?: "asc" | "desc"
|
|
190
|
+
}
|
|
191
|
+
| undefined
|
|
192
|
+
>(undefined)
|
|
186
193
|
|
|
187
194
|
const [state, setStokerState] = useStokerState()
|
|
188
195
|
const setState = useCallback(
|
|
@@ -1194,6 +1201,16 @@ function Collection({
|
|
|
1194
1201
|
}
|
|
1195
1202
|
| undefined
|
|
1196
1203
|
setDefaultSort(defaultSortOverride || defaultSort)
|
|
1204
|
+
const secondarySort = (await getCachedConfigValue(customization, [
|
|
1205
|
+
...collectionAdminPath,
|
|
1206
|
+
"secondarySort",
|
|
1207
|
+
])) as
|
|
1208
|
+
| {
|
|
1209
|
+
field: string
|
|
1210
|
+
direction?: "asc" | "desc"
|
|
1211
|
+
}
|
|
1212
|
+
| undefined
|
|
1213
|
+
setSecondarySort(secondarySort)
|
|
1197
1214
|
const sortState = state[`collection-sort-${labels.collection.toLowerCase()}`]
|
|
1198
1215
|
if (sortState && !relationList) {
|
|
1199
1216
|
const newSorting = JSON.parse(sortState)
|
|
@@ -2513,6 +2530,7 @@ function Collection({
|
|
|
2513
2530
|
setBackToStartKey={setBackToStartKey}
|
|
2514
2531
|
search={search}
|
|
2515
2532
|
defaultSort={defaultSort}
|
|
2533
|
+
secondarySort={secondarySort}
|
|
2516
2534
|
setOptimisticList={setOptimisticList}
|
|
2517
2535
|
relationList={relationList}
|
|
2518
2536
|
relationCollection={relationCollection}
|
package/src/List.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
getCachedConfigValue,
|
|
20
20
|
getField,
|
|
21
21
|
getFieldCustomization,
|
|
22
|
+
getSystemFieldsSchema,
|
|
22
23
|
isRelationField,
|
|
23
24
|
isSortingEnabled,
|
|
24
25
|
tryFunction,
|
|
@@ -212,6 +213,12 @@ interface ListProps {
|
|
|
212
213
|
direction?: "asc" | "desc"
|
|
213
214
|
}
|
|
214
215
|
| undefined
|
|
216
|
+
secondarySort:
|
|
217
|
+
| {
|
|
218
|
+
field: string
|
|
219
|
+
direction?: "asc" | "desc"
|
|
220
|
+
}
|
|
221
|
+
| undefined
|
|
215
222
|
setOptimisticList: () => void
|
|
216
223
|
relationList?: RelationList
|
|
217
224
|
relationCollection?: CollectionSchema
|
|
@@ -237,6 +244,7 @@ export function List({
|
|
|
237
244
|
setBackToStartKey,
|
|
238
245
|
search,
|
|
239
246
|
defaultSort,
|
|
247
|
+
secondarySort,
|
|
240
248
|
setOptimisticList,
|
|
241
249
|
relationList,
|
|
242
250
|
relationCollection,
|
|
@@ -246,6 +254,7 @@ export function List({
|
|
|
246
254
|
hasBreadcrumbs,
|
|
247
255
|
}: ListProps) {
|
|
248
256
|
const { labels, fields, access, recordTitleField, softDelete, fullTextSearch } = collection
|
|
257
|
+
const systemFields = getSystemFieldsSchema()
|
|
249
258
|
const { serverWriteOnly } = access
|
|
250
259
|
const softDeleteField = softDelete?.archivedField
|
|
251
260
|
const softDeleteTimestampField = softDelete?.timestampField
|
|
@@ -632,7 +641,31 @@ export function List({
|
|
|
632
641
|
})
|
|
633
642
|
.filter(Boolean) as ColumnDef<StokerRecord>[]
|
|
634
643
|
|
|
635
|
-
|
|
644
|
+
const allColumns = [selectColumnDef, ...fieldColumns]
|
|
645
|
+
|
|
646
|
+
if (secondarySort && !allColumns.some((column) => column.id === secondarySort.field)) {
|
|
647
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
648
|
+
const hiddenColumn: any = {
|
|
649
|
+
id: secondarySort.field,
|
|
650
|
+
accessorKey: secondarySort.field,
|
|
651
|
+
header: () => null,
|
|
652
|
+
cell: () => null,
|
|
653
|
+
enableHiding: true,
|
|
654
|
+
}
|
|
655
|
+
const field = getField(fields.concat(systemFields), secondarySort.field)
|
|
656
|
+
if (field.type === "String") {
|
|
657
|
+
hiddenColumn.sortingFn = "stringSortingFn"
|
|
658
|
+
} else if (isRelationField(field)) {
|
|
659
|
+
hiddenColumn.sortingFn = "relationSortingFn"
|
|
660
|
+
} else if (field.type === "Timestamp") {
|
|
661
|
+
hiddenColumn.sortingFn = "dateSortingFn"
|
|
662
|
+
} else {
|
|
663
|
+
hiddenColumn.sortingFn = "rawSortingFn"
|
|
664
|
+
}
|
|
665
|
+
allColumns.push(hiddenColumn as ColumnDef<StokerRecord>)
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
return allColumns
|
|
636
669
|
}, [fields, isPreloadCacheEnabled, isServerReadOnly, recordTitleField, connectionStatus])
|
|
637
670
|
|
|
638
671
|
const isSearchRelevanceOrder = !!(search && isPreloadCacheEnabled)
|
|
@@ -838,7 +871,10 @@ export function List({
|
|
|
838
871
|
} else if (recordTitleField) {
|
|
839
872
|
setSorting([{ id: recordTitleField, desc: false }])
|
|
840
873
|
}
|
|
841
|
-
|
|
874
|
+
if ((isPreloadCacheEnabled || isServerReadOnly) && secondarySort) {
|
|
875
|
+
setSorting((prev) => [...prev, { id: secondarySort.field, desc: secondarySort.direction === "desc" }])
|
|
876
|
+
}
|
|
877
|
+
}, [table, recordTitleField, secondarySort, isPreloadCacheEnabled, isServerReadOnly])
|
|
842
878
|
|
|
843
879
|
useEffect(() => {
|
|
844
880
|
if (isPreloadCacheEnabled || isServerReadOnly) {
|
|
@@ -1725,29 +1761,39 @@ export function List({
|
|
|
1725
1761
|
{headerGroup.headers.map((header) => {
|
|
1726
1762
|
let className = ""
|
|
1727
1763
|
if (header.id !== "select") {
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
)
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1764
|
+
if (
|
|
1765
|
+
!systemFields.some(
|
|
1766
|
+
(systemField) => systemField.name === header.id,
|
|
1767
|
+
)
|
|
1768
|
+
) {
|
|
1769
|
+
const field = getField(fields, header.id)
|
|
1770
|
+
const fieldCustomization = getFieldCustomization(
|
|
1771
|
+
field,
|
|
1772
|
+
customization,
|
|
1773
|
+
)
|
|
1774
|
+
const hidden = tryFunction(fieldCustomization.admin?.hidden)
|
|
1775
|
+
if (hidden) {
|
|
1776
|
+
switch (hidden) {
|
|
1777
|
+
case "sm":
|
|
1778
|
+
className = cn(className, "hidden", "sm:table-cell")
|
|
1779
|
+
break
|
|
1780
|
+
case "md":
|
|
1781
|
+
className = cn(className, "hidden", "md:table-cell")
|
|
1782
|
+
break
|
|
1783
|
+
case "lg":
|
|
1784
|
+
className = cn(className, "hidden", "lg:table-cell")
|
|
1785
|
+
break
|
|
1786
|
+
case "xl":
|
|
1787
|
+
className = cn(className, "hidden", "xl:table-cell")
|
|
1788
|
+
break
|
|
1789
|
+
case "2xl":
|
|
1790
|
+
className = cn(
|
|
1791
|
+
className,
|
|
1792
|
+
"hidden",
|
|
1793
|
+
"2xl:table-cell",
|
|
1794
|
+
)
|
|
1795
|
+
break
|
|
1796
|
+
}
|
|
1751
1797
|
}
|
|
1752
1798
|
}
|
|
1753
1799
|
} else {
|
|
@@ -1795,50 +1841,58 @@ export function List({
|
|
|
1795
1841
|
{row.getVisibleCells().map((cell: Cell<unknown, unknown>) => {
|
|
1796
1842
|
let className = "p-0"
|
|
1797
1843
|
const id = cell.column.columnDef.id
|
|
1844
|
+
const field = getField(fields.concat(systemFields), id)
|
|
1798
1845
|
if (id !== "select") {
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
)
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1846
|
+
if (
|
|
1847
|
+
!systemFields.some(
|
|
1848
|
+
(systemField) => systemField.name === id,
|
|
1849
|
+
)
|
|
1850
|
+
) {
|
|
1851
|
+
const fieldCustomization = getFieldCustomization(
|
|
1852
|
+
field,
|
|
1853
|
+
customization,
|
|
1854
|
+
)
|
|
1855
|
+
const hidden = tryFunction(
|
|
1856
|
+
fieldCustomization.admin?.hidden,
|
|
1857
|
+
)
|
|
1858
|
+
if (hidden) {
|
|
1859
|
+
switch (hidden) {
|
|
1860
|
+
case "sm":
|
|
1861
|
+
className = cn(
|
|
1862
|
+
className,
|
|
1863
|
+
"hidden",
|
|
1864
|
+
"sm:table-cell",
|
|
1865
|
+
)
|
|
1866
|
+
break
|
|
1867
|
+
case "md":
|
|
1868
|
+
className = cn(
|
|
1869
|
+
className,
|
|
1870
|
+
"hidden",
|
|
1871
|
+
"md:table-cell",
|
|
1872
|
+
)
|
|
1873
|
+
break
|
|
1874
|
+
case "lg":
|
|
1875
|
+
className = cn(
|
|
1876
|
+
className,
|
|
1877
|
+
"hidden",
|
|
1878
|
+
"lg:table-cell",
|
|
1879
|
+
)
|
|
1880
|
+
break
|
|
1881
|
+
case "xl":
|
|
1882
|
+
className = cn(
|
|
1883
|
+
className,
|
|
1884
|
+
"hidden",
|
|
1885
|
+
"xl:table-cell",
|
|
1886
|
+
)
|
|
1887
|
+
break
|
|
1888
|
+
case "2xl":
|
|
1889
|
+
className = cn(
|
|
1890
|
+
className,
|
|
1891
|
+
"hidden",
|
|
1892
|
+
"2xl:table-cell",
|
|
1893
|
+
)
|
|
1894
|
+
break
|
|
1895
|
+
}
|
|
1842
1896
|
}
|
|
1843
1897
|
}
|
|
1844
1898
|
if (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getField, getFieldCustomization, tryFunction } from "@stoker-platform/utils"
|
|
1
|
+
import { getField, getFieldCustomization, getSystemFieldsSchema, tryFunction } from "@stoker-platform/utils"
|
|
2
2
|
import { CollectionCustomization, CollectionSchema, StokerRecord } from "@stoker-platform/types"
|
|
3
3
|
|
|
4
4
|
export const getSortingValue = (
|
|
@@ -10,6 +10,11 @@ export const getSortingValue = (
|
|
|
10
10
|
parentRecord?: StokerRecord,
|
|
11
11
|
) => {
|
|
12
12
|
const { fields } = collection
|
|
13
|
+
const systemFields = getSystemFieldsSchema()
|
|
14
|
+
if (systemFields.some((systemField) => systemField.name === field)) {
|
|
15
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
16
|
+
return record[field]
|
|
17
|
+
}
|
|
13
18
|
const fieldSchema = getField(fields, field)
|
|
14
19
|
const fieldCustomization = getFieldCustomization(fieldSchema, customization)
|
|
15
20
|
// eslint-disable-next-line security/detect-object-injection
|