Skip to content

Commit ff3064c

Browse files
committed
feat: add text type input
1 parent ce18f1a commit ff3064c

File tree

9 files changed

+175
-73
lines changed

9 files changed

+175
-73
lines changed

src/api/services.xml

+1-1
Large diffs are not rendered by default.

src/js/api/requests.js

+3-36
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const getWorkflowById = async (id, asXml = false) => {
2323
if (asXml) {
2424
return await API.getWorkflowByIdJSON(id);
2525
} else {
26-
return await API.getWorkflowById(id);
26+
return await API.getWorkflowById(id, webservices);
2727
}
2828
} else {
2929
const xml = `<Workflow>
@@ -33,41 +33,8 @@ export const getWorkflowById = async (id, asXml = false) => {
3333
<Author/>
3434
</Information>
3535
<Steps>
36-
<Step>
37-
<No>0</No>
38-
<Name>OcropusBinarization</Name>
39-
<Service>
40-
<Key>6</Key>
41-
</Service>
42-
<Inputs>
43-
<Data>
44-
<Name>inputImage</Name>
45-
<Path>qwertz/2299942_0.jpg</Path>
46-
</Data>
47-
<Parameter>
48-
<Name>skewsteps</Name>
49-
<Value>543</Value></Parameter>
50-
</Inputs>
51-
</Step>
52-
<Step>
53-
<No>1</No>
54-
<Name>OtsuBinarization</Name>
55-
<Service>
56-
<Key>0</Key>
57-
</Service>
58-
<Inputs>
59-
<Data>
60-
<Name>inputImage</Name>
61-
<Value>
62-
<WorkflowStep>
63-
<Ref>0</Ref>
64-
<ServiceOutputName>ocropusBinaryImage</ServiceOutputName>
65-
</WorkflowStep>
66-
</Value>
67-
</Data>
68-
</Inputs>
69-
</Step>
70-
</Steps>
36+
<Step> <No>0</No> <Name>FilePickermimetypes</Name> <Service> <Key>47</Key> </Service> <Inputs> <Parameter> <Name>regex</Name> <Value>12345</Value> </Parameter> </Inputs> </Step> <Step> <No>1</No> <Name>OcropusBinarization</Name> <Service> <Key>6</Key> </Service> <Inputs> <Parameter> <Name>enableSkew</Name> <Value>true</Value> </Parameter> </Inputs> </Step>
37+
</Steps>
7138
</Workflow>`;
7239
return asXml ? xml : await Decorators.workflowDecorator(xml, webservices);
7340
}

src/js/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export let app;
148148
"$deleteElements",
149149
"$setSelectValueInElement",
150150
"$setInputValueInElement",
151+
"$setTextValueInElement",
151152
"$addLink",
152153
"deleteLink",
153154
"$moveSelectedElements",

src/js/constants/selectors.js

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const DATA_INPUT_CONTENT_CLASS = "content";
1313

1414
export const PARAMETER_INPUTS = "inputs";
1515
export const PARAMETER_SELECTS = "selects";
16+
export const PARAMETER_TEXTS = "texts";
1617

1718
export const AREA_SELECTION_ELEMENT = "areaSelectionHighlight";
1819
export const TRASH_SELECTOR = "#trash";

src/js/elements/addElement.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,17 @@ const createBox = (
123123
* @param {object} params
124124
*/
125125
export const buildDefaultParameters = params => {
126-
const defaultParams = { select: {}, number: {} };
126+
const defaultParams = { select: {}, number: {}, text: {} };
127127
for (const p of params) {
128-
let { type, name, defaultValue, values } = p;
128+
let { type, name, defaultValue, definedValue, values } = p;
129129
if (type === Types.SELECT.type) {
130130
defaultValue = values[defaultValue];
131131
}
132-
defaultParams[type][name] = { value: defaultValue, defaultValue, values };
132+
defaultParams[type][name] = {
133+
value: definedValue ? definedValue : defaultValue,
134+
defaultValue,
135+
values
136+
};
133137
}
134138
return defaultParams;
135139
};

src/js/layout/inputs.js

+116-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import {
2626
NO_PARAMETER_CLASS,
2727
PARAMETER_SELECTS,
2828
PARAMETER_INPUTS,
29-
INTERFACE_ROOT
29+
INTERFACE_ROOT,
30+
PARAMETER_TEXTS
3031
} from "../constants/selectors";
3132
import { objectToString } from "./utils";
3233
import { layoutSettingsApp } from "../layoutSettings";
@@ -378,6 +379,97 @@ export const checkInputValue = (input, { boxName, boxId }) => {
378379
input.toggleClass("is-invalid", !isValid);
379380
};
380381

382+
/**
383+
* create text DOM element, with
384+
* - name
385+
* - text tag
386+
* - reset button
387+
* - information
388+
*
389+
* @param {*} element element to append select
390+
* @param {*} param parameter data
391+
* @param {*} resetButton reset button html element
392+
* @param {*} defaultTooltip default tooltip html element
393+
* @param {*} givenDefaultValue default value
394+
*/
395+
export const createText = (
396+
element,
397+
param,
398+
resetButton,
399+
defaultTooltip,
400+
givenDefaultValue
401+
) => {
402+
const {
403+
name,
404+
values = {},
405+
defaultValue: defaultOption,
406+
description,
407+
$: attributes
408+
} = param;
409+
410+
// wrapper
411+
const newText = $("<div/>", { class: "input row" });
412+
413+
// param name
414+
const nameEl = $("<span/>", {
415+
class: `${PARAM_NAME_CLASS} ${NAME_COL}`,
416+
text: name,
417+
title: name
418+
});
419+
420+
// param input
421+
let required = false;
422+
if (attributes && attributes.Status === "required") {
423+
required = true;
424+
}
425+
426+
const inputEl = $(`<${Types.TEXT.tag} />`, {
427+
class: `${PARAM_COL} form-control mr-1`,
428+
prop: { disabled: false, required }, // userdefined?
429+
attr: {
430+
type: "text",
431+
name,
432+
"data-default": defaultOption,
433+
value: givenDefaultValue ? givenDefaultValue : defaultOption
434+
}
435+
});
436+
437+
// update param
438+
inputEl.on({
439+
blur: function() {
440+
const input = $(this);
441+
const value = input.val();
442+
const attr = input.attr("name");
443+
app.$setTextValueInElement({ element, attr, value });
444+
},
445+
click: function() {
446+
$(this).select();
447+
},
448+
input: function() {
449+
// do not save each time you write, or it would be annoying
450+
}
451+
});
452+
453+
// reset
454+
const resetButtonNumber = resetButton.clone(true).attr({
455+
"data-parent": "input",
456+
"data-value": defaultOption
457+
});
458+
459+
// add tooltip
460+
let tooltip = $();
461+
if (description || values.length) {
462+
const tooltipText = `${description}${TOOLTIP_BREAK_LINE}${objectToString({
463+
default: defaultOption,
464+
...values
465+
})}`;
466+
tooltip = defaultTooltip.attr("data-title", tooltipText);
467+
}
468+
469+
newText.append(nameEl, inputEl, resetButtonNumber, tooltip);
470+
return newText;
471+
};
472+
381473
/**
382474
* create and append parameters in foreign object of element
383475
*
@@ -399,6 +491,7 @@ export const createParametersInForeignObject = (
399491

400492
const selectsArr = [];
401493
const inputsArr = [];
494+
const textsArr = [];
402495

403496
// create reset button
404497
const resetButton = $("<button/>", {
@@ -446,6 +539,17 @@ export const createParametersInForeignObject = (
446539
inputsArr.push(newInput);
447540
break;
448541
}
542+
case Types.TEXT.type: {
543+
const newText = createText(
544+
element,
545+
param,
546+
resetButton,
547+
defaultTooltip,
548+
defaultValue
549+
);
550+
textsArr.push(newText);
551+
break;
552+
}
449553
default:
450554
throw "Type " + type + " not handled";
451555
}
@@ -454,20 +558,28 @@ export const createParametersInForeignObject = (
454558
// append selects and inputs
455559
const selects = $("<div/>", { class: PARAMETER_SELECTS });
456560
const inputs = $("<div/>", { class: PARAMETER_INPUTS });
561+
const texts = $("<div/>", { class: PARAMETER_TEXTS });
457562
selects.append(selectsArr);
458563
inputs.append(inputsArr);
564+
texts.append(textsArr);
565+
const parameters = [selects, inputs, texts];
459566

460567
// add params to boxes
461568
const foreignObject = $(
462569
`g[model-id=${element.attributes.id}] foreignObject body`
463570
);
464571
const container = foreignObject
465572
.find(`.${BOX_CONTAINER_CLASS}`)
466-
.append(inputs, selects);
573+
.append(parameters);
467574

468575
// create text if no parameter
469576
let noParameter = $();
470-
if (inputs.children().length + selects.children().length === 0) {
577+
if (
578+
inputs.children().length +
579+
selects.children().length +
580+
texts.children().length ===
581+
0
582+
) {
471583
noParameter = $(`<div/>`, {
472584
class: NO_PARAMETER_CLASS,
473585
text: NO_PARAMETER_TEXT
@@ -477,8 +589,7 @@ export const createParametersInForeignObject = (
477589
// hide parameters depending on theme options
478590
const showParameters = layoutSettingsApp.isShowParametersChecked();
479591
if (!showParameters) {
480-
selects.hide();
481-
inputs.hide();
592+
parameters.forEach(el => el.hide());
482593
noParameter.hide();
483594
}
484595

src/js/layout/utils.js

+38-18
Original file line numberDiff line numberDiff line change
@@ -69,33 +69,53 @@ export const generateUniqueId = () => {
6969
.substr(2, 9);
7070
};
7171

72+
/**
73+
* return whether the input is of type parameter
74+
* useful to differentiate from inputs and ports parameters
75+
*
76+
* @param {*} input
77+
*/
7278
export const isParamInput = input => {
79+
const validParameterTypes = [
80+
Types.SELECT.type,
81+
Types.NUMBER.type,
82+
Types.TEXT.type
83+
];
7384
if (input.type) {
74-
return input.type === Types.SELECT.type || input.type === Types.NUMBER.type;
85+
return validParameterTypes.includes(input.type);
7586
}
7687

77-
return input[Types.SELECT.type] || input[Types.NUMBER.type];
88+
return validParameterTypes.map(type => input[type]).includes(true);
7889
};
7990

80-
export const isPort = el => {
81-
if (el.type) {
82-
return el.type === Types.FILE.type || el.type === Types.FOLDER.type;
83-
}
84-
return el[Types.FILE.type] || el[Types.FOLDER.type];
85-
};
86-
87-
export const isPortUserdefined = el => {
88-
if (el.type) {
89-
return (
90-
el.type === Types.FILE.type || el.type === Types.FOLDER.type
91-
// && el.userdefined
92-
);
91+
// export const isPort = el => {
92+
// if (el.type) {
93+
// return el.type === Types.FILE.type || el.type === Types.FOLDER.type;
94+
// }
95+
// return el[Types.FILE.type] || el[Types.FOLDER.type];
96+
// };
97+
98+
/**
99+
* return whether the element is of port
100+
* useful to differentiate from inputs and ports parameters
101+
*
102+
* @param {*} input
103+
*/
104+
export const isPortUserdefined = input => {
105+
const validPortTypes = [Types.FILE.type, Types.FOLDER.type];
106+
if (input.type) {
107+
return validPortTypes.includes(input.type);
108+
// && input.userdefined
93109
}
94-
return (
95-
el[Types.FILE.type] || el[Types.FOLDER.type] //&& el[Object.keys(el)[0]].userdefined
96-
);
110+
return validPortTypes.map(type => input[type]).includes(true); //&& el[Object.keys(el)[0]].userdefined
97111
};
98112

113+
/**
114+
* transform object to a readable string
115+
* use to format values constraints (min, max, default, ...)
116+
*
117+
* @param {object} obj
118+
*/
99119
export const objectToString = obj => {
100120
let str = "";
101121
for (let p in obj) {

src/js/store/modules/Interface.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import {
3333
DELETE_LINK,
3434
ADD_LINK,
3535
SET_INPUT_VALUE,
36-
SET_SELECT_VALUE,
3736
COPY_SELECTION,
3837
UNSELECT_ALL_ELEMENTS,
3938
MOVE_ELEMENTS,
@@ -92,13 +91,9 @@ const Interface = {
9291
[COPY_SELECTION](state) {
9392
state.elements.forEach(el => (el.copied = el.selected));
9493
},
95-
[SET_SELECT_VALUE](state, { element, value, attr }) {
94+
[SET_INPUT_VALUE](state, { type, element, value, attr }) {
9695
const el = findElementByBoxId(state.elements, element.attributes.boxId);
97-
Vue.set(el.defaultParams[Types.SELECT.type][attr], "value", value);
98-
},
99-
[SET_INPUT_VALUE](state, { element, value, attr }) {
100-
const el = findElementByBoxId(state.elements, element.attributes.boxId);
101-
Vue.set(el.defaultParams[Types.NUMBER.type][attr], "value", value);
96+
Vue.set(el.defaultParams[type][attr], "value", value);
10297
},
10398
[ADD_LINK](state, { link, graph }) {
10499
addLinktoLinks(state.links, link, graph);
@@ -184,10 +179,13 @@ const Interface = {
184179
commit(COPY_SELECTION);
185180
},
186181
$setSelectValueInElement({ commit }, payload) {
187-
commit(SET_SELECT_VALUE, payload);
182+
commit(SET_INPUT_VALUE, { type: Types.SELECT.type, ...payload });
188183
},
189184
$setInputValueInElement({ commit }, payload) {
190-
commit(SET_INPUT_VALUE, payload);
185+
commit(SET_INPUT_VALUE, { type: Types.NUMBER.type, ...payload });
186+
},
187+
$setTextValueInElement({ commit }, payload) {
188+
commit(SET_INPUT_VALUE, { type: Types.TEXT.type, ...payload });
191189
},
192190
$addLink({ commit }, payload) {
193191
commit(ADD_LINK, payload);

yarn.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -2747,7 +2747,7 @@ diffie-hellman@^5.0.0:
27472747

27482748
"divaservices-utils@https://github.com/pyphilia/divaservices-utils":
27492749
version "1.0.0"
2750-
resolved "https://github.com/pyphilia/divaservices-utils#3414747eb12fa0befbc24a6545c5d3d3f317c1cb"
2750+
resolved "https://github.com/pyphilia/divaservices-utils#dc3bf6dd7dd75e0c7d02526d713ff665eddfd8a6"
27512751
dependencies:
27522752
eslint "^6.6.0"
27532753
node-fetch "^2.6.0"

0 commit comments

Comments
 (0)