diff --git a/packages/data-models/flowTypes.ts b/packages/data-models/flowTypes.ts index 8b83153593..300db7fc5e 100644 --- a/packages/data-models/flowTypes.ts +++ b/packages/data-models/flowTypes.ts @@ -338,8 +338,10 @@ export namespace FlowTypes { _dynamicDependencies?: { [reference: string]: string[] }; _translatedFields?: { [field: string]: any }; _evalContext?: { itemContext: any }; // force specific context variables when calculating eval statements (such as loop items) + _index?: number; // Added dynamically to some rows, i.e. those in item loops __EMPTY?: any; // empty cells (can be removed after pr 679 merged) } + export type IDynamicField = { [key: string]: IDynamicField | TemplateRowDynamicEvaluator[] }; type IDynamicPrefix = IAppConfig["DYNAMIC_PREFIXES"][number]; @@ -393,7 +395,6 @@ export namespace FlowTypes { "save_to_device", "set_field", "set_item", - "set_item_at_index", "set_items", "set_local", "share", diff --git a/src/app/shared/components/template/components/data-items/data-items.component.ts b/src/app/shared/components/template/components/data-items/data-items.component.ts index bc8d9c4821..2cd9808690 100644 --- a/src/app/shared/components/template/components/data-items/data-items.component.ts +++ b/src/app/shared/components/template/components/data-items/data-items.component.ts @@ -104,18 +104,15 @@ export class TmplDataItemsComponent extends TemplateBaseComponent implements OnD if (r.action_list) { r.action_list = r.action_list.map((a) => { if (a.action_id === "set_item") { - a.args = [this.dataListName, r._evalContext.itemContext.id]; + const row_ids = Object.values(dataList).map((v) => v.id); + const row_id = r._evalContext.itemContext.id; + a.args = [this.dataListName, row_ids, row_id]; } if (a.action_id === "set_items") { // TODO - add a check for @item refs and replace parameter list with correct values // for each individual item (default will be just to pick the first) a.args = [this.dataListName, Object.values(dataList).map((v) => v.id)]; } - if (a.action_id === "set_item_at_index") { - const row_ids = Object.values(dataList).map((v) => v.id); - const currentItemIndex = row_ids.indexOf(r._evalContext.itemContext.id); - a.args = a.args.concat([this.dataListName, currentItemIndex, row_ids]); - } return a; }); } diff --git a/src/app/shared/components/template/processors/item.ts b/src/app/shared/components/template/processors/item.ts index 61f8a31718..64990f119f 100644 --- a/src/app/shared/components/template/processors/item.ts +++ b/src/app/shared/components/template/processors/item.ts @@ -37,7 +37,7 @@ export class ItemProcessor { private generateLoopItemRows(templateRows: FlowTypes.TemplateRow[], items: any[]) { const loopItemRows: FlowTypes.TemplateRow[] = []; for (const [index, item] of Object.entries(items)) { - item._index = index; + item._index = Number(index); const evalContext = { itemContext: item }; for (const r of templateRows) { const itemRow = this.setRecursiveRowEvalContext(r, evalContext); diff --git a/src/app/shared/components/template/services/template-variables.service.ts b/src/app/shared/components/template/services/template-variables.service.ts index 75984760e8..90c41a5fe3 100644 --- a/src/app/shared/components/template/services/template-variables.service.ts +++ b/src/app/shared/components/template/services/template-variables.service.ts @@ -126,7 +126,7 @@ export class TemplateVariablesService extends AsyncServiceBase { **/ private shouldEvaluateField(fieldName: keyof FlowTypes.TemplateRow, omitFields: string[] = []) { if (omitFields.includes(fieldName)) return false; - if (fieldName.startsWith("_")) return false; + if (fieldName.startsWith("_") && fieldName !== "_index") return false; return true; } diff --git a/src/app/shared/services/dynamic-data/dynamic-data.service.ts b/src/app/shared/services/dynamic-data/dynamic-data.service.ts index 78386e05ea..58a4fa09a8 100644 --- a/src/app/shared/services/dynamic-data/dynamic-data.service.ts +++ b/src/app/shared/services/dynamic-data/dynamic-data.service.ts @@ -66,18 +66,35 @@ export class DynamicDataService extends AsyncServiceBase { } private registerTemplateActionHandlers() { this.templateActionRegistry.register({ + /** + * Write properties on the current item (default), or on an explicitly targeted item, + * e.g. + * click | set_item | completed:true; + * click | set_item | id: @item.id, completed:true; + * click | set_item | _index: @item._index + 1, completed:true; + */ set_item: async ({ args, params }) => { - const [flow_name, row_id] = args; - await this.update("data_list", flow_name, row_id, params); - }, - set_item_at_index: async ({ args, params }) => { - const [targetIndexString, flow_name, currentItemIndex, row_ids] = args; - const targetIndex = this.evaluateItemIndexString(targetIndexString, currentItemIndex); - const targetRowId = row_ids[targetIndex]; - if (targetRowId) { - await this.update("data_list", flow_name, targetRowId, params); + const [flow_name, row_ids, row_id] = args; + const { _index, id, ...writeableProps } = params; + + // Target current row if another target is not explicitly provided + let targetRowId = row_id; + if (_index) { + targetRowId = row_ids[_index]; + } + if (id) { + targetRowId = id; + } + + if (row_ids.includes(targetRowId)) { + await this.update("data_list", flow_name, targetRowId, writeableProps); } else { - console.warn(`[SET ITEM AT INDEX] - No item at index ${targetIndex}`); + if (id) { + console.warn(`[SET ITEM] - No item with ID ${id}`); + } + if (_index !== undefined) { + console.warn(`[SET ITEM] - No item at index ${_index}`); + } } }, set_items: async ({ args, params }) => {