free-fe-core-modules 0.0.2 → 0.0.4

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 (104) hide show
  1. package/components/Basic/EIcon.vue +2 -4
  2. package/components/Basic/LeveledMenus.vue +0 -5
  3. package/components/Basic/SummaryHead.vue +23 -3
  4. package/components/Dialog/BasicDialog.vue +2 -3
  5. package/components/SlidingCarousel/index.vue +13 -3
  6. package/components/SlidingNews/index.vue +13 -3
  7. package/components/ThemeSwitch/index.vue +7 -5
  8. package/composible/useObjectData.js +69 -0
  9. package/free-field/Fields/AgreementCheck.js +170 -0
  10. package/free-field/Fields/ApiCall.js +123 -0
  11. package/{field-components/Fields/Boolean.vue → free-field/Fields/Boolean.js} +40 -46
  12. package/free-field/Fields/Category.js +28 -0
  13. package/free-field/Fields/Check.js +106 -0
  14. package/free-field/Fields/Customize.js +87 -0
  15. package/free-field/Fields/Date.js +133 -0
  16. package/free-field/Fields/DateRange.js +226 -0
  17. package/free-field/Fields/DynamicList.js +565 -0
  18. package/{field-components → free-field}/Fields/FixedList.vue +78 -83
  19. package/free-field/Fields/InputFieldList.vue +324 -0
  20. package/{field-components → free-field}/Fields/Labels.vue +24 -15
  21. package/{field-components → free-field}/Fields/MixedTable.vue +53 -61
  22. package/free-field/Fields/Number.js +167 -0
  23. package/free-field/Fields/Password.js +81 -0
  24. package/{field-components → free-field}/Fields/Permission.vue +17 -13
  25. package/{field-components → free-field}/Fields/PermissionEditor.vue +62 -105
  26. package/{field-components → free-field}/Fields/QueryFilters.vue +65 -48
  27. package/{field-components → free-field}/Fields/RadioList.vue +36 -12
  28. package/{field-components → free-field}/Fields/Rich.vue +104 -114
  29. package/{field-components → free-field}/Fields/Search.vue +35 -26
  30. package/{field-components → free-field}/Fields/Select.vue +116 -87
  31. package/{field-components → free-field}/Fields/SelectionChain.vue +89 -67
  32. package/{field-components/Fields/Separator.vue → free-field/Fields/Separator.js} +11 -16
  33. package/{field-components → free-field}/Fields/SingleList.vue +27 -21
  34. package/free-field/Fields/Static.js +27 -0
  35. package/free-field/Fields/String.js +105 -0
  36. package/free-field/Fields/Text.js +80 -0
  37. package/{field-components → free-field}/Fields/Time.vue +59 -43
  38. package/{field-components → free-field}/Fields/TimeRange.vue +107 -92
  39. package/free-field/Fields/Year.js +137 -0
  40. package/{field-components → free-field}/Fields/YearRange.vue +63 -73
  41. package/{field-components → free-field}/Fields/index.js +28 -30
  42. package/free-field/composible/fieldWrapper.js +221 -0
  43. package/free-field/composible/freeFieldLabel.js +22 -0
  44. package/free-field/composible/readonlyContent.js +36 -0
  45. package/free-field/composible/useFileSizeUtils.js +52 -0
  46. package/free-field/composible/useFreeField.js +143 -0
  47. package/{field-components → free-field}/index.js +3 -3
  48. package/i18n/en-us/index.js +1 -1
  49. package/i18n/zh-cn/index.js +1 -1
  50. package/index.js +1 -4
  51. package/package.json +2 -2
  52. package/router/error/data.js +4 -1
  53. package/view/dict/index.vue +13 -2
  54. package/view/error/list.vue +22 -14
  55. package/view/menu/index.vue +19 -4
  56. package/view/system/index.vue +15 -2
  57. package/field-components/Fields/AgreementCheck.vue +0 -161
  58. package/field-components/Fields/ApiCall.vue +0 -139
  59. package/field-components/Fields/Category.vue +0 -33
  60. package/field-components/Fields/Check.vue +0 -131
  61. package/field-components/Fields/Customize.vue +0 -103
  62. package/field-components/Fields/Date.vue +0 -142
  63. package/field-components/Fields/DateRange.vue +0 -199
  64. package/field-components/Fields/DynamicList.vue +0 -575
  65. package/field-components/Fields/FieldEditor.vue +0 -379
  66. package/field-components/Fields/File.vue +0 -382
  67. package/field-components/Fields/FileList.vue +0 -405
  68. package/field-components/Fields/FileListCombined.vue +0 -142
  69. package/field-components/Fields/Image.vue +0 -328
  70. package/field-components/Fields/ImageList.vue +0 -285
  71. package/field-components/Fields/ImageListCombined.vue +0 -76
  72. package/field-components/Fields/InputFieldList.vue +0 -299
  73. package/field-components/Fields/Number.vue +0 -247
  74. package/field-components/Fields/Password.vue +0 -79
  75. package/field-components/Fields/Static.vue +0 -22
  76. package/field-components/Fields/String.vue +0 -185
  77. package/field-components/Fields/Text.vue +0 -89
  78. package/field-components/Fields/UltimateFile.vue +0 -100
  79. package/field-components/Fields/Year.vue +0 -124
  80. package/field-components/Fields/components/FieldTypeOptions.vue +0 -248
  81. package/field-components/components/FieldComponents.vue +0 -246
  82. package/free-fields/AutoHide.js +0 -66
  83. package/free-fields/CenterContent.js +0 -15
  84. package/free-fields/Draggable.js +0 -30
  85. package/free-fields/Droppable.js +0 -114
  86. package/free-fields/EditableString.js +0 -63
  87. package/free-fields/FieldCategory.js +0 -83
  88. package/free-fields/FieldTypeSelect.js +0 -94
  89. package/free-fields/fieldEditors/arrayEditor.js +0 -3
  90. package/free-fields/fieldEditors/boolEditor.js +0 -22
  91. package/free-fields/fieldEditors/dateEditor.js +0 -23
  92. package/free-fields/fieldEditors/datetimeEditor.js +0 -23
  93. package/free-fields/fieldEditors/index.js +0 -21
  94. package/free-fields/fieldEditors/jsonEditor.js +0 -371
  95. package/free-fields/fieldEditors/labeledField.js +0 -74
  96. package/free-fields/fieldEditors/numberEditor.js +0 -51
  97. package/free-fields/fieldEditors/objectEditor.js +0 -3
  98. package/free-fields/fieldEditors/selectEditor.js +0 -0
  99. package/free-fields/fieldEditors/stringEditor.js +0 -49
  100. package/free-fields/fieldEditors/textEditor.js +0 -50
  101. package/free-fields/fieldEditors/timeEditor.js +0 -23
  102. package/free-fields/index.js +0 -402
  103. /package/{field-components/Display → free-field/Layout}/index.js +0 -0
  104. /package/{field-components → free-field}/style.sass +0 -0
@@ -0,0 +1,137 @@
1
+ import { ref, defineComponent, getCurrentInstance, h, computed } from 'vue';
2
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
+ import { QSelect } from 'quasar';
4
+ import freeFieldLabel from '../composible/freeFieldLabel';
5
+
6
+ export default defineComponent({
7
+ name: 'InputFieldYear',
8
+ fieldInfo: {
9
+ Category: 'DateTime',
10
+ Label: '年份',
11
+ Value: 'Year',
12
+ Extra: [
13
+ {
14
+ Type: 'String',
15
+ Label: '最小值',
16
+ Name: 'MinValue',
17
+ },
18
+ {
19
+ Type: 'String',
20
+ Label: '最大值',
21
+ Name: 'MaxValue',
22
+ },
23
+ {
24
+ Type: 'Boolean',
25
+ Label: '最大至“现在”',
26
+ Name: 'Info.TillNow',
27
+ },
28
+ {
29
+ Type: 'Boolean',
30
+ Label: '最小从“现在”',
31
+ Name: 'Info.FromNow',
32
+ },
33
+ {
34
+ Type: 'DynamicList',
35
+ Label: '选项',
36
+ Name: 'Options',
37
+ Options: {
38
+ Columns: [
39
+ {
40
+ Label: 'Year',
41
+ Name: 'Value',
42
+ },
43
+ {
44
+ Label: 'Extra',
45
+ Name: 'Extra',
46
+ Type: 'FieldList',
47
+ Options: {
48
+ Columns: [
49
+ {
50
+ Label: '#',
51
+ Name: 'Index',
52
+ },
53
+ {
54
+ Label: '名称',
55
+ Name: 'Name',
56
+ },
57
+ {
58
+ Label: '标题',
59
+ Name: 'Label',
60
+ },
61
+ ],
62
+ },
63
+ },
64
+ ],
65
+ },
66
+ },
67
+ ],
68
+ Description: '',
69
+ },
70
+ props: {
71
+ ...freeFieldProps,
72
+ },
73
+ emits: ['input'],
74
+ methods: {
75
+ ...useFreeFieldMethods,
76
+ },
77
+ setup(props, { emit, slots }){
78
+ if (!props.Field) return {};
79
+
80
+ const { fieldData, setFieldData } = useFreeField(props);
81
+
82
+ const before = (props.Field.Label !== void 0) ? () => h(freeFieldLabel, {
83
+ Field: props.Field,
84
+ }) : undefined;
85
+
86
+ const yearOptions = computed(() => {
87
+ if (props.Field.Type !== 'Year') return [];
88
+
89
+ if (props.Field.Options && Array.isArray(props.Field.Options)) {
90
+ return props.Field.Options;
91
+ }
92
+
93
+ let minYear = 1900;
94
+ let maxYear = Date.now().year;
95
+
96
+ if (props.Field.MinValue && Number(props.Field.MinValue)) {
97
+ minYear = Number(props.Field.MinValue);
98
+ }
99
+ if (props.Field.MaxValue && Number(props.Field.MaxValue)) {
100
+ maxYear = Number(props.Field.MaxValue);
101
+ }
102
+
103
+ const options = [];
104
+ for (let i = minYear; i <= maxYear; i += 1) {
105
+ options.push(i);
106
+ }
107
+ return options;
108
+ });
109
+
110
+ const selectNode = () => h(QSelect, {
111
+ hideBottomSpace: true,
112
+ readonly: props.Field?.ReadOnly,
113
+ 'map-options': true,
114
+ label: props.Field.Placeholder,
115
+
116
+ class: 'full-width',
117
+ style: props.Field.Info?.Style,
118
+
119
+ rules: props.Field.Rules,
120
+
121
+ options: yearOptions.value,
122
+ modelValue: fieldData.value,
123
+ 'onUpdate:modelValue': (v) => {
124
+ setFieldData(v, emit);
125
+ },
126
+ }, {
127
+ before,
128
+ });
129
+
130
+ return () => h('div', {
131
+ class: 'simple-field input-field-year row items-center no-wrap',
132
+ }, [
133
+ selectNode(),
134
+ slots.warning && slots.warning(),
135
+ ]);
136
+ },
137
+ });
@@ -10,7 +10,7 @@
10
10
  {{Field.Label || ''}}
11
11
  <span v-if="Field.Required" class="required-mark">*</span>
12
12
  </span>
13
- <span class="readonly-content">{{fieldData}}</span>
13
+ <span class="readonly-content">{{fieldData.value}}</span>
14
14
  </span>
15
15
  <span v-else class="row items-center no-wrap">
16
16
  <q-select
@@ -18,11 +18,10 @@
18
18
  hide-bottom-space
19
19
  :options="minYearOptions"
20
20
  :readonly="Field.ReadOnly"
21
- v-bind="$attrs"
22
21
  @input="rangeChanged"
23
22
  :ref="`input_field_validator_first`"
24
23
  >
25
- <template v-slot:before v-if="typeof Field.Label !== 'undefined'">
24
+ <template v-slot:before v-if="Field.Label !== void 0">
26
25
  <span
27
26
  :class="`field-label ${(Field.Label && Field.Label.trim().length)
28
27
  ? '' : 'field-label-empty'} ${Field.Required ? 'required' : ''}`"
@@ -40,7 +39,6 @@
40
39
  :options="maxYearOptions"
41
40
  :readonly="Field.ReadOnly"
42
41
  @input="rangeChanged"
43
- v-bind="$attrs"
44
42
  :ref="`input_field_validator_second`"
45
43
  />
46
44
  </span>
@@ -50,12 +48,11 @@
50
48
  </template>
51
49
 
52
50
  <script>
53
- import { defineComponent } from 'vue';
54
- import mixins from 'free-fe-mixins';
51
+ import { defineComponent, ref, getCurrentInstance } from 'vue';
52
+ import { useFreeField, freeFieldProps } from '../composible/useFreeField';
55
53
 
56
54
  export default defineComponent({
57
55
  name: 'InputFieldYearRange',
58
- mixins: [mixins.InputFieldMixin],
59
56
  fieldInfo: {
60
57
  Category: 'DateTime',
61
58
  Label: '年份范围',
@@ -84,62 +81,51 @@ export default defineComponent({
84
81
  ],
85
82
  Description: '',
86
83
  },
87
- data() {
88
- return {
89
- range: {
90
- min: '',
91
- max: '',
92
- },
93
- };
84
+ props: {
85
+ ...freeFieldProps,
94
86
  },
95
- watch: {
96
- fieldData() {
97
- const yl = (this.fieldData || '').split(this.Field.Separator || '~');
98
- [this.range.min, this.range.max] = yl;
99
-
100
- // if (!this.range.min) {
101
- // this.$set(this.range, 'min', Number(this.Field.MinValue) || 1900);
102
- // }
103
- // if (!this.range.max) {
104
- // this.$set(this.range, 'max', Number(this.Field.MaxValue)
105
- // || (this.Field.TillNow ? Date.now().year : 2050));
106
- // }
107
- },
108
- range() {
109
- if (this.range.min && this.range.max) return;
110
- this.fieldData = [this.range.min, this.range.max].join(
111
- this.Field.Separator || '~',
112
- );
113
- this.$emit('input');
114
- },
115
- },
116
- created() {
117
- // if (!this.range.min) {
118
- // this.$set(this.range, 'min', Number(this.Field.MinValue) || 1900);
119
- // }
120
- // if (!this.range.max) {
121
- // this.$set(this.range, 'max', Number(this.Field.MaxValue)
122
- // || (this.Field.TillNow ? Date.now().year : 2050));
123
- // }
124
- },
125
- computed: {
126
- minYearOptions() {
127
- if (this.Field.Options && Array.isArray(this.Field.Options)) {
128
- return this.Field.Options;
87
+ emits:['input'],
88
+ setup(props, { emit }) {
89
+ if (!props.Field) return () => null;
90
+
91
+ const { proxy:vm } = getCurrentInstance();
92
+
93
+ const { fieldData, setFieldData } = useFreeField(props);
94
+
95
+ const min = ref('');
96
+ const max = ref('');
97
+
98
+ const rangeChanged = () => {
99
+ setFieldData([min.value, max.value].join(props.Field.Separator || '~'), emit);
100
+ };
101
+
102
+ watchEffect(() => {
103
+ const yl = (fieldData.value || '').split(props.Field.Separator || '~');
104
+ min.value = yl[0] && yl[0].trim();
105
+ max.value = yl[1] && yl[1].trim();
106
+ });
107
+
108
+ watch(range, () => {
109
+ rangeChanged();
110
+ })
111
+
112
+ const minYearOptions = computed(() => {
113
+ if (props.Field.Options && Array.isArray(props.Field.Options)) {
114
+ return props.Field.Options;
129
115
  }
130
116
 
131
117
  let minYear = 1900;
132
118
  let maxYear = Date.now().year;
133
119
 
134
- if (this.Field.MinValue && Number(this.Field.MinValue)) {
135
- minYear = Number(this.Field.MinValue);
120
+ if (props.Field.MinValue && Number(props.Field.MinValue)) {
121
+ minYear = Number(props.Field.MinValue);
136
122
  }
137
- if (this.Field.MaxValue && Number(this.Field.MaxValue)) {
138
- maxYear = Number(this.Field.MaxValue);
123
+ if (props.Field.MaxValue && Number(props.Field.MaxValue)) {
124
+ maxYear = Number(props.Field.MaxValue);
139
125
  }
140
126
 
141
- if (this.range.max && this.range.max < maxYear.toString()) {
142
- maxYear = Number(this.range.max) - 1;
127
+ if (max.value && max.value < maxYear.toString()) {
128
+ maxYear = Number(max.value) - 1;
143
129
  }
144
130
 
145
131
  const options = [];
@@ -148,24 +134,25 @@ export default defineComponent({
148
134
  }
149
135
 
150
136
  return options;
151
- },
152
- maxYearOptions() {
153
- if (this.Field.Options && Array.isArray(this.Field.Options)) {
154
- return this.Field.Options;
137
+ });
138
+
139
+ const maxYearOptions = computed(() => {
140
+ if (props.Field.Options && Array.isArray(props.Field.Options)) {
141
+ return props.Field.Options;
155
142
  }
156
143
 
157
144
  let minYear = 1900;
158
145
  let maxYear = Date.now().year;
159
146
 
160
- if (this.Field.MinValue && Number(this.Field.MinValue)) {
161
- minYear = Number(this.Field.MinValue);
147
+ if (props.Field.MinValue && Number(props.Field.MinValue)) {
148
+ minYear = Number(props.Field.MinValue);
162
149
  }
163
- if (this.Field.MaxValue && Number(this.Field.MaxValue)) {
164
- maxYear = Number(this.Field.MaxValue);
150
+ if (props.Field.MaxValue && Number(props.Field.MaxValue)) {
151
+ maxYear = Number(props.Field.MaxValue);
165
152
  }
166
153
 
167
- if (this.range.min && this.range.min > minYear.toString()) {
168
- minYear = Number(this.range.min) + 1;
154
+ if (min.value && min.value > minYear.toString()) {
155
+ minYear = Number(min.value) + 1;
169
156
  }
170
157
 
171
158
  const options = [];
@@ -174,15 +161,18 @@ export default defineComponent({
174
161
  }
175
162
 
176
163
  return options;
177
- },
178
- },
179
- methods: {
180
- rangeChanged() {
181
- this.fieldData = [this.range.min, this.range.max].join(
182
- this.Field.Separator || '~',
183
- );
184
- this.$emit('input');
185
- },
164
+ });
165
+
166
+
167
+ return {
168
+ fieldData,
169
+ range,
170
+
171
+ minYearOptions,
172
+ maxYearOptions,
173
+
174
+ rangeChanged,
175
+ };
186
176
  },
187
177
  });
188
178
  </script>
@@ -1,41 +1,40 @@
1
- import fStatic from './Static.vue';
1
+ import fStatic from './Static.js';
2
2
  import fSelect from './Select.vue';
3
- import fString from './String.vue';
4
- import fPassword from './Password.vue';
5
- import fCategory from './Category.vue';
6
- import fCheck from './Check.vue';
3
+ import fString from './String.js';
4
+ import fPassword from './Password.js';
5
+ import fCategory from './Category.js';
6
+ import fCheck from './Check.js';
7
7
  import fLabels from './Labels.vue';
8
- import fNumber from './Number.vue';
8
+ import fNumber from './Number.js';
9
9
  import fPermission from './Permission.vue';
10
10
  import fSearch from './Search.vue';
11
- import fText from './Text.vue';
11
+ import fText from './Text.js';
12
12
  import fTime from './Time.vue';
13
13
  import fTimeRange from './TimeRange.vue';
14
- import fDate from './Date.vue';
15
- import fDateRange from './DateRange.vue';
16
- import fYear from './Year.vue';
14
+ import fDate from './Date.js';
15
+ import fDateRange from './DateRange.js';
16
+ import fYear from './Year.js';
17
17
  import fYearRange from './YearRange.vue';
18
18
  import fRadioList from './RadioList.vue';
19
- import fBoolean from './Boolean.vue';
20
- import fFile from './File.vue';
21
- import fFileList from './FileList.vue';
22
- import fImage from './Image.vue';
23
- import fImageList from './ImageList.vue';
19
+ import fBoolean from './Boolean.js';
20
+ // import fFile from './File.vue';
21
+ // import fFileList from './FileList.vue';
22
+ // import fImage from './Image.vue';
23
+ // import fImageList from './ImageList.vue';
24
24
  import fFixedList from './FixedList.vue';
25
- import fDynamicList from './DynamicList.vue';
25
+ import fDynamicList from './DynamicList.js';
26
26
  import fSingleList from './SingleList.vue';
27
27
  import fSelectChain from './SelectionChain.vue';
28
28
  import fRich from './Rich.vue';
29
- import fFieldEditor from './FieldEditor.vue';
30
29
  import fFieldList from './InputFieldList.vue';
31
30
  import fMixedTable from './MixedTable.vue';
32
- import fCustomize from './Customize.vue';
33
- import fAgreementCheck from './AgreementCheck.vue';
34
- import fSeparator from './Separator.vue';
31
+ import fCustomize from './Customize.js';
32
+ import fAgreementCheck from './AgreementCheck.js';
33
+ import fSeparator from './Separator.js';
35
34
  import fQueryFilters from './QueryFilters.vue';
36
- import fFileListCombined from './FileListCombined.vue';
37
- import fImageListCombined from './ImageListCombined.vue';
38
- import fApiCall from './ApiCall.vue';
35
+ // import fFileListCombined from './FileListCombined.vue';
36
+ // import fImageListCombined from './ImageListCombined.vue';
37
+ import fApiCall from './ApiCall.js';
39
38
 
40
39
  export default {
41
40
  Static: fStatic,
@@ -57,24 +56,23 @@ export default {
57
56
  YearRange: fYearRange,
58
57
  RadioList: fRadioList,
59
58
  Boolean: fBoolean,
60
- File: fFile,
61
- FileList: fFileList,
62
- Image: fImage,
63
- ImageList: fImageList,
59
+ // File: fFile,
60
+ // FileList: fFileList,
61
+ // Image: fImage,
62
+ // ImageList: fImageList,
64
63
  FixedList: fFixedList,
65
64
  DynamicList: fDynamicList,
66
65
  SingleList: fSingleList,
67
66
  SelectionChain: fSelectChain,
68
67
  Rich: fRich,
69
- FieldEditor: fFieldEditor,
70
68
  FieldList: fFieldList,
71
69
  MixedTable: fMixedTable,
72
70
  Customize: fCustomize,
73
71
  AgreementCheck: fAgreementCheck,
74
72
  Separator: fSeparator,
75
73
  QueryFilters: fQueryFilters,
76
- FileListCombined: fFileListCombined,
77
- ImageListCombined: fImageListCombined,
74
+ // FileListCombined: fFileListCombined,
75
+ // ImageListCombined: fImageListCombined,
78
76
  ApiCall: fApiCall,
79
77
  // Static: () => import('./Static.vue'),
80
78
  // Select: () => import('./Select.vue'),
@@ -0,0 +1,221 @@
1
+ import {
2
+ defineComponent,
3
+ getCurrentInstance,
4
+ h,
5
+ ref,
6
+ reactive,
7
+ watchEffect,
8
+ computed,
9
+ onMounted,
10
+ nextTick,
11
+ isRef,
12
+ } from "vue";
13
+ import { freeFieldProps } from "./useFreeField";
14
+
15
+ export default defineComponent({
16
+ name: "FreeFieldWrapper",
17
+ props: {
18
+ ...freeFieldProps,
19
+ noExtra: { type: Boolean, default: false },
20
+ noWarning: { type: Boolean, default: false },
21
+ noTips: { type: Boolean, default: false },
22
+ },
23
+ emits: ['input'],
24
+ setup(props, { slots, emit, expose, attrs }) {
25
+ if (!props.Field) return {};
26
+
27
+ const { proxy: vm } = getCurrentInstance();
28
+
29
+ const localField = computed(() => {
30
+ const lField = { ...props.Field };
31
+ lField.Rules = lField.Rules || [];
32
+ for (let i = 0; i < lField.Rules.length; i += 1) {
33
+ const rule = lField.Rules[i];
34
+
35
+ if (
36
+ typeof rule === "string" &&
37
+ vm.ctx.validators[rule] &&
38
+ vm.ctx.validators[rule].validator
39
+ ) {
40
+ lField.Rules[i] = (val) =>
41
+ vm.ctx.validators[rule].validator(isRef(val) ? val.value : val);
42
+ }
43
+ }
44
+
45
+ if (lField.Required) {
46
+ lField.Rules.push(
47
+ (val) => {
48
+ const pVal = isRef(val) ? val.value : val;
49
+ return typeof pVal !== "undefined" && pVal !== "";
50
+ }
51
+ );
52
+ }
53
+
54
+ return lField;
55
+ });
56
+
57
+ const dashedName = (props.Field.Name || "").replace(/\./g, "-");
58
+ const hasError = ref(false);
59
+
60
+ // TODO: any other solution to replace the eval??
61
+ const evalFunc = (cond, pName = "data") => {
62
+ const funcStr = `
63
+ (${pName}) => {
64
+ return ${cond};
65
+ }
66
+ `;
67
+
68
+ try {
69
+ // eslint-disable-next-line no-eval
70
+ return eval(funcStr);
71
+ } catch (ex) {
72
+ return undefined;
73
+ }
74
+ };
75
+
76
+ const shouldHide = computed(() => {
77
+ // show when
78
+ if (props.Field.Info && props.Field.Info.ShowWhen) {
79
+ const theFunc = evalFunc(props.Field.Info.ShowWhen);
80
+ if (typeof theFunc !== "function") {
81
+ return true;
82
+ }
83
+ const condResult = theFunc(props.values);
84
+ if (!condResult) return true;
85
+ }
86
+
87
+ // hide (when)
88
+ if (
89
+ props.Field.Hidden &&
90
+ props.Field.Info &&
91
+ props.Field.Info.HideWhenUndefined
92
+ ) {
93
+ const checkField =
94
+ props.Field.Info.HideWhenUndefinedField || props.Field.Name;
95
+ if (checkField) {
96
+ const fList = checkField.split(",");
97
+ for (let i = 0; i < fList.length; i += 1) {
98
+ const fl = fList[i];
99
+
100
+ const flv = Object.nestValue(vm.data, fl.trim());
101
+ if (typeof flv === "undefined") return true;
102
+
103
+ if (props.Field.Info.IncludeEmptyObject) {
104
+ return !Object.hasValue(flv);
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ }
110
+
111
+ return props.Field.Hidden;
112
+ });
113
+
114
+ let realComponent = reactive({});
115
+
116
+ watchEffect(() => {
117
+ const fComponents = vm.ctx.FieldComponents || {};
118
+ let field;
119
+
120
+ // for some specified types
121
+ if (props.Field.Component) {
122
+ field = props.Field.Component;
123
+ // TODO: make select and radio as two diff components
124
+ // } else if (props.Field.Type === 'Select' && props.Field.AsRadio) {
125
+ // field = fComponents.RadioList;
126
+ } else {
127
+ if (typeof props.Field.Type === "undefined") {
128
+ field = fComponents.String;
129
+ } else {
130
+ field = fComponents[props.Field.Type] || props.Field.Type;
131
+ }
132
+ }
133
+
134
+ realComponent = field;
135
+ });
136
+
137
+ if (props.Field && props.Field.Info && props.Field.Info.KeepChanged) {
138
+ onMounted(() => {
139
+ nextTick(() => {
140
+ props.$emit("input", props.Field);
141
+ });
142
+ });
143
+ }
144
+
145
+ const wrapperClass = `free-field-wrapper ${
146
+ props.Field.Label && props.Field.Label.trim().length
147
+ ? "with-label"
148
+ : "without-label"
149
+ } ${props.Field.Label ? "free-field-wrapper-" + props.Field.Label : ""} ${
150
+ props.Field.Name ? "free-field-wrapper-" + dashedName : ""
151
+ } ${props.Field.Info?.Classes || ""}`;
152
+
153
+ const warningSlot = (!props.noWarning && localField.value.Warning)
154
+ && h('span', {
155
+ class: 'input-field-warning no-wrap',
156
+ },[
157
+ h('span', { class: 'input-field-warning-icon' }),
158
+ h('span', { class: 'input-field-warning-icon-sign-top' }),
159
+ h('span', { class: 'input-field-warning-icon-sign-dot' }),
160
+ h('span', { class: 'input-field-warning-text ellipsis' }, localField.value.Warning),
161
+ ]);
162
+
163
+ if (realComponent) {
164
+ const compEmits = {};
165
+ (realComponent.emits || []).forEach((em) => {
166
+ if (!em || em === 'input') return;
167
+
168
+ const captEm = `${em[0].toUpperCase()}${em.substring(1)}`;
169
+ compEmits[`on${captEm}`] = (...args) => {
170
+ // should not emit event directly as we were not inlucde these events in the emits list
171
+ // but we could get any matched handller from the parent component and then call that
172
+ // handller directly
173
+ // emit(em, ...args);
174
+ const outerHandller = attrs[`on${captEm}`];
175
+ if (typeof outerHandller === 'function') {
176
+ outerHandller(...args);
177
+ }
178
+ };
179
+ })
180
+
181
+ const emitsRef = ref(realComponent.emits);
182
+
183
+ expose ({
184
+ emits: emitsRef,
185
+ })
186
+
187
+
188
+ return () =>
189
+ h(
190
+ "div",
191
+ {
192
+ class: wrapperClass,
193
+ },
194
+ [
195
+ h(
196
+ realComponent,
197
+ {
198
+ Field: localField.value,
199
+ values: props.values,
200
+ style: shouldHide.value ? "display:none;" : "",
201
+ class: [
202
+ props.Field.ReadOnly ? "free-field--readonly" : "",
203
+ !shouldHide.value && hasError.value ? "hasError" : "",
204
+ ],
205
+ onInput: () => {
206
+ emit("input", props.Field);
207
+ },
208
+ ...compEmits,
209
+ },
210
+ {
211
+ ...slots,
212
+ warning: slots.warning ? slots.warning : () => warningSlot,
213
+ }
214
+ ),
215
+ ]
216
+ );
217
+ } else {
218
+ return () => null;
219
+ }
220
+ },
221
+ });
@@ -0,0 +1,22 @@
1
+ import { defineComponent, h } from 'vue';
2
+
3
+ export default defineComponent({
4
+ name: 'FreeFieldLabel',
5
+ props: {
6
+ Field: { type: Object },
7
+ },
8
+ setup(props){
9
+ return () => (props.Field?.Label === void 0) ? null : h('span', {
10
+ class:`field-label field-label-readonly ${(props.Field.Label && props.Field.Label.trim().length)
11
+ ? '' : 'field-label-empty'} ${props.Field.Required ? 'required' : ''}`,
12
+ }, [
13
+ props.Field.Description && h(QTooltip, {
14
+ anchor: "top right",
15
+ }, props.Field.Description),
16
+ props.Field.Label || '',
17
+ props.Field.Required && h('span', {
18
+ class: 'required-mark',
19
+ }, '*'),
20
+ ]);
21
+ },
22
+ });