11import { Typography } from "@material-ui/core" ;
22import { ObjectsTable , ObjectsTableDetailField , TableColumn , TableState } from "d2-ui-components" ;
33import _ from "lodash" ;
4- import React , { useEffect , useState } from "react" ;
4+ import React , { useCallback , useEffect , useMemo , useState } from "react" ;
55import { ProgramEvent } from "../../../../../domain/events/entities/ProgramEvent" ;
66import { DataElement , Program } from "../../../../../domain/metadata/entities/MetadataEntities" ;
77import i18n from "../../../../../locales" ;
8+ import SyncRule from "../../../../../models/syncRule" ;
89import { useAppContext } from "../../../contexts/AppContext" ;
910import Dropdown from "../../dropdown/Dropdown" ;
1011import { Toggle } from "../../toggle/Toggle" ;
@@ -20,30 +21,127 @@ type CustomProgram = Program & {
2021
2122export default function EventsSelectionStep ( { syncRule, onChange } : SyncWizardStepProps ) {
2223 const { compositionRoot } = useAppContext ( ) ;
24+
25+ const [ memoizedSyncRule ] = useState < SyncRule > ( syncRule ) ;
2326 const [ objects , setObjects ] = useState < ProgramEvent [ ] | undefined > ( ) ;
2427 const [ programs , setPrograms ] = useState < CustomProgram [ ] > ( [ ] ) ;
2528 const [ programFilter , changeProgramFilter ] = useState < string > ( "" ) ;
26- const [ error , setError ] = useState ( ) ;
29+ const [ error , setError ] = useState < unknown > ( ) ;
30+
31+ useEffect ( ( ) => {
32+ const sync = compositionRoot . sync . events ( memoizedSyncRule . toBuilder ( ) ) ;
33+ sync . extractMetadata < CustomProgram > ( ) . then ( ( { programs = [ ] } ) => setPrograms ( programs ) ) ;
34+ } , [ memoizedSyncRule , compositionRoot ] ) ;
2735
2836 useEffect ( ( ) => {
37+ if ( programs . length === 0 ) return ;
2938 compositionRoot . events
3039 . list (
3140 {
32- ...syncRule . dataParams ,
41+ ...memoizedSyncRule . dataParams ,
3342 allEvents : true ,
3443 } ,
3544 programs . map ( ( { id } ) => id )
3645 )
3746 . then ( setObjects )
3847 . catch ( setError ) ;
39- } , [ compositionRoot , syncRule , programs ] ) ;
48+ } , [ compositionRoot , memoizedSyncRule , programs ] ) ;
4049
41- useEffect ( ( ) => {
42- const sync = compositionRoot . sync . events ( syncRule . toBuilder ( ) ) ;
43- sync . extractMetadata < CustomProgram > ( ) . then ( ( { programs = [ ] } ) => setPrograms ( programs ) ) ;
44- } , [ syncRule , compositionRoot ] ) ;
50+ const handleTableChange = useCallback (
51+ ( tableState : TableState < ProgramEvent > ) => {
52+ const { selection } = tableState ;
53+ onChange ( syncRule . updateDataSyncEvents ( selection . map ( ( { id } ) => id ) ) ) ;
54+ } ,
55+ [ onChange , syncRule ]
56+ ) ;
57+
58+ const updateSyncAll = useCallback (
59+ ( value : boolean ) => {
60+ onChange ( syncRule . updateDataSyncAllEvents ( value ) . updateDataSyncEvents ( undefined ) ) ;
61+ } ,
62+ [ onChange , syncRule ]
63+ ) ;
64+
65+ const addToSelection = useCallback (
66+ ( ids : string [ ] ) => {
67+ const oldSelection = _ . difference ( syncRule . dataSyncEvents , ids ) ;
68+ const newSelection = _ . difference ( ids , syncRule . dataSyncEvents ) ;
69+
70+ onChange ( syncRule . updateDataSyncEvents ( [ ...oldSelection , ...newSelection ] ) ) ;
71+ } ,
72+ [ onChange , syncRule ]
73+ ) ;
74+
75+ const columns : TableColumn < ProgramEvent > [ ] = useMemo (
76+ ( ) => [
77+ { name : "id" as const , text : i18n . t ( "UID" ) , sortable : true } ,
78+ {
79+ name : "program" as const ,
80+ text : i18n . t ( "Program" ) ,
81+ sortable : true ,
82+ getValue : ( { program } ) => _ . find ( programs , { id : program } ) ?. name ?? program ,
83+ } ,
84+ { name : "orgUnitName" as const , text : i18n . t ( "Organisation unit" ) , sortable : true } ,
85+ { name : "eventDate" as const , text : i18n . t ( "Event date" ) , sortable : true } ,
86+ {
87+ name : "lastUpdated" as const ,
88+ text : i18n . t ( "Last updated" ) ,
89+ sortable : true ,
90+ hidden : true ,
91+ } ,
92+ { name : "status" as const , text : i18n . t ( "Status" ) , sortable : true } ,
93+ { name : "storedBy" as const , text : i18n . t ( "Stored by" ) , sortable : true } ,
94+ ] ,
95+ [ programs ]
96+ ) ;
97+
98+ const details : ObjectsTableDetailField < ProgramEvent > [ ] = useMemo (
99+ ( ) => [
100+ { name : "id" as const , text : i18n . t ( "UID" ) } ,
101+ {
102+ name : "program" as const ,
103+ text : i18n . t ( "Program" ) ,
104+ getValue : ( { program } ) => _ . find ( programs , { id : program } ) ?. name ?? program ,
105+ } ,
106+ { name : "orgUnitName" as const , text : i18n . t ( "Organisation unit" ) } ,
107+ { name : "created" as const , text : i18n . t ( "Created" ) } ,
108+ { name : "lastUpdated" as const , text : i18n . t ( "Last updated" ) } ,
109+ { name : "eventDate" as const , text : i18n . t ( "Event date" ) } ,
110+ { name : "dueDate" as const , text : i18n . t ( "Due date" ) } ,
111+ { name : "status" as const , text : i18n . t ( "Status" ) } ,
112+ { name : "storedBy" as const , text : i18n . t ( "Stored by" ) } ,
113+ ] ,
114+ [ programs ]
115+ ) ;
116+
117+ const actions = useMemo (
118+ ( ) => [
119+ {
120+ name : "select" ,
121+ text : i18n . t ( "Select" ) ,
122+ primary : true ,
123+ multiple : true ,
124+ onClick : addToSelection ,
125+ isActive : ( ) => false ,
126+ } ,
127+ ] ,
128+ [ addToSelection ]
129+ ) ;
45130
46- const buildAdditionalColumns = ( ) => {
131+ const filterComponents = useMemo (
132+ ( ) => (
133+ < Dropdown
134+ key = { "program-filter" }
135+ items = { programs }
136+ onValueChange = { changeProgramFilter }
137+ value = { programFilter }
138+ label = { i18n . t ( "Program" ) }
139+ />
140+ ) ,
141+ [ programFilter , programs ]
142+ ) ;
143+
144+ const additionalColumns = useMemo ( ( ) => {
47145 const program = _ . find ( programs , { id : programFilter } ) ;
48146 const dataElements = _ ( program ?. programStages ?? [ ] )
49147 . map ( ( { programStageDataElements } ) =>
@@ -61,82 +159,8 @@ export default function EventsSelectionStep({ syncRule, onChange }: SyncWizardSt
61159 return _ . find ( row . dataValues , { dataElement : id } ) ?. value ?? "-" ;
62160 } ,
63161 } ) ) ;
64- } ;
65-
66- const handleTableChange = ( tableState : TableState < ProgramEvent > ) => {
67- const { selection } = tableState ;
68- onChange ( syncRule . updateDataSyncEvents ( selection . map ( ( { id } ) => id ) ) ) ;
69- } ;
70-
71- const updateSyncAll = ( value : boolean ) => {
72- onChange ( syncRule . updateDataSyncAllEvents ( value ) . updateDataSyncEvents ( undefined ) ) ;
73- } ;
74-
75- const addToSelection = ( ids : string [ ] ) => {
76- const oldSelection = _ . difference ( syncRule . dataSyncEvents , ids ) ;
77- const newSelection = _ . difference ( ids , syncRule . dataSyncEvents ) ;
78-
79- onChange ( syncRule . updateDataSyncEvents ( [ ...oldSelection , ...newSelection ] ) ) ;
80- } ;
162+ } , [ programFilter , programs ] ) ;
81163
82- const columns : TableColumn < ProgramEvent > [ ] = [
83- { name : "id" as const , text : i18n . t ( "UID" ) , sortable : true } ,
84- {
85- name : "program" as const ,
86- text : i18n . t ( "Program" ) ,
87- sortable : true ,
88- getValue : ( { program } ) => _ . find ( programs , { id : program } ) ?. name ?? program ,
89- } ,
90- { name : "orgUnitName" as const , text : i18n . t ( "Organisation unit" ) , sortable : true } ,
91- { name : "eventDate" as const , text : i18n . t ( "Event date" ) , sortable : true } ,
92- {
93- name : "lastUpdated" as const ,
94- text : i18n . t ( "Last updated" ) ,
95- sortable : true ,
96- hidden : true ,
97- } ,
98- { name : "status" as const , text : i18n . t ( "Status" ) , sortable : true } ,
99- { name : "storedBy" as const , text : i18n . t ( "Stored by" ) , sortable : true } ,
100- ] ;
101-
102- const details : ObjectsTableDetailField < ProgramEvent > [ ] = [
103- { name : "id" as const , text : i18n . t ( "UID" ) } ,
104- {
105- name : "program" as const ,
106- text : i18n . t ( "Program" ) ,
107- getValue : ( { program } ) => _ . find ( programs , { id : program } ) ?. name ?? program ,
108- } ,
109- { name : "orgUnitName" as const , text : i18n . t ( "Organisation unit" ) } ,
110- { name : "created" as const , text : i18n . t ( "Created" ) } ,
111- { name : "lastUpdated" as const , text : i18n . t ( "Last updated" ) } ,
112- { name : "eventDate" as const , text : i18n . t ( "Event date" ) } ,
113- { name : "dueDate" as const , text : i18n . t ( "Due date" ) } ,
114- { name : "status" as const , text : i18n . t ( "Status" ) } ,
115- { name : "storedBy" as const , text : i18n . t ( "Stored by" ) } ,
116- ] ;
117-
118- const actions = [
119- {
120- name : "select" ,
121- text : i18n . t ( "Select" ) ,
122- primary : true ,
123- multiple : true ,
124- onClick : addToSelection ,
125- isActive : ( ) => false ,
126- } ,
127- ] ;
128-
129- const filterComponents = (
130- < Dropdown
131- key = { "program-filter" }
132- items = { programs }
133- onValueChange = { changeProgramFilter }
134- value = { programFilter }
135- label = { i18n . t ( "Program" ) }
136- />
137- ) ;
138-
139- const additionalColumns = buildAdditionalColumns ( ) ;
140164 const filteredObjects =
141165 objects ?. filter ( ( { program } ) => ! programFilter || program === programFilter ) ?? [ ] ;
142166
@@ -149,6 +173,8 @@ export default function EventsSelectionStep({ syncRule, onChange }: SyncWizardSt
149173 ) ;
150174 }
151175
176+ console . log ( "loading" , objects === undefined ) ;
177+
152178 return (
153179 < React . Fragment >
154180 < Toggle
0 commit comments