quasar-ui-danx 0.0.10 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +8 -2
- package/src/components/ActionTable/ActionTable.vue +143 -0
- package/src/components/ActionTable/BatchActionMenu.vue +60 -0
- package/src/components/ActionTable/EmptyTableState.vue +33 -0
- package/src/components/ActionTable/Filters/CollapsableFiltersSidebar.vue +36 -0
- package/src/components/ActionTable/Filters/FilterGroupItem.vue +28 -0
- package/src/components/ActionTable/Filters/FilterGroupList.vue +76 -0
- package/src/components/ActionTable/Filters/FilterListToggle.vue +50 -0
- package/src/components/ActionTable/Filters/FilterableField.vue +143 -0
- package/src/components/ActionTable/Filters/index.ts +5 -0
- package/src/components/ActionTable/Form/Fields/BooleanField.vue +37 -0
- package/src/components/ActionTable/Form/Fields/ConfirmPasswordField.vue +46 -0
- package/src/components/ActionTable/Form/Fields/DateField.vue +59 -0
- package/src/components/ActionTable/Form/Fields/DateRangeField.vue +110 -0
- package/src/components/ActionTable/Form/Fields/DateTimeField.vue +50 -0
- package/src/components/ActionTable/Form/Fields/DateTimePicker.vue +59 -0
- package/src/components/ActionTable/Form/Fields/EditableDiv.vue +39 -0
- package/src/components/ActionTable/Form/Fields/FieldLabel.vue +32 -0
- package/src/components/ActionTable/Form/Fields/FileUploadButton.vue +78 -0
- package/src/components/ActionTable/Form/Fields/InlineDateTimeField.vue +44 -0
- package/src/components/ActionTable/Form/Fields/IntegerField.vue +26 -0
- package/src/components/ActionTable/Form/Fields/LabelValueBlock.vue +22 -0
- package/src/components/ActionTable/Form/Fields/LabeledInput.vue +63 -0
- package/src/components/ActionTable/Form/Fields/MultiFileField.vue +91 -0
- package/src/components/ActionTable/Form/Fields/MultiKeywordField.vue +57 -0
- package/src/components/ActionTable/Form/Fields/NewPasswordField.vue +39 -0
- package/src/components/ActionTable/Form/Fields/NumberField.vue +94 -0
- package/src/components/ActionTable/Form/Fields/NumberRangeField.vue +140 -0
- package/src/components/ActionTable/Form/Fields/SelectDrawer.vue +136 -0
- package/src/components/ActionTable/Form/Fields/SelectField.vue +318 -0
- package/src/components/ActionTable/Form/Fields/SelectWithChildrenField.vue +81 -0
- package/src/components/ActionTable/Form/Fields/SingleFileField.vue +78 -0
- package/src/components/ActionTable/Form/Fields/TextField.vue +82 -0
- package/src/components/ActionTable/Form/Fields/WysiwygField.vue +46 -0
- package/src/components/ActionTable/Form/Fields/index.ts +23 -0
- package/src/components/ActionTable/Form/RenderedForm.vue +76 -0
- package/src/components/ActionTable/Form/index.ts +2 -0
- package/src/components/ActionTable/RenderComponentColumn.vue +22 -0
- package/src/components/ActionTable/TableSummaryRow.vue +95 -0
- package/src/components/ActionTable/index.ts +10 -0
- package/src/components/ActionTable/listActions.ts +362 -0
- package/src/components/ActionTable/listHelpers.ts +74 -0
- package/src/components/ActionTable/tableColumns.ts +72 -0
- package/src/components/DragAndDrop/HandleDraggable.vue +29 -29
- package/src/components/DragAndDrop/ListItemDraggable.vue +10 -10
- package/src/components/DragAndDrop/index.ts +0 -1
- package/src/components/DragAndDrop/listDragAndDrop.ts +1 -1
- package/src/components/Utility/CollapsableSidebar.vue +119 -0
- package/src/components/Utility/ContentDrawer.vue +70 -0
- package/src/components/Utility/Dialogs/ConfirmDialog.vue +132 -0
- package/src/components/Utility/Dialogs/FullScreenDialog.vue +46 -0
- package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +105 -0
- package/src/components/Utility/Dialogs/InfoDialog.vue +92 -0
- package/src/components/Utility/Dialogs/InputDialog.vue +35 -0
- package/src/components/Utility/ImagePreview.vue +192 -0
- package/src/components/Utility/Popover/PopoverMenu.vue +64 -0
- package/src/components/Utility/Transitions/ListTransition.vue +50 -0
- package/src/components/Utility/Transitions/SlideTransition.vue +63 -0
- package/src/components/Utility/Transitions/StaggeredListTransition.vue +97 -0
- package/src/components/Utility/index.ts +11 -0
- package/src/components/index.ts +3 -0
- package/src/helpers/FileUpload.ts +295 -0
- package/src/helpers/FlashMessages.ts +79 -0
- package/src/helpers/array.ts +37 -0
- package/src/helpers/compatibility.ts +64 -0
- package/src/helpers/date.ts +5 -0
- package/src/helpers/download.ts +200 -0
- package/src/helpers/downloadPdf.ts +92 -0
- package/src/helpers/files.ts +52 -0
- package/src/helpers/formats.ts +183 -0
- package/src/helpers/http.ts +62 -0
- package/src/helpers/index.ts +12 -1
- package/src/helpers/multiFileUpload.ts +68 -0
- package/src/helpers/singleFileUpload.ts +54 -0
- package/src/helpers/storage.ts +8 -0
- package/src/index.esm.js +3 -4
- package/src/svg/FilterIcon.svg +7 -0
- package/src/svg/ImageIcon.svg +30 -0
- package/src/svg/PdfIcon.svg +21 -0
- package/src/svg/PercentIcon.svg +13 -0
- package/src/svg/TrashIcon.svg +15 -0
- package/src/svg/XIcon.svg +18 -0
- package/src/svg/index.ts +8 -0
- package/src/vendor/tinymce-config.ts +1 -0
- package/src/vue-plugin.js +7 -4
- package/tsconfig.json +14 -13
- package/src/components/DragAndDrop/Icons/index.ts +0 -2
- /package/src/{components/DragAndDrop/Icons → svg}/DragHandleDotsIcon.svg +0 -0
- /package/src/{components/DragAndDrop/Icons → svg}/DragHandleIcon.svg +0 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
import { download } from "@ui/helpers/download";
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Asynchronously load a file from the URL and trigger a download in the browser
|
5
|
+
*
|
6
|
+
* @param url
|
7
|
+
* @param filename
|
8
|
+
* @param postParams
|
9
|
+
* @returns {Promise<void>}
|
10
|
+
*/
|
11
|
+
export async function downloadFile(url, filename = "", postParams = null) {
|
12
|
+
let fetchOptions = undefined;
|
13
|
+
|
14
|
+
if (postParams) {
|
15
|
+
fetchOptions = {
|
16
|
+
method: "POST",
|
17
|
+
"Content-Type": "application/json",
|
18
|
+
body: JSON.stringify(postParams)
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
const response = await fetch(url, fetchOptions);
|
23
|
+
|
24
|
+
if (!response.ok) {
|
25
|
+
throw Error("File download failed: invalid response from server");
|
26
|
+
}
|
27
|
+
|
28
|
+
let errorMessage;
|
29
|
+
|
30
|
+
// Handle a JSON response (which indicates an error occurred)
|
31
|
+
try {
|
32
|
+
// @ts-expect-error data is defined on response
|
33
|
+
const jsonResponse = JSON.parse(new TextDecoder().decode(response.data));
|
34
|
+
console.error("Error downloading file:", jsonResponse);
|
35
|
+
errorMessage = jsonResponse.message;
|
36
|
+
if (jsonResponse.errors) {
|
37
|
+
errorMessage = jsonResponse.errors[0].message;
|
38
|
+
}
|
39
|
+
} catch (e) {
|
40
|
+
// we expect an error thrown for invalid JSON when the response is a file
|
41
|
+
}
|
42
|
+
|
43
|
+
if (errorMessage) {
|
44
|
+
throw new Error("Failed to download file: " + errorMessage);
|
45
|
+
}
|
46
|
+
|
47
|
+
await downloadFileResponse(response, filename);
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Downloads a file from a response object w/ a file attachment
|
52
|
+
*
|
53
|
+
* @param response
|
54
|
+
* @param filename
|
55
|
+
*/
|
56
|
+
export async function downloadFileResponse(response, filename = "") {
|
57
|
+
const contentDisposition = getResponseHeader(
|
58
|
+
response,
|
59
|
+
"content-disposition",
|
60
|
+
""
|
61
|
+
);
|
62
|
+
|
63
|
+
const contentType = getResponseHeader(response, "content-type", "");
|
64
|
+
|
65
|
+
const match = contentDisposition.match(/filename="([^"]+)"/);
|
66
|
+
|
67
|
+
filename = filename || (match && match[1]) || "download.pdf";
|
68
|
+
|
69
|
+
let data = response.data;
|
70
|
+
if (!data) {
|
71
|
+
data = await response.blob();
|
72
|
+
}
|
73
|
+
|
74
|
+
download(data, filename, contentType);
|
75
|
+
}
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Get a header from a response object
|
79
|
+
* @param response
|
80
|
+
* @param header
|
81
|
+
* @param defaultValue
|
82
|
+
* @returns {*}
|
83
|
+
*/
|
84
|
+
export function getResponseHeader(response, header, defaultValue) {
|
85
|
+
if (response.headers) {
|
86
|
+
if (typeof response.headers.get === "function") {
|
87
|
+
return response.headers.get(header) || defaultValue;
|
88
|
+
} else {
|
89
|
+
return response.headers[header] || defaultValue;
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import { FlashMessages, useCompatibility } from "@ui/helpers";
|
2
|
+
import ExifReader from "exifreader";
|
3
|
+
|
4
|
+
export async function resolveFileLocation(file, waitMessage = null) {
|
5
|
+
if (file.location) {
|
6
|
+
return file.location;
|
7
|
+
}
|
8
|
+
|
9
|
+
try {
|
10
|
+
const tags = await ExifReader.load(file.blobUrl || file.url, {
|
11
|
+
expanded: true
|
12
|
+
});
|
13
|
+
if (tags.gps) {
|
14
|
+
return {
|
15
|
+
latitude: tags.gps.Latitude,
|
16
|
+
longitude: tags.gps.Longitude
|
17
|
+
};
|
18
|
+
}
|
19
|
+
|
20
|
+
const { waitForLocation, location } = useCompatibility();
|
21
|
+
|
22
|
+
// Show a waiting for location message if we have not returned within 1 second
|
23
|
+
if (waitMessage) {
|
24
|
+
setTimeout(() => {
|
25
|
+
if (!location.value && waitMessage) {
|
26
|
+
FlashMessages.warning(waitMessage);
|
27
|
+
}
|
28
|
+
}, 1000);
|
29
|
+
}
|
30
|
+
|
31
|
+
// Wait for the browser to return the location (https only as http will not return a location)
|
32
|
+
if (window.location.protocol === "https:") {
|
33
|
+
await waitForLocation();
|
34
|
+
}
|
35
|
+
// Ignore the wait message if we already returned
|
36
|
+
waitMessage = false;
|
37
|
+
if (!location.value) {
|
38
|
+
return null;
|
39
|
+
}
|
40
|
+
|
41
|
+
return {
|
42
|
+
latitude: location.value.latitude,
|
43
|
+
longitude: location.value.longitude,
|
44
|
+
accuracy: location.value.accuracy,
|
45
|
+
altitude: location.value.altitude,
|
46
|
+
altitudeAccuracy: location.value.altitudeAccuracy
|
47
|
+
};
|
48
|
+
} catch (error) {
|
49
|
+
console.error(error);
|
50
|
+
return null;
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,183 @@
|
|
1
|
+
import { DateTime, IANAZone } from "luxon";
|
2
|
+
|
3
|
+
const SERVER_TZ = new IANAZone("America/Chicago");
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Converts a date string from the server's time zone to the user's time zone.
|
7
|
+
* @param {String} dateTimeString
|
8
|
+
* @returns {DateTime}
|
9
|
+
*/
|
10
|
+
export function localizedDateTime(dateTimeString) {
|
11
|
+
dateTimeString = dateTimeString?.replace("T", " ");
|
12
|
+
// noinspection JSCheckFunctionSignatures
|
13
|
+
return DateTime.fromSQL(dateTimeString, { zone: SERVER_TZ }).setZone("local");
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Converts a date string from the user's time zone to the server's time zone.
|
18
|
+
* @param dateTimeString
|
19
|
+
* @returns {DateTime}
|
20
|
+
*/
|
21
|
+
export function remoteDateTime(dateTimeString) {
|
22
|
+
dateTimeString = dateTimeString?.replace("T", " ");
|
23
|
+
// noinspection JSCheckFunctionSignatures
|
24
|
+
return DateTime.fromSQL(dateTimeString, { zone: "local" }).setZone(SERVER_TZ);
|
25
|
+
}
|
26
|
+
|
27
|
+
/**
|
28
|
+
* @param {DateTime|String} dateTime
|
29
|
+
* @returns {DateTime|*}
|
30
|
+
*/
|
31
|
+
export function parseDateTime(dateTime) {
|
32
|
+
if (typeof dateTime === "string") {
|
33
|
+
dateTime = dateTime.replace("T", " ").replace(/\//g, "-");
|
34
|
+
return DateTime.fromSQL(dateTime);
|
35
|
+
}
|
36
|
+
return dateTime || DateTime.fromSQL("0000-00-00 00:00:00");
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Parses a Quasar formatted date string into a Luxon DateTime object
|
41
|
+
* @param date
|
42
|
+
* @param format
|
43
|
+
* @returns {DateTime}
|
44
|
+
*/
|
45
|
+
export function parseQDate(date, format = "yyyy/MM/dd") {
|
46
|
+
return DateTime.fromFormat(date, format);
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Parses a Quasar formatted date/time string into a Luxon DateTime object
|
51
|
+
* @param date
|
52
|
+
* @param format
|
53
|
+
* @returns {DateTime}
|
54
|
+
*/
|
55
|
+
export function parseQDateTime(date, format = "yyyy/MM/dd HH:mm:ss") {
|
56
|
+
return DateTime.fromFormat(date, format);
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Formats a Luxon DateTime object into a Quasar formatted date string
|
61
|
+
* @param date
|
62
|
+
* @returns {string}
|
63
|
+
*/
|
64
|
+
export function fQDate(date) {
|
65
|
+
return fDate(date, { format: "yyyy/MM/dd" });
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
*
|
70
|
+
* @param {String} dateTimeString
|
71
|
+
* @param options
|
72
|
+
* @returns {string}
|
73
|
+
*/
|
74
|
+
export function fLocalizedDateTime(dateTimeString, options = {}) {
|
75
|
+
return fDateTime(localizedDateTime(dateTimeString), options);
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Formats a date/time object or string into a human-readable format
|
80
|
+
*
|
81
|
+
* @param {String|Object} dateTime
|
82
|
+
* @param format
|
83
|
+
* @param {String|null} empty
|
84
|
+
* @returns {string}
|
85
|
+
*/
|
86
|
+
export function fDateTime(
|
87
|
+
dateTime = null,
|
88
|
+
{ format = "M/d/yy h:mma", empty = "- -" } = {}
|
89
|
+
) {
|
90
|
+
const formatted = (dateTime ? parseDateTime(dateTime) : DateTime.now()).toFormat(format).toLowerCase();
|
91
|
+
return formatted === "invalid datetime" ? empty : formatted;
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Formats a date/time object or string into the best format for DB input
|
96
|
+
* @param dateTime
|
97
|
+
* @returns {string}
|
98
|
+
*/
|
99
|
+
export function dbDateTime(dateTime = null) {
|
100
|
+
return fDateTime(dateTime, { format: "yyyy-MM-dd HH:mm:ss", empty: null });
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Formats a date object or string into a human-readable format
|
105
|
+
* @param {String|Object} dateTime
|
106
|
+
* @param {String|null} empty
|
107
|
+
* @param format
|
108
|
+
* @returns {string}
|
109
|
+
*/
|
110
|
+
export function fDate(dateTime, { empty = "--", format = "M/d/yy" } = {}) {
|
111
|
+
const formatted = parseDateTime(dateTime).toFormat(format);
|
112
|
+
return ["Invalid DateTime", "invalid datetime"].includes(formatted) ? empty : formatted;
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Formats a number of seconds into Hours / Minutes / Seconds or just Minutes and Seconds
|
117
|
+
*
|
118
|
+
* @param second
|
119
|
+
* @returns {string}
|
120
|
+
*/
|
121
|
+
export function fSecondsToTime(second) {
|
122
|
+
const time = DateTime.now().setZone("UTC").startOf("year").set({ second });
|
123
|
+
const hours = Math.floor(second / 3600);
|
124
|
+
return (hours ? hours + ":" : "") + time.toFormat("mm:ss");
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* Formats an amount into USD currency format
|
129
|
+
* @param amount
|
130
|
+
* @returns {string}
|
131
|
+
*/
|
132
|
+
export function fCurrency(amount) {
|
133
|
+
return new Intl.NumberFormat("en-US", {
|
134
|
+
style: "currency",
|
135
|
+
currency: "USD"
|
136
|
+
}).format(amount);
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Formats a number into a human-readable format
|
141
|
+
* @param number
|
142
|
+
* @param options
|
143
|
+
* @returns {string}
|
144
|
+
*/
|
145
|
+
export function fNumber(number, options = {}) {
|
146
|
+
return new Intl.NumberFormat("en-US", options).format(number);
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Truncates the string by removing chars from the middle of the string
|
151
|
+
* @param str
|
152
|
+
* @param maxLength
|
153
|
+
* @returns {string|*}
|
154
|
+
*/
|
155
|
+
export function centerTruncate(str, maxLength) {
|
156
|
+
if (str.length > maxLength) {
|
157
|
+
const frontCharCount = Math.floor((maxLength - 3) / 2);
|
158
|
+
const backCharCount = maxLength - frontCharCount - 3;
|
159
|
+
return (
|
160
|
+
str.substring(0, frontCharCount) +
|
161
|
+
"..." +
|
162
|
+
str.substring(str.length - backCharCount)
|
163
|
+
);
|
164
|
+
} else {
|
165
|
+
return str;
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Formats a number into a percentage
|
171
|
+
* @param num
|
172
|
+
* @param options
|
173
|
+
* @returns {string}
|
174
|
+
*/
|
175
|
+
export function fPercent(num, options = { multiplier: 100, maximumFractionDigits: 1, NaN: "N/A" }) {
|
176
|
+
num = parseFloat(num);
|
177
|
+
|
178
|
+
if (isNaN(num)) {
|
179
|
+
return options.NaN;
|
180
|
+
}
|
181
|
+
|
182
|
+
return fNumber(num * options.multiplier, options) + "%";
|
183
|
+
}
|
@@ -0,0 +1,62 @@
|
|
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
|
+
},
|
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
|
+
}
|
24
|
+
};
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Fetches a resource list applying the filter. If there is a selected resource,
|
28
|
+
* stores that resource from the already populated list. If that resource does not exist
|
29
|
+
* also fetches that resource record from the endpoint, then adds it to the list if it
|
30
|
+
* does not exist in the filtered list
|
31
|
+
*
|
32
|
+
* @param fetchFn
|
33
|
+
* @param list
|
34
|
+
* @param id
|
35
|
+
* @param filter
|
36
|
+
* @returns {Promise<void>}
|
37
|
+
*/
|
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
|
+
}
|
44
|
+
|
45
|
+
// Get the filtered campaign list
|
46
|
+
list.value = await fetchFn(filter);
|
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
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Returns the value of the URL parameter (if it is set)
|
56
|
+
* @param key
|
57
|
+
* @param url
|
58
|
+
*/
|
59
|
+
export function getUrlParam(key, url = undefined) {
|
60
|
+
const params = new URLSearchParams(url?.replace(/.*\?/, "") || window.location.search);
|
61
|
+
return params.get(key);
|
62
|
+
}
|
package/src/helpers/index.ts
CHANGED
@@ -1 +1,12 @@
|
|
1
|
-
export * from
|
1
|
+
export * from "./array";
|
2
|
+
export * from "./compatibility";
|
3
|
+
export * from "./download";
|
4
|
+
export * from "./files";
|
5
|
+
export * from "./FileUpload";
|
6
|
+
export * from "./FlashMessages";
|
7
|
+
export * from "./formats";
|
8
|
+
export * from "./http";
|
9
|
+
export * from "./multiFileUpload";
|
10
|
+
export * from "./singleFileUpload";
|
11
|
+
export * from "./storage";
|
12
|
+
export * from "./utils";
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { FileUpload, FileUploadOptions } from "@ui/helpers/FileUpload";
|
2
|
+
import { ref } from "vue";
|
3
|
+
|
4
|
+
export function useMultiFileUpload(options: FileUploadOptions) {
|
5
|
+
const uploadedFiles = ref([]);
|
6
|
+
const onCompleteCb = ref(null);
|
7
|
+
const onFilesChangeCb = ref(null);
|
8
|
+
const onFilesSelected = (e) => {
|
9
|
+
uploadedFiles.value = [...uploadedFiles.value, ...e.target.files];
|
10
|
+
new FileUpload(e.target.files, options)
|
11
|
+
.onProgress(({ file }) => {
|
12
|
+
updateFileInList(file);
|
13
|
+
})
|
14
|
+
.onComplete(({ file, uploadedFile }) => {
|
15
|
+
updateFileInList(file, uploadedFile);
|
16
|
+
})
|
17
|
+
.onAllComplete(() => {
|
18
|
+
onCompleteCb.value && onCompleteCb.value();
|
19
|
+
onFilesChangeCb.value && onFilesChangeCb.value(uploadedFiles.value);
|
20
|
+
})
|
21
|
+
.upload();
|
22
|
+
};
|
23
|
+
|
24
|
+
function updateFileInList(file, replace = null) {
|
25
|
+
const index = uploadedFiles.value.findIndex(f => f.id === file.id);
|
26
|
+
if (index !== -1) {
|
27
|
+
uploadedFiles.value.splice(index, 1, replace || file);
|
28
|
+
}
|
29
|
+
onFilesChangeCb.value && onFilesChangeCb.value(uploadedFiles.value);
|
30
|
+
}
|
31
|
+
|
32
|
+
const onDrop = (e) => {
|
33
|
+
onFilesSelected({ target: { files: e.dataTransfer.files } });
|
34
|
+
};
|
35
|
+
|
36
|
+
const onFilesChange = (cb) => {
|
37
|
+
onFilesChangeCb.value = cb;
|
38
|
+
};
|
39
|
+
|
40
|
+
const onComplete = (cb) => {
|
41
|
+
onCompleteCb.value = cb;
|
42
|
+
};
|
43
|
+
|
44
|
+
const onClear = () => {
|
45
|
+
uploadedFiles.value = [];
|
46
|
+
onFilesChangeCb.value && onFilesChangeCb.value(uploadedFiles.value);
|
47
|
+
onCompleteCb.value && onCompleteCb.value();
|
48
|
+
};
|
49
|
+
|
50
|
+
const onRemove = (file) => {
|
51
|
+
const index = uploadedFiles.value.findIndex(f => f.id === file.id);
|
52
|
+
if (index !== -1) {
|
53
|
+
uploadedFiles.value.splice(index, 1);
|
54
|
+
}
|
55
|
+
onFilesChangeCb.value && onFilesChangeCb.value(uploadedFiles.value);
|
56
|
+
onCompleteCb.value && onCompleteCb.value();
|
57
|
+
};
|
58
|
+
|
59
|
+
return {
|
60
|
+
onClear,
|
61
|
+
onRemove,
|
62
|
+
onComplete,
|
63
|
+
onFilesChange,
|
64
|
+
onDrop,
|
65
|
+
onFilesSelected,
|
66
|
+
uploadedFiles
|
67
|
+
};
|
68
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { FileUpload, FileUploadOptions } from "@ui/helpers";
|
2
|
+
import { computed, ref } from "vue";
|
3
|
+
|
4
|
+
export function useSingleFileUpload(options: FileUploadOptions) {
|
5
|
+
const uploadedFile = ref(null);
|
6
|
+
const onCompleteCb = ref(null);
|
7
|
+
const onFileChangeCb = ref(null);
|
8
|
+
|
9
|
+
const onFileSelected = (e) => {
|
10
|
+
uploadedFile.value = null;
|
11
|
+
new FileUpload(e.target.files[0], options)
|
12
|
+
.onProgress(({ file }) => {
|
13
|
+
uploadedFile.value = file;
|
14
|
+
onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
|
15
|
+
})
|
16
|
+
.onComplete(({ uploadedFile: completedFile }) => {
|
17
|
+
uploadedFile.value = completedFile;
|
18
|
+
onCompleteCb.value && onCompleteCb.value(uploadedFile.value);
|
19
|
+
onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
|
20
|
+
})
|
21
|
+
.upload();
|
22
|
+
};
|
23
|
+
|
24
|
+
const onDrop = (e) => {
|
25
|
+
onFileSelected({ target: { files: e.dataTransfer.files } });
|
26
|
+
};
|
27
|
+
|
28
|
+
const isFileUploaded = computed(() => {
|
29
|
+
return uploadedFile.value && uploadedFile.value.url;
|
30
|
+
});
|
31
|
+
|
32
|
+
const onFileChange = (cb) => {
|
33
|
+
onFileChangeCb.value = cb;
|
34
|
+
};
|
35
|
+
|
36
|
+
const onComplete = (cb) => {
|
37
|
+
onCompleteCb.value = cb;
|
38
|
+
};
|
39
|
+
|
40
|
+
const onClear = () => {
|
41
|
+
uploadedFile.value = null;
|
42
|
+
onFileChangeCb.value && onFileChangeCb.value(uploadedFile.value);
|
43
|
+
};
|
44
|
+
|
45
|
+
return {
|
46
|
+
isFileUploaded,
|
47
|
+
onClear,
|
48
|
+
onComplete,
|
49
|
+
onFileChange,
|
50
|
+
onDrop,
|
51
|
+
onFileSelected,
|
52
|
+
uploadedFile
|
53
|
+
};
|
54
|
+
}
|
package/src/index.esm.js
CHANGED
@@ -0,0 +1,7 @@
|
|
1
|
+
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<g>
|
3
|
+
<path
|
4
|
+
d="M9.16667 17.5V12.5H10.8333V14.1667H17.5V15.8333H10.8333V17.5H9.16667ZM2.5 15.8333V14.1667H7.5V15.8333H2.5ZM5.83333 12.5V10.8333H2.5V9.16667H5.83333V7.5H7.5V12.5H5.83333ZM9.16667 10.8333V9.16667H17.5V10.8333H9.16667ZM12.5 7.5V2.5H14.1667V4.16667H17.5V5.83333H14.1667V7.5H12.5ZM2.5 5.83333V4.16667H10.8333V5.83333H2.5Z"
|
5
|
+
fill="currentColor"/>
|
6
|
+
</g>
|
7
|
+
</svg>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<svg
|
2
|
+
viewBox="0 0 20 20"
|
3
|
+
fill="none"
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
5
|
+
>
|
6
|
+
<path
|
7
|
+
fill-rule="evenodd"
|
8
|
+
clip-rule="evenodd"
|
9
|
+
d="M17.8587 18.5578C18.2529 18.5578 18.5725 18.2383 18.5725 17.8441L18.5725 2.1414C18.5725 1.7472 18.2529 1.42764 17.8587 1.42764L2.15604 1.42764C1.76184 1.42764 1.44228 1.7472 1.44228 2.1414L1.44228 17.8441C1.44228 18.2383 1.76184 18.5578 2.15604 18.5578L17.8587 18.5578ZM20 17.8441C20 19.0267 19.0413 19.9854 17.8587 19.9854L2.15604 19.9854C0.97345 19.9854 0.014769 19.0267 0.014769 17.8441L0.014769 2.1414C0.014769 0.958801 0.97345 0.00012055 2.15604 0.00012055L17.8587 0.00012055C19.0413 0.00012055 20 0.958801 20 2.1414L20 17.8441Z"
|
10
|
+
fill="currentColor"
|
11
|
+
/>
|
12
|
+
<path
|
13
|
+
fill-rule="evenodd"
|
14
|
+
clip-rule="evenodd"
|
15
|
+
d="M13.2048 4.99588C12.2193 4.99588 11.4204 5.79478 11.4204 6.78027C11.4204 7.76577 12.2193 8.56467 13.2048 8.56467C14.1903 8.56467 14.9892 7.76577 14.9892 6.78027C14.9892 5.79478 14.1903 4.99588 13.2048 4.99588ZM9.99292 6.78027C9.99292 5.00638 11.4309 3.56836 13.2048 3.56836C14.9787 3.56836 16.4167 5.00638 16.4167 6.78027C16.4167 8.55416 14.9787 9.99218 13.2048 9.99218C11.4309 9.99218 9.99292 8.55416 9.99292 6.78027Z"
|
16
|
+
fill="currentColor"
|
17
|
+
/>
|
18
|
+
<path
|
19
|
+
fill-rule="evenodd"
|
20
|
+
clip-rule="evenodd"
|
21
|
+
d="M2.84806 9.9929C5.50442 9.93497 8.09526 10.8216 10.1592 12.4951C12.2256 14.1705 13.6294 16.5256 14.1203 19.1401C14.193 19.5275 13.9379 19.9005 13.5505 19.9733C13.1631 20.046 12.79 19.7909 12.7173 19.4035C12.2889 17.1216 11.0636 15.0662 9.26019 13.6039C7.45676 12.1417 5.19246 11.3678 2.8713 11.4203C2.86529 11.4204 2.85927 11.4205 2.85326 11.4204C2.18034 11.4186 1.50881 11.4813 0.847849 11.6076C0.460656 11.6816 0.0867981 11.4277 0.0128145 11.0405C-0.0611691 10.6533 0.192737 10.2794 0.57993 10.2055C1.3275 10.0626 2.08698 9.99144 2.84806 9.9929Z"
|
22
|
+
fill="currentColor"
|
23
|
+
/>
|
24
|
+
<path
|
25
|
+
fill-rule="evenodd"
|
26
|
+
clip-rule="evenodd"
|
27
|
+
d="M10.9536 13.8192C12.4542 13.1749 14.0708 12.8443 15.7039 12.8477C16.9949 12.8471 18.2773 13.0574 19.5005 13.4705C19.8739 13.5966 20.0745 14.0016 19.9483 14.3751C19.8222 14.7486 19.4172 14.9491 19.0437 14.823C17.9677 14.4596 16.8395 14.2746 15.7037 14.2752L15.7018 14.2752C14.263 14.2721 12.8388 14.5633 11.5168 15.1309C11.1546 15.2864 10.7348 15.1189 10.5793 14.7567C10.4238 14.3944 10.5914 13.9747 10.9536 13.8192Z"
|
28
|
+
fill="currentColor"
|
29
|
+
/>
|
30
|
+
</svg>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 550.801 550.801">
|
2
|
+
<g>
|
3
|
+
<path d="M160.381,282.225c0-14.832-10.299-23.684-28.474-23.684c-7.414,0-12.437,0.715-15.071,1.432V307.6
|
4
|
+
c3.114,0.707,6.942,0.949,12.192,0.949C148.419,308.549,160.381,298.74,160.381,282.225z"/>
|
5
|
+
<path d="M272.875,259.019c-8.145,0-13.397,0.717-16.519,1.435v105.523c3.116,0.729,8.142,0.729,12.69,0.729
|
6
|
+
c33.017,0.231,54.554-17.946,54.554-56.474C323.842,276.719,304.215,259.019,272.875,259.019z"/>
|
7
|
+
<path d="M488.426,197.019H475.2v-63.816c0-0.398-0.063-0.799-0.116-1.202c-0.021-2.534-0.827-5.023-2.562-6.995L366.325,3.694
|
8
|
+
c-0.032-0.031-0.063-0.042-0.085-0.076c-0.633-0.707-1.371-1.295-2.151-1.804c-0.231-0.155-0.464-0.285-0.706-0.419
|
9
|
+
c-0.676-0.369-1.393-0.675-2.131-0.896c-0.2-0.056-0.38-0.138-0.58-0.19C359.87,0.119,359.037,0,358.193,0H97.2
|
10
|
+
c-11.918,0-21.6,9.693-21.6,21.601v175.413H62.377c-17.049,0-30.873,13.818-30.873,30.873v160.545
|
11
|
+
c0,17.043,13.824,30.87,30.873,30.87h13.224V529.2c0,11.907,9.682,21.601,21.6,21.601h356.4c11.907,0,21.6-9.693,21.6-21.601
|
12
|
+
V419.302h13.226c17.044,0,30.871-13.827,30.871-30.87v-160.54C519.297,210.838,505.47,197.019,488.426,197.019z M97.2,21.605
|
13
|
+
h250.193v110.513c0,5.967,4.841,10.8,10.8,10.8h95.407v54.108H97.2V21.605z M362.359,309.023c0,30.876-11.243,52.165-26.82,65.333
|
14
|
+
c-16.971,14.117-42.82,20.814-74.396,20.814c-18.9,0-32.297-1.197-41.401-2.389V234.365c13.399-2.149,30.878-3.346,49.304-3.346
|
15
|
+
c30.612,0,50.478,5.508,66.039,17.226C351.828,260.69,362.359,280.547,362.359,309.023z M80.7,393.499V234.365
|
16
|
+
c11.241-1.904,27.042-3.346,49.296-3.346c22.491,0,38.527,4.308,49.291,12.928c10.292,8.131,17.215,21.534,17.215,37.328
|
17
|
+
c0,15.799-5.25,29.198-14.829,38.285c-12.442,11.728-30.865,16.996-52.407,16.996c-4.778,0-9.1-0.243-12.435-0.723v57.67H80.7
|
18
|
+
V393.499z M453.601,523.353H97.2V419.302h356.4V523.353z M484.898,262.127h-61.989v36.851h57.913v29.674h-57.913v64.848h-36.593
|
19
|
+
V232.216h98.582V262.127z"/>
|
20
|
+
</g>
|
21
|
+
</svg>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
viewBox="0 0 394.4 394.4" xml:space="preserve"
|
3
|
+
>
|
4
|
+
<g>
|
5
|
+
<path d="M37.4,377.4c-5.223,0-10.438-1.992-14.423-5.977c-7.97-7.963-7.97-20.883,0-28.846l319.6-319.601
|
6
|
+
c7.97-7.97,20.876-7.97,28.846,0c7.97,7.962,7.97,20.882,0,28.845l-319.6,319.601C47.838,375.408,42.623,377.4,37.4,377.4z
|
7
|
+
M394.4,299.199c0-52.496-42.704-95.199-95.2-95.199S204,246.703,204,299.199s42.704,95.201,95.2,95.201
|
8
|
+
S394.4,351.695,394.4,299.199z M353.601,299.199c0,29.996-24.405,54.4-54.4,54.4s-54.4-24.404-54.4-54.4
|
9
|
+
c0-29.994,24.405-54.398,54.4-54.398S353.601,269.205,353.601,299.199z M190.4,95.2C190.4,42.704,147.696,0,95.2,0S0,42.704,0,95.2
|
10
|
+
s42.704,95.2,95.2,95.2S190.4,147.696,190.4,95.2z M149.6,95.2c0,29.995-24.405,54.4-54.4,54.4s-54.4-24.405-54.4-54.4
|
11
|
+
s24.405-54.4,54.4-54.4S149.6,65.206,149.6,95.2z"/>
|
12
|
+
</g>
|
13
|
+
</svg>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<svg
|
2
|
+
width="18"
|
3
|
+
height="20"
|
4
|
+
viewBox="0 0 16 18"
|
5
|
+
fill="none"
|
6
|
+
xmlns="http://www.w3.org/2000/svg"
|
7
|
+
>
|
8
|
+
<path
|
9
|
+
d="M13.8333 4.83333L13.1108 14.9517C13.0808 15.3722 12.8927 15.7657 12.5842 16.053C12.2757 16.3403 11.8698 16.5 11.4483 16.5H4.55159C4.13004 16.5 3.72414 16.3403 3.41566 16.053C3.10717 15.7657 2.91902 15.3722 2.88909 14.9517L2.16659 4.83333M6.33325 8.16667V13.1667M9.66659 8.16667V13.1667M10.4999 4.83333V2.33333C10.4999 2.11232 10.4121 1.90036 10.2558 1.74408C10.0996 1.5878 9.8876 1.5 9.66659 1.5H6.33325C6.11224 1.5 5.90028 1.5878 5.744 1.74408C5.58772 1.90036 5.49992 2.11232 5.49992 2.33333V4.83333M1.33325 4.83333H14.6666"
|
10
|
+
stroke="currentColor"
|
11
|
+
stroke-width="2"
|
12
|
+
stroke-linecap="round"
|
13
|
+
stroke-linejoin="round"
|
14
|
+
/>
|
15
|
+
</svg>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<svg
|
2
|
+
viewBox="0 0 17 17"
|
3
|
+
fill="none"
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
5
|
+
>
|
6
|
+
<path
|
7
|
+
fill-rule="evenodd"
|
8
|
+
clip-rule="evenodd"
|
9
|
+
d="M16.8222 0.177828C17.0593 0.414932 17.0593 0.799354 16.8222 1.03646L1.03646 16.8222C0.799354 17.0593 0.414932 17.0593 0.177828 16.8222C-0.059276 16.5851 -0.059276 16.2006 0.177828 15.9635L15.9635 0.177828C16.2006 -0.059276 16.5851 -0.059276 16.8222 0.177828Z"
|
10
|
+
fill="currentColor"
|
11
|
+
/>
|
12
|
+
<path
|
13
|
+
fill-rule="evenodd"
|
14
|
+
clip-rule="evenodd"
|
15
|
+
d="M0.177828 0.177828C0.414932 -0.059276 0.799354 -0.059276 1.03646 0.177828L16.8222 15.9635C17.0593 16.2006 17.0593 16.5851 16.8222 16.8222C16.5851 17.0593 16.2006 17.0593 15.9635 16.8222L0.177828 1.03646C-0.059276 0.799354 -0.059276 0.414932 0.177828 0.177828Z"
|
16
|
+
fill="currentColor"
|
17
|
+
/>
|
18
|
+
</svg>
|
package/src/svg/index.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export { default as DragHandleDotsIcon } from "./DragHandleDotsIcon.svg";
|
2
|
+
export { default as DragHandleIcon } from "./DragHandleIcon.svg";
|
3
|
+
export { default as FilterIcon } from "./FilterIcon.svg";
|
4
|
+
export { default as ImageIcon } from "./ImageIcon.svg";
|
5
|
+
export { default as PdfIcon } from "./PdfIcon.svg";
|
6
|
+
export { default as PercentIcon } from "./PercentIcon.svg";
|
7
|
+
export { default as TrashIcon } from "./TrashIcon.svg";
|
8
|
+
export { default as XIcon } from "./XIcon.svg";
|
@@ -0,0 +1 @@
|
|
1
|
+
export const apiKey = "YOUR_API_KEY";
|