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.
- package/README.md +7 -0
- package/components/.gitkeep +0 -0
- package/components/Basic/BreadCrumbs.vue +87 -0
- package/components/Basic/EIcon.vue +84 -0
- package/components/Basic/LeveledMenus.vue +92 -0
- package/components/Basic/SummaryHead.vue +312 -0
- package/components/Dialog/BasicDialog.vue +442 -0
- package/components/Dialog/index.js +38 -0
- package/components/Dialog/index1.js +49 -0
- package/components/FloatingWindow/index.vue +140 -0
- package/components/SelectLocales/index.vue +47 -0
- package/components/SlidingCarousel/index.vue +86 -0
- package/components/SlidingNews/index.vue +138 -0
- package/components/StickyButtons/index.vue +98 -0
- package/components/ThemeSwitch/index.vue +77 -0
- package/field-components/Display/index.js +3 -0
- package/field-components/Fields/AgreementCheck.vue +161 -0
- package/field-components/Fields/ApiCall.vue +139 -0
- package/field-components/Fields/Boolean.vue +112 -0
- package/field-components/Fields/Category.vue +33 -0
- package/field-components/Fields/Check.vue +131 -0
- package/field-components/Fields/Customize.vue +103 -0
- package/field-components/Fields/Date.vue +142 -0
- package/field-components/Fields/DateRange.vue +199 -0
- package/field-components/Fields/DynamicList.vue +575 -0
- package/field-components/Fields/FieldEditor.vue +379 -0
- package/field-components/Fields/File.vue +382 -0
- package/field-components/Fields/FileList.vue +405 -0
- package/field-components/Fields/FileListCombined.vue +142 -0
- package/field-components/Fields/FixedList.vue +372 -0
- package/field-components/Fields/Image.vue +328 -0
- package/field-components/Fields/ImageList.vue +285 -0
- package/field-components/Fields/ImageListCombined.vue +76 -0
- package/field-components/Fields/InputFieldList.vue +299 -0
- package/field-components/Fields/Labels.vue +182 -0
- package/field-components/Fields/MixedTable.vue +367 -0
- package/field-components/Fields/Number.vue +247 -0
- package/field-components/Fields/Password.vue +79 -0
- package/field-components/Fields/Permission.vue +83 -0
- package/field-components/Fields/PermissionEditor.vue +205 -0
- package/field-components/Fields/QueryFilters.vue +162 -0
- package/field-components/Fields/RadioList.vue +81 -0
- package/field-components/Fields/Rich.vue +369 -0
- package/field-components/Fields/Search.vue +499 -0
- package/field-components/Fields/Select.vue +376 -0
- package/field-components/Fields/SelectionChain.vue +198 -0
- package/field-components/Fields/Separator.vue +26 -0
- package/field-components/Fields/SingleList.vue +125 -0
- package/field-components/Fields/Static.vue +22 -0
- package/field-components/Fields/String.vue +185 -0
- package/field-components/Fields/Text.vue +89 -0
- package/field-components/Fields/Time.vue +160 -0
- package/field-components/Fields/TimeRange.vue +348 -0
- package/field-components/Fields/UltimateFile.vue +100 -0
- package/field-components/Fields/Year.vue +124 -0
- package/field-components/Fields/YearRange.vue +188 -0
- package/field-components/Fields/components/FieldTypeOptions.vue +248 -0
- package/field-components/Fields/index.js +117 -0
- package/field-components/components/FieldComponents.vue +246 -0
- package/field-components/index.js +13 -0
- package/field-components/style.sass +11 -0
- package/free-fields/AutoHide.js +66 -0
- package/free-fields/CenterContent.js +15 -0
- package/free-fields/Draggable.js +30 -0
- package/free-fields/Droppable.js +114 -0
- package/free-fields/EditableString.js +63 -0
- package/free-fields/FieldCategory.js +83 -0
- package/free-fields/FieldTypeSelect.js +94 -0
- package/free-fields/fieldEditors/arrayEditor.js +3 -0
- package/free-fields/fieldEditors/boolEditor.js +22 -0
- package/free-fields/fieldEditors/dateEditor.js +23 -0
- package/free-fields/fieldEditors/datetimeEditor.js +23 -0
- package/free-fields/fieldEditors/index.js +21 -0
- package/free-fields/fieldEditors/jsonEditor.js +371 -0
- package/free-fields/fieldEditors/labeledField.js +74 -0
- package/free-fields/fieldEditors/numberEditor.js +51 -0
- package/free-fields/fieldEditors/objectEditor.js +3 -0
- package/free-fields/fieldEditors/selectEditor.js +0 -0
- package/free-fields/fieldEditors/stringEditor.js +49 -0
- package/free-fields/fieldEditors/textEditor.js +50 -0
- package/free-fields/fieldEditors/timeEditor.js +23 -0
- package/free-fields/index.js +402 -0
- package/i18n/en-us/index.js +73 -0
- package/i18n/fields/en-us/index.js +9 -0
- package/i18n/fields/zh-cn/index.js +9 -0
- package/i18n/zh-cn/index.js +73 -0
- package/index.js +367 -0
- package/package.json +11 -0
- package/router/dict/api.js +18 -0
- package/router/dict/data.js +48 -0
- package/router/dict/index.js +7 -0
- package/router/error/api.js +14 -0
- package/router/error/data.js +33 -0
- package/router/error/index.js +9 -0
- package/router/index.js +13 -0
- package/router/menu/api.js +24 -0
- package/router/menu/data.js +85 -0
- package/router/menu/index.js +7 -0
- package/router/system/api.js +10 -0
- package/router/system/data.js +46 -0
- package/router/system/index.js +7 -0
- package/stores/index.js +17 -0
- package/stores/module-mourning/actions.js +3 -0
- package/stores/module-mourning/getters.js +1 -0
- package/stores/module-mourning/index.js +11 -0
- package/stores/module-mourning/state.js +3 -0
- package/stores/mourning.js +3 -0
- package/view/dict/index.vue +284 -0
- package/view/error/list.vue +197 -0
- package/view/menu/index.vue +332 -0
- package/view/mourning/mourning.vue +45 -0
- package/view/system/index.vue +149 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-if="Field"
|
|
4
|
+
:class="`free-field-wrapper ${localField.Label
|
|
5
|
+
&& localField.Label.trim().length ? 'with-label'
|
|
6
|
+
: 'without-label'} ${Field.Label ?
|
|
7
|
+
'free-field-wrapper-'+Field.Label : ''} ${Field.Name ?
|
|
8
|
+
'free-field-wrapper-'+dashedName : ''} ${(Field && Field.Info)
|
|
9
|
+
? (Field.Info.Classes || '') : ''}`"
|
|
10
|
+
>
|
|
11
|
+
<component
|
|
12
|
+
:style="shouldHide ? 'display: none;' : ''"
|
|
13
|
+
:is="realComp"
|
|
14
|
+
:Field="localField"
|
|
15
|
+
:modelValue="data"
|
|
16
|
+
:ref="`input_field_validator_${localField.Name || localField.Label}`"
|
|
17
|
+
:class="[
|
|
18
|
+
(localField && localField.ReadOnly) ? 'free-field--readonly' : '',
|
|
19
|
+
(!shouldHide && hasError) ? 'hasError' : ''
|
|
20
|
+
]"
|
|
21
|
+
@input="inputChanged"
|
|
22
|
+
v-bind="Object.assign({},vBindValue(localField), $attrs)"
|
|
23
|
+
>
|
|
24
|
+
<template
|
|
25
|
+
v-for="slt in ((Field && Field.Slots) || [])"
|
|
26
|
+
v-slot:[slt]="props"
|
|
27
|
+
>
|
|
28
|
+
<slot :name="slt" v-bind="props"></slot>
|
|
29
|
+
</template>
|
|
30
|
+
</component>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
import { defineComponent, markRaw } from 'vue';
|
|
36
|
+
import mixins from 'free-fe-mixins';
|
|
37
|
+
|
|
38
|
+
// TODO: any other solution to replace the eval??
|
|
39
|
+
const evalFunc = (cond, pName = 'data') => {
|
|
40
|
+
const funcStr = `
|
|
41
|
+
(${pName}) => {
|
|
42
|
+
return ${cond};
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
// eslint-disable-next-line no-eval
|
|
48
|
+
return eval(funcStr);
|
|
49
|
+
} catch (ex) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default defineComponent({
|
|
55
|
+
name: 'FreeField',
|
|
56
|
+
mixins: [mixins.ObjectDataMixin, mixins.InputFieldValidator],
|
|
57
|
+
emits: ['input'],
|
|
58
|
+
props: {
|
|
59
|
+
Field: { type: Object },
|
|
60
|
+
},
|
|
61
|
+
data() {
|
|
62
|
+
return {
|
|
63
|
+
realComp: undefined,
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
computed: {
|
|
67
|
+
dashedName() {
|
|
68
|
+
return (this.Field.Name || '').replace(/\./g, '-');
|
|
69
|
+
},
|
|
70
|
+
shouldHide() {
|
|
71
|
+
if (!this.Field) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// show when
|
|
76
|
+
if (this.Field.Info && this.Field.Info.ShowWhen) {
|
|
77
|
+
const theFunc = evalFunc(this.Field.Info.ShowWhen);
|
|
78
|
+
if (typeof theFunc !== 'function') {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
const condResult = theFunc(this.data);
|
|
82
|
+
if (!condResult) return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// hide (when)
|
|
86
|
+
if (this.Field.Hidden
|
|
87
|
+
&& this.Field.Info
|
|
88
|
+
&& this.Field.Info.HideWhenUndefined) {
|
|
89
|
+
const checkField = this.Field.Info.HideWhenUndefinedField || this.Field.Name;
|
|
90
|
+
if (checkField) {
|
|
91
|
+
const fList = checkField.split(',');
|
|
92
|
+
for (let i = 0; i < fList.length; i += 1) {
|
|
93
|
+
const fl = fList[i];
|
|
94
|
+
|
|
95
|
+
const flv = Object.nestValue(this.data, fl.trim());
|
|
96
|
+
if (typeof flv === 'undefined') return true;
|
|
97
|
+
|
|
98
|
+
if (this.Field.Info.IncludeEmptyObject) {
|
|
99
|
+
return !Object.hasValue(flv);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return this.Field.Hidden;
|
|
107
|
+
},
|
|
108
|
+
localField() {
|
|
109
|
+
const rules = [];
|
|
110
|
+
const lField = { ...this.Field };
|
|
111
|
+
lField.Rules = lField.Rules || [];
|
|
112
|
+
for (let i = 0; i < lField.Rules.length; i += 1) {
|
|
113
|
+
const rule = lField.Rules[i];
|
|
114
|
+
|
|
115
|
+
if (typeof rule === 'string' && this.ctx.validators[rule] && this.ctx.validators[rule].validator) {
|
|
116
|
+
lField.Rules[i] = this.ctx.validators[rule].validator;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (lField.Required) {
|
|
121
|
+
rules.push(val => typeof val !== 'undefined' && val !== '');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
lField.rules = [].concat(this.Field.Rules).concat(rules).concat(lField.rules);
|
|
125
|
+
|
|
126
|
+
return lField;
|
|
127
|
+
},
|
|
128
|
+
vBindValue() {
|
|
129
|
+
return (d) => {
|
|
130
|
+
if (!d || typeof d !== 'object') return {};
|
|
131
|
+
|
|
132
|
+
const ret = {};
|
|
133
|
+
Object.keys(d).forEach((dk) => {
|
|
134
|
+
if (!dk) return;
|
|
135
|
+
|
|
136
|
+
if (
|
|
137
|
+
dk.charAt(0) === dk.charAt(0).toLowerCase()
|
|
138
|
+
|| ['Placeholder', 'ReadOnly'].indexOf(dk) >= 0
|
|
139
|
+
) {
|
|
140
|
+
switch (dk) {
|
|
141
|
+
case 'Placeholder':
|
|
142
|
+
ret.placeholder = d[dk];
|
|
143
|
+
break;
|
|
144
|
+
case 'ReadOnly':
|
|
145
|
+
ret.readonly = d[dk];
|
|
146
|
+
break;
|
|
147
|
+
default:
|
|
148
|
+
ret[dk] = d[dk];
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
return ret;
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
watch: {
|
|
159
|
+
// eslint-disable-next-line func-names
|
|
160
|
+
'Field.Type': function (nv) {
|
|
161
|
+
if (!this.realComp || this.realComp.name !== nv) {
|
|
162
|
+
this.getRRealComp();
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
created() {
|
|
167
|
+
this.getRRealComp();
|
|
168
|
+
|
|
169
|
+
if (this.Field && this.Field.Info && this.Field.Info.KeepChanged) {
|
|
170
|
+
this.$nextTick(() => {
|
|
171
|
+
this.$emit('input', this.Field);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
methods: {
|
|
176
|
+
getRRealComp() {
|
|
177
|
+
// all components
|
|
178
|
+
const fComponents = this.ctx ? this.ctx.FieldComponents || {} : {};
|
|
179
|
+
let field;
|
|
180
|
+
|
|
181
|
+
// for some specified types
|
|
182
|
+
if (this.Field.Component) {
|
|
183
|
+
field = this.Field.Component;
|
|
184
|
+
} else if (this.Field.Type === 'Select' && this.Field.AsRadio) {
|
|
185
|
+
field = fComponents.RadioList;
|
|
186
|
+
} else {
|
|
187
|
+
if(typeof this.Field.Type === 'undefined') {
|
|
188
|
+
field = fComponents.String;
|
|
189
|
+
} else {
|
|
190
|
+
field = fComponents[this.Field.Type] || this.Field.Type;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
this.realComp = markRaw(field);
|
|
195
|
+
// return field;
|
|
196
|
+
},
|
|
197
|
+
inputChanged(f) {
|
|
198
|
+
this.$emit('input', f || this.Field);
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
</script>
|
|
203
|
+
|
|
204
|
+
<style lang="sass">
|
|
205
|
+
@import '../style.sass'
|
|
206
|
+
|
|
207
|
+
.free-field-wrapper
|
|
208
|
+
width: 100%
|
|
209
|
+
.free-field-wrapper
|
|
210
|
+
width: unset
|
|
211
|
+
.simple-field
|
|
212
|
+
// display: inline-block
|
|
213
|
+
width: 100%
|
|
214
|
+
.free-field-range-separator
|
|
215
|
+
margin: 0 6px
|
|
216
|
+
.field-label-empty
|
|
217
|
+
display: inline-block
|
|
218
|
+
margin-left: 0
|
|
219
|
+
padding-left: 0
|
|
220
|
+
width: $fieldLabelWidth
|
|
221
|
+
min-width: $fieldLabelWidth
|
|
222
|
+
|
|
223
|
+
.field-label
|
|
224
|
+
display: inline-block
|
|
225
|
+
margin-left: 0
|
|
226
|
+
padding-left: 0
|
|
227
|
+
font-size: $fieldLabelFontSize
|
|
228
|
+
width: $fieldLabelWidth
|
|
229
|
+
min-width: $fieldLabelWidth
|
|
230
|
+
color: $fieldLabelColor
|
|
231
|
+
text-align: right
|
|
232
|
+
white-space: normal
|
|
233
|
+
|
|
234
|
+
.field-label:after
|
|
235
|
+
content: $fieldLabelAfter
|
|
236
|
+
|
|
237
|
+
.required-mark
|
|
238
|
+
color: $fieldLabelRequiredColor
|
|
239
|
+
position: relative
|
|
240
|
+
top: 3px
|
|
241
|
+
|
|
242
|
+
.q-uploader
|
|
243
|
+
flex: 1
|
|
244
|
+
box-shadow: unset
|
|
245
|
+
|
|
246
|
+
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
$inputFieldCategoryMargin: var(--input-field-category-margin, unset)
|
|
2
|
+
$inputFieldWrapperMargin: var(--input-field-wrapper-margin, unset)
|
|
3
|
+
$inputFieldMargin: var(--input-field-margin, unset)
|
|
4
|
+
$simpleFieldHeight: var(--simple-field-height, unset)
|
|
5
|
+
$simpleFieldWidth: var(--simple-field-width, 100%)
|
|
6
|
+
$fieldLabelWidth: var(--field-label-width,120px)
|
|
7
|
+
$fieldLabelFontSize: var(--field-label-font-size,12px)
|
|
8
|
+
$fieldLabelColor: var(--field-label-color,unset)
|
|
9
|
+
$fieldLabelAfter: var(--field-label-after,'')
|
|
10
|
+
$fieldLabelRequiredColor: var(--field-label-required-color,#E33)
|
|
11
|
+
$editorAreaBackground: var(--editor-area-background, unset)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineComponent,
|
|
3
|
+
h,
|
|
4
|
+
ref,
|
|
5
|
+
computed,
|
|
6
|
+
nextTick,
|
|
7
|
+
} from "vue";
|
|
8
|
+
import { QIcon } from 'quasar';
|
|
9
|
+
|
|
10
|
+
export default defineComponent({
|
|
11
|
+
name: "FreeFieldAutoHide",
|
|
12
|
+
props: {
|
|
13
|
+
hideIcon: String,
|
|
14
|
+
vertical: Boolean,
|
|
15
|
+
size: String,
|
|
16
|
+
duration: Number
|
|
17
|
+
},
|
|
18
|
+
setup(props, { slots }) {
|
|
19
|
+
const hovered = ref(false);
|
|
20
|
+
const defaultIcon = props.vertical ? 'more_vert' : 'more_horiz';
|
|
21
|
+
const freez = ref(false);
|
|
22
|
+
|
|
23
|
+
const renderH = computed(() => {
|
|
24
|
+
if(hovered.value) {
|
|
25
|
+
return h('div', {
|
|
26
|
+
onMouseleave: () => {
|
|
27
|
+
if(freez.value) return;
|
|
28
|
+
|
|
29
|
+
nextTick(() => {
|
|
30
|
+
hovered.value = false;
|
|
31
|
+
freez.value = true;
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
onMousemove: () => {
|
|
35
|
+
nextTick(() => {
|
|
36
|
+
freez.value = false;
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
}, slots.default ? slots.default() : undefined);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return h(
|
|
43
|
+
QIcon,
|
|
44
|
+
{
|
|
45
|
+
name: props.hideIcon || defaultIcon,
|
|
46
|
+
size: props.size || 'md',
|
|
47
|
+
onMouseenter: () => {
|
|
48
|
+
if(freez.value) return;
|
|
49
|
+
|
|
50
|
+
nextTick(() => {
|
|
51
|
+
freez.value = true;
|
|
52
|
+
})
|
|
53
|
+
},
|
|
54
|
+
onMousemove: () => {
|
|
55
|
+
nextTick(() => {
|
|
56
|
+
hovered.value = true;
|
|
57
|
+
freez.value = false;
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return () => renderH.value;
|
|
65
|
+
},
|
|
66
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineComponent,
|
|
3
|
+
h,
|
|
4
|
+
} from "vue";
|
|
5
|
+
|
|
6
|
+
export default defineComponent({
|
|
7
|
+
name: "FreeFieldCenterContent",
|
|
8
|
+
setup(props, { slots }) {
|
|
9
|
+
return () => h('div', {
|
|
10
|
+
class: "relative-position full-height full-width"
|
|
11
|
+
}, h('div', {
|
|
12
|
+
class: "absolute-center"
|
|
13
|
+
}, slots.default ? slots.default() : undefined))
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { defineComponent, h } from 'vue';
|
|
2
|
+
|
|
3
|
+
export default defineComponent({
|
|
4
|
+
name: "FreeFieldDraggable",
|
|
5
|
+
props: {
|
|
6
|
+
dropEffect: String,
|
|
7
|
+
dataName: String,
|
|
8
|
+
data: {
|
|
9
|
+
default: ""
|
|
10
|
+
},
|
|
11
|
+
extra: Object
|
|
12
|
+
},
|
|
13
|
+
setup(props, { slots }){
|
|
14
|
+
const onDragstart = (e) => {
|
|
15
|
+
if(typeof props.data === 'object' && props.extra) {
|
|
16
|
+
e.dataTransfer.setData(props.dataName || "data", JSON.stringify(Array.isArray(props.data) ? [...props.data, ...props.extra] : {...props.data, ...props.extra}));
|
|
17
|
+
} else {
|
|
18
|
+
e.dataTransfer.setData(props.dataName || "data", JSON.stringify(props.data));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
e.dataTransfer.dropEffect = props.dropEffect;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return () => h('div', {
|
|
25
|
+
class: 'free-field-draggable',
|
|
26
|
+
draggable: true,
|
|
27
|
+
onDragstart,
|
|
28
|
+
}, slots.default ? slots.default() : undefined)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { defineComponent, h, ref } from 'vue';
|
|
2
|
+
|
|
3
|
+
export default defineComponent({
|
|
4
|
+
name: "FreeFieldDroppable",
|
|
5
|
+
props: {
|
|
6
|
+
exact: Boolean,
|
|
7
|
+
dataName: [String, Array],
|
|
8
|
+
notToDraggable: Boolean,
|
|
9
|
+
enterClass: String,
|
|
10
|
+
enterStyle: {
|
|
11
|
+
type: Object,
|
|
12
|
+
default: () => ({})
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
emits: ['freeTrigger', 'drop'],
|
|
16
|
+
setup(props, { emit, slots }){
|
|
17
|
+
const selfRef = ref(null);
|
|
18
|
+
const originalStyle = {};
|
|
19
|
+
|
|
20
|
+
const getTransferData = (e) => {
|
|
21
|
+
let dropData;
|
|
22
|
+
if(typeof props.dataName === 'string') {
|
|
23
|
+
dropData = e.dataTransfer.getData(props.dataName);
|
|
24
|
+
} else if(Array.isArray(props.dataName)) {
|
|
25
|
+
dropData = {};
|
|
26
|
+
for(let dn of props.dataName) {
|
|
27
|
+
const dd = e.dataTransfer.getData(dn);
|
|
28
|
+
|
|
29
|
+
if(dd) {
|
|
30
|
+
dropData = `{"${dn}": ${dd}}`
|
|
31
|
+
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
dropData = e.dataTransfer.getData('data')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return dropData || "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const onDragenter = (e) => {
|
|
43
|
+
if(props.exact && e.target !== selfRef.value) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Object.keys(props.enterStyle).forEach(sk => {
|
|
48
|
+
originalStyle[sk] = e.target.style[sk];
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (props.notToDraggable && e.target.draggable === true) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
e.target.classList.add(props.enterClass);
|
|
56
|
+
Object.keys(originalStyle).forEach(sk => {
|
|
57
|
+
e.target.style[sk] = props.enterStyle[sk];
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const onDragleave = (e) => {
|
|
62
|
+
if(props.exact && e.target !== selfRef.value) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
e.target.classList.remove(props.enterClass);
|
|
67
|
+
Object.keys(originalStyle).forEach(sk => {
|
|
68
|
+
e.target.style[sk] = originalStyle[sk];
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const onDragover = (e) => {
|
|
73
|
+
e.preventDefault()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const onDrop = (e) => {
|
|
77
|
+
if(props.exact && e.target !== selfRef.value) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
e.preventDefault()
|
|
82
|
+
|
|
83
|
+
// don't drop on other draggables
|
|
84
|
+
if (props.notToDraggable && e.target.draggable === true) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let dropData = getTransferData(e);
|
|
89
|
+
|
|
90
|
+
try{
|
|
91
|
+
dropData = dropData && JSON.parse(dropData);
|
|
92
|
+
} catch(_) {
|
|
93
|
+
dropData = "";
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if(dropData) {
|
|
97
|
+
emit('drop', dropData);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
e.target.classList.remove(props.enterClass);
|
|
101
|
+
Object.keys(originalStyle).forEach(sk => {
|
|
102
|
+
e.target.style[sk] = originalStyle[sk];
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return () => h('div', {
|
|
107
|
+
ref: selfRef,
|
|
108
|
+
onDragenter,
|
|
109
|
+
onDragleave,
|
|
110
|
+
onDragover,
|
|
111
|
+
onDrop,
|
|
112
|
+
}, slots.default ? slots.default() : undefined)
|
|
113
|
+
}
|
|
114
|
+
})
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineComponent,
|
|
3
|
+
h,
|
|
4
|
+
ref,
|
|
5
|
+
computed,
|
|
6
|
+
nextTick,
|
|
7
|
+
} from "vue";
|
|
8
|
+
|
|
9
|
+
export default defineComponent({
|
|
10
|
+
name: "FreeFieldEditableString",
|
|
11
|
+
props: {
|
|
12
|
+
modelValue: [String, Number],
|
|
13
|
+
debounce: Number
|
|
14
|
+
},
|
|
15
|
+
emits: ["update:modelValue"],
|
|
16
|
+
setup(props, { emit }) {
|
|
17
|
+
const editable = ref(false);
|
|
18
|
+
const inputRef = ref(null);
|
|
19
|
+
|
|
20
|
+
const inputEvent = (e) => {
|
|
21
|
+
const vv = typeof props.modelValue === 'number' ? (Number(e.target.value) || 0) : e.target.value;
|
|
22
|
+
emit("update:modelValue", vv);
|
|
23
|
+
editable.value = false;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const renderH = computed(() => {
|
|
27
|
+
if(editable.value) {
|
|
28
|
+
return h("input", {
|
|
29
|
+
style: "outline: none; border: none;padding: 0;margin:0;width: 100%;",
|
|
30
|
+
ref: inputRef,
|
|
31
|
+
value: props.modelValue || '',
|
|
32
|
+
onKeydown: (e) => e.code === 'Enter' && inputRef.value.blur(),
|
|
33
|
+
onBlur: inputEvent,
|
|
34
|
+
onClick: (e) => {
|
|
35
|
+
e.cancelBubble = true;
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return h(
|
|
42
|
+
"div",
|
|
43
|
+
{
|
|
44
|
+
class: "",
|
|
45
|
+
style: "min-width: 4px; min-height: 12px;",
|
|
46
|
+
onClick: (e) => {
|
|
47
|
+
e.cancelBubble = true;
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
editable.value = true;
|
|
50
|
+
nextTick(() => {
|
|
51
|
+
inputRef.value.focus();
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
[
|
|
56
|
+
props.modelValue
|
|
57
|
+
]
|
|
58
|
+
);
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
return () => renderH.value;
|
|
62
|
+
},
|
|
63
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineComponent,
|
|
3
|
+
h,
|
|
4
|
+
ref,
|
|
5
|
+
computed,
|
|
6
|
+
nextTick,
|
|
7
|
+
} from "vue";
|
|
8
|
+
import { QSpace, QSeparator } from 'quasar';
|
|
9
|
+
|
|
10
|
+
export default defineComponent({
|
|
11
|
+
name: "FreeFieldCategory",
|
|
12
|
+
props: {
|
|
13
|
+
hide: Boolean,
|
|
14
|
+
hidden: Boolean,
|
|
15
|
+
line: Boolean,
|
|
16
|
+
title: String,
|
|
17
|
+
titleClass: String,
|
|
18
|
+
titleStyle: String,
|
|
19
|
+
showLabel: {
|
|
20
|
+
type: String,
|
|
21
|
+
default: 'Show'
|
|
22
|
+
},
|
|
23
|
+
hideLabel: {
|
|
24
|
+
type: String,
|
|
25
|
+
default: 'Hide'
|
|
26
|
+
},
|
|
27
|
+
titleClickable: Boolean,
|
|
28
|
+
showLabelWhenHidden: Boolean
|
|
29
|
+
},
|
|
30
|
+
setup(props, { slots }) {
|
|
31
|
+
const hidden = ref(props.hidden || false);
|
|
32
|
+
const hovered = ref(false);
|
|
33
|
+
const titleClickable = props.titleClickable && props.hide;
|
|
34
|
+
|
|
35
|
+
return () => h('div',{
|
|
36
|
+
class: 'free-field-category',
|
|
37
|
+
style: 'font-size: 16px;'
|
|
38
|
+
},[
|
|
39
|
+
h('div', {
|
|
40
|
+
class: `free-field-category-title row no-wrap text-grey-9 ${titleClickable ? 'cursor-pointer' : ''}`,
|
|
41
|
+
onMouseenter: () => {
|
|
42
|
+
nextTick(() => {
|
|
43
|
+
hovered.value = true
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
onMouseleave: () => {
|
|
47
|
+
nextTick(() => {
|
|
48
|
+
hovered.value = false
|
|
49
|
+
})
|
|
50
|
+
},
|
|
51
|
+
onClick: () => {
|
|
52
|
+
if(!titleClickable) return;
|
|
53
|
+
|
|
54
|
+
nextTick(() => {
|
|
55
|
+
hidden.value = !hidden.value;
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
[
|
|
60
|
+
h('div', {
|
|
61
|
+
class: props.titleClass || 'q-mb-sm',
|
|
62
|
+
style: props.titleStyle,
|
|
63
|
+
} ,props.title || ''),
|
|
64
|
+
h(QSpace),
|
|
65
|
+
props.hide ? ((hovered.value || (props.showLabelWhenHidden && hidden.value)) ? h('div', {
|
|
66
|
+
class: `free-field-category-hide-btn cursor-pointer ${props.titleClass}`,
|
|
67
|
+
style: props.titleStyle,
|
|
68
|
+
onClick: () => {
|
|
69
|
+
if(props.titleClickable) return;
|
|
70
|
+
|
|
71
|
+
nextTick(() => {
|
|
72
|
+
hidden.value = !hidden.value;
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
} ,(hidden.value ? props.showLabel : props.hideLabel) || '') : undefined) : undefined,
|
|
76
|
+
]),
|
|
77
|
+
slots.default ? (hidden.value ? undefined : slots.default()) : undefined,
|
|
78
|
+
props.line ? h(QSeparator, {
|
|
79
|
+
class: 'free-field-category-line q-my-sm'
|
|
80
|
+
}) : undefined,
|
|
81
|
+
]);
|
|
82
|
+
},
|
|
83
|
+
});
|