Skip to content

Commit 6c2f82e

Browse files
Merge branch 'master' into feat/templated-android-config
2 parents 007f3b7 + 391daa1 commit 6c2f82e

File tree

6 files changed

+79
-36
lines changed

6 files changed

+79
-36
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"intro.js": "^3.4.0",
8989
"jquery": "^3.7.1",
9090
"jquery-touchswipe": "^1.6.19",
91-
"katex": "^0.16.9",
91+
"katex": "^0.16.10",
9292
"lottie-web": "^5.12.2",
9393
"marked": "^2.1.3",
9494
"mergexml": "^1.2.3",

packages/data-models/flowTypes.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,21 @@ export namespace FlowTypes {
337337
/** Keep a list of dynamic dependencies used within a template, by reference (e.g. {@local.var1 : ["text_1"]}) */
338338
_dynamicDependencies?: { [reference: string]: string[] };
339339
_translatedFields?: { [field: string]: any };
340-
_evalContext?: { itemContext: any }; // force specific context variables when calculating eval statements (such as loop items)
340+
_evalContext?: { itemContext: TemplateRowItemEvalContext }; // force specific context variables when calculating eval statements (such as loop items)
341341
__EMPTY?: any; // empty cells (can be removed after pr 679 merged)
342342
}
343343
export type IDynamicField = { [key: string]: IDynamicField | TemplateRowDynamicEvaluator[] };
344344

345+
export interface TemplateRowItemEvalContext {
346+
// item metadata
347+
_id: string;
348+
_index: number;
349+
_first: boolean;
350+
_last: boolean;
351+
// item data
352+
[key: string]: any;
353+
}
354+
345355
type IDynamicPrefix = IAppConfig["DYNAMIC_PREFIXES"][number];
346356

347357
/** Data passed back from regex match, e.g. expression @local.someField => type:local, fieldName: someField */

src/app/shared/components/template/components/data-items/data-items.component.ts

+30-16
Original file line numberDiff line numberDiff line change
@@ -74,34 +74,48 @@ export class TmplDataItemsComponent extends TemplateBaseComponent implements OnD
7474
parameterList: any
7575
) {
7676
const parsedItemDataList = await this.parseDataList(itemDataList);
77-
const itemRows = new ItemProcessor(parsedItemDataList, parameterList).process(rows);
78-
const parsedItemRows = await this.hackProcessRows(itemRows);
79-
const replacedActionRows = this.setActionListMeta(parsedItemRows, parsedItemDataList);
77+
const { itemRows, itemData } = new ItemProcessor(parsedItemDataList, parameterList).process(
78+
rows
79+
);
80+
const itemRowsWithMeta = this.setItemMeta(itemRows, itemData);
81+
82+
const parsedItemRows = await this.hackProcessRows(itemRowsWithMeta);
8083
// TODO - deep diff and only update changed
81-
this.itemRows = replacedActionRows;
84+
this.itemRows = parsedItemRows;
8285
this.cdr.markForCheck();
8386
}
8487

8588
/**
86-
* Update any action list set_item args to contain name of current data list and item id
87-
* and set_items action to include all currently displayed rows
89+
* Update item dynamic evaluation context and action lists to include relevant
90+
* item data
91+
* @param templateRows List of template rows generated from itemData by item processor
92+
* @param itemData List of original item data used to create item rows (post operations such as filter/sort)
8893
* */
89-
private setActionListMeta(
90-
rows: FlowTypes.TemplateRow[],
91-
dataList: {
92-
[index: string]: any;
93-
}
94-
) {
95-
return rows.map((r) => {
94+
private setItemMeta(templateRows: FlowTypes.TemplateRow[], itemData: FlowTypes.Data_listRow[]) {
95+
const lastItemIndex = itemData.length - 1;
96+
const itemDataIDs = itemData.map((item) => item.id);
97+
// Reassign metadata fields previously assigned by item as rendered row count may have changed
98+
return templateRows.map((r) => {
99+
// Map the row item context to the original list of items rendered to know position in item list.
100+
const itemIndex = itemDataIDs.indexOf(r._evalContext.itemContext._id);
101+
// Update metadata fields as _first, _last and index may have changed based on dynamic updates
102+
r._evalContext.itemContext = {
103+
...r._evalContext.itemContext,
104+
_index: itemIndex,
105+
_first: itemIndex === 0,
106+
_last: itemIndex === lastItemIndex,
107+
};
108+
// Update any action list set_item args to contain name of current data list and item id
109+
// and set_items action to include all currently displayed rows
96110
if (r.action_list) {
97111
r.action_list = r.action_list.map((a) => {
98112
if (a.action_id === "set_item") {
99-
a.args = [this.dataListName, r._evalContext.itemContext.id];
113+
a.args = [this.dataListName, r._evalContext.itemContext._id];
100114
}
101115
if (a.action_id === "set_items") {
102116
// TODO - add a check for @item refs and replace parameter list with correct values
103117
// for each individual item (default will be just to pick the first)
104-
a.args = [this.dataListName, Object.values(dataList).map((v) => v.id)];
118+
a.args = [this.dataListName, itemDataIDs];
105119
}
106120
return a;
107121
});
@@ -114,7 +128,7 @@ export class TmplDataItemsComponent extends TemplateBaseComponent implements OnD
114128
* Ordinarily rows would be processed as part of the regular template processing,
115129
* however this must be bypassed to allow multiple reprocessing on item updates
116130
*/
117-
private async hackProcessRows(rows) {
131+
private async hackProcessRows(rows: FlowTypes.TemplateRow[]) {
118132
const processor = new TemplateRowService(this.injector, {
119133
name: "",
120134
template: {

src/app/shared/components/template/processors/item.ts

+25-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ export class ItemProcessor {
1515
const pipedData = this.pipeData(data, this.parameterList);
1616
const itemRows = this.generateLoopItemRows(templateRows, pipedData);
1717
const parsedItemRows = this.hackSetNestedName(itemRows);
18-
return parsedItemRows;
18+
// Return both rows for rendering and list of itemData used (post pipe operations)
19+
return { itemRows: parsedItemRows, itemData: pipedData };
1920
}
2021

2122
private pipeData(data: any[], parameter_list: any) {
@@ -32,13 +33,31 @@ export class ItemProcessor {
3233
/**
3334
* Takes a row and list of items to iterate over, creating a new entry for each item with
3435
* the same row values but a unique evaluation context for populating dynamic variables from the item
35-
* @param items - list of items to iterate over
36+
* @param templateRows - list of template rows to iterate over for each item
37+
* @param itemData - list of items to iterate over
3638
*/
37-
private generateLoopItemRows(templateRows: FlowTypes.TemplateRow[], items: any[]) {
39+
private generateLoopItemRows(
40+
templateRows: FlowTypes.TemplateRow[],
41+
itemData: FlowTypes.Data_listRow[]
42+
) {
3843
const loopItemRows: FlowTypes.TemplateRow[] = [];
39-
for (const [index, item] of Object.entries(items)) {
40-
item._index = index;
41-
const evalContext = { itemContext: item };
44+
const lastItemIndex = itemData.length - 1;
45+
for (const [indexKey, item] of Object.entries(itemData)) {
46+
const _index = Number(indexKey);
47+
const itemContextMeta: FlowTypes.TemplateRowItemEvalContext = {
48+
_index,
49+
_id: item["id"],
50+
_first: _index === 0,
51+
_last: _index === lastItemIndex,
52+
};
53+
const evalContext: FlowTypes.TemplateRow["_evalContext"] = {
54+
itemContext: {
55+
...item,
56+
...itemContextMeta,
57+
// Assign row dynamic context to allow reference to rendered row metadata, including
58+
// item index, id, and whether first or last item in list
59+
},
60+
};
4261
for (const r of templateRows) {
4362
const itemRow = this.setRecursiveRowEvalContext(r, evalContext);
4463
loopItemRows.push(itemRow);

src/app/shared/components/template/services/instance/template-row.service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export class TemplateRowService extends SyncServiceBase {
284284
const itemDataList: { [id: string]: any } = row.value;
285285
const parameterList = this.hackUnparseItemParameterList(row);
286286
const parsedItemDataList = await this.parseDataList(itemDataList);
287-
const itemRows = new ItemProcessor(parsedItemDataList, parameterList).process(row.rows);
287+
const { itemRows } = new ItemProcessor(parsedItemDataList, parameterList).process(row.rows);
288288
const parsedItemRows = await this.processRows(itemRows, isNestedTemplate, row.name);
289289
return parsedItemRows;
290290
}

yarn.lock

+11-11
Original file line numberDiff line numberDiff line change
@@ -14586,12 +14586,12 @@ __metadata:
1458614586
linkType: hard
1458714587

1458814588
"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.7, follow-redirects@npm:^1.15.4":
14589-
version: 1.15.5
14590-
resolution: "follow-redirects@npm:1.15.5"
14589+
version: 1.15.6
14590+
resolution: "follow-redirects@npm:1.15.6"
1459114591
peerDependenciesMeta:
1459214592
debug:
1459314593
optional: true
14594-
checksum: 5ca49b5ce6f44338cbfc3546823357e7a70813cecc9b7b768158a1d32c1e62e7407c944402a918ea8c38ae2e78266312d617dc68783fac502cbb55e1047b34ec
14594+
checksum: a62c378dfc8c00f60b9c80cab158ba54e99ba0239a5dd7c81245e5a5b39d10f0c35e249c3379eae719ff0285fff88c365dd446fab19dee771f1d76252df1bbf5
1459514595
languageName: node
1459614596
linkType: hard
1459714597

@@ -14859,7 +14859,7 @@ __metadata:
1485914859
karma-coverage: ~2.2.0
1486014860
karma-jasmine: ~5.1.0
1486114861
karma-jasmine-html-reporter: ~2.0.0
14862-
katex: ^0.16.9
14862+
katex: ^0.16.10
1486314863
lint-staged: ^13.0.3
1486414864
lottie-web: ^5.12.2
1486514865
marked: ^2.1.3
@@ -18265,14 +18265,14 @@ __metadata:
1826518265
languageName: node
1826618266
linkType: hard
1826718267

18268-
"katex@npm:^0.16.9":
18269-
version: 0.16.9
18270-
resolution: "katex@npm:0.16.9"
18268+
"katex@npm:^0.16.10":
18269+
version: 0.16.10
18270+
resolution: "katex@npm:0.16.10"
1827118271
dependencies:
1827218272
commander: ^8.3.0
1827318273
bin:
1827418274
katex: cli.js
18275-
checksum: 861194dfd4d86505e657f688fb73048d46ac498edafce71199502a35b03c0ecc35ba930c631be79c4a09d90a0d23476673cd52f6bc367c7a161854d64005fa95
18275+
checksum: 108e9d810e17840c43eef8d46171096f4cc97852bfd1e2dd1890d9b3435846816e3e98678a31d38bd064eb97eea83b18ff224cb65d5f9511b54ce7ff4359b591
1827618276
languageName: node
1827718277
linkType: hard
1827818278

@@ -26726,8 +26726,8 @@ __metadata:
2672626726
linkType: hard
2672726727

2672826728
"webpack-dev-middleware@npm:^5.3.1":
26729-
version: 5.3.3
26730-
resolution: "webpack-dev-middleware@npm:5.3.3"
26729+
version: 5.3.4
26730+
resolution: "webpack-dev-middleware@npm:5.3.4"
2673126731
dependencies:
2673226732
colorette: ^2.0.10
2673326733
memfs: ^3.4.3
@@ -26736,7 +26736,7 @@ __metadata:
2673626736
schema-utils: ^4.0.0
2673726737
peerDependencies:
2673826738
webpack: ^4.0.0 || ^5.0.0
26739-
checksum: dd332cc6da61222c43d25e5a2155e23147b777ff32fdf1f1a0a8777020c072fbcef7756360ce2a13939c3f534c06b4992a4d659318c4a7fe2c0530b52a8a6621
26739+
checksum: 90cf3e27d0714c1a745454a1794f491b7076434939340605b9ee8718ba2b85385b120939754e9fdbd6569811e749dee53eec319e0d600e70e0b0baffd8e3fb13
2674026740
languageName: node
2674126741
linkType: hard
2674226742

0 commit comments

Comments
 (0)