quasar-ui-danx 0.4.10 → 0.4.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. package/dist/danx.es.js +5954 -5721
  2. package/dist/danx.es.js.map +1 -1
  3. package/dist/danx.umd.js +6 -6
  4. package/dist/danx.umd.js.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/index.d.ts +7 -0
  7. package/index.ts +1 -0
  8. package/package.json +8 -3
  9. package/src/components/ActionTable/ActionMenu.vue +26 -31
  10. package/src/components/ActionTable/ActionTable.vue +4 -1
  11. package/src/components/ActionTable/Columns/ActionTableColumn.vue +14 -6
  12. package/src/components/ActionTable/Columns/ActionTableHeaderColumn.vue +63 -42
  13. package/src/components/ActionTable/Form/ActionForm.vue +55 -0
  14. package/src/components/ActionTable/Form/Fields/EditOnClickTextField.vue +11 -5
  15. package/src/components/ActionTable/Form/Fields/FileUploadButton.vue +1 -0
  16. package/src/components/ActionTable/Form/Fields/MultiFileField.vue +1 -1
  17. package/src/components/ActionTable/Form/Fields/NumberField.vue +0 -1
  18. package/src/components/ActionTable/Form/RenderedForm.vue +11 -10
  19. package/src/components/ActionTable/Form/index.ts +1 -0
  20. package/src/components/ActionTable/Layouts/ActionTableLayout.vue +3 -3
  21. package/src/components/ActionTable/TableSummaryRow.vue +48 -37
  22. package/src/components/ActionTable/Toolbars/ActionToolbar.vue +2 -2
  23. package/src/components/ActionTable/listControls.ts +3 -2
  24. package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +30 -5
  25. package/src/components/Utility/Files/FilePreview.vue +72 -12
  26. package/src/components/Utility/Popovers/PopoverMenu.vue +34 -29
  27. package/src/config/index.ts +2 -1
  28. package/src/helpers/FileUpload.ts +59 -8
  29. package/src/helpers/actions.ts +27 -27
  30. package/src/helpers/download.ts +8 -2
  31. package/src/helpers/multiFileUpload.ts +6 -4
  32. package/src/helpers/objectStore.ts +14 -17
  33. package/src/helpers/request.ts +12 -0
  34. package/src/helpers/singleFileUpload.ts +63 -55
  35. package/src/helpers/utils.ts +9 -0
  36. package/src/index.ts +1 -0
  37. package/src/styles/danx.scss +5 -0
  38. package/src/styles/index.scss +1 -0
  39. package/src/styles/themes/danx/action-table.scss +24 -13
  40. package/src/types/actions.d.ts +13 -4
  41. package/src/types/controls.d.ts +4 -4
  42. package/src/types/files.d.ts +10 -5
  43. package/src/types/index.d.ts +0 -1
  44. package/src/types/requests.d.ts +2 -0
  45. package/src/types/tables.d.ts +28 -22
  46. package/src/{vue-plugin.js → vue-plugin.ts} +5 -4
  47. package/tsconfig.json +1 -0
  48. package/types/index.d.ts +2 -0
@@ -1,7 +1,7 @@
1
1
  import { useDebounceFn } from "@vueuse/core";
2
2
  import { uid } from "quasar";
3
3
  import { isReactive, Ref, shallowRef } from "vue";
4
- import { ActionOptions, ActionTarget, AnyObject } from "../types";
4
+ import type { ActionOptions, ActionOptionsPartial, ActionTarget, AnyObject, ResourceAction } from "../types";
5
5
  import { FlashMessages } from "./FlashMessages";
6
6
  import { storeObject } from "./objectStore";
7
7
 
@@ -10,39 +10,40 @@ export const activeActionVnode: Ref = shallowRef(null);
10
10
  /**
11
11
  * Hook to perform an action on a set of targets
12
12
  * This helper allows you to perform actions by name on a set of targets using a provided list of actions
13
- *
14
- * @param actions
15
- * @param {ActionOptions | null} globalOptions
16
13
  */
17
- export function useActions(actions: ActionOptions[], globalOptions: ActionOptions | null = null) {
14
+ export function useActions(actions: ActionOptions[], globalOptions: ActionOptionsPartial | null = null) {
18
15
  const namespace = uid();
19
16
 
20
17
  /**
21
18
  * Resolve the action object based on the provided name (or return the object if the name is already an object)
22
19
  */
23
- function getAction(action: string | ActionOptions): ActionOptions {
24
- if (typeof action === "string") {
25
- action = actions.find(a => a.name === action) || { name: action };
20
+ function getAction(actionName: string | ActionOptions | ResourceAction): ResourceAction {
21
+ let actionOptions: ActionOptions | ResourceAction;
22
+
23
+ /// Resolve the action options or resource action based on the provided input
24
+ if (typeof actionName === "string") {
25
+ actionOptions = actions.find(a => a.name === actionName) || { name: actionName };
26
+ } else {
27
+ actionOptions = actionName;
26
28
  }
27
29
 
28
30
  // If the action is already reactive, return it
29
- if (isReactive(action) && action.__type) return action;
31
+ if (isReactive(actionOptions) && "__type" in actionOptions) return actionOptions as ResourceAction;
30
32
 
31
- action = { ...globalOptions, ...action };
33
+ const resourceAction: ResourceAction = storeObject({
34
+ ...globalOptions,
35
+ ...actionOptions,
36
+ trigger: (target, input) => performAction(resourceAction, target, input),
37
+ isApplying: false,
38
+ __type: "__Action:" + namespace
39
+ });
32
40
 
33
41
  // Assign Trigger function if it doesn't exist
34
- if (!action.trigger) {
35
- if (action.debounce) {
36
- action.trigger = useDebounceFn((target, input) => performAction(action, target, input), action.debounce);
37
- } else {
38
- action.trigger = (target, input) => performAction(action, target, input);
39
- }
42
+ if (actionOptions.debounce) {
43
+ resourceAction.trigger = useDebounceFn((target, input) => performAction(resourceAction, target, input), actionOptions.debounce);
40
44
  }
41
45
 
42
- // Set the initial state for the action
43
- action.isApplying = false;
44
-
45
- return storeObject({ ...action, __type: "__Action:" + namespace });
46
+ return resourceAction;
46
47
  }
47
48
 
48
49
  /**
@@ -52,17 +53,17 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
52
53
  * @param filters
53
54
  * @returns {ActionOptions[]}
54
55
  */
55
- function getActions(filters?: AnyObject): ActionOptions[] {
56
+ function getActions(filters?: AnyObject): ResourceAction[] {
56
57
  let filteredActions = [...actions];
57
58
 
58
59
  if (filters) {
59
- for (const filter of Object.keys(filters)) {
60
- const filterValue = filters[filter];
61
- filteredActions = filteredActions.filter((a: AnyObject) => a[filter] === filterValue || (Array.isArray(filterValue) && filterValue.includes(a[filter])));
60
+ for (const filterKey of Object.keys(filters)) {
61
+ const filterValue = filters[filterKey];
62
+ filteredActions = filteredActions.filter((a: AnyObject) => a[filterKey] === filterValue || (Array.isArray(filterValue) && filterValue.includes(a[filterKey])));
62
63
  }
63
64
  }
64
65
 
65
- return filteredActions.map((a: AnyObject) => getAction(a));
66
+ return filteredActions.map((a: ActionOptions) => getAction(a));
66
67
  }
67
68
 
68
69
  /**
@@ -72,8 +73,7 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
72
73
  * @param {object[]|object} target - an array of targets or a single target object
73
74
  * @param {any} input - The input data to pass to the action handler
74
75
  */
75
- async function performAction(action: string | ActionOptions, target: ActionTarget = null, input: any = null) {
76
- action = getAction(action);
76
+ async function performAction(action: ResourceAction, target: ActionTarget = null, input: any = null) {
77
77
  // Resolve the original action, if the current action is an alias
78
78
  const aliasedAction = action.alias ? getAction(action.alias) : null;
79
79
 
@@ -23,6 +23,7 @@ export function download(data: any, strFileName?: string, strMimeType?: string)
23
23
 
24
24
  var anchor = document.createElement("a");
25
25
 
26
+ // @ts-ignore
26
27
  var toString = function (a) {
27
28
  return String(a);
28
29
  };
@@ -35,8 +36,10 @@ export function download(data: any, strFileName?: string, strMimeType?: string)
35
36
  var blob;
36
37
 
37
38
  var reader;
39
+ // @ts-ignore
38
40
  myBlob = myBlob.call ? myBlob.bind(self) : Blob;
39
41
 
42
+ // @ts-ignore
40
43
  if (String(this) === "true") {
41
44
  // reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
42
45
  payload = [payload, mimeType];
@@ -64,6 +67,7 @@ export function download(data: any, strFileName?: string, strMimeType?: string)
64
67
  };
65
68
  ajax.onerror = function (e) {
66
69
  // As a fallback, just open the request in a new tab
70
+ // @ts-ignore
67
71
  window.open(url, "_blank").focus();
68
72
  };
69
73
  setTimeout(function () {
@@ -77,6 +81,7 @@ export function download(data: any, strFileName?: string, strMimeType?: string)
77
81
 
78
82
  // go ahead and download dataURLs right away
79
83
  if (/^data:[\w+-]+\/[\w+-]+[,;]/.test(payload)) {
84
+ // @ts-ignore
80
85
  if (payload.length > 1024 * 1024 * 1.999 && myBlob !== toString) {
81
86
  payload = dataUrlToBlob(payload);
82
87
  mimeType = payload.type || defaultMime;
@@ -93,13 +98,14 @@ export function download(data: any, strFileName?: string, strMimeType?: string)
93
98
  ? payload
94
99
  : new myBlob([payload], { type: mimeType });
95
100
 
96
- function dataUrlToBlob(strUrl) {
101
+ function dataUrlToBlob(strUrl: string) {
97
102
  var parts = strUrl.split(/[:;,]/);
98
103
 
99
104
  var type = parts[1];
100
105
 
101
106
  var decoder = parts[2] === "base64" ? atob : decodeURIComponent;
102
107
 
108
+ // @ts-ignore
103
109
  var binData = decoder(parts.pop());
104
110
 
105
111
  var mx = binData.length;
@@ -113,7 +119,7 @@ export function download(data: any, strFileName?: string, strMimeType?: string)
113
119
  return new myBlob([uiArr], { type: type });
114
120
  }
115
121
 
116
- function saver(url, winMode) {
122
+ function saver(url: string, winMode: boolean | string) {
117
123
  if ("download" in anchor) {
118
124
  // html5 A[download]
119
125
  anchor.href = url;
@@ -16,14 +16,16 @@ export function useMultiFileUpload(options?: FileUploadOptions) {
16
16
  const onFilesSelected = (e: any) => {
17
17
  uploadedFiles.value = [...uploadedFiles.value, ...e.target.files];
18
18
  new FileUpload(e.target.files, options)
19
- .onProgress(({ file }: { file: UploadedFile }) => {
20
- updateFileInList(file);
19
+ .prepare()
20
+ .onProgress(({ file }) => {
21
+ file && updateFileInList(file);
21
22
  })
22
23
  .onComplete(({ file, uploadedFile }) => {
23
24
  file && updateFileInList(file, uploadedFile);
24
25
  })
25
- .onError(({ file }: { file: UploadedFile }) => {
26
- FlashMessages.error(`Failed to upload ${file.name}`);
26
+ .onError(({ file, error }) => {
27
+ console.error("Failed to upload", file, error);
28
+ FlashMessages.error(`Failed to upload ${file.name}: ${error}`);
27
29
  })
28
30
  .onAllComplete(() => {
29
31
  onCompleteCb.value && onCompleteCb.value({
@@ -1,4 +1,4 @@
1
- import { reactive, UnwrapNestedRefs } from "vue";
1
+ import { ShallowReactive, shallowReactive } from "vue";
2
2
  import { TypedObject } from "../types";
3
3
 
4
4
  const store = new Map<string, any>();
@@ -6,27 +6,25 @@ const store = new Map<string, any>();
6
6
  /**
7
7
  * Store an object in the object store via type + id
8
8
  * Returns the stored object that should be used instead of the passed object as the returned object is shared across the system
9
- *
10
- * @param {TypedObject} newObject
11
- * @returns {TypedObject}
12
9
  */
13
- export function storeObject<T extends TypedObject>(newObject: T): UnwrapNestedRefs<T> {
10
+ export function storeObject<T extends TypedObject>(newObject: T): ShallowReactive<T> {
14
11
  const id = newObject.id || newObject.name;
15
12
  const type = newObject.__type;
16
- if (!id || !type) return reactive(newObject);
13
+ if (!id || !type) return shallowReactive(newObject);
14
+
15
+ if (!newObject.__timestamp) {
16
+ newObject.__timestamp = newObject.updated_at || 0;
17
+ }
17
18
 
18
19
  const objectKey = `${type}:${id}`;
19
20
 
20
- const oldObject: UnwrapNestedRefs<T> | undefined = store.get(objectKey);
21
+ // Retrieve the existing object if it already exists in the store
22
+ const oldObject = store.get(objectKey);
21
23
 
22
- // Apply all properties from newObject to oldObject then store and return the updated object
23
- if (oldObject) {
24
- const oldTimestamp = oldObject.__timestamp || oldObject.updated_at;
25
- const newTimestamp = newObject.__timestamp || newObject.updated_at;
26
- // If the old object is newer, do not store the new object, just return the old
27
- if (oldTimestamp && newTimestamp && newTimestamp < oldTimestamp) {
28
- return oldObject;
29
- }
24
+ // If an old object exists, and it is newer than the new object, do not store the new object, just return the old
25
+ // @ts-expect-error __timestamp is guaranteed to be set in this case on both old and new
26
+ if (oldObject && newObject.__timestamp <= oldObject.__timestamp) {
27
+ return oldObject;
30
28
  }
31
29
 
32
30
  // Recursively store all the children of the object as well
@@ -41,12 +39,11 @@ export function storeObject<T extends TypedObject>(newObject: T): UnwrapNestedRe
41
39
 
42
40
  // Update the old object with the new object properties
43
41
  if (oldObject) {
44
- // If the new object is newer, apply all properties from the new object to the old object
45
42
  Object.assign(oldObject, newObject);
46
43
  return oldObject;
47
44
  }
48
45
 
49
- const reactiveObject = reactive(newObject);
46
+ const reactiveObject = shallowReactive(newObject);
50
47
  store.set(objectKey, reactiveObject);
51
48
  return reactiveObject;
52
49
  }
@@ -1,6 +1,7 @@
1
1
  import { Ref } from "vue";
2
2
  import { danxOptions } from "../config";
3
3
  import { HttpResponse, RequestApi } from "../types";
4
+ import { sleep } from "./utils";
4
5
 
5
6
  /**
6
7
  * A simple request helper that wraps the fetch API
@@ -70,6 +71,17 @@ export const request: RequestApi = {
70
71
 
71
72
  return result;
72
73
  },
74
+
75
+ async poll(url: string, options, interval, fnUntil) {
76
+ let response;
77
+ do {
78
+ response = await request.call(url, options);
79
+ await sleep(interval);
80
+ } while (!fnUntil(response));
81
+
82
+ return response;
83
+ },
84
+
73
85
  async get(url, options) {
74
86
  return await request.call(url, {
75
87
  method: "get",
@@ -1,60 +1,68 @@
1
1
  import { computed, Ref, ref } from "vue";
2
- import { FileUpload, FileUploadOptions, UploadedFile } from "./FileUpload";
2
+ import { FileUploadOptions, UploadedFile } from "../types";
3
+ import { FileUpload } from "./FileUpload";
4
+ import { FlashMessages } from "./FlashMessages";
3
5
 
4
- interface FileUploadCallbackParams {
5
- file: UploadedFile;
6
- uploadedFile: UploadedFile;
7
- }
6
+ type FileUploadCallback = ((file: UploadedFile | null) => void) | null;
8
7
 
9
8
  export function useSingleFileUpload(options: FileUploadOptions | null = null) {
10
- const uploadedFile: Ref<UploadedFile | null> = ref(null);
11
- const onCompleteCb: Ref<Function | null> = ref(null);
12
- const onFileChangeCb: Ref<Function | null> = ref(null);
13
-
14
- const onFileSelected = (e: any) => {
15
- uploadedFile.value = null;
16
- new FileUpload(e.target?.files[0], options)
17
- .onProgress(({ file }: FileUploadCallbackParams) => {
18
- uploadedFile.value = file;
19
- onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
20
- })
21
- .onComplete(({ uploadedFile: completedFile }: FileUploadCallbackParams) => {
22
- uploadedFile.value = completedFile;
23
- onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
24
- onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
25
- })
26
- .upload();
27
- };
28
-
29
- const onDrop = (e: InputEvent) => {
30
- onFileSelected({ target: { files: e.dataTransfer?.files } });
31
- };
32
-
33
- const isFileUploaded = computed(() => {
34
- return uploadedFile.value && uploadedFile.value.url;
35
- });
36
-
37
- const onFileChange = (cb: Function) => {
38
- onFileChangeCb.value = cb;
39
- };
40
-
41
- const onComplete = (cb: Function) => {
42
- onCompleteCb.value = cb;
43
- };
44
-
45
- const clearUploadedFile = () => {
46
- uploadedFile.value = null;
47
- onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
48
- onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
49
- };
50
-
51
- return {
52
- isFileUploaded,
53
- clearUploadedFile,
54
- onComplete,
55
- onFileChange,
56
- onDrop,
57
- onFileSelected,
58
- uploadedFile
59
- };
9
+ const uploadedFile: Ref<UploadedFile | null | undefined> = ref(null);
10
+ const onCompleteCb: Ref<FileUploadCallback> = ref(null);
11
+ const onFileChangeCb: Ref<FileUploadCallback> = ref(null);
12
+
13
+ const onFileSelected = (e: any) => {
14
+ uploadedFile.value = null;
15
+ new FileUpload(e.target?.files[0], options)
16
+ .prepare()
17
+ .onProgress(({ file }) => {
18
+ if (file) {
19
+ uploadedFile.value = file;
20
+ onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
21
+ }
22
+ })
23
+ .onComplete(({ uploadedFile: completedFile }) => {
24
+ if (completedFile) {
25
+ uploadedFile.value = completedFile;
26
+ onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
27
+ onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
28
+ }
29
+ })
30
+ .onError(({ file, error }) => {
31
+ console.error("Failed to upload", file, error);
32
+ FlashMessages.error(`Failed to upload ${file.name}: ${error}`);
33
+ })
34
+ .upload();
35
+ };
36
+
37
+ const onDrop = (e: InputEvent) => {
38
+ onFileSelected({ target: { files: e.dataTransfer?.files } });
39
+ };
40
+
41
+ const isFileUploaded = computed(() => {
42
+ return uploadedFile.value && uploadedFile.value.url;
43
+ });
44
+
45
+ const onFileChange = (cb: FileUploadCallback) => {
46
+ onFileChangeCb.value = cb;
47
+ };
48
+
49
+ const onComplete = (cb: FileUploadCallback) => {
50
+ onCompleteCb.value = cb;
51
+ };
52
+
53
+ const clearUploadedFile = () => {
54
+ uploadedFile.value = null;
55
+ onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
56
+ onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
57
+ };
58
+
59
+ return {
60
+ isFileUploaded,
61
+ clearUploadedFile,
62
+ onComplete,
63
+ onFileChange,
64
+ onDrop,
65
+ onFileSelected,
66
+ uploadedFile
67
+ };
60
68
  }
@@ -11,6 +11,15 @@ export function sleep(delay: number) {
11
11
  return new Promise((resolve) => setTimeout(resolve, delay));
12
12
  }
13
13
 
14
+ /**
15
+ * Poll a callback function until the result is true
16
+ */
17
+ export async function pollUntil(callback: () => any, interval = 1000) {
18
+ while (!(await callback())) {
19
+ await sleep(interval);
20
+ }
21
+ }
22
+
14
23
  /**
15
24
  * Wait for a ref to have a value and then resolve the promise
16
25
  */
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./vue-plugin";
@@ -0,0 +1,5 @@
1
+ .dx-action-table {
2
+ .dx-column-shrink {
3
+ width: 1px;
4
+ }
5
+ }
@@ -5,3 +5,4 @@
5
5
  @import "quasar-reset";
6
6
  @import "general";
7
7
  @import "transitions";
8
+ @import "danx";
@@ -1,19 +1,30 @@
1
+ .dx-action-table {
2
+ .dx-column-shrink {
3
+ width: 1px;
4
+ }
5
+
6
+ // Make sure the checkbox column is left aligned and always the same size
7
+ thead > tr:first-child > th:first-child, tbody > tr:not(.dx-table-summary-tr) > td:first-child {
8
+ @apply text-left w-[1px] pl-4;
9
+ }
10
+ }
11
+
1
12
  .dx-table-summary-tr {
2
- @apply bg-gray-100;
13
+ @apply bg-gray-100;
3
14
 
4
- &.has-selection {
5
- @apply bg-blue-600 text-white;
6
- }
15
+ &.has-selection {
16
+ @apply bg-blue-600 text-white;
17
+ }
7
18
 
8
- &.is-loading {
9
- @apply opacity-50;
10
- }
19
+ &.is-loading {
20
+ @apply opacity-50;
21
+ }
11
22
 
12
- .dx-table-summary-td {
13
- @apply font-bold bg-gray-100 pl-5;
23
+ .dx-table-summary-td {
24
+ @apply font-bold bg-gray-100 pl-5;
14
25
 
15
- &.has-selection {
16
- @apply bg-blue-600 text-white pl-4;
17
- }
18
- }
26
+ &.has-selection {
27
+ @apply bg-blue-600 text-white pl-4;
28
+ }
29
+ }
19
30
  }
@@ -18,17 +18,17 @@ export interface ActionTargetItem extends TypedObject {
18
18
  export type ActionTarget = ActionTargetItem[] | ActionTargetItem | null;
19
19
 
20
20
  export interface ActionOptions {
21
- name?: string;
21
+ name: string;
22
22
  alias?: string;
23
23
  label?: string;
24
+ icon?: string | object;
25
+ iconClass?: string | object;
24
26
  menu?: boolean;
25
27
  batch?: boolean;
26
28
  category?: string;
27
29
  class?: string;
28
30
  debounce?: number;
29
- isApplying?: boolean;
30
31
  optimistic?: boolean | ((action: ActionOptions, target: ActionTargetItem | null, input: any) => void);
31
- trigger?: (target?: ActionTarget, input?: any) => Promise<any>;
32
32
  vnode?: ((target: ActionTarget) => VNode) | any;
33
33
  enabled?: (target: object) => boolean;
34
34
  batchEnabled?: (targets: object[]) => boolean;
@@ -39,5 +39,14 @@ export interface ActionOptions {
39
39
  onBatchSuccess?: (result: any, targets: ActionTargetItem[], input: any) => any;
40
40
  onError?: (result: any, targets: ActionTarget, input: any) => any;
41
41
  onFinish?: (result: any, targets: ActionTarget, input: any) => any;
42
- __type?: string;
42
+ }
43
+
44
+ export interface ActionOptionsPartial extends ActionOptions {
45
+ name?: string;
46
+ }
47
+
48
+ export interface ResourceAction extends ActionOptions {
49
+ isApplying: boolean;
50
+ trigger: (target?: ActionTarget, input?: any) => Promise<any>;
51
+ __type: string;
43
52
  }
@@ -25,17 +25,17 @@ export interface FilterGroup {
25
25
  export interface ListControlsRoutes {
26
26
  list(pager?: ListControlsPagination): Promise<ActionTargetItem[]>;
27
27
 
28
- summary?(filter?: ListControlsFilter): Promise<object>;
28
+ summary?(filter?: ListControlsFilter): Promise<AnyObject>;
29
29
 
30
30
  details?(target: ActionTargetItem): Promise<ActionTargetItem>;
31
31
 
32
32
  more?(pager: ListControlsPagination): Promise<ActionTargetItem[]>;
33
33
 
34
- fieldOptions?(filter?: AnyObject): Promise<object>;
34
+ fieldOptions?(filter?: AnyObject): Promise<AnyObject>;
35
35
 
36
- applyAction?(action: string, target: ActionTargetItem | null, data: object): Promise<object>;
36
+ applyAction?(action: string, target: ActionTargetItem | null, data?: object): Promise<AnyObject>;
37
37
 
38
- batchAction?(action: string, targets: ActionTargetItem[], data: object): Promise<object>;
38
+ batchAction?(action: string, targets: ActionTargetItem[], data: object): Promise<AnyObject>;
39
39
 
40
40
  export?(filter?: ListControlsFilter, name?: string): Promise<void>;
41
41
  }
@@ -1,7 +1,10 @@
1
+ import { AnyObject, TypedObject } from "src/types/shared";
2
+
1
3
  export interface FileUploadOptions {
2
4
  directory?: string,
3
5
  createPresignedUpload?: ((path: string, name: string, mime?: string) => Promise<UploadedFile>) | null;
4
6
  completePresignedUpload?: ((fileId: string) => Promise<UploadedFile>) | null;
7
+ refreshFile?: ((fileId: string) => Promise<UploadedFile>) | null;
5
8
  }
6
9
 
7
10
  export interface XHRFileUpload {
@@ -12,11 +15,12 @@ export interface XHRFileUpload {
12
15
  body?: FormData | UploadedFile | string;
13
16
  }
14
17
 
15
- export interface UploadedFile {
16
- id: string,
18
+ export interface UploadedFile extends TypedObject {
19
+ id: string;
17
20
  resource_id?: string;
18
- name: string,
19
- size: number,
21
+ name: string;
22
+ filename?: string;
23
+ size: number;
20
24
  type: string;
21
25
  mimeType?: string;
22
26
  mime?: string;
@@ -27,6 +31,7 @@ export interface UploadedFile {
27
31
  thumb?: UploadedFile;
28
32
  optimized?: UploadedFile;
29
33
  transcodes?: UploadedFile[];
34
+ meta?: AnyObject;
30
35
  }
31
36
 
32
37
  export interface FileUploadCompleteCallbackParams {
@@ -44,7 +49,7 @@ export interface FileUploadProgressCallbackParams {
44
49
  }
45
50
 
46
51
  export interface FileUploadErrorCallbackParams {
47
- e: InputEvent;
52
+ e: InputEvent | ProgressEvent;
48
53
  file: UploadedFile;
49
54
  error: any;
50
55
  }
@@ -9,4 +9,3 @@ export * from "./forms";
9
9
  export * from "./requests";
10
10
  export * from "./shared";
11
11
  export * from "./tables";
12
-
@@ -10,6 +10,8 @@ export interface RequestApi {
10
10
  get(url: string, options?: RequestCallOptions): Promise<any>;
11
11
 
12
12
  post(url: string, data?: object, options?: RequestCallOptions): Promise<any>;
13
+
14
+ poll(url: string, options?: RequestCallOptions, interval: number, fnUntil: (response) => boolean): Promise<any>;
13
15
  }
14
16
 
15
17
  export interface HttpResponse {
@@ -2,26 +2,32 @@ import { VNode } from "vue";
2
2
  import { ActionOptions } from "./actions";
3
3
 
4
4
  export interface TableColumn {
5
- actionMenu?: ActionOptions[],
6
- align?: string,
7
- category?: string,
8
- class?: string | object,
9
- field?: string,
10
- format?: (value: any, options: any) => any,
11
- innerClass?: string | object,
12
- style?: string | object,
13
- headerStyle?: string | object,
14
- isSavingRow?: boolean | (() => boolean),
15
- label: string,
16
- maxWidth?: number,
17
- minWidth?: number,
18
- name: string,
19
- onClick?: (target: any) => void,
20
- required?: boolean,
21
- resizeable?: boolean,
22
- sortable?: boolean,
23
- sortBy?: string,
24
- sortByExpression?: string,
25
- titleColumns?: () => string[],
26
- vnode?: () => VNode | any,
5
+ actionMenu?: ActionOptions[];
6
+ align?: string;
7
+ category?: string;
8
+ class?: string | object;
9
+ field?: string;
10
+ format?: (value: any, options: any) => any;
11
+ hideContent?: boolean;
12
+ shrink?: boolean;
13
+ headerClass?: string | object;
14
+ summaryClass?: string | object;
15
+ columnClass?: string | object;
16
+ innerClass?: string | object;
17
+ style?: string | object;
18
+ headerStyle?: string | object;
19
+ isSavingRow?: boolean | (() => boolean);
20
+ label: string;
21
+ width?: number;
22
+ maxWidth?: number;
23
+ minWidth?: number;
24
+ name: string;
25
+ onClick?: (target: any) => void;
26
+ required?: boolean;
27
+ resizeable?: boolean;
28
+ sortable?: boolean;
29
+ sortBy?: string;
30
+ sortByExpression?: string;
31
+ titleColumns?: () => string[];
32
+ vnode?: (row?) => VNode | any;
27
33
  }