quasar-ui-danx 0.0.27 → 0.0.29

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.0.27",
3
+ "version": "0.0.29",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -1,23 +1,12 @@
1
1
  <template>
2
- <div>
3
- <PopoverMenu
4
- class="px-4 h-full flex"
5
- :items="items"
6
- @action-item="onAction"
7
- />
8
- <Component
9
- v-if="confirmDialog"
10
- :is="confirmDialog.is"
11
- v-bind="confirmDialog.props"
12
- :is-saving="isSaving"
13
- @close="onCancel"
14
- @confirm="onConfirmAction"
15
- />
16
- </div>
2
+ <PopoverMenu
3
+ class="px-4 h-full flex"
4
+ :items="items"
5
+ @action-item="onAction"
6
+ />
17
7
  </template>
18
8
  <script setup>
19
- import { ref, shallowRef } from 'vue';
20
- import { FlashMessages } from '../../helpers';
9
+ import { performAction } from '../../helpers';
21
10
  import { PopoverMenu } from '../Utility';
22
11
 
23
12
  const emit = defineEmits(['action']);
@@ -33,65 +22,8 @@ const props = defineProps({
33
22
  });
34
23
 
35
24
 
36
- const activeAction = shallowRef(null);
37
- const confirmDialog = shallowRef(null);
38
- const isSaving = ref(false);
39
-
40
25
  function onAction(item) {
41
26
  emit('action', item);
42
-
43
- activeAction.value = item;
44
-
45
- if (item.confirmDialog) {
46
- confirmDialog.value = typeof item.confirmDialog === 'function' ? item.confirmDialog(props.rows) : item.confirmDialog;
47
- } else {
48
- console.log('handle default action');
49
- }
50
- }
51
-
52
- function onCancel() {
53
- activeAction.value = null;
54
- confirmDialog.value = null;
27
+ performAction(item, props.rows);
55
28
  }
56
-
57
- async function onConfirmAction(input) {
58
- if (!activeAction.value.onAction) {
59
- throw new Error('No onAction handler found for the selected action:' + activeAction.value.action);
60
- }
61
-
62
- isSaving.value = true;
63
- const result = await activeAction.value.onAction(input, props.rows);
64
- isSaving.value = false;
65
-
66
- if (!result.success) {
67
- const errors = [];
68
- if (result.errors) {
69
- errors.push(...result.errors);
70
- } else if (result.error) {
71
- errors.push(result.error.message);
72
- } else {
73
- errors.push('An unknown error occurred. Please try again later.');
74
- }
75
-
76
- FlashMessages.combine('error', errors);
77
-
78
- if (activeAction.value.onError) {
79
- await activeAction.value.onError(result, input);
80
- }
81
- }
82
-
83
- FlashMessages.success(`The update was successful`);
84
-
85
- if (activeAction.value.onSuccess) {
86
- await activeAction.value.onSuccess(result, input);
87
- }
88
-
89
- if (activeAction.value.onFinish) {
90
- await activeAction.value.onFinish();
91
- }
92
-
93
- confirmDialog.value = null;
94
- activeAction.value = null;
95
- }
96
-
97
29
  </script>
@@ -1,6 +1,6 @@
1
1
  export {
2
2
  default as CollapsableFiltersSidebar
3
3
  } from "./CollapsableFiltersSidebar.vue";
4
- export { default as FilterFieldList } from "src/components/ActionTable/Filters/FilterFieldList.vue";
4
+ export { default as FilterFieldList } from "./FilterFieldList.vue";
5
5
  export { default as FilterListToggle } from "./FilterListToggle.vue";
6
6
  export { default as FilterToolbarLayout } from "./FilterToolbarLayout.vue";
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <div class="flex flex-grow flex-col flex-nowrap overflow-hidden h-full bg-white">
3
+ <slot name="top" />
4
+ <slot name="toolbar" />
5
+ <div class="flex flex-nowrap flex-grow overflow-hidden w-full">
6
+ <slot name="filters" />
7
+ <slot />
8
+ </div>
9
+ <ActionPerformerTool
10
+ v-if="activeAction"
11
+ :targets="actionTargets"
12
+ :action="activeAction"
13
+ @done="clearAction"
14
+ />
15
+ </div>
16
+ </template>
17
+ <script setup>
18
+ import { actionTargets, activeAction, clearAction } from '../../../helpers';
19
+ import { ActionPerformerTool } from '../../Utility';
20
+ </script>
@@ -0,0 +1 @@
1
+ export { default as ActionTableLayout } from "./ActionTableLayout.vue";
@@ -1,5 +1,6 @@
1
1
  export * from "./Filters";
2
2
  export * from "./Form";
3
+ export * from "./Layouts";
3
4
  export * from "./listActions";
4
5
  export * from "./listHelpers";
5
6
  export * from "./tableColumns";
@@ -1,6 +1,6 @@
1
1
  import { computed, ref, watch } from "vue";
2
- import { getItem, setItem } from "../../helpers";
3
- import { getFilterFromUrl, waitForRef } from "./listHelpers";
2
+ import { getItem, setItem, waitForRef } from "../../helpers";
3
+ import { getFilterFromUrl } from "./listHelpers";
4
4
 
5
5
  export function useListActions(name, {
6
6
  listRoute,
@@ -1,4 +1,4 @@
1
- import { onMounted, watch } from "vue";
1
+ import { onMounted } from "vue";
2
2
  import { getUrlParam } from "../../helpers";
3
3
 
4
4
  export function registerStickyScrolling(tableRef) {
@@ -37,29 +37,12 @@ export function mapSortBy(pagination, columns) {
37
37
  ];
38
38
  }
39
39
 
40
- /**
41
- * Wait for a ref to have a value and then resolve the promise
42
- *
43
- * @param ref
44
- * @param value
45
- * @returns {Promise<void>}
46
- */
47
- export function waitForRef(ref, value) {
48
- return new Promise<void>((resolve) => {
49
- watch(ref, (newValue) => {
50
- if (newValue === value) {
51
- resolve();
52
- }
53
- });
54
- });
55
- }
56
-
57
40
  /**
58
41
  * Returns the filter from the URL if it is set
59
42
  * @param url
60
43
  * @param allowedKeys
61
44
  */
62
- export function getFilterFromUrl(url, allowedKeys = null) {
45
+ export function getFilterFromUrl(url: string, allowedKeys = null) {
63
46
  const filter = {};
64
47
  const urlFilter = getUrlParam("filter", url);
65
48
  if (urlFilter) {
@@ -34,7 +34,7 @@
34
34
  </a>
35
35
  <q-item
36
36
  v-else
37
- :key="item.action"
37
+ :key="item.name || item.action"
38
38
  clickable
39
39
  :class="item.class"
40
40
  @click="onAction(item)"
@@ -55,7 +55,7 @@ defineProps({
55
55
  type: Array,
56
56
  required: true,
57
57
  validator(items) {
58
- return items.every((item) => item.label && (item.url || item.action));
58
+ return items.every((item) => item.label && (item.url || item.action || item.name));
59
59
  }
60
60
  },
61
61
  disabled: Boolean,
@@ -63,7 +63,7 @@ defineProps({
63
63
  });
64
64
 
65
65
  function onAction(item) {
66
- emit('action', item.action);
66
+ emit('action', item.name || item.action);
67
67
  emit('action-item', item);
68
68
  }
69
69
  </script>
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <div>
3
+ <Component
4
+ v-if="confirmDialog"
5
+ :is="confirmDialog.is"
6
+ v-bind="confirmDialog.props"
7
+ :is-saving="isSaving"
8
+ @confirm="onConfirmAction"
9
+ @close="$emit('done')"
10
+ />
11
+ </div>
12
+ </template>
13
+ <script setup>
14
+ import { onMounted, ref, shallowRef } from 'vue';
15
+ import { FlashMessages } from '../../../helpers';
16
+
17
+ const emit = defineEmits(['done']);
18
+ const props = defineProps({
19
+ action: {
20
+ type: Object,
21
+ required: true
22
+ },
23
+ targets: {
24
+ type: Array,
25
+ required: true
26
+ }
27
+ });
28
+
29
+ const confirmDialog = shallowRef(props.action.confirmDialog ? props.action.confirmDialog(props.targets) : null);
30
+ const isSaving = ref(null);
31
+
32
+ onMounted(async () => {
33
+ // If there is no dialog, we auto-confirm the action
34
+ if (!confirmDialog.value) {
35
+ await onConfirmAction();
36
+ }
37
+ });
38
+
39
+ async function onConfirmAction(input) {
40
+ if (!props.action.onAction) {
41
+ throw new Error('No onAction handler found for the selected action:' + props.action.name);
42
+ }
43
+
44
+ isSaving.value = true;
45
+ const result = await props.action.onAction(props.targets, input);
46
+ isSaving.value = false;
47
+
48
+ if (!result.success) {
49
+ const errors = [];
50
+ if (result.errors) {
51
+ errors.push(...result.errors);
52
+ } else if (result.error) {
53
+ errors.push(result.error.message);
54
+ } else {
55
+ errors.push('An unknown error occurred. Please try again later.');
56
+ }
57
+
58
+ FlashMessages.combine('error', errors);
59
+
60
+ if (props.action.onError) {
61
+ await props.action.onError(result, props.targets, input);
62
+ }
63
+ }
64
+
65
+ FlashMessages.success(`The update was successful`);
66
+
67
+ if (props.action.onSuccess) {
68
+ await props.action.onSuccess(result, props.targets, input);
69
+ }
70
+
71
+ if (props.action.onFinish) {
72
+ await props.action.onFinish(result, props.targets, input);
73
+ }
74
+
75
+ emit('done');
76
+ }
77
+ </script>
@@ -0,0 +1 @@
1
+ export { default as ActionPerformerTool } from "./ActionPerformerTool.vue";
@@ -4,4 +4,5 @@ export * from "./Files";
4
4
  export * from "./Formats";
5
5
  export * from "./Layouts";
6
6
  export * from "./Popovers";
7
+ export * from "./Tools";
7
8
  export * from "./Transitions";
@@ -9,6 +9,7 @@ export * from "./FlashMessages";
9
9
  export * from "./formats";
10
10
  export * from "./http";
11
11
  export * from "./multiFileUpload";
12
+ export * from "./performAction";
12
13
  export * from "./singleFileUpload";
13
14
  export * from "./storage";
14
15
  export * from "./utils";
@@ -0,0 +1,58 @@
1
+ import { ref } from "vue";
2
+ import { waitForRef } from "./index";
3
+
4
+ export const activeAction = ref(null);
5
+ export const actionTargets = ref([]);
6
+
7
+ /**
8
+ * Hook to perform an action on a set of targets
9
+ * This helper allows you to perform actions by name on a set of targets using a provided list of actions
10
+ *
11
+ * @param actions
12
+ * @returns {{performAction(name, targets): Promise<void>}}
13
+ */
14
+ export function usePerformAction(actions: any[]) {
15
+ return {
16
+ /**
17
+ * Perform an action on a set of targets
18
+ *
19
+ * @param name - can either be a string or an action object
20
+ * @param targets - an array of targets (or a single target object)
21
+ * @returns {Promise<void>}
22
+ */
23
+ async performAction(name, targets) {
24
+ const action = typeof name === "string" ? actions.find(a => a.name === name) : name;
25
+ if (!action) {
26
+ throw new Error(`Unknown action: ${name}`);
27
+ }
28
+ targets = Array.isArray(targets) ? targets : [targets];
29
+
30
+ await performAction(action, targets);
31
+ }
32
+ };
33
+ }
34
+
35
+ /**
36
+ * Perform an action on a set of targets
37
+ *
38
+ * NOTE: This function and variables should be used w/ the ActionPerformerTool - make sure to use a Layout that has
39
+ * rendered this component so the actions will be performed
40
+ *
41
+ * @param action
42
+ * @param targets
43
+ * @returns {Promise<void>}
44
+ */
45
+ export async function performAction(action: any, targets: any[]): Promise<void> {
46
+ activeAction.value = action;
47
+ actionTargets.value = targets;
48
+ await waitForRef(activeAction, null);
49
+ }
50
+
51
+ /**
52
+ * Clear the active action and targets - (note: this will tear down any dialogs / rendered components) triggered by the
53
+ * ActionPerformerTool
54
+ */
55
+ export function clearAction() {
56
+ activeAction.value = null;
57
+ actionTargets.value = [];
58
+ }
@@ -1,3 +1,5 @@
1
+ import { watch } from "vue";
2
+
1
3
  /**
2
4
  * Sleep function to be used in conjuction with async await:
3
5
  *
@@ -7,7 +9,24 @@
7
9
  * @returns {Promise<any>}
8
10
  */
9
11
  export function sleep(delay) {
10
- return new Promise((resolve) => setTimeout(resolve, delay));
12
+ return new Promise((resolve) => setTimeout(resolve, delay));
13
+ }
14
+
15
+ /**
16
+ * Wait for a ref to have a value and then resolve the promise
17
+ *
18
+ * @param ref
19
+ * @param value
20
+ * @returns {Promise<void>}
21
+ */
22
+ export function waitForRef(ref, value) {
23
+ return new Promise<void>((resolve) => {
24
+ watch(ref, (newValue) => {
25
+ if (newValue === value) {
26
+ resolve();
27
+ }
28
+ });
29
+ });
11
30
  }
12
31
 
13
32
  /**
@@ -18,7 +37,7 @@ export function sleep(delay) {
18
37
  * @returns {number}
19
38
  */
20
39
  export function minmax(min, max, value) {
21
- return Math.max(min, Math.min(max, value));
40
+ return Math.max(min, Math.min(max, value));
22
41
  }
23
42
 
24
43
  /**
@@ -27,7 +46,7 @@ export function minmax(min, max, value) {
27
46
  * @returns {number}
28
47
  */
29
48
  export function metersToMiles(meters) {
30
- return meters * 0.000621371;
49
+ return meters * 0.000621371;
31
50
  }
32
51
 
33
52
  /**
@@ -36,7 +55,7 @@ export function metersToMiles(meters) {
36
55
  * @returns {number}
37
56
  */
38
57
  export function milesToMeters(miles) {
39
- return miles / 0.000621371;
58
+ return miles / 0.000621371;
40
59
  }
41
60
 
42
61
  /**
@@ -45,19 +64,19 @@ export function milesToMeters(miles) {
45
64
  * @returns {null|{lng: number, lat: number}}
46
65
  */
47
66
  export function parseCoords(location) {
48
- const latLong = location.split(",");
67
+ const latLong = location.split(",");
49
68
 
50
- if (latLong.length === 2) {
51
- const lat = parseFloat(latLong[0].trim());
52
- const lng = parseFloat(latLong[1].trim());
69
+ if (latLong.length === 2) {
70
+ const lat = parseFloat(latLong[0].trim());
71
+ const lng = parseFloat(latLong[1].trim());
53
72
 
54
- if (!isNaN(lat) && !isNaN(lng)) {
55
- return {
56
- lat,
57
- lng,
58
- };
73
+ if (!isNaN(lat) && !isNaN(lng)) {
74
+ return {
75
+ lat,
76
+ lng,
77
+ };
78
+ }
59
79
  }
60
- }
61
80
 
62
- return null;
81
+ return null;
63
82
  }