free-fe-core-modules 0.0.1

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 (112) hide show
  1. package/README.md +7 -0
  2. package/components/.gitkeep +0 -0
  3. package/components/Basic/BreadCrumbs.vue +87 -0
  4. package/components/Basic/EIcon.vue +84 -0
  5. package/components/Basic/LeveledMenus.vue +92 -0
  6. package/components/Basic/SummaryHead.vue +312 -0
  7. package/components/Dialog/BasicDialog.vue +442 -0
  8. package/components/Dialog/index.js +38 -0
  9. package/components/Dialog/index1.js +49 -0
  10. package/components/FloatingWindow/index.vue +140 -0
  11. package/components/SelectLocales/index.vue +47 -0
  12. package/components/SlidingCarousel/index.vue +86 -0
  13. package/components/SlidingNews/index.vue +138 -0
  14. package/components/StickyButtons/index.vue +98 -0
  15. package/components/ThemeSwitch/index.vue +77 -0
  16. package/field-components/Display/index.js +3 -0
  17. package/field-components/Fields/AgreementCheck.vue +161 -0
  18. package/field-components/Fields/ApiCall.vue +139 -0
  19. package/field-components/Fields/Boolean.vue +112 -0
  20. package/field-components/Fields/Category.vue +33 -0
  21. package/field-components/Fields/Check.vue +131 -0
  22. package/field-components/Fields/Customize.vue +103 -0
  23. package/field-components/Fields/Date.vue +142 -0
  24. package/field-components/Fields/DateRange.vue +199 -0
  25. package/field-components/Fields/DynamicList.vue +575 -0
  26. package/field-components/Fields/FieldEditor.vue +379 -0
  27. package/field-components/Fields/File.vue +382 -0
  28. package/field-components/Fields/FileList.vue +405 -0
  29. package/field-components/Fields/FileListCombined.vue +142 -0
  30. package/field-components/Fields/FixedList.vue +372 -0
  31. package/field-components/Fields/Image.vue +328 -0
  32. package/field-components/Fields/ImageList.vue +285 -0
  33. package/field-components/Fields/ImageListCombined.vue +76 -0
  34. package/field-components/Fields/InputFieldList.vue +299 -0
  35. package/field-components/Fields/Labels.vue +182 -0
  36. package/field-components/Fields/MixedTable.vue +367 -0
  37. package/field-components/Fields/Number.vue +247 -0
  38. package/field-components/Fields/Password.vue +79 -0
  39. package/field-components/Fields/Permission.vue +83 -0
  40. package/field-components/Fields/PermissionEditor.vue +205 -0
  41. package/field-components/Fields/QueryFilters.vue +162 -0
  42. package/field-components/Fields/RadioList.vue +81 -0
  43. package/field-components/Fields/Rich.vue +369 -0
  44. package/field-components/Fields/Search.vue +499 -0
  45. package/field-components/Fields/Select.vue +376 -0
  46. package/field-components/Fields/SelectionChain.vue +198 -0
  47. package/field-components/Fields/Separator.vue +26 -0
  48. package/field-components/Fields/SingleList.vue +125 -0
  49. package/field-components/Fields/Static.vue +22 -0
  50. package/field-components/Fields/String.vue +185 -0
  51. package/field-components/Fields/Text.vue +89 -0
  52. package/field-components/Fields/Time.vue +160 -0
  53. package/field-components/Fields/TimeRange.vue +348 -0
  54. package/field-components/Fields/UltimateFile.vue +100 -0
  55. package/field-components/Fields/Year.vue +124 -0
  56. package/field-components/Fields/YearRange.vue +188 -0
  57. package/field-components/Fields/components/FieldTypeOptions.vue +248 -0
  58. package/field-components/Fields/index.js +117 -0
  59. package/field-components/components/FieldComponents.vue +246 -0
  60. package/field-components/index.js +13 -0
  61. package/field-components/style.sass +11 -0
  62. package/free-fields/AutoHide.js +66 -0
  63. package/free-fields/CenterContent.js +15 -0
  64. package/free-fields/Draggable.js +30 -0
  65. package/free-fields/Droppable.js +114 -0
  66. package/free-fields/EditableString.js +63 -0
  67. package/free-fields/FieldCategory.js +83 -0
  68. package/free-fields/FieldTypeSelect.js +94 -0
  69. package/free-fields/fieldEditors/arrayEditor.js +3 -0
  70. package/free-fields/fieldEditors/boolEditor.js +22 -0
  71. package/free-fields/fieldEditors/dateEditor.js +23 -0
  72. package/free-fields/fieldEditors/datetimeEditor.js +23 -0
  73. package/free-fields/fieldEditors/index.js +21 -0
  74. package/free-fields/fieldEditors/jsonEditor.js +371 -0
  75. package/free-fields/fieldEditors/labeledField.js +74 -0
  76. package/free-fields/fieldEditors/numberEditor.js +51 -0
  77. package/free-fields/fieldEditors/objectEditor.js +3 -0
  78. package/free-fields/fieldEditors/selectEditor.js +0 -0
  79. package/free-fields/fieldEditors/stringEditor.js +49 -0
  80. package/free-fields/fieldEditors/textEditor.js +50 -0
  81. package/free-fields/fieldEditors/timeEditor.js +23 -0
  82. package/free-fields/index.js +402 -0
  83. package/i18n/en-us/index.js +73 -0
  84. package/i18n/fields/en-us/index.js +9 -0
  85. package/i18n/fields/zh-cn/index.js +9 -0
  86. package/i18n/zh-cn/index.js +73 -0
  87. package/index.js +367 -0
  88. package/package.json +11 -0
  89. package/router/dict/api.js +18 -0
  90. package/router/dict/data.js +48 -0
  91. package/router/dict/index.js +7 -0
  92. package/router/error/api.js +14 -0
  93. package/router/error/data.js +33 -0
  94. package/router/error/index.js +9 -0
  95. package/router/index.js +13 -0
  96. package/router/menu/api.js +24 -0
  97. package/router/menu/data.js +85 -0
  98. package/router/menu/index.js +7 -0
  99. package/router/system/api.js +10 -0
  100. package/router/system/data.js +46 -0
  101. package/router/system/index.js +7 -0
  102. package/stores/index.js +17 -0
  103. package/stores/module-mourning/actions.js +3 -0
  104. package/stores/module-mourning/getters.js +1 -0
  105. package/stores/module-mourning/index.js +11 -0
  106. package/stores/module-mourning/state.js +3 -0
  107. package/stores/mourning.js +3 -0
  108. package/view/dict/index.vue +284 -0
  109. package/view/error/list.vue +197 -0
  110. package/view/menu/index.vue +332 -0
  111. package/view/mourning/mourning.vue +45 -0
  112. package/view/system/index.vue +149 -0
@@ -0,0 +1,285 @@
1
+ <template>
2
+ <div class="row input-field-image-list">
3
+ <span
4
+ :class="`field-label ${(Field.Label && Field.Label.trim().length)
5
+ ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
6
+ v-if="typeof Field.Label !== 'undefined'">
7
+ <q-tooltip v-if="Field.Description" anchor="top right">{{Field.Description}}</q-tooltip>
8
+ {{Field.Label || ''}}
9
+ <span v-if="Field.Required" class="required-mark">*</span>
10
+ </span>
11
+ <q-uploader
12
+ @finish="uploaded"
13
+ @removed="uploaded"
14
+ @rejected="filesRejected"
15
+ :factory="factoryFn"
16
+ multiple
17
+ :max-files="Field.Options && Field.Options.MaxCount"
18
+ :max-file-size="maxFileSize"
19
+ :max-total-size="maxTotalSize"
20
+ :class="`q-ma-xs ${hasError ? 'input-field--error' : ''}`"
21
+ ref="uploader"
22
+ >
23
+ <template v-slot:list="scope">
24
+ <div class="uploader-btns row no-wrap items-center">
25
+ <q-spinner v-if="scope.isUploading" class="q-uploader__spinner" />
26
+ <q-btn
27
+ v-if="scope.canAddFiles"
28
+ type="a"
29
+ icon="add_box"
30
+ label="点击添加"
31
+ class="add-btn"
32
+ dense
33
+ flat
34
+ :disabled="Field.ReadOnly"
35
+ >
36
+ <q-uploader-add-trigger v-if="!Field.ReadOnly"/>
37
+ </q-btn>
38
+ <q-btn
39
+ v-if="scope.canUpload"
40
+ icon="cloud_upload"
41
+ @click="scope.upload"
42
+ class="upload-btn"
43
+ label="点击上传"
44
+ dense
45
+ flat
46
+ :disabled="Field.ReadOnly"
47
+ ></q-btn>
48
+
49
+ <q-btn
50
+ v-if="scope.isUploading"
51
+ icon="clear"
52
+ @click="scope.abort"
53
+ class="abort-btn"
54
+ round
55
+ dense
56
+ flat
57
+ :disabled="Field.ReadOnly"
58
+ ></q-btn>
59
+ <slot name="warning"></slot>
60
+ </div>
61
+
62
+ <div v-if="scope.files.length" class="file-list row items-start justify-start q-gutter-xl">
63
+ <q-card
64
+ flat
65
+ class="file-list-item"
66
+ v-for="(file, index) in scope.files" :key="index">
67
+ <e-icon class="file-image" :name="fileThumb(file)" thumb
68
+ :relative="filePreviewType(file) !== 'image'"
69
+ @click="preview(file)">
70
+ <div class="view-btn-wrapper absolute-full justify-center text-center">
71
+ <q-btn
72
+ flat
73
+ class="view-btn full-height full-width"
74
+ @click="preview(file)"
75
+ >查看</q-btn>
76
+ </div>
77
+ </e-icon>
78
+ <span class="file-name full-width ellipsis">
79
+ {{ file.name }}
80
+ <q-tooltip>{{ file.name }}</q-tooltip>
81
+ </span>
82
+
83
+ <span class="file-size full-width ellipsis">
84
+ Size: {{ file.sizeLabel || file.__sizeLabel }}
85
+ </span>
86
+
87
+ <q-btn
88
+ flat
89
+ dense
90
+ round
91
+ class="delete-btn"
92
+ icon="close"
93
+ @click="scope.removeFile(file)"
94
+ :disabled="Field.ReadOnly"
95
+ />
96
+ </q-card>
97
+ </div>
98
+ <!-- <q-list separator v-if="scope.files.length">
99
+ <q-item>
100
+ <q-item-section v-for="(file, index) in scope.files" :key="index">
101
+ <q-item-label class="full-width ellipsis">
102
+ {{ file.name }}
103
+ <q-tooltip>{{ file.name }}</q-tooltip>
104
+ </q-item-label>
105
+
106
+ <q-item-label caption>Size: {{ file.sizeLabel || file.__sizeLabel }}</q-item-label>
107
+
108
+ <q-item-section v-if="file.__img" thumbnail class="gt-xs">
109
+ <img :src="file.__img.src" />
110
+ </q-item-section>
111
+ <q-item-section v-if="file.id" thumbnail class="gt-xs">
112
+ <img :src="`${ctx.config.thumbUrlBase}${file.id}`" />
113
+ </q-item-section>
114
+
115
+ <q-item-section side>
116
+ <q-btn
117
+ class="gt-xs"
118
+ size="12px"
119
+ flat
120
+ dense
121
+ round
122
+ icon="delete"
123
+ @click="scope.removeFile(file)"
124
+ :disabled="Field.ReadOnly"
125
+ />
126
+ </q-item-section>
127
+ </q-item-section>
128
+ </q-item>
129
+ </q-list> -->
130
+ <!-- <div v-else class="text-center">no file selected yet</div> -->
131
+ <div class="input-field--error-tag" v-if="hasError">
132
+ <e-icon name="error"></e-icon>
133
+ </div>
134
+ </template>
135
+ </q-uploader>
136
+ <q-dialog class="image-preview-dialog"
137
+ flat
138
+ full-width full-height v-model="showPreview"
139
+ style="background: rgba(0,0,0,0)">
140
+ <div class="image-preview">
141
+ <q-img
142
+ v-if="previewType=== 'image'"
143
+ contain :src="previewFile"
144
+ @click="showPreview=false"
145
+ style="height: 100%; max-width: 100%;">
146
+ </q-img>
147
+
148
+ <q-pdfviewer
149
+ v-if="previewType === 'pdf'"
150
+ v-model="showPreview"
151
+ @click="showPreview=false"
152
+ :src="previewFile"
153
+ type="pdfjs"
154
+ style="height: 100%; max-width: 100%;"
155
+ />
156
+ </div>
157
+ </q-dialog>
158
+ </div>
159
+ </template>
160
+
161
+ <script>
162
+ import { defineComponent } from 'vue';
163
+ import mixnins from 'free-fe-mixins';
164
+
165
+ export default defineComponent({
166
+ name: 'InputFieldImageList',
167
+ mixins: [mixnins.UploaderMixin, mixnins.InputFieldMixin],
168
+ emits:['input'],
169
+ fieldInfo: {
170
+ Category: 'Upload',
171
+ Label: '图片列表',
172
+ Value: 'ImageList',
173
+ Extra: [
174
+ {
175
+ Type: 'String',
176
+ Label: '支持的文件类型',
177
+ Name: 'Options.Ext',
178
+ Default: 'jpg,png,bmp',
179
+ },
180
+ {
181
+ Type: 'String',
182
+ Label: '最大文件大小',
183
+ Name: 'MaxValue',
184
+ Default: '10m',
185
+ },
186
+ {
187
+ Type: 'String',
188
+ Label: '最大总大小',
189
+ Name: 'Options.MaxTotal',
190
+ Default: '50m',
191
+ },
192
+ ],
193
+ Description: '',
194
+ },
195
+ data() {
196
+ return {
197
+ hasError: false,
198
+ };
199
+ },
200
+ watch: {
201
+ fieldData() {
202
+ if (this.fieldData) {
203
+ this.$refs.uploader.files = this.fieldData;
204
+ }
205
+ },
206
+ },
207
+ mounted() {
208
+ if (this.fieldData) {
209
+ try {
210
+ this.$refs.uploader.files = this.fieldData;
211
+ } catch (ex) {
212
+ //
213
+ }
214
+ }
215
+ },
216
+ methods: {
217
+ validate() {
218
+ if (this.Field.Required) {
219
+ this.hasError = this.$refs.uploader.files.length <= 0;
220
+ return this.$refs.uploader.files.length > 0;
221
+ }
222
+
223
+ const rules = Array.isArray(typeof this.Field.Rules) ? this.Field.Rules : [this.Field.Rules];
224
+
225
+ let isValid = true;
226
+ for (let i = 0; i < rules.length; i += 1) {
227
+ const r = rules[i];
228
+
229
+ if (typeof r === 'function') {
230
+ isValid = isValid && r(this.$refs.uploader.files);
231
+ }
232
+ }
233
+
234
+ this.hasError = !isValid;
235
+ return isValid;
236
+ },
237
+ factoryFn() {
238
+ return {
239
+ url: this.Field.url || `${this.ctx.config.baseUrl}/upload`,
240
+ fieldName: 'file',
241
+ };
242
+ },
243
+ uploaded() {
244
+ const uploadedFiles = [];
245
+ for (let i = 0; i < this.$refs.uploader.files.length; i += 1) {
246
+ const file = this.$refs.uploader.files[i];
247
+
248
+ const { xhr } = file;
249
+ let res;
250
+ if (xhr && xhr.response) {
251
+ if (typeof xhr.response === 'string') {
252
+ //
253
+ res = JSON.parse(xhr.response);
254
+ } else if (typeof xhr.response === 'object') {
255
+ //
256
+ res = xhr.response;
257
+ } else {
258
+ //
259
+ return;
260
+ }
261
+
262
+ if (res && res.msg === 'OK') {
263
+ uploadedFiles.push({
264
+ id: res.data.id,
265
+ // eslint-disable-next-line no-underscore-dangle
266
+ sizeLabel: file.__sizeLabel,
267
+ name: file.name,
268
+ size: file.size,
269
+ type: file.type,
270
+ });
271
+ }
272
+ } else if (file.id) {
273
+ // old files
274
+ uploadedFiles.push(file);
275
+ }
276
+ }
277
+
278
+ this.fieldData = uploadedFiles;
279
+ this.$emit('input');
280
+
281
+ this.validate();
282
+ },
283
+ },
284
+ });
285
+ </script>
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <div class="row input-field-image-list combined input-field--readonly">
3
+ <span
4
+ :class="`field-label ${(Field.Label && Field.Label.trim().length)
5
+ ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
6
+ v-if="typeof Field.Label !== 'undefined'">
7
+ <q-tooltip v-if="Field.Description" anchor="top right">{{Field.Description}}</q-tooltip>
8
+ {{Field.Label || ''}}
9
+ </span>
10
+ <q-uploader
11
+ multiple
12
+ :class="`q-ma-xs `"
13
+ ref="uploader"
14
+ >
15
+ <template v-slot:list="scope">
16
+ <div v-if="scope.files.length" class="file-list row items-start justify-start q-gutter-xl">
17
+ <q-card
18
+ flat
19
+ class="file-list-item"
20
+ v-for="(file, index) in scope.files" :key="index">
21
+ <e-icon class="file-image" :name="fileThumb(file)" thumb :relative="false">
22
+ <div class="view-btn-wrapper absolute-full justify-center text-center">
23
+ <q-btn
24
+ flat
25
+ class="view-btn full-height full-width"
26
+ @click="preview(file)"
27
+ >查看</q-btn>
28
+ </div>
29
+ </e-icon>
30
+ <span class="file-name full-width ellipsis">
31
+ {{ file.name }}
32
+ <q-tooltip>{{ file.name }}</q-tooltip>
33
+ </span>
34
+
35
+ <span class="file-size full-width ellipsis">
36
+ Size: {{ file.sizeLabel || file.__sizeLabel }}
37
+ </span>
38
+ </q-card>
39
+ </div>
40
+ </template>
41
+ </q-uploader>
42
+ <q-dialog class="image-preview-dialog"
43
+ flat
44
+ full-width full-height v-model="showPreview"
45
+ style="background: rgba(0,0,0,0)">
46
+ <div class="image-preview">
47
+ <q-img contain :src="previewFile"
48
+ @click="showPreview=false"
49
+ style="height: 100%; max-width: 100%;"></q-img>
50
+ </div>
51
+ </q-dialog>
52
+ </div>
53
+ </template>
54
+
55
+ <script>
56
+ import { defineComponent } from 'vue';
57
+ import mixnins from 'free-fe-mixins';
58
+
59
+ export default defineComponent({
60
+ name: 'InputFieldImageListCombined',
61
+ mixins: [mixnins.UploaderMixin, mixnins.InputFieldMixin],
62
+ fieldInfo: {
63
+ Category: 'Upload',
64
+ Label: '合并图片列表',
65
+ Value: 'ImageListCombined',
66
+ Description: '',
67
+ },
68
+ watch: {
69
+ fieldData() {
70
+ if (this.fieldData) {
71
+ this.$refs.uploader.files = this.fieldData;
72
+ }
73
+ },
74
+ },
75
+ });
76
+ </script>
@@ -0,0 +1,299 @@
1
+ <template>
2
+ <div class="input-field-list">
3
+ <dynamic-list
4
+ :Field="localField"
5
+ :values="data"
6
+ readonly
7
+ ref="fieldList"
8
+ selection="multiple"
9
+ >
10
+ <template v-slot:top>
11
+ <q-btn-group class="action-buttons">
12
+ <q-btn
13
+ icon="content_copy"
14
+ @click="copy"
15
+ >
16
+ <q-tooltip>拷贝选中</q-tooltip>
17
+ </q-btn>
18
+ <q-btn
19
+ icon="content_paste"
20
+ @click="paste"
21
+ >
22
+ <q-tooltip>粘贴</q-tooltip>
23
+ </q-btn>
24
+ <q-btn
25
+ icon="update"
26
+ @click="batch"
27
+ v-if="$refs.fieldList && $refs.fieldList.selected.length > 0"
28
+ >
29
+ <q-tooltip>批量修改</q-tooltip>
30
+ </q-btn>
31
+ </q-btn-group>
32
+ </template>
33
+ <template v-slot:header-actions>
34
+ <q-btn
35
+ flat
36
+ round
37
+ icon="add"
38
+ @click="addField"
39
+ ></q-btn>
40
+ </template>
41
+ <template v-slot:body-actions="props">
42
+ <q-btn
43
+ flat
44
+ round
45
+ icon="edit"
46
+ @click="editingField=props.row"
47
+ ></q-btn>
48
+ <q-btn
49
+ flat
50
+ round
51
+ icon="delete"
52
+ @click="deleteField(props)"
53
+ ></q-btn>
54
+ </template>
55
+ <template v-slot:warning>
56
+ <slot name="warning"></slot>
57
+ </template>
58
+ </dynamic-list>
59
+
60
+ <free-field
61
+ :Field="editingFieldField"
62
+ :values="editingField"
63
+ @cancel="editingField = undefined; $emit('cancel')"
64
+ @save="saveField"
65
+ @input="$emit('input')"
66
+ @update:field="editingFieldChanged"
67
+ ></free-field>
68
+ </div>
69
+ </template>
70
+
71
+ <script>
72
+ import { defineComponent } from 'vue';
73
+ import mixins from 'free-fe-mixins';
74
+ import DynamicList from './DynamicList';
75
+
76
+ const clipBoardStore = {
77
+ content: '',
78
+ items: [],
79
+ };
80
+
81
+ // const DynamicList = { ...DList };
82
+ // DynamicList.mixins = (DynamicList.mixins || []).concat(InputFieldMixin.mixins);
83
+ // DynamicList.props = { ...InputFieldMixin.props, ...DynamicList.props };
84
+ // DynamicList.computed = {
85
+
86
+ // ...InputFieldMixin.computed,
87
+ // ...DynamicList.computed,
88
+ // };
89
+ // DynamicList.methods = {
90
+
91
+ // ...InputFieldMixin.methods,
92
+ // ...DynamicList.methods,
93
+ // };
94
+ // DynamicList.created = DynamicList.created || InputFieldMixin.created;
95
+
96
+ export default defineComponent({
97
+ name: 'InputFieldList',
98
+ mixins: [mixins.InputFieldMixin],
99
+ emits:['save', 'delete', 'cancel','paste:fields', 'batch:fields'],
100
+ fieldInfo: {
101
+ Category: 'Advanced',
102
+ Label: '字段列表',
103
+ Value: 'FieldList',
104
+ Description: '',
105
+ },
106
+ components: {
107
+ DynamicList,
108
+ },
109
+ data() {
110
+ return {
111
+ editingField: undefined,
112
+ changedFields: [],
113
+ };
114
+ },
115
+ computed: {
116
+ editingFieldField() {
117
+ return {
118
+ Type: 'FieldEditor',
119
+ Name: '',
120
+ show: !!this.editingField,
121
+ };
122
+ },
123
+ localField() {
124
+ return {
125
+ Type: 'DynamicList',
126
+ showTop: true,
127
+ Name: this.Field && this.Field.Name ? this.Field.Name : 'Fields',
128
+ Options: {
129
+ Columns:
130
+ this.Field && this.Field.Options && this.Field.Options.Columns
131
+ ? this.Field.Options.Columns
132
+ : [
133
+ {
134
+ Label: '#',
135
+ Name: 'Index',
136
+ sortable: true,
137
+ style: 'max-width: 100px;',
138
+ },
139
+ // {
140
+ // Label: '日期',
141
+ // Name: 'LastUpdateDate',
142
+ // style: 'max-width: 160px;',
143
+ // sortable: true,
144
+ // Options: {
145
+ // Filters: 'normalDate',
146
+ // },
147
+ // },
148
+ {
149
+ Label: '名称',
150
+ Name: 'Name',
151
+ style: 'max-width: 300px; overflow: hidden',
152
+ sortable: true,
153
+ },
154
+ {
155
+ Label: '标题',
156
+ Name: 'Label',
157
+ style: 'max-width: 300px; min-width: 100px',
158
+ sortable: true,
159
+ },
160
+ {
161
+ Label: '类型',
162
+ Name: 'Type',
163
+ style: 'max-width: 200px; min-width: 100px',
164
+ sortable: true,
165
+ },
166
+ ],
167
+ },
168
+ };
169
+ },
170
+ },
171
+ methods: {
172
+ addField() {
173
+ let newIndex = 1;
174
+
175
+ if (this.data) {
176
+ const fName = this.Field && this.Field.Name ? this.Field.Name : 'Fields';
177
+ const fData = this.data[fName];
178
+
179
+ if (fData && fData.length) {
180
+ newIndex = fData[fData.length - 1].Index + 1;
181
+ }
182
+ }
183
+
184
+ this.editingField = {
185
+ Index: newIndex,
186
+ };
187
+ },
188
+ saveField() {
189
+ if (!this.editingField) return;
190
+ const theField = { ...this.editingField };
191
+
192
+ if (theField.isBatchEditing) {
193
+ if (this.$refs.fieldList.selected.length > 0) {
194
+ const items = [];
195
+ for (let i = 0; i < this.$refs.fieldList.selected.length; i += 1) {
196
+ const item = this.$refs.fieldList.selected[i];
197
+
198
+ if (item && item.id) {
199
+ items.push(item.id);
200
+ }
201
+ }
202
+
203
+ const newFld = {};
204
+ for (let i = 0; i < this.changedFields.length; i += 1) {
205
+ const fld = this.changedFields[i];
206
+ if (fld && typeof theField[fld] !== 'undefined') {
207
+ newFld[fld] = theField[fld];
208
+ }
209
+ }
210
+ this.editingField = undefined;
211
+ this.$emit(
212
+ 'batch:fields',
213
+ { ...newFld, ids: items.join(',') },
214
+ );
215
+ }
216
+ } else {
217
+ if (typeof theField.auto__index === 'undefined') {
218
+ // adding new
219
+ this.$refs.fieldList.addRow(theField);
220
+ }
221
+
222
+ this.editingField = undefined;
223
+
224
+ this.$emit('save', theField);
225
+ }
226
+ },
227
+ deleteField(p) {
228
+ this.$refs.fieldList.deleteRow(p);
229
+ this.$emit('delete', p.row);
230
+ },
231
+ copy() {
232
+ clipBoardStore.items = [];
233
+
234
+ if (
235
+ !this.$refs.fieldList
236
+ || !this.$refs.fieldList.selected
237
+ || this.$refs.fieldList.selected.length <= 0
238
+ ) {
239
+ return;
240
+ }
241
+
242
+ const items = [];
243
+ for (let i = 0; i < this.$refs.fieldList.selected.length; i += 1) {
244
+ const item = this.$refs.fieldList.selected[i];
245
+
246
+ if (item) {
247
+ items.push(item.id);
248
+ }
249
+ clipBoardStore.items.push(item);
250
+ }
251
+
252
+ if (items.length <= 0) return;
253
+
254
+ clipBoardStore.content = `EIS_FLOW_FIELD_COPY:${items.join(',')}`;
255
+ },
256
+ paste() {
257
+ // local paste
258
+ if (clipBoardStore.items && clipBoardStore.items.length > 0) {
259
+ const fName = (this.Field && this.Field.Name) ? this.Field.Name : 'Fields';
260
+ this.data[fName] = this.data[fName] || [];
261
+ this.data[fName] = this.data[fName].concat(clipBoardStore.items.map((i) => {
262
+ delete i.id;
263
+ delete i.auto__index;
264
+ return i;
265
+ })).sort((a, b) => a.Index - b.Index);
266
+ }
267
+
268
+ // emit to parent
269
+ if (
270
+ clipBoardStore.content
271
+ && clipBoardStore.content.startsWith('EIS_FLOW_FIELD_COPY:')
272
+ ) {
273
+ this.$emit(
274
+ 'paste:fields',
275
+ clipBoardStore.content.substr('EIS_FLOW_FIELD_COPY:'.length),
276
+ clipBoardStore.items,
277
+ );
278
+ }
279
+ },
280
+ editingFieldChanged(f) {
281
+ if (!f) return;
282
+ this.changedFields.push(f);
283
+ },
284
+ batch() {
285
+ if (
286
+ !this.$refs.fieldList
287
+ || !this.$refs.fieldList.selected
288
+ || this.$refs.fieldList.selected.length <= 0
289
+ ) {
290
+ return;
291
+ }
292
+
293
+ this.editingField = {
294
+ isBatchEditing: true,
295
+ };
296
+ },
297
+ },
298
+ });
299
+ </script>