quasar-ui-danx 0.0.30 → 0.0.32

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quasar-ui-danx",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -1,11 +1,15 @@
1
1
  <template>
2
2
  <PopoverMenu
3
- class="px-4 h-full flex"
4
- :items="items"
3
+ class="px-2 flex action-button"
4
+ :items="activeItems"
5
+ :disabled="targets.length === 0"
5
6
  @action-item="onAction"
6
- />
7
+ >
8
+ <q-tooltip v-if="targets.length === 0">{{ tooltip }}</q-tooltip>
9
+ </PopoverMenu>
7
10
  </template>
8
11
  <script setup>
12
+ import { computed } from 'vue';
9
13
  import { performAction } from '../../helpers';
10
14
  import { PopoverMenu } from '../Utility';
11
15
 
@@ -15,15 +19,23 @@ const props = defineProps({
15
19
  type: Array,
16
20
  required: true
17
21
  },
18
- rows: {
22
+ targets: {
19
23
  type: Array,
20
24
  required: true
25
+ },
26
+ tooltip: {
27
+ type: String,
28
+ default: 'First select records to perform a batch action'
21
29
  }
22
30
  });
23
31
 
32
+ const activeItems = computed(() => props.items.filter(item => {
33
+ if (item.enabled === undefined) return true;
34
+ return typeof item.enabled === 'function' ? !!item.enabled(props.targets?.[0] ?? null, props.targets) : !!item.enabled;
35
+ }));
24
36
 
25
37
  function onAction(item) {
26
38
  emit('action', item);
27
- performAction(item, props.rows);
39
+ performAction(item, props.targets);
28
40
  }
29
41
  </script>
@@ -52,6 +52,7 @@
52
52
  <component
53
53
  :is="rowProps.col.onClick ? 'a' : 'div'"
54
54
  class="flex items-center flex-nowrap"
55
+ :class="{'justify-end': rowProps.col.align === 'right', 'justify-center': rowProps.col.align === 'center', 'justify-start': rowProps.col.align === 'left'}"
55
56
  @click="() => rowProps.col.onClick && rowProps.col.onClick(rowProps.row)"
56
57
  >
57
58
  <RenderComponent
@@ -72,7 +73,7 @@
72
73
  <ActionMenu
73
74
  v-if="rowProps.col.actions" class="ml-2"
74
75
  :items="rowProps.col.actions"
75
- :rows="[rowProps.row]"
76
+ :targets="[rowProps.row]"
76
77
  @action="(action) => $emit('action', {action: action, row: rowProps.row})"
77
78
  />
78
79
  </component>
@@ -3,6 +3,7 @@
3
3
  class="p-3 actionable"
4
4
  :class="{'opacity-50 cursor-not-allowed': disabled}"
5
5
  >
6
+ <slot />
6
7
  <Transition
7
8
  mode="out-in"
8
9
  :duration="150"
@@ -45,7 +45,15 @@ async function onConfirmAction(input) {
45
45
  const result = await props.action.onAction(props.targets, input);
46
46
  isSaving.value = false;
47
47
 
48
- if (!result.success) {
48
+ if (result.success) {
49
+ FlashMessages.success(`The update was successful`);
50
+
51
+ if (props.action.onSuccess) {
52
+ await props.action.onSuccess(result, props.targets, input);
53
+ }
54
+
55
+ emit('done');
56
+ } else {
49
57
  const errors = [];
50
58
  if (result.errors) {
51
59
  errors.push(...result.errors);
@@ -62,16 +70,8 @@ async function onConfirmAction(input) {
62
70
  }
63
71
  }
64
72
 
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
73
  if (props.action.onFinish) {
72
74
  await props.action.onFinish(result, props.targets, input);
73
75
  }
74
-
75
- emit('done');
76
76
  }
77
77
  </script>
@@ -1,26 +1,26 @@
1
1
  export const request = {
2
- async get(url, options = {}) {
3
- return fetch(url, {
4
- method: "get",
5
- headers: {
6
- Accept: "application/json",
7
- "Content-Type": "application/json"
8
- },
9
- ...options
10
- });
11
- },
2
+ async get(url, options = {}) {
3
+ return fetch(url, {
4
+ method: "get",
5
+ headers: {
6
+ Accept: "application/json",
7
+ "Content-Type": "application/json"
8
+ },
9
+ ...options
10
+ }).then((r) => r.json());
11
+ },
12
12
 
13
- async post(url, data = {}, options = {}) {
14
- return fetch(url, {
15
- method: "post",
16
- body: JSON.stringify(data),
17
- headers: {
18
- Accept: "application/json",
19
- "Content-Type": "application/json"
20
- },
21
- ...options
22
- }).then((r) => r.json());
23
- }
13
+ async post(url, data = {}, options = {}) {
14
+ return fetch(url, {
15
+ method: "post",
16
+ body: JSON.stringify(data),
17
+ headers: {
18
+ Accept: "application/json",
19
+ "Content-Type": "application/json"
20
+ },
21
+ ...options
22
+ }).then((r) => r.json());
23
+ }
24
24
  };
25
25
 
26
26
  /**
@@ -36,19 +36,19 @@ export const request = {
36
36
  * @returns {Promise<void>}
37
37
  */
38
38
  export async function fetchResourceListWithSelected(fetchFn, list, id, filter) {
39
- // First make sure we have the selected record, so we can always add it to the list
40
- let selectedResource;
41
- if (id) {
42
- selectedResource = list.value.find((c) => c.id === id) || (await fetchFn({ id }))[0];
43
- }
39
+ // First make sure we have the selected record, so we can always add it to the list
40
+ let selectedResource;
41
+ if (id) {
42
+ selectedResource = list.value.find((c) => c.id === id) || (await fetchFn({ id }))[0];
43
+ }
44
44
 
45
- // Get the filtered campaign list
46
- list.value = await fetchFn(filter);
45
+ // Get the filtered campaign list
46
+ list.value = await fetchFn(filter);
47
47
 
48
- // If our selected campaign is not in the filtered list, add it
49
- if (selectedResource && !list.value.find((c) => c.id === id)) {
50
- list.value.push(selectedResource);
51
- }
48
+ // If our selected campaign is not in the filtered list, add it
49
+ if (selectedResource && !list.value.find((c) => c.id === id)) {
50
+ list.value.push(selectedResource);
51
+ }
52
52
  }
53
53
 
54
54
  /**
@@ -57,6 +57,6 @@ export async function fetchResourceListWithSelected(fetchFn, list, id, filter) {
57
57
  * @param url
58
58
  */
59
59
  export function getUrlParam(key, url = undefined) {
60
- const params = new URLSearchParams(url?.replace(/.*\?/, "") || window.location.search);
61
- return params.get(key);
60
+ const params = new URLSearchParams(url?.replace(/.*\?/, "") || window.location.search);
61
+ return params.get(key);
62
62
  }
@@ -12,6 +12,17 @@ export const actionTargets = ref([]);
12
12
  * @returns {{performAction(name, targets): Promise<void>}}
13
13
  */
14
14
  export function usePerformAction(actions: any[]) {
15
+
16
+ function filterActions(filters) {
17
+ let filteredActions = [...actions];
18
+
19
+ for (const filter of Object.keys(filters)) {
20
+ const filterValue = filters[filter];
21
+ filteredActions = filteredActions.filter(a => a[filter] === filterValue || (Array.isArray(filterValue) && filterValue.includes(a[filter])));
22
+ }
23
+ return filteredActions;
24
+ }
25
+
15
26
  return {
16
27
  /**
17
28
  * Perform an action on a set of targets
@@ -29,7 +40,10 @@ export function usePerformAction(actions: any[]) {
29
40
  targets = Array.isArray(targets) ? targets : [targets];
30
41
 
31
42
  await performAction({ ...action, ...options }, targets);
32
- }
43
+ },
44
+
45
+ actions,
46
+ filterActions,
33
47
  };
34
48
  }
35
49
 
@@ -0,0 +1,10 @@
1
+ .action-button {
2
+ cursor: pointer;
3
+ border-radius: 0.5em;
4
+ transition: all 0.5s;
5
+ outline: 1px solid transparent;
6
+
7
+ &:hover {
8
+ @apply bg-blue-light outline outline-blue-base;
9
+ }
10
+ }