quasar-ui-danx 0.3.24 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quasar-ui-danx",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -5,6 +5,7 @@
5
5
  v-if="field.options?.length > 0 || loading"
6
6
  :model-value="modelValue"
7
7
  :options="field.options"
8
+ :clearable="field.clearable === undefined ? true : field.clearable"
8
9
  multiple
9
10
  :loading="loading"
10
11
  :chip-limit="1"
@@ -30,6 +31,7 @@
30
31
  v-else-if="field.type === 'single-select'"
31
32
  :model-value="modelValue"
32
33
  :options="field.options"
34
+ :clearable="field.clearable === undefined ? true : field.clearable"
33
35
  :placeholder="field.placeholder"
34
36
  :loading="loading"
35
37
  :label="field.label"
@@ -108,41 +110,41 @@
108
110
  </template>
109
111
  <script setup>
110
112
  import {
111
- BooleanField,
112
- DateField,
113
- DateRangeField,
114
- MultiKeywordField,
115
- NumberRangeField,
116
- SelectField,
117
- SelectWithChildrenField
113
+ BooleanField,
114
+ DateField,
115
+ DateRangeField,
116
+ MultiKeywordField,
117
+ NumberRangeField,
118
+ SelectField,
119
+ SelectWithChildrenField
118
120
  } from "../Form/Fields";
119
121
 
120
122
  const emit = defineEmits(["update:model-value"]);
121
123
  const props = defineProps({
122
- field: {
123
- type: Object,
124
- required: true
125
- },
126
- modelValue: {
127
- type: [String, Array, Number, Object, Boolean],
128
- default: undefined
129
- },
130
- loading: Boolean
124
+ field: {
125
+ type: Object,
126
+ required: true
127
+ },
128
+ modelValue: {
129
+ type: [String, Array, Number, Object, Boolean],
130
+ default: undefined
131
+ },
132
+ loading: Boolean
131
133
  });
132
134
 
133
135
  function onUpdate(val) {
134
- let newVal = val || undefined;
136
+ let newVal = val || undefined;
135
137
 
136
- switch (props.field.type) {
137
- case "multi-select":
138
- newVal = val.length > 0 ? val : undefined;
139
- break;
140
- case "single-select":
141
- case "boolean":
142
- newVal = val === null ? undefined : val;
143
- break;
144
- }
138
+ switch (props.field.type) {
139
+ case "multi-select":
140
+ newVal = (val && val.length > 0) ? val : undefined;
141
+ break;
142
+ case "single-select":
143
+ case "boolean":
144
+ newVal = val === null ? undefined : val;
145
+ break;
146
+ }
145
147
 
146
- emit("update:model-value", newVal);
148
+ emit("update:model-value", newVal);
147
149
  }
148
150
  </script>
@@ -75,6 +75,7 @@
75
75
  :label="field.label || undefined"
76
76
  :no-label="noLabel"
77
77
  :show-name="showName"
78
+ :clearable="field.clearable || clearable"
78
79
  :disable="disable"
79
80
  :readonly="readonly"
80
81
  @update:model-value="onInput(field.name, $event)"
@@ -111,65 +112,66 @@ import { FlashMessages, incrementName, replace } from "../../../helpers";
111
112
  import { TrashIcon as RemoveIcon } from "../../../svg";
112
113
  import { ConfirmDialog } from "../../Utility";
113
114
  import {
114
- BooleanField,
115
- DateField,
116
- DateRangeField,
117
- IntegerField,
118
- MultiFileField,
119
- NumberField,
120
- SingleFileField,
121
- TextField,
122
- WysiwygField
115
+ BooleanField,
116
+ DateField,
117
+ DateRangeField,
118
+ IntegerField,
119
+ MultiFileField,
120
+ NumberField,
121
+ SingleFileField,
122
+ TextField,
123
+ WysiwygField
123
124
  } from "./Fields";
124
125
 
125
126
  const emit = defineEmits(["update:values"]);
126
127
  const props = defineProps({
127
- values: {
128
- type: Array,
129
- default: null
130
- },
131
- form: {
132
- type: Object,
133
- required: true
134
- },
135
- noLabel: Boolean,
136
- showName: Boolean,
137
- disable: Boolean,
138
- readonly: Boolean,
139
- saving: Boolean,
140
- emptyValue: {
141
- type: [String, Number, Boolean],
142
- default: undefined
143
- },
144
- canModifyVariations: Boolean
128
+ values: {
129
+ type: Array,
130
+ default: null
131
+ },
132
+ form: {
133
+ type: Object,
134
+ required: true
135
+ },
136
+ noLabel: Boolean,
137
+ showName: Boolean,
138
+ disable: Boolean,
139
+ clearable: Boolean,
140
+ readonly: Boolean,
141
+ saving: Boolean,
142
+ emptyValue: {
143
+ type: [String, Number, Boolean],
144
+ default: undefined
145
+ },
146
+ canModifyVariations: Boolean
145
147
  });
146
148
 
147
149
  const FORM_FIELD_MAP = {
148
- BOOLEAN: BooleanField,
149
- DATE: DateField,
150
- DATE_RANGE: DateRangeField,
151
- INTEGER: IntegerField,
152
- NUMBER: NumberField,
153
- TEXT: TextField,
154
- SINGLE_FILE: SingleFileField,
155
- MULTI_FILE: MultiFileField,
156
- WYSIWYG: WysiwygField
150
+ BOOLEAN: BooleanField,
151
+ DATE: DateField,
152
+ DATE_RANGE: DateRangeField,
153
+ INTEGER: IntegerField,
154
+ NUMBER: NumberField,
155
+ TEXT: TextField,
156
+ SINGLE_FILE: SingleFileField,
157
+ MULTI_FILE: MultiFileField,
158
+ WYSIWYG: WysiwygField
157
159
  };
158
160
 
159
161
  const mappedFields = props.form.fields.map((field) => ({
160
- placeholder: `Enter ${field.label}`,
161
- ...field,
162
- component: FORM_FIELD_MAP[field.type],
163
- default: field.type === "BOOLEAN" ? false : ""
162
+ placeholder: `Enter ${field.label}`,
163
+ ...field,
164
+ component: FORM_FIELD_MAP[field.type],
165
+ default: field.type === "BOOLEAN" ? false : ""
164
166
  }));
165
167
 
166
168
  const variationNames = computed(() => {
167
- const names = [...new Set(props.values.map(v => v.variation))].sort();
168
- // Always guarantee that we show the default variation
169
- if (names.length === 0) {
170
- names.push("");
171
- }
172
- return names;
169
+ const names = [...new Set(props.values.map(v => v.variation))].sort();
170
+ // Always guarantee that we show the default variation
171
+ if (names.length === 0) {
172
+ names.push("");
173
+ }
174
+ return names;
173
175
  });
174
176
 
175
177
  const currentVariation = ref(variationNames.value[0] || "");
@@ -179,88 +181,88 @@ const variationToDelete = ref("");
179
181
  const canAddVariation = computed(() => props.canModifyVariations && !props.readonly && !props.disable && variationNames.value.length < props.form.variations);
180
182
 
181
183
  function getFieldResponse(name, variation) {
182
- if (!props.values) return undefined;
183
- return props.values.find((v) => v.variation === (variation !== undefined ? variation : currentVariation.value) && v.name === name);
184
+ if (!props.values) return undefined;
185
+ return props.values.find((v) => v.variation === (variation !== undefined ? variation : currentVariation.value) && v.name === name);
184
186
  }
185
187
  function getFieldValue(name) {
186
- return getFieldResponse(name)?.value;
188
+ return getFieldResponse(name)?.value;
187
189
  }
188
190
  function onInput(name, value) {
189
- const fieldResponse = getFieldResponse(name);
190
- const newFieldResponse = {
191
- name,
192
- variation: currentVariation.value || "",
193
- value: value === undefined ? props.emptyValue : value
194
- };
195
- const newValues = replace(props.values, fieldResponse, newFieldResponse, true);
196
- emit("update:values", newValues);
191
+ const fieldResponse = getFieldResponse(name);
192
+ const newFieldResponse = {
193
+ name,
194
+ variation: currentVariation.value || "",
195
+ value: value === undefined ? props.emptyValue : value
196
+ };
197
+ const newValues = replace(props.values, fieldResponse, newFieldResponse, true);
198
+ emit("update:values", newValues);
197
199
  }
198
200
 
199
201
  function createVariation(variation) {
200
- return props.form.fields.map((field) => ({
201
- variation,
202
- name: field.name,
203
- value: field.type === "BOOLEAN" ? false : null
204
- }));
202
+ return props.form.fields.map((field) => ({
203
+ variation,
204
+ name: field.name,
205
+ value: field.type === "BOOLEAN" ? false : null
206
+ }));
205
207
  }
206
208
 
207
209
  function onAddVariation() {
208
- if (props.saving) return;
209
- let newValues = [...props.values];
210
+ if (props.saving) return;
211
+ let newValues = [...props.values];
210
212
 
211
- if (newValues.length === 0) {
212
- newValues = createVariation("");
213
- }
214
- const previousName = variationNames.value[variationNames.value.length - 1];
215
- const newName = incrementName(!previousName ? "1" : previousName);
216
- const newVariation = createVariation(newName);
217
- emit("update:values", [...newValues, ...newVariation]);
218
- currentVariation.value = newName;
213
+ if (newValues.length === 0) {
214
+ newValues = createVariation("");
215
+ }
216
+ const previousName = variationNames.value[variationNames.value.length - 1];
217
+ const newName = incrementName(!previousName ? "1" : previousName);
218
+ const newVariation = createVariation(newName);
219
+ emit("update:values", [...newValues, ...newVariation]);
220
+ currentVariation.value = newName;
219
221
  }
220
222
 
221
223
  function onChangeVariationName() {
222
- if (!newVariationName.value) return;
223
- if (variationNames.value.includes(newVariationName.value)) {
224
- FlashMessages.error("Variation name already exists");
225
- return;
226
- }
227
- const newValues = props.values.map((v) => {
228
- if (v.variation === variationToEdit.value) {
229
- return { ...v, variation: newVariationName.value };
230
- }
231
- return v;
232
- });
233
- emit("update:values", newValues);
224
+ if (!newVariationName.value) return;
225
+ if (variationNames.value.includes(newVariationName.value)) {
226
+ FlashMessages.error("Variation name already exists");
227
+ return;
228
+ }
229
+ const newValues = props.values.map((v) => {
230
+ if (v.variation === variationToEdit.value) {
231
+ return { ...v, variation: newVariationName.value };
232
+ }
233
+ return v;
234
+ });
235
+ emit("update:values", newValues);
234
236
 
235
- currentVariation.value = newVariationName.value;
236
- variationToEdit.value = false;
237
- newVariationName.value = "";
237
+ currentVariation.value = newVariationName.value;
238
+ variationToEdit.value = false;
239
+ newVariationName.value = "";
238
240
  }
239
241
 
240
242
  function onRemoveVariation(name) {
241
- if (!name) return;
243
+ if (!name) return;
242
244
 
243
- const newValues = props.values.filter((v) => v.variation !== name);
244
- emit("update:values", newValues);
245
+ const newValues = props.values.filter((v) => v.variation !== name);
246
+ emit("update:values", newValues);
245
247
 
246
- if (currentVariation.value === name) {
247
- currentVariation.value = variationNames.value[0];
248
- }
249
- variationToDelete.value = "";
248
+ if (currentVariation.value === name) {
249
+ currentVariation.value = variationNames.value[0];
250
+ }
251
+ variationToDelete.value = "";
250
252
  }
251
253
 
252
254
  function isVariationFormComplete(variation) {
253
- const requiredGroups = {};
254
- return props.form.fields.filter(r => r.required || r.required_group).every((field) => {
255
- const fieldResponse = getFieldResponse(field.name, variation);
256
- const hasValue = !!fieldResponse && fieldResponse.value !== null;
257
- if (field.required_group) {
258
- // This required group has already been satisfied
259
- if (requiredGroups[field.required_group]) return true;
260
- return requiredGroups[field.required_group] = hasValue;
261
- } else {
262
- return hasValue;
263
- }
264
- });
255
+ const requiredGroups = {};
256
+ return props.form.fields.filter(r => r.required || r.required_group).every((field) => {
257
+ const fieldResponse = getFieldResponse(field.name, variation);
258
+ const hasValue = !!fieldResponse && fieldResponse.value !== null;
259
+ if (field.required_group) {
260
+ // This required group has already been satisfied
261
+ if (requiredGroups[field.required_group]) return true;
262
+ return requiredGroups[field.required_group] = hasValue;
263
+ } else {
264
+ return hasValue;
265
+ }
266
+ });
265
267
  }
266
268
  </script>
@@ -2,81 +2,82 @@ import { computed, ref, watch } from "vue";
2
2
  import { getItem, setItem } from "../../helpers";
3
3
 
4
4
  export interface TableColumn {
5
- actionMenu?: object,
6
- align?: string,
7
- category?: string,
8
- class?: string | object,
9
- field: string,
10
- format?: Function,
11
- innerClass?: string | object,
12
- style?: string | object,
13
- headerStyle?: string | object,
14
- isSavingRow?: boolean | Function,
15
- label: string,
16
- maxWidth?: number,
17
- minWidth?: number,
18
- name: string,
19
- onClick?: Function,
20
- required?: boolean,
21
- resizeable?: boolean,
22
- sortable?: boolean,
23
- sortBy?: string,
24
- sortByExpression?: string,
25
- titleColumns?: Function,
26
- vnode?: Function,
5
+ actionMenu?: object,
6
+ align?: string,
7
+ category?: string,
8
+ class?: string | object,
9
+ field: string,
10
+ format?: Function,
11
+ innerClass?: string | object,
12
+ style?: string | object,
13
+ headerStyle?: string | object,
14
+ isSavingRow?: boolean | Function,
15
+ label: string,
16
+ maxWidth?: number,
17
+ minWidth?: number,
18
+ name: string,
19
+ onClick?: Function,
20
+ required?: boolean,
21
+ resizeable?: boolean,
22
+ sortable?: boolean,
23
+ sortBy?: string,
24
+ sortByExpression?: string,
25
+ titleColumns?: Function,
26
+ vnode?: Function,
27
27
  }
28
28
 
29
29
  export function useTableColumns(name: string, columns: TableColumn[]) {
30
- const COLUMN_ORDER_KEY = `${name}-column-order`;
31
- const VISIBLE_COLUMNS_KEY = `${name}-visible-columns`;
32
- const TITLE_COLUMNS_KEY = `${name}-title-columns`;
30
+ const COLUMN_ORDER_KEY = `${name}-column-order`;
31
+ const VISIBLE_COLUMNS_KEY = `${name}-visible-columns`;
32
+ const TITLE_COLUMNS_KEY = `${name}-title-columns`;
33
33
 
34
- // The list that defines the order the columns should appear in
35
- const columnOrder = ref(getItem(COLUMN_ORDER_KEY) || []);
34
+ // The list that defines the order the columns should appear in
35
+ const columnOrder = ref(getItem(COLUMN_ORDER_KEY) || []);
36
36
 
37
- // Manages visible columns on the table
38
- const hiddenColumnNames = ref(getItem(VISIBLE_COLUMNS_KEY, []));
37
+ // Manages visible columns on the table
38
+ const hiddenColumnNames = ref(getItem(VISIBLE_COLUMNS_KEY, []));
39
39
 
40
- // Title columns will have their name appear on the first column of the table as part of the records' title
41
- const titleColumnNames = ref(getItem(TITLE_COLUMNS_KEY, []));
40
+ // Title columns will have their name appear on the first column of the table as part of the records' title
41
+ const titleColumnNames = ref(getItem(TITLE_COLUMNS_KEY, []));
42
42
 
43
- // Columns that should be locked to the left side of the table
44
- const lockedColumns = computed(() => orderedColumns.value.slice(0, 1));
43
+ // Columns that should be locked to the left side of the table
44
+ const lockedColumns = computed(() => orderedColumns.value.slice(0, 1));
45
45
 
46
- // The resolved list of columns in the order they should appear in
47
- const orderedColumns = computed(() => [...columns].sort((a, b) => {
48
- const aIndex = columnOrder.value.indexOf(a.name);
49
- const bIndex = columnOrder.value.indexOf(b.name);
50
- return aIndex === -1 ? 1 : bIndex === -1 ? -1 : aIndex - bIndex;
51
- }));
46
+ // The resolved list of columns in the order they should appear in
47
+ const orderedColumns = computed(() => [...columns].sort((a, b) => {
48
+ const aIndex = columnOrder.value.indexOf(a.name);
49
+ const bIndex = columnOrder.value.indexOf(b.name);
50
+ return aIndex === -1 ? 1 : bIndex === -1 ? -1 : aIndex - bIndex;
51
+ }));
52
52
 
53
- // The ordered list of columns. The ordering of this list is editable and will be stored in localStorage
54
- const sortableColumns = computed({
55
- get() {
56
- return orderedColumns.value.slice(1);
57
- },
58
- set(newColumns) {
59
- columnOrder.value = [...lockedColumns.value.map(c => c.name), ...newColumns.map(c => c.name)];
60
- setItem(COLUMN_ORDER_KEY, columnOrder.value);
61
- }
62
- });
53
+ // The ordered list of columns. The ordering of this list is editable and will be stored in localStorage
54
+ const sortableColumns = computed({
55
+ get() {
56
+ return orderedColumns.value.slice(1);
57
+ },
58
+ set(newColumns) {
59
+ columnOrder.value = [...lockedColumns.value.map(c => c.name), ...newColumns.map(c => c.name)];
60
+ setItem(COLUMN_ORDER_KEY, columnOrder.value);
61
+ }
62
+ });
63
63
 
64
- // The list of columns that are visible. To edit the visible columns, edit the hiddenColumnNames list
65
- const visibleColumns = computed(() => orderedColumns.value.filter(c => !hiddenColumnNames.value.includes(c.name)));
64
+ // The list of columns that are visible. To edit the visible columns, edit the hiddenColumnNames list
65
+ const visibleColumns = computed(() => orderedColumns.value.filter(c => !hiddenColumnNames.value.includes(c.name)));
66
66
 
67
- // The list of columns that should be included in the title of a row
68
- const orderedTitleColumns = computed(() => orderedColumns.value.filter(c => titleColumnNames.value.includes(c.name)));
67
+ // The list of columns that should be included in the title of a row
68
+ const orderedTitleColumns = computed(() => orderedColumns.value.filter(c => titleColumnNames.value.includes(c.name)));
69
69
 
70
- // Save changes to the list of hidden columns in localStorage
71
- watch(() => hiddenColumnNames.value, () => setItem(VISIBLE_COLUMNS_KEY, hiddenColumnNames.value));
72
- watch(() => titleColumnNames.value, () => setItem(TITLE_COLUMNS_KEY, titleColumnNames.value));
70
+ // Save changes to the list of hidden columns in localStorage
71
+ watch(() => hiddenColumnNames.value, () => setItem(VISIBLE_COLUMNS_KEY, hiddenColumnNames.value));
72
+ watch(() => titleColumnNames.value, () => setItem(TITLE_COLUMNS_KEY, titleColumnNames.value));
73
73
 
74
- return {
75
- sortableColumns,
76
- lockedColumns,
77
- visibleColumns,
78
- hiddenColumnNames,
79
- titleColumnNames,
80
- orderedTitleColumns
81
- };
74
+ return {
75
+ sortableColumns,
76
+ lockedColumns,
77
+ visibleColumns,
78
+ hiddenColumnNames,
79
+ columnOrder,
80
+ titleColumnNames,
81
+ orderedTitleColumns
82
+ };
82
83
  }