chem-generic-ui 0.1.45 → 0.1.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.babelrc +11 -0
  2. package/.eslintrc +23 -0
  3. package/.tool-versions +3 -0
  4. package/chem-generic-ui-v0.1.41.tgz +0 -0
  5. package/dist/bundle.js +1 -1
  6. package/dist/bundle.js.LICENSE.txt +70 -0
  7. package/dist/ds_details.json +57 -0
  8. package/dist/ds_klass.json +102 -0
  9. package/dist/ds_props.json +54 -0
  10. package/dist/index.html +14 -0
  11. package/dist/sg_details.json +2036 -0
  12. package/dist/sg_klass.json +850 -0
  13. package/dist/units_system.json +430 -0
  14. package/package.json +3 -6
  15. package/public/ds_details.json +57 -0
  16. package/public/ds_klass.json +102 -0
  17. package/public/ds_props.json +54 -0
  18. package/public/favicon.ico +0 -0
  19. package/public/images/not_available.svg +1 -0
  20. package/public/index.html +47 -0
  21. package/public/logo192.png +0 -0
  22. package/public/logo512.png +0 -0
  23. package/public/manifest.json +25 -0
  24. package/public/robots.txt +3 -0
  25. package/public/sg_details.json +2036 -0
  26. package/public/sg_klass.json +850 -0
  27. package/public/test/ds_props.json +54 -0
  28. package/public/units_system.json +430 -0
  29. package/src/asserts/bootstrap-theme.min.css +6 -0
  30. package/src/asserts/bootstrap.min.css +6 -0
  31. package/src/asserts/main.css +458 -0
  32. package/src/asserts/main.scss +490 -0
  33. package/src/components/admin/ElementManager.js +28 -0
  34. package/src/components/details/GenDSDetails.js +164 -0
  35. package/src/components/details/GenSgDetails.js +396 -0
  36. package/src/components/dnd/DragDropItemTypes.js +13 -0
  37. package/src/components/dnd/GenericElDropTarget.js +160 -0
  38. package/src/components/dnd/GridDnD.js +42 -0
  39. package/src/components/dnd/PanelDnD.js +85 -0
  40. package/src/components/fields/ButtonConfirm.js +45 -0
  41. package/src/components/fields/ButtonTooltip.js +46 -0
  42. package/src/components/fields/FieldLabel.js +18 -0
  43. package/src/components/fields/GenDSMisType.js +20 -0
  44. package/src/components/fields/GenFormGroupCb.js +17 -0
  45. package/src/components/fields/GenProperties.js +56 -0
  46. package/src/components/fields/GenPropertiesFields.js +440 -0
  47. package/src/components/layers/GenPropertiesLayer.js +178 -0
  48. package/src/components/layers/LayerModal.js +52 -0
  49. package/src/components/layers/LayersLayout.js +68 -0
  50. package/src/components/models/Attachment.js +37 -0
  51. package/src/components/models/GenericSubField.js +10 -0
  52. package/src/components/table/DropLinkRenderer.js +35 -0
  53. package/src/components/table/DropRenderer.js +31 -0
  54. package/src/components/table/DropTextRenderer.js +25 -0
  55. package/src/components/table/GenericElTableDropTarget.js +131 -0
  56. package/src/components/table/GridBtn.js +41 -0
  57. package/src/components/table/GridEntry.js +75 -0
  58. package/src/components/table/SamOption.js +53 -0
  59. package/src/components/table/SelectRenderer.js +34 -0
  60. package/src/components/table/TableRecord.js +254 -0
  61. package/src/components/table/UConverterRenderer.js +24 -0
  62. package/src/components/tools/collate.js +65 -0
  63. package/src/components/tools/orten.js +171 -0
  64. package/src/components/tools/utils.js +414 -0
  65. package/src/data/SystemUnits.js +434 -0
  66. package/src/data/systemUnits.json +430 -0
  67. package/src/index.css +13 -0
  68. package/src/index.html +1 -0
  69. package/src/index.js +45 -0
  70. package/src/logo.svg +1 -0
  71. package/src/simulations/SimuDS.js +52 -0
  72. package/src/simulations/SimuSG.js +54 -0
  73. package/webpack.config.js +46 -0
@@ -0,0 +1,414 @@
1
+ /* eslint-disable no-param-reassign */
2
+ /* eslint-disable object-curly-newline */
3
+ /* eslint-disable camelcase */
4
+ /* eslint-disable no-unused-vars */
5
+ /* eslint-disable max-len */
6
+ /* eslint-disable react/forbid-prop-types */
7
+ import React from 'react';
8
+ // import PropTypes from 'prop-types';
9
+ // import { Button, OverlayTrigger, Tooltip, Popover, ControlLabel } from 'react-bootstrap';
10
+ // import uuid from 'uuid';
11
+ import { v4 as uuid } from 'uuid';
12
+ import { findIndex, findKey, cloneDeep } from 'lodash';
13
+ // import NotificationActions from '../../components/actions/NotificationActions';
14
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
15
+ import SystemUnits from '../../data/SystemUnits';
16
+ import Attachment from '../models/Attachment';
17
+
18
+ // move from GenericElCommon.js
19
+ const uploadFiles = (properties, event, field, layer) => {
20
+ const files = [];
21
+ const fieldObj = properties.layers[`${layer}`].fields.find(e => e.field === field) || {};
22
+ const value = fieldObj.value || {};
23
+ switch (event.action) {
24
+ case 'l': {
25
+ const valIdx = findIndex((value.files || []), o => o.uid === event.uid);
26
+ const label = event && event.val && event.val.target && event.val.target.value;
27
+ if (value.files[valIdx] && label) value.files[valIdx].label = label;
28
+ break;
29
+ }
30
+ case 'f': {
31
+ (event.val || []).forEach((file) => {
32
+ const uid = uuid();
33
+ if (typeof value.files === 'undefined' || value.files === null) value.files = [];
34
+ value.files.push({ uid, filename: file.name });
35
+ files.push({ uid, filename: file.name, file: Attachment.fromFile(file) });
36
+ });
37
+ break;
38
+ }
39
+ case 'd': {
40
+ const valIdx = findIndex((value.files || []), o => o.uid === event.uid);
41
+ if (valIdx >= 0 && value.files && value.files.length > 0) value.files.splice(valIdx, 1);
42
+ return [value, files, event.uid];
43
+ }
44
+ default:
45
+ console.log(event);
46
+ }
47
+ return [value, files];
48
+ };
49
+
50
+ // move from GenPropertiesLayer.js
51
+ const showProperties = (fObj, layers) => {
52
+ let showField = true;
53
+ if (fObj && fObj.cond_fields && fObj.cond_fields.length > 0) {
54
+ showField = false;
55
+ for (let i = 0; i < fObj.cond_fields.length; i += 1) {
56
+ const cond = fObj.cond_fields[i] || {};
57
+ const { layer, field, value } = cond;
58
+ if (field && field !== '') {
59
+ const fd = ((layers[layer] || {}).fields || []).find(f => f.field === field) || {};
60
+ if (fd.type === 'checkbox' && ((['false', 'no', 'f', '0'].includes((value || '').trim().toLowerCase()) && (typeof (fd && fd.value) === 'undefined' || fd.value === false)) ||
61
+ (['true', 'yes', 't', '1'].includes((value || '').trim().toLowerCase()) && (typeof (fd && fd.value) !== 'undefined' && fd.value === true)))) {
62
+ showField = true;
63
+ break;
64
+ } else if (['text', 'select'].includes(fd && fd.type) && (typeof (fd && fd.value) !== 'undefined' && ((fd && fd.value) || '').trim() === (value || '').trim())) {
65
+ showField = true;
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ }
71
+ return showField;
72
+ };
73
+
74
+ class GenericDummy {
75
+ constructor() {
76
+ this.type = 'dummy';
77
+ this.field = uuid();
78
+ this.position = 100;
79
+ this.label = '';
80
+ this.default = '';
81
+ this.required = false;
82
+ }
83
+ }
84
+
85
+ const inputEventVal = (event, type) => {
86
+ if (type === 'select') {
87
+ return event ? event.value : null;
88
+ } else if (type.startsWith('drag')) {
89
+ return event;
90
+ } else if (type === 'checkbox') {
91
+ return event.target.checked;
92
+ } else if (type === 'formula-field') {
93
+ if (event.target) {
94
+ return event.target.value;
95
+ }
96
+ return event;
97
+ }
98
+ return event.target && event.target.value;
99
+ };
100
+
101
+ const absOlsTermId = val => (val || '').split('|')[0].trim();
102
+ const absOlsTermLabel = val => val.replace(absOlsTermId(val), '').replace('|', '').trim();
103
+ const toNum = (val) => {
104
+ const parse = Number((val || ''));
105
+ return Number.isNaN(parse) ? 0 : parse;
106
+ };
107
+
108
+ const genUnitSup = (val) => {
109
+ if (typeof val === 'undefined' || val === null) return '';
110
+ const vals = val.match(/<\s*(\w+\b)(?:(?!<\s*\/\s*\1\b)[\s\S])*<\s*\/\s*\1\s*>|[^<]+/g);
111
+ const reV = vals.map((v) => {
112
+ const supVal = v.match(/<sup[^>]*>([^<]+)<\/sup>/);
113
+ if (supVal) return <sup key={uuid()}>{supVal[1]}</sup>;
114
+ const subVal = v.match(/<sub[^>]*>([^<]+)<\/sub>/);
115
+ if (subVal) return <sub key={uuid()}>{subVal[1]}</sub>;
116
+ return v;
117
+ });
118
+ return <span>{reV}</span>;
119
+ };
120
+
121
+ const toBool = (val) => {
122
+ const valLower = String(val).toLowerCase();
123
+ return !(!valLower || valLower === 'false' || valLower === '0');
124
+ };
125
+
126
+ const genUnitsSystem = () => (SystemUnits.SYSTEM_UNITS || {}).fields || [];
127
+
128
+ const genUnits = field => (genUnitsSystem().find(u => u.field === field) || {}).units || [];
129
+
130
+ const genUnit = (field, key) => {
131
+ const units = genUnits(field);
132
+ return units.find(u => u.key === key) || {};
133
+ };
134
+
135
+ const reUnit = (unitsSystem, optionLayers) => {
136
+ const uniFileds = (unitsSystem.fields || []);
137
+ const uniObj = uniFileds.find(fiel => fiel.field === optionLayers);
138
+ const defaultUnit = ((uniObj && uniObj.field) || '');
139
+ const preUnit = uniFileds.length > 0 ? uniFileds[0].field : '';
140
+ return defaultUnit === '' ? preUnit : defaultUnit;
141
+ };
142
+
143
+ const convertTemp = (key, val) => {
144
+ switch (key) {
145
+ case 'F':
146
+ return ((parseFloat(val) * 1.8) + 32).toFixed(2);
147
+ case 'K':
148
+ return (((parseFloat(val) + 459.67) * 5) / 9).toFixed(2);
149
+ case 'C':
150
+ return (parseFloat(val) - 273.15).toFixed(2);
151
+ default:
152
+ return val;
153
+ }
154
+ };
155
+
156
+ const unitConvToBase = (field = {}) => {
157
+ const units = genUnits(field.option_layers);
158
+ if (units.length <= 1) {
159
+ return field.value;
160
+ }
161
+ const idx = findIndex(units, u => u.key === field.value_system);
162
+ if (idx <= 0) return field.value;
163
+ return ((field.value * units[0].nm) / ((units[idx] && units[idx].nm) || 1) || 0);
164
+ };
165
+
166
+ const unitConversion = (field, key, val) => {
167
+ if (typeof val === 'undefined' || val == null || val === 0 || val === '') {
168
+ return val;
169
+ }
170
+ if (field === 'temperature') {
171
+ return convertTemp(key, val);
172
+ }
173
+ const units = genUnits(field);
174
+ if (units.length <= 1) {
175
+ return val;
176
+ }
177
+ const idx = findIndex(units, u => u.key === key);
178
+ if (idx === -1) {
179
+ return val;
180
+ }
181
+ const pIdx = idx === 0 ? (units.length) : idx;
182
+ const pre = (units[pIdx - 1] && units[pIdx - 1].nm) || 1;
183
+ const curr = (units[idx] && units[idx].nm) || 1;
184
+ return parseFloat((parseFloat(val) * (curr / pre)).toFixed(5));
185
+ };
186
+
187
+ // const notification = props =>
188
+ // (
189
+ // NotificationActions.add({
190
+ // title: props.title,
191
+ // message: props.msg,
192
+ // level: props.lvl,
193
+ // position: 'tc',
194
+ // dismissible: 'button',
195
+ // autoDismiss: props.autoDismiss || 5,
196
+ // uid: props.uid || uuid.v4()
197
+ // })
198
+ // );
199
+
200
+ // const validateLayerInput = (layer, act = 'new') => {
201
+ // if (layer.key === '') {
202
+ // notification({ title: `Layer [${layer.key}]`, lvl: 'error', msg: 'Please input Name.' });
203
+ // return false;
204
+ // }
205
+ // if (act === 'new' && !(/^[a-z][a-z_]+[a-z]$/g.test(layer.key))) {
206
+ // notification({ title: `Layer [${layer.key}]`, lvl: 'error', msg: 'This Name is invalid, please try a different one.' });
207
+ // return false;
208
+ // }
209
+ // if (parseInt((layer.cols || 1), 10) < 1) {
210
+ // notification({ title: `Layer [${layer.key}]`, lvl: 'error', msg: 'The minimun of Column per Row is 1, please input a different one.' });
211
+ // return false;
212
+ // }
213
+ // return true;
214
+ // };
215
+
216
+ // const validateSelectList = (selectName, element) => {
217
+ // if (selectName === '') {
218
+ // notification({ title: `Select List [${selectName}]`, lvl: 'error', msg: 'Please input Name.' });
219
+ // return false;
220
+ // }
221
+ // if (!(/^[a-z][a-z_]+[a-z]$/g.test(selectName))) {
222
+ // notification({ title: `Select List [${selectName}]`, lvl: 'error', msg: 'This Name is invalid, please try a different one.' });
223
+ // return false;
224
+ // }
225
+ // if (element.properties_template.select_options[`${selectName}`]) {
226
+ // notification({ title: `Select List [${selectName}]`, lvl: 'error', msg: 'This name of Select List is already taken. Please choose another one.' });
227
+ // return false;
228
+ // }
229
+ // return true;
230
+ // };
231
+
232
+ const clsInputGroup = (el) => {
233
+ if (!el) return el;
234
+ const genericEl = el;
235
+ const { layers } = genericEl.properties_template;
236
+ const keys = Object.keys(layers);
237
+ keys.forEach((key) => {
238
+ const layer = layers[key];
239
+ layer.fields.filter(e => e.type === 'input-group')
240
+ .forEach((e) => {
241
+ e.sub_fields.forEach((s) => {
242
+ const ff = s;
243
+ if (ff.type === 'text') { ff.value = ''; }
244
+ });
245
+ });
246
+ });
247
+ return genericEl;
248
+ };
249
+
250
+ const molOptions = [{ label: 'InChiKey', value: 'inchikey' }, { label: 'SMILES', value: 'smiles' }, { label: 'IUPAC', value: 'iupac' }, { label: 'Mass', value: 'molecular_weight' }];
251
+ const samOptions = [{ label: 'Name', value: 'name' }, { label: 'Ext. Label', value: 'external_label' }, { label: 'Mass', value: 'molecular_weight' }];
252
+
253
+ const findCurrentNode = (_srcKey, _layerVals) => {
254
+ const result = [];
255
+ const fs = _layerVals.filter(o => o.wf && o.wf_info && o.wf_info.source_layer === _srcKey);
256
+ if (fs.length > 1) {
257
+ fs.forEach((o) => {
258
+ findCurrentNode(o, _layerVals);
259
+ });
260
+ } else if (fs.length === 1) {
261
+ return findCurrentNode(fs[0].key, _layerVals);
262
+ }
263
+ return [_srcKey];
264
+ };
265
+
266
+ const decorateNode = (_elements, _layers) => {
267
+ if (!_elements || _elements.length < 1) return _elements;
268
+ const m = {
269
+ background: '#D6D5E6',
270
+ color: '#333',
271
+ // border: '1px solid #222138',
272
+ // width: 180,
273
+ };
274
+ const elements = _elements;
275
+ elements.map((e) => {
276
+ if (['input', 'output'].includes(e.type) || e.animated) return e;
277
+ const lk = e.data.lKey;
278
+ const fk = findKey(_layers, o => o.wf && (o.key === lk || o.key.startsWith(`${lk}.`)));
279
+ if (fk) {
280
+ e.style = m;
281
+ return e;
282
+ }
283
+ return e;
284
+ });
285
+ return elements;
286
+ };
287
+
288
+ const conFlowEls = (props) => {
289
+ const { properties, properties_release } = props;
290
+ const { flow, layers } = properties_release;
291
+ const deep = cloneDeep(flow);
292
+ const els = (deep && deep.elements) || [];
293
+ els.map((d) => {
294
+ if (['default'].includes(d.type) && d.data) {
295
+ const { lKey } = d.data;
296
+ const fk = findKey((properties.layers || {}), o => o.wf && (o.key === lKey || o.key.startsWith(`${lKey}.`)));
297
+ const chk = fk ? (<div style={{ position: 'absolute', top: '0px', right: '2px', color: 'green', zIndex: '100' }}><FontAwesomeIcon icon="far fa-check-circle" /></div>) : null;
298
+ const layer = layers[lKey] || {};
299
+ const ll = (
300
+ <div>
301
+ {chk}
302
+ <div style={{ borderWidth: '0px 0px 1px 0px', borderColor: 'black', borderStyle: 'solid' }}><b>{layer.label}</b></div>
303
+ <div>({layer.key})</div>
304
+ </div>
305
+ );
306
+ d.data = { label: ll, lKey: layer.key };
307
+ }
308
+ return d;
309
+ });
310
+ return els;
311
+ };
312
+
313
+ const storeFlow = (props) => {
314
+ const { elements } = props;
315
+ const els = cloneDeep(elements);
316
+ els.map((d) => {
317
+ if (['default'].includes(d.type) && d.data) {
318
+ delete d.data.label;
319
+ delete d.data.layer;
320
+ }
321
+ return d;
322
+ });
323
+ return els;
324
+ };
325
+
326
+ const flowDefault = [
327
+ {
328
+ id: '1', type: 'input', data: { label: 'Start' }, position: { x: 250, y: 15 }
329
+ },
330
+ {
331
+ id: '2', type: 'output', data: { label: 'End' }, position: { x: 250, y: 255 }
332
+ }
333
+ ];
334
+
335
+ const isLayerInWF = (_element, _layerKey) => {
336
+ const { flow } = _element.properties_template;
337
+ const finds = ((flow || {}).elements || []).filter(e => e.type === 'default' && (e.data || {}).lKey === _layerKey);
338
+ return (finds.length > 0);
339
+ };
340
+
341
+ // const validateLayerDeletion = (_element, _delKey) => {
342
+ // if (isLayerInWF(_element, _delKey)) {
343
+ // notification({ title: `Layer [${_delKey}]`, lvl: 'warning', msg: `This layer [${_delKey}] can not be removed because it is currently used in workflow.` });
344
+ // return false;
345
+ // }
346
+ // return true;
347
+ // };
348
+
349
+ // const validateLayerUpdation = (_element, _updates) => {
350
+ // const { key, wf } = _updates;
351
+ // if (isLayerInWF(_element, key)) {
352
+ // if (!wf) {
353
+ // notification({ title: `Layer [${key}]`, lvl: 'warning', msg: `Can not change the attribute 'used in Workflow?' because this layer [${key}] is currently used in workflow.` });
354
+ // return false;
355
+ // }
356
+ // }
357
+ // const { layers } = _element.properties_template;
358
+ // if (wf && layers[key] && (layers[key].cond_fields || []).length > 0) {
359
+ // notification({ title: `Layer [${key}]`, lvl: 'warning', msg: 'Can not use in Workflow because the Layer Restriction has been set.' });
360
+ // return false;
361
+ // }
362
+ // return true;
363
+ // };
364
+
365
+ const swapAryEls = (_ary, idx1, idx2) => {
366
+ const ary = _ary;
367
+ const temp = ary[idx1];
368
+ ary[idx1] = ary[idx2];
369
+ ary[idx2] = temp;
370
+ return ary;
371
+ };
372
+
373
+ // re-fetch workflow and set to state of store, should be out-of this project
374
+ // const renderFlowModal = (generic, isToggle) => {
375
+ // const segmentKlasses = (UserStore.getState() && UserStore.getState().segmentKlasses) || [];
376
+ // let shortLabel = generic.short_label;
377
+ // if (!shortLabel) {
378
+ // shortLabel = segmentKlasses.filter(s => s.id === generic.segment_klass_id);
379
+ // shortLabel = shortLabel.length > 0 ? shortLabel[0].label : '';
380
+ // }
381
+ // const params = {
382
+ // properties_release: cloneDeep(generic.properties_release) || {},
383
+ // properties: cloneDeep(generic.properties) || {},
384
+ // shortLabel,
385
+ // toggle: isToggle
386
+ // };
387
+ // UIActions.rerenderGenericWorkflow(params);
388
+ // };
389
+
390
+ const downloadFile = (file) => {
391
+ const { contents, name } = file;
392
+ const link = document.createElement('a');
393
+ link.download = name;
394
+ link.href = contents;
395
+ const event = new window.MouseEvent('click', {
396
+ view: window,
397
+ bubbles: true,
398
+ cancelable: true
399
+ });
400
+ link.dispatchEvent(event);
401
+ };
402
+
403
+ export {
404
+ GenericDummy,
405
+ // validateLayerInput,
406
+ // validateSelectList,
407
+ // notification,
408
+ genUnitsSystem, genUnits, genUnit,
409
+ unitConvToBase, unitConversion, toBool, toNum, genUnitSup, absOlsTermId, absOlsTermLabel, reUnit,
410
+ clsInputGroup, inputEventVal, molOptions, samOptions, conFlowEls, storeFlow, flowDefault,
411
+ // validateLayerUpdation,
412
+ // validateLayerDeletion,
413
+ swapAryEls, decorateNode, showProperties, downloadFile, uploadFiles
414
+ };