quasar-ui-danx 0.4.12 → 0.4.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. package/dist/danx.es.js +10975 -6424
  2. package/dist/danx.es.js.map +1 -1
  3. package/dist/danx.umd.js +137 -7
  4. package/dist/danx.umd.js.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +3 -2
  7. package/src/components/ActionTable/ActionTable.vue +65 -63
  8. package/src/components/ActionTable/Form/ActionForm.vue +18 -12
  9. package/src/components/ActionTable/Form/RenderedForm.vue +86 -60
  10. package/src/components/ActionTable/Layouts/ActionTableLayout.vue +80 -70
  11. package/src/components/ActionTable/Toolbars/ActionToolbar.vue +29 -29
  12. package/src/components/ActionTable/listControls.ts +32 -31
  13. package/src/components/Navigation/NavigationMenu.vue +83 -40
  14. package/src/components/PanelsDrawer/PanelsDrawer.vue +20 -8
  15. package/src/components/PanelsDrawer/PanelsDrawerPanels.vue +3 -1
  16. package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +17 -4
  17. package/src/components/Utility/Tools/RenderVnode.vue +5 -1
  18. package/src/components/Utility/Transitions/AutoHeightTransition.vue +21 -0
  19. package/src/components/Utility/Transitions/index.ts +1 -0
  20. package/src/config/index.ts +1 -0
  21. package/src/helpers/actions.ts +31 -20
  22. package/src/helpers/date.ts +2 -2
  23. package/src/helpers/formats.ts +55 -5
  24. package/src/helpers/objectStore.ts +7 -0
  25. package/src/helpers/request.ts +1 -1
  26. package/src/helpers/routes.ts +5 -0
  27. package/src/helpers/utils.ts +3 -3
  28. package/src/types/actions.d.ts +4 -7
  29. package/src/types/config.d.ts +3 -1
  30. package/src/types/controls.d.ts +5 -7
  31. package/src/types/forms.d.ts +20 -1
  32. package/src/types/shared.d.ts +1 -0
@@ -1,4 +1,5 @@
1
1
  import { DateTime, IANAZone } from "luxon";
2
+ import { parse as parseYAML, stringify as stringifyYAML } from "yaml";
2
3
  import { ActionTargetItem, fDateOptions } from "../types";
3
4
  import { isJSON } from "./utils";
4
5
 
@@ -335,10 +336,59 @@ export function fJSON(string: string | object) {
335
336
  }
336
337
  }
337
338
 
338
- export function fMarkdownJSON(string: string | object): string {
339
- if (isJSON(string)) {
340
- return `\`\`\`json\n${fJSON(string)}\n\`\`\``;
339
+ /**
340
+ * Convert markdown formatted string into a valid JSON object
341
+ */
342
+ export function parseMarkdownJSON(string: string | object): object | null | false {
343
+ if (!string) return null;
344
+ if (typeof string === "object") return string as object;
345
+
346
+ try {
347
+ return JSON.parse(parseMarkdownCode(string));
348
+ } catch (e) {
349
+ return false;
350
+ }
351
+ }
352
+
353
+ export function parseMarkdownYAML(string: string): object | null | false {
354
+ if (!string) return null;
355
+
356
+ try {
357
+ return parseYAML(parseMarkdownCode(string)) || (string ? undefined : null);
358
+ } catch (e) {
359
+ return false;
360
+ }
361
+ }
362
+
363
+ /**
364
+ * Parse a markdown formatted string and return the code block content
365
+ */
366
+ export function parseMarkdownCode(string: string): string {
367
+ return string.replace(/^```[a-z0-9]{1,6}\s/, "").replace(/```$/, "");
368
+ }
369
+
370
+ /**
371
+ * Convert a JSON object or string of code into a markdown formatted JSON string
372
+ * ie: a valid JSON string with a ```json prefix and ``` postfix
373
+ */
374
+ export function fMarkdownCode(type: string, string: string | object): string {
375
+ if (typeof string === "object" || isJSON(string)) {
376
+ switch (type) {
377
+ case "yaml":
378
+ string = stringifyYAML(string);
379
+ break;
380
+ case "ts":
381
+ string = "";
382
+ break;
383
+ default:
384
+ string = fJSON(string);
385
+ }
341
386
  }
342
- // @ts-expect-error Guaranteed to only allow strings here using isJSON check
343
- return string;
387
+
388
+ const regex = new RegExp(`\`\`\`${type}`, "g");
389
+ if (!((string || "") as string).match(regex)) {
390
+ return `\`\`\`${type}\n${string}\n\`\`\``;
391
+ }
392
+
393
+ return string as string;
344
394
  }
@@ -1,3 +1,4 @@
1
+ import { uid } from "quasar";
1
2
  import { ShallowReactive, shallowReactive } from "vue";
2
3
  import { TypedObject } from "../types";
3
4
 
@@ -12,6 +13,9 @@ export function storeObject<T extends TypedObject>(newObject: T): ShallowReactiv
12
13
  const type = newObject.__type;
13
14
  if (!id || !type) return shallowReactive(newObject);
14
15
 
16
+ if (!newObject.__id) {
17
+ newObject.__id = uid();
18
+ }
15
19
  if (!newObject.__timestamp) {
16
20
  newObject.__timestamp = newObject.updated_at || 0;
17
21
  }
@@ -34,6 +38,9 @@ export function storeObject<T extends TypedObject>(newObject: T): ShallowReactiv
34
38
  for (const index in value) {
35
39
  newObject[key][index] = storeObject(value[index]);
36
40
  }
41
+ } else if (value?.__type) {
42
+ // @ts-expect-error newObject[key] is guaranteed to be a TypedObject
43
+ newObject[key] = storeObject(value);
37
44
  }
38
45
  }
39
46
 
@@ -45,7 +45,7 @@ export const request: RequestApi = {
45
45
  // If the request was aborted too late, but there was still another request that was made after the current,
46
46
  // then abort the current request with an abort flag
47
47
  if (timestamp < request.abortControllers[abortKey].timestamp) {
48
- throw new Error("Request was aborted due to a newer request being made: " + timestamp + " < " + request.abortControllers[abortKey].timestamp);
48
+ return { abort: true };
49
49
  }
50
50
 
51
51
  // Otherwise, the current is the most recent request, so we can delete the abort controller
@@ -1,3 +1,4 @@
1
+ import { storeObject } from "../helpers";
1
2
  import { ListControlsRoutes } from "../types";
2
3
  import { downloadFile } from "./downloadPdf";
3
4
  import { request } from "./request";
@@ -13,6 +14,10 @@ export function useActionRoutes(baseUrl: string): ListControlsRoutes {
13
14
  details(target) {
14
15
  return request.get(`${baseUrl}/${target.id}/details`);
15
16
  },
17
+ async detailsAndStore(target) {
18
+ const item = await request.get(`${baseUrl}/${target.id}/details`);
19
+ return storeObject(item);
20
+ },
16
21
  fieldOptions() {
17
22
  return request.get(`${baseUrl}/field-options`);
18
23
  },
@@ -91,12 +91,12 @@ export function incrementName(name: string) {
91
91
  * Check if a string is a valid JSON object. If an object is passed, always return true
92
92
  */
93
93
  export function isJSON(string: string | object) {
94
- if (!string) {
95
- return false;
96
- }
97
94
  if (typeof string === "object") {
98
95
  return true;
99
96
  }
97
+ if (!string) {
98
+ return false;
99
+ }
100
100
  try {
101
101
  JSON.parse(string);
102
102
  return true;
@@ -6,13 +6,14 @@ export interface ActionPanel {
6
6
  label: string;
7
7
  category?: string;
8
8
  class?: string | object;
9
- enabled?: boolean | (() => boolean);
10
- tabVnode?: (activePanel: string | number) => VNode | any;
11
- vnode: (activePanel: string) => VNode | any;
9
+ enabled?: boolean | ((activeItem: ActionTargetItem) => boolean);
10
+ tabVnode?: (activeItem: ActionTargetItem | null | undefined, activePanel: string | number) => VNode | any;
11
+ vnode: (activeItem: ActionTargetItem | null | undefined) => VNode | any;
12
12
  }
13
13
 
14
14
  export interface ActionTargetItem extends TypedObject {
15
15
  isSaving?: boolean;
16
+ updated_at?: string;
16
17
  }
17
18
 
18
19
  export type ActionTarget = ActionTargetItem[] | ActionTargetItem | null;
@@ -41,10 +42,6 @@ export interface ActionOptions {
41
42
  onFinish?: (result: any, targets: ActionTarget, input: any) => any;
42
43
  }
43
44
 
44
- export interface ActionOptionsPartial extends ActionOptions {
45
- name?: string;
46
- }
47
-
48
45
  export interface ResourceAction extends ActionOptions {
49
46
  isApplying: boolean;
50
47
  trigger: (target?: ActionTarget, input?: any) => Promise<any>;
@@ -1,11 +1,13 @@
1
1
  import { QNotifyCreateOptions } from "quasar";
2
+ import { Router } from "vue-router";
2
3
  import { FileUploadOptions } from "./files";
3
4
  import { RequestOptions } from "./requests";
4
5
 
5
6
  export interface DanxOptions {
6
7
  tinyMceApiKey?: string;
7
8
  fileUpload?: FileUploadOptions;
8
- request?: RequestOptions,
9
+ request?: RequestOptions;
10
+ router?: Router;
9
11
  flashMessages?: {
10
12
  default?: QNotifyCreateOptions;
11
13
  success?: QNotifyCreateOptions;
@@ -1,5 +1,4 @@
1
1
  import { ComputedRef, Ref, ShallowRef } from "vue";
2
- import { Router } from "vue-router";
3
2
  import { ActionTargetItem } from "./actions";
4
3
  import { AnyObject, LabelValueItem } from "./shared";
5
4
 
@@ -29,6 +28,8 @@ export interface ListControlsRoutes {
29
28
 
30
29
  details?(target: ActionTargetItem): Promise<ActionTargetItem>;
31
30
 
31
+ detailsAndStore?(target: ActionTargetItem): Promise<ActionTargetItem>;
32
+
32
33
  more?(pager: ListControlsPagination): Promise<ActionTargetItem[]>;
33
34
 
34
35
  fieldOptions?(filter?: AnyObject): Promise<AnyObject>;
@@ -67,10 +68,6 @@ export interface PagedItems {
67
68
  } | undefined;
68
69
  }
69
70
 
70
- export interface ListControlsInitializeOptions {
71
- vueRouter?: Router;
72
- }
73
-
74
71
  export interface ActionController {
75
72
  name: string;
76
73
  label: string;
@@ -95,15 +92,16 @@ export interface ActionController {
95
92
  activePanel: ShallowRef<string | null>;
96
93
 
97
94
  // Actions
98
- initialize: (options: ListControlsInitializeOptions) => void;
95
+ initialize: () => void;
99
96
  resetPaging: () => void;
100
- setPagination: (updated: ListControlsPagination) => void;
97
+ setPagination: (updated: Partial<ListControlsPagination>) => void;
101
98
  setSelectedRows: (selection: ActionTargetItem[]) => void;
102
99
  clearSelectedRows: () => void;
103
100
  loadList: (filter?: ListControlsFilter) => Promise<void>;
104
101
  loadSummary: (filter?: ListControlsFilter) => Promise<void>;
105
102
  loadListAndSummary: (filter?: ListControlsFilter) => Promise<void>;
106
103
  loadMore: (index: number, perPage?: number) => Promise<boolean>;
104
+ loadFieldOptions: () => Promise<void>;
107
105
  getActiveItemDetails: () => Promise<void>;
108
106
  refreshAll: () => Promise<void[]>;
109
107
  exportList: (filter?: ListControlsFilter) => Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import { VNode } from "vue";
2
+ import { AnyObject } from "./shared";
2
3
 
3
4
  export interface FormFieldOption {
4
5
  value: string;
@@ -11,11 +12,13 @@ export interface FormField {
11
12
  name: string;
12
13
  label: string;
13
14
  placeholder?: string;
14
- vnode?: ((props) => VNode | any);
15
+ enabled?: boolean | ((input: AnyObject) => boolean);
16
+ vnode?: ((field: FormFieldOption, input?: AnyObject) => VNode | any);
15
17
  component?: any;
16
18
  clearable?: boolean;
17
19
  required?: boolean;
18
20
  required_group?: string;
21
+ default_value?: any;
19
22
  toggleIndeterminate?: boolean;
20
23
  inline?: boolean;
21
24
  maxLength?: number;
@@ -35,3 +38,19 @@ export interface FormFieldValue {
35
38
  value: any,
36
39
  variation?: string
37
40
  }
41
+
42
+ export interface RenderedFormProps {
43
+ values?: FormFieldValue[] | object | null;
44
+ form: Form;
45
+ noLabel?: boolean;
46
+ showName?: boolean;
47
+ disable?: boolean;
48
+ readonly?: boolean;
49
+ saving?: boolean;
50
+ clearable?: boolean;
51
+ emptyValue?: string | number | boolean;
52
+ canModifyVariations?: boolean;
53
+ fieldClass?: string;
54
+ savingClass?: string;
55
+ savedAt?: string;
56
+ }
@@ -5,6 +5,7 @@ export interface TypedObject {
5
5
  name?: string;
6
6
  __type: string;
7
7
  __timestamp?: number;
8
+ __id?: string;
8
9
 
9
10
  [key: string]: TypedObject[] | any;
10
11
  }