1- /*
2- * This file is part of Edgehog.
3- *
4- * Copyright 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 2025, 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
2018
19+ import _ from "lodash" ;
20+ import { useMemo } from "react" ;
2121import { FormattedMessage } from "react-intl" ;
22- import { graphql , usePaginationFragment } from "react-relay/hooks" ;
22+ import { graphql , useFragment } from "react-relay/hooks" ;
2323
24- import type { ApplicationDevicesTable_PaginationQuery } from "@/api/__generated__/ApplicationDevicesTable_PaginationQuery.graphql" ;
2524import type {
26- ApplicationDevicesTable_ReleaseFragment $data,
27- ApplicationDevicesTable_ReleaseFragment $key,
28- } from "@/api/__generated__/ApplicationDevicesTable_ReleaseFragment .graphql" ;
25+ ApplicationDevicesTable_ReleaseEdgeFragment $data,
26+ ApplicationDevicesTable_ReleaseEdgeFragment $key,
27+ } from "@/api/__generated__/ApplicationDevicesTable_ReleaseEdgeFragment .graphql" ;
2928
3029import ConnectionStatus from "@/components/ConnectionStatus" ;
3130import DeploymentStateComponent , {
3231 type DeploymentState ,
3332} from "@/components/DeploymentState" ;
34- import Table , { createColumnHelper } from "@/components/Table" ;
33+ import { createColumnHelper } from "@/components/Table" ;
3534import { Link , Route } from "@/Navigation" ;
35+ import InfiniteTable from "./InfiniteTable" ;
3636
3737// We use graphql fields below in columns configuration
3838/* eslint-disable relay/unused-fields */
3939const APPLICATION_DEVICES_TABLE_FRAGMENT = graphql `
40- fragment ApplicationDevicesTable_ReleaseFragment on Application
41- @refetchable(queryName: "ApplicationDevicesTable_PaginationQuery")
42- @argumentDefinitions(filter: { type: "ReleaseFilterInput" }) {
43- releases(first: $first, after: $after, filter: $filter)
44- @connection(key: "ApplicationDevicesTable_releases") {
45- edges {
46- node {
47- deployments {
48- edges {
49- node {
40+ fragment ApplicationDevicesTable_ReleaseEdgeFragment on ReleaseConnection {
41+ edges {
42+ node {
43+ deployments {
44+ edges {
45+ node {
46+ id
47+ state
48+ isReady
49+ device {
5050 id
51- state
52- isReady
53- device {
54- id
55- name
56- online
57- }
58- release {
59- version
60- }
51+ name
52+ online
53+ }
54+ release {
55+ version
6156 }
6257 }
6358 }
@@ -68,7 +63,7 @@ const APPLICATION_DEVICES_TABLE_FRAGMENT = graphql`
6863` ;
6964
7065type ReleaseRecord = NonNullable <
71- ApplicationDevicesTable_ReleaseFragment $data[ "releases" ] [ "edges" ]
66+ ApplicationDevicesTable_ReleaseEdgeFragment $data[ "edges" ]
7267> [ number ] [ "node" ] ;
7368
7469type TableRecord = NonNullable <
@@ -77,28 +72,30 @@ type TableRecord = NonNullable<
7772
7873type ApplicationDevicesTableProps = {
7974 className ?: string ;
80- applicationDevicesRef : ApplicationDevicesTable_ReleaseFragment$key ;
81- hideSearch ?: boolean ;
75+ applicationDevicesRef : ApplicationDevicesTable_ReleaseEdgeFragment$key ;
76+ loading ?: boolean ;
77+ onLoadMore ?: ( ) => void ;
8278} ;
8379
8480const ApplicationDevicesTable = ( {
8581 className,
8682 applicationDevicesRef,
87- hideSearch = false ,
83+ loading = false ,
84+ onLoadMore,
8885} : ApplicationDevicesTableProps ) => {
89- const { data } = usePaginationFragment <
90- ApplicationDevicesTable_PaginationQuery ,
91- ApplicationDevicesTable_ReleaseFragment$key
92- > ( APPLICATION_DEVICES_TABLE_FRAGMENT , applicationDevicesRef ) ;
86+ const applicationDevicesFragment = useFragment (
87+ APPLICATION_DEVICES_TABLE_FRAGMENT ,
88+ applicationDevicesRef || null ,
89+ ) ;
90+ const releases = useMemo < ReleaseRecord [ ] > ( ( ) => {
91+ return (
92+ _ . compact ( applicationDevicesFragment ?. edges ?. map ( ( e ) => e ?. node ) ) ?? [ ]
93+ ) ;
94+ } , [ applicationDevicesFragment ] ) ;
9395
94- const releasesData =
95- data . releases . edges ?. map ( ( edge ) => ( {
96- deployments :
97- edge . node . deployments . edges ?. map (
98- ( deploymentEdge ) => deploymentEdge . node ,
99- ) ?? [ ] ,
100- } ) ) ?? [ ] ;
101- const tableData = releasesData . flatMap ( ( release ) => release . deployments ) ;
96+ const tableData = releases . flatMap (
97+ ( release ) => release . deployments ?. edges ?. map ( ( edge ) => edge . node ) ?? [ ] ,
98+ ) ;
10299
103100 const columnHelper = createColumnHelper < TableRecord > ( ) ;
104101 const columns = [
@@ -158,11 +155,13 @@ const ApplicationDevicesTable = ({
158155
159156 return (
160157 < div >
161- < Table
158+ < InfiniteTable
162159 className = { className }
163160 columns = { columns }
164161 data = { tableData }
165- hideSearch = { hideSearch }
162+ loading = { loading }
163+ onLoadMore = { onLoadMore }
164+ hideSearch
166165 />
167166 </ div >
168167 ) ;
0 commit comments