@koumoul/vjsf 2.11.1 → 2.12.0-beta.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/.eslintignore +4 -1
- package/.eslintrc.js +17 -12
- package/CONTRIBUTE.md +23 -3
- package/README.md +2 -1
- package/babel.config.js +4 -0
- package/dist/main.js +2 -1
- package/dist/main.js.LICENSE.txt +10 -0
- package/dist/third-party.js +4 -12
- package/dist/third-party.js.LICENSE.txt +8 -0
- package/lib/VJsfNoDeps.js +15 -5
- package/lib/deps/third-party.js +1 -1
- package/lib/mixins/EditableArray.js +2 -1
- package/lib/mixins/ObjectContainer.js +2 -2
- package/lib/mixins/SelectProperty.js +10 -8
- package/lib/utils/expr-eval-parser.js +21 -0
- package/lib/utils/options.js +14 -7
- package/lib/utils/select.js +31 -0
- package/package.json +29 -37
- package/test-apps/compiled/README.me +10 -0
- package/test-apps/compiled/index.html +85 -0
- package/test-apps/compiled/package-lock.json +37386 -0
- package/test-apps/compiled/package.json +7 -0
- package/webpack.config.js +6 -13
- package/.babelrc +0 -4
package/lib/VJsfNoDeps.js
CHANGED
|
@@ -16,6 +16,7 @@ import MarkdownEditor from './mixins/MarkdownEditor'
|
|
|
16
16
|
import Tooltip from './mixins/Tooltip'
|
|
17
17
|
import Validatable from './mixins/Validatable'
|
|
18
18
|
import Dependent from './mixins/Dependent'
|
|
19
|
+
import exprEvalParser from './utils/expr-eval-parser'
|
|
19
20
|
const expr = require('property-expr')
|
|
20
21
|
|
|
21
22
|
const debugExpr = require('debug')('vjsf:expr')
|
|
@@ -260,10 +261,7 @@ export default {
|
|
|
260
261
|
this.$watch(watcher, () => {
|
|
261
262
|
const fullSchema = schemaUtils.prepareFullSchema(this.resolvedSchema, this.value, this.fullOptions)
|
|
262
263
|
// kinda hackish but prevents triggering large rendering chains when nothing meaningful changes
|
|
263
|
-
if (deepEqual(fullSchema, this.fullSchema))
|
|
264
|
-
} else {
|
|
265
|
-
this.fullSchema = fullSchema
|
|
266
|
-
}
|
|
264
|
+
if (!deepEqual(fullSchema, this.fullSchema)) this.fullSchema = fullSchema
|
|
267
265
|
}, {
|
|
268
266
|
immediate: true,
|
|
269
267
|
deep: true
|
|
@@ -280,7 +278,6 @@ export default {
|
|
|
280
278
|
if (!this.fullSchema || this.fullSchema.const !== undefined || this.display === 'hidden' || (this.fullSchema.readOnly && this.fullOptions.hideReadOnly)) {
|
|
281
279
|
return
|
|
282
280
|
}
|
|
283
|
-
|
|
284
281
|
if (this.fullSchema['x-if'] && !this.getFromExpr(this.fullSchema['x-if'])) {
|
|
285
282
|
return
|
|
286
283
|
}
|
|
@@ -343,6 +340,7 @@ export default {
|
|
|
343
340
|
|
|
344
341
|
this._vjsf_getters = this._vjsf_getters || {}
|
|
345
342
|
|
|
343
|
+
// newFunction can only be defined on main options (not x-options to prevent injection)
|
|
346
344
|
if (this.initialOptions.evalMethod === 'newFunction') {
|
|
347
345
|
debugExpr(`evaluate expression "${exp}" with newFunction method`, expData)
|
|
348
346
|
// use a powerful meta-programming approach with "new Function", not safe if the schema is user-submitted
|
|
@@ -351,6 +349,12 @@ export default {
|
|
|
351
349
|
const result = this._vjsf_getters[exp](...Object.values(expData))
|
|
352
350
|
debugExpr(`result`, result)
|
|
353
351
|
return result
|
|
352
|
+
} else if (this.fullOptions.evalMethod === 'evalExpr') {
|
|
353
|
+
debugExpr(`evaluate expression "${exp}" with exprEval method`, expData)
|
|
354
|
+
// TODO: conserve compiled expression for reuse ?
|
|
355
|
+
const result = exprEvalParser.evaluate(exp, expData)
|
|
356
|
+
debugExpr(result)
|
|
357
|
+
return result
|
|
354
358
|
} else {
|
|
355
359
|
exp = this.prefixExpr(exp)
|
|
356
360
|
debugExpr(`evaluate expression "${exp}" with propertyExpr method`, expData)
|
|
@@ -475,9 +479,15 @@ export default {
|
|
|
475
479
|
return this.input(undefined)
|
|
476
480
|
}
|
|
477
481
|
let value = this.value
|
|
482
|
+
|
|
483
|
+
// create empty objects
|
|
478
484
|
if (this.fullSchema.type === 'object' && [undefined, null].includes(value) && !this.isSelectProp) {
|
|
479
485
|
value = {}
|
|
480
486
|
}
|
|
487
|
+
// in the special case of objects based on select remove empty objects
|
|
488
|
+
if (this.fullSchema.type === 'object' && this.isSelectProp && value && Object.keys(value).length === 0) {
|
|
489
|
+
value = undefined
|
|
490
|
+
}
|
|
481
491
|
|
|
482
492
|
// const always wins
|
|
483
493
|
if (this.fullSchema.const !== undefined) value = this.fullSchema.const
|
package/lib/deps/third-party.js
CHANGED
|
@@ -5,7 +5,7 @@ import Vue from 'vue'
|
|
|
5
5
|
import Draggable from 'vuedraggable'
|
|
6
6
|
const _global = (typeof window !== 'undefined' && window) || (typeof global !== 'undefined' && global) || {}
|
|
7
7
|
_global.markdownit = require('markdown-it')
|
|
8
|
-
Vue.component('
|
|
8
|
+
Vue.component('Draggable', Draggable)
|
|
9
9
|
_global.Ajv = require('ajv')
|
|
10
10
|
_global.ajvLocalize = require('ajv-i18n')
|
|
11
11
|
_global.ajvAddFormats = require('ajv-formats')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import copy from 'fast-copy'
|
|
2
|
+
import selectUtils from '../utils/select'
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
data() {
|
|
@@ -255,7 +256,7 @@ export default {
|
|
|
255
256
|
const titleClass = 'py-2 pr-2 ' + this.fullOptions.arrayItemsTitlesClasses[this.sectionDepth] || this.fullOptions.arrayItemsTitlesClasses[this.fullOptions.arrayItemsTitlesClasses.length - 1]
|
|
256
257
|
|
|
257
258
|
let cardChildren = [
|
|
258
|
-
h('v-card-title', { props: { primaryTitle: true }, class: titleClass }, [this.itemTitle
|
|
259
|
+
h('v-card-title', { props: { primaryTitle: true }, class: titleClass }, [selectUtils.getObjectTitle(item, this.itemTitle, this.fullSchema), h('v-spacer'), actions]),
|
|
259
260
|
h('v-card-text', [itemChild])
|
|
260
261
|
]
|
|
261
262
|
|
|
@@ -148,7 +148,7 @@ export default {
|
|
|
148
148
|
if (childProp.componentInstance.validate(true)) {
|
|
149
149
|
this.currentStep += 1
|
|
150
150
|
}
|
|
151
|
-
} } },
|
|
151
|
+
} } }, this.fullOptions.messages.stepperContinue)])
|
|
152
152
|
])]
|
|
153
153
|
)
|
|
154
154
|
]
|
|
@@ -312,7 +312,7 @@ export default {
|
|
|
312
312
|
this.triggerChangeCurrentOneOf = true
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
|
-
flatChildren.push(h('v-select', { props, on }, [this.renderTooltip(h, 'append-outer')]))
|
|
315
|
+
flatChildren.push(h('v-select', { props, on, style: (this.subSchemasConstProp && this.subSchemasConstProp['x-style']) || '' }, [this.renderTooltip(h, 'append-outer')]))
|
|
316
316
|
if (this.currentOneOf && this.showCurrentOneOf) {
|
|
317
317
|
flatChildren.push(this.renderChildProp(h, { ...this.currentOneOf, type: 'object', title: null }, 'currentOneOf', this.sectionDepth + 1))
|
|
318
318
|
}
|
|
@@ -20,16 +20,14 @@ export default {
|
|
|
20
20
|
if (this.fullSchema.type === 'array' && this.fullSchema.items && this.fullSchema.items.enum) return true
|
|
21
21
|
if (this.oneOfSelect) return true
|
|
22
22
|
if (this.examplesSelect) return true
|
|
23
|
-
|
|
23
|
+
// WARNING: it is important not to use this.fromUrl here
|
|
24
|
+
// because it is empty at first when fromUrlParams are not ready yet and it creates initialization problems
|
|
25
|
+
if (this.fullSchema['x-fromUrl']) return true
|
|
24
26
|
if (this.fromData) return true
|
|
25
27
|
return false
|
|
26
28
|
},
|
|
27
29
|
oneOfSelect() {
|
|
28
|
-
|
|
29
|
-
if (this.fullSchema.type === 'array' && this.fullSchema.items && ['string', 'integer', 'number'].includes(this.fullSchema.items.type) && (this.fullSchema.items.oneOf || this.fullSchema.items.anyOf)) return true
|
|
30
|
-
if (['string', 'integer', 'number'].includes(this.fullSchema.type) && this.fullSchema.oneOf && this.fullSchema.oneOf[0] && this.fullSchema.oneOf[0].const !== undefined) return true
|
|
31
|
-
if (['string', 'integer', 'number'].includes(this.fullSchema.type) && this.fullSchema.anyOf && this.fullSchema.anyOf[0] && this.fullSchema.anyOf[0].const !== undefined) return true
|
|
32
|
-
return false
|
|
30
|
+
return selectUtils.isOneOfSelect(this.fullSchema)
|
|
33
31
|
},
|
|
34
32
|
examplesSelect() {
|
|
35
33
|
if (!this.fullSchema) return
|
|
@@ -185,13 +183,17 @@ export default {
|
|
|
185
183
|
},
|
|
186
184
|
renderSelectIcon(h, item) {
|
|
187
185
|
if (!this.itemIcon) return
|
|
188
|
-
|
|
186
|
+
let itemIcon = item[this.itemIcon]
|
|
189
187
|
if (!itemIcon) return
|
|
190
|
-
let iconChild
|
|
188
|
+
let iconChild
|
|
191
189
|
if (itemIcon.startsWith('http://') || itemIcon.startsWith('https://')) {
|
|
192
190
|
iconChild = h('img', { domProps: { src: itemIcon }, style: 'height:100%;width:100%;' })
|
|
193
191
|
} else if (itemIcon.startsWith('<?xml') || itemIcon.startsWith('<svg')) {
|
|
194
192
|
iconChild = h('div', { domProps: { innerHTML: itemIcon } })
|
|
193
|
+
} else {
|
|
194
|
+
const prefix = this.fullOptions.iconfont + '-'
|
|
195
|
+
if (this.fullOptions.iconfont && !itemIcon.startsWith(prefix)) itemIcon = prefix + itemIcon
|
|
196
|
+
iconChild = h('v-icon', null, itemIcon)
|
|
195
197
|
}
|
|
196
198
|
return h('v-avatar', { props: { tile: true, size: 20 }, class: 'mr-2' }, [iconChild])
|
|
197
199
|
},
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Parser } from 'expr-eval'
|
|
2
|
+
|
|
3
|
+
export default new Parser({
|
|
4
|
+
// Useless in our use case
|
|
5
|
+
// mathematical
|
|
6
|
+
add: false,
|
|
7
|
+
concatenate: false,
|
|
8
|
+
divide: false,
|
|
9
|
+
factorial: false,
|
|
10
|
+
multiply: false,
|
|
11
|
+
power: false,
|
|
12
|
+
remainer: false,
|
|
13
|
+
substract: false,
|
|
14
|
+
// programatic
|
|
15
|
+
assignement: false,
|
|
16
|
+
|
|
17
|
+
// logical
|
|
18
|
+
logical: true,
|
|
19
|
+
comparison: true,
|
|
20
|
+
in: true
|
|
21
|
+
})
|
package/lib/utils/options.js
CHANGED
|
@@ -90,7 +90,8 @@ export const localizedMessages = {
|
|
|
90
90
|
mdeGuide: 'Documentation de la syntaxe',
|
|
91
91
|
undo: 'Undo',
|
|
92
92
|
redo: 'Redo',
|
|
93
|
-
selectAll: 'Select all'
|
|
93
|
+
selectAll: 'Select all',
|
|
94
|
+
stepperContinue: 'continue'
|
|
94
95
|
},
|
|
95
96
|
fr: {
|
|
96
97
|
required: 'Cette information est obligatoire',
|
|
@@ -124,7 +125,8 @@ export const localizedMessages = {
|
|
|
124
125
|
mdeGuide: 'Syntax documentation',
|
|
125
126
|
undo: 'Défaire',
|
|
126
127
|
redo: 'Refaire',
|
|
127
|
-
selectAll: 'Tout sélectionner'
|
|
128
|
+
selectAll: 'Tout sélectionner',
|
|
129
|
+
stepperContinue: 'continuer'
|
|
128
130
|
},
|
|
129
131
|
es: {
|
|
130
132
|
required: 'Esta información es requerida',
|
|
@@ -139,7 +141,8 @@ export const localizedMessages = {
|
|
|
139
141
|
minItems: 'Al menos {minItems} articulos',
|
|
140
142
|
maxItems: 'Hasta {maxItems} articulos',
|
|
141
143
|
pattern: 'El formato esperado no se respeta',
|
|
142
|
-
selectAll: 'Seleccionar todo'
|
|
144
|
+
selectAll: 'Seleccionar todo',
|
|
145
|
+
stepperContinue: 'continuar'
|
|
143
146
|
},
|
|
144
147
|
de: {
|
|
145
148
|
required: 'Diese Informationen sind erforderlich',
|
|
@@ -154,7 +157,8 @@ export const localizedMessages = {
|
|
|
154
157
|
minItems: 'Mindestens {minItems} Elemente',
|
|
155
158
|
maxItems: 'Bis zu {maxItems} Artikel',
|
|
156
159
|
pattern: 'Das erwartete Format wird nicht eingehalten',
|
|
157
|
-
selectAll: 'Wählen Sie Alle'
|
|
160
|
+
selectAll: 'Wählen Sie Alle',
|
|
161
|
+
stepperContinue: 'weiter'
|
|
158
162
|
},
|
|
159
163
|
ar: {
|
|
160
164
|
required: 'هذه المعلومة مطلوبة',
|
|
@@ -169,7 +173,8 @@ export const localizedMessages = {
|
|
|
169
173
|
minItems: 'قطع {minItems} لا يمكن اختيار أقل من ',
|
|
170
174
|
maxItems: 'قطع {maxItems} لا يمكن اختيار أكثر من ',
|
|
171
175
|
pattern: 'لا يوجد تشابه مع النموذج المطلوب',
|
|
172
|
-
selectAll: 'اختر الكل'
|
|
176
|
+
selectAll: 'اختر الكل',
|
|
177
|
+
stepperContinue: 'استمر'
|
|
173
178
|
},
|
|
174
179
|
tr: {
|
|
175
180
|
required: 'Zorunlu alan',
|
|
@@ -184,7 +189,8 @@ export const localizedMessages = {
|
|
|
184
189
|
minItems: 'En az seçenek sayısı {minItems}',
|
|
185
190
|
maxItems: 'En çok seçenek sayısı {maxItems}',
|
|
186
191
|
pattern: 'İstenilen paten tutmuyor',
|
|
187
|
-
selectAll: 'Hepsini seç'
|
|
192
|
+
selectAll: 'Hepsini seç',
|
|
193
|
+
stepperContinue: 'devam et'
|
|
188
194
|
},
|
|
189
195
|
nl: {
|
|
190
196
|
required: 'Deze informatie is vereist',
|
|
@@ -199,7 +205,8 @@ export const localizedMessages = {
|
|
|
199
205
|
minItems: 'Minimaal {minItems} antwoorden',
|
|
200
206
|
maxItems: 'Maximaal {maxItems} antwoorden',
|
|
201
207
|
pattern: 'Invoer voldoet niet aan verwachte patroon',
|
|
202
|
-
selectAll: 'Selecteer alles'
|
|
208
|
+
selectAll: 'Selecteer alles',
|
|
209
|
+
stepperContinue: 'doorgaan'
|
|
203
210
|
}
|
|
204
211
|
}
|
|
205
212
|
|
package/lib/utils/select.js
CHANGED
|
@@ -106,3 +106,34 @@ selectUtils.fillList = (fullSchema, value, selectItems, itemKey) => {
|
|
|
106
106
|
})
|
|
107
107
|
return value.filter(item => !!item)
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
selectUtils.isOneOfSelect = (fullSchema) => {
|
|
111
|
+
if (!fullSchema) return
|
|
112
|
+
if (fullSchema.type === 'array' && fullSchema.items && ['string', 'integer', 'number'].includes(fullSchema.items.type) && (fullSchema.items.oneOf || fullSchema.items.anyOf)) return true
|
|
113
|
+
if (['string', 'integer', 'number'].includes(fullSchema.type) && fullSchema.oneOf && fullSchema.oneOf[0] && fullSchema.oneOf[0].const !== undefined) return true
|
|
114
|
+
if (['string', 'integer', 'number'].includes(fullSchema.type) && fullSchema.anyOf && fullSchema.anyOf[0] && fullSchema.anyOf[0].const !== undefined) return true
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// get an object title if x-itemTitles is defined, handle direct values or values matched to a label through a oneOf/anyof
|
|
119
|
+
selectUtils.getObjectTitle = (item, itemTitle, fullSchema) => {
|
|
120
|
+
if (!itemTitle) return null
|
|
121
|
+
const titlePropertySchema = fullSchema.items && fullSchema.items.properties && fullSchema.items.properties[itemTitle]
|
|
122
|
+
if (titlePropertySchema) {
|
|
123
|
+
const oneOfSelect = selectUtils.isOneOfSelect(titlePropertySchema)
|
|
124
|
+
if (oneOfSelect) {
|
|
125
|
+
const of = titlePropertySchema.anyOf || titlePropertySchema.oneOf
|
|
126
|
+
const ofItem = of.find(ofItem => ofItem.const === item[itemTitle] || (ofItem.enum && ofItem.enum[0] === item[itemTitle]))
|
|
127
|
+
if (ofItem) return ofItem.title
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (fullSchema.items && (fullSchema.items.oneOf || fullSchema.items.anyOf)) {
|
|
132
|
+
const of = fullSchema.items.oneOf || fullSchema.items.anyOf
|
|
133
|
+
const props = of[0].properties
|
|
134
|
+
const key = Object.keys(props).find(p => !!props[p].const)
|
|
135
|
+
const ofItem = of.find(ofItem => ofItem.properties[key].const === item[itemTitle])
|
|
136
|
+
if (ofItem) return ofItem.title
|
|
137
|
+
}
|
|
138
|
+
return item[itemTitle]
|
|
139
|
+
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koumoul/vjsf",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0-beta.0",
|
|
4
4
|
"description": "Generate forms for the vuetify UI library (vuejs) based on annotated JSON schemas.",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"lint": "eslint --ext js
|
|
8
|
-
"lint-fix": "eslint --fix --ext js
|
|
7
|
+
"lint": "eslint --ext js .",
|
|
8
|
+
"lint-fix": "eslint --fix --ext js .",
|
|
9
9
|
"build": "rm -rf dist && webpack && cp lib/VJsf.css dist/main.css",
|
|
10
10
|
"prepare": "npm run lint && npm test && npm run build && npm run doc-build",
|
|
11
11
|
"postpublish": "gh-pages-multi deploy -v -s doc/dist -t latest",
|
|
12
12
|
"test": "jest",
|
|
13
|
+
"test-watch": "jest --watch",
|
|
13
14
|
"test-update": "jest --updateSnapshot",
|
|
14
|
-
"
|
|
15
|
-
"doc-
|
|
16
|
-
"
|
|
17
|
-
"doc-build": "BASE=/vuetify-jsonschema-form/latest/ nuxt generate doc",
|
|
18
|
-
"doc-master": "BASE=/vuetify-jsonschema-form/master/ nuxt generate doc && gh-pages-multi deploy -v -s doc/dist -t master"
|
|
15
|
+
"doc-build": "(cd doc && BASE=/vuetify-jsonschema-form/latest/ nuxt generate)",
|
|
16
|
+
"doc-master": "(cd doc && BASE=/vuetify-jsonschema-form/master/ nuxt generate) && gh-pages-multi deploy -v -s doc/dist -t maste",
|
|
17
|
+
"analyze": "webpack --profile --json > dist/stats.json && webpack-bundle-analyzer dist/stats.json"
|
|
19
18
|
},
|
|
20
19
|
"jest": {
|
|
21
20
|
"moduleFileExtensions": [
|
|
@@ -33,7 +32,8 @@
|
|
|
33
32
|
],
|
|
34
33
|
"snapshotSerializers": [
|
|
35
34
|
"jest-serializer-vue"
|
|
36
|
-
]
|
|
35
|
+
],
|
|
36
|
+
"testEnvironment": "jsdom"
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
@@ -46,36 +46,36 @@
|
|
|
46
46
|
},
|
|
47
47
|
"homepage": "https://github.com/koumoul-dev/vuetify-jsonschema-form#readme",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@mdi/js": "^6.5.95",
|
|
50
|
-
"ajv": "^8.9.0",
|
|
51
|
-
"ajv-formats": "^2.1.1",
|
|
52
|
-
"ajv-i18n": "^4.2.0",
|
|
53
49
|
"debounce": "^1.2.1",
|
|
54
50
|
"debug": "^4.3.3",
|
|
55
51
|
"fast-copy": "^2.1.1",
|
|
56
52
|
"fast-equals": "^2.0.4",
|
|
53
|
+
"match-all": "^1.2.6"
|
|
54
|
+
},
|
|
55
|
+
"optionalDependencies": {
|
|
56
|
+
"@mdi/font": "^6.5.95",
|
|
57
|
+
"@mdi/js": "^6.5.95",
|
|
58
|
+
"ajv": "^8.11.0",
|
|
59
|
+
"ajv-formats": "^2.1.1",
|
|
60
|
+
"ajv-i18n": "^4.2.0",
|
|
61
|
+
"expr-eval": "^2.0.2",
|
|
57
62
|
"markdown-it": "^12.3.2",
|
|
58
|
-
"match-all": "^1.2.6",
|
|
59
|
-
"object-hash": "^2.2.0",
|
|
60
63
|
"property-expr": "^2.0.5",
|
|
61
64
|
"vuedraggable": "^2.24.3"
|
|
62
65
|
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"vuetify": "^2.0.0"
|
|
68
|
+
},
|
|
63
69
|
"devDependencies": {
|
|
64
70
|
"@babel/core": "^7.16.12",
|
|
71
|
+
"@babel/plugin-transform-runtime": "^7.17.0",
|
|
65
72
|
"@babel/preset-env": "^7.16.11",
|
|
66
73
|
"@koumoul/data-fair-search-widget": "^0.3.0",
|
|
67
74
|
"@koumoul/gh-pages-multi": "^0.6.0",
|
|
68
|
-
"@mdi/font": "^6.5.95",
|
|
69
|
-
"@nuxtjs/axios": "^5.13.6",
|
|
70
|
-
"@nuxtjs/vuetify": "^1.12.3",
|
|
71
|
-
"@toast-ui/vue-editor": "^2.5.1",
|
|
72
75
|
"@vue/test-utils": "^1.3.0",
|
|
73
|
-
"axios": "^0.25.0",
|
|
74
|
-
"babel-core": "^7.0.0-bridge.0",
|
|
75
76
|
"babel-eslint": "^10.1.0",
|
|
76
|
-
"babel-
|
|
77
|
-
"
|
|
78
|
-
"easymde": "^2.16.1",
|
|
77
|
+
"babel-jest": "^27.5.1",
|
|
78
|
+
"babel-loader": "^8.2.4",
|
|
79
79
|
"eslint": "^6.1.0",
|
|
80
80
|
"eslint-config-standard": "^13.0.1",
|
|
81
81
|
"eslint-plugin-import": "^2.18.2",
|
|
@@ -84,22 +84,14 @@
|
|
|
84
84
|
"eslint-plugin-promise": "^4.2.1",
|
|
85
85
|
"eslint-plugin-standard": "^4.0.0",
|
|
86
86
|
"eslint-plugin-vue": "^7.20.0",
|
|
87
|
-
"
|
|
88
|
-
"jest": "^26.1.0",
|
|
87
|
+
"jest": "^27.5.1",
|
|
89
88
|
"jest-serializer-vue": "^2.0.2",
|
|
90
|
-
"mini-css-extract-plugin": "^1.6.2",
|
|
91
|
-
"nuxt": "^2.15.8",
|
|
92
|
-
"random-words": "^1.1.0",
|
|
93
|
-
"sanitize-html": "^2.6.1",
|
|
94
|
-
"stringify-object": "^3.3.0",
|
|
95
|
-
"tiptap-vuetify": "^2.24.0",
|
|
96
89
|
"v-mask": "^2.3.0",
|
|
97
90
|
"vue-axios": "^2.1.5",
|
|
98
|
-
"vue-cropperjs": "^4.2.0",
|
|
99
91
|
"vue-jest": "^3.0.7",
|
|
100
|
-
"vue-
|
|
101
|
-
"
|
|
102
|
-
"webpack-
|
|
103
|
-
"
|
|
92
|
+
"vue-loader": "^15.9.8",
|
|
93
|
+
"webpack": "^5.72.0",
|
|
94
|
+
"webpack-bundle-analyzer": "^4.5.0",
|
|
95
|
+
"webpack-cli": "^4.9.2"
|
|
104
96
|
}
|
|
105
97
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>VJSF - test apps - compiled</title>
|
|
4
|
+
|
|
5
|
+
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
|
|
6
|
+
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
|
|
7
|
+
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
|
|
8
|
+
<link href="/dist/main.css" rel="stylesheet">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="app">
|
|
12
|
+
<v-app>
|
|
13
|
+
<v-main>
|
|
14
|
+
<v-container>
|
|
15
|
+
<h1>VJSF - Test app - Compiled</h1>
|
|
16
|
+
|
|
17
|
+
<h2>Very basic form</h2>
|
|
18
|
+
<v-form v-model="form1.valid">
|
|
19
|
+
<v-jsf :schema="form1.schema" :options="form1.options" v-model="form1.model"></v-jsf>
|
|
20
|
+
</v-form>
|
|
21
|
+
valid={{form1.valid}}, model={{form1.model}}
|
|
22
|
+
|
|
23
|
+
<h2>Form with draggable array elements</h2>
|
|
24
|
+
<v-form v-model="form2.valid">
|
|
25
|
+
<v-jsf :schema="form2.schema" :options="form2.options" v-model="form2.model"></v-jsf>
|
|
26
|
+
</v-form>
|
|
27
|
+
valid={{form2.valid}}, model={{form2.model}}
|
|
28
|
+
</v-container>
|
|
29
|
+
|
|
30
|
+
</v-main>
|
|
31
|
+
</v-app>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
|
|
35
|
+
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
|
|
36
|
+
<script src="/dist/main.js"></script>
|
|
37
|
+
<script src="/dist/third-party.js"></script>
|
|
38
|
+
<script>
|
|
39
|
+
Vue.component('VJsf', VJsf.default)
|
|
40
|
+
new Vue({
|
|
41
|
+
el: '#app',
|
|
42
|
+
vuetify: new Vuetify(),
|
|
43
|
+
data() {
|
|
44
|
+
return {
|
|
45
|
+
form1: {
|
|
46
|
+
valid: null,
|
|
47
|
+
schema: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
stringProp: { type: 'string', title: `I'm a string`, description: 'This description is used as a help message.' }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
options: {},
|
|
54
|
+
model: {}
|
|
55
|
+
},
|
|
56
|
+
form2: {
|
|
57
|
+
valid: null,
|
|
58
|
+
schema: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
properties: {
|
|
61
|
+
arrayProp: {
|
|
62
|
+
type: 'array',
|
|
63
|
+
items: {
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: {
|
|
66
|
+
stringProp: { type: 'string', title: `I'm a string` }
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
options: {},
|
|
73
|
+
model: {
|
|
74
|
+
arrayProp: [
|
|
75
|
+
{stringProp: 'value 1'},
|
|
76
|
+
{stringProp: 'value 2'}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
</script>
|
|
84
|
+
</body>
|
|
85
|
+
</html>
|