atom-nuxt 1.0.140 → 1.0.142

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.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atomengine/atom-nuxt",
3
3
  "configKey": "atomNuxt",
4
- "version": "1.0.140",
4
+ "version": "1.0.142",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
7
7
  "unbuild": "3.5.0"
@@ -20,7 +20,6 @@ watch(() => props.modelValue, (newValue) => {
20
20
  });
21
21
  const filter = ref(props.filter);
22
22
  watch(() => props.filter, (newValue) => {
23
- debugger;
24
23
  filter.value = newValue;
25
24
  });
26
25
  const searchDialogSelectedValue = ref(null);
@@ -65,7 +64,11 @@ const selectedValue = computed({
65
64
  } else {
66
65
  model.value = val;
67
66
  }
68
- debouncedUpdate();
67
+ if (props.filter.type === "search" || props.filter.type === "multiSearch" || props.filter.type === "option" || props.filter.type === "multiOption" || props.filter.type === "multiOptionTree") {
68
+ emitUpdate();
69
+ } else {
70
+ debouncedUpdate();
71
+ }
69
72
  }
70
73
  });
71
74
  const {
@@ -152,13 +155,13 @@ const displayForChip = (item) => {
152
155
  </template>
153
156
  </v-date-picker>
154
157
  </v-menu>
155
- <crud-address-search-field
156
- v-else-if="filter.optionType === 'LocationPoint'"
157
- :id="filter.key"
158
- :disabled="disabled"
159
- :label="filter.label"
160
- v-model="selectedValue"
161
- />
158
+ <crud-address-search-field
159
+ v-else-if="filter.optionType === 'LocationPoint'"
160
+ :id="filter.key"
161
+ :disabled="disabled"
162
+ :label="filter.label"
163
+ v-model="selectedValue"
164
+ />
162
165
  <v-text-field
163
166
  v-else
164
167
  dense
@@ -243,20 +246,20 @@ const displayForChip = (item) => {
243
246
 
244
247
  <template v-else-if="filter.type === 'multiOptionTree'">
245
248
  <div class="bg-white border">
246
- <v-treeview
247
- class="ma-0 pa-0"
248
- :id="filter.key"
249
- v-model="selectedValue"
250
- :disabled="disabled"
251
- select-strategy="default"
252
- :hint="filter.description"
253
- :items="filter.options"
254
- item-title="label"
255
- :clearable="true"
256
- item-value="value"
257
- :selectable="true"
258
- density="compact"
259
- ></v-treeview>
249
+ <v-treeview
250
+ class="ma-0 pa-0"
251
+ :id="filter.key"
252
+ v-model="selectedValue"
253
+ :disabled="disabled"
254
+ select-strategy="default"
255
+ :hint="filter.description"
256
+ :items="filter.options"
257
+ item-title="label"
258
+ :clearable="true"
259
+ item-value="value"
260
+ :selectable="true"
261
+ density="compact"
262
+ ></v-treeview>
260
263
  </div>
261
264
  </template>
262
265
  <template v-else-if="filter.type === 'search' || filter.type === 'multiSearch' ">
@@ -54,19 +54,22 @@ const dialog = ref(false);
54
54
  const filesToUpload = ref([]);
55
55
  const fileToUpload = ref(null);
56
56
  const searchValue = ref(null);
57
+ const tempModel = ref(null);
58
+ const cloneModel = () => props.multiple ? [...model.value || []] : model.value;
57
59
  const finish = () => {
60
+ model.value = props.multiple ? [...tempModel.value] : tempModel.value;
58
61
  dialog.value = false;
59
62
  };
60
63
  const onSelectImage = (item) => {
61
64
  if (props.multiple) {
62
- if (model.value === null) model.value = [];
63
- if (!model.value.includes(item)) {
64
- model.value.push(item);
65
+ if (!tempModel.value) tempModel.value = [];
66
+ if (!tempModel.value.includes(item)) {
67
+ tempModel.value.push(item);
65
68
  } else {
66
- model.value = model.value.filter((i) => i !== item);
69
+ tempModel.value = tempModel.value.filter((i) => i !== item);
67
70
  }
68
71
  } else {
69
- model.value = model.value === item ? null : item;
72
+ tempModel.value = tempModel.value === item ? null : item;
70
73
  }
71
74
  };
72
75
  const {
@@ -103,12 +106,14 @@ const processUploads = async () => {
103
106
  await createUpload(upload);
104
107
  if (!hasUploadErrors.value && hasItem.value) {
105
108
  model.value = completedUpload.value.id;
109
+ dialog.value = false;
106
110
  }
107
111
  }
108
112
  uploadsLoading.value = false;
109
- if (!props.multiple) {
113
+ if (props.multiple) {
110
114
  filesToUpload.value = [];
111
- dialog.value = false;
115
+ } else {
116
+ fileToUpload.value = null;
112
117
  }
113
118
  };
114
119
  const selectionFilters = computed(() => {
@@ -125,6 +130,11 @@ const hasSelection = computed(() => {
125
130
  return model.value && model.value !== "" && (model.value.length > 0 || model.value > 0);
126
131
  }
127
132
  });
133
+ watch(() => dialog.value, (val) => {
134
+ if (val) {
135
+ tempModel.value = cloneModel();
136
+ }
137
+ });
128
138
  watch(() => filesToUpload.value, () => {
129
139
  if (filesToUpload.value.length > 0) {
130
140
  processUploads();
@@ -140,14 +150,20 @@ watch(() => fileToUpload.value, () => {
140
150
  <template>
141
151
  <div>
142
152
  <div v-if="title" style="font-size: 12px;" class="text-grey-darken-2 mb-1">{{ title }}</div>
153
+
143
154
  <div v-if="!hasSelection" class="mb-3">
144
- <v-btn :disabled="disabled" @click="dialog = true" size="small"
145
- color="success">
155
+ <v-btn :disabled="disabled" @click="dialog = true" size="small" color="success">
146
156
  Select Media
147
157
  </v-btn>
148
158
  </div>
149
- <crud-list-loader v-if="hasSelection" :limit="1000" :disable-no-results="true" :custom-filters="selectionFilters"
150
- :path="path">
159
+
160
+ <crud-list-loader
161
+ v-if="hasSelection"
162
+ :per-page="1000"
163
+ :disable-no-results="true"
164
+ :custom-filters="selectionFilters"
165
+ :path="path"
166
+ >
151
167
  <template #default="uploadSlot">
152
168
  <div v-for="item in uploadSlot.items" :key="item.id">
153
169
  <crud-upload-field-selection
@@ -156,19 +172,20 @@ watch(() => fileToUpload.value, () => {
156
172
  :file-name-key="fileNameKey"
157
173
  :image-click-action="() => { if(replaceable && !multiple) { dialog = true; }}"
158
174
  :item="item"
159
- :selected="false">
175
+ :selected="false"
176
+ >
160
177
  <template #additionalActions>
161
- <slot name="additionalActions" :item="item">
162
-
163
- </slot>
178
+ <slot name="additionalActions" :item="item" />
164
179
  </template>
165
180
  </crud-upload-field-selection>
166
181
  </div>
167
182
  </template>
168
183
  </crud-list-loader>
169
- <v-dialog v-model="dialog" max-width="1700">
184
+
185
+ <v-dialog v-model="dialog" @update:modelValue="val => { dialog = val; if (val) tempModel = cloneModel(); }" max-width="1700">
170
186
  <v-card>
171
187
  <h2 class="mb-0 border-b pa-4" v-if="title">{{ title }}</h2>
188
+
172
189
  <div style="height: 90vh; overflow: auto;" class="pa-4 d-flex flex-column">
173
190
  <div class="flex-wrap">
174
191
  <div class="border pa-3 rounded mb-3">
@@ -189,13 +206,15 @@ watch(() => fileToUpload.value, () => {
189
206
  v-model="fileToUpload"
190
207
  :disabled="uploadsLoading"
191
208
  />
192
- <crud-error-display :errors="uploadErrors"></crud-error-display>
209
+ <crud-error-display :errors="uploadErrors" />
193
210
  </div>
194
- <v-btn :loading="uploadsLoading"
195
- class="ml-2"
196
- @click="processUploads"
197
- color='primary'
198
- :disabled="(multiple && (filesToUpload === null || filesToUpload.length === 0)) || (!multiple && fileToUpload === null)">
211
+ <v-btn
212
+ :loading="uploadsLoading"
213
+ class="ml-2"
214
+ @click="processUploads"
215
+ color="primary"
216
+ :disabled="(multiple && (!filesToUpload || filesToUpload.length === 0)) || (!multiple && !fileToUpload)"
217
+ >
199
218
  <v-icon small class="mr-1">mdi-upload</v-icon>
200
219
  Upload
201
220
  </v-btn>
@@ -204,12 +223,16 @@ watch(() => fileToUpload.value, () => {
204
223
  <v-text-field
205
224
  v-model="searchValue"
206
225
  label="Search by file name"
207
- :disabled="uploadsLoading"/>
226
+ :disabled="uploadsLoading"
227
+ />
208
228
  </div>
209
-
210
- <crud-list-loader v-if="hasSelection" :limit="1000" :disable-no-results="true"
211
- :custom-filters="selectionFilters"
212
- :path="path">
229
+ <crud-list-loader
230
+ v-if="tempModel && (Array.isArray(tempModel) ? tempModel.length : tempModel)"
231
+ :per-page="1000"
232
+ :disable-no-results="true"
233
+ :custom-filters="{ ids: multiple ? tempModel : [tempModel] }"
234
+ :path="path"
235
+ >
213
236
  <template #default="uploadSlot">
214
237
  <div class="pa-3 border rounded mb-3 bg-white">
215
238
  <h4 class="mb-2">Selected media:</h4>
@@ -219,56 +242,65 @@ watch(() => fileToUpload.value, () => {
219
242
  :file-name-key="fileNameKey"
220
243
  @click="onSelectImage(item.id)"
221
244
  :item="item"
222
- :selected="false"
223
- class="col-6">
224
- </crud-upload-field-selection>
245
+ :selected="multiple ? tempModel.includes(item.id) : tempModel === item.id"
246
+ class="col-6"
247
+ />
225
248
  </div>
226
249
  </div>
227
250
  </template>
228
251
  </crud-list-loader>
229
252
 
230
253
  <div class="border pa-3 rounded overflow-scroll flex-fill">
231
- <crud-list-loader :custom-filters="{keywords: searchValue, ...customFilters}"
232
- :debounced="true"
233
- :per-page="66"
234
- :page="uploadsPage"
235
- :path="path">
254
+ <crud-list-loader
255
+ :custom-filters="{ keywords: searchValue, ...customFilters }"
256
+ :debounced="true"
257
+ :per-page="66"
258
+ :page="uploadsPage"
259
+ :path="path"
260
+ >
236
261
  <template #empty>
237
- <v-alert>
238
- No media for filter, upload new instead
239
- </v-alert>
262
+ <v-alert>No media for filter, upload new instead</v-alert>
240
263
  </template>
241
264
 
242
- <template #default="{items,currentPage,totalPages}">
243
- <div class="d-flex align-between flex-wrap " style="gap: 8px; overflow-x: hidden;">
244
- <div class="d-inline-flex border align-center rounded bg-white"
245
- style="max-width: 250px; flex: 0 0 auto;" v-for="item in items" :key="'selection-'+item.id">
265
+ <template #default="{ items, currentPage, totalPages }">
266
+ <div class="d-flex align-between flex-wrap" style="gap: 8px; overflow-x: hidden;">
267
+ <div
268
+ class="d-inline-flex border align-center rounded bg-white"
269
+ style="max-width: 250px; flex: 0 0 auto;"
270
+ v-for="item in items"
271
+ :key="'selection-'+item.id"
272
+ >
246
273
  <crud-upload-field-selection
274
+ v-model="tempModel"
247
275
  :hide-title="true"
248
276
  :file-name-key="fileNameKey"
249
277
  :mime-key="mimeKey"
250
278
  class="flex-fill"
251
279
  @click="onSelectImage(item.id)"
252
280
  :item="item"
253
- v-model="model"
254
- >
255
- </crud-upload-field-selection>
281
+ :selected="multiple ? tempModel.includes(item.id) : tempModel === item.id"
282
+ />
256
283
  </div>
257
284
  <v-col cols="12">
258
- <v-pagination :length="totalPages" v-model="uploadsPage"/>
285
+ <v-pagination :length="totalPages" v-model="uploadsPage" />
259
286
  </v-col>
260
287
  </div>
261
288
  </template>
262
289
  </crud-list-loader>
263
-
264
290
  </div>
265
291
  </div>
292
+
266
293
  <div class="border-t pa-4">
267
- <v-btn v-if="hasSelection" :loading="uploadsLoading" @click="finish" color='success'>
294
+ <v-btn
295
+ v-if="tempModel && (Array.isArray(tempModel) ? tempModel.length > 0 : true)"
296
+ :loading="uploadsLoading"
297
+ @click="finish"
298
+ color="success"
299
+ >
268
300
  <v-icon small class="mr-1">mdi-content-save</v-icon>
269
301
  Done
270
302
  </v-btn>
271
- <v-btn v-else @click="dialog = false" color='error'>
303
+ <v-btn v-else @click="dialog = false" color="error">
272
304
  <v-icon small class="mr-1">mdi-close</v-icon>
273
305
  Cancel
274
306
  </v-btn>
@@ -83,70 +83,81 @@ const containerClasses = computed(() => {
83
83
  "pa-1": true,
84
84
  "position-relative": true,
85
85
  "cursor": true,
86
- "d-flex": true
86
+ "d-flex": true,
87
+ "border": selected.value,
88
+ "border-primary": selected.value,
89
+ "shadow": selected.value
87
90
  };
88
91
  });
89
92
  </script>
90
93
 
91
94
  <template>
92
95
  <div :class="containerClasses">
96
+ <div class="d-flex justify-center flex-fill align-center" v-bind="props">
97
+ <nuxt-img v-if="isImage"
98
+ @click="imageClickAction"
99
+ style="width:100px; height:100px; object-fit: cover;"
100
+ format="webp"
101
+ :src="url"
102
+ fit="cover"
103
+ :width="item.width ?? 100"
104
+ :height="item.height ?? 'auto'"
105
+ />
106
+ <video v-else-if="isVideo"
107
+ @click="imageClickAction"
108
+ :src="url"
109
+ :width="50"
110
+ :height="50"
111
+ class="flex-shrink-1"></video>
112
+ <div v-else class="bg-white d-flex justify-center align-center" style="height: 100px; width: 100px;">
113
+ <v-icon :icon="mimeTypeToMdiIcon(item[mimeKey])" size="40" color="primary" class="m-auto"></v-icon>
114
+ </div>
115
+ <div v-if="!hideTitle"
116
+ style="font-size: 12px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-all;"
117
+ class="text-wrap ml-2">{{ item[fileNameKey] }}
118
+ </div>
119
+ <div class="ml-2 d-flex flex-column align-center">
120
+ <v-btn size="x-small" target="_blank" color="primary" :icon="true" :href="downloadUrl">
121
+ <v-icon icon="mdi-download"></v-icon>
122
+ </v-btn>
123
+ <slot name="additionalActions" :item="item">
124
+ </slot>
125
+ </div>
126
+
127
+ </div>
93
128
  <v-tooltip>
94
129
  <template v-slot:activator="{ props }">
95
- <div class="d-flex justify-center flex-fill align-center" v-bind="props">
96
- <nuxt-img v-if="isImage"
97
- @click="imageClickAction"
98
- style="width:100px; height:100px; object-fit: cover;"
99
- format="webp"
100
- :src="url"
101
- fit="cover"
102
- :width="item.width ?? 100"
103
- :height="item.height ?? 'auto'"
104
- />
105
- <video v-else-if="isVideo"
106
- @click="imageClickAction"
107
- :src="url"
108
- :width="50"
109
- :height="50"
110
- class="flex-shrink-1"></video>
111
- <div v-else class="bg-white d-flex justify-center align-center" style="height: 100px; width: 100px;">
112
- <v-icon :icon="mimeTypeToMdiIcon(item[mimeKey])" size="40" color="primary" class="m-auto"></v-icon>
113
- </div>
114
- <div v-if="!hideTitle"
115
- style="font-size: 12px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-all;"
116
- class="text-wrap ml-2">{{ item[fileNameKey] }}
117
- </div>
118
- <div class="ml-2 d-flex flex-column align-center">
119
- <v-btn size="x-small" target="_blank" color="primary" :icon="true" :href="downloadUrl">
120
- <v-icon icon="mdi-download"></v-icon>
121
- </v-btn>
122
- <slot name="additionalActions" :item="item">
123
- </slot>
124
- </div>
125
-
126
- </div>
130
+ <v-avatar
131
+ v-bind="props"
132
+ style="position: absolute; top: 5px; left: 5px;"
133
+ size="20"
134
+ color="black">
135
+ <v-icon size="10">mdi-magnify-plus</v-icon>
136
+ </v-avatar>
127
137
  </template>
128
- <div>
129
- <div class="d-flex flex-column justify-center text-wrap flex-shrink-1" style="font-size: 14px;">
130
- <nuxt-img v-if="isImage"
131
- style="width:600px; height:auto; max-width:100%;"
132
- :src="largeUrl"
133
- :width="item.width ?? 100"
134
- :height="item.height ?? 'auto'"
135
- />
136
- <div style="overflow-wrap: break-word; word-wrap: break-word; word-break: break-all;"
137
- class="font-weight-bold text-wrap">{{ item[fileNameKey] }}
138
- </div>
139
- <div>
140
- <small>{{ formatStringDate(item.createdAt, 'DD/MM/YYYY HH:mm', 'YYYY-MM-DD HH:mm:ss') }}</small>
141
- </div>
138
+ <div>
139
+ <div class="d-flex flex-column justify-center text-wrap flex-shrink-1" style="font-size: 14px;">
140
+ <nuxt-img v-if="isImage"
141
+ style="width:600px; height:auto; max-width:100%;"
142
+ :src="largeUrl"
143
+ :width="item.width ?? 100"
144
+ :height="item.height ?? 'auto'"
145
+ />
146
+ <div style="overflow-wrap: break-word; word-wrap: break-word; word-break: break-all;"
147
+ class="font-weight-bold text-wrap">{{ item[fileNameKey] }}
148
+ </div>
149
+ <div>
150
+ <small>{{ formatStringDate(item.createdAt, 'DD/MM/YYYY HH:mm', 'YYYY-MM-DD HH:mm:ss') }}</small>
142
151
  </div>
143
152
  </div>
153
+ </div>
144
154
  </v-tooltip>
155
+
145
156
  <v-avatar
146
157
  style="position: absolute; top: 5px; right: 5px;"
147
158
  size="20"
148
159
  v-if="selected"
149
- color="success">
160
+ color="accent">
150
161
  <v-icon dark size="10">mdi-check</v-icon>
151
162
  </v-avatar>
152
163
  <v-avatar
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atom-nuxt",
3
- "version": "1.0.140",
3
+ "version": "1.0.142",
4
4
  "description": "My new Nuxt module",
5
5
  "repository": "atomengine/atom-nuxt",
6
6
  "license": "MIT",