quasar-ui-danx 0.3.22 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/.eslintrc.cjs +32 -30
  2. package/danx-local.sh +1 -1
  3. package/dist/danx.es.js +7490 -7519
  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 +64 -45
  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 +22 -21
  15. package/src/components/ActionTable/Form/Fields/DateRangeField.vue +3 -5
  16. package/src/components/ActionTable/Form/Fields/FileUploadButton.vue +33 -34
  17. package/src/components/ActionTable/Form/Fields/TextField.vue +36 -36
  18. package/src/components/ActionTable/Form/RenderedForm.vue +137 -112
  19. package/src/components/ActionTable/Form/form.d.ts +31 -0
  20. package/src/components/ActionTable/Layouts/ActionTableLayout.vue +88 -4
  21. package/src/components/ActionTable/TableSummaryRow.vue +4 -4
  22. package/src/components/ActionTable/Toolbars/ActionToolbar.vue +46 -0
  23. package/src/components/ActionTable/Toolbars/index.ts +1 -0
  24. package/src/components/ActionTable/index.ts +1 -2
  25. package/src/components/ActionTable/listControls.ts +512 -385
  26. package/src/components/ActionTable/listHelpers.ts +46 -44
  27. package/src/components/PanelsDrawer/PanelsDrawer.vue +37 -26
  28. package/src/components/PanelsDrawer/PanelsDrawerPanels.vue +1 -1
  29. package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +1 -6
  30. package/src/components/Utility/Buttons/ExportButton.vue +1 -1
  31. package/src/components/Utility/Buttons/RefreshButton.vue +5 -5
  32. package/src/components/Utility/Controls/PreviousNextControls.vue +4 -4
  33. package/src/components/Utility/Layouts/CollapsableSidebar.vue +2 -8
  34. package/src/components/Utility/Popovers/PopoverMenu.vue +3 -3
  35. package/src/helpers/actions.ts +197 -187
  36. package/src/styles/general.scss +12 -11
  37. package/src/styles/quasar-reset.scss +59 -11
  38. package/src/styles/themes/danx/action-table.scss +19 -0
  39. package/src/styles/themes/danx/buttons.scss +13 -0
  40. package/src/styles/themes/danx/forms.scss +5 -0
  41. package/src/styles/themes/danx/index.scss +3 -0
  42. package/src/styles/themes/danx/panels.scss +19 -0
  43. package/src/styles/themes/danx/sidebar.scss +3 -0
  44. package/src/styles/themes/danx/toolbar.scss +3 -0
  45. package/types/index.d.ts +1 -0
  46. 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.1",
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"
10
+ :pagination="pagination"
8
11
  :columns="columns"
9
- :loading="isLoadingList"
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, columns)})"
19
22
  >
20
23
  <template #no-data>
21
24
  <slot name="empty">
@@ -24,10 +27,11 @@
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
36
  :columns="columns"
33
37
  @clear="$emit('update:selected-rows', [])"
@@ -60,58 +64,73 @@
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 hasData = computed(() => props.pagedItems?.data?.length);
112
120
  const COLUMN_SETTINGS_KEY = `column-settings-${props.name}`;
113
121
  const columnSettings = ref(getItem(COLUMN_SETTINGS_KEY) || {});
114
122
  function onUpdateColumnSettings() {
115
- setItem(COLUMN_SETTINGS_KEY, columnSettings.value);
123
+ setItem(COLUMN_SETTINGS_KEY, columnSettings.value);
116
124
  }
117
125
  </script>
126
+
127
+ <style scoped lang="scss">
128
+ .dx-action-table {
129
+ &.dx-no-data {
130
+ :deep(.q-table__middle) {
131
+ flex-grow: 0;
132
+ flex-shrink: 1;
133
+ }
134
+ }
135
+ }
136
+ </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";
@@ -2,36 +2,37 @@
2
2
  <CollapsableSidebar
3
3
  :collapse="!showFilters"
4
4
  disabled
5
- min-width="0"
6
- max-width="18rem"
5
+ :min-width="minWidth"
6
+ :max-width="maxWidth"
7
7
  :name="name"
8
8
  @update:collapse="$emit('update:show-filters', !$event)"
9
9
  >
10
10
  <FilterFieldList
11
- :filter="filter"
12
- :filter-fields="filterFields"
13
- @update:filter="$emit('update:filter', $event)"
11
+ :filter="activeFilter"
12
+ :filter-fields="filters"
13
+ @update:filter="$emit('update:active-filter', $event)"
14
14
  />
15
15
  </CollapsableSidebar>
16
16
  </template>
17
- <script setup>
17
+ <script setup lang="ts">
18
+ import { FilterField, ListControlsFilter } from "src/components/ActionTable/listControls";
18
19
  import { FilterFieldList } from ".";
19
20
  import { CollapsableSidebar } from "../../Utility";
20
21
 
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
- }
22
+ defineEmits(["update:active-filter", "update:show-filters"]);
23
+
24
+ export interface Props {
25
+ name: string,
26
+ showFilters?: boolean,
27
+ activeFilter: ListControlsFilter,
28
+ minWidth?: string,
29
+ maxWidth?: string,
30
+ filters?: FilterField[]
31
+ }
32
+
33
+ withDefaults(defineProps<Props>(), {
34
+ minWidth: "5rem",
35
+ maxWidth: "18rem",
36
+ filters: () => []
36
37
  });
37
38
  </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({
@@ -12,8 +12,8 @@
12
12
  ref="fileUpload"
13
13
  data-testid="file-upload"
14
14
  type="file"
15
- :accept="(geolocation && cameraOnly) ? 'image/*;capture=camera' : undefined"
16
- :capture="(geolocation && cameraOnly) ? 'environment' : undefined"
15
+ :accept="geolocation ? 'image/*;capture=camera' : undefined"
16
+ :capture="geolocation ? 'environment' : undefined"
17
17
  class="hidden"
18
18
  multiple
19
19
  @change="onAttachFiles"
@@ -28,29 +28,28 @@ import { FileUpload } from "../../../../helpers";
28
28
 
29
29
  defineExpose({ upload });
30
30
  const emit = defineEmits([
31
- "uploading",
32
- "file-progress",
33
- "file-complete",
34
- "complete"
31
+ "uploading",
32
+ "file-progress",
33
+ "file-complete",
34
+ "complete"
35
35
  ]);
36
36
  const props = defineProps({
37
- ...QBtn.props,
38
- text: {
39
- type: String,
40
- default: "Add File"
41
- },
42
- locationWaitMessage: {
43
- type: String,
44
- default: "Waiting for location..."
45
- },
46
- cameraOnly: Boolean,
47
- geolocation: Boolean
37
+ ...QBtn.props,
38
+ text: {
39
+ type: String,
40
+ default: "Add File"
41
+ },
42
+ locationWaitMessage: {
43
+ type: String,
44
+ default: "Waiting for location..."
45
+ },
46
+ geolocation: Boolean
48
47
  });
49
48
 
50
49
  const fileUpload = ref(null);
51
50
 
52
51
  function upload() {
53
- fileUpload.value.click();
52
+ fileUpload.value.click();
54
53
  }
55
54
 
56
55
  /**
@@ -60,23 +59,23 @@ function upload() {
60
59
  * @returns {Promise<void>}
61
60
  */
62
61
  async function onAttachFiles({ target: { files } }) {
63
- emit("uploading", files);
64
- let fileUpload = new FileUpload(files)
65
- .onProgress(({ file, progress }) => {
66
- file.progress = progress;
67
- emit("file-progress", file);
68
- })
69
- .onComplete(({ file, uploadedFile }) => {
70
- emit("file-complete", { file, uploadedFile });
71
- })
72
- .onAllComplete(() => {
73
- emit("complete", fileUpload.files);
74
- });
62
+ emit("uploading", files);
63
+ let fileUpload = new FileUpload(files)
64
+ .onProgress(({ file, progress }) => {
65
+ file.progress = progress;
66
+ emit("file-progress", file);
67
+ })
68
+ .onComplete(({ file, uploadedFile }) => {
69
+ emit("file-complete", { file, uploadedFile });
70
+ })
71
+ .onAllComplete(() => {
72
+ emit("complete", fileUpload.files);
73
+ });
75
74
 
76
- if (props.geolocation) {
77
- await fileUpload.resolveLocation(props.locationWaitMessage);
78
- }
75
+ if (props.geolocation) {
76
+ await fileUpload.resolveLocation(props.locationWaitMessage);
77
+ }
79
78
 
80
- fileUpload.upload();
79
+ fileUpload.upload();
81
80
  }
82
81
  </script>
@@ -42,41 +42,41 @@ import LabelValueBlock from "./LabelValueBlock";
42
42
 
43
43
  defineEmits(["update:model-value", "submit"]);
44
44
  defineProps({
45
- modelValue: {
46
- type: [String, Number],
47
- default: ""
48
- },
49
- field: {
50
- type: Object,
51
- default: null
52
- },
53
- type: {
54
- type: String,
55
- default: "text"
56
- },
57
- label: {
58
- type: String,
59
- default: null
60
- },
61
- labelClass: {
62
- type: String,
63
- default: "text-sm text-gray-700"
64
- },
65
- parentClass: {
66
- type: String,
67
- default: ""
68
- },
69
- inputClass: {
70
- type: String,
71
- default: ""
72
- },
73
- noLabel: Boolean,
74
- showName: Boolean,
75
- disabled: Boolean,
76
- readonly: Boolean,
77
- debounce: {
78
- type: [String, Number],
79
- default: 0
80
- }
45
+ modelValue: {
46
+ type: [String, Number],
47
+ default: ""
48
+ },
49
+ field: {
50
+ type: Object,
51
+ default: null
52
+ },
53
+ type: {
54
+ type: String,
55
+ default: "text"
56
+ },
57
+ label: {
58
+ type: String,
59
+ default: null
60
+ },
61
+ labelClass: {
62
+ type: String,
63
+ default: ""
64
+ },
65
+ parentClass: {
66
+ type: String,
67
+ default: ""
68
+ },
69
+ inputClass: {
70
+ type: String,
71
+ default: ""
72
+ },
73
+ noLabel: Boolean,
74
+ showName: Boolean,
75
+ disabled: Boolean,
76
+ readonly: Boolean,
77
+ debounce: {
78
+ type: [String, Number],
79
+ default: 0
80
+ }
81
81
  });
82
82
  </script>