|
1 | | -/* |
2 | | - * This file is part of Edgehog. |
3 | | - * |
4 | | - * Copyright 2023-2025 SECO Mind Srl |
5 | | - * |
6 | | - * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | | - * you may not use this file except in compliance with the License. |
8 | | - * You may obtain a copy of the License at |
9 | | - * |
10 | | - * http://www.apache.org/licenses/LICENSE-2.0 |
11 | | - * |
12 | | - * Unless required by applicable law or agreed to in writing, software |
13 | | - * distributed under the License is distributed on an "AS IS" BASIS, |
14 | | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | | - * See the License for the specific language governing permissions and |
16 | | - * limitations under the License. |
17 | | - * |
18 | | - * SPDX-License-Identifier: Apache-2.0 |
19 | | - */ |
| 1 | +// This file is part of Edgehog. |
| 2 | +// |
| 3 | +// Copyright 2023-2026 SECO Mind Srl |
| 4 | +// |
| 5 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +// you may not use this file except in compliance with the License. |
| 7 | +// You may obtain a copy of the License at |
| 8 | +// |
| 9 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +// |
| 11 | +// Unless required by applicable law or agreed to in writing, software |
| 12 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +// See the License for the specific language governing permissions and |
| 15 | +// limitations under the License. |
| 16 | +// |
| 17 | +// SPDX-License-Identifier: Apache-2.0 |
20 | 18 |
|
21 | | -import { useCallback, useEffect, useMemo, useState } from "react"; |
22 | | -import { FormattedMessage } from "react-intl"; |
23 | | -import { graphql, usePaginationFragment } from "react-relay/hooks"; |
24 | 19 | import _ from "lodash"; |
| 20 | +import { useMemo } from "react"; |
| 21 | +import { FormattedMessage } from "react-intl"; |
| 22 | +import { graphql, useFragment } from "react-relay/hooks"; |
25 | 23 |
|
26 | | -import type { BaseImagesTable_PaginationQuery } from "@/api/__generated__/BaseImagesTable_PaginationQuery.graphql"; |
27 | 24 | import type { |
28 | | - BaseImagesTable_BaseImagesFragment$data, |
29 | | - BaseImagesTable_BaseImagesFragment$key, |
30 | | -} from "@/api/__generated__/BaseImagesTable_BaseImagesFragment.graphql"; |
| 25 | + BaseImagesTable_BaseImageEdgeFragment$data, |
| 26 | + BaseImagesTable_BaseImageEdgeFragment$key, |
| 27 | +} from "@/api/__generated__/BaseImagesTable_BaseImageEdgeFragment.graphql"; |
31 | 28 |
|
32 | | -import { createColumnHelper } from "@/components/Table"; |
33 | 29 | import InfiniteTable from "@/components/InfiniteTable"; |
| 30 | +import { createColumnHelper } from "@/components/Table"; |
34 | 31 | import { Link, Route } from "@/Navigation"; |
35 | | -import { RECORDS_TO_LOAD_FIRST, RECORDS_TO_LOAD_NEXT } from "@/constants"; |
36 | 32 |
|
37 | 33 | // We use graphql fields below in columns configuration |
38 | 34 | /* eslint-disable relay/unused-fields */ |
39 | 35 | const BASE_IMAGES_TABLE_FRAGMENT = graphql` |
40 | | - fragment BaseImagesTable_BaseImagesFragment on BaseImageCollection |
41 | | - @refetchable(queryName: "BaseImagesTable_PaginationQuery") |
42 | | - @argumentDefinitions(filter: { type: "BaseImageFilterInput" }) { |
43 | | - id |
44 | | - baseImages(first: $first, after: $after, filter: $filter) |
45 | | - @connection(key: "BaseImagesTable_baseImages") { |
46 | | - edges { |
47 | | - node { |
48 | | - id |
49 | | - version |
50 | | - startingVersionRequirement |
51 | | - localizedReleaseDisplayNames { |
52 | | - value |
53 | | - languageTag |
54 | | - } |
| 36 | + fragment BaseImagesTable_BaseImageEdgeFragment on BaseImageConnection { |
| 37 | + edges { |
| 38 | + node { |
| 39 | + id |
| 40 | + version |
| 41 | + startingVersionRequirement |
| 42 | + localizedReleaseDisplayNames { |
| 43 | + value |
| 44 | + languageTag |
55 | 45 | } |
56 | 46 | } |
57 | 47 | } |
58 | 48 | } |
59 | 49 | `; |
60 | 50 |
|
61 | 51 | type TableRecord = NonNullable< |
62 | | - NonNullable<BaseImagesTable_BaseImagesFragment$data["baseImages"]>["edges"] |
| 52 | + NonNullable<BaseImagesTable_BaseImageEdgeFragment$data>["edges"] |
63 | 53 | >[number]["node"]; |
64 | 54 |
|
65 | 55 | const columnHelper = createColumnHelper<TableRecord>(); |
@@ -113,99 +103,40 @@ const getColumnsDefinition = (baseImageCollectionId: string) => [ |
113 | 103 |
|
114 | 104 | type Props = { |
115 | 105 | className?: string; |
116 | | - baseImageCollectionRef: BaseImagesTable_BaseImagesFragment$key; |
117 | | - hideSearch?: boolean; |
| 106 | + baseImagesRef: BaseImagesTable_BaseImageEdgeFragment$key; |
| 107 | + baseImageCollectionId: string; |
| 108 | + loading?: boolean; |
| 109 | + onLoadMore?: () => void; |
118 | 110 | }; |
119 | 111 |
|
120 | 112 | const BaseImagesTable = ({ |
121 | 113 | className, |
122 | | - baseImageCollectionRef, |
123 | | - hideSearch = false, |
| 114 | + baseImagesRef, |
| 115 | + baseImageCollectionId, |
| 116 | + loading = false, |
| 117 | + onLoadMore, |
124 | 118 | }: Props) => { |
125 | | - const { |
126 | | - data: paginationData, |
127 | | - loadNext, |
128 | | - hasNext, |
129 | | - isLoadingNext, |
130 | | - refetch, |
131 | | - } = usePaginationFragment< |
132 | | - BaseImagesTable_PaginationQuery, |
133 | | - BaseImagesTable_BaseImagesFragment$key |
134 | | - >(BASE_IMAGES_TABLE_FRAGMENT, baseImageCollectionRef); |
135 | | - |
136 | | - const [searchText, setSearchText] = useState<string | null>(null); |
137 | | - |
138 | | - const columns = useMemo( |
139 | | - () => getColumnsDefinition(paginationData.id), |
140 | | - [paginationData.id], |
| 119 | + const baseImagesFragment = useFragment( |
| 120 | + BASE_IMAGES_TABLE_FRAGMENT, |
| 121 | + baseImagesRef || null, |
141 | 122 | ); |
| 123 | + const baseImages = useMemo<TableRecord[]>(() => { |
| 124 | + return _.compact(baseImagesFragment?.edges?.map((e) => e?.node)) ?? []; |
| 125 | + }, [baseImagesFragment]); |
142 | 126 |
|
143 | | - const debounceRefetch = useMemo( |
144 | | - () => |
145 | | - _.debounce((text: string) => { |
146 | | - if (text === "") { |
147 | | - refetch( |
148 | | - { |
149 | | - first: RECORDS_TO_LOAD_FIRST, |
150 | | - }, |
151 | | - { fetchPolicy: "network-only" }, |
152 | | - ); |
153 | | - } else { |
154 | | - refetch( |
155 | | - { |
156 | | - first: RECORDS_TO_LOAD_FIRST, |
157 | | - filter: { |
158 | | - or: [ |
159 | | - { version: { ilike: `%${text}%` } }, |
160 | | - { url: { ilike: `%${text}%` } }, |
161 | | - { |
162 | | - startingVersionRequirement: { |
163 | | - ilike: `%${text}%`, |
164 | | - }, |
165 | | - }, |
166 | | - ], |
167 | | - }, |
168 | | - }, |
169 | | - { fetchPolicy: "network-only" }, |
170 | | - ); |
171 | | - } |
172 | | - }, 500), |
173 | | - [refetch], |
| 127 | + const columns = useMemo( |
| 128 | + () => getColumnsDefinition(baseImageCollectionId), |
| 129 | + [baseImageCollectionId], |
174 | 130 | ); |
175 | 131 |
|
176 | | - useEffect(() => { |
177 | | - if (searchText !== null) { |
178 | | - debounceRefetch(searchText); |
179 | | - } |
180 | | - }, [debounceRefetch, searchText]); |
181 | | - |
182 | | - const loadNextBaseImageCollections = useCallback(() => { |
183 | | - if (hasNext && !isLoadingNext) { |
184 | | - loadNext(RECORDS_TO_LOAD_NEXT); |
185 | | - } |
186 | | - }, [hasNext, isLoadingNext, loadNext]); |
187 | | - |
188 | | - const baseImages = useMemo(() => { |
189 | | - return ( |
190 | | - paginationData.baseImages?.edges |
191 | | - ?.map((edge) => edge?.node) |
192 | | - .filter((node): node is TableRecord => node != null) ?? [] |
193 | | - ); |
194 | | - }, [paginationData]); |
195 | | - |
196 | | - if (!paginationData.baseImages) { |
197 | | - return null; |
198 | | - } |
199 | | - |
200 | 132 | return ( |
201 | 133 | <InfiniteTable |
202 | 134 | className={className} |
203 | 135 | columns={columns} |
204 | 136 | data={baseImages} |
205 | | - loading={isLoadingNext} |
206 | | - onLoadMore={hasNext ? loadNextBaseImageCollections : undefined} |
207 | | - setSearchText={setSearchText} |
208 | | - hideSearch={hideSearch} |
| 137 | + loading={loading} |
| 138 | + onLoadMore={onLoadMore} |
| 139 | + hideSearch |
209 | 140 | /> |
210 | 141 | ); |
211 | 142 | }; |
|
0 commit comments