expressa 2.1.0 → 2.1.2

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 (190) hide show
  1. package/.circleci/config.yml +21 -21
  2. package/.eslintrc.json +29 -29
  3. package/LICENSE +21 -21
  4. package/README.md +137 -137
  5. package/auth/jwt.js +31 -31
  6. package/controllers/collections.js +299 -260
  7. package/controllers/install.js +105 -105
  8. package/controllers/status.js +43 -43
  9. package/controllers/users.js +52 -52
  10. package/cypress/fixtures/example.json +4 -4
  11. package/cypress/integration/0_install_spec.js +8 -8
  12. package/cypress/integration/custom_collections.js +30 -30
  13. package/cypress/integration/home.js +9 -9
  14. package/cypress/integration/settings.js +34 -34
  15. package/cypress/integration/users.js +61 -61
  16. package/cypress/plugins/index.js +17 -17
  17. package/cypress/support/commands.js +69 -69
  18. package/cypress/support/index.js +20 -20
  19. package/cypress/support/util.js +10 -10
  20. package/cypress.config.js +18 -18
  21. package/cypress.json +4 -4
  22. package/db/cached.js +44 -44
  23. package/db/file.js +131 -131
  24. package/db/memory.js +92 -92
  25. package/db/mongo.js +93 -93
  26. package/db/postgres.js +100 -100
  27. package/doc/authentication.md +38 -38
  28. package/doc/automatic-fields.md +12 -12
  29. package/doc/blogexample.md +16 -16
  30. package/doc/custom-endpoints.md +20 -20
  31. package/doc/database.md +23 -23
  32. package/doc/development.md +33 -33
  33. package/doc/listeners.md +103 -103
  34. package/doc/modules.md +8 -8
  35. package/doc/permissions.md +14 -14
  36. package/doc/relationships.md +65 -65
  37. package/doc/testing.md +47 -47
  38. package/doc/uploading-files.md +53 -53
  39. package/listeners.js +65 -65
  40. package/listeners_collection_permissions.js +29 -29
  41. package/listeners_users.js +96 -96
  42. package/listeners_validation.js +43 -43
  43. package/middleware/logging.js +30 -30
  44. package/middleware/permissions.js +41 -41
  45. package/modules/access_keys/access_keys.js +32 -32
  46. package/modules/admin/.babelrc +8 -8
  47. package/modules/admin/.editorconfig +14 -14
  48. package/modules/admin/.eslintignore +5 -5
  49. package/modules/admin/.eslintrc.js +197 -197
  50. package/modules/admin/.postcssrc.js +10 -10
  51. package/modules/admin/.travis.yml +5 -5
  52. package/modules/admin/LICENSE +21 -21
  53. package/modules/admin/README.md +88 -88
  54. package/modules/admin/build/build.js +46 -46
  55. package/modules/admin/build/check-versions.js +64 -64
  56. package/modules/admin/build/utils.js +109 -109
  57. package/modules/admin/build/vue-loader.conf.js +5 -5
  58. package/modules/admin/build/webpack.base.conf.js +112 -112
  59. package/modules/admin/build/webpack.dev.conf.js +95 -95
  60. package/modules/admin/build/webpack.prod.conf.js +112 -112
  61. package/modules/admin/config/dev.env.js +8 -8
  62. package/modules/admin/config/index.js +86 -86
  63. package/modules/admin/config/prod.env.js +5 -5
  64. package/modules/admin/dist/css/430.8c9b0482.css +8 -0
  65. package/modules/admin/dist/css/430.8c9b0482.css.gz +0 -0
  66. package/modules/admin/dist/css/566.7a90435e.css +7 -0
  67. package/modules/admin/dist/css/566.7a90435e.css.gz +0 -0
  68. package/modules/admin/dist/css/569.db9a10c2.css +213 -0
  69. package/modules/admin/dist/css/569.db9a10c2.css.gz +0 -0
  70. package/modules/admin/dist/css/572.513a323e.css +210 -0
  71. package/modules/admin/dist/css/572.513a323e.css.gz +0 -0
  72. package/modules/admin/dist/css/622.7a90435e.css +7 -0
  73. package/modules/admin/dist/css/622.7a90435e.css.gz +0 -0
  74. package/modules/admin/dist/css/651.e946bda7.css +6 -0
  75. package/modules/admin/dist/css/651.e946bda7.css.gz +0 -0
  76. package/modules/admin/dist/css/750.79723422.css +2 -0
  77. package/modules/admin/dist/css/750.79723422.css.gz +0 -0
  78. package/modules/admin/dist/css/798.c6646d20.css +1 -0
  79. package/modules/admin/dist/css/798.c6646d20.css.gz +0 -0
  80. package/modules/admin/dist/css/950.1fd9d57c.css +7 -0
  81. package/modules/admin/dist/css/950.1fd9d57c.css.gz +0 -0
  82. package/modules/admin/dist/css/app.c25a6c6c.css +592 -0
  83. package/modules/admin/dist/css/app.c25a6c6c.css.gz +0 -0
  84. package/modules/admin/dist/favicon.ico +0 -0
  85. package/modules/admin/dist/index.html +1 -0
  86. package/modules/admin/dist/static/fonts/element-icons.313f7da.woff +0 -0
  87. package/modules/admin/dist/static/fonts/element-icons.4520188.ttf +0 -0
  88. package/modules/admin/dist/static/img/404.4cf6930.png +0 -0
  89. package/modules/admin/dist/static/js/311.03ef5ed9.js +1 -0
  90. package/modules/admin/dist/static/js/311.03ef5ed9.js.gz +0 -0
  91. package/modules/admin/dist/static/js/430.ddfa4b9e.js +1 -0
  92. package/modules/admin/dist/static/js/430.ddfa4b9e.js.gz +0 -0
  93. package/modules/admin/dist/static/js/460.770a630c.js +1 -0
  94. package/modules/admin/dist/static/js/460.770a630c.js.gz +0 -0
  95. package/modules/admin/dist/static/js/550.e9a3a306.js +1 -0
  96. package/modules/admin/dist/static/js/550.e9a3a306.js.gz +0 -0
  97. package/modules/admin/dist/static/js/569.711f16a3.js +1 -0
  98. package/modules/admin/dist/static/js/569.711f16a3.js.gz +0 -0
  99. package/modules/admin/dist/static/js/572.5c8cfea9.js +1 -0
  100. package/modules/admin/dist/static/js/572.5c8cfea9.js.gz +0 -0
  101. package/modules/admin/dist/static/js/603.bbe5ed23.js +1 -0
  102. package/modules/admin/dist/static/js/603.bbe5ed23.js.gz +0 -0
  103. package/modules/admin/dist/static/js/622.9f06567e.js +1 -0
  104. package/modules/admin/dist/static/js/622.9f06567e.js.gz +0 -0
  105. package/modules/admin/dist/static/js/651.86d741f0.js +1 -0
  106. package/modules/admin/dist/static/js/651.86d741f0.js.gz +0 -0
  107. package/modules/admin/dist/static/js/653.7a309059.js +1 -0
  108. package/modules/admin/dist/static/js/653.7a309059.js.gz +0 -0
  109. package/modules/admin/dist/static/js/750.10551ec8.js +1 -0
  110. package/modules/admin/dist/static/js/750.10551ec8.js.gz +0 -0
  111. package/modules/admin/dist/static/js/798.93ec90bc.js +1 -0
  112. package/modules/admin/dist/static/js/798.93ec90bc.js.gz +0 -0
  113. package/modules/admin/dist/static/js/950.d7f72b66.js +1 -0
  114. package/modules/admin/dist/static/js/950.d7f72b66.js.gz +0 -0
  115. package/modules/admin/dist/static/js/app.23870b61.js +2 -0
  116. package/modules/admin/dist/static/js/app.23870b61.js.LICENSE.txt +121 -0
  117. package/modules/admin/dist/static/js/app.23870b61.js.LICENSE.txt.gz +0 -0
  118. package/modules/admin/dist/static/js/app.23870b61.js.gz +0 -0
  119. package/modules/admin/index.html +16 -16
  120. package/modules/admin/package.json +101 -101
  121. package/modules/admin/src/App.vue +11 -11
  122. package/modules/admin/src/api/login.js +26 -26
  123. package/modules/admin/src/api/table.js +9 -9
  124. package/modules/admin/src/components/Breadcrumb/index.vue +79 -79
  125. package/modules/admin/src/components/Hamburger/index.vue +62 -62
  126. package/modules/admin/src/components/JSONEditor.vue +206 -206
  127. package/modules/admin/src/components/SvgIcon/index.vue +43 -43
  128. package/modules/admin/src/icons/index.js +9 -9
  129. package/modules/admin/src/icons/svgo.yml +22 -22
  130. package/modules/admin/src/main.js +42 -42
  131. package/modules/admin/src/permission.js +49 -49
  132. package/modules/admin/src/router/index.js +200 -200
  133. package/modules/admin/src/store/getters.js +11 -11
  134. package/modules/admin/src/store/index.js +17 -17
  135. package/modules/admin/src/store/modules/app.js +43 -43
  136. package/modules/admin/src/store/modules/user.js +104 -104
  137. package/modules/admin/src/styles/element-ui.scss +29 -29
  138. package/modules/admin/src/styles/index.scss +78 -78
  139. package/modules/admin/src/styles/mixin.scss +27 -27
  140. package/modules/admin/src/styles/sidebar.scss +133 -133
  141. package/modules/admin/src/styles/transition.scss +46 -46
  142. package/modules/admin/src/styles/variables.scss +4 -4
  143. package/modules/admin/src/utils/auth.js +15 -15
  144. package/modules/admin/src/utils/index.js +74 -74
  145. package/modules/admin/src/utils/request.js +47 -47
  146. package/modules/admin/src/utils/validate.js +31 -31
  147. package/modules/admin/src/views/404.vue +235 -235
  148. package/modules/admin/src/views/Dev.vue +33 -33
  149. package/modules/admin/src/views/EditDocument.vue +121 -121
  150. package/modules/admin/src/views/Endpoints.vue +279 -279
  151. package/modules/admin/src/views/Home.vue +84 -84
  152. package/modules/admin/src/views/Install.vue +79 -79
  153. package/modules/admin/src/views/ListDocuments.vue +72 -72
  154. package/modules/admin/src/views/ListDocuments2.vue +467 -467
  155. package/modules/admin/src/views/ManageListeners.vue +67 -67
  156. package/modules/admin/src/views/ManageMiddleware.vue +43 -43
  157. package/modules/admin/src/views/ManagePermissions.vue +75 -75
  158. package/modules/admin/src/views/ViewRequest.vue +77 -77
  159. package/modules/admin/src/views/form/index.vue +91 -91
  160. package/modules/admin/src/views/layout/Layout.vue +69 -69
  161. package/modules/admin/src/views/layout/components/AppMain.vue +41 -41
  162. package/modules/admin/src/views/layout/components/Navbar.vue +97 -97
  163. package/modules/admin/src/views/layout/components/Sidebar/Item.vue +29 -29
  164. package/modules/admin/src/views/layout/components/Sidebar/Link.vue +39 -39
  165. package/modules/admin/src/views/layout/components/Sidebar/SidebarItem.vue +103 -103
  166. package/modules/admin/src/views/layout/components/Sidebar/index.vue +62 -62
  167. package/modules/admin/src/views/layout/components/index.js +3 -3
  168. package/modules/admin/src/views/layout/mixin/ResizeHandler.js +41 -41
  169. package/modules/admin/src/views/login/index.vue +195 -195
  170. package/modules/admin/src/views/tree/index.vue +77 -77
  171. package/modules/collections/collections.js +45 -39
  172. package/modules/core/core.js +197 -197
  173. package/modules/logging/logging.js +88 -88
  174. package/modules/permissions/permissions.js +106 -106
  175. package/package.json +59 -59
  176. package/scripts/expressa +12 -12
  177. package/scripts/run_cypress_tests.sh +35 -35
  178. package/scripts/run_db_tests.sh +8 -8
  179. package/test/0-install.js +96 -96
  180. package/test/collections.js +431 -431
  181. package/test/collections.querying.js +372 -288
  182. package/test/db.js +258 -258
  183. package/test/db.strings.js +73 -73
  184. package/test/db.updating.js +186 -186
  185. package/test/logging.js +29 -29
  186. package/test/test.js +93 -93
  187. package/test/testserver.js +30 -30
  188. package/test/testutils.js +136 -136
  189. package/test/users.js +425 -425
  190. package/util.js +522 -522
@@ -1,62 +1,62 @@
1
- <template>
2
- <div>
3
- <svg
4
- :class="{'is-active':isActive}"
5
- t="1492500959545"
6
- class="hamburger"
7
- style=""
8
- viewBox="0 0 1024 1024"
9
- version="1.1"
10
- xmlns="http://www.w3.org/2000/svg"
11
- p-id="1691"
12
- xmlns:xlink="http://www.w3.org/1999/xlink"
13
- width="64"
14
- height="64"
15
- @click="toggleClick"
16
- >
17
- <path
18
- d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
19
- p-id="1692"
20
- />
21
- <path
22
- d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
23
- p-id="1693"
24
- />
25
- <path
26
- d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
27
- p-id="1694"
28
- />
29
- </svg>
30
- </div>
31
- </template>
32
-
33
- <script>
34
- export default {
35
- name: 'Hamburger',
36
- props: {
37
- isActive: {
38
- type: Boolean,
39
- default: false
40
- },
41
- toggleClick: {
42
- type: Function,
43
- default: null
44
- }
45
- }
46
- }
47
- </script>
48
-
49
- <style scoped>
50
- .hamburger {
51
- display: inline-block;
52
- cursor: pointer;
53
- width: 20px;
54
- height: 20px;
55
- transform: rotate(90deg);
56
- transition: .38s;
57
- transform-origin: 50% 50%;
58
- }
59
- .hamburger.is-active {
60
- transform: rotate(0deg);
61
- }
62
- </style>
1
+ <template>
2
+ <div>
3
+ <svg
4
+ :class="{'is-active':isActive}"
5
+ t="1492500959545"
6
+ class="hamburger"
7
+ style=""
8
+ viewBox="0 0 1024 1024"
9
+ version="1.1"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ p-id="1691"
12
+ xmlns:xlink="http://www.w3.org/1999/xlink"
13
+ width="64"
14
+ height="64"
15
+ @click="toggleClick"
16
+ >
17
+ <path
18
+ d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
19
+ p-id="1692"
20
+ />
21
+ <path
22
+ d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
23
+ p-id="1693"
24
+ />
25
+ <path
26
+ d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
27
+ p-id="1694"
28
+ />
29
+ </svg>
30
+ </div>
31
+ </template>
32
+
33
+ <script>
34
+ export default {
35
+ name: 'Hamburger',
36
+ props: {
37
+ isActive: {
38
+ type: Boolean,
39
+ default: false
40
+ },
41
+ toggleClick: {
42
+ type: Function,
43
+ default: null
44
+ }
45
+ }
46
+ }
47
+ </script>
48
+
49
+ <style scoped>
50
+ .hamburger {
51
+ display: inline-block;
52
+ cursor: pointer;
53
+ width: 20px;
54
+ height: 20px;
55
+ transform: rotate(90deg);
56
+ transition: .38s;
57
+ transform-origin: 50% 50%;
58
+ }
59
+ .hamburger.is-active {
60
+ transform: rotate(0deg);
61
+ }
62
+ </style>
@@ -1,206 +1,206 @@
1
- <template>
2
- <div>
3
- <div class="jsoneditor-vue" />
4
- </div>
5
- </template>
6
-
7
- <script>
8
- const { JSONEditor } = require('@json-editor/json-editor/dist/jsoneditor')
9
- import 'json-schema-editor'
10
- export default {
11
- props: {
12
- value: {
13
- type: Object,
14
- default: () => {}
15
- },
16
- schema: {
17
- type: Object,
18
- default: () => {}
19
- }
20
- },
21
- data() {
22
- return {
23
- editor: null,
24
- error: false,
25
- json: this.value,
26
- internalChange: false
27
- }
28
- },
29
- watch: {
30
- /* value: {
31
- handler: 'update'
32
- } */
33
- },
34
- mounted() {
35
- this.update()
36
- },
37
- methods: {
38
- update() {
39
- var options = {
40
- schema: this.schema,
41
- startval: this.value,
42
- theme: 'bootstrap4',
43
- iconlib: 'materialicons',
44
- required_by_default: true,
45
- }
46
- if (this.editor) {
47
- this.editor.destroy()
48
- }
49
- this.editor = new JSONEditor(this.$el.querySelector('.jsoneditor-vue'), options)
50
- let first = true
51
- this.editor.on('change', () => {
52
- if (first) {
53
- first = false
54
- return
55
- }
56
- this.$emit('input', this.editor.getValue())
57
- })
58
- },
59
- onSave() {
60
- this.$emit('json-save', this.json)
61
- }
62
- }
63
- }
64
-
65
- if (JSONEditor) {
66
- JSONEditor.defaults.resolvers.unshift(function(schema) {
67
- if (schema.type === 'object' && schema.format === 'schema') {
68
- return 'schema'
69
- }
70
-
71
- // If no valid editor is returned, the next resolver function will be used
72
- })
73
-
74
- JSONEditor.defaults.editors.schema = class schema extends JSONEditor.AbstractEditor {
75
- setValue(value, initial) {
76
- this.value = value
77
- this.schemaeditor.setValue(value)
78
- this.onChange()
79
- }
80
-
81
- getValue() {
82
- if (typeof this.schemaeditor !== 'undefined') { return this.schemaeditor.getValue() } else { return {} }
83
- }
84
-
85
- register() {
86
- super.register()
87
- if (!this.input) return
88
- this.input.setAttribute('name', this.formname)
89
- }
90
- unregister() {
91
- super.unregister()
92
- if (!this.input) return
93
- this.input.removeAttribute('name')
94
- }
95
- getNumColumns() {
96
- return 12
97
- }
98
- build() {
99
- var self = this
100
- if (!this.options.compact) {
101
- this.label = this.header = this.theme.getFormInputLabel(this.getTitle())
102
- }
103
- if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description)
104
- if (this.options.compact) this.container.className += ' compact'
105
-
106
- this.input = document.createElement('div')
107
- this.control = this.theme.getFormControl(this.label, this.input, this.description)
108
-
109
- if (this.schema.readOnly || this.schema.readonly) {
110
- this.always_disabled = true
111
- this.input.disabled = true
112
- }
113
-
114
- this.container.appendChild(this.control)
115
-
116
- this.schemaeditor = new window.JSONSchemaEditor(this.input, {
117
- startval: {}
118
- })
119
- this.schemaeditor.on('change', function() {
120
- self.onChange(true)
121
- })
122
- }
123
- enable() {
124
- if (!this.always_disabled) {
125
- this.input.disabled = false
126
- }
127
-
128
- super.enable()
129
- }
130
- disable() {
131
- this.input.disabled = true
132
- super.disable()
133
- }
134
- destroy() {
135
- if (this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label)
136
- if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description)
137
- if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input)
138
- super.destroy()
139
- }
140
- }
141
- }
142
-
143
- </script>
144
-
145
- <style>
146
- /* Override JSONEditor's textarea styles to make it expandable */
147
- /* Use high specificity to override inline styles */
148
- .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id] {
149
- resize: both !important;
150
- min-height: 250px !important;
151
- min-width: 250px !important;
152
- /* Add padding to create a larger hit area for the resize handle */
153
- padding-right: 20px !important;
154
- padding-bottom: 20px !important;
155
- }
156
-
157
- /* Make the resize handle easier to grab with larger hit area and clear visibility */
158
- .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id]::-webkit-resizer {
159
- width: 20px !important;
160
- height: 20px !important;
161
- /* Position it in the corner of the larger hit area */
162
- margin-right: -20px !important;
163
- margin-bottom: -20px !important;
164
- /* Use border to create visible resize handle */
165
- border-right: 2px solid #999 !important;
166
- border-bottom: 2px solid #999 !important;
167
- background: transparent !important;
168
- }
169
-
170
- /* Alternative approach - add a visible corner indicator using ::after pseudo-element */
171
- .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id] {
172
- position: relative !important;
173
- }
174
-
175
- .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id]::after {
176
- content: "⋰⋰⋰" !important;
177
- position: absolute !important;
178
- bottom: 2px !important;
179
- right: 2px !important;
180
- font-size: 8px !important;
181
- line-height: 6px !important;
182
- color: #999 !important;
183
- pointer-events: none !important;
184
- transform: rotate(45deg) !important;
185
- }
186
- .jsoneditor-vue img {
187
- border: 1px solid #ddd;
188
- border-radius: 4px;
189
- padding: 5px;
190
- width: 150px;
191
- }
192
- .jsoneditor-vue img:hover {
193
- box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);
194
- }
195
- .jsoneditor-vue button.btn {
196
- font-size: 14px !important;
197
- padding: 3px;
198
- }
199
- .jsoneditor-vue .form-control-label, label {
200
- font-weight: bold;
201
- }
202
- .jsoneditor-vue input[type="checkbox"] {
203
- margin-right: 5px;
204
- margin-top: 3px;
205
- }
206
- </style>
1
+ <template>
2
+ <div>
3
+ <div class="jsoneditor-vue" />
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ const { JSONEditor } = require('@json-editor/json-editor/dist/jsoneditor')
9
+ import 'json-schema-editor'
10
+ export default {
11
+ props: {
12
+ value: {
13
+ type: Object,
14
+ default: () => {}
15
+ },
16
+ schema: {
17
+ type: Object,
18
+ default: () => {}
19
+ }
20
+ },
21
+ data() {
22
+ return {
23
+ editor: null,
24
+ error: false,
25
+ json: this.value,
26
+ internalChange: false
27
+ }
28
+ },
29
+ watch: {
30
+ /* value: {
31
+ handler: 'update'
32
+ } */
33
+ },
34
+ mounted() {
35
+ this.update()
36
+ },
37
+ methods: {
38
+ update() {
39
+ var options = {
40
+ schema: this.schema,
41
+ startval: this.value,
42
+ theme: 'bootstrap4',
43
+ iconlib: 'materialicons',
44
+ required_by_default: true,
45
+ }
46
+ if (this.editor) {
47
+ this.editor.destroy()
48
+ }
49
+ this.editor = new JSONEditor(this.$el.querySelector('.jsoneditor-vue'), options)
50
+ let first = true
51
+ this.editor.on('change', () => {
52
+ if (first) {
53
+ first = false
54
+ return
55
+ }
56
+ this.$emit('input', this.editor.getValue())
57
+ })
58
+ },
59
+ onSave() {
60
+ this.$emit('json-save', this.json)
61
+ }
62
+ }
63
+ }
64
+
65
+ if (JSONEditor) {
66
+ JSONEditor.defaults.resolvers.unshift(function(schema) {
67
+ if (schema.type === 'object' && schema.format === 'schema') {
68
+ return 'schema'
69
+ }
70
+
71
+ // If no valid editor is returned, the next resolver function will be used
72
+ })
73
+
74
+ JSONEditor.defaults.editors.schema = class schema extends JSONEditor.AbstractEditor {
75
+ setValue(value, initial) {
76
+ this.value = value
77
+ this.schemaeditor.setValue(value)
78
+ this.onChange()
79
+ }
80
+
81
+ getValue() {
82
+ if (typeof this.schemaeditor !== 'undefined') { return this.schemaeditor.getValue() } else { return {} }
83
+ }
84
+
85
+ register() {
86
+ super.register()
87
+ if (!this.input) return
88
+ this.input.setAttribute('name', this.formname)
89
+ }
90
+ unregister() {
91
+ super.unregister()
92
+ if (!this.input) return
93
+ this.input.removeAttribute('name')
94
+ }
95
+ getNumColumns() {
96
+ return 12
97
+ }
98
+ build() {
99
+ var self = this
100
+ if (!this.options.compact) {
101
+ this.label = this.header = this.theme.getFormInputLabel(this.getTitle())
102
+ }
103
+ if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description)
104
+ if (this.options.compact) this.container.className += ' compact'
105
+
106
+ this.input = document.createElement('div')
107
+ this.control = this.theme.getFormControl(this.label, this.input, this.description)
108
+
109
+ if (this.schema.readOnly || this.schema.readonly) {
110
+ this.always_disabled = true
111
+ this.input.disabled = true
112
+ }
113
+
114
+ this.container.appendChild(this.control)
115
+
116
+ this.schemaeditor = new window.JSONSchemaEditor(this.input, {
117
+ startval: {}
118
+ })
119
+ this.schemaeditor.on('change', function() {
120
+ self.onChange(true)
121
+ })
122
+ }
123
+ enable() {
124
+ if (!this.always_disabled) {
125
+ this.input.disabled = false
126
+ }
127
+
128
+ super.enable()
129
+ }
130
+ disable() {
131
+ this.input.disabled = true
132
+ super.disable()
133
+ }
134
+ destroy() {
135
+ if (this.label && this.label.parentNode) this.label.parentNode.removeChild(this.label)
136
+ if (this.description && this.description.parentNode) this.description.parentNode.removeChild(this.description)
137
+ if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input)
138
+ super.destroy()
139
+ }
140
+ }
141
+ }
142
+
143
+ </script>
144
+
145
+ <style>
146
+ /* Override JSONEditor's textarea styles to make it expandable */
147
+ /* Use high specificity to override inline styles */
148
+ .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id] {
149
+ resize: both !important;
150
+ min-height: 250px !important;
151
+ min-width: 250px !important;
152
+ /* Add padding to create a larger hit area for the resize handle */
153
+ padding-right: 20px !important;
154
+ padding-bottom: 20px !important;
155
+ }
156
+
157
+ /* Make the resize handle easier to grab with larger hit area and clear visibility */
158
+ .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id]::-webkit-resizer {
159
+ width: 20px !important;
160
+ height: 20px !important;
161
+ /* Position it in the corner of the larger hit area */
162
+ margin-right: -20px !important;
163
+ margin-bottom: -20px !important;
164
+ /* Use border to create visible resize handle */
165
+ border-right: 2px solid #999 !important;
166
+ border-bottom: 2px solid #999 !important;
167
+ background: transparent !important;
168
+ }
169
+
170
+ /* Alternative approach - add a visible corner indicator using ::after pseudo-element */
171
+ .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id] {
172
+ position: relative !important;
173
+ }
174
+
175
+ .jsoneditor-vue .je-modal textarea.form-control.je-edit-json--textarea[id]::after {
176
+ content: "⋰⋰⋰" !important;
177
+ position: absolute !important;
178
+ bottom: 2px !important;
179
+ right: 2px !important;
180
+ font-size: 8px !important;
181
+ line-height: 6px !important;
182
+ color: #999 !important;
183
+ pointer-events: none !important;
184
+ transform: rotate(45deg) !important;
185
+ }
186
+ .jsoneditor-vue img {
187
+ border: 1px solid #ddd;
188
+ border-radius: 4px;
189
+ padding: 5px;
190
+ width: 150px;
191
+ }
192
+ .jsoneditor-vue img:hover {
193
+ box-shadow: 0 0 2px 1px rgba(0, 140, 186, 0.5);
194
+ }
195
+ .jsoneditor-vue button.btn {
196
+ font-size: 14px !important;
197
+ padding: 3px;
198
+ }
199
+ .jsoneditor-vue .form-control-label, label {
200
+ font-weight: bold;
201
+ }
202
+ .jsoneditor-vue input[type="checkbox"] {
203
+ margin-right: 5px;
204
+ margin-top: 3px;
205
+ }
206
+ </style>
@@ -1,43 +1,43 @@
1
- <template>
2
- <svg :class="svgClass" aria-hidden="true">
3
- <use :xlink:href="iconName" />
4
- </svg>
5
- </template>
6
-
7
- <script>
8
- export default {
9
- name: 'SvgIcon',
10
- props: {
11
- iconClass: {
12
- type: String,
13
- required: true
14
- },
15
- className: {
16
- type: String,
17
- default: ''
18
- }
19
- },
20
- computed: {
21
- iconName() {
22
- return `#icon-${this.iconClass}`
23
- },
24
- svgClass() {
25
- if (this.className) {
26
- return 'svg-icon ' + this.className
27
- } else {
28
- return 'svg-icon'
29
- }
30
- }
31
- }
32
- }
33
- </script>
34
-
35
- <style scoped>
36
- .svg-icon {
37
- width: 1em;
38
- height: 1em;
39
- vertical-align: -0.15em;
40
- fill: currentColor;
41
- overflow: hidden;
42
- }
43
- </style>
1
+ <template>
2
+ <svg :class="svgClass" aria-hidden="true">
3
+ <use :xlink:href="iconName" />
4
+ </svg>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'SvgIcon',
10
+ props: {
11
+ iconClass: {
12
+ type: String,
13
+ required: true
14
+ },
15
+ className: {
16
+ type: String,
17
+ default: ''
18
+ }
19
+ },
20
+ computed: {
21
+ iconName() {
22
+ return `#icon-${this.iconClass}`
23
+ },
24
+ svgClass() {
25
+ if (this.className) {
26
+ return 'svg-icon ' + this.className
27
+ } else {
28
+ return 'svg-icon'
29
+ }
30
+ }
31
+ }
32
+ }
33
+ </script>
34
+
35
+ <style scoped>
36
+ .svg-icon {
37
+ width: 1em;
38
+ height: 1em;
39
+ vertical-align: -0.15em;
40
+ fill: currentColor;
41
+ overflow: hidden;
42
+ }
43
+ </style>
@@ -1,9 +1,9 @@
1
- import Vue from 'vue'
2
- import SvgIcon from '@/components/SvgIcon' // svg组件
3
-
4
- // eslint-disable-next-line vue/component-definition-name-casing
5
- Vue.component('svg-icon', SvgIcon)
6
-
7
- const requireAll = requireContext => requireContext.keys().map(requireContext)
8
- const req = require.context('./svg', false, /\.svg$/)
9
- requireAll(req)
1
+ import Vue from 'vue'
2
+ import SvgIcon from '@/components/SvgIcon' // svg组件
3
+
4
+ // eslint-disable-next-line vue/component-definition-name-casing
5
+ Vue.component('svg-icon', SvgIcon)
6
+
7
+ const requireAll = requireContext => requireContext.keys().map(requireContext)
8
+ const req = require.context('./svg', false, /\.svg$/)
9
+ requireAll(req)