Is it possible to add "bpmn:Resource" element in propertiesPanel and edit its attribute? how to do it?
I've already added some properties to property panel based on the property-panel[link] example.
But I have a challenge in adding 'bpmn:Resource' to the properties panel. I don't want it to be added as an extensionElement.
I'd like it to be inside bpmn:Definitions (beside bpmn:Process). Also I'd like to extend the original bpmn:Resource to add some parameters.
So in MyModdle.json I added:
{
"name": "Resource",
"extends": [
"bpmn:Resource"
],
"properties": [
{
"name": "parameters",
"isMany": true,
"type": "MyParameter"
}
]
}, {
"name": "MyParameter",
"properties": [
{
"name": "myParameterType",
"isAttr": true,
"type": "String"
}
{
"name": "myParameterName",
"isAttr": true,
"type": "String"
},
{
"name": "myParameterValue",
"isAttr": true,
"type": "String"
}
]
}
now for example in newElement function of MyResource.js
var newElement = function (type, prop, factory) {
return function (element, extensionElements, value) {
var commands = [];
var resource = getResource(element);
if (!resource) {
var parent = extensionElements;
resource = createResource(parent, bpmnFactory);
console.log('resource', resource);
commands.push(cmdHelper.addAndRemoveElementsFromList(
element,
extensionElements,
'values',
'extensionElements',
[resource],
[]
));
}
var newElem = createResourceParameter(type, resource, bpmnFactory, {
resourceId: 'id-' + value
});
commands.push(cmdHelper.addElementsTolist(element, parameters, prop, [newElem]));
return commands;
};
}
I know this cmdHelper adds 'bpmn:Resource' to extensionElements but I don't know what to use instead!
Related
I need to deserialize ( and later on serialize ) a piece of data that has this type of a structure :
{
"type": "TypeApplication",
"val": {
"con": {
"type": "TypeConstructor",
"val": [
"Builtin",
"Record"
]
},
"arg": {
"type": "RowCons",
"val": {
"label": "953e3dd6-826e-1985-cb99-fd4ed4da754e",
"type": {
"type": "TypeApplication",
"val": {
"con": {
"type": "TypeConstructor",
"val": [
"Builtin",
"List"
]
},
"arg": {
"type": "Element",
"meta": {
"multiLine": true
}
}
},
"system": {
"label": "nullam-senectus-port - Text",
"isBindable": true,
"defaultValue": [
{
"id": "4a05486f-f24d-45f8-ae13-ab05f824d74d",
"type": "String",
"pluginType": "Basic",
"data": {
"value": "Nullam senectus porttitor in eget. Eget rutrum leo interdum."
},
"children": [],
"text": true
}
],
"isUnlinked": false,
"isDefault": false
}
},
"tail": {
"type": "RowCons",
"val": {
"label": "94f603df-d585-b45a-4252-9ec77cf5b13c",
"type": {
"type": "TypeApplication",
"val": {
"con": {
"type": "TypeConstructor",
"val": [
"Builtin",
"List"
]
},
"arg": {
"type": "Element",
"meta": {
"multiLine": true
}
}
},
"system": {
"label": "best-services - Text",
"isBindable": true,
"defaultValue": [
{
"id": "6265ca45-3f69-4844-97e2-c05bbfb9fee5",
"type": "String",
"pluginType": "Basic",
"data": {
"value": "Best Services"
},
"children": [],
"text": true
}
]
}
},
"tail": {
"type": "RowEmpty"
}
}
}
}
}
}
}
I do not know what this data exactly is, but I know this is trying to represent a function/element that takes in values and defaults for those values as parameters/properties.
I want to deserialize it using serde and consequently serialize it too.
I have so far been able to write something that sort of works but not really :
#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(tag = "type", content = "val")]
pub enum WebflowPropDataType {
TypeApplication {
con: Box<WebflowPropDataType>, // Normally Passes the Type Constructor
arg: Box<WebflowPropDataType>, // Normally Passes the Row Constructor
},
TypeConstructor(Vec<String>), // Stores Value of TypeConstructor
RowCons {
label: String, // Stores the label of the Row
#[serde(rename = "type")]
row_con_type: Box<WebflowPropDataType>, // Stores the type of the Row
tail: Box<WebflowPropDataType>,
},
RowEmpty, // For Ending the recursive usage of rowConstructor
}
#[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct WebflowRowConDataType {
#[serde(rename = "type")]
val_type: String, // TypeApplication
val: Box<WebflowPropDataType>,
}
This works for a structure like this :
{
"type": "TypeApplication",
"val":{
"con": {
"type": "TypeConstructor",
"val": []
},
"arg": {
"type": "RowEmpty"
}
}
}
but would fail if I try to work with initial example. I know this may be due to the lack of a proper arg type or maybe even the TypeApplication Enum hand is malformed.
I do see that a adjancent typing solution would be enough for most of the times but there are cases as seen in the example structure that there is a third value called system and I am unable to determine what type of approach would help me achieve this type of outcome.
How should I approach this problem in order to generate this type of code.
I am not asking anyone to write me a solution but to give me suggestion as to what my approach should be? Whether you'd know what type of data this is/how to generated this , or even if there are some other library I should look into to manipulate this type of data or maybe look at other approaches.
PS : - My end goal is to be able to generate / serialize this type of JSON code from already contained knowledge of properties and default values of a function/object.
Here are my recommendations:
Use just #[serde(tag = "type")] instead of #[serde(tag = "type", content = "val")]. You will have to handle val manually (extracting the current enum members into separate structs), but this allows you to also handle TypeApplication.system and Element.meta.
This also has the small benefit of reducing the amount of Boxes involved.
Consider whether all of the different cases in WebflowPropDataType can actually occur everywhere it's used. If not (maybe Element can only happen under TypeApplication.val.arg), then you may want to split the enum into multiple so that this is reflected in the type system.
Example for #1:
use serde::{Serialize, Deserialize};
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TypeApplicationVal {
con: WebflowPropDataType, // Normally Passes the Type Constructor
arg: WebflowPropDataType, // Normally Passes the Row Constructor
}
// #[skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct TypeApplicationSystem {
label: String,
#[serde(rename = "isBindable")]
is_bindable: bool,
// TODO: defaultValue
#[serde(rename = "isUnlinked")]
#[serde(skip_serializing_if = "Option::is_none")]
is_unlinked: Option<bool>,
#[serde(rename = "isDefault")]
#[serde(skip_serializing_if = "Option::is_none")]
is_default: Option<bool>,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct RowConsVal {
label: String, // Stores the label of the Row
#[serde(rename = "type")]
typ: WebflowPropDataType, // Stores the type of the Row
tail: WebflowPropDataType,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ElementMeta {
#[serde(rename = "multiLine")]
multi_line: bool,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum WebflowPropDataType {
TypeApplication {
val: Box<TypeApplicationVal>,
#[serde(skip_serializing_if = "Option::is_none")]
system: Option<TypeApplicationSystem>,
},
TypeConstructor {
val: Vec<String> // Stores Value of TypeConstructor
},
RowCons {
val: Box<RowConsVal>,
},
Element {
meta: ElementMeta,
},
RowEmpty, // For Ending the recursive usage of rowConstructor
}
playground
I try to fill a treelist with remote data via a ajax proxy but the treelist shows only the first level and try to reload the sub levels even though the json response contain a complete tree structure. Fiddle link: https://fiddle.sencha.com/#view/editor&fiddle/33u9
When i try to expand the node 'SUB a' (or set the expanded property to true) the store trys to reload the node.
Why is the tree structure from the json response not honored?
Thanks in Advance.
The backend response looks like:
{
"data": {
"root": [
{
"leaf": true,
"text": "Server"
},
{
"leaf": true,
"text": "Storage"
},
{
"text": "SUB a"
"children": [
{
"leaf": true,
"text": "Modul A - 1"
},
{
"leaf": true,
"text": "Modul A - 2"
}
],
},
{
"leaf": true,
"text": "Modul B"
}
]
},
"success": true
}
The used reader config is
reader: {
type: 'json',
rootProperty: 'data.root',
successProperty: 'data.success',
},
After playing around i use the following workaround:
getNavigation: function() {
var me = this,
tree = me.getView().down('navigationtree'),
store = tree.getStore(),
node = store.getRoot();
Ext.Ajax.request({
url: '/getnav',
method: 'POST',
success: function(response) {
var obj = Ext.decode(response.responseText),
childs = obj.data.root;
tree.suspendEvents();
node.removeAll();
childs.forEach(function(item) {
node.appendChild(item);
});
tree.resumeEvents();
},
failure: function(response) {
//debugger;
console.log('server-side failure with status code ' + response.status);
}
}).then(function() {
//debugger;
}
);
}
The funny things is that only the first level of the tree has to be added all following sub-levels are added automaticaly.
I have the following in the application template:
<vaadin-grid id="directory">
<vaadin-grid-tree-column path="name" header="Name"></vaadin-grid-tree-column>
</vaadin-grid>
The iron-ajax calls the following on a successful response:
getlist(request) {
var myResponse = request.detail.response;
console.log(myResponse);
this.$.directory.items = myResponse;
}
The data that is returned is:
[
{
"name": "apps",
"fullpath": "/db/system/xqdoc/apps",
"children": [
{
"name": "xqDoc",
"fullpath": "/db/system/xqdoc/apps/xqDoc",
"children": [
{
"name": "modules",
"fullpath": "/db/system/xqdoc/apps/xqDoc/modules",
"children": [
{
"name": "config.xqm.xml",
"fullpath": "/db/system/xqdoc/apps/xqDoc/modules/config.xqm.xml"
},
{
"name": "xqdoc-lib.xqy.xml",
"fullpath": "/db/system/xqdoc/apps/xqDoc/modules/xqdoc-lib.xqy.xml"
}
]
}
]
}
]
}
]
The apps shows up, but when I expand the apps node, then xqDoc node doees not show up.
Do I need additional data in the dataset?
Am I missing some coding that is needed?
I have the solution.
<vaadin-grid id="directory" selected-items="{{selected}}">
<vaadin-grid-tree-column path="name" header="Name"item-has-children-path="hasChildren"></vaadin-grid-tree-column>
</vaadin-grid>
I setup the provider using the connectedCallback and not to use an iron-ajax for talking with the server.
connectedCallback() {
super.connectedCallback();
const grid = this.$.directory;
this.$.directory.dataProvider = function(params, callback) {
let url = "/exist/restxq/xqdoc/level" +
'?page=' + params.page + // the requested page index
'&per_page=' + params.pageSize; // number of items on the page
if (params.parentItem) {
url += '&path=' + params.parentItem.fullpath;
}
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var response = JSON.parse(xhr.responseText);
callback(
response.data, // requested page of items
response.totalSize // total number of items
);
};
xhr.open('GET', url, true);
xhr.send();
};
this.$.directory.addEventListener('active-item-changed', function(event) {
const item = event.detail.value;
if (item && item.hasChildren == false) {
grid.selectedItems = [item];
} else {
grid.selectedItems = [];
}
});
}
The web service returns a level of the tree:
{
"totalSize": 2,
"data": [
{
"name": "apps",
"fullpath": "/apps",
"hasChildren": true
},
{
"name": "lib",
"fullpath": "/lib",
"hasChildren": true
}
]
}
The codebase is here: https://github.com/lcahlander/xqDoc-eXist-db
I have an array like this:
var colors = [
{
"name": "red",
"ids":[
{
"id": 1
}
]
},
{
"name": "blue",
"ids":[
{
"id": 5
}
]
}
]
And I essentially want to find the object where the first id within ids is equal to something.
_.findWhere(colors, {
"ids.0.id": 1
})
Is this the best way to go about it?
var color = _.chain(colors)
.map(function(color){
color.id = color.ids[0].id
return color
})
.findWhere({
"id": 1
})
.value()
console.log(color)
_.findWhere is just a convenience wrapper for _.find so if findWhere doesn't do quite what you need, go straight to find and do it by hand:
var color = _(colors).find(function(color) {
return color.ids[0].id === 1;
});
I would like to do the following with the contextmenu plugin:
- Rename "Create" as "Add"
- Remove "Edit"
How does one do it?
I do NOT want to create a custom menu because then I only get a node and not the nice data object that can be used in the Create, Rename and Delete events.
Found the answer in the code of jstree itself:
Added this to the jstree code:
"contextmenu": {
items: customContextMenu
}
And this for the context menu items:
function customContextMenu() {
'use strict';
var items = {
"create" : {
"separator_before": false,
"separator_after": true,
"_disabled": false, //(this.check("create_node", data.reference, {}, "last")),
"label": "Add",
"action": function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.create_node(obj, {}, "last", function (new_node) {
setTimeout(function () { inst.edit(new_node); }, 0);
});
}
},
"rename" : {
"separator_before": false,
"separator_after": false,
"_disabled": false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")),
"label": "Rename",
"action": function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.edit(obj);
}
},
"remove" : {
"separator_before": false,
"icon": false,
"separator_after": false,
"_disabled": false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")),
"label": "Withdraw",
"action": function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
if (inst.is_selected(obj)) {
inst.delete_node(inst.get_selected());
} else {
inst.delete_node(obj);
}
}
}
};
return items;
}