sprintify-ui 0.0.6 → 0.0.8

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.
Files changed (45) hide show
  1. package/README.md +13 -0
  2. package/dist/sprintify-ui.es.js +9166 -8089
  3. package/dist/types/src/components/BaseApp.vue.d.ts +48 -0
  4. package/dist/types/src/components/BaseAppDialogs.vue.d.ts +80 -0
  5. package/dist/types/src/components/BaseAppNotifications.vue.d.ts +44 -0
  6. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +7 -7
  7. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +7 -7
  8. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +4 -4
  9. package/dist/types/src/components/BaseDataIterator.vue.d.ts +4 -4
  10. package/dist/types/src/components/BaseDataTable.vue.d.ts +4 -4
  11. package/dist/types/src/components/BaseFileUploader.vue.d.ts +20 -1
  12. package/dist/types/src/components/BaseInput.vue.d.ts +4 -4
  13. package/dist/types/src/components/BaseLoadingCover.vue.d.ts +4 -4
  14. package/dist/types/src/components/BasePassword.vue.d.ts +1 -1
  15. package/dist/types/src/components/BaseSelect.vue.d.ts +1 -1
  16. package/dist/types/src/components/BaseTextarea.vue.d.ts +4 -4
  17. package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +1 -1
  18. package/dist/types/src/components/index.d.ts +9 -1
  19. package/dist/types/src/index.d.ts +42 -32
  20. package/dist/types/src/stores/dialogs.d.ts +9 -0
  21. package/dist/types/src/stores/notifications.d.ts +10 -0
  22. package/dist/types/src/stores/systemAlerts.d.ts +9 -0
  23. package/dist/types/src/types/types.d.ts +58 -0
  24. package/package.json +1 -1
  25. package/src/components/BaseApp.vue +16 -0
  26. package/src/components/BaseAppDialogs.vue +113 -0
  27. package/src/components/BaseAppNotifications.vue +73 -0
  28. package/src/components/BaseDataTable.vue +8 -8
  29. package/src/components/BaseDatePicker.vue +1 -1
  30. package/src/components/BaseDateSelect.vue +1 -1
  31. package/src/components/BaseDialog.vue +1 -0
  32. package/src/components/BaseFileUploader.vue +16 -7
  33. package/src/components/BaseInputLabel.vue +3 -3
  34. package/src/components/BaseMediaLibrary.vue +10 -10
  35. package/src/components/BaseTagAutocomplete.vue +4 -4
  36. package/src/components/index.ts +16 -1
  37. package/src/index.ts +23 -14
  38. package/src/lang/en.json +9 -8
  39. package/src/lang/fr.json +9 -8
  40. package/src/stores/dialogs.ts +45 -0
  41. package/src/stores/notifications.ts +47 -0
  42. package/src/stores/systemAlerts.ts +33 -0
  43. package/src/types/types.ts +67 -0
  44. package/dist/types/src/components/BaseLoadingPage.vue.d.ts +0 -2
  45. package/src/components/BaseLoadingPage.vue +0 -19
@@ -36,13 +36,17 @@ import { config } from '@/index';
36
36
  import { PropType } from 'vue';
37
37
  import { UploadedFile } from '@/types/UploadedFile';
38
38
  import { toHumanList, fileSizeFormat } from '../utils';
39
- //import { useNotificationsStore } from '../stores/notifications';
39
+ import { useNotificationsStore } from '../stores/notifications';
40
40
 
41
41
  const http = config.http;
42
42
  const i18n = useI18n();
43
- //const notifications = useNotificationsStore();
43
+ const notifications = useNotificationsStore();
44
44
 
45
45
  const props = defineProps({
46
+ url: {
47
+ default: undefined,
48
+ type: String,
49
+ },
46
50
  disabled: {
47
51
  default: false,
48
52
  type: Boolean,
@@ -91,13 +95,13 @@ async function onPictureUpload(file: File) {
91
95
 
92
96
  try {
93
97
  if (file.size > props.maxSize) {
94
- /* notifications.push({
98
+ notifications.push({
95
99
  color: 'danger',
96
100
  title: i18n.t('sui.error'),
97
101
  text: i18n.t('sui.the_file_size_must_not_exceed_x', {
98
102
  x: fileSizeFormat(props.maxSize),
99
103
  }),
100
- }); */
104
+ });
101
105
  return;
102
106
  }
103
107
 
@@ -109,7 +113,7 @@ async function onPictureUpload(file: File) {
109
113
  props.acceptedExtensions.length
110
114
  ) {
111
115
  if (!props.acceptedExtensions.includes(extension)) {
112
- /* notifications.push({
116
+ notifications.push({
113
117
  color: 'danger',
114
118
  title: i18n.t('sui.error'),
115
119
  text:
@@ -119,7 +123,7 @@ async function onPictureUpload(file: File) {
119
123
  ' ' +
120
124
  toHumanList(props.acceptedExtensions, i18n.t('sui.or')) +
121
125
  '.',
122
- }); */
126
+ });
123
127
  return;
124
128
  }
125
129
  }
@@ -131,7 +135,7 @@ async function onPictureUpload(file: File) {
131
135
  uploading.value = true;
132
136
  emit('upload:start');
133
137
 
134
- const response = await http.post(config.upload_url, formData);
138
+ const response = await http.post(props.url ?? config.upload_url, formData);
135
139
 
136
140
  const payload = response.data as UploadedFile;
137
141
  payload.original_file = file;
@@ -154,6 +158,11 @@ async function onPictureUpload(file: File) {
154
158
  }
155
159
  } catch (e: unknown) {
156
160
  emit('upload:fail');
161
+ notifications.push({
162
+ color: 'danger',
163
+ title: i18n.t('sui.error'),
164
+ text: i18n.t('sui.upload_failed'),
165
+ });
157
166
  } finally {
158
167
  emit('upload:end');
159
168
  uploading.value = false;
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <label :class="classes"
3
- >{{ label }}<span v-if="required" class="text-red-600"> *</span></label
4
- >
2
+ <label :class="classes">
3
+ {{ label }}<span v-if="required" class="text-red-600"> *</span>
4
+ </label>
5
5
  </template>
6
6
 
7
7
  <script lang="ts">
@@ -91,15 +91,15 @@ import { Media } from '@/types/Media';
91
91
  import _, { cloneDeep, get } from 'lodash';
92
92
  import { PropType } from 'vue';
93
93
  import { MediaLibraryPayload } from '@/types/types';
94
- //import { useDialogsStore } from '../stores/dialogs';
95
- //import { useNotificationsStore } from '../stores/notifications';
94
+ import { useDialogsStore } from '../stores/dialogs';
95
+ import { useNotificationsStore } from '../stores/notifications';
96
96
  import { capitalize } from 'lodash';
97
97
  import { fileSizeFormat } from 'src/utils';
98
98
 
99
99
  const i18n = useI18n();
100
100
 
101
- //const dialogs = useDialogsStore();
102
- //const notifications = useNotificationsStore();
101
+ const dialogs = useDialogsStore();
102
+ const notifications = useNotificationsStore();
103
103
 
104
104
  const emit = defineEmits([
105
105
  'update',
@@ -188,11 +188,11 @@ function onUploadSuccess(file: UploadedFile) {
188
188
  }
189
189
 
190
190
  if (numberOfFiles.value >= props.max && props.max > 1) {
191
- /* notifications.push({
191
+ notifications.push({
192
192
  title: i18n.t('sui.whoops'),
193
193
  text: i18n.t('sui.you_can_upload_up_to_n_files', { count: props.max }),
194
194
  color: 'danger',
195
- }); */
195
+ });
196
196
  return;
197
197
  }
198
198
 
@@ -213,25 +213,25 @@ function onUploadSuccess(file: UploadedFile) {
213
213
  }
214
214
 
215
215
  function promptRemoveUploadedFile(index: number, length = 1) {
216
- /* dialogs.push({
216
+ dialogs.push({
217
217
  title: i18n.t('sui.remove_file'),
218
218
  message: i18n.t('sui.remove_file_description'),
219
219
  color: 'warning',
220
220
  onConfirm() {
221
221
  removeUploadedFile(index, length);
222
222
  },
223
- }); */
223
+ });
224
224
  }
225
225
 
226
226
  function promptRemoveMedia(index: number) {
227
- /* dialogs.push({
227
+ dialogs.push({
228
228
  title: i18n.t('sui.remove_file'),
229
229
  message: i18n.t('sui.remove_file_description'),
230
230
  color: 'warning',
231
231
  onConfirm() {
232
232
  removeMedia(index);
233
233
  },
234
- }); */
234
+ });
235
235
  }
236
236
 
237
237
  function removeUploadedFile(index: number, length = 1) {
@@ -83,7 +83,7 @@ import { PropType, Ref, ComputedRef } from 'vue';
83
83
  import { NormalizedOption, Option, OptionValue } from '@/types/types';
84
84
  import { useInfiniteScroll } from '@vueuse/core';
85
85
  import BaseLoadingCover from './BaseLoadingCover.vue';
86
- //import { useNotificationsStore } from '../../stores/notifications';
86
+ import { useNotificationsStore } from '@/stores/notifications';
87
87
 
88
88
  const props = defineProps({
89
89
  modelValue: {
@@ -140,7 +140,7 @@ const emit = defineEmits([
140
140
  ]);
141
141
 
142
142
  const i18n = useI18n();
143
- //const notifications = useNotificationsStore();
143
+ const notifications = useNotificationsStore();
144
144
 
145
145
  const timerId = ref(0);
146
146
  const keywords = ref('');
@@ -308,11 +308,11 @@ const toggleOption = (option: NormalizedOption) => {
308
308
 
309
309
  const addOption = (option: NormalizedOption) => {
310
310
  if (props.max && normalizedModelValue.value.length >= props.max) {
311
- /* notifications.push({
311
+ notifications.push({
312
312
  title: i18n.t('sui.whoops'),
313
313
  text: i18n.t('sui.you_cannot_select_more_than_x_items', { x: props.max }),
314
314
  color: 'warning',
315
- }); */
315
+ });
316
316
  return;
317
317
  }
318
318
 
@@ -1,4 +1,7 @@
1
1
  import BaseAlert from './BaseAlert.vue';
2
+ import BaseApp from './BaseApp.vue';
3
+ import BaseAppDialogs from './BaseAppDialogs.vue';
4
+ import BaseAppNotifications from './BaseAppNotifications.vue';
2
5
  import BaseAutocomplete from './BaseAutocomplete.vue';
3
6
  import BaseAutocompleteFetch from './BaseAutocompleteFetch.vue';
4
7
  import BaseAvatar from './BaseAvatar.vue';
@@ -16,7 +19,11 @@ import BaseDataIterator from './BaseDataIterator.vue';
16
19
  import BaseDataTable from './BaseDataTable.vue';
17
20
  import BaseDatePicker from './BaseDatePicker.vue';
18
21
  import BaseDateSelect from './BaseDateSelect.vue';
19
-
22
+ import BaseDescriptionList from './BaseDescriptionList.vue';
23
+ import BaseDescriptionListItem from './BaseDescriptionListItem.vue';
24
+ import BaseDialog from './BaseDialog.vue';
25
+ import BaseFilePicker from './BaseFilePicker.vue';
26
+ import BaseFileUploader from './BaseFileUploader.vue';
20
27
  import { Icon as BaseIcon } from '@iconify/vue';
21
28
  import BaseLoadingCover from './BaseLoadingCover.vue';
22
29
  import BaseMenu from './BaseMenu.vue';
@@ -26,6 +33,9 @@ import BaseTableColumn from './BaseTableColumn.vue';
26
33
 
27
34
  export {
28
35
  BaseAlert,
36
+ BaseApp,
37
+ BaseAppDialogs,
38
+ BaseAppNotifications,
29
39
  BaseAutocomplete,
30
40
  BaseAutocompleteFetch,
31
41
  BaseAvatar,
@@ -43,6 +53,11 @@ export {
43
53
  BaseDataTable,
44
54
  BaseDatePicker,
45
55
  BaseDateSelect,
56
+ BaseDescriptionList,
57
+ BaseDescriptionListItem,
58
+ BaseDialog,
59
+ BaseFilePicker,
60
+ BaseFileUploader,
46
61
  BaseIcon,
47
62
  BaseLoadingCover,
48
63
  BaseMenu,
package/src/index.ts CHANGED
@@ -5,12 +5,15 @@ import QueryString from 'qs';
5
5
  import { createI18n, I18n } from 'vue-i18n';
6
6
  import en from '@/lang/en.json';
7
7
  import fr from '@/lang/fr.json';
8
+ import { useDialogsStore } from './stores/dialogs';
9
+ import { useNotificationsStore } from './stores/notifications';
10
+ import { useSystemAlertStore } from './stores/systemAlerts';
8
11
 
9
12
  const messages = { en, fr };
10
13
 
11
14
  import './assets/main.css';
12
15
 
13
- interface SprintifyUIConfig {
16
+ export interface Options {
14
17
  // eslint-disable-next-line @typescript-eslint/ban-types
15
18
  i18n?: I18n<typeof messages, {}, {}, string, true>;
16
19
  http?: AxiosInstance;
@@ -19,8 +22,10 @@ interface SprintifyUIConfig {
19
22
  parseQueryString?: (params: string) => Record<string, any>;
20
23
  }
21
24
 
22
- const pluginConfig = {
25
+ const config = {
23
26
  i18n: createI18n({
27
+ locale: 'en',
28
+ fallbackLocale: 'en',
24
29
  messages: { en, fr },
25
30
  }),
26
31
  http: axios.create(),
@@ -36,30 +41,30 @@ const pluginConfig = {
36
41
  },
37
42
  };
38
43
 
39
- function install(app: App, config?: SprintifyUIConfig) {
44
+ function install(app: App, options?: Options) {
40
45
  for (const key in components) {
41
46
  // @ts-expect-error Will throw
42
47
  app.component(key, components[key]);
43
48
  }
44
49
 
45
- if (config?.i18n) {
46
- pluginConfig.i18n = config.i18n;
50
+ if (options?.i18n) {
51
+ config.i18n = options.i18n;
47
52
  }
48
53
 
49
- if (config?.http) {
50
- pluginConfig.http = config.http;
54
+ if (options?.http) {
55
+ config.http = options.http;
51
56
  }
52
57
 
53
- if (config?.upload_url) {
54
- pluginConfig.upload_url = config.upload_url;
58
+ if (options?.upload_url) {
59
+ config.upload_url = options.upload_url;
55
60
  }
56
61
 
57
- if (config?.formatQueryString) {
58
- pluginConfig.formatQueryString = config.formatQueryString;
62
+ if (options?.formatQueryString) {
63
+ config.formatQueryString = options.formatQueryString;
59
64
  }
60
65
 
61
- if (config?.parseQueryString) {
62
- pluginConfig.parseQueryString = config.parseQueryString;
66
+ if (options?.parseQueryString) {
67
+ config.parseQueryString = options.parseQueryString;
63
68
  }
64
69
  }
65
70
 
@@ -71,4 +76,8 @@ export * from './utils';
71
76
 
72
77
  export { messages };
73
78
 
74
- export { pluginConfig as config };
79
+ export { config };
80
+
81
+ export { useDialogsStore };
82
+ export { useNotificationsStore };
83
+ export { useSystemAlertStore };
package/src/lang/en.json CHANGED
@@ -38,19 +38,20 @@
38
38
  "the_file_size_must_not_exceed_x": "The file size must not exceed {x}",
39
39
  "the_file_type_is_invalid": "The file type is invalid",
40
40
  "type_to_start_your_search": "Type to start your search",
41
- "up_to_x": "Up to {x}",
42
- "whoops": "Whoops",
43
- "x_rows_selected": "1 item selected | {count} items selected",
44
- "year": "Year",
45
- "yes_delete": "Yes, delete",
46
- "you_can_upload_up_to_n_files": "You can upload one file at most|You can upload up to {count} files",
47
- "you_cannot_select_more_than_x_items": "You can't select more than one item|You can't select more than {x} items",
48
41
  "units": {
49
42
  "b": "B",
50
43
  "gb": "GB",
51
44
  "kb": "kB",
52
45
  "mb": "MB",
53
46
  "tb": "TB"
54
- }
47
+ },
48
+ "up_to_x": "Up to {x}",
49
+ "upload_failed": "Upload failed",
50
+ "whoops": "Whoops",
51
+ "x_rows_selected": "1 item selected | {count} items selected",
52
+ "year": "Year",
53
+ "yes_delete": "Yes, delete",
54
+ "you_can_upload_up_to_n_files": "You can upload one file at most|You can upload up to {count} files",
55
+ "you_cannot_select_more_than_x_items": "You can't select more than one item|You can't select more than {x} items"
55
56
  }
56
57
  }
package/src/lang/fr.json CHANGED
@@ -38,19 +38,20 @@
38
38
  "the_file_size_must_not_exceed_x": "La taille du fichier ne doit pas dépasser {x}",
39
39
  "the_file_type_is_invalid": "Le type de fichier n'est pas valide",
40
40
  "type_to_start_your_search": "Tapez pour lancer votre recherche",
41
- "up_to_x": "Jusqu'à {x}",
42
- "whoops": "Oups",
43
- "x_rows_selected": "1 item sélectionné | \n{count} items sélectionnés",
44
- "year": "An",
45
- "yes_delete": "Oui, supprimer",
46
- "you_can_upload_up_to_n_files": "Vous pouvez télécharger un fichier au maximum|Vous pouvez télécharger jusqu'à {count} fichiers",
47
- "you_cannot_select_more_than_x_items": "Vous ne pouvez pas sélectionner plus de un élément|Vous ne pouvez pas sélectionner plus de {x} éléments",
48
41
  "units": {
49
42
  "b": "o",
50
43
  "gb": "Go",
51
44
  "kb": "Ko",
52
45
  "mb": "Mo",
53
46
  "tb": "To"
54
- }
47
+ },
48
+ "up_to_x": "Jusqu'à {x}",
49
+ "upload_failed": "Le téléchargement a échoué",
50
+ "whoops": "Oups",
51
+ "x_rows_selected": "1 item sélectionné | \n{count} items sélectionnés",
52
+ "year": "An",
53
+ "yes_delete": "Oui, supprimer",
54
+ "you_can_upload_up_to_n_files": "Vous pouvez télécharger un fichier au maximum|Vous pouvez télécharger jusqu'à {count} fichiers",
55
+ "you_cannot_select_more_than_x_items": "Vous ne pouvez pas sélectionner plus de un élément|Vous ne pouvez pas sélectionner plus de {x} éléments"
55
56
  }
56
57
  }
@@ -0,0 +1,45 @@
1
+ import { defineStore } from 'pinia';
2
+ import { config } from '@/index';
3
+ import { Dialog, DialogOptions } from '../types/types';
4
+
5
+ export const useDialogsStore = defineStore('dialogs', {
6
+ state: () => {
7
+ return {
8
+ count: 0,
9
+ dialogs: [] as Dialog[],
10
+ };
11
+ },
12
+ actions: {
13
+ push(options: DialogOptions) {
14
+ this.count++;
15
+ this.dialogs.push({
16
+ id: this.count,
17
+ color: options.color ?? 'info',
18
+ title: options.title,
19
+ message: options.message,
20
+ confirmText: options.confirmText ?? config.i18n.global.t('sui.confirm'),
21
+ cancelText: options.cancelText ?? config.i18n.global.t('sui.cancel'),
22
+ closeOnOutsideClick: options.closeOnOutsideClick ?? true,
23
+ onConfirm:
24
+ options.onConfirm ??
25
+ function () {
26
+ return;
27
+ },
28
+ onCancel:
29
+ options.onCancel ??
30
+ function () {
31
+ return;
32
+ },
33
+ });
34
+ },
35
+ remove(dialog: Dialog) {
36
+ this.dialogs.splice(
37
+ this.dialogs.findIndex((a) => a.id === dialog.id),
38
+ 1
39
+ );
40
+ },
41
+ clear() {
42
+ this.dialogs = [];
43
+ },
44
+ },
45
+ });
@@ -0,0 +1,47 @@
1
+ import { defineStore } from 'pinia';
2
+ import { Notification, NotificationOptions } from '../types/types';
3
+
4
+ export const useNotificationsStore = defineStore('notifications', {
5
+ state: () => {
6
+ return {
7
+ count: 0,
8
+ notifications: [] as Notification[],
9
+ timeouts: {} as Record<number, number>,
10
+ };
11
+ },
12
+ actions: {
13
+ push(options: NotificationOptions) {
14
+ this.count++;
15
+
16
+ const id = this.count;
17
+
18
+ const notification = {
19
+ id: id,
20
+ color: options.color ?? 'info',
21
+ title: options.title,
22
+ text: options.text,
23
+ duration: options.duration ?? 3000,
24
+ };
25
+
26
+ this.notifications.push(notification);
27
+
28
+ this.timeouts[id] = setTimeout(() => {
29
+ this.remove(notification);
30
+ }, notification.duration);
31
+ },
32
+ remove(notification: Notification) {
33
+ this.notifications.splice(
34
+ this.notifications.findIndex((n) => n.id === notification.id),
35
+ 1
36
+ );
37
+ clearTimeout(this.timeouts[notification.id]);
38
+ },
39
+ clear() {
40
+ this.notifications = [];
41
+ Object.values(this.timeouts).forEach((timeout) => {
42
+ clearTimeout(timeout);
43
+ });
44
+ this.timeouts = [];
45
+ },
46
+ },
47
+ });
@@ -0,0 +1,33 @@
1
+ import { defineStore } from 'pinia';
2
+ import { SystemAlert, SystemAlertOptions } from '../types/types';
3
+
4
+ export const useSystemAlertStore = defineStore('systemAlerts', {
5
+ state: () => {
6
+ return {
7
+ count: 0,
8
+ systemAlerts: [] as SystemAlert[],
9
+ };
10
+ },
11
+ actions: {
12
+ push(systemAlert: SystemAlertOptions) {
13
+ this.count++;
14
+ this.systemAlerts.push({
15
+ id: this.count,
16
+ color: systemAlert.color ?? 'info',
17
+ message: systemAlert.message,
18
+ to: systemAlert.to,
19
+ action: systemAlert.action,
20
+ closable: systemAlert.closable ?? false,
21
+ });
22
+ },
23
+ remove(systemAlert: SystemAlert) {
24
+ this.systemAlerts.splice(
25
+ this.systemAlerts.findIndex((a) => a.id === systemAlert.id),
26
+ 1
27
+ );
28
+ },
29
+ clear() {
30
+ this.systemAlerts = [];
31
+ },
32
+ },
33
+ });
@@ -110,3 +110,70 @@ export interface BaseTableColumn {
110
110
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
111
  tdAttrs: (row: Row, column: BaseTableColumn) => Record<string, any>;
112
112
  }
113
+
114
+ /**
115
+ * System alert
116
+ */
117
+
118
+ export interface SystemAlertOptions {
119
+ color?: 'info' | 'success' | 'danger' | 'warning';
120
+ message: string;
121
+ to?: RouteLocationRaw;
122
+ action?: () => void;
123
+ closable?: boolean;
124
+ }
125
+
126
+ export interface SystemAlert {
127
+ id: number;
128
+ color: 'info' | 'success' | 'danger' | 'warning';
129
+ message: string;
130
+ to?: RouteLocationRaw;
131
+ action?: () => void;
132
+ closable: boolean;
133
+ }
134
+
135
+ /**
136
+ * Dialog
137
+ */
138
+
139
+ export interface DialogOptions {
140
+ color?: 'info' | 'success' | 'danger' | 'warning';
141
+ title: string;
142
+ message: string;
143
+ confirmText?: string;
144
+ cancelText?: string;
145
+ closeOnOutsideClick?: boolean;
146
+ onConfirm?: () => void;
147
+ onCancel?: () => void;
148
+ }
149
+
150
+ export interface Dialog {
151
+ id: number;
152
+ color: 'info' | 'success' | 'danger' | 'warning';
153
+ title: string;
154
+ message: string;
155
+ confirmText: string;
156
+ cancelText: string;
157
+ closeOnOutsideClick: boolean;
158
+ onConfirm: () => void;
159
+ onCancel: () => void;
160
+ }
161
+
162
+ /**
163
+ * Notification
164
+ */
165
+
166
+ export interface NotificationOptions {
167
+ title: string;
168
+ text: string;
169
+ color?: 'info' | 'success' | 'danger' | 'warning';
170
+ duration?: number;
171
+ }
172
+
173
+ export interface Notification {
174
+ id: number;
175
+ title: string;
176
+ text: string;
177
+ color: 'info' | 'success' | 'danger' | 'warning';
178
+ duration: number;
179
+ }
@@ -1,2 +0,0 @@
1
- declare const _default: any;
2
- export default _default;
@@ -1,19 +0,0 @@
1
- <template>
2
- <div
3
- class="fixed inset-0 z-loading flex h-full w-full items-center justify-center bg-white"
4
- >
5
- <div class="flex flex-col items-center">
6
- <img
7
- :src="'/img/logo/icon-color.svg'"
8
- alt="Loading"
9
- class="mb-14 w-16 animate-pulse"
10
- />
11
- <svg class="h-6 w-6 animate-spin text-primary-500" viewBox="0 0 24 24">
12
- <path
13
- fill="currentColor"
14
- d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z"
15
- />
16
- </svg>
17
- </div>
18
- </div>
19
- </template>