@stoker-platform/web-app 0.5.203 → 0.5.205

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.205
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: fix filter clearing issue
8
+
9
+ ## 0.5.204
10
+
11
+ ### Patch Changes
12
+
13
+ - feat: add record sidebar filters
14
+ - @stoker-platform/node-client@0.5.80
15
+ - @stoker-platform/utils@0.5.71
16
+ - @stoker-platform/web-client@0.5.84
17
+
3
18
  ## 0.5.203
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.203",
3
+ "version": "0.5.205",
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.79",
55
- "@stoker-platform/utils": "0.5.70",
56
- "@stoker-platform/web-client": "0.5.83",
54
+ "@stoker-platform/node-client": "0.5.80",
55
+ "@stoker-platform/utils": "0.5.71",
56
+ "@stoker-platform/web-client": "0.5.84",
57
57
  "@tanstack/react-table": "^8.21.3",
58
58
  "@types/react": "18.3.13",
59
59
  "@types/react-dom": "18.3.1",
@@ -1359,6 +1359,9 @@ function Collection({
1359
1359
  }
1360
1360
  }
1361
1361
  })
1362
+ if (relationList.showFilters) {
1363
+ excluded.push(...relationList.showFilters)
1364
+ }
1362
1365
  }
1363
1366
  return excluded
1364
1367
  }, [isPreloadCacheEnabled, cardsConfig, statusField, tab, filters])
package/src/Filters.tsx CHANGED
@@ -58,6 +58,7 @@ interface FiltersProps {
58
58
  relationParent?: StokerRecord
59
59
  assignable?: Assignable
60
60
  isAssigning?: boolean
61
+ isSidebar?: boolean
61
62
  }
62
63
 
63
64
  export function Filters({
@@ -68,6 +69,7 @@ export function Filters({
68
69
  relationParent,
69
70
  assignable,
70
71
  isAssigning,
72
+ isSidebar,
71
73
  }: FiltersProps) {
72
74
  const { labels, fields } = collection
73
75
  const location = useLocation()
@@ -830,6 +832,13 @@ export function Filters({
830
832
  filters.forEach((filter) => {
831
833
  if (filter.type === "status" || filter.type === "range") return
832
834
  if (relationList && relationList.field === filter.field) return
835
+ if (
836
+ "condition" in filter &&
837
+ filter.condition &&
838
+ !filter.condition(relationCollection, relationParent, isAssigning)
839
+ )
840
+ return
841
+ if (isSidebar && !relationList?.showFilters?.includes(filter.field)) return
833
842
  const field = getField(fields, filter.field)
834
843
  if (!field) return
835
844
  if (filter.type === "select") {
package/src/Record.tsx CHANGED
@@ -30,6 +30,7 @@ import { serverReadOnly } from "./utils/serverReadOnly"
30
30
  import { useRouteLoading } from "./providers/LoadingProvider"
31
31
  import { getRelationFields } from "./utils/getRelationFields"
32
32
  import { FiltersProvider } from "./providers/FiltersProvider"
33
+ import { SidebarFilters } from "./SidebarFilters"
33
34
  import Collection from "./Collection"
34
35
  import { Breadcrumbs } from "./Breadcrumbs"
35
36
  import { Separator } from "./components/ui/separator"
@@ -82,6 +83,7 @@ export const Record = ({ collection }: { collection: CollectionSchema }) => {
82
83
 
83
84
  const [isAssigning, setIsAssigning] = useState<Record<string, boolean>>({})
84
85
  const [assignable, setAssignable] = useState<Assignable[] | undefined>(undefined)
86
+ const [sidebarFiltersContainer, setSidebarFiltersContainer] = useState<HTMLDivElement | null>(null)
85
87
 
86
88
  useEffect(() => {
87
89
  if (id && record && record.id !== id) {
@@ -213,6 +215,7 @@ export const Record = ({ collection }: { collection: CollectionSchema }) => {
213
215
  customRecordPages={customRecordPages}
214
216
  isAssigning={isAssigning}
215
217
  setIsAssigning={setIsAssigning}
218
+ filtersContainerRef={setSidebarFiltersContainer}
216
219
  />
217
220
  <Routes>
218
221
  <Route
@@ -277,6 +280,25 @@ export const Record = ({ collection }: { collection: CollectionSchema }) => {
277
280
  </div>
278
281
  </>
279
282
  )}
283
+ {sidebarFiltersContainer && (
284
+ <SidebarFilters
285
+ key={`${relationList.collection}-sidebar-filters`}
286
+ container={sidebarFiltersContainer}
287
+ collection={relationCollection}
288
+ relationList={relationList}
289
+ relationCollection={collection}
290
+ relationParent={record}
291
+ assignable={assignable?.find(
292
+ (item: Assignable) =>
293
+ item.collection === relationList.collection,
294
+ )}
295
+ isAssigning={
296
+ isAssigning?.[
297
+ relationList.collection.toLowerCase()
298
+ ]
299
+ }
300
+ />
301
+ )}
280
302
  <Collection
281
303
  key={`${relationList.collection}-collection`}
282
304
  collection={relationCollection}
@@ -35,12 +35,14 @@ export const RecordSidebar = ({
35
35
  customRecordPages,
36
36
  isAssigning,
37
37
  setIsAssigning,
38
+ filtersContainerRef,
38
39
  }: {
39
40
  record: StokerRecord
40
41
  collection: CollectionSchema
41
42
  customRecordPages?: CustomRecordPage[]
42
43
  isAssigning: Record<string, boolean>
43
44
  setIsAssigning: (isAssigning: Record<string, boolean>) => void
45
+ filtersContainerRef?: (element: HTMLDivElement | null) => void
44
46
  }) => {
45
47
  const { labels } = collection
46
48
  const { path, id } = useParams()
@@ -308,6 +310,7 @@ export const RecordSidebar = ({
308
310
  )}
309
311
  </div>
310
312
  </SidebarMenu>
313
+ <div ref={filtersContainerRef} />
311
314
  </SidebarGroupContent>
312
315
  </SidebarGroup>
313
316
  </SidebarContent>
@@ -0,0 +1,59 @@
1
+ import { Assignable, CollectionSchema, RelationList, StokerRecord } from "@stoker-platform/types"
2
+ import { useMemo } from "react"
3
+ import { createPortal } from "react-dom"
4
+ import { Filters } from "./Filters"
5
+ import { useFilters } from "./providers/FiltersProvider"
6
+ import { Separator } from "./components/ui/separator"
7
+
8
+ export const SidebarFilters = ({
9
+ container,
10
+ collection,
11
+ relationList,
12
+ relationCollection,
13
+ relationParent,
14
+ assignable,
15
+ isAssigning,
16
+ }: {
17
+ container: HTMLElement
18
+ collection: CollectionSchema
19
+ relationList: RelationList
20
+ relationCollection: CollectionSchema
21
+ relationParent: StokerRecord
22
+ assignable?: Assignable
23
+ isAssigning?: boolean
24
+ }) => {
25
+ const { filters } = useFilters()
26
+ const showFilters = relationList.showFilters
27
+
28
+ const excluded = useMemo(
29
+ () =>
30
+ filters
31
+ .filter((filter) => filter.type !== "status" && filter.type !== "range")
32
+ .map((filter) => filter.field)
33
+ .filter((field) => !showFilters?.includes(field)),
34
+ [filters, showFilters],
35
+ )
36
+
37
+ if (!showFilters?.length) return null
38
+ const hasFiltersToShow = filters.some(
39
+ (filter) => filter.type !== "status" && filter.type !== "range" && showFilters.includes(filter.field),
40
+ )
41
+ if (!hasFiltersToShow) return null
42
+
43
+ return createPortal(
44
+ <div className="flex flex-col gap-4 px-2 pt-2">
45
+ <Separator />
46
+ <Filters
47
+ collection={collection}
48
+ excluded={excluded}
49
+ relationList={relationList}
50
+ relationCollection={relationCollection}
51
+ relationParent={relationParent}
52
+ assignable={assignable}
53
+ isAssigning={isAssigning}
54
+ isSidebar={true}
55
+ />
56
+ </div>,
57
+ container,
58
+ )
59
+ }
@@ -51,5 +51,23 @@ export const getFilterDisjunctions = (collection: CollectionSchema, options?: Fi
51
51
  incrementDisjunctions(2)
52
52
  }
53
53
  }
54
+ if (
55
+ options?.isAssigning &&
56
+ options.relationList &&
57
+ options.relationParent?.id &&
58
+ options.assignable?.includeValueInFilters?.length &&
59
+ options.filters
60
+ ) {
61
+ const activeOrCount = options.filters.filter(
62
+ (filter) =>
63
+ filter.type === "select" &&
64
+ filter.value &&
65
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
66
+ options.assignable!.includeValueInFilters!.some((item) => item.field === filter.field),
67
+ ).length
68
+ for (let i = 0; i < activeOrCount; i++) {
69
+ incrementDisjunctions(2)
70
+ }
71
+ }
54
72
  return disjunctions
55
73
  }