From a66a11502c095cc4a32bdbd9c6ecda26902d0938 Mon Sep 17 00:00:00 2001 From: Stuart Marshall Date: Thu, 11 Sep 2025 17:03:10 +0100 Subject: [PATCH] feat: add configuration for widgets through the card component via workflow configs --- .../app/media/js/viewmodels/card-component.js | 71 +++++++++++++++++++ .../views/components/cards/default.htm | 3 +- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/arches/app/media/js/viewmodels/card-component.js b/arches/app/media/js/viewmodels/card-component.js index 21ff201e9e..1f6fcfd5e1 100644 --- a/arches/app/media/js/viewmodels/card-component.js +++ b/arches/app/media/js/viewmodels/card-component.js @@ -316,5 +316,76 @@ export default function(params) { } }; + this.getNodeOptions = (nodeId, widgetConfig) => { + const options = params.nodeOptions?.[nodeId] || {}; + const nodeOptions = {}; + + if (!options) return; + + // Default handlers + this.handlers = { + config(context) { + const { options, widgetConfig } = context; + options.config = ko.observable(Object.assign(widgetConfig, options.config)); + }, + node(context) { + const { params, nodeId, options } = context; + const originalNode = params.form.nodeLookup[nodeId]; + options.node = Object.assign(originalNode, options.node); + }, + widget: (context) => { + const { options, nodeId } = context; + const widget = context.self.form.card().widgets().filter(widget => widget.node_id() === nodeId)[0]; + + const allKeys = new Set([...Object.keys(options.widget), ...Object.keys(widget)]); + + allKeys.forEach(key => { + if (key in options.widget) { + if (ko.isObservable(widget[key])) { + widget[key](options.widget[key]); + } else { + widget[key] = options.widget[key]; + } + } else { + options.widget[key] = widget[key]; + } + }); + }, + default(context, key) { + const { options } = context; + options[key] = ko.observable(options[key]); + } + }; + + // Apply custom handlers to modify widget + if (params.customHandlers) { + Object.keys(params.customHandlers).forEach(key => { + this.handlers[key] = (context) => params.customHandlers[key](context); + }); + } + + // supply context of the card component to the handlers + const context = { + self: this, + params, + nodeId, + widgetConfig, + options, + handlers: this.handlers + }; + + // Process options with handlers + Object.keys(options).forEach(key => { + if (key in this.handlers) { + this.handlers[key](context); + } else { + this.handlers.default(context, key); + } + }); + + Object.assign(nodeOptions, options); + return nodeOptions; + }; + this.initialize(); }; diff --git a/arches/app/templates/views/components/cards/default.htm b/arches/app/templates/views/components/cards/default.htm index 469e247679..cc484730d8 100644 --- a/arches/app/templates/views/components/cards/default.htm +++ b/arches/app/templates/views/components/cards/default.htm @@ -326,7 +326,8 @@

expanded: self.expanded, graph: self.form.graph, type: "resource-editor", - disabled: !self.card.isWritable && !self.preview + disabled: !self.card.isWritable && !self.preview, + ...self.getNodeOptions?.(widget.node_id(), widget.configJSON()) } }, css:{ "active": widget.selected, "hover": widget.hovered, "widget-preview": self.preview }, click: function(data, e) { if (!widget.selected() && self.preview) {widget.selected(true);}