Skip to content

Commit 20ad3f4

Browse files
ISSUE-138342: Support for CompositeKeys in ListView component (#96)
1 parent ee3efc6 commit 20ad3f4

File tree

1 file changed

+96
-37
lines changed

1 file changed

+96
-37
lines changed

scripts/dxcomponents/components/containers/templates/listview/list-view.component.js

Lines changed: 96 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export class ListViewComponent extends BaseComponent {
1616
singleSelectionMode;
1717
multiSelectionMode;
1818
rowID;
19-
response;
19+
listViewItems;
2020
compositeKeys;
2121
showDynamicFields;
2222
filterPayload;
@@ -28,6 +28,7 @@ export class ListViewComponent extends BaseComponent {
2828
fieldDefs;
2929
label = "";
3030
componentValue;
31+
contextPage;
3132

3233
props = {
3334
label: "",
@@ -53,50 +54,66 @@ export class ListViewComponent extends BaseComponent {
5354
}
5455

5556
update(pConn, payload) {
56-
if (this.pConn === pConn && this.payload === payload) {
57+
const pConnChanged = this.pConn !== pConn;
58+
if (!pConnChanged && this.payload === payload) {
5759
return;
5860
}
5961
this.pConn = pConn;
62+
63+
const shouldReloadData = this.#shouldReloadData(this.payload, payload) || pConnChanged;
6064
this.payload = payload;
61-
this.#updateSelf();
65+
66+
this.#updateSelf(shouldReloadData);
6267
}
6368

6469
onEvent(event) {
6570
if (event.type === "SelectSingleItem") {
66-
const index = Number(event.componentData.selectedItemIndex);
67-
this.#fieldOnChange(index);
71+
const selectedItemIndex = Number(event.componentData.selectedItemIndex);
72+
this.#fieldOnChange(selectedItemIndex);
6873
} else {
6974
console.log(TAG, `onEvent received unsupported event type ${event.type}`);
7075
}
7176
}
7277

78+
#shouldReloadData(oldPayload, newPayload) {
79+
const filterPayload = (payload) => {
80+
// Fields to exclude from comparison (they contain selection values, not data config).
81+
const { value, selectionKey, contextPage, primaryField, ...rest } = payload;
82+
return rest;
83+
};
84+
return JSON.stringify(filterPayload(oldPayload)) !== JSON.stringify(filterPayload(newPayload));
85+
}
86+
7387
#fieldOnChange(selectedItemIndex) {
74-
if (!this.response || selectedItemIndex < 0 || selectedItemIndex >= this.response.length) {
88+
if (!this.listViewItems || selectedItemIndex < 0 || selectedItemIndex >= this.listViewItems.length) {
7589
console.warn(TAG, "Unexpected state when updating selected item index");
7690
return;
7791
}
7892

79-
const reqObj = {};
93+
const selectedObject = {};
8094
if (this.compositeKeys?.length > 1) {
81-
const selectedRow = this.response[selectedItemIndex];
82-
this.compositeKeys.forEach((element) => {
83-
reqObj[element] = selectedRow[element];
95+
const selectedRow = this.listViewItems[selectedItemIndex];
96+
this.compositeKeys.forEach((compositeKey) => {
97+
selectedObject[compositeKey] = selectedRow[compositeKey];
8498
});
8599
} else {
86-
reqObj[this.rowID] = this.response[selectedItemIndex][this.rowID];
100+
selectedObject[this.rowID] = this.listViewItems[selectedItemIndex][this.rowID];
87101
}
102+
88103
this.selectedItemIndex = selectedItemIndex;
89-
this.pConn?.getListActions?.()?.setSelectedRows([reqObj]);
104+
this.pConn?.getListActions?.()?.setSelectedRows([selectedObject]);
90105
}
91106

92-
#updateSelf() {
107+
#updateSelf(shouldReloadData = true) {
93108
this.configProps$ = this.pConn.getConfigProps();
94109

95110
// By default, pyGUID is used for Data classes and pyID is for Work classes as row-id/key
96111
const defaultRowID = this.configProps$?.referenceType === "Case" ? "pyID" : "pyGUID";
97112
this.compositeKeys = this.configProps$?.compositeKeys ?? this.payload.compositeKeys;
98113
this.rowID = this.compositeKeys && this.compositeKeys?.length === 1 ? this.compositeKeys[0] : defaultRowID;
114+
99115
this.componentValue = this.configProps$?.value;
116+
this.contextPage = this.configProps$?.contextPage;
100117

101118
this.showDynamicFields = this.configProps$?.showDynamicFields;
102119
this.selectionMode = this.configProps$.selectionMode;
@@ -115,37 +132,79 @@ export class ListViewComponent extends BaseComponent {
115132

116133
this.label = title;
117134

118-
if (this.configProps$) {
119-
if (!this.payload) {
120-
this.payload = { referenceList: this.configProps$.referenceList };
121-
}
122-
getListContextResponse({
123-
pConn: this.pConn,
124-
bInForm$: this.bInForm$,
125-
...this.payload,
126-
listContext: this.listContext,
127-
ref: this.ref,
128-
showDynamicFields: this.showDynamicFields,
129-
cosmosTableRef: this.cosmosTableRef,
130-
selectionMode: this.selectionMode,
131-
}).then((response) => {
132-
this.listContext = response;
133-
this.#getListData(() => {
134-
this.#updateSelectedItemIndex();
135-
this.#sendPropsUpdate();
136-
});
137-
});
135+
if (!shouldReloadData) {
136+
this.#updateSelectedItemIndex();
137+
this.#sendPropsUpdate();
138+
return;
139+
}
140+
141+
console.log(TAG, `ListView update requires data reload.`);
142+
143+
if (!this.configProps$) {
144+
console.warn(TAG, `No config props found for ListView component.`);
145+
return;
146+
}
147+
148+
if (!this.payload) {
149+
this.payload = { referenceList: this.configProps$.referenceList };
138150
}
151+
getListContextResponse({
152+
pConn: this.pConn,
153+
bInForm$: this.bInForm$,
154+
...this.payload,
155+
listContext: this.listContext,
156+
ref: this.ref,
157+
showDynamicFields: this.showDynamicFields,
158+
cosmosTableRef: this.cosmosTableRef,
159+
selectionMode: this.selectionMode,
160+
}).then((response) => {
161+
this.listContext = response;
162+
this.#getListData(() => {
163+
this.#updateSelectedItemIndex();
164+
this.#sendPropsUpdate();
165+
});
166+
});
139167
}
140168

141169
#updateSelectedItemIndex() {
142-
const index = this.response.findIndex((item) => {
170+
if (this.compositeKeys && this.compositeKeys.length > 1) {
171+
this.#updateSelectedItemIndexForCompositeKeys();
172+
} else {
173+
this.#updateSelectedItemIndexForSingleKey();
174+
}
175+
}
176+
177+
#updateSelectedItemIndexForCompositeKeys() {
178+
if (!this.listViewItems || this.listViewItems.length === 0) {
179+
this.selectedItemIndex = null;
180+
return;
181+
}
182+
183+
const index = this.listViewItems.findIndex((item) => {
184+
return this.compositeKeys.every((key) => {
185+
const left = item[key];
186+
const right = this.contextPage?.[key];
187+
return left != null && right != null && left === right;
188+
});
189+
});
190+
if (index == -1) {
191+
console.log(TAG, `No matching item found.`);
192+
}
193+
this.selectedItemIndex = index === -1 ? null : index;
194+
}
195+
196+
#updateSelectedItemIndexForSingleKey() {
197+
if (!this.listViewItems || this.listViewItems.length === 0) {
198+
this.selectedItemIndex = null;
199+
return;
200+
}
201+
const index = this.listViewItems.findIndex((item) => {
143202
const left = item[this.rowID];
144203
const right = this.componentValue;
145204
return left != null && right != null && left === right;
146205
});
147206
if (index == -1) {
148-
console.log(TAG, `No matching item found for componentValue.`);
207+
console.log(TAG, `No matching item found.`);
149208
}
150209
this.selectedItemIndex = index === -1 ? null : index;
151210
}
@@ -157,7 +216,7 @@ export class ListViewComponent extends BaseComponent {
157216
selectedItemIndex: String(this.selectedItemIndex),
158217
columnNames: this.displayedColumns$,
159218
columnLabels: this.displayedColumnsLabels$,
160-
items: this.response,
219+
items: this.listViewItems,
161220
};
162221
this.componentsManager.onComponentPropsUpdate(this);
163222
}
@@ -198,7 +257,7 @@ export class ListViewComponent extends BaseComponent {
198257
this.fields$ = this.#updateFields(this.fields$, fieldsMetaData.data.fields, columns);
199258
this.displayedColumns$ = columns.map((c) => c.id);
200259
this.displayedColumnsLabels$ = columns.map((c) => c.label);
201-
this.response = tableDataResults;
260+
this.listViewItems = tableDataResults;
202261

203262
// disabling parsing for now parsing data according to field types like date/date-time/currency
204263
// this.updatedRefList = this.updateData(tableDataResults, this.fields$);

0 commit comments

Comments
 (0)