free-fe-core-modules 0.0.24 → 0.0.26
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/components/Basic/BreadCrumbs.vue +2 -1
- package/components/Basic/SummaryHead.vue +7 -0
- package/composible/useObjectData.js +13 -2
- package/free-field/Fields/Column.vue +15 -4
- package/free-field/Fields/DynamicList.js +1 -1
- package/free-field/Fields/MixedTable.vue +12 -3
- package/free-field/Fields/Number.js +26 -2
- package/free-field/Fields/NumberRange.vue +2 -2
- package/free-field/Fields/Permission.vue +1 -1
- package/free-field/Fields/Row.vue +15 -3
- package/free-field/Fields/Search.vue +1 -1
- package/free-field/Fields/Select.vue +37 -6
- package/free-field/Fields/SelectionChain.vue +1 -1
- package/free-field/Fields/Tabs.vue +3 -3
- package/free-field/Fields/Text.js +2 -0
- package/free-field/Fields/Time.vue +1 -1
- package/free-field/Fields/YearRange.vue +2 -2
- package/free-field/composible/fieldWrapper.js +1 -0
- package/free-field/composible/useUploader.js +5 -4
- package/index.js +19 -3
- package/package.json +1 -1
- package/view/dict/index.vue +39 -2
- package/view/error/list.vue +1 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
/>
|
|
10
10
|
<q-space></q-space>
|
|
11
11
|
<q-btn v-if="meta.length > 0 && canBack"
|
|
12
|
-
flat icon="
|
|
12
|
+
flat :icon="backIcon" @click="back">{{$t(backText)}}</q-btn>
|
|
13
13
|
</q-breadcrumbs>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
@@ -24,6 +24,7 @@ export default defineComponent({
|
|
|
24
24
|
props: {
|
|
25
25
|
canBack: { type: Boolean, default: true },
|
|
26
26
|
backText: { type: String, default: '返回' },
|
|
27
|
+
backIcon: { type: String, default: 'keyboard_arrow_left' },
|
|
27
28
|
},
|
|
28
29
|
setup() {
|
|
29
30
|
const router = useRouter();
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
<q-btn
|
|
34
34
|
flat
|
|
35
35
|
round
|
|
36
|
+
:disable="item.disable"
|
|
36
37
|
class="summary-head-btn"
|
|
37
38
|
v-if="item.button"
|
|
38
39
|
@click="button_clicked(item)">
|
|
@@ -133,7 +134,11 @@ export default defineComponent({
|
|
|
133
134
|
return item.number;
|
|
134
135
|
},
|
|
135
136
|
button_clicked(item) {
|
|
137
|
+
if (item.disable) return;
|
|
138
|
+
|
|
139
|
+
item.disable = true;
|
|
136
140
|
Promise.resolve(typeof item.action === 'function' ? item.action(item) : '').then(() => {
|
|
141
|
+
item.disable = false;
|
|
137
142
|
if (item.event) {
|
|
138
143
|
if (item.event_params) {
|
|
139
144
|
this.Bus?.$emit(item.event, item.event_params);
|
|
@@ -150,6 +155,8 @@ export default defineComponent({
|
|
|
150
155
|
|
|
151
156
|
this.router.push(item.route);
|
|
152
157
|
}
|
|
158
|
+
}).catch(() => {
|
|
159
|
+
item.disable = false;
|
|
153
160
|
});
|
|
154
161
|
},
|
|
155
162
|
},
|
|
@@ -31,8 +31,11 @@ export function useObjectData(props, ctx) {
|
|
|
31
31
|
|
|
32
32
|
const refreshData = (...args) => {
|
|
33
33
|
// support multiple get data functions
|
|
34
|
+
let hasMultipleGetData = false;
|
|
35
|
+
|
|
34
36
|
const getDataList = [];
|
|
35
37
|
if (Array.isArray(props.GetData)) {
|
|
38
|
+
hasMultipleGetData = true;
|
|
36
39
|
getDataList.push(...props.GetData);
|
|
37
40
|
} else {
|
|
38
41
|
getDataList.push(props.GetData);
|
|
@@ -45,12 +48,20 @@ export function useObjectData(props, ctx) {
|
|
|
45
48
|
|
|
46
49
|
if (typeof getData === 'function') {
|
|
47
50
|
Promise.resolve(getData(...args)).then((d) => {
|
|
48
|
-
|
|
51
|
+
if (hasMultipleGetData) {
|
|
52
|
+
Object.assign(data.value, unref(d[0]));
|
|
53
|
+
} else {
|
|
54
|
+
data.value = unref(d);
|
|
55
|
+
}
|
|
49
56
|
}).finally(() => {
|
|
50
57
|
callsLeft.value --;
|
|
51
58
|
});
|
|
52
59
|
} else {
|
|
53
|
-
|
|
60
|
+
if (hasMultipleGetData) {
|
|
61
|
+
Object.assign(data.value, unref(getData[0]));
|
|
62
|
+
} else {
|
|
63
|
+
data.value = unref(getData);
|
|
64
|
+
}
|
|
54
65
|
callsLeft.value --;
|
|
55
66
|
}
|
|
56
67
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="free-field-column column" :class="columnClasses" v-if="Field">
|
|
3
3
|
<free-field
|
|
4
|
-
v-for="(field, idx) in Field.Options?.
|
|
4
|
+
v-for="(field, idx) in Field.Options?.Fields"
|
|
5
5
|
:Field="field"
|
|
6
6
|
:values="fieldData"
|
|
7
7
|
:key="idx"
|
|
8
|
-
|
|
8
|
+
ref="fieldsToValidate"
|
|
9
|
+
@input="$emit('input', field)"></free-field>
|
|
9
10
|
</div>
|
|
10
11
|
</template>
|
|
11
12
|
|
|
12
13
|
<script>
|
|
13
14
|
import { defineComponent } from 'vue';
|
|
14
15
|
import { freeFieldProps } from '../composible/useFreeField';
|
|
16
|
+
import { useFormValidator} from '../../composible/useFormValidator';
|
|
15
17
|
|
|
16
18
|
export default defineComponent({
|
|
17
19
|
name: 'InputFieldColumn',
|
|
@@ -26,7 +28,7 @@ export default defineComponent({
|
|
|
26
28
|
{
|
|
27
29
|
Label: '不换行',
|
|
28
30
|
Name: 'Options.NoWrap',
|
|
29
|
-
Type: '
|
|
31
|
+
Type: 'Boolean',
|
|
30
32
|
},
|
|
31
33
|
{
|
|
32
34
|
Label: '横向对齐',
|
|
@@ -80,7 +82,7 @@ export default defineComponent({
|
|
|
80
82
|
},
|
|
81
83
|
{
|
|
82
84
|
Label: '字段',
|
|
83
|
-
Name: 'Options.
|
|
85
|
+
Name: 'Options.Fields',
|
|
84
86
|
Type: 'FieldList',
|
|
85
87
|
Options: {
|
|
86
88
|
Columns: [
|
|
@@ -117,6 +119,15 @@ export default defineComponent({
|
|
|
117
119
|
],
|
|
118
120
|
Description: '',
|
|
119
121
|
},
|
|
122
|
+
setup(props) {
|
|
123
|
+
if(!props.Field) return () => null;
|
|
124
|
+
|
|
125
|
+
const { validate } = useFormValidator('fieldsToValidate');
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
validate,
|
|
129
|
+
}
|
|
130
|
+
},
|
|
120
131
|
computed: {
|
|
121
132
|
columnClasses() {
|
|
122
133
|
return this.Field.Options?.NoWrap ? 'nowrap' : '' + this.Field.Options?.ItemsAlign + ' ' + this.Field.Options?.JustifyAlign;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
</template>
|
|
34
34
|
<template v-slot:body>
|
|
35
35
|
<q-tr
|
|
36
|
-
v-for="(r,index) in
|
|
36
|
+
v-for="(r,index) in localRows"
|
|
37
37
|
:key="index"
|
|
38
38
|
:class="((index || 0) % 2) ? 'row-zebra-odd' : 'row-zebra-even'"
|
|
39
39
|
>
|
|
@@ -218,7 +218,9 @@ export default defineComponent({
|
|
|
218
218
|
d.Options.Rows[i] = d.Options.Rows[i] || {};
|
|
219
219
|
|
|
220
220
|
// set data row index
|
|
221
|
-
d.Options.Rows[i].auto__index
|
|
221
|
+
if (d.Options.Rows[i].auto__index === void 0) {
|
|
222
|
+
d.Options.Rows[i].auto__index = `${i + 1}`;
|
|
223
|
+
}
|
|
222
224
|
|
|
223
225
|
// limit rowspan and colspan
|
|
224
226
|
if (typeof rowColNumbers[i] === 'undefined') {
|
|
@@ -258,7 +260,8 @@ export default defineComponent({
|
|
|
258
260
|
for (let i = 0; i < d.Options.Rows.length; i += 1) {
|
|
259
261
|
// this.data.Options.Rows[i].rowSize = rowColNumbers[i];
|
|
260
262
|
// remove extra cells according to the span
|
|
261
|
-
const
|
|
263
|
+
const auto__index = d.Options.Rows[i].auto__index;
|
|
264
|
+
const newRow = { rowSize: rowColNumbers[i], auto__index };
|
|
262
265
|
for (let j = 0; j < rowColNumbers[i]; j += 1) {
|
|
263
266
|
newRow[j] = d.Options.Rows[i][j];
|
|
264
267
|
}
|
|
@@ -359,6 +362,12 @@ export default defineComponent({
|
|
|
359
362
|
cellChanged: (f) => {
|
|
360
363
|
emit('input', f);
|
|
361
364
|
},
|
|
365
|
+
localRows: computed(() => {
|
|
366
|
+
if (!props.Field?.Options?.Rows) return [];
|
|
367
|
+
|
|
368
|
+
props.Field.Options.Rows.sort((a, b) => (Number(a.auto__index) || 0) - (Number(b.auto__index) || 0));
|
|
369
|
+
return props.Field.Options.Rows;
|
|
370
|
+
}),
|
|
362
371
|
}
|
|
363
372
|
},
|
|
364
373
|
});
|
|
@@ -37,6 +37,17 @@ export default defineComponent({
|
|
|
37
37
|
Label: '最大长度',
|
|
38
38
|
Name: 'Options.MaxLength',
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
Type: 'Number',
|
|
42
|
+
Label: '基数',
|
|
43
|
+
Name: 'Options.BaseNum',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
Type: 'Boolean',
|
|
47
|
+
Label: '只允许整数',
|
|
48
|
+
Name: 'Options.IntegerOnly',
|
|
49
|
+
Default: false,
|
|
50
|
+
},
|
|
40
51
|
{
|
|
41
52
|
Type: 'DynamicList',
|
|
42
53
|
Label: '附加字段',
|
|
@@ -118,7 +129,7 @@ export default defineComponent({
|
|
|
118
129
|
|
|
119
130
|
const readonlyNode = () => h(ReadonlyContent, {
|
|
120
131
|
Field: props.Field,
|
|
121
|
-
Content: fieldData.value,
|
|
132
|
+
Content: props.Field.Options?.BaseNum ? (Number(props.Field.Options?.BaseNum || 0) + Number(fieldData.value || 0)) : fieldData.value,
|
|
122
133
|
});
|
|
123
134
|
|
|
124
135
|
const before = () => h(freeFieldLabel, {
|
|
@@ -133,8 +144,21 @@ export default defineComponent({
|
|
|
133
144
|
class: 'postfix',
|
|
134
145
|
}, props.Field.Options?.Postfix));
|
|
135
146
|
|
|
147
|
+
const mask = computed(() => {
|
|
148
|
+
if (!props.Field?.Options) return undefined;
|
|
149
|
+
|
|
150
|
+
if (props.Field.Options.IntegerOnly) {
|
|
151
|
+
const ll = props.Field.Options.MaxLength || 15;
|
|
152
|
+
console.log('mask', Array.from({length: ll}).map(() => '#').join(''))
|
|
153
|
+
return Array.from({length: ll}).map(() => '#').join('');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return undefined;
|
|
157
|
+
});
|
|
158
|
+
|
|
136
159
|
const inputNode = computed(() => h(QInput, {
|
|
137
|
-
type: 'number',
|
|
160
|
+
type: mask.value ? 'text' : 'number',
|
|
161
|
+
mask,
|
|
138
162
|
maxlength: props.Field.Options?.MaxLength,
|
|
139
163
|
autocomplete: 'off',
|
|
140
164
|
// bottomSlots: true,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
:readonly="Field.ReadOnly"
|
|
18
18
|
:placeholder="$attrs.placeholder || $t(getModule('field-components').config['defaultInputFieldPlaceholder'])"
|
|
19
19
|
hide-bottom-space
|
|
20
|
-
@
|
|
20
|
+
@update:modelValue="rangeChanged"
|
|
21
21
|
type="number"
|
|
22
22
|
v-model.number="range.min"
|
|
23
23
|
:ref="`input_field_validator_${Field.Name || Field.Label}`"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
:readonly="Field.ReadOnly"
|
|
44
44
|
:placeholder="$attrs.placeholder || $t(getModule('field-components').config['defaultInputFieldPlaceholder'])"
|
|
45
45
|
hide-bottom-space
|
|
46
|
-
@
|
|
46
|
+
@update:modelValue="rangeChanged"
|
|
47
47
|
type="number"
|
|
48
48
|
v-model.number="range.max"
|
|
49
49
|
:ref="`input_field_validator_${Field.Name || Field.Label}2`"
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="free-field-row row" :class="rowClasses" v-if="Field">
|
|
3
3
|
<free-field
|
|
4
|
-
v-for="(field, idx) in Field.Options?.
|
|
4
|
+
v-for="(field, idx) in Field.Options?.Fields"
|
|
5
5
|
:Field="field"
|
|
6
6
|
:values="fieldData"
|
|
7
7
|
:key="idx"
|
|
8
|
-
|
|
8
|
+
ref="fieldsToValidate"
|
|
9
|
+
@input="$emit('input', field)"></free-field>
|
|
9
10
|
</div>
|
|
10
11
|
</template>
|
|
11
12
|
|
|
12
13
|
<script>
|
|
14
|
+
// TODO: correct the validations
|
|
13
15
|
import { defineComponent } from 'vue';
|
|
14
16
|
import { freeFieldProps } from '../composible/useFreeField';
|
|
17
|
+
import { useFormValidator} from '../../composible/useFormValidator';
|
|
15
18
|
|
|
16
19
|
export default defineComponent({
|
|
17
20
|
name: 'InputFieldRow',
|
|
@@ -80,7 +83,7 @@ export default defineComponent({
|
|
|
80
83
|
},
|
|
81
84
|
{
|
|
82
85
|
Label: '字段',
|
|
83
|
-
Name: 'Options.
|
|
86
|
+
Name: 'Options.Fields',
|
|
84
87
|
Type: 'FieldList',
|
|
85
88
|
Options: {
|
|
86
89
|
Columns: [
|
|
@@ -117,6 +120,15 @@ export default defineComponent({
|
|
|
117
120
|
],
|
|
118
121
|
Description: '',
|
|
119
122
|
},
|
|
123
|
+
setup(props) {
|
|
124
|
+
if(!props.Field) return () => null;
|
|
125
|
+
|
|
126
|
+
const { validate } = useFormValidator('fieldsToValidate');
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
validate,
|
|
130
|
+
}
|
|
131
|
+
},
|
|
120
132
|
computed: {
|
|
121
133
|
rowClasses() {
|
|
122
134
|
return this.Field.Options?.NoWrap ? 'nowrap' : '' + this.Field.Options?.ItemsAlign + ' ' + this.Field.Options?.JustifyAlign;
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
hide-bottom-space
|
|
48
48
|
:modelValue="fieldData.value"
|
|
49
49
|
@update:modelValue="selectChanged"
|
|
50
|
-
:options="
|
|
50
|
+
:options="localOptions"
|
|
51
51
|
option-value="Value"
|
|
52
52
|
option-label="Label"
|
|
53
53
|
map-options
|
|
@@ -56,8 +56,9 @@
|
|
|
56
56
|
:multiple="Field.Multiple"
|
|
57
57
|
:readonly="Field.ReadOnly"
|
|
58
58
|
ref="fieldToValid"
|
|
59
|
-
:use-input="Field && Field.UseInput"
|
|
60
|
-
|
|
59
|
+
:use-input="Field && (Field.UseInput || (Field.Info?.CanFilter))"
|
|
60
|
+
@filter="filterFunc"
|
|
61
|
+
:use-chips="Field && (Field.UseChip || (Field.Info && Field.Info.Chip))"
|
|
61
62
|
v-bind="inputControlSettings"
|
|
62
63
|
:rules="Field.Rules"
|
|
63
64
|
>
|
|
@@ -147,7 +148,7 @@
|
|
|
147
148
|
v-model="checked"
|
|
148
149
|
:val="option.Value"
|
|
149
150
|
:disable="Field.ReadOnly"
|
|
150
|
-
@
|
|
151
|
+
@update:modelValue="checkChanged(option.Value)"
|
|
151
152
|
></q-checkbox>
|
|
152
153
|
</div>
|
|
153
154
|
</span>
|
|
@@ -156,7 +157,7 @@
|
|
|
156
157
|
</template>
|
|
157
158
|
|
|
158
159
|
<script>
|
|
159
|
-
import { ref, computed, defineComponent, getCurrentInstance,
|
|
160
|
+
import { ref, computed, defineComponent, getCurrentInstance, watchEffect } from 'vue';
|
|
160
161
|
import { useFreeField, freeFieldProps } from '../composible/useFreeField';
|
|
161
162
|
import { useFormValidator} from '../../composible/useFormValidator';
|
|
162
163
|
|
|
@@ -187,6 +188,16 @@ export default defineComponent({
|
|
|
187
188
|
Label: '可多选',
|
|
188
189
|
Name: 'Multiple',
|
|
189
190
|
},
|
|
191
|
+
{
|
|
192
|
+
Type: 'Check',
|
|
193
|
+
Label: '显示为碎屑',
|
|
194
|
+
Name: 'Info.Chip',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
Type: 'Check',
|
|
198
|
+
Label: '可筛选',
|
|
199
|
+
Name: 'Info.CanFilter',
|
|
200
|
+
},
|
|
190
201
|
{
|
|
191
202
|
Type: 'String',
|
|
192
203
|
Name: 'Info.Url',
|
|
@@ -287,7 +298,7 @@ export default defineComponent({
|
|
|
287
298
|
});
|
|
288
299
|
|
|
289
300
|
|
|
290
|
-
|
|
301
|
+
watchEffect(() => {
|
|
291
302
|
if (props.Field.AsCheck) {
|
|
292
303
|
if (fieldData.value) {
|
|
293
304
|
checked.value = `${fieldData.value}`.split(',');
|
|
@@ -380,9 +391,12 @@ export default defineComponent({
|
|
|
380
391
|
}
|
|
381
392
|
});
|
|
382
393
|
|
|
394
|
+
const localOptions = ref(props.Field.Options || []);
|
|
395
|
+
|
|
383
396
|
return {
|
|
384
397
|
fieldData,
|
|
385
398
|
setFieldData,
|
|
399
|
+
localOptions,
|
|
386
400
|
|
|
387
401
|
hasError,
|
|
388
402
|
checked,
|
|
@@ -395,6 +409,23 @@ export default defineComponent({
|
|
|
395
409
|
selectChanged,
|
|
396
410
|
checkChanged,
|
|
397
411
|
inputControlSettings,
|
|
412
|
+
|
|
413
|
+
filterFunc: (val, update) => {
|
|
414
|
+
if (val === '') {
|
|
415
|
+
update(() => {
|
|
416
|
+
localOptions.value = this.Field.Options || [];
|
|
417
|
+
})
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
update(() => {
|
|
422
|
+
const needle = val.toLowerCase();
|
|
423
|
+
|
|
424
|
+
localOptions.value = (this.Field.Options || []).filter(opt => {
|
|
425
|
+
return `${opt.Label || opt.Value || opt}`.toLowerCase().indexOf(needle) > -1;
|
|
426
|
+
});
|
|
427
|
+
})
|
|
428
|
+
},
|
|
398
429
|
};
|
|
399
430
|
},
|
|
400
431
|
});
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
v-for="(t, idx) in fieldData.value" :key="idx"
|
|
38
38
|
:name="idx">
|
|
39
39
|
<free-field
|
|
40
|
-
v-for="(field, idx) in Field.Options?.
|
|
40
|
+
v-for="(field, idx) in Field.Options?.Fields"
|
|
41
41
|
:Field="field"
|
|
42
42
|
:values="t"
|
|
43
43
|
:key="idx"
|
|
44
44
|
ref="fieldsToValidate"
|
|
45
|
-
@input="fieldChanged"></free-field>
|
|
45
|
+
@input="fieldChanged(field)"></free-field>
|
|
46
46
|
</q-tab-panel>
|
|
47
47
|
</q-tab-panels>
|
|
48
48
|
</div>
|
|
@@ -74,7 +74,7 @@ export default defineComponent({
|
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
Label: '字段',
|
|
77
|
-
Name: 'Options.
|
|
77
|
+
Name: 'Options.Fields',
|
|
78
78
|
Type: 'FieldList',
|
|
79
79
|
Options: {
|
|
80
80
|
Columns: [
|
|
@@ -27,6 +27,7 @@ export default defineComponent({
|
|
|
27
27
|
setup(props, { emit, slots, expose, attrs }){
|
|
28
28
|
if (!props.Field) return {};
|
|
29
29
|
|
|
30
|
+
const { proxy:vm } = getCurrentInstance();
|
|
30
31
|
const { fieldData, setFieldData, inputControlSettings } = useFreeField(props);
|
|
31
32
|
|
|
32
33
|
const rows = ref(3);
|
|
@@ -54,6 +55,7 @@ export default defineComponent({
|
|
|
54
55
|
rows: rows.value,
|
|
55
56
|
|
|
56
57
|
...inputControlSettings.value,
|
|
58
|
+
placeholder: props.Field?.Placeholder || attrs.placeholder || vm.$t(vm.getModule('core-modules').config['defaultInputFieldPlaceholder']),
|
|
57
59
|
|
|
58
60
|
class: 'full-width',
|
|
59
61
|
style: props.Field.Info?.Style,
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
</span>
|
|
14
14
|
<q-input v-else v-model="fieldData.value" hide-bottom-space
|
|
15
15
|
:readonly="Field.ReadOnly"
|
|
16
|
-
@
|
|
16
|
+
@update:modelValue="$emit('input')"
|
|
17
17
|
v-bind="inputControlSettings"
|
|
18
18
|
ref="fieldToValid">
|
|
19
19
|
<template v-slot:before v-if="Field.Label !== void 0">
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
hide-bottom-space
|
|
19
19
|
:options="minYearOptions"
|
|
20
20
|
:readonly="Field.ReadOnly"
|
|
21
|
-
@
|
|
21
|
+
@update:modelValue="rangeChanged"
|
|
22
22
|
v-bind="inputControlSettings"
|
|
23
23
|
ref="input_field_validator_first"
|
|
24
24
|
>
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
hide-bottom-space
|
|
40
40
|
:options="maxYearOptions"
|
|
41
41
|
:readonly="Field.ReadOnly"
|
|
42
|
-
@
|
|
42
|
+
@update:modelValue="rangeChanged"
|
|
43
43
|
v-bind="inputControlSettings"
|
|
44
44
|
ref="input_field_validator_second"
|
|
45
45
|
/>
|
|
@@ -146,12 +146,13 @@ export function useUploader(props, ctx) {
|
|
|
146
146
|
zip: 'application/zip',
|
|
147
147
|
};
|
|
148
148
|
|
|
149
|
-
extList.forEach((ext) => {
|
|
149
|
+
extList.forEach((ext = '') => {
|
|
150
|
+
if (!ext) return;
|
|
150
151
|
let type = ext.trim().toLowerCase();
|
|
151
|
-
type = MIME_TYPE_LIST[type]
|
|
152
|
+
type = MIME_TYPE_LIST[type];
|
|
152
153
|
|
|
153
|
-
if (type && typeList.indexOf(type) < 0) typeList.push(type);
|
|
154
|
-
if (ext && typeList.indexOf(ext) < 0) typeList.push(ext);
|
|
154
|
+
if (!ext.startsWith('.') && type && typeList.indexOf(type) < 0) typeList.push(type);
|
|
155
|
+
if (ext.startsWith('.') && typeList.indexOf(ext) < 0) typeList.push(ext);
|
|
155
156
|
});
|
|
156
157
|
|
|
157
158
|
return typeList.join(',');
|
package/index.js
CHANGED
|
@@ -53,10 +53,23 @@ const filters = {
|
|
|
53
53
|
case '.png':
|
|
54
54
|
case '.jpeg':
|
|
55
55
|
case '.bmp':
|
|
56
|
+
case '.gif':
|
|
56
57
|
return `${config.imageUrlBase}${url}`;
|
|
57
58
|
case '.zip':
|
|
59
|
+
case '.rar':
|
|
60
|
+
case '.7z':
|
|
61
|
+
case '.tar':
|
|
62
|
+
case '.gz':
|
|
63
|
+
case '.bz2':
|
|
64
|
+
case '.xz':
|
|
65
|
+
case '.tgz':
|
|
58
66
|
return `${config.zipUrlBase}${url}`;
|
|
59
67
|
case '.mp4':
|
|
68
|
+
case '.avi':
|
|
69
|
+
case '.mov':
|
|
70
|
+
case '.wmv':
|
|
71
|
+
case '.flv':
|
|
72
|
+
case '.mkv':
|
|
60
73
|
return `${config.videoUrlBase}${url}`;
|
|
61
74
|
default:
|
|
62
75
|
return `${config.documentUrlBase}${url}`;
|
|
@@ -210,9 +223,12 @@ export default (app, root) => {
|
|
|
210
223
|
Type: 'Tabs',
|
|
211
224
|
Label: '显示内容',
|
|
212
225
|
DataType: 'Array',
|
|
213
|
-
Default:
|
|
214
|
-
Locale:
|
|
215
|
-
|
|
226
|
+
Default: config.locales.map((l) => ({
|
|
227
|
+
Locale: l.locale,
|
|
228
|
+
Name: l.name,
|
|
229
|
+
Label: '',
|
|
230
|
+
Description: '',
|
|
231
|
+
})),
|
|
216
232
|
Options: {
|
|
217
233
|
Dense: true,
|
|
218
234
|
LabelField: 'Name',
|
package/package.json
CHANGED
package/view/dict/index.vue
CHANGED
|
@@ -205,13 +205,21 @@ export default defineComponent({
|
|
|
205
205
|
},
|
|
206
206
|
addNode(n) {
|
|
207
207
|
if (this.selectedDictNode && this.selectedDictNode.id === n.id) {
|
|
208
|
+
// collapse the node when clicking it again (after clicking add button)
|
|
208
209
|
this.selectedDictNode = {};
|
|
209
210
|
this.editingDict = {};
|
|
210
211
|
this.$refs.dictTree.setExpanded(n.id, false);
|
|
211
212
|
} else {
|
|
213
|
+
// add new node
|
|
212
214
|
this.selectedDictNode = n;
|
|
213
215
|
this.editingDict = {
|
|
214
216
|
Type: 'String',
|
|
217
|
+
Labels: this.ctx.config.locales.map((l) => ({
|
|
218
|
+
Label: '',
|
|
219
|
+
Locale: l.locale,
|
|
220
|
+
Description: '',
|
|
221
|
+
Name: l.name,
|
|
222
|
+
})),
|
|
215
223
|
};
|
|
216
224
|
}
|
|
217
225
|
|
|
@@ -223,10 +231,31 @@ export default defineComponent({
|
|
|
223
231
|
this.makeLabelsName(n);
|
|
224
232
|
|
|
225
233
|
if (this.selectedDictNode && this.selectedDictNode.id === n.id) {
|
|
234
|
+
// collapse the node when clicking it again (after clicking edit button)
|
|
226
235
|
this.selectedDictNode = {};
|
|
227
236
|
this.editingDict = {};
|
|
228
237
|
this.$refs.dictTree.setExpanded(n.id, false);
|
|
229
238
|
} else {
|
|
239
|
+
// edit node
|
|
240
|
+
n.Labels = n.Labels || [];
|
|
241
|
+
// check labels according to the locales
|
|
242
|
+
const locales = this.ctx.config.locales || [];
|
|
243
|
+
for(let i = 0; i < locales.length; i += 1) {
|
|
244
|
+
const locale = locales[i];
|
|
245
|
+
const existsLabel = n.Labels.find((l) => l.Locale === locale.locale);
|
|
246
|
+
|
|
247
|
+
if (!existsLabel) {
|
|
248
|
+
n.Labels.push({
|
|
249
|
+
Label: '',
|
|
250
|
+
Locale: locale.locale,
|
|
251
|
+
Description: '',
|
|
252
|
+
Name: locale.name,
|
|
253
|
+
});
|
|
254
|
+
} else {
|
|
255
|
+
existsLabel.Name = locale.name;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
230
259
|
this.selectedDictNode = n;
|
|
231
260
|
this.editingDict = { ...n };
|
|
232
261
|
this.$refs.dictTree.setExpanded(n.id, true);
|
|
@@ -235,9 +264,12 @@ export default defineComponent({
|
|
|
235
264
|
deleteNode(n) {
|
|
236
265
|
if (n.addingNew || !n.id) return;
|
|
237
266
|
|
|
267
|
+
let label = (n.Labels || []).find((l) => l.Locale === this.$i18n.locale);
|
|
268
|
+
label = label && label.Label;
|
|
269
|
+
|
|
238
270
|
this.$MsgDialog({
|
|
239
271
|
type: '',
|
|
240
|
-
content: this.$t('删除确认', { type: this.$t('字典项'), name: n.Name }),
|
|
272
|
+
content: this.$t('删除确认', { type: this.$t('字典项'), name: label || n.Name }),
|
|
241
273
|
canCancel: true,
|
|
242
274
|
okText: this.$t('okButtonText'),
|
|
243
275
|
cancelText: this.$t('cancelButtonText'),
|
|
@@ -245,7 +277,12 @@ export default defineComponent({
|
|
|
245
277
|
.then(() => {
|
|
246
278
|
this.deleteDict(n.id).then((d) => {
|
|
247
279
|
if (d && d.msg === 'OK') {
|
|
248
|
-
this.
|
|
280
|
+
const parentNode = this.$refs.dictTree.getNodeByKey(n.Parent);
|
|
281
|
+
if (parentNode) {
|
|
282
|
+
parentNode.children = parentNode.children.filter((c) => c.id !== n.id);
|
|
283
|
+
} else {
|
|
284
|
+
this.data.docs = this.data.docs.filter((c) => c.id !== n.id);
|
|
285
|
+
}
|
|
249
286
|
}
|
|
250
287
|
});
|
|
251
288
|
})
|