@nent/core
Version:
258 lines (257 loc) • 8.39 kB
JavaScript
/*!
* NENT 2022
*/
import { Component, Element, h, Host, Method, Prop, State, } from '@stencil/core';
import { ActionActivationStrategy, } from '../../services/actions';
import { debugIf, isValue, warn } from '../../services/common';
/**
* This element defines how or when a group of actions are
* activated. The actions activated must be included between
* this elements tags.
*
* @system actions
*/
export class ActionActivator {
constructor() {
this.actions = [];
this.activated = false;
/**
* The activation strategy to use for the contained actions.
*/
this.activate = 'on-element-event';
/**
* This is the name of the event/s to listen to on the target element
* separated by comma.
*/
this.targetEvent = 'click,keydown';
/**
* Turn on debug statements for load, update and render events.
*/
this.debug = false;
/**
* Limit the activation to ONCE. This could be helpful if an action
* has side-effects if it is run multiple times.
*
* Note: the activation
* state is stored in memory and does not persist across refreshes.
*/
this.once = false;
}
/**
* Manually activate all actions within this activator.
*/
async activateActions(once = false) {
if ((once || this.once) && this.activated)
return;
const values = {};
let isValid = true;
this.childInputs.forEach((el, index) => {
var _a, _b;
if (((_a = el.checkValidity) === null || _a === void 0 ? void 0 : _a.call(el)) === false) {
(_b = el.reportValidity) === null || _b === void 0 ? void 0 : _b.call(el);
isValid = false;
}
else {
values[el.id || el.name || index] =
el.value || (el.type == 'checkbox' ? el.checked : null);
}
});
if (!isValid)
return;
await Promise.all(this.childActions.map(async (a) => {
const action = await a.getAction();
if (!action)
return;
const dataString = JSON.stringify(action.data);
debugIf(this.debug, `n-action-activator: activating [${this.activate}~{topic: ${action === null || action === void 0 ? void 0 : action.topic}, command:${action === null || action === void 0 ? void 0 : action.command}, data: ${dataString}]`);
await a.sendAction(values);
}));
this.activated = true;
}
get childInputs() {
return this.el.querySelectorAll('input,select,textarea');
}
get childActions() {
const actions = Array.from(this.el.childNodes)
.filter(n => n.nodeName.toLocaleLowerCase().includes('action'))
.map(n => n);
return actions;
}
async componentDidLoad() {
debugIf(this.debug, `n-action-activator: loading`);
if (this.childActions.length === 0) {
warn(`n-action-activator: no children actions detected`);
return;
}
if (this.activate === ActionActivationStrategy.OnElementEvent) {
const elements = this.targetElement
? this.el.ownerDocument.querySelectorAll(this.targetElement)
: this.el.querySelectorAll('a,button,input[type=button]');
if (!elements || elements.length == 0) {
warn(`n-action-activator: no elements found for '${this.targetElement}'`);
}
else {
debugIf(this.debug, `n-action-activator: elements found ${elements.length}`);
elements.forEach(element => {
debugIf(this.debug, `n-action-activator: element found ${element.nodeName}`);
const events = this.targetEvent
.split(',')
.filter(e => isValue(e));
events.forEach(event => {
this.debug,
`n-action-activator: element event ${event} registered on ${element.nodeName}`,
element.addEventListener(event, async () => {
debugIf(this.debug, `n-action-activator: received ${element.nodeName} ${this.targetEvent} event`);
await this.activateActions();
});
});
});
}
}
else if (this.activate === ActionActivationStrategy.OnRender) {
await this.activateActions();
}
}
render() {
return (h(Host, { style: { display: 'contents' } },
h("slot", null)));
}
static get is() { return "n-action-activator"; }
static get properties() { return {
"activate": {
"type": "string",
"mutable": false,
"complexType": {
"original": "| 'on-render'\n | 'on-element-event'\n | 'on-enter'\n | 'at-time'\n | 'at-time-end'\n | 'on-exit'",
"resolved": "\"at-time\" | \"at-time-end\" | \"on-element-event\" | \"on-enter\" | \"on-exit\" | \"on-render\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "The activation strategy to use for the contained actions."
},
"attribute": "activate",
"reflect": false,
"defaultValue": "'on-element-event'"
},
"targetElement": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The element or elements to watch for events when using the OnElementEvent\nactivation strategy. This element uses the HTML Element querySelectorAll\nfunction to find the element/s based on the query in this attribute.\n\nIf left blank, this element looks for child elements matching:\n'a,button,input[type=button]'\n\nFor use with activate=\"on-element-event\" and \"at-time\""
},
"attribute": "target-element",
"reflect": false
},
"targetEvent": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "This is the name of the event/s to listen to on the target element\nseparated by comma."
},
"attribute": "target-event",
"reflect": false,
"defaultValue": "'click,keydown'"
},
"time": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The time, in seconds at which the contained actions should be submitted.\n\nFor use with activate=\"at-time\" Only!"
},
"attribute": "time",
"reflect": false
},
"debug": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Turn on debug statements for load, update and render events."
},
"attribute": "debug",
"reflect": false,
"defaultValue": "false"
},
"once": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Limit the activation to ONCE. This could be helpful if an action\nhas side-effects if it is run multiple times.\n\nNote: the activation\nstate is stored in memory and does not persist across refreshes."
},
"attribute": "once",
"reflect": false,
"defaultValue": "false"
}
}; }
static get states() { return {
"actions": {},
"activated": {}
}; }
static get methods() { return {
"activateActions": {
"complexType": {
"signature": "(once?: boolean) => Promise<void>",
"parameters": [{
"tags": [],
"text": ""
}],
"references": {
"Promise": {
"location": "global"
},
"Record": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Manually activate all actions within this activator.",
"tags": []
}
}
}; }
static get elementRef() { return "el"; }
}