@bagelink/vue 1.2.126 → 1.2.132

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 (57) hide show
  1. package/dist/components/AddressSearch.vue.d.ts.map +1 -1
  2. package/dist/components/Carousel2.vue.d.ts +89 -0
  3. package/dist/components/Carousel2.vue.d.ts.map +1 -0
  4. package/dist/components/DragOver.vue.d.ts +1 -0
  5. package/dist/components/DragOver.vue.d.ts.map +1 -1
  6. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  7. package/dist/components/ImportData.vue.d.ts.map +1 -1
  8. package/dist/components/Loading.vue.d.ts +1 -0
  9. package/dist/components/Loading.vue.d.ts.map +1 -1
  10. package/dist/components/Modal.vue.d.ts +10 -5
  11. package/dist/components/Modal.vue.d.ts.map +1 -1
  12. package/dist/components/Pill.vue.d.ts +2 -0
  13. package/dist/components/Pill.vue.d.ts.map +1 -1
  14. package/dist/components/calendar/views/CalendarPopover.vue.d.ts +2 -2
  15. package/dist/components/calendar/views/CalendarPopover.vue.d.ts.map +1 -1
  16. package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
  17. package/dist/components/dataTable/useTableData.d.ts +10 -10
  18. package/dist/components/dataTable/useTableData.d.ts.map +1 -1
  19. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  20. package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts +5 -1
  21. package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
  22. package/dist/components/form/inputs/Upload/upload.types.d.ts +2 -0
  23. package/dist/components/form/inputs/Upload/upload.types.d.ts.map +1 -1
  24. package/dist/components/form/inputs/Upload/useFileUpload.d.ts +8 -1
  25. package/dist/components/form/inputs/Upload/useFileUpload.d.ts.map +1 -1
  26. package/dist/components/form/inputs/index.d.ts +0 -1
  27. package/dist/components/form/inputs/index.d.ts.map +1 -1
  28. package/dist/index.cjs +599 -1008
  29. package/dist/index.mjs +599 -1008
  30. package/dist/style.css +1747 -1932
  31. package/dist/types/BagelForm.d.ts.map +1 -1
  32. package/dist/types/TableSchema.d.ts +1 -1
  33. package/dist/types/TableSchema.d.ts.map +1 -1
  34. package/dist/utils/BagelFormUtils.d.ts +2 -2
  35. package/dist/utils/BagelFormUtils.d.ts.map +1 -1
  36. package/package.json +1 -1
  37. package/src/components/DragOver.vue +21 -2
  38. package/src/components/ImportData.vue +34 -33
  39. package/src/components/Loading.vue +58 -50
  40. package/src/components/Modal.vue +10 -4
  41. package/src/components/Pill.vue +28 -5
  42. package/src/components/dataTable/DataTable.vue +5 -11
  43. package/src/components/dataTable/useTableData.ts +11 -10
  44. package/src/components/form/inputs/SelectInput.vue +1 -1
  45. package/src/components/form/inputs/Upload/UploadInput.vue +35 -47
  46. package/src/components/form/inputs/Upload/upload.css +12 -9
  47. package/src/components/form/inputs/Upload/upload.types.ts +2 -0
  48. package/src/components/form/inputs/Upload/useFileUpload.ts +35 -9
  49. package/src/components/form/inputs/index.ts +0 -1
  50. package/src/styles/layout.css +1466 -1460
  51. package/src/styles/theme.css +2 -1
  52. package/src/types/BagelForm.ts +2 -0
  53. package/src/types/TableSchema.ts +1 -1
  54. package/src/utils/BagelFormUtils.ts +2 -2
  55. package/dist/types/timeago.d.ts +0 -23
  56. package/dist/types/timeago.d.ts.map +0 -1
  57. package/src/components/form/inputs/FileUpload.vue +0 -724
@@ -25,6 +25,8 @@ const props = defineProps<{
25
25
  round?: boolean
26
26
  btn?: BtnProp
27
27
  btnEnd?: BtnProp
28
+ large?: boolean
29
+ small?: boolean
28
30
  }>()
29
31
 
30
32
  const slots: SetupContext['slots'] = useSlots()
@@ -77,11 +79,14 @@ const computedBackgroundColor = $computed(
77
79
 
78
80
  <template>
79
81
  <div
82
+ style="height: var(--pill-height);"
80
83
  :disabled="disabled" :class="{
81
84
  'bgl_pill': !icon || slots.default || value,
82
85
  round,
83
86
  'bgl_flatPill': flat,
84
87
  'bgl_pill-border': border || outline,
88
+ 'pillLarge': large,
89
+ 'pillSmall': small,
85
90
  }"
86
91
  >
87
92
  <div class="bgl_pill-flex">
@@ -91,12 +96,18 @@ const computedBackgroundColor = $computed(
91
96
  <Btn class="bgl_pill-btn" round thin v-bind="btn" />
92
97
  </div>
93
98
  </div>
94
- <Icon v-if="icon" :icon="icon" />
99
+ <Icon v-if="icon" :icon="icon" style="font-size: var(--pill-font-size)" />
95
100
  <slot />
96
101
  <template v-if="!slots.default">
97
- {{ value || modelValue }}
102
+ <p
103
+ class="pillText"
104
+ >
105
+ {{ value || modelValue }}
106
+ {{ slots.default ? slots.default : value || modelValue }}
107
+ {{ value || modelValue }}
108
+ </p>
98
109
  </template>
99
- <Icon v-if="iconEnd" :icon="iconEnd" />
110
+ <Icon v-if="iconEnd" :icon="iconEnd" style="font-size: var(--pill-font-size)" />
100
111
  <div v-if="loading" class="loading" />
101
112
  <div v-else>
102
113
  <div v-if="btnEnd" class="flex h-100">
@@ -108,6 +119,17 @@ const computedBackgroundColor = $computed(
108
119
  </template>
109
120
 
110
121
  <style scoped>
122
+ .pillLarge{
123
+ --pill-font-size: var(--bgl-font-size);
124
+ --pill-height:auto;
125
+ }
126
+ .pillSmall{
127
+ --pill-font-size: 9px;
128
+ --pill-height:15px;
129
+ }
130
+ .pillText{
131
+ font-size: var(--pill-font-size);
132
+ }
111
133
  .bgl_pill-btn{
112
134
  color: var(--pill-btn-color);
113
135
  background: var(--pill-btn-bg);
@@ -137,14 +159,15 @@ const computedBackgroundColor = $computed(
137
159
  }
138
160
 
139
161
  .bgl_pill {
140
- padding-inline: 0.25rem;
162
+ padding-inline: calc(var(--pill-font-size) / 6);
163
+ padding-block: calc(var(--pill-font-size) / 24);
141
164
  transition: var(--bgl-transition);
142
165
  background-color: v-bind(computedBackgroundColor);
143
166
  color: v-bind(cumputedTextColor);
144
167
  display: inline-block;
145
168
  margin-inline-end: 0.25rem;
146
169
  border-radius: var(--pill-border-radius);
147
- height: var(--pill-height);
170
+ min-height: var(--pill-height);
148
171
  vertical-align: middle;
149
172
  margin-bottom: 0.25rem;
150
173
  }
@@ -7,7 +7,7 @@ import {
7
7
  keyToLabel,
8
8
  getNestedValue
9
9
  } from '@bagelink/vue'
10
- import { useSlots, watch, computed } from 'vue'
10
+ import { useSlots, watch, computed, toValue } from 'vue'
11
11
  import { useSchemaField } from '../../composables/useSchemaField'
12
12
  import { useTableData } from './useTableData'
13
13
  import { useTableSelection } from './useTableSelection'
@@ -30,12 +30,6 @@ const loading = defineModel('loading', { default: false })
30
30
  const itemHeight = defineModel('itemHeight', { default: 50 })
31
31
  const selectedItems = defineModel<string[]>('selectedItems', { default: [] as string[] })
32
32
 
33
- // Create computed properties to wrap the props
34
- const data = computed(() => props.data)
35
- const schema = computed(() => props.schema as any)
36
- const columns = computed(() => props.columns as any)
37
- const useServerSort = computed(() => props.useServerSort as any)
38
-
39
33
  const {
40
34
  computedSchema,
41
35
  computedData,
@@ -44,10 +38,10 @@ const {
44
38
  toggleSort,
45
39
  cleanTransformedData
46
40
  } = useTableData<T>({
47
- data,
48
- schema,
49
- columns,
50
- useServerSort,
41
+ data: computed(() => props.data),
42
+ schema: computed(() => toValue(props.schema)),
43
+ columns: computed(() => toValue(props.columns)),
44
+ useServerSort: computed(() => toValue(props.useServerSort)),
51
45
  onSort: (field, direction) => {
52
46
  emit('orderBy', `${field.trim()} ${direction.trim()}` as EmitOrderT)
53
47
  }
@@ -1,5 +1,5 @@
1
1
  import type { BglFormSchemaT } from '@bagelink/vue'
2
- import type { ComputedRef, MaybeRefOrGetter } from 'vue'
2
+ import type { MaybeRefOrGetter } from 'vue'
3
3
  import type { SortDirectionsT } from '../../types/TableSchema'
4
4
  import { useBglSchema, isDate, keyToLabel } from '@bagelink/vue'
5
5
  import { computed, ref, watch, toValue } from 'vue'
@@ -14,10 +14,10 @@ const SRC_VALUE_COMPONENTS = new Set(['img', 'iframe'])
14
14
 
15
15
  // Extend the base options interface to include computed refs
16
16
  export interface UseTableDataOptions<T> {
17
- data: ComputedRef<T[]>
18
- schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
19
- columns?: MaybeRefOrGetter<string[]>
20
- useServerSort?: MaybeRefOrGetter<boolean>
17
+ data: MaybeRefOrGetter<T[]>
18
+ schema?: MaybeRefOrGetter<BglFormSchemaT<T> | undefined>
19
+ columns?: MaybeRefOrGetter<string[] | undefined>
20
+ useServerSort?: MaybeRefOrGetter<boolean | undefined>
21
21
  onSort?: (field: string, direction: SortDirectionsT) => void
22
22
  }
23
23
 
@@ -44,7 +44,7 @@ export function useTableData<T extends { [key: string]: any }>(options: UseTable
44
44
  schemaState.value = 'loading'
45
45
 
46
46
  // Get the data safely
47
- const dataValue = options.data.value || []
47
+ const dataValue = toValue(options.data) || []
48
48
 
49
49
  // Get the schema from useBglSchema
50
50
  const schema = useBglSchema<T>({
@@ -100,6 +100,9 @@ export function useTableData<T extends { [key: string]: any }>(options: UseTable
100
100
  const computedSchema = computed(() => resolvedSchema.value)
101
101
 
102
102
  function transform(rowData: T): TransformedData<T> {
103
+ // TODO: only use type casting in the return statement
104
+ // TODO: replace assignments with Object.assign(transformed, {[key]: value})
105
+
103
106
  const transformed = { ...rowData } as TransformedData<T>
104
107
  const schemaFields = computedSchema.value.filter((f: any) => f.id)
105
108
 
@@ -150,16 +153,14 @@ export function useTableData<T extends { [key: string]: any }>(options: UseTable
150
153
 
151
154
  const computedData = computed(() => {
152
155
  // Get the data safely
153
- const currentData = options.data.value || []
156
+ const currentData = toValue(options.data) || []
154
157
 
155
158
  // If there's no data, return an empty array
156
159
  if (!Array.isArray(currentData) || currentData.length === 0) {
157
160
  return []
158
161
  }
159
162
 
160
- const useServerSortValue = $computed(() => toValue(options.useServerSort))
161
-
162
- if (!sortField.value || useServerSortValue === true) {
163
+ if (!sortField.value || toValue(options.useServerSort) === true) {
163
164
  return currentData.map(transform)
164
165
  }
165
166
 
@@ -205,7 +205,7 @@ onMounted(() => {
205
205
  >
206
206
  <template #trigger>
207
207
  <label>
208
- {{ label }} <span v-if="required">*</span>
208
+ {{ label }} <span v-if="required && label">*</span>
209
209
  <div class="flex gap-05">
210
210
  <TextInput
211
211
  v-if="searchable && open"
@@ -1,14 +1,13 @@
1
1
  <script setup lang="ts">
2
2
  import type { UploadInputProps } from '@bagelink/vue'
3
- import { Btn, IMAGE_FORMATS_REGEXP, Icon, Card, Image, pathKeyToURL } from '@bagelink/vue'
4
- import { watchDebounced } from '@vueuse/core'
5
- import { toValue } from 'vue'
3
+ import { Btn, IMAGE_FORMATS_REGEXP, Icon, Card, Image, pathKeyToURL, Loading } from '@bagelink/vue'
4
+ import { onMounted } from 'vue'
6
5
  import { useFileUpload } from './useFileUpload'
7
6
 
8
7
  const props = withDefaults(defineProps<UploadInputProps>(), {
9
8
  height: '215px',
10
9
  theme: 'dropzone',
11
- accept: '*'
10
+ accept: '*',
12
11
  })
13
12
 
14
13
  const emit = defineEmits(['update:modelValue', 'addFileStart'])
@@ -18,15 +17,23 @@ const {
18
17
  pathKeys,
19
18
  removeFile,
20
19
  flushQueue,
21
- fileToUrl,
22
20
  addFile,
23
21
  browse,
24
- pk
22
+ pk,
25
23
  } = useFileUpload({
26
24
  disabled: props.disabled,
27
25
  dirPath: props.dirPath,
28
26
  multiple: props.multiple,
29
- accept: props.accept
27
+ accept: props.accept,
28
+ namespace: props.id,
29
+ onFileQueued: async () => {
30
+ await flushQueue()
31
+ updateModelValue()
32
+ }
33
+ })
34
+
35
+ onMounted(() => {
36
+ if (props.modelValue) pk.value = [props.modelValue].flat()
30
37
  })
31
38
 
32
39
  const isImage = (str: string) => IMAGE_FORMATS_REGEXP.test(str)
@@ -39,31 +46,24 @@ function handleDrag(e: DragEvent, isDragging = false) {
39
46
  if (!props.disabled) isDragOver = isDragging
40
47
  }
41
48
 
49
+ function updateModelValue() {
50
+ if (props.multiple) emit('update:modelValue', pathKeys.value)
51
+ else emit('update:modelValue', pathKeys.value[0] || undefined)
52
+ }
53
+
42
54
  async function handleDrop(e: DragEvent) {
43
55
  if (props.disabled) return
44
56
  e.preventDefault()
45
57
  e.stopPropagation()
46
58
  emit('addFileStart')
47
59
  addFile(e.dataTransfer?.files)
48
- await flushQueue()
49
- // emit('update:modelValue', pathKeys.value)
50
60
  isDragOver = false
51
61
  }
52
62
 
53
- watchDebounced(() => toValue(pk), (value) => {
54
- if (props.multiple) emit('update:modelValue', value)
55
- else emit('update:modelValue', value[0] || undefined)
56
- }, { deep: true, immediate: true })
57
-
58
- watchDebounced(() => props.modelValue, (newVal, oldVal) => {
59
- if (`${newVal}` === `${oldVal}`) return
60
- if (newVal === undefined) return
61
- if (Array.isArray(newVal)) {
62
- pk.value = newVal
63
- } else {
64
- pk.value = [newVal]
65
- }
66
- }, { immediate: true, debounce: 500 })
63
+ function fileName(pathKey: string) {
64
+ if (!pathKey || typeof pathKey !== 'string') return 'file'
65
+ return pathKey.split('/').pop() || 'file'
66
+ }
67
67
  </script>
68
68
 
69
69
  <template>
@@ -108,7 +108,7 @@ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
108
108
  flat
109
109
  thin
110
110
  :href="pathKeyToURL(path_key)"
111
- :download="path_key.split('/').pop()"
111
+ :download="fileName(path_key)"
112
112
  />
113
113
  <div class="flex gap-025 rounded pe-1 ps-05 py-025 bg-gray-80 -my-1 ">
114
114
  <Icon icon="draft" :size="1.5" />
@@ -116,7 +116,7 @@ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
116
116
  v-lightbox="{ src: pathKeyToURL(path_key), download: true }"
117
117
  class="ellipsis-1 word-break-all h-20 m-0 color-black txt16"
118
118
  >
119
- {{ path_key.split('/').pop() }}
119
+ {{ fileName(path_key) }}
120
120
  </p>
121
121
  </div>
122
122
  </div>
@@ -161,7 +161,7 @@ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
161
161
  />
162
162
  <Icon v-else icon="description" class="multi-preview" />
163
163
  <p class="m-0">
164
- {{ path_key.split('/').pop() }}
164
+ {{ fileName(path_key) }}
165
165
  </p>
166
166
  <Btn
167
167
  thin
@@ -177,12 +177,12 @@ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
177
177
  class="multi-image-item-preview"
178
178
  :class="{ 'bgl_fill-image': fill }"
179
179
  >
180
- <Image
180
+ <img
181
181
  v-if="isImage(file.file.type)"
182
182
  class="multi-preview"
183
- :src="fileToUrl(file.file)"
183
+ :src="file.url"
184
184
  alt=""
185
- />
185
+ >
186
186
  <Icon v-else icon="description" class="multi-preview" />
187
187
  <p class="no-margin multi-preview-txt">
188
188
  {{ file.name }}
@@ -232,7 +232,7 @@ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
232
232
  thin
233
233
  icon="download"
234
234
  :href="pathKeyToURL(path_key)"
235
- :download="path_key.split('/').pop()"
235
+ :download="fileName(path_key)"
236
236
  />
237
237
  </div>
238
238
  <div v-if="isImage(path_key)" class="h-100">
@@ -259,25 +259,13 @@ watchDebounced(() => props.modelValue, (newVal, oldVal) => {
259
259
  class="single-image-item-preview"
260
260
  :class="{ 'bgl_fill-image': fill }"
261
261
  >
262
- <div
263
- class="pie"
264
- :style="{ '--p': file.progress }"
265
- style="--b: 2px"
266
- :class="{ complete: file.progress === 100 }"
267
- >
268
- <span v-if="file.progress < 100" class="progress">
269
- {{ file.progress.toFixed(0) }}
270
- </span>
271
- <Icon class="success" icon="check_circle" />
272
- </div>
273
- <Image
262
+ <Loading type="bar" :progress="file.progress" class="absolute bottom-05 end start w-100px mx-auto" />
263
+ <img
274
264
  v-if="isImage(file.file.type)"
275
- v-lightbox="{ src: fileToUrl(file.file), download: true }"
276
- class="single-preview"
277
-
278
- :src="fileToUrl(file.file)"
265
+ class="single-preview opacity-5"
266
+ :src="file.url"
279
267
  alt=""
280
- />
268
+ >
281
269
  </div>
282
270
  </div>
283
271
  </slot>
@@ -35,13 +35,16 @@
35
35
  margin: 0.5rem !important;
36
36
  background: var(--bgl-popup-bg);
37
37
  padding: 0;
38
- padding-inline-end: 0.75rem;
38
+ padding-inline-end: 1rem;
39
+ padding-inline-start: 0.25rem;
39
40
  text-align: start;
40
41
  color: var(--input-color);
41
42
  display: grid;
42
43
  grid-template-columns: auto 1fr 22px;
43
- gap: 1rem;
44
+ gap: 0.5rem;
44
45
  align-items: center;
46
+ height: var(--btn-height);
47
+ font-size: var(--label-font-size);
45
48
  }
46
49
 
47
50
  .multi-image-item-preview p {
@@ -51,9 +54,10 @@
51
54
  }
52
55
 
53
56
  .multi-preview {
54
- width: 40px;
55
- height: 40px;
56
- border-radius: var(--input-border-radius);
57
+ /* width: 40px; */
58
+ height: calc(var(--btn-height) - 0.5rem);
59
+ max-width: calc(var(--btn-height) - 0.5rem);
60
+ border-radius: calc(var(--input-border-radius) / 2);
57
61
  object-fit: cover;
58
62
  background: var(--bgl-gray-light);
59
63
  text-align: center !important;
@@ -92,14 +96,13 @@
92
96
  }
93
97
 
94
98
  .single-preview {
95
- border-radius: var(--input-border-radius);
96
99
  margin: 1rem;
97
100
  padding: 0px;
98
- min-height: calc(100% - 2rem);
99
101
  height: calc(100% - 2rem);
100
- object-fit: cover;
102
+ max-height: calc(100% - 2rem);
101
103
  background: var(--bgl-gray-light);
102
- width: 90%;
104
+ max-width: calc(100% - 2rem);
105
+ object-fit: contain;
103
106
  }
104
107
 
105
108
  .single-image-item-preview:hover::after {
@@ -36,8 +36,10 @@ export interface UploadOptions {
36
36
 
37
37
  export interface QueueFile {
38
38
  file: File
39
+ url?: string
39
40
  progress: number
40
41
  uploading?: boolean
41
42
  name?: string
42
43
  uploaded?: boolean
44
+ namespace?: string
43
45
  }
@@ -8,11 +8,15 @@ interface UseFileUploadProps {
8
8
  dirPath?: string
9
9
  accept?: string
10
10
  disabled?: boolean
11
+ namespace?: string
12
+ onFileQueued?: (files: QueueFile[]) => void
11
13
  }
12
14
 
13
15
  export function useFileUpload(props: UseFileUploadProps = {}) {
14
16
  files.setBaseUrl(useBagel().host)
15
17
 
18
+ const namespace = props.namespace || 'default'
19
+
16
20
  const fileQueue = ref<QueueFile[]>([])
17
21
  const storageFiles = ref<BglFile[]>([])
18
22
  const pk = ref<string[]>([])
@@ -40,12 +44,22 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
40
44
  }
41
45
 
42
46
  const newQueueFiles = filesToAdd.map(f => ({
47
+ url: fileToUrl(f),
43
48
  name: f.name,
44
49
  file: f,
45
- progress: 0
50
+ progress: 0,
51
+ namespace
46
52
  }))
53
+ if (props.multiple) {
54
+ fileQueue.value.push(...newQueueFiles)
55
+ } else {
56
+ fileQueue.value = newQueueFiles
57
+ }
47
58
 
48
- fileQueue.value.push(...newQueueFiles)
59
+ // Call the onFilesQueued callback if provided
60
+ if (props.onFileQueued && newQueueFiles.length > 0) {
61
+ props.onFileQueued(newQueueFiles)
62
+ }
49
63
  }
50
64
 
51
65
  const removeFile = async (pathKeyOrFile: string | File | QueueFile) => {
@@ -64,7 +78,15 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
64
78
  console.error('Error deleting file:', error)
65
79
  }
66
80
  } else if (pathKeyOrFile) {
67
- const index = fileQueue.value.findIndex(({ file }) => file.name === pathKeyOrFile.name)
81
+ // For File or QueueFile, check if it's in our queue for this namespace
82
+ const fileToRemove = pathKeyOrFile instanceof File
83
+ ? { name: pathKeyOrFile.name }
84
+ : pathKeyOrFile
85
+
86
+ const index = fileQueue.value.findIndex(queueFile => queueFile.file.name === fileToRemove.name
87
+ && queueFile.namespace === namespace
88
+ )
89
+
68
90
  if (index !== -1) {
69
91
  fileQueue.value.splice(index, 1)
70
92
  }
@@ -72,7 +94,10 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
72
94
  }
73
95
 
74
96
  const flushQueue = async () => {
75
- for (const file of fileQueue.value) {
97
+ // Only process files in the current namespace
98
+ const namespaceQueue = fileQueue.value.filter(file => file.namespace === namespace)
99
+
100
+ for (const file of namespaceQueue) {
76
101
  file.uploading = true
77
102
 
78
103
  // If not multiple, replace the existing file
@@ -85,7 +110,7 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
85
110
  onUploadProgress: (e: ProgressEvent) => {
86
111
  file.progress = (e.loaded / e.total) * 100 - 1
87
112
  },
88
- dirPath: props.dirPath,
113
+ dirPath: props.dirPath
89
114
  })
90
115
  pk.value.push(data.path_key)
91
116
  } catch (error) {
@@ -93,12 +118,12 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
93
118
  }
94
119
  }
95
120
 
96
- // Clear the queue after processing
97
- fileQueue.value = []
121
+ // Clear only files in the current namespace from the queue
122
+ fileQueue.value = fileQueue.value.filter(file => file.namespace !== namespace)
98
123
  }
99
124
 
100
125
  // UI interaction
101
- const browse = (upload = false) => {
126
+ const browse = (autoFlush = false) => {
102
127
  if (props.disabled) return
103
128
 
104
129
  const input = document.createElement('input')
@@ -108,7 +133,7 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
108
133
 
109
134
  input.onchange = (e: Event) => {
110
135
  addFile((e.target as HTMLInputElement).files)
111
- if (upload) {
136
+ if (autoFlush) {
112
137
  flushQueue()
113
138
  }
114
139
  }
@@ -140,5 +165,6 @@ export function useFileUpload(props: UseFileUploadProps = {}) {
140
165
  flushQueue,
141
166
  addFile,
142
167
  browse,
168
+ namespace
143
169
  }
144
170
  }
@@ -5,7 +5,6 @@ export { default as ColorInput } from './ColorInput.vue'
5
5
  export { default as DateInput } from './DateInput.vue'
6
6
  export { default as DatePicker } from './DatePicker.vue'
7
7
  export { default as EmailInput } from './EmailInput.vue'
8
- export { default as FileUpload } from './FileUpload.vue'
9
8
  export { default as JSONInput } from './JSONInput.vue'
10
9
  export { default as NumberInput } from './NumberInput.vue'
11
10
  export { default as OTP } from './OTP.vue'