quasar-ui-danx 0.4.3 → 0.4.5

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.4.3",
3
+ "version": "0.4.5",
4
4
  "author": "Dan <dan@flytedesk.com>",
5
5
  "description": "DanX Vue / Quasar component library",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  :selected="selectedRows"
10
10
  :pagination="pagination"
11
11
  :columns="tableColumns"
12
- :loading="loadingList"
12
+ :loading="loadingList || loadingSummary"
13
13
  :rows="pagedItems?.data || []"
14
14
  :binary-state-sort="false"
15
15
  selection="multiple"
@@ -8,6 +8,7 @@
8
8
  :actions="actions?.filter(a => a.batch)"
9
9
  :action-target="controller.selectedRows.value"
10
10
  :exporter="controller.exportList"
11
+ :loading="controller.isLoadingList.value || controller.isLoadingSummary.value"
11
12
  @refresh="controller.refreshAll"
12
13
  >
13
14
  <template #default>
@@ -1,5 +1,5 @@
1
1
  import { computed, Ref, ref, shallowRef, watch } from "vue";
2
- import { RouteLocationNormalizedLoaded, RouteParams, Router, useRoute, useRouter } from "vue-router";
2
+ import { RouteLocationNormalizedLoaded, RouteParams, Router } from "vue-router";
3
3
  import { getItem, setItem, storeObject, waitForRef } from "../../helpers";
4
4
  import {
5
5
  ActionController,
@@ -7,6 +7,7 @@ import {
7
7
  AnyObject,
8
8
  FilterGroup,
9
9
  ListControlsFilter,
10
+ ListControlsInitializeOptions,
10
11
  ListControlsOptions,
11
12
  ListControlsPagination,
12
13
  PagedItems
@@ -380,21 +381,21 @@ export function useListControls(name: string, options: ListControlsOptions): Act
380
381
  }
381
382
 
382
383
  async function exportList(filter?: ListControlsFilter) {
383
- return options.routes.export(filter);
384
+ options.routes.export && await options.routes.export(filter);
384
385
  }
385
386
 
386
387
  // Initialize the list actions and load settings, lists, summaries, filter fields, etc.
387
- function initialize() {
388
+ function initialize(initOptions: ListControlsInitializeOptions) {
389
+ vueRouter = initOptions.vueRouter;
390
+ vueRoute = initOptions.vueRoute;
388
391
  isInitialized = true;
389
392
  loadSettings();
390
393
 
391
- // Setup Vue Router handling
392
- vueRoute = useRoute();
393
- vueRouter = useRouter();
394
+ console.log("initialize() called", name, options, "initOptions", initOptions);
394
395
  /**
395
396
  * Watch the id params in the route and set the active item to the item with the given id.
396
397
  */
397
- if (options.routes.details) {
398
+ if (options.routes.details && vueRoute) {
398
399
  const { params, meta } = vueRoute;
399
400
 
400
401
  const controlRouteName = vueRoute.name;
@@ -1,22 +1,53 @@
1
1
  import { Ref } from "vue";
2
2
  import { danxOptions } from "../config";
3
- import { AnyObject } from "../types";
3
+ import { RequestApi } from "../types";
4
4
 
5
5
  /**
6
6
  * A simple request helper that wraps the fetch API
7
7
  * to make GET and POST requests easier w/ JSON payloads
8
8
  */
9
- export const request = {
10
- url(url: string) {
9
+ export const request: RequestApi = {
10
+ abortControllers: {},
11
+
12
+ url(url) {
11
13
  if (url.startsWith("http")) {
12
14
  return url;
13
15
  }
14
16
  return (danxOptions.value.request?.baseUrl || "").replace(/\/$/, "") + "/" + url;
15
17
  },
16
18
 
17
- async call(url: string, options: RequestInit): Promise<object> {
19
+ async call(url, options) {
18
20
  try {
21
+ const abort = new AbortController();
22
+ const timestamp = new Date().getTime();
23
+
24
+ console.log("call", url, options);
25
+ if (options?.abortOn) {
26
+ console.log("setting up abort", options.abortOn);
27
+ const previousAbort = options.abortOn && request.abortControllers[options.abortOn];
28
+ // If there is already an abort controller set for this key, abort it
29
+ if (previousAbort) {
30
+ previousAbort.abort.abort();
31
+ }
32
+
33
+ // Set the new abort controller for this key
34
+ request.abortControllers[options.abortOn] = { abort, timestamp };
35
+ options.signal = abort.signal;
36
+ }
37
+
38
+ console.log("current timestamp:", timestamp);
19
39
  const response = await fetch(request.url(url), options);
40
+
41
+ // handle the case where the request was aborted too late, and we need to abort the response via timestamp check
42
+ if (options?.abortOn) {
43
+ if (request.abortControllers[options.abortOn].timestamp !== timestamp) {
44
+ console.log("aborting request", options.abortOn, timestamp, "!==", request.abortControllers[options.abortOn].timestamp);
45
+ return { abort: true };
46
+ }
47
+
48
+ delete request.abortControllers[options.abortOn];
49
+ }
50
+
20
51
  const result = await response.json();
21
52
 
22
53
  if (response.status === 401) {
@@ -40,7 +71,7 @@ export const request = {
40
71
  };
41
72
  }
42
73
  },
43
- async get(url: string, options: RequestInit = {}): Promise<object> {
74
+ async get(url, options) {
44
75
  return await request.call(url, {
45
76
  method: "get",
46
77
  headers: {
@@ -52,10 +83,10 @@ export const request = {
52
83
  });
53
84
  },
54
85
 
55
- async post(url: string, data: AnyObject = {}, options: RequestInit = {}) {
56
- return request.call(url, {
86
+ async post(url, data, options) {
87
+ return await request.call(url, {
57
88
  method: "post",
58
- body: JSON.stringify(data),
89
+ body: data && JSON.stringify(data),
59
90
  headers: {
60
91
  Accept: "application/json",
61
92
  "Content-Type": "application/json",
@@ -1,28 +1,29 @@
1
- import { ActionTargetItem, AnyObject, ListControlsPagination } from "../types";
1
+ import { ListControlsRoutes } from "../types";
2
2
  import { downloadFile } from "./downloadPdf";
3
3
  import { request } from "./request";
4
4
 
5
- export function useActionRoutes(baseUrl: string) {
5
+ export function useActionRoutes(baseUrl: string): ListControlsRoutes {
6
6
  return {
7
- list(pager: ListControlsPagination) {
8
- return request.post(`${baseUrl}/list`, pager);
7
+ list(pager?) {
8
+ console.log("here");
9
+ return request.post(`${baseUrl}/list`, pager, { abortOn: "list" });
9
10
  },
10
- summary(filter: AnyObject) {
11
+ summary(filter) {
11
12
  return request.post(`${baseUrl}/summary`, { filter });
12
13
  },
13
- details(target: ActionTargetItem) {
14
+ details(target) {
14
15
  return request.get(`${baseUrl}/${target.id}/details`);
15
16
  },
16
17
  fieldOptions() {
17
18
  return request.get(`${baseUrl}/field-options`);
18
19
  },
19
- applyAction(action: string, target: ActionTargetItem | null, data: object) {
20
+ applyAction(action, target, data) {
20
21
  return request.post(`${baseUrl}/${target ? target.id : "new"}/apply-action`, { action, data });
21
22
  },
22
- batchAction(action: string, targets: ActionTargetItem[], data: object) {
23
+ batchAction(action, targets, data) {
23
24
  return request.post(`${baseUrl}/batch-action`, { action, filter: { id: targets.map(r => r.id) }, data });
24
25
  },
25
- export(filter: AnyObject, name?: string) {
26
+ export(filter, name) {
26
27
  return downloadFile(`${baseUrl}/export`, name || "export.csv", { filter });
27
28
  }
28
29
  };
@@ -1,6 +1,7 @@
1
1
  import { ComputedRef, Ref, ShallowRef } from "vue";
2
+ import { RouteLocationNormalizedLoaded, Router } from "vue-router";
2
3
  import { ActionTargetItem } from "./actions";
3
- import { LabelValueItem } from "./shared";
4
+ import { AnyObject, LabelValueItem } from "./shared";
4
5
 
5
6
  export interface ListControlsFilter {
6
7
  [key: string]: object | object[] | null | undefined | string | number | boolean;
@@ -20,13 +21,23 @@ export interface FilterGroup {
20
21
  fields: FilterableField[];
21
22
  }
22
23
 
24
+
23
25
  export interface ListControlsRoutes {
24
- list: (pager: object) => Promise<ActionTargetItem[]>;
25
- details?: (item: object) => Promise<ActionTargetItem> | null;
26
- summary?: (filter: object | null) => Promise<object> | null;
27
- fieldOptions?: (filter: object | null) => Promise<object> | null;
28
- more?: (pager: object) => Promise<ActionTargetItem[]> | null;
29
- export: (filter?: ListControlsFilter) => Promise<void>;
26
+ list(pager?: ListControlsPagination): Promise<ActionTargetItem[]>;
27
+
28
+ summary?(filter?: ListControlsFilter): Promise<object>;
29
+
30
+ details?(target: ActionTargetItem): Promise<ActionTargetItem>;
31
+
32
+ more?(pager: ListControlsPagination): Promise<ActionTargetItem[]>;
33
+
34
+ fieldOptions?(filter?: AnyObject): Promise<object>;
35
+
36
+ applyAction?(action: string, target: ActionTargetItem | null, data: object): Promise<object>;
37
+
38
+ batchAction?(action: string, targets: ActionTargetItem[], data: object): Promise<object>;
39
+
40
+ export?(filter?: ListControlsFilter, name?: string): Promise<void>;
30
41
  }
31
42
 
32
43
  export interface ListControlsOptions {
@@ -44,6 +55,8 @@ export interface ListControlsPagination {
44
55
  page?: number;
45
56
  rowsNumber?: number;
46
57
  rowsPerPage?: number;
58
+ perPage?: number;
59
+ filter?: ListControlsFilter;
47
60
  }
48
61
 
49
62
  export interface PagedItems {
@@ -54,6 +67,11 @@ export interface PagedItems {
54
67
  } | undefined;
55
68
  }
56
69
 
70
+ export interface ListControlsInitializeOptions {
71
+ vueRoute: RouteLocationNormalizedLoaded;
72
+ vueRouter: Router;
73
+ }
74
+
57
75
  export interface ActionController {
58
76
  name: string;
59
77
  label: string;
@@ -78,7 +96,7 @@ export interface ActionController {
78
96
  activePanel: ShallowRef<string | null>;
79
97
 
80
98
  // Actions
81
- initialize: () => void;
99
+ initialize: (options: ListControlsInitializeOptions) => void;
82
100
  resetPaging: () => void;
83
101
  setPagination: (updated: ListControlsPagination) => void;
84
102
  setSelectedRows: (selection: ActionTargetItem[]) => void;
@@ -1,3 +1,15 @@
1
+ export interface RequestApi {
2
+ abortControllers: { [key: string]: { abort: AbortController, timestamp: number } };
3
+
4
+ url(url: string): string;
5
+
6
+ call(url: string, options?: RequestCallOptions): Promise<any>;
7
+
8
+ get(url: string, options?: RequestCallOptions): Promise<any>;
9
+
10
+ post(url: string, data?: object, options?: RequestCallOptions): Promise<any>;
11
+ }
12
+
1
13
  export interface HttpResponse {
2
14
  headers: any;
3
15
  data?: any;
@@ -11,3 +23,8 @@ export interface RequestOptions {
11
23
  headers?: object;
12
24
  onUnauthorized?: (response) => object;
13
25
  }
26
+
27
+ export interface RequestCallOptions extends RequestInit {
28
+ abortOn?: string;
29
+ }
30
+