quasar-ui-danx 0.3.22 → 0.4.2

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 (53) hide show
  1. package/.eslintrc.cjs +32 -30
  2. package/danx-local.sh +1 -1
  3. package/dist/danx.es.js +7413 -7461
  4. package/dist/danx.es.js.map +1 -1
  5. package/dist/danx.umd.js +5 -5
  6. package/dist/danx.umd.js.map +1 -1
  7. package/dist/style.css +1 -1
  8. package/package.json +1 -1
  9. package/src/components/ActionTable/ActionMenu.vue +1 -1
  10. package/src/components/ActionTable/ActionTable.vue +67 -47
  11. package/src/components/ActionTable/{ActionTableColumn.vue → Columns/ActionTableColumn.vue} +4 -3
  12. package/src/components/ActionTable/{ActionTableHeaderColumn.vue → Columns/ActionTableHeaderColumn.vue} +2 -2
  13. package/src/components/ActionTable/Columns/index.ts +2 -0
  14. package/src/components/ActionTable/Filters/CollapsableFiltersSidebar.vue +23 -21
  15. package/src/components/ActionTable/Form/Fields/DateRangeField.vue +3 -5
  16. package/src/components/ActionTable/Form/Fields/NumberField.vue +60 -59
  17. package/src/components/ActionTable/Form/Fields/SelectField.vue +135 -135
  18. package/src/components/ActionTable/Form/Fields/TextField.vue +36 -36
  19. package/src/components/ActionTable/Form/RenderedForm.vue +133 -112
  20. package/src/components/ActionTable/Form/form.d.ts +31 -0
  21. package/src/components/ActionTable/Layouts/ActionTableLayout.vue +93 -4
  22. package/src/components/ActionTable/TableSummaryRow.vue +4 -4
  23. package/src/components/ActionTable/Toolbars/ActionToolbar.vue +46 -0
  24. package/src/components/ActionTable/Toolbars/index.ts +1 -0
  25. package/src/components/ActionTable/index.ts +1 -2
  26. package/src/components/ActionTable/listControls.ts +512 -385
  27. package/src/components/ActionTable/listHelpers.ts +46 -44
  28. package/src/components/ActionTable/tableColumns.ts +66 -66
  29. package/src/components/PanelsDrawer/PanelsDrawer.vue +37 -26
  30. package/src/components/PanelsDrawer/PanelsDrawerPanels.vue +1 -1
  31. package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +1 -6
  32. package/src/components/Utility/Buttons/ExportButton.vue +1 -1
  33. package/src/components/Utility/Buttons/RefreshButton.vue +5 -5
  34. package/src/components/Utility/Controls/PreviousNextControls.vue +4 -4
  35. package/src/components/Utility/Dialogs/ConfirmDialog.vue +69 -115
  36. package/src/components/Utility/Dialogs/DialogLayout.vue +95 -0
  37. package/src/components/Utility/Dialogs/InfoDialog.vue +40 -80
  38. package/src/components/Utility/Layouts/CollapsableSidebar.vue +2 -8
  39. package/src/components/Utility/Popovers/PopoverMenu.vue +3 -3
  40. package/src/components/Utility/Tools/RenderVnode.vue +21 -12
  41. package/src/helpers/actions.ts +198 -188
  42. package/src/styles/general.scss +12 -11
  43. package/src/styles/quasar-reset.scss +81 -22
  44. package/src/styles/themes/danx/action-table.scss +19 -0
  45. package/src/styles/themes/danx/buttons.scss +13 -0
  46. package/src/styles/themes/danx/dialogs.scss +43 -0
  47. package/src/styles/themes/danx/forms.scss +23 -0
  48. package/src/styles/themes/danx/index.scss +7 -0
  49. package/src/styles/themes/danx/panels.scss +19 -0
  50. package/src/styles/themes/danx/sidebar.scss +3 -0
  51. package/src/styles/themes/danx/toolbar.scss +3 -0
  52. package/types/index.d.ts +1 -0
  53. package/src/styles/actions.scss +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quasar-ui-danx",
3
- "version": "0.3.22",
3
+ "version": "0.4.2",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <PopoverMenu
3
- class="px-2 flex action-button"
3
+ class="px-2 flex dx-action-button"
4
4
  :items="activeActions"
5
5
  :disabled="!hasTarget"
6
6
  :tooltip="!hasTarget ? tooltip : null"
@@ -1,21 +1,24 @@
1
1
  <template>
2
- <div class="overflow-hidden w-full">
2
+ <div
3
+ class="dx-action-table overflow-hidden"
4
+ :class="{'dx-no-data': !hasData}"
5
+ >
3
6
  <ActionVnode />
4
7
  <QTable
5
8
  ref="actionTable"
6
9
  :selected="selectedRows"
7
- :pagination="quasarPagination"
8
- :columns="columns"
9
- :loading="isLoadingList"
10
+ :pagination="pagination"
11
+ :columns="tableColumns"
12
+ :loading="loadingList"
10
13
  :rows="pagedItems?.data || []"
11
14
  :binary-state-sort="false"
12
15
  selection="multiple"
13
16
  :rows-per-page-options="rowsPerPageOptions"
14
17
  class="sticky-column sticky-header w-full h-full !border-0"
15
- color="blue-600"
18
+ :color="color"
16
19
  @update:selected="$emit('update:selected-rows', $event)"
17
20
  @update:pagination="() => {}"
18
- @request="$emit('update:quasar-pagination', {...$event.pagination, __sort: mapSortBy($event.pagination, columns)})"
21
+ @request="(e) => $emit('update:pagination', {...e.pagination, __sort: mapSortBy(e.pagination, tableColumns)})"
19
22
  >
20
23
  <template #no-data>
21
24
  <slot name="empty">
@@ -24,12 +27,13 @@
24
27
  </template>
25
28
  <template #top-row>
26
29
  <TableSummaryRow
30
+ v-if="hasData"
27
31
  :label="label"
28
32
  :item-count="summary?.count || 0"
29
33
  :selected-count="selectedRows.length"
30
- :loading="isLoadingSummary"
34
+ :loading="loadingSummary"
31
35
  :summary="summary"
32
- :columns="columns"
36
+ :columns="tableColumns"
33
37
  @clear="$emit('update:selected-rows', [])"
34
38
  />
35
39
  </template>
@@ -60,58 +64,74 @@
60
64
 
61
65
  <script setup>
62
66
  import { QTable } from "quasar";
63
- import { ref } from "vue";
67
+ import { computed, ref } from "vue";
64
68
  import { getItem, setItem } from "../../helpers";
65
69
  import { ActionVnode } from "../Utility";
66
- import ActionTableColumn from "./ActionTableColumn.vue";
67
- import ActionTableHeaderColumn from "./ActionTableHeaderColumn";
70
+ import { ActionTableColumn, ActionTableHeaderColumn } from "./Columns";
68
71
  import EmptyTableState from "./EmptyTableState.vue";
69
72
  import { mapSortBy, registerStickyScrolling } from "./listHelpers";
70
73
  import TableSummaryRow from "./TableSummaryRow.vue";
71
74
 
72
- defineEmits(["update:quasar-pagination", "update:selected-rows"]);
75
+ defineEmits(["update:selected-rows", "update:pagination"]);
73
76
  const props = defineProps({
74
- name: {
75
- type: String,
76
- required: true
77
- },
78
- label: {
79
- type: String,
80
- required: true
81
- },
82
- selectedRows: {
83
- type: Array,
84
- required: true
85
- },
86
- quasarPagination: {
87
- type: Object,
88
- required: true
89
- },
90
- isLoadingList: Boolean,
91
- pagedItems: {
92
- type: Object,
93
- default: null
94
- },
95
- isLoadingSummary: Boolean,
96
- summary: {
97
- type: Object,
98
- default: null
99
- },
100
- columns: {
101
- type: Array,
102
- required: true
103
- },
104
- rowsPerPageOptions: {
105
- type: Array,
106
- default: () => [10, 25, 50, 100]
107
- }
77
+ name: {
78
+ type: String,
79
+ required: true
80
+ },
81
+ label: {
82
+ type: String,
83
+ required: true
84
+ },
85
+ color: {
86
+ type: String,
87
+ default: "blue-600"
88
+ },
89
+ selectedRows: {
90
+ type: Array,
91
+ required: true
92
+ },
93
+ pagination: {
94
+ type: Object,
95
+ required: true
96
+ },
97
+ loadingList: Boolean,
98
+ loadingSummary: Boolean,
99
+ pagedItems: {
100
+ type: Object,
101
+ default: null
102
+ },
103
+ summary: {
104
+ type: Object,
105
+ default: null
106
+ },
107
+ columns: {
108
+ type: Array,
109
+ required: true
110
+ },
111
+ rowsPerPageOptions: {
112
+ type: Array,
113
+ default: () => [10, 25, 50, 100]
114
+ }
108
115
  });
109
116
  const actionTable = ref(null);
110
117
  registerStickyScrolling(actionTable);
111
118
 
119
+ const tableColumns = computed(() => props.columns.map((column) => ({ ...column, field: column.field || column.name })));
120
+ const hasData = computed(() => props.pagedItems?.data?.length);
112
121
  const COLUMN_SETTINGS_KEY = `column-settings-${props.name}`;
113
122
  const columnSettings = ref(getItem(COLUMN_SETTINGS_KEY) || {});
114
123
  function onUpdateColumnSettings() {
115
- setItem(COLUMN_SETTINGS_KEY, columnSettings.value);
124
+ setItem(COLUMN_SETTINGS_KEY, columnSettings.value);
116
125
  }
117
126
  </script>
127
+
128
+ <style scoped lang="scss">
129
+ .dx-action-table {
130
+ &.dx-no-data {
131
+ :deep(.q-table__middle) {
132
+ flex-grow: 0;
133
+ flex-shrink: 1;
134
+ }
135
+ }
136
+ }
137
+ </style>
@@ -44,6 +44,7 @@
44
44
  class="flex flex-shrink-0 pl-2"
45
45
  >
46
46
  <ActionMenu
47
+ class="dx-column-action-menu"
47
48
  :actions="column.actionMenu"
48
49
  :target="row"
49
50
  :loading="isSaving"
@@ -56,9 +57,9 @@
56
57
  <script setup>
57
58
  import { QTd } from "quasar";
58
59
  import { computed } from "vue";
59
- import { RenderVnode } from "../Utility";
60
- import ActionMenu from "./ActionMenu";
61
- import { TitleColumnFormat } from "./Columns";
60
+ import { RenderVnode } from "../../Utility";
61
+ import ActionMenu from "../ActionMenu";
62
+ import { TitleColumnFormat } from "./";
62
63
 
63
64
  const props = defineProps({
64
65
  rowProps: {
@@ -20,8 +20,8 @@
20
20
  <script setup>
21
21
  import { QTh } from "quasar";
22
22
  import { computed } from "vue";
23
- import { DragHandleIcon as RowResizeIcon } from "../../svg";
24
- import { HandleDraggable } from "../DragAndDrop";
23
+ import { DragHandleIcon as RowResizeIcon } from "../../../svg";
24
+ import { HandleDraggable } from "../../DragAndDrop";
25
25
 
26
26
  const emit = defineEmits(["update:model-value"]);
27
27
  const props = defineProps({
@@ -1,3 +1,5 @@
1
+ export { default as ActionTableColumn } from "./ActionTableColumn.vue";
2
+ export { default as ActionTableHeaderColumn } from "./ActionTableHeaderColumn.vue";
1
3
  export { default as ColumnListItem } from "./ColumnListItem.vue";
2
4
  export { default as ColumnSettingsDialog } from "./ColumnSettingsDialog.vue";
3
5
  export { default as TitleColumnFormat } from "./TitleColumnFormat.vue";
@@ -1,37 +1,39 @@
1
1
  <template>
2
2
  <CollapsableSidebar
3
+ class="dx-collapsable-filters-sidebar"
3
4
  :collapse="!showFilters"
4
5
  disabled
5
- min-width="0"
6
- max-width="18rem"
6
+ :min-width="minWidth"
7
+ :max-width="maxWidth"
7
8
  :name="name"
8
9
  @update:collapse="$emit('update:show-filters', !$event)"
9
10
  >
10
11
  <FilterFieldList
11
- :filter="filter"
12
- :filter-fields="filterFields"
13
- @update:filter="$emit('update:filter', $event)"
12
+ :filter="activeFilter"
13
+ :filter-fields="filters"
14
+ @update:filter="$emit('update:active-filter', $event)"
14
15
  />
15
16
  </CollapsableSidebar>
16
17
  </template>
17
- <script setup>
18
+ <script setup lang="ts">
19
+ import { FilterField, ListControlsFilter } from "src/components/ActionTable/listControls";
18
20
  import { FilterFieldList } from ".";
19
21
  import { CollapsableSidebar } from "../../Utility";
20
22
 
21
- defineEmits(["update:filter", "update:show-filters"]);
22
- defineProps({
23
- name: {
24
- type: String,
25
- required: true
26
- },
27
- showFilters: Boolean,
28
- filter: {
29
- type: Object,
30
- default: null
31
- },
32
- filterFields: {
33
- type: Array,
34
- default: () => []
35
- }
23
+ defineEmits(["update:active-filter", "update:show-filters"]);
24
+
25
+ export interface Props {
26
+ name: string,
27
+ showFilters?: boolean,
28
+ activeFilter: ListControlsFilter,
29
+ minWidth?: string,
30
+ maxWidth?: string,
31
+ filters?: FilterField[]
32
+ }
33
+
34
+ withDefaults(defineProps<Props>(), {
35
+ minWidth: "5rem",
36
+ maxWidth: "18rem",
37
+ filters: () => []
36
38
  });
37
39
  </script>
@@ -1,10 +1,7 @@
1
1
  <template>
2
2
  <div>
3
- <div
4
- v-if="label"
5
- class="font-bold text-xs mb-2"
6
- >
7
- {{ label }}
3
+ <div class="mb-2">
4
+ <FieldLabel :label="label" />
8
5
  </div>
9
6
  <template v-if="inline">
10
7
  <QDate
@@ -41,6 +38,7 @@
41
38
  import { CalendarIcon as DateIcon } from "@heroicons/vue/outline";
42
39
  import { computed, ref, watch } from "vue";
43
40
  import { fDate, parseQDate, parseQDateTime } from "../../../../helpers";
41
+ import FieldLabel from "./FieldLabel";
44
42
 
45
43
  const emit = defineEmits(["update:model-value"]);
46
44
  const props = defineProps({
@@ -1,13 +1,14 @@
1
1
  <template>
2
2
  <QInput
3
+ class="dx-number-field max-w-full"
4
+ :class="{'dx-no-prepend-label': hidePrependLabel, 'dx-prepend-label': !hidePrependLabel}"
3
5
  :model-value="numberVal"
4
6
  :data-testid="'number-field-' + fieldOptions.id"
5
7
  :placeholder="fieldOptions.placeholder"
6
8
  outlined
7
9
  dense
8
10
  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 max-w-full': hidePrependLabel, 'prepend-label': !hidePrependLabel}"
11
+ :input-class="inputClass"
11
12
  @update:model-value="onInput"
12
13
  >
13
14
  <template #prepend>
@@ -27,33 +28,33 @@ import FieldLabel from "./FieldLabel";
27
28
 
28
29
  const emit = defineEmits(["update:model-value", "update"]);
29
30
  const props = defineProps({
30
- modelValue: {
31
- type: [String, Number],
32
- default: ""
33
- },
34
- precision: {
35
- type: Number,
36
- default: 2
37
- },
38
- label: {
39
- type: String,
40
- default: undefined
41
- },
42
- field: {
43
- type: Object,
44
- default: null
45
- },
46
- inputClass: {
47
- type: String,
48
- default: ""
49
- },
50
- delay: {
51
- type: Number,
52
- default: 1000
53
- },
54
- hidePrependLabel: Boolean,
55
- currency: Boolean,
56
- showName: Boolean
31
+ modelValue: {
32
+ type: [String, Number],
33
+ default: ""
34
+ },
35
+ precision: {
36
+ type: Number,
37
+ default: 2
38
+ },
39
+ label: {
40
+ type: String,
41
+ default: undefined
42
+ },
43
+ field: {
44
+ type: Object,
45
+ default: null
46
+ },
47
+ inputClass: {
48
+ type: [String, Object],
49
+ default: ""
50
+ },
51
+ delay: {
52
+ type: Number,
53
+ default: 1000
54
+ },
55
+ hidePrependLabel: Boolean,
56
+ currency: Boolean,
57
+ showName: Boolean
57
58
  });
58
59
 
59
60
  const numberVal = ref(format(props.modelValue));
@@ -62,46 +63,46 @@ watch(() => props.modelValue, () => numberVal.value = format(props.modelValue));
62
63
  const fieldOptions = computed(() => props.field || { label: props.label || "", placeholder: "", id: "" });
63
64
 
64
65
  function format(number) {
65
- if (!number && number !== 0 && number !== "0") return number;
66
+ if (!number && number !== 0 && number !== "0") return number;
66
67
 
67
- const minimumFractionDigits = Math.min(props.precision, ("" + number).split(".")[1]?.length || 0);
68
- let options = {
69
- minimumFractionDigits
70
- };
68
+ const minimumFractionDigits = Math.min(props.precision, ("" + number).split(".")[1]?.length || 0);
69
+ let options = {
70
+ minimumFractionDigits
71
+ };
71
72
 
72
- if (props.currency) {
73
- options = {
74
- style: "currency",
75
- currency: "USD",
76
- minimumFractionDigits
77
- };
78
- }
79
- return fNumber(number, options);
73
+ if (props.currency) {
74
+ options = {
75
+ style: "currency",
76
+ currency: "USD",
77
+ minimumFractionDigits
78
+ };
79
+ }
80
+ return fNumber(number, options);
80
81
  }
81
82
 
82
83
  const onUpdateDebounced = useDebounceFn((val) => emit("update", val), props.delay);
83
84
 
84
85
  function onInput(value) {
85
- let number = "";
86
+ let number = "";
86
87
 
87
- // Prevent invalid characters
88
- if (value.match(/[^\d.,$]/)) {
89
- const oldVal = numberVal.value;
90
- // XXX: To get QInput to show only the value we want
91
- numberVal.value += " ";
92
- return nextTick(() => numberVal.value = oldVal);
93
- }
88
+ // Prevent invalid characters
89
+ if (value.match(/[^\d.,$]/)) {
90
+ const oldVal = numberVal.value;
91
+ // XXX: To get QInput to show only the value we want
92
+ numberVal.value += " ";
93
+ return nextTick(() => numberVal.value = oldVal);
94
+ }
94
95
 
95
- if (value !== "") {
96
- value = value.replace(/[^\d.]/g, "");
97
- number = Number(value);
98
- numberVal.value = format(number);
99
- }
96
+ if (value !== "") {
97
+ value = value.replace(/[^\d.]/g, "");
98
+ number = Number(value);
99
+ numberVal.value = format(number);
100
+ }
100
101
 
101
- number = number === "" ? undefined : number;
102
- emit("update:model-value", number);
102
+ number = number === "" ? undefined : number;
103
+ emit("update:model-value", number);
103
104
 
104
- // Delay the change event, so we only see the value after the user has finished
105
- onUpdateDebounced(number);
105
+ // Delay the change event, so we only see the value after the user has finished
106
+ onUpdateDebounced(number);
106
107
  }
107
108
  </script>