quasar-ui-danx 0.0.50 → 0.1.1

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.50",
3
+ "version": "0.1.1",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -1,64 +1,65 @@
1
1
  <template>
2
- <q-table
3
- ref="actionTable"
4
- :selected="selectedRows"
5
- :pagination="quasarPagination"
6
- :columns="columns"
7
- :loading="isLoadingList"
8
- :rows="pagedItems?.data || []"
9
- selection="multiple"
10
- :rows-per-page-options="rowsPerPageOptions"
11
- class="sticky-column sticky-header w-full !border-0"
12
- color="blue-base"
13
- @update:selected="$emit('update:selected-rows', $event)"
14
- @update:pagination="() => {}"
15
- @request="$emit('update:quasar-pagination', {...$event.pagination, __sort: mapSortBy($event.pagination, columns)})"
16
- >
17
- <template #no-data>
18
- <slot name="empty">
19
- <EmptyTableState :text="`There are no ${label.toLowerCase()} matching the applied filter`" />
20
- </slot>
21
- </template>
22
- <template #top-row>
23
- <TableSummaryRow
24
- :label="label"
25
- :item-count="summary?.count || 0"
26
- :selected-count="selectedRows.length"
27
- :loading="isLoadingSummary"
28
- :summary="summary"
29
- :columns="columns"
30
- @clear="$emit('update:selected-rows', [])"
31
- />
32
- </template>
33
- <template #header-cell="rowProps">
34
- <q-th
35
- :key="rowProps.key"
36
- :props="rowProps"
37
- :data-drop-zone="`resize-column-` + rowProps.col.name"
38
- >
39
- {{ rowProps.col.label }}
40
- <HandleDraggable
41
- v-if="rowProps.col.resizeable"
42
- :drop-zone="`resize-column-` + rowProps.col.name"
43
- class="resize-handle"
44
- @resize="onResizeColumn(rowProps.col, $event)"
2
+ <div class="overflow-hidden">
3
+ <ActionVnode />
4
+ <q-table
5
+ ref="actionTable"
6
+ :selected="selectedRows"
7
+ :pagination="quasarPagination"
8
+ :columns="columns"
9
+ :loading="isLoadingList"
10
+ :rows="pagedItems?.data || []"
11
+ selection="multiple"
12
+ :rows-per-page-options="rowsPerPageOptions"
13
+ class="sticky-column sticky-header w-full !border-0"
14
+ color="blue-base"
15
+ @update:selected="$emit('update:selected-rows', $event)"
16
+ @update:pagination="() => {}"
17
+ @request="$emit('update:quasar-pagination', {...$event.pagination, __sort: mapSortBy($event.pagination, columns)})"
18
+ >
19
+ <template #no-data>
20
+ <slot name="empty">
21
+ <EmptyTableState :text="`There are no ${label.toLowerCase()} matching the applied filter`" />
22
+ </slot>
23
+ </template>
24
+ <template #top-row>
25
+ <TableSummaryRow
26
+ :label="label"
27
+ :item-count="summary?.count || 0"
28
+ :selected-count="selectedRows.length"
29
+ :loading="isLoadingSummary"
30
+ :summary="summary"
31
+ :columns="columns"
32
+ @clear="$emit('update:selected-rows', [])"
33
+ />
34
+ </template>
35
+ <template #header-cell="rowProps">
36
+ <q-th
37
+ :key="rowProps.key"
38
+ :props="rowProps"
39
+ :data-drop-zone="`resize-column-` + rowProps.col.name"
45
40
  >
46
- <RowResizeIcon class="w-4 text-neutral-base" />
47
- </HandleDraggable>
48
- </q-th>
49
- </template>
50
- <template #body-cell="rowProps">
51
- <ActionTableColumn
52
- :row-props="rowProps"
53
- :settings="columnSettings[rowProps.col.name]"
54
- >
55
- <slot :column-name="rowProps.col.name" :row="rowProps.row" :value="rowProps.value" />
56
- </ActionTableColumn>
57
- </template>
58
- <template #bottom>
59
- <ActionVnode />
60
- </template>
61
- </q-table>
41
+ {{ rowProps.col.label }}
42
+ <HandleDraggable
43
+ v-if="rowProps.col.resizeable"
44
+ :drop-zone="`resize-column-` + rowProps.col.name"
45
+ class="resize-handle"
46
+ @resize="onResizeColumn(rowProps.col, $event)"
47
+ >
48
+ <RowResizeIcon class="w-4 text-neutral-base" />
49
+ </HandleDraggable>
50
+ </q-th>
51
+ </template>
52
+ <template #body-cell="rowProps">
53
+ <ActionTableColumn
54
+ :key="rowProps.key"
55
+ :row-props="rowProps"
56
+ :settings="columnSettings[rowProps.col.name]"
57
+ >
58
+ <slot :column-name="rowProps.col.name" :row="rowProps.row" :value="rowProps.value" />
59
+ </ActionTableColumn>
60
+ </template>
61
+ </q-table>
62
+ </div>
62
63
  </template>
63
64
 
64
65
  <script setup>
@@ -1,30 +1,33 @@
1
1
  <template>
2
- <q-td :key="rowProps.key" :props="rowProps" :style="columnStyle">
3
- <div
4
- class="flex items-center flex-nowrap"
5
- :class="columnClass"
6
- >
7
- <a
8
- v-if="column.onClick"
9
- class="flex-grow"
10
- @click="column.onClick(row)"
2
+ <q-td :key="rowProps.key" :props="rowProps">
3
+ <div :style="columnStyle">
4
+ <div
5
+ class="flex items-center flex-nowrap"
6
+ :class="columnClass"
11
7
  >
12
- <RenderVnode v-if="column.vnode" :vnode="column.vnode(row)" />
13
- <slot v-else>{{ value }}</slot>
14
- </a>
15
- <div v-else class="flex-grow">
16
- <RenderVnode v-if="column.vnode" :vnode="column.vnode(row)" />
17
- <slot v-else>{{ value }}</slot>
18
- </div>
19
- <div v-if="column.actionMenu" class="flex flex-shrink-0 pl-2">
20
- <ActionMenu
21
- :actions="column.actionMenu"
22
- :target="row"
23
- :loading="isSaving"
24
- />
8
+ <div class="flex-grow">
9
+ <a
10
+ v-if="column.onClick"
11
+ @click="column.onClick(row)"
12
+ >
13
+ <RenderVnode v-if="column.vnode" :vnode="column.vnode(row)" />
14
+ <slot v-else>{{ value }}</slot>
15
+ </a>
16
+ <div v-else>
17
+ <RenderVnode v-if="column.vnode" :vnode="column.vnode(row)" />
18
+ <slot v-else>{{ value }}</slot>
19
+ </div>
20
+ <TitleColumnFormat v-if="column.titleColumns" :row="row" :columns="column.titleColumns()" />
21
+ </div>
22
+ <div v-if="column.actionMenu" class="flex flex-shrink-0 pl-2">
23
+ <ActionMenu
24
+ :actions="column.actionMenu"
25
+ :target="row"
26
+ :loading="isSaving"
27
+ />
28
+ </div>
25
29
  </div>
26
30
  </div>
27
- <TitleColumnFormat v-if="column.titleColumns" :row="row" :columns="column.titleColumns()" />
28
31
  </q-td>
29
32
  </template>
30
33
  <script setup>
@@ -67,7 +67,7 @@ import { ChevronDownIcon as DropDownIcon } from '@heroicons/vue/outline';
67
67
  import { QSelect } from 'quasar';
68
68
  import { computed, isRef, nextTick, ref } from 'vue';
69
69
 
70
- const emit = defineEmits(['update:model-value', 'search']);
70
+ const emit = defineEmits(['update:model-value', 'search', 'update']);
71
71
  const props = defineProps({
72
72
  ...QSelect.props,
73
73
  modelValue: {
@@ -260,7 +260,7 @@ function onUpdate(value) {
260
260
 
261
261
  value = value === '__null__' ? null : value;
262
262
 
263
- emit('change', value);
263
+ emit('update', value);
264
264
  emit('update:model-value', value);
265
265
  }
266
266
 
@@ -296,7 +296,7 @@ async function onFilter(val, update) {
296
296
  */
297
297
  function onClear() {
298
298
  emit('update:model-value', undefined);
299
- emit('change', undefined);
299
+ emit('update', undefined);
300
300
  }
301
301
 
302
302
  /**
@@ -115,6 +115,9 @@ export function useListControls(name: string, {
115
115
 
116
116
  if (Object.keys(urlFilter).length > 0) {
117
117
  filter.value = urlFilter;
118
+
119
+ // Override whatever is in local storage with this new filter
120
+ updateSettings("filter", filter.value);
118
121
  }
119
122
  }
120
123
  }
@@ -182,6 +185,17 @@ export function useListControls(name: string, {
182
185
  return Promise.all([loadList(), loadSummary(), loadFilterFieldOptions(), getActiveItemDetails()]);
183
186
  }
184
187
 
188
+ /**
189
+ * Updates the settings in local storage
190
+ * @param key
191
+ * @param value
192
+ */
193
+ function updateSettings(key, value) {
194
+ const settings = getItem(PAGE_SETTINGS_KEY) || {};
195
+ settings[key] = value;
196
+ setItem(PAGE_SETTINGS_KEY, settings);
197
+ }
198
+
185
199
  /**
186
200
  * Loads the filter and pagination settings from local storage.
187
201
  */
@@ -28,6 +28,8 @@ export function mapSortBy(pagination, columns) {
28
28
  if (!pagination.sortBy) return null;
29
29
 
30
30
  const column = columns.find(c => c.name === pagination.sortBy);
31
+ if (!column) return null;
32
+
31
33
  return [
32
34
  {
33
35
  column: column.sortBy || column.name,
@@ -1,21 +1,21 @@
1
1
  <template>
2
2
  <QTabs
3
- :model-value="modelValue"
4
- vertical
5
- align="left"
6
- class="panel-tabs p-4 h-auto"
7
- no-caps
8
- @update:model-value="$emit('update:model-value', $event)"
3
+ :model-value="modelValue"
4
+ vertical
5
+ align="left"
6
+ class="panel-tabs p-4 h-auto"
7
+ no-caps
8
+ @update:model-value="$emit('update:model-value', $event)"
9
9
  >
10
10
  <template v-for="panel in panels">
11
- <template v-if="panel.enabled !== false">
11
+ <template v-if="panel.enabled === undefined || !!panel.enabled">
12
12
  <RenderVnode
13
- v-if="panel.tabVnode"
14
- :key="panel.name"
15
- :vnode="panel.tabVnode"
16
- :is-active="modelValue === panel.name"
17
- :name="panel.name"
18
- :label="panel.label"
13
+ v-if="panel.tabVnode"
14
+ :key="panel.name"
15
+ :vnode="panel.tabVnode"
16
+ :is-active="modelValue === panel.name"
17
+ :name="panel.name"
18
+ :label="panel.label"
19
19
  />
20
20
  <QTab v-else :key="panel.name" :name="panel.name" :label="panel.label" />
21
21
  </template>
@@ -23,14 +23,14 @@
23
23
  </QTabs>
24
24
  </template>
25
25
  <script setup>
26
- import { QTab } from "quasar";
27
- import { RenderVnode } from "quasar-ui-danx";
26
+ import { QTab } from 'quasar';
27
+ import { RenderVnode } from 'quasar-ui-danx';
28
28
 
29
- defineEmits(["update:model-value"]);
29
+ defineEmits(['update:model-value']);
30
30
  defineProps({
31
31
  modelValue: {
32
32
  type: String,
33
- default: "general"
33
+ default: 'general'
34
34
  },
35
35
  panels: {
36
36
  type: Array,
@@ -40,8 +40,8 @@ defineProps({
40
40
  </script>
41
41
 
42
42
  <style
43
- lang="scss"
44
- scoped
43
+ lang="scss"
44
+ scoped
45
45
  >
46
46
  .panel-tabs {
47
47
  :deep(.q-tab) {
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <QTooltip
3
+ ref="tooltipBox"
4
+ v-model="show"
5
+ no-parent-event
6
+ class="!pointer-events-auto"
7
+ @mouseenter="onEnterTooltip"
8
+ @mouseleave="onLeaveTooltip"
9
+ >
10
+ <slot>{{ tooltip }}</slot>
11
+ </QTooltip>
12
+ </template>
13
+ <script setup>
14
+ import { onMounted, ref } from 'vue';
15
+
16
+ defineProps({ tooltip: { type: String, default: '' } });
17
+ const show = ref(false);
18
+ const tooltipBox = ref(null);
19
+ const isHovering = ref(false);
20
+ const isHoveringParent = ref(false);
21
+ onMounted(() => {
22
+ tooltipBox.value.$el.parentNode.addEventListener('mouseover', onEnterParent);
23
+ tooltipBox.value.$el.parentNode.addEventListener('mouseleave', onLeaveParent);
24
+ });
25
+ function onEnterParent() {
26
+ show.value = true;
27
+ isHoveringParent.value = true;
28
+ }
29
+ function onLeaveParent() {
30
+ isHoveringParent.value = false;
31
+ if (!show.value) return;
32
+
33
+ setTimeout(() => {
34
+ if (isHovering.value || isHoveringParent.value) {
35
+ onLeaveParent();
36
+ } else {
37
+ show.value = false;
38
+ }
39
+ }, 200);
40
+ }
41
+ function onEnterTooltip() {
42
+ isHovering.value = true;
43
+ show.value = true;
44
+ }
45
+ function onLeaveTooltip() {
46
+ isHovering.value = false;
47
+ show.value = false;
48
+ }
49
+ </script>
@@ -1 +1,2 @@
1
1
  export { default as PopoverMenu } from "./PopoverMenu.vue";
2
+ export { default as InteractiveTooltip } from "./InteractiveTooltip.vue";
@@ -74,6 +74,10 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
74
74
  throw new Error(`Unknown action: ${name}`);
75
75
  }
76
76
 
77
+ if (!action.activeTarget) {
78
+ throw new Error(`Action ${action.name} does not have an activeTarget ref. Please use useActions() or manually set the activeTarget ref`);
79
+ }
80
+
77
81
  const vnode = action.vnode && action.vnode(target);
78
82
  let result: any;
79
83