@icure/form 1.0.0
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.
- package/.editorconfig +12 -0
- package/.idea/inspectionProfiles/Project_Default.xml +73 -0
- package/.idea/iqr-text-field.iml +9 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.mocharc.json +5 -0
- package/app/demo-app.ts +191 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +14 -0
- package/lib/iqr-form/fields/datePicker.d.ts +8 -0
- package/lib/iqr-form/fields/datePicker.js +42 -0
- package/lib/iqr-form/fields/dateTimePicker.d.ts +8 -0
- package/lib/iqr-form/fields/dateTimePicker.js +42 -0
- package/lib/iqr-form/fields/measureField.d.ts +8 -0
- package/lib/iqr-form/fields/measureField.js +42 -0
- package/lib/iqr-form/fields/multipleChoice.d.ts +8 -0
- package/lib/iqr-form/fields/multipleChoice.js +42 -0
- package/lib/iqr-form/fields/numberField.d.ts +8 -0
- package/lib/iqr-form/fields/numberField.js +42 -0
- package/lib/iqr-form/fields/textfield.d.ts +1 -0
- package/lib/iqr-form/fields/textfield.js +86 -0
- package/lib/iqr-form/fields/timePicker.d.ts +8 -0
- package/lib/iqr-form/fields/timePicker.js +42 -0
- package/lib/iqr-form/index.d.ts +7 -0
- package/lib/iqr-form/index.js +83 -0
- package/lib/iqr-form/model/index.d.ts +78 -0
- package/lib/iqr-form/model/index.js +114 -0
- package/lib/iqr-form/renderer/cards.d.ts +2 -0
- package/lib/iqr-form/renderer/cards.js +43 -0
- package/lib/iqr-form/renderer/form.d.ts +2 -0
- package/lib/iqr-form/renderer/form.js +44 -0
- package/lib/iqr-form/renderer/index.d.ts +3 -0
- package/lib/iqr-form/renderer/index.js +2 -0
- package/lib/iqr-text-field/index.d.ts +2 -0
- package/lib/iqr-text-field/index.js +335 -0
- package/lib/iqr-text-field/plugin/caret-fix-plugin.d.ts +2 -0
- package/lib/iqr-text-field/plugin/caret-fix-plugin.js +23 -0
- package/lib/iqr-text-field/plugin/has-content-class-plugin.d.ts +2 -0
- package/lib/iqr-text-field/plugin/has-content-class-plugin.js +18 -0
- package/lib/iqr-text-field/plugin/mask-plugin.d.ts +2 -0
- package/lib/iqr-text-field/plugin/mask-plugin.js +143 -0
- package/lib/iqr-text-field/plugin/regexp-plugin.d.ts +2 -0
- package/lib/iqr-text-field/plugin/regexp-plugin.js +46 -0
- package/lib/iqr-text-field/prosemirror-commands.d.ts +4 -0
- package/lib/iqr-text-field/prosemirror-commands.js +52 -0
- package/lib/iqr-text-field/prosemirror-utils.d.ts +5 -0
- package/lib/iqr-text-field/prosemirror-utils.js +15 -0
- package/lib/iqr-text-field/schema/common-marks.d.ts +10 -0
- package/lib/iqr-text-field/schema/common-marks.js +90 -0
- package/lib/iqr-text-field/schema/date-time-schema.d.ts +7 -0
- package/lib/iqr-text-field/schema/date-time-schema.js +88 -0
- package/lib/iqr-text-field/schema/decimal-schema.d.ts +3 -0
- package/lib/iqr-text-field/schema/decimal-schema.js +27 -0
- package/lib/iqr-text-field/schema/index.d.ts +11 -0
- package/lib/iqr-text-field/schema/index.js +18 -0
- package/lib/iqr-text-field/schema/markdown-schema.d.ts +8 -0
- package/lib/iqr-text-field/schema/markdown-schema.js +139 -0
- package/lib/iqr-text-field/schema/measure-schema.d.ts +3 -0
- package/lib/iqr-text-field/schema/measure-schema.js +35 -0
- package/lib/iqr-text-field/schema/token-schema.d.ts +6 -0
- package/lib/iqr-text-field/schema/token-schema.js +36 -0
- package/lib/iqr-text-field/schema/utils.d.ts +11 -0
- package/lib/iqr-text-field/schema/utils.js +11 -0
- package/lib/iqr-text-field/selection-companion.d.ts +11 -0
- package/lib/iqr-text-field/selection-companion.js +52 -0
- package/lib/iqr-text-field/suggestion-palette.d.ts +33 -0
- package/lib/iqr-text-field/suggestion-palette.js +139 -0
- package/package.json +60 -0
- package/test/form.yaml +96 -0
- package/test/simple/test.spec.ts +303 -0
- package/webpack.config.js +41 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SuggestionPalette = void 0;
|
|
7
|
+
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
|
8
|
+
class SuggestionPalette {
|
|
9
|
+
constructor(view, suggestionProvider, suggestionStopWordsProvider, delay) {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
this.delay = () => false;
|
|
12
|
+
this.lastTime = 0;
|
|
13
|
+
this.hasFocus = false;
|
|
14
|
+
this.suggestions = [];
|
|
15
|
+
this.suggestionStopWordsProvider = suggestionStopWordsProvider;
|
|
16
|
+
this.suggestionProvider = suggestionProvider;
|
|
17
|
+
this.palette = document.createElement("div");
|
|
18
|
+
this.palette.className = "suggestion-palette";
|
|
19
|
+
(_b = (_a = view.dom) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.appendChild(this.palette);
|
|
20
|
+
delay && (this.delay = delay);
|
|
21
|
+
this.update(view, undefined);
|
|
22
|
+
}
|
|
23
|
+
focusItem(idx) {
|
|
24
|
+
const ul = this.palette.getElementsByTagName('ul')[0];
|
|
25
|
+
if (ul) {
|
|
26
|
+
ul.classList.add('focused');
|
|
27
|
+
const lis = ul.getElementsByTagName('li');
|
|
28
|
+
this.currentFocus !== undefined && lis[this.currentFocus].classList.remove('focused');
|
|
29
|
+
idx !== undefined && lis[idx].classList.add('focused');
|
|
30
|
+
this.currentFocus = idx;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
focus() {
|
|
34
|
+
if (this.palette.style.display === "none")
|
|
35
|
+
return false;
|
|
36
|
+
this.hasFocus = true;
|
|
37
|
+
this.focusItem(0);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
focusOrInsert(view, transactionProvider) {
|
|
41
|
+
if (this.palette.style.display === "none")
|
|
42
|
+
return false;
|
|
43
|
+
return this.hasFocus ? this.insert(view, transactionProvider) : this.focus();
|
|
44
|
+
}
|
|
45
|
+
insert(view, transactionProvider) {
|
|
46
|
+
if (this.palette.style.display === "none" || !this.hasFocus || this.currentFocus === undefined)
|
|
47
|
+
return false;
|
|
48
|
+
const sug = this.suggestions[this.currentFocus];
|
|
49
|
+
if (sug) {
|
|
50
|
+
const sel = view.state.selection;
|
|
51
|
+
const stopWords = this.suggestionStopWordsProvider();
|
|
52
|
+
let length = sug.terms.join(' ').length - 1;
|
|
53
|
+
while (sel.to - length >= 0 && !fast_deep_equal_1.default(view.state.doc.textBetween(sel.to - length, sel.to).split(/\s+/).filter(x => !stopWords.has(x)), sug.terms)) {
|
|
54
|
+
length++;
|
|
55
|
+
}
|
|
56
|
+
if (length > sel.to) {
|
|
57
|
+
length = sug.terms.join(' ').length;
|
|
58
|
+
while (sel.to - length >= 0 && !view.state.doc.textBetween(sel.to - length, sel.to).startsWith(sug.terms[0])) {
|
|
59
|
+
length++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (length <= sel.to) {
|
|
63
|
+
transactionProvider(sel.to - length, sel.to, sug).then(tr => tr && view.dispatch(tr.scrollIntoView()));
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
arrowUp() {
|
|
70
|
+
if (!this.hasFocus)
|
|
71
|
+
return false;
|
|
72
|
+
this.currentFocus && this.focusItem(this.currentFocus - 1);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
arrowDown() {
|
|
76
|
+
if (!this.hasFocus)
|
|
77
|
+
return false;
|
|
78
|
+
this.currentFocus !== undefined && this.currentFocus < this.palette.getElementsByTagName('ul')[0].childElementCount - 1 && this.focusItem(this.currentFocus + 1);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
update(view, lastState) {
|
|
82
|
+
let state = view.state;
|
|
83
|
+
// Hide the palette if the selection is not empty
|
|
84
|
+
this.focusItem(undefined);
|
|
85
|
+
this.hasFocus = false;
|
|
86
|
+
if (!state.selection.empty) {
|
|
87
|
+
this.palette.style.display = "none";
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
let $pos = state.selection.$head;
|
|
91
|
+
if ((lastState === null || lastState === void 0 ? void 0 : lastState.doc.textContent) === state.doc.textContent) {
|
|
92
|
+
this.palette.style.display = "none";
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const text = state.doc.textBetween($pos.pos ? $pos.before() + 1 : 0, $pos.pos);
|
|
96
|
+
const words = text.split(/\s+/);
|
|
97
|
+
const terms = words.filter(x => x.length > 2 && !this.suggestionStopWordsProvider().has(x));
|
|
98
|
+
const lastTerms = terms.length > 3 ? terms.slice(length - 3) : terms;
|
|
99
|
+
const fingerprint = lastTerms.join(' ');
|
|
100
|
+
const { to } = state.selection;
|
|
101
|
+
if (this.previousFingerprint !== fingerprint) {
|
|
102
|
+
this.previousFingerprint = fingerprint;
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
if (this.previousFingerprint !== fingerprint)
|
|
105
|
+
return;
|
|
106
|
+
const res = this.suggestionProvider(lastTerms);
|
|
107
|
+
this.suggestions = res;
|
|
108
|
+
if (res.length) {
|
|
109
|
+
this.palette.innerHTML = `<ul>${res.map(x => `<li id="${x.id}" data-code="${x.code}">${x.text}<div class="icn-container"><svg class="tab-icn" viewBox="0 0 24 24"><path d="M12.29 8.12L15.17 11H2c-.55 0-1 .45-1 1s.45 1 1 1h13.17l-2.88 2.88c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0l4.59-4.59c.39-.39.39-1.02 0-1.41L13.7 6.7c-.39-.39-1.02-.39-1.41 0-.38.39-.39 1.03 0 1.42zM20 7v10c0 .55.45 1 1 1s1-.45 1-1V7c0-.55-.45-1-1-1s-1 .45-1 1z"/></svg><svg class="return-icn" viewBox="0 0 24 24"><path d="M19 8v3H5.83l2.88-2.88c.39-.39.39-1.02 0-1.41-.39-.39-1.02-.39-1.41 0L2.71 11.3c-.39.39-.39 1.02 0 1.41L7.3 17.3c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L5.83 13H20c.55 0 1-.45 1-1V8c0-.55-.45-1-1-1s-1 .45-1 1z"/></svg></div></li>`).join('\n')}</ul>`;
|
|
110
|
+
// These are in screen coordinates
|
|
111
|
+
const end = view.coordsAtPos(to);
|
|
112
|
+
this.display(end, (this.lastTime = +new Date()));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.palette.style.display = "none";
|
|
116
|
+
}
|
|
117
|
+
}, 30);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
display(pos, time) {
|
|
121
|
+
var _a;
|
|
122
|
+
if (time !== this.lastTime)
|
|
123
|
+
return;
|
|
124
|
+
if (this.delay()) {
|
|
125
|
+
setTimeout(() => this.display(pos, time), 100);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
this.palette.style.display = "";
|
|
129
|
+
const box = (_a = this.palette.offsetParent) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
|
|
130
|
+
const palBox = this.palette.getBoundingClientRect();
|
|
131
|
+
if (box) {
|
|
132
|
+
const l = (box.left + pos.left);
|
|
133
|
+
this.palette.style.left = Math.max(box.left, l - palBox.width) + 'px';
|
|
134
|
+
this.palette.style.top = (pos.top + box.top) + "px";
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
destroy() { this.palette.remove(); }
|
|
138
|
+
}
|
|
139
|
+
exports.SuggestionPalette = SuggestionPalette;
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@icure/form",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "webpack-dev-server --env.mode development",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dist": "webpack --env.mode production",
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@icure/api": "^4.0.8",
|
|
17
|
+
"@webcomponents/webcomponentsjs": "^2.4.4",
|
|
18
|
+
"fast-deep-equal": "^3.1.3",
|
|
19
|
+
"lit-element": "^2.4.0",
|
|
20
|
+
"prosemirror-commands": "^1.1.4",
|
|
21
|
+
"prosemirror-history": "^1.1.3",
|
|
22
|
+
"prosemirror-keymap": "^1.1.4",
|
|
23
|
+
"prosemirror-markdown": "^1.5.0",
|
|
24
|
+
"prosemirror-model": "^1.11.2",
|
|
25
|
+
"prosemirror-schema-basic": "^1.1.2",
|
|
26
|
+
"prosemirror-schema-list": "^1.1.4",
|
|
27
|
+
"prosemirror-state": "^1.3.4",
|
|
28
|
+
"prosemirror-view": "^1.16.0",
|
|
29
|
+
"yaml": "^1.10.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/mocha": "^8.2.0",
|
|
33
|
+
"@types/prosemirror-commands": "^1.0.3",
|
|
34
|
+
"@types/prosemirror-history": "^1.0.1",
|
|
35
|
+
"@types/prosemirror-keymap": "^1.0.3",
|
|
36
|
+
"@types/prosemirror-markdown": "^1.0.3",
|
|
37
|
+
"@types/prosemirror-schema-basic": "^1.0.1",
|
|
38
|
+
"@types/prosemirror-schema-list": "^1.0.1",
|
|
39
|
+
"@types/prosemirror-state": "^1.2.6",
|
|
40
|
+
"@types/prosemirror-view": "^1.15.1",
|
|
41
|
+
"assert": "^2.0.0",
|
|
42
|
+
"babel": "^6.23.0",
|
|
43
|
+
"babel-preset-es2017": "^6.24.1",
|
|
44
|
+
"copy-webpack-plugin": "^6.2.0",
|
|
45
|
+
"css-loader": "^5.0.1",
|
|
46
|
+
"extract-loader": "^5.1.0",
|
|
47
|
+
"html-webpack-plugin": "^4.5.0",
|
|
48
|
+
"lit-scss-loader": "^1.0.1",
|
|
49
|
+
"minisearch": "^3.0.2",
|
|
50
|
+
"mocha": "^8.2.1",
|
|
51
|
+
"sass": "^1.32.2",
|
|
52
|
+
"sass-loader": "^10.1.1",
|
|
53
|
+
"ts-loader": "^8.0.4",
|
|
54
|
+
"ts-node": "^9.1.1",
|
|
55
|
+
"typescript": "^4.0.3",
|
|
56
|
+
"webpack": "^4.44.2",
|
|
57
|
+
"webpack-cli": "^3.3.12",
|
|
58
|
+
"webpack-dev-server": "^3.11.0"
|
|
59
|
+
}
|
|
60
|
+
}
|
package/test/form.yaml
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
form: Waiting room GP
|
|
2
|
+
description: Fill in the patient information inside the waiting room
|
|
3
|
+
sections:
|
|
4
|
+
- section: All fields
|
|
5
|
+
fields:
|
|
6
|
+
- field: This field is a TextField
|
|
7
|
+
type: textfield
|
|
8
|
+
shortLabel: TextField
|
|
9
|
+
schema: styled-text-with-codes
|
|
10
|
+
- field: This field is a NumberField
|
|
11
|
+
type: number-field
|
|
12
|
+
shortLabel: NumberField
|
|
13
|
+
- field: This field is a MeasureField
|
|
14
|
+
type: measure-field
|
|
15
|
+
shortLabel: MeasureField
|
|
16
|
+
- field: This field is a DatePicker
|
|
17
|
+
type: date-picker
|
|
18
|
+
shortLabel: DatePicker
|
|
19
|
+
- field: This field is a TimePicker
|
|
20
|
+
type: time-picker
|
|
21
|
+
shortLabel: TimePicker
|
|
22
|
+
- field: This field is a DateTimePicker
|
|
23
|
+
type: date-time-picker
|
|
24
|
+
shortLabel: DateTimePicker
|
|
25
|
+
- field: This field is a MultipleChoice
|
|
26
|
+
type: multiple-choice
|
|
27
|
+
shortLabel: MultipleChoice
|
|
28
|
+
- section: Grouped fields
|
|
29
|
+
groups:
|
|
30
|
+
- group: You can group fields together
|
|
31
|
+
fields:
|
|
32
|
+
- field: This field is a TextField
|
|
33
|
+
type: textfield
|
|
34
|
+
shortLabel: TextField
|
|
35
|
+
schema: styled-text-with-codes
|
|
36
|
+
- field: This field is a NumberField
|
|
37
|
+
type: number-field
|
|
38
|
+
shortLabel: NumberField
|
|
39
|
+
- field: This field is a MeasureField
|
|
40
|
+
type: measure-field
|
|
41
|
+
shortLabel: MeasureField
|
|
42
|
+
- field: This field is a DatePicker
|
|
43
|
+
type: date-picker
|
|
44
|
+
shortLabel: DatePicker
|
|
45
|
+
- field: This field is a TimePicker
|
|
46
|
+
type: time-picker
|
|
47
|
+
shortLabel: TimePicker
|
|
48
|
+
- field: This field is a DateTimePicker
|
|
49
|
+
type: date-time-picker
|
|
50
|
+
shortLabel: DateTimePicker
|
|
51
|
+
- field: This field is a MultipleChoice
|
|
52
|
+
type: multiple-choice
|
|
53
|
+
shortLabel: MultipleChoice
|
|
54
|
+
- group: And you can add tags and codes
|
|
55
|
+
fields:
|
|
56
|
+
- field: This field is a TextField
|
|
57
|
+
type: textfield
|
|
58
|
+
shortLabel: TextField
|
|
59
|
+
rows: 3
|
|
60
|
+
grows: true
|
|
61
|
+
schema: text-document
|
|
62
|
+
tags:
|
|
63
|
+
- CD-ITEM|diagnosis|1
|
|
64
|
+
codifications:
|
|
65
|
+
- BE-THESAURUS
|
|
66
|
+
- ICD10
|
|
67
|
+
options:
|
|
68
|
+
option: blink
|
|
69
|
+
- field: This field is a NumberField
|
|
70
|
+
type: number-field
|
|
71
|
+
shortLabel: NumberField
|
|
72
|
+
tags:
|
|
73
|
+
- CD-ITEM|parameter|1
|
|
74
|
+
- CD-PARAMETER|bmi|1
|
|
75
|
+
codifications: []
|
|
76
|
+
options:
|
|
77
|
+
option: bang
|
|
78
|
+
- field: This field is a MeasureField
|
|
79
|
+
type: measure-field
|
|
80
|
+
shortLabel: MeasureField
|
|
81
|
+
tags:
|
|
82
|
+
- CD-ITEM|parameter|1
|
|
83
|
+
- CD-PARAMETER|heartbeat|1
|
|
84
|
+
codifications: []
|
|
85
|
+
options:
|
|
86
|
+
unit: bpm
|
|
87
|
+
- field: This field is a MultipleChoice
|
|
88
|
+
type: multiple-choice
|
|
89
|
+
shortLabel: MultipleChoice
|
|
90
|
+
rows: 4
|
|
91
|
+
columns: 4
|
|
92
|
+
tags: []
|
|
93
|
+
codifications:
|
|
94
|
+
- KATZ
|
|
95
|
+
options:
|
|
96
|
+
many: no
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { strictEqual } from "assert";
|
|
2
|
+
import YAML from "yaml"
|
|
3
|
+
import {
|
|
4
|
+
Form,
|
|
5
|
+
Section,
|
|
6
|
+
Group,
|
|
7
|
+
TextField,
|
|
8
|
+
NumberField,
|
|
9
|
+
DatePicker,
|
|
10
|
+
TimePicker, DateTimePicker, MultipleChoice, MeasureField
|
|
11
|
+
} from "../../src/app/components/iqr-form/model"
|
|
12
|
+
|
|
13
|
+
describe("Typescript usage suite", () => {
|
|
14
|
+
it("should Render simple form", () => {
|
|
15
|
+
const text = YAML.stringify(JSON.parse(JSON.stringify(new Form("Waiting room GP", [
|
|
16
|
+
new Section("The reason of your visit", [
|
|
17
|
+
new TextField("What symptoms, or more generally what reason motivated your visit" ),
|
|
18
|
+
new MultipleChoice("What is the level of pain that you are experiencing" )
|
|
19
|
+
]),
|
|
20
|
+
new Section("The reason of your visit", [
|
|
21
|
+
new Group("If you have measured your blood pressure. Please introduce it below", [
|
|
22
|
+
new MeasureField("Systolic blood pressure"),
|
|
23
|
+
new MeasureField( "Diastolic blood pressure")
|
|
24
|
+
])
|
|
25
|
+
]),
|
|
26
|
+
], "Fill in the patient information inside the waiting room"))))
|
|
27
|
+
console.log(text)
|
|
28
|
+
strictEqual(text, "form: Waiting room GP\n" +
|
|
29
|
+
"description: Fill in the patient information inside the waiting room\n" +
|
|
30
|
+
"sections:\n" +
|
|
31
|
+
" - section: The reason of your visit\n" +
|
|
32
|
+
" fields:\n" +
|
|
33
|
+
" - field: What symptoms, or more generally what reason motivated your visit\n" +
|
|
34
|
+
" type: textfield\n" +
|
|
35
|
+
" schema: styled-text-with-codes\n" +
|
|
36
|
+
" - field: What is the level of pain that you are experiencing\n" +
|
|
37
|
+
" type: multiple-choice\n" +
|
|
38
|
+
" - section: The reason of your visit\n" +
|
|
39
|
+
" fields:\n" +
|
|
40
|
+
" - group: If you have measured your blood pressure. Please introduce it below\n" +
|
|
41
|
+
" fields:\n" +
|
|
42
|
+
" - field: Systolic blood pressure\n" +
|
|
43
|
+
" type: measure-field\n" +
|
|
44
|
+
" - field: Diastolic blood pressure\n" +
|
|
45
|
+
" type: measure-field\n");
|
|
46
|
+
});
|
|
47
|
+
it("should Parse simple form", () => {
|
|
48
|
+
const original = "form: Waiting room GP\n" +
|
|
49
|
+
"description: Fill in the patient information inside the waiting room\n" +
|
|
50
|
+
"sections:\n" +
|
|
51
|
+
" - section: The reason of your visit\n" +
|
|
52
|
+
" fields:\n" +
|
|
53
|
+
" - field: What symptoms, or more generally what reason motivated your visit\n" +
|
|
54
|
+
" type: textfield\n" +
|
|
55
|
+
" schema: styled-text-with-codes\n" +
|
|
56
|
+
" - field: What is the level of pain that you are experiencing\n" +
|
|
57
|
+
" type: multiple-choice\n" +
|
|
58
|
+
" - section: The reason of your visit\n" +
|
|
59
|
+
" fields:\n" +
|
|
60
|
+
" - group: If you have measured your blood pressure. Please introduce it below\n" +
|
|
61
|
+
" fields:\n" +
|
|
62
|
+
" - field: Systolic blood pressure\n" +
|
|
63
|
+
" type: measure-field\n" +
|
|
64
|
+
" - field: Diastolic blood pressure\n" +
|
|
65
|
+
" type: measure-field\n"
|
|
66
|
+
const form = Form.parse(YAML.parse(original))
|
|
67
|
+
const text = YAML.stringify(JSON.parse(JSON.stringify(form)))
|
|
68
|
+
console.log(text)
|
|
69
|
+
strictEqual(text, original);
|
|
70
|
+
});
|
|
71
|
+
it("should Render complex form", () => {
|
|
72
|
+
const text = YAML.stringify(JSON.parse(JSON.stringify(new Form("Waiting room GP", [
|
|
73
|
+
new Section("All fields", [
|
|
74
|
+
new TextField("This field is a TextField", "TextField"),
|
|
75
|
+
new NumberField("This field is a NumberField", "NumberField"),
|
|
76
|
+
new MeasureField("This field is a MeasureField", "MeasureField"),
|
|
77
|
+
new DatePicker("This field is a DatePicker", "DatePicker"),
|
|
78
|
+
new TimePicker("This field is a TimePicker", "TimePicker"),
|
|
79
|
+
new DateTimePicker("This field is a DateTimePicker", "DateTimePicker"),
|
|
80
|
+
new MultipleChoice("This field is a MultipleChoice", "MultipleChoice"),
|
|
81
|
+
]),
|
|
82
|
+
new Section("Grouped fields", [
|
|
83
|
+
new Group("You can group fields together", [
|
|
84
|
+
new TextField("This field is a TextField", "TextField"),
|
|
85
|
+
new NumberField("This field is a NumberField", "NumberField"),
|
|
86
|
+
new MeasureField("This field is a MeasureField", "MeasureField"),
|
|
87
|
+
new DatePicker("This field is a DatePicker", "DatePicker"),
|
|
88
|
+
new TimePicker("This field is a TimePicker", "TimePicker"),
|
|
89
|
+
new DateTimePicker("This field is a DateTimePicker", "DateTimePicker"),
|
|
90
|
+
new MultipleChoice("This field is a MultipleChoice", "MultipleChoice"),
|
|
91
|
+
]),
|
|
92
|
+
new Group("And you can add tags and codes", [
|
|
93
|
+
new TextField("This field is a TextField", "TextField", 3, true, "text-document", ['CD-ITEM|diagnosis|1'], ['BE-THESAURUS','ICD10'], {option: "blink"}),
|
|
94
|
+
new NumberField("This field is a NumberField", "NumberField", ['CD-ITEM|parameter|1', 'CD-PARAMETER|bmi|1'], [], {option: "bang"}),
|
|
95
|
+
new MeasureField("This field is a MeasureField", "MeasureField", ['CD-ITEM|parameter|1', 'CD-PARAMETER|heartbeat|1'], [], {unit: "bpm"}),
|
|
96
|
+
new MultipleChoice("This field is a MultipleChoice", "MultipleChoice", 4, 4, [], ['KATZ'], {many:"no"}),
|
|
97
|
+
])
|
|
98
|
+
]),
|
|
99
|
+
], "Fill in the patient information inside the waiting room"))))
|
|
100
|
+
console.log(text)
|
|
101
|
+
strictEqual(text, `form: Waiting room GP
|
|
102
|
+
description: Fill in the patient information inside the waiting room
|
|
103
|
+
sections:
|
|
104
|
+
- section: All fields
|
|
105
|
+
fields:
|
|
106
|
+
- field: This field is a TextField
|
|
107
|
+
type: textfield
|
|
108
|
+
shortLabel: TextField
|
|
109
|
+
schema: styled-text-with-codes
|
|
110
|
+
- field: This field is a NumberField
|
|
111
|
+
type: number-field
|
|
112
|
+
shortLabel: NumberField
|
|
113
|
+
- field: This field is a MeasureField
|
|
114
|
+
type: measure-field
|
|
115
|
+
shortLabel: MeasureField
|
|
116
|
+
- field: This field is a DatePicker
|
|
117
|
+
type: date-picker
|
|
118
|
+
shortLabel: DatePicker
|
|
119
|
+
- field: This field is a TimePicker
|
|
120
|
+
type: time-picker
|
|
121
|
+
shortLabel: TimePicker
|
|
122
|
+
- field: This field is a DateTimePicker
|
|
123
|
+
type: date-time-picker
|
|
124
|
+
shortLabel: DateTimePicker
|
|
125
|
+
- field: This field is a MultipleChoice
|
|
126
|
+
type: multiple-choice
|
|
127
|
+
shortLabel: MultipleChoice
|
|
128
|
+
- section: Grouped fields
|
|
129
|
+
fields:
|
|
130
|
+
- group: You can group fields together
|
|
131
|
+
fields:
|
|
132
|
+
- field: This field is a TextField
|
|
133
|
+
type: textfield
|
|
134
|
+
shortLabel: TextField
|
|
135
|
+
schema: styled-text-with-codes
|
|
136
|
+
- field: This field is a NumberField
|
|
137
|
+
type: number-field
|
|
138
|
+
shortLabel: NumberField
|
|
139
|
+
- field: This field is a MeasureField
|
|
140
|
+
type: measure-field
|
|
141
|
+
shortLabel: MeasureField
|
|
142
|
+
- field: This field is a DatePicker
|
|
143
|
+
type: date-picker
|
|
144
|
+
shortLabel: DatePicker
|
|
145
|
+
- field: This field is a TimePicker
|
|
146
|
+
type: time-picker
|
|
147
|
+
shortLabel: TimePicker
|
|
148
|
+
- field: This field is a DateTimePicker
|
|
149
|
+
type: date-time-picker
|
|
150
|
+
shortLabel: DateTimePicker
|
|
151
|
+
- field: This field is a MultipleChoice
|
|
152
|
+
type: multiple-choice
|
|
153
|
+
shortLabel: MultipleChoice
|
|
154
|
+
- group: And you can add tags and codes
|
|
155
|
+
fields:
|
|
156
|
+
- field: This field is a TextField
|
|
157
|
+
type: textfield
|
|
158
|
+
shortLabel: TextField
|
|
159
|
+
rows: 3
|
|
160
|
+
grows: true
|
|
161
|
+
schema: text-document
|
|
162
|
+
tags:
|
|
163
|
+
- CD-ITEM|diagnosis|1
|
|
164
|
+
codifications:
|
|
165
|
+
- BE-THESAURUS
|
|
166
|
+
- ICD10
|
|
167
|
+
options:
|
|
168
|
+
option: blink
|
|
169
|
+
- field: This field is a NumberField
|
|
170
|
+
type: number-field
|
|
171
|
+
shortLabel: NumberField
|
|
172
|
+
tags:
|
|
173
|
+
- CD-ITEM|parameter|1
|
|
174
|
+
- CD-PARAMETER|bmi|1
|
|
175
|
+
codifications: []
|
|
176
|
+
options:
|
|
177
|
+
option: bang
|
|
178
|
+
- field: This field is a MeasureField
|
|
179
|
+
type: measure-field
|
|
180
|
+
shortLabel: MeasureField
|
|
181
|
+
tags:
|
|
182
|
+
- CD-ITEM|parameter|1
|
|
183
|
+
- CD-PARAMETER|heartbeat|1
|
|
184
|
+
codifications: []
|
|
185
|
+
options:
|
|
186
|
+
unit: bpm
|
|
187
|
+
- field: This field is a MultipleChoice
|
|
188
|
+
type: multiple-choice
|
|
189
|
+
shortLabel: MultipleChoice
|
|
190
|
+
rows: 4
|
|
191
|
+
columns: 4
|
|
192
|
+
tags: []
|
|
193
|
+
codifications:
|
|
194
|
+
- KATZ
|
|
195
|
+
options:
|
|
196
|
+
many: no
|
|
197
|
+
`);
|
|
198
|
+
});
|
|
199
|
+
it("should Parse complex form", () => {
|
|
200
|
+
const original = "form: Waiting room GP\n" +
|
|
201
|
+
"description: Fill in the patient information inside the waiting room\n" +
|
|
202
|
+
"sections:\n" +
|
|
203
|
+
" - section: All fields\n" +
|
|
204
|
+
" fields:\n" +
|
|
205
|
+
" - field: This field is a TextField\n" +
|
|
206
|
+
" type: textfield\n" +
|
|
207
|
+
" shortLabel: TextField\n" +
|
|
208
|
+
" schema: styled-text-with-codes\n" +
|
|
209
|
+
" - field: This field is a NumberField\n" +
|
|
210
|
+
" type: number-field\n" +
|
|
211
|
+
" shortLabel: NumberField\n" +
|
|
212
|
+
" - field: This field is a MeasureField\n" +
|
|
213
|
+
" type: measure-field\n" +
|
|
214
|
+
" shortLabel: MeasureField\n" +
|
|
215
|
+
" - field: This field is a DatePicker\n" +
|
|
216
|
+
" type: date-picker\n" +
|
|
217
|
+
" shortLabel: DatePicker\n" +
|
|
218
|
+
" - field: This field is a TimePicker\n" +
|
|
219
|
+
" type: time-picker\n" +
|
|
220
|
+
" shortLabel: TimePicker\n" +
|
|
221
|
+
" - field: This field is a DateTimePicker\n" +
|
|
222
|
+
" type: date-time-picker\n" +
|
|
223
|
+
" shortLabel: DateTimePicker\n" +
|
|
224
|
+
" - field: This field is a MultipleChoice\n" +
|
|
225
|
+
" type: multiple-choice\n" +
|
|
226
|
+
" shortLabel: MultipleChoice\n" +
|
|
227
|
+
" - section: Grouped fields\n" +
|
|
228
|
+
" fields:\n" +
|
|
229
|
+
" - group: You can group fields together\n" +
|
|
230
|
+
" fields:\n" +
|
|
231
|
+
" - field: This field is a TextField\n" +
|
|
232
|
+
" type: textfield\n" +
|
|
233
|
+
" shortLabel: TextField\n" +
|
|
234
|
+
" schema: styled-text-with-codes\n" +
|
|
235
|
+
" - field: This field is a NumberField\n" +
|
|
236
|
+
" type: number-field\n" +
|
|
237
|
+
" shortLabel: NumberField\n" +
|
|
238
|
+
" - field: This field is a MeasureField\n" +
|
|
239
|
+
" type: measure-field\n" +
|
|
240
|
+
" shortLabel: MeasureField\n" +
|
|
241
|
+
" - field: This field is a DatePicker\n" +
|
|
242
|
+
" type: date-picker\n" +
|
|
243
|
+
" shortLabel: DatePicker\n" +
|
|
244
|
+
" - field: This field is a TimePicker\n" +
|
|
245
|
+
" type: time-picker\n" +
|
|
246
|
+
" shortLabel: TimePicker\n" +
|
|
247
|
+
" - field: This field is a DateTimePicker\n" +
|
|
248
|
+
" type: date-time-picker\n" +
|
|
249
|
+
" shortLabel: DateTimePicker\n" +
|
|
250
|
+
" - field: This field is a MultipleChoice\n" +
|
|
251
|
+
" type: multiple-choice\n" +
|
|
252
|
+
" shortLabel: MultipleChoice\n" +
|
|
253
|
+
" - group: And you can add tags and codes\n" +
|
|
254
|
+
" fields:\n" +
|
|
255
|
+
" - field: This field is a TextField\n" +
|
|
256
|
+
" type: textfield\n" +
|
|
257
|
+
" shortLabel: TextField\n" +
|
|
258
|
+
" rows: 3\n" +
|
|
259
|
+
" grows: true\n" +
|
|
260
|
+
" schema: text-document\n" +
|
|
261
|
+
" tags:\n" +
|
|
262
|
+
" - CD-ITEM|diagnosis|1\n" +
|
|
263
|
+
" codifications:\n" +
|
|
264
|
+
" - BE-THESAURUS\n" +
|
|
265
|
+
" - ICD10\n" +
|
|
266
|
+
" options:\n" +
|
|
267
|
+
" option: blink\n" +
|
|
268
|
+
" - field: This field is a NumberField\n" +
|
|
269
|
+
" type: number-field\n" +
|
|
270
|
+
" shortLabel: NumberField\n" +
|
|
271
|
+
" tags:\n" +
|
|
272
|
+
" - CD-ITEM|parameter|1\n" +
|
|
273
|
+
" - CD-PARAMETER|bmi|1\n" +
|
|
274
|
+
" codifications: []\n" +
|
|
275
|
+
" options:\n" +
|
|
276
|
+
" option: bang\n" +
|
|
277
|
+
" - field: This field is a MeasureField\n" +
|
|
278
|
+
" type: measure-field\n" +
|
|
279
|
+
" shortLabel: MeasureField\n" +
|
|
280
|
+
" tags:\n" +
|
|
281
|
+
" - CD-ITEM|parameter|1\n" +
|
|
282
|
+
" - CD-PARAMETER|heartbeat|1\n" +
|
|
283
|
+
" codifications: []\n" +
|
|
284
|
+
" options:\n" +
|
|
285
|
+
" unit: bpm\n" +
|
|
286
|
+
" - field: This field is a MultipleChoice\n" +
|
|
287
|
+
" type: multiple-choice\n" +
|
|
288
|
+
" shortLabel: MultipleChoice\n" +
|
|
289
|
+
" rows: 4\n" +
|
|
290
|
+
" columns: 4\n" +
|
|
291
|
+
" tags: []\n" +
|
|
292
|
+
" codifications:\n" +
|
|
293
|
+
" - KATZ\n" +
|
|
294
|
+
" options:\n" +
|
|
295
|
+
" many: no\n"
|
|
296
|
+
const form = Form.parse(YAML.parse(original))
|
|
297
|
+
const text = YAML.stringify(JSON.parse(JSON.stringify(form)))
|
|
298
|
+
console.log(text)
|
|
299
|
+
strictEqual(text, original);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
2
|
+
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
3
|
+
|
|
4
|
+
module.exports = ({mode}) => {
|
|
5
|
+
return {
|
|
6
|
+
mode,
|
|
7
|
+
entry: './app/demo-app.ts',
|
|
8
|
+
plugins: [
|
|
9
|
+
new HtmlWebpackPlugin({
|
|
10
|
+
template: 'index.html'
|
|
11
|
+
}),
|
|
12
|
+
new CopyWebpackPlugin({
|
|
13
|
+
patterns: [
|
|
14
|
+
{context: 'node_modules/@webcomponents/webcomponentsjs', from: '**/*.js', to: 'webcomponents'},
|
|
15
|
+
]
|
|
16
|
+
})
|
|
17
|
+
],
|
|
18
|
+
devtool: mode === 'development' ? 'source-map' : 'none',
|
|
19
|
+
module: {
|
|
20
|
+
rules: [
|
|
21
|
+
{
|
|
22
|
+
test: /\.tsx?$/,
|
|
23
|
+
use: 'ts-loader',
|
|
24
|
+
exclude: /node_modules/,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
test: /\.css|\.s(c|a)ss$/,
|
|
28
|
+
use: [{
|
|
29
|
+
loader: 'lit-scss-loader',
|
|
30
|
+
options: {
|
|
31
|
+
minify: true, // defaults to false
|
|
32
|
+
},
|
|
33
|
+
}, 'extract-loader', 'css-loader', 'sass-loader'],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
resolve: {
|
|
38
|
+
extensions: ['.tsx', '.ts', '.js'],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
};
|