quasar-ui-danx 0.0.11 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. package/dist/index.css +5 -0
  2. package/dist/index.min.css +5 -0
  3. package/dist/index.rtl.css +5 -0
  4. package/dist/index.rtl.min.css +5 -0
  5. package/package.json +6 -1
  6. package/src/components/ActionTable/ActionTable.vue +49 -41
  7. package/src/components/ActionTable/BatchActionMenu.vue +20 -20
  8. package/src/components/ActionTable/EmptyTableState.vue +5 -5
  9. package/src/components/ActionTable/Filters/CollapsableFiltersSidebar.vue +11 -11
  10. package/src/components/ActionTable/Filters/FilterGroupItem.vue +7 -7
  11. package/src/components/ActionTable/Filters/FilterGroupList.vue +29 -29
  12. package/src/components/ActionTable/Filters/FilterListToggle.vue +15 -15
  13. package/src/components/ActionTable/Filters/FilterableField.vue +82 -80
  14. package/src/components/ActionTable/Filters/index.ts +5 -0
  15. package/src/components/ActionTable/Form/Fields/BooleanField.vue +13 -13
  16. package/src/components/ActionTable/Form/Fields/ConfirmPasswordField.vue +11 -11
  17. package/src/components/ActionTable/Form/Fields/DateField.vue +13 -13
  18. package/src/components/ActionTable/Form/Fields/DateRangeField.vue +25 -25
  19. package/src/components/ActionTable/Form/Fields/DateTimeField.vue +21 -21
  20. package/src/components/ActionTable/Form/Fields/DateTimePicker.vue +23 -23
  21. package/src/components/ActionTable/Form/Fields/FileUploadButton.vue +31 -31
  22. package/src/components/ActionTable/Form/Fields/InlineDateTimeField.vue +19 -19
  23. package/src/components/ActionTable/Form/Fields/IntegerField.vue +7 -7
  24. package/src/components/ActionTable/Form/Fields/LabelValueBlock.vue +22 -0
  25. package/src/components/ActionTable/Form/Fields/LabeledInput.vue +19 -19
  26. package/src/components/ActionTable/Form/Fields/MultiFileField.vue +40 -40
  27. package/src/components/ActionTable/Form/Fields/MultiKeywordField.vue +23 -23
  28. package/src/components/ActionTable/Form/Fields/NewPasswordField.vue +10 -10
  29. package/src/components/ActionTable/Form/Fields/NumberField.vue +29 -29
  30. package/src/components/ActionTable/Form/Fields/NumberRangeField.vue +33 -33
  31. package/src/components/ActionTable/Form/Fields/SelectDrawer.vue +36 -36
  32. package/src/components/ActionTable/Form/Fields/SelectField.vue +66 -66
  33. package/src/components/ActionTable/Form/Fields/SelectWithChildrenField.vue +23 -23
  34. package/src/components/ActionTable/Form/Fields/SingleFileField.vue +32 -32
  35. package/src/components/ActionTable/Form/Fields/TextField.vue +36 -36
  36. package/src/components/ActionTable/Form/Fields/WysiwygField.vue +16 -16
  37. package/src/components/ActionTable/Form/Fields/index.ts +23 -23
  38. package/src/components/ActionTable/Form/RenderedForm.vue +27 -25
  39. package/src/components/ActionTable/Form/index.ts +2 -0
  40. package/src/components/ActionTable/TableSummaryRow.vue +33 -33
  41. package/src/components/ActionTable/index.ts +8 -13
  42. package/src/components/ActionTable/listActions.ts +340 -339
  43. package/src/components/ActionTable/listHelpers.ts +74 -0
  44. package/src/components/ActionTable/tableColumns.ts +56 -56
  45. package/src/components/DragAndDrop/HandleDraggable.vue +29 -29
  46. package/src/components/DragAndDrop/ListItemDraggable.vue +10 -10
  47. package/src/components/DragAndDrop/index.ts +0 -1
  48. package/src/components/DragAndDrop/listDragAndDrop.ts +1 -1
  49. package/src/components/Utility/CollapsableSidebar.vue +35 -35
  50. package/src/components/Utility/ContentDrawer.vue +20 -20
  51. package/src/components/Utility/Dialogs/ConfirmDialog.vue +55 -55
  52. package/src/components/Utility/Dialogs/FullScreenDialog.vue +18 -18
  53. package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +105 -0
  54. package/src/components/Utility/Dialogs/InfoDialog.vue +10 -10
  55. package/src/components/Utility/Dialogs/InputDialog.vue +13 -13
  56. package/src/components/Utility/ImagePreview.vue +192 -0
  57. package/src/components/Utility/Popover/PopoverMenu.vue +64 -0
  58. package/src/components/Utility/Transitions/StaggeredListTransition.vue +15 -15
  59. package/src/components/Utility/index.ts +11 -9
  60. package/src/components/index.ts +1 -1
  61. package/src/helpers/FileUpload.ts +274 -273
  62. package/src/helpers/compatibility.ts +45 -45
  63. package/src/helpers/date.ts +2 -2
  64. package/src/helpers/download.ts +166 -158
  65. package/src/helpers/downloadPdf.ts +48 -48
  66. package/src/helpers/files.ts +42 -42
  67. package/src/helpers/index.ts +2 -0
  68. package/src/helpers/multiFileUpload.ts +56 -56
  69. package/src/helpers/singleFileUpload.ts +49 -49
  70. package/src/index.esm.js +3 -4
  71. package/src/svg/FilterIcon.svg +7 -0
  72. package/src/svg/ImageIcon.svg +30 -0
  73. package/src/svg/PdfIcon.svg +21 -0
  74. package/src/svg/PercentIcon.svg +13 -0
  75. package/src/svg/TrashIcon.svg +15 -0
  76. package/src/svg/XIcon.svg +18 -0
  77. package/src/svg/index.ts +8 -0
  78. package/src/vendor/tinymce-config.ts +1 -0
  79. package/src/vue-plugin.js +7 -4
  80. package/tsconfig.json +18 -14
  81. package/src/components/ActionTable/tableHelpers.ts +0 -83
  82. package/src/components/DragAndDrop/Icons/index.ts +0 -2
  83. /package/src/{components/DragAndDrop/Icons → svg}/DragHandleDotsIcon.svg +0 -0
  84. /package/src/{components/DragAndDrop/Icons → svg}/DragHandleIcon.svg +0 -0
@@ -1,44 +1,44 @@
1
1
  <template>
2
- <QBtn v-bind="$props" @click="$refs.fileUpload.click()">
2
+ <q-btn v-bind="$props" @click="$refs.fileUpload.click()">
3
3
  <slot>
4
4
  <PlusIcon class="w-5 mr-2" />
5
5
  {{ text }}
6
6
  </slot>
7
7
 
8
8
  <input
9
- ref="fileUpload"
10
- data-testid="file-upload"
11
- type="file"
12
- :accept="geolocation ? 'image/*;capture=camera' : undefined"
13
- :capture="geolocation ? 'environment' : undefined"
14
- class="hidden"
15
- multiple
16
- @change="onAttachFiles"
9
+ ref="fileUpload"
10
+ data-testid="file-upload"
11
+ type="file"
12
+ :accept="geolocation ? 'image/*;capture=camera' : undefined"
13
+ :capture="geolocation ? 'environment' : undefined"
14
+ class="hidden"
15
+ multiple
16
+ @change="onAttachFiles"
17
17
  />
18
- </QBtn>
18
+ </q-btn>
19
19
  </template>
20
20
  <script setup>
21
- import { PlusIcon } from "@heroicons/vue/outline";
22
- import { FileUpload } from "danx/src/helpers";
23
- import { QBtn } from "quasar";
24
- import { ref } from "vue";
21
+ import { PlusIcon } from '@heroicons/vue/outline';
22
+ import { FileUpload } from '@ui/helpers';
23
+ import { QBtn } from 'quasar';
24
+ import { ref } from 'vue';
25
25
 
26
26
  defineExpose({ upload });
27
27
  const emit = defineEmits([
28
- "uploading",
29
- "file-progress",
30
- "file-complete",
31
- "complete"
28
+ 'uploading',
29
+ 'file-progress',
30
+ 'file-complete',
31
+ 'complete'
32
32
  ]);
33
33
  const props = defineProps({
34
34
  ...QBtn.props,
35
35
  text: {
36
36
  type: String,
37
- default: "Add File"
37
+ default: 'Add File'
38
38
  },
39
39
  locationWaitMessage: {
40
40
  type: String,
41
- default: "Waiting for location..."
41
+ default: 'Waiting for location...'
42
42
  },
43
43
  geolocation: Boolean
44
44
  });
@@ -56,18 +56,18 @@ function upload() {
56
56
  * @returns {Promise<void>}
57
57
  */
58
58
  async function onAttachFiles({ target: { files } }) {
59
- emit("uploading", files);
59
+ emit('uploading', files);
60
60
  let fileUpload = new FileUpload(files)
61
- .onProgress(({ file, progress }) => {
62
- file.progress = progress;
63
- emit("file-progress", file);
64
- })
65
- .onComplete(({ file, uploadedFile }) => {
66
- emit("file-complete", { file, uploadedFile });
67
- })
68
- .onAllComplete(() => {
69
- emit("complete", fileUpload.files);
70
- });
61
+ .onProgress(({ file, progress }) => {
62
+ file.progress = progress;
63
+ emit('file-progress', file);
64
+ })
65
+ .onComplete(({ file, uploadedFile }) => {
66
+ emit('file-complete', { file, uploadedFile });
67
+ })
68
+ .onAllComplete(() => {
69
+ emit('complete', fileUpload.files);
70
+ });
71
71
 
72
72
  if (props.geolocation) {
73
73
  await fileUpload.resolveLocation(props.locationWaitMessage);
@@ -1,33 +1,33 @@
1
1
  <template>
2
2
  <div class="inline-block">
3
3
  <div
4
- class="cursor-pointer py-2 hover:bg-blue-light flex items-center justify-end"
4
+ class="cursor-pointer py-2 hover:bg-blue-light flex items-center justify-end"
5
5
  >
6
- {{ fLocalizedDateTime(modelValue, { empty: "Never" }) }}
6
+ {{ fLocalizedDateTime(modelValue, { empty: 'Never' }) }}
7
7
  <EditIcon class="w-4 font-bold ml-2 text-gray-base" />
8
- <QPopupEdit
9
- v-slot="scope"
10
- :model-value="modelValue"
11
- touch-position
12
- :offset="[0, 20]"
13
- class="bg-blue-base text-white !min-w-0"
8
+ <q-popup-edit
9
+ v-slot="scope"
10
+ :model-value="modelValue"
11
+ touch-position
12
+ :offset="[0, 20]"
13
+ class="bg-blue-base text-white !min-w-0"
14
14
  >
15
15
  <DateTimePicker
16
- v-model="scope.value"
17
- :nullable="nullable"
18
- @save="onSave(scope)"
19
- @cancel="scope.cancel"
16
+ v-model="scope.value"
17
+ :nullable="nullable"
18
+ @save="onSave(scope)"
19
+ @cancel="scope.cancel"
20
20
  />
21
- </QPopupEdit>
21
+ </q-popup-edit>
22
22
  </div>
23
23
  </div>
24
24
  </template>
25
25
  <script setup>
26
- import { PencilIcon as EditIcon } from "@heroicons/vue/solid";
27
- import DateTimePicker from "danx/src/components/ActionTable/Form/Fields/DateTimePicker";
28
- import { fLocalizedDateTime } from "danx/src/helpers/formats";
26
+ import { PencilIcon as EditIcon } from '@heroicons/vue/solid';
27
+ import { fLocalizedDateTime } from '@ui/helpers/formats';
28
+ import DateTimePicker from './DateTimePicker';
29
29
 
30
- const emit = defineEmits(["close", "save", "update:model-value"]);
30
+ const emit = defineEmits(['close', 'save', 'update:model-value']);
31
31
  defineProps({
32
32
  modelValue: {
33
33
  type: String,
@@ -37,8 +37,8 @@ defineProps({
37
37
  });
38
38
 
39
39
  function onSave(scope) {
40
- emit("update:model-value", scope.value);
41
- emit("save", scope.value);
40
+ emit('update:model-value', scope.value);
41
+ emit('save', scope.value);
42
42
  scope.set();
43
43
  }
44
44
  </script>
@@ -1,17 +1,17 @@
1
1
  <template>
2
2
  <NumberField
3
- :field="field"
4
- :precision="0"
5
- :model-value="modelValue"
6
- :show-name="showName"
7
- @update:model-value="$emit('update:model-value', $event)"
3
+ :field="field"
4
+ :precision="0"
5
+ :model-value="modelValue"
6
+ :show-name="showName"
7
+ @update:model-value="$emit('update:model-value', $event)"
8
8
  />
9
9
  </template>
10
10
 
11
11
  <script setup>
12
- import NumberField from "danx/src/components/ActionTable/Form/Fields/NumberField";
12
+ import NumberField from './NumberField';
13
13
 
14
- defineEmits(["update:model-value"]);
14
+ defineEmits(['update:model-value']);
15
15
  defineProps({
16
16
  modelValue: {
17
17
  type: [String, Number],
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div>
3
+ <div class="text-xs font-bold">{{ label }}</div>
4
+ <div :class="{'mt-2': !dense, 'mt-1': dense, 'text-no-wrap': nowrap}">
5
+ <slot>{{ value || "-" }}</slot>
6
+ </div>
7
+ </div>
8
+ </template>
9
+ <script setup>
10
+ defineProps({
11
+ label: {
12
+ type: String,
13
+ required: true
14
+ },
15
+ value: {
16
+ type: [String, Number],
17
+ default: "-"
18
+ },
19
+ dense: Boolean,
20
+ nowrap: Boolean
21
+ });
22
+ </script>
@@ -4,34 +4,34 @@
4
4
  <slot name="label">{{ label }}</slot>
5
5
  </label>
6
6
  <div class="mt-1">
7
- <QInput
8
- :model-value="modelValue"
9
- :error-message="error"
10
- :error="!!error"
11
- no-error-icon
12
- outlined
13
- dense
14
- :disable="disabled"
15
- :readonly="disabled"
16
- :type="type"
17
- :name="name"
18
- :placeholder="placeholder || label"
19
- :required="required"
20
- :rules="rules"
21
- :lazy-rules="!!rules"
22
- class="w-full"
23
- @update:model-value="$emit('update:model-value', $event)"
7
+ <q-input
8
+ :model-value="modelValue"
9
+ :error-message="error"
10
+ :error="!!error"
11
+ no-error-icon
12
+ outlined
13
+ dense
14
+ :disable="disabled"
15
+ :readonly="disabled"
16
+ :type="type"
17
+ :name="name"
18
+ :placeholder="placeholder || label"
19
+ :required="required"
20
+ :rules="rules"
21
+ :lazy-rules="!!rules"
22
+ class="w-full"
23
+ @update:model-value="$emit('update:model-value', $event)"
24
24
  />
25
25
  </div>
26
26
  </div>
27
27
  </template>
28
28
 
29
29
  <script setup>
30
- defineEmits(["update:model-value"]);
30
+ defineEmits(['update:model-value']);
31
31
  defineProps({
32
32
  type: {
33
33
  type: String,
34
- default: "text"
34
+ default: 'text'
35
35
  },
36
36
  name: {
37
37
  type: String,
@@ -1,58 +1,58 @@
1
1
  <template>
2
2
  <div
3
- class="max-w-full relative overflow-auto"
4
- :class="{'p-4 border rounded border-gray-medium': !readonly}"
5
- @dragover.prevent
6
- @drop.prevent="onDrop"
3
+ class="max-w-full relative overflow-auto"
4
+ :class="{'p-4 border rounded border-gray-medium': !readonly}"
5
+ @dragover.prevent
6
+ @drop.prevent="onDrop"
7
7
  >
8
8
  <FieldLabel
9
- :field="field"
10
- :show-name="showName"
11
- class="text-sm font-semibold"
9
+ :field="field"
10
+ :show-name="showName"
11
+ class="text-sm font-semibold"
12
12
  />
13
13
  <div
14
- v-if="!disable && !readonly"
15
- class="text-sm my-2"
14
+ v-if="!disable && !readonly"
15
+ class="text-sm my-2"
16
16
  >
17
17
  <a
18
- class="text-blue-base"
19
- @click="$refs.file.click()"
18
+ class="text-blue-base"
19
+ @click="$refs.file.click()"
20
20
  >Upload</a>
21
21
  <a
22
- v-if="uploadedFiles.length > 0"
23
- class="ml-3 text-red-dark"
24
- @click="onClear"
22
+ v-if="uploadedFiles.length > 0"
23
+ class="ml-3 text-red-dark"
24
+ @click="onClear"
25
25
  >Clear</a>
26
26
  <input
27
- ref="file"
28
- class="hidden"
29
- type="file"
30
- multiple
31
- @change="onFilesSelected"
27
+ ref="file"
28
+ class="hidden"
29
+ type="file"
30
+ multiple
31
+ @change="onFilesSelected"
32
32
  />
33
33
  </div>
34
34
 
35
35
  <div class="max-w-[50em] flex items-stretch justify-start">
36
36
  <ImagePreview
37
- v-for="file in uploadedFiles"
38
- :key="'file-upload-' + file.id"
39
- class="w-32 m-2 cursor-pointer bg-neutral-plus-5"
40
- :class="{'border border-dashed border-blue-base': !uploadedFiles.length}"
41
- :image="file"
42
- :related-files="uploadedFiles"
43
- downloadable
44
- :removable="!readonly && !disable"
45
- @remove="onRemove(file)"
37
+ v-for="file in uploadedFiles"
38
+ :key="'file-upload-' + file.id"
39
+ class="w-32 m-2 cursor-pointer bg-neutral-plus-5"
40
+ :class="{'border border-dashed border-blue-base': !uploadedFiles.length}"
41
+ :image="file"
42
+ :related-files="uploadedFiles"
43
+ downloadable
44
+ :removable="!readonly && !disable"
45
+ @remove="onRemove(file)"
46
46
  />
47
47
  <ImagePreview
48
- v-if="!disable && !readonly"
49
- class="w-32 m-2 cursor-pointer border border-dashed border-blue-base"
50
- disabled
51
- @click="$refs.file.click()"
48
+ v-if="!disable && !readonly"
49
+ class="w-32 m-2 cursor-pointer border border-dashed border-blue-base"
50
+ disabled
51
+ @click="$refs.file.click()"
52
52
  />
53
53
  <div
54
- v-if="readonly && uploadedFiles.length === 0"
55
- class="p-1"
54
+ v-if="readonly && uploadedFiles.length === 0"
55
+ class="p-1"
56
56
  >
57
57
  --
58
58
  </div>
@@ -61,12 +61,12 @@
61
61
  </template>
62
62
 
63
63
  <script setup>
64
- import ImagePreview from "components/Common/ImagePreview";
65
- import FieldLabel from "danx/src/components/ActionTable/Form/Fields/FieldLabel";
66
- import { useMultiFileUpload } from "src/helpers/multiFileUpload";
67
- import { onMounted } from "vue";
64
+ import { ImagePreview } from '@ui/components';
65
+ import { useMultiFileUpload } from '@ui/helpers';
66
+ import { onMounted } from 'vue';
67
+ import FieldLabel from './FieldLabel';
68
68
 
69
- const emit = defineEmits(["update:model-value"]);
69
+ const emit = defineEmits(['update:model-value']);
70
70
  const props = defineProps({
71
71
  modelValue: {
72
72
  type: [Object, String],
@@ -87,5 +87,5 @@ onMounted(() => {
87
87
  uploadedFiles.value = props.modelValue;
88
88
  }
89
89
  });
90
- onComplete(() => emit("update:model-value", uploadedFiles.value));
90
+ onComplete(() => emit('update:model-value', uploadedFiles.value));
91
91
  </script>
@@ -1,37 +1,37 @@
1
1
  <template>
2
2
  <div>
3
3
  <SelectField
4
- v-model="selectedFieldName"
5
- :label="undefined"
6
- :options="field.options"
7
- class="mb-2"
8
- @update:model-value="onChange"
4
+ v-model="selectedFieldName"
5
+ :label="undefined"
6
+ :options="field.options"
7
+ class="mb-2"
8
+ @update:model-value="onChange"
9
9
  />
10
10
  <TextField
11
- v-model="textInput"
12
- :field="field"
13
- :no-label="!field.label"
14
- label-class="text-xs font-bold text-gray-dark"
15
- parent-class="tight-label"
16
- input-class="!py-0"
17
- dense
18
- type="textarea"
19
- :debounce="500"
20
- @update:model-value="onChange"
11
+ v-model="textInput"
12
+ :field="field"
13
+ :no-label="!field.label"
14
+ label-class="text-xs font-bold text-gray-dark"
15
+ parent-class="tight-label"
16
+ input-class="!py-0"
17
+ dense
18
+ type="textarea"
19
+ :debounce="500"
20
+ @update:model-value="onChange"
21
21
  />
22
22
  </div>
23
23
  </template>
24
24
 
25
25
  <script setup>
26
- import SelectField from "danx/src/components/ActionTable/Form/Fields/SelectField";
27
- import TextField from "danx/src/components/ActionTable/Form/Fields/TextField";
28
- import { computed, ref, watch } from "vue";
26
+ import { computed, ref, watch } from 'vue';
27
+ import SelectField from './SelectField';
28
+ import TextField from './TextField';
29
29
 
30
- const emit = defineEmits(["update:model-value"]);
30
+ const emit = defineEmits(['update:model-value']);
31
31
  const props = defineProps({
32
32
  modelValue: {
33
33
  type: [String, Number, Object],
34
- default: ""
34
+ default: ''
35
35
  },
36
36
  field: {
37
37
  type: Object,
@@ -43,12 +43,12 @@ const selectedFieldName = ref(props.field.defaultOption);
43
43
  const searchList = computed(() => props.modelValue && props.modelValue[selectedFieldName.value]);
44
44
  const textInput = ref(formatModelValue());
45
45
  function onChange() {
46
- textInput.value = textInput.value?.replace(/\n/g, ",").replace(/,{2,}/g, ",") || "";
47
- emit("update:model-value", textInput.value ? { [selectedFieldName.value]: textInput.value.split(",") } : undefined);
46
+ textInput.value = textInput.value?.replace(/\n/g, ',').replace(/,{2,}/g, ',') || '';
47
+ emit('update:model-value', textInput.value ? { [selectedFieldName.value]: textInput.value.split(',') } : undefined);
48
48
  }
49
49
 
50
50
  function formatModelValue() {
51
- return Array.isArray(searchList.value) ? searchList.value?.join(",") : "";
51
+ return Array.isArray(searchList.value) ? searchList.value?.join(',') : '';
52
52
  }
53
53
 
54
54
  watch(() => props.modelValue, () => {
@@ -1,28 +1,28 @@
1
1
  <template>
2
2
  <LabeledInput
3
- type="password"
4
- v-bind="props"
5
- :rules="rules"
6
- @update:model-value="$emit('update:model-value', $event)"
3
+ type="password"
4
+ v-bind="props"
5
+ :rules="rules"
6
+ @update:model-value="$emit('update:model-value', $event)"
7
7
  />
8
8
  </template>
9
9
 
10
10
  <script setup>
11
- import LabeledInput from "danx/src/components/ActionTable/Form/Fields/LabeledInput";
11
+ import LabeledInput from './LabeledInput';
12
12
 
13
- defineEmits(["update:model-value"]);
13
+ defineEmits(['update:model-value']);
14
14
  const props = defineProps({
15
15
  name: {
16
16
  type: String,
17
- default: "password"
17
+ default: 'password'
18
18
  },
19
19
  label: {
20
20
  type: String,
21
- default: "Password"
21
+ default: 'Password'
22
22
  },
23
23
  placeholder: {
24
24
  type: String,
25
- default: "Enter Password"
25
+ default: 'Enter Password'
26
26
  },
27
27
  modelValue: {
28
28
  type: [String, Number],
@@ -35,5 +35,5 @@ const props = defineProps({
35
35
  disabled: Boolean
36
36
  });
37
37
 
38
- const rules = [(val) => val.length >= 8 || "Please use at least 8 characters"];
38
+ const rules = [(val) => val.length >= 8 || 'Please use at least 8 characters'];
39
39
  </script>
@@ -1,34 +1,34 @@
1
1
  <template>
2
- <QInput
3
- :model-value="numberVal"
4
- :data-testid="'number-field-' + fieldOptions.id"
5
- :placeholder="fieldOptions.placeholder"
6
- outlined
7
- dense
8
- inputmode="numeric"
9
- :input-class="{[inputClass]: true, 'text-right bg-white': !hidePrependLabel, 'text-right !text-xs text-black font-normal': hidePrependLabel}"
10
- :class="{'no-prepend-icon w-32': hidePrependLabel, 'prepend-label': !hidePrependLabel}"
11
- @update:model-value="onInput"
2
+ <q-input
3
+ :model-value="numberVal"
4
+ :data-testid="'number-field-' + fieldOptions.id"
5
+ :placeholder="fieldOptions.placeholder"
6
+ outlined
7
+ dense
8
+ inputmode="numeric"
9
+ :input-class="{[inputClass]: true, 'text-right bg-white': !hidePrependLabel, 'text-right !text-xs text-black font-normal': hidePrependLabel}"
10
+ :class="{'no-prepend-icon w-32': hidePrependLabel, 'prepend-label': !hidePrependLabel}"
11
+ @update:model-value="onInput"
12
12
  >
13
13
  <template #prepend>
14
14
  <FieldLabel
15
- :field="fieldOptions"
16
- :show-name="showName"
15
+ :field="fieldOptions"
16
+ :show-name="showName"
17
17
  />
18
18
  </template>
19
- </QInput>
19
+ </q-input>
20
20
  </template>
21
21
 
22
22
  <script setup>
23
- import FieldLabel from "danx/src/components/ActionTable/Form/Fields/FieldLabel";
24
- import { fNumber } from "danx/src/helpers/formats";
25
- import { computed, nextTick, ref, watch } from "vue";
23
+ import { fNumber } from '@ui/helpers/formats';
24
+ import { computed, nextTick, ref, watch } from 'vue';
25
+ import FieldLabel from './FieldLabel';
26
26
 
27
- const emit = defineEmits(["update:model-value"]);
27
+ const emit = defineEmits(['update:model-value']);
28
28
  const props = defineProps({
29
29
  modelValue: {
30
30
  type: [String, Number],
31
- default: ""
31
+ default: ''
32
32
  },
33
33
  precision: {
34
34
  type: Number,
@@ -44,7 +44,7 @@ const props = defineProps({
44
44
  },
45
45
  inputClass: {
46
46
  type: String,
47
- default: ""
47
+ default: ''
48
48
  },
49
49
  hidePrependLabel: Boolean,
50
50
  currency: Boolean,
@@ -54,41 +54,41 @@ const props = defineProps({
54
54
  const numberVal = ref(format(props.modelValue));
55
55
  watch(() => props.modelValue, () => numberVal.value = format(props.modelValue));
56
56
 
57
- const fieldOptions = computed(() => props.field || { label: props.label || "", placeholder: "", id: "" });
57
+ const fieldOptions = computed(() => props.field || { label: props.label || '', placeholder: '', id: '' });
58
58
 
59
59
  function format(number) {
60
- if (!number && number !== 0 && number !== "0") return number;
60
+ if (!number && number !== 0 && number !== '0') return number;
61
61
 
62
- const minimumFractionDigits = Math.min(props.precision, ("" + number).split(".")[1]?.length || 0);
62
+ const minimumFractionDigits = Math.min(props.precision, ('' + number).split('.')[1]?.length || 0);
63
63
  let options = {
64
64
  minimumFractionDigits
65
65
  };
66
66
 
67
67
  if (props.currency) {
68
68
  options = {
69
- style: "currency",
70
- currency: "USD",
69
+ style: 'currency',
70
+ currency: 'USD',
71
71
  minimumFractionDigits
72
72
  };
73
73
  }
74
74
  return fNumber(number, options);
75
75
  }
76
76
  function onInput(value) {
77
- let number = "";
77
+ let number = '';
78
78
 
79
79
  // Prevent invalid characters
80
80
  if (value.match(/[^\d.,$]/)) {
81
81
  const oldVal = numberVal.value;
82
82
  // XXX: To get QInput to show only the value we want
83
- numberVal.value += " ";
83
+ numberVal.value += ' ';
84
84
  return nextTick(() => numberVal.value = oldVal);
85
85
  }
86
86
 
87
- if (value !== "") {
88
- value = value.replace(/[^\d.]/g, "");
87
+ if (value !== '') {
88
+ value = value.replace(/[^\d.]/g, '');
89
89
  number = Number(value);
90
90
  numberVal.value = format(number);
91
91
  }
92
- emit("update:model-value", number === "" ? undefined : number);
92
+ emit('update:model-value', number === '' ? undefined : number);
93
93
  }
94
94
  </script>