@adminforth/upload 1.0.21 β 1.0.23
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/custom/preview.vue +3 -0
- package/custom/uploader.vue +11 -2
- package/dist/custom/preview.vue +3 -0
- package/dist/custom/uploader.vue +11 -2
- package/dist/index.js +12 -12
- package/index.ts +1 -1
- package/package.json +1 -1
- package/types.ts +5 -0
package/custom/preview.vue
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
v-if="contentType && contentType.startsWith('image')"
|
|
6
6
|
:src="url"
|
|
7
7
|
class="rounded-md"
|
|
8
|
+
:style="maxWidth"
|
|
8
9
|
ref="img"
|
|
9
10
|
data-zoomable
|
|
10
11
|
@click.stop="zoom.open()"
|
|
@@ -70,6 +71,8 @@ const url = computed(() => {
|
|
|
70
71
|
return props.record[`previewUrl_${props.meta.pluginInstanceId}`];
|
|
71
72
|
});
|
|
72
73
|
|
|
74
|
+
const maxWidth = computed(() => props.meta.maxWidth ? { maxWidth: props.meta.maxWidth } : {});
|
|
75
|
+
|
|
73
76
|
|
|
74
77
|
// since we have no way to know the content type of the file, we will try to guess it from extension
|
|
75
78
|
// for better experience probably we should check whether user saves content type in the database and use it here
|
package/custom/uploader.vue
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<IconMagic class="w-5 h-5"/>
|
|
12
12
|
</button>
|
|
13
13
|
|
|
14
|
-
<label for="
|
|
14
|
+
<label :for="inputId"
|
|
15
15
|
class="flex flex-col px-3 items-center justify-center w-full h-64 border-2 border-dashed rounded-lg cursor-pointer dark:hover:bg-gray-800 hover:bg-gray-100 dark:hover:border-gray-500 dark:hover:bg-gray-600"
|
|
16
16
|
@dragover.prevent="() => dragging = true"
|
|
17
17
|
@dragleave.prevent="() => dragging = false"
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
61
|
</div>
|
|
62
|
-
<input id="
|
|
62
|
+
<input :id="inputId" type="file" class="hidden" @change="onFileChange" ref="uploadInputRef" />
|
|
63
63
|
</label>
|
|
64
64
|
</div>
|
|
65
65
|
|
|
@@ -70,6 +70,7 @@ import { computed, ref, onMounted, watch } from 'vue'
|
|
|
70
70
|
import { callAdminForthApi } from '@/utils'
|
|
71
71
|
import { IconMagic } from '@iconify-prerendered/vue-mdi';
|
|
72
72
|
|
|
73
|
+
const inputId = computed(() => `dropzone-file-${props.meta.pluginInstanceId}`);
|
|
73
74
|
|
|
74
75
|
import ImageGenerator from '@@/plugins/UploadPlugin/imageGenerator.vue';
|
|
75
76
|
|
|
@@ -85,6 +86,8 @@ const emit = defineEmits([
|
|
|
85
86
|
'update:emptiness',
|
|
86
87
|
]);
|
|
87
88
|
|
|
89
|
+
const uploadInputRef = ref(null);
|
|
90
|
+
|
|
88
91
|
const showImageGen = ref(false);
|
|
89
92
|
const dragging = ref(false);
|
|
90
93
|
|
|
@@ -136,6 +139,7 @@ function clear() {
|
|
|
136
139
|
progress.value = 0;
|
|
137
140
|
uploaded.value = false;
|
|
138
141
|
uploadedSize.value = 0;
|
|
142
|
+
uploadInputRef.value.value = null;
|
|
139
143
|
emit('update:value', null);
|
|
140
144
|
}
|
|
141
145
|
|
|
@@ -154,6 +158,11 @@ function humanifySize(size) {
|
|
|
154
158
|
|
|
155
159
|
|
|
156
160
|
const onFileChange = async (e) => {
|
|
161
|
+
// if empty then return
|
|
162
|
+
if (!e.target.files || e.target.files.length === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
157
166
|
imgPreview.value = null;
|
|
158
167
|
progress.value = 0;
|
|
159
168
|
uploaded.value = false;
|
package/dist/custom/preview.vue
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
v-if="contentType && contentType.startsWith('image')"
|
|
6
6
|
:src="url"
|
|
7
7
|
class="rounded-md"
|
|
8
|
+
:style="maxWidth"
|
|
8
9
|
ref="img"
|
|
9
10
|
data-zoomable
|
|
10
11
|
@click.stop="zoom.open()"
|
|
@@ -70,6 +71,8 @@ const url = computed(() => {
|
|
|
70
71
|
return props.record[`previewUrl_${props.meta.pluginInstanceId}`];
|
|
71
72
|
});
|
|
72
73
|
|
|
74
|
+
const maxWidth = computed(() => props.meta.maxWidth ? { maxWidth: props.meta.maxWidth } : {});
|
|
75
|
+
|
|
73
76
|
|
|
74
77
|
// since we have no way to know the content type of the file, we will try to guess it from extension
|
|
75
78
|
// for better experience probably we should check whether user saves content type in the database and use it here
|
package/dist/custom/uploader.vue
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<IconMagic class="w-5 h-5"/>
|
|
12
12
|
</button>
|
|
13
13
|
|
|
14
|
-
<label for="
|
|
14
|
+
<label :for="inputId"
|
|
15
15
|
class="flex flex-col px-3 items-center justify-center w-full h-64 border-2 border-dashed rounded-lg cursor-pointer dark:hover:bg-gray-800 hover:bg-gray-100 dark:hover:border-gray-500 dark:hover:bg-gray-600"
|
|
16
16
|
@dragover.prevent="() => dragging = true"
|
|
17
17
|
@dragleave.prevent="() => dragging = false"
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
61
|
</div>
|
|
62
|
-
<input id="
|
|
62
|
+
<input :id="inputId" type="file" class="hidden" @change="onFileChange" ref="uploadInputRef" />
|
|
63
63
|
</label>
|
|
64
64
|
</div>
|
|
65
65
|
|
|
@@ -70,6 +70,7 @@ import { computed, ref, onMounted, watch } from 'vue'
|
|
|
70
70
|
import { callAdminForthApi } from '@/utils'
|
|
71
71
|
import { IconMagic } from '@iconify-prerendered/vue-mdi';
|
|
72
72
|
|
|
73
|
+
const inputId = computed(() => `dropzone-file-${props.meta.pluginInstanceId}`);
|
|
73
74
|
|
|
74
75
|
import ImageGenerator from '@@/plugins/UploadPlugin/imageGenerator.vue';
|
|
75
76
|
|
|
@@ -85,6 +86,8 @@ const emit = defineEmits([
|
|
|
85
86
|
'update:emptiness',
|
|
86
87
|
]);
|
|
87
88
|
|
|
89
|
+
const uploadInputRef = ref(null);
|
|
90
|
+
|
|
88
91
|
const showImageGen = ref(false);
|
|
89
92
|
const dragging = ref(false);
|
|
90
93
|
|
|
@@ -136,6 +139,7 @@ function clear() {
|
|
|
136
139
|
progress.value = 0;
|
|
137
140
|
uploaded.value = false;
|
|
138
141
|
uploadedSize.value = 0;
|
|
142
|
+
uploadInputRef.value.value = null;
|
|
139
143
|
emit('update:value', null);
|
|
140
144
|
}
|
|
141
145
|
|
|
@@ -154,6 +158,11 @@ function humanifySize(size) {
|
|
|
154
158
|
|
|
155
159
|
|
|
156
160
|
const onFileChange = async (e) => {
|
|
161
|
+
// if empty then return
|
|
162
|
+
if (!e.target.files || e.target.files.length === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
157
166
|
imgPreview.value = null;
|
|
158
167
|
progress.value = 0;
|
|
159
168
|
uploaded.value = false;
|
package/dist/index.js
CHANGED
|
@@ -97,7 +97,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
97
97
|
modifyResourceConfig: { get: () => super.modifyResourceConfig }
|
|
98
98
|
});
|
|
99
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
100
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
101
101
|
_super.modifyResourceConfig.call(this, adminforth, resourceConfig);
|
|
102
102
|
// after column to store the path of the uploaded file, add new VirtualColumn,
|
|
103
103
|
// show only in edit and create views
|
|
@@ -124,6 +124,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
124
124
|
generateImages: this.options.generation ? true : false,
|
|
125
125
|
pathColumnLabel: resourceConfig.columns[pathColumnIndex].label,
|
|
126
126
|
fieldsForContext: (_c = this.options.generation) === null || _c === void 0 ? void 0 : _c.fieldsForContext,
|
|
127
|
+
maxWidth: (_d = this.options.preview) === null || _d === void 0 ? void 0 : _d.maxWidth,
|
|
127
128
|
};
|
|
128
129
|
// define components which will be imported from other components
|
|
129
130
|
this.componentPath('imageGenerator.vue');
|
|
@@ -145,14 +146,14 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
145
146
|
if (!resourceConfig.columns[pathColumnIndex].components) {
|
|
146
147
|
resourceConfig.columns[pathColumnIndex].components = {};
|
|
147
148
|
}
|
|
148
|
-
if (((
|
|
149
|
+
if (((_e = this.options.preview) === null || _e === void 0 ? void 0 : _e.showInList) || ((_f = this.options.preview) === null || _f === void 0 ? void 0 : _f.showInList) === undefined) {
|
|
149
150
|
// add preview column to list
|
|
150
151
|
resourceConfig.columns[pathColumnIndex].components.list = {
|
|
151
152
|
file: this.componentPath('preview.vue'),
|
|
152
153
|
meta: pluginFrontendOptions,
|
|
153
154
|
};
|
|
154
155
|
}
|
|
155
|
-
if (((
|
|
156
|
+
if (((_g = this.options.preview) === null || _g === void 0 ? void 0 : _g.showInShow) || ((_h = this.options.preview) === null || _h === void 0 ? void 0 : _h.showInShow) === undefined) {
|
|
156
157
|
resourceConfig.columns[pathColumnIndex].components.show = {
|
|
157
158
|
file: this.componentPath('preview.vue'),
|
|
158
159
|
meta: pluginFrontendOptions,
|
|
@@ -173,7 +174,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
173
174
|
virtualColumn.editingNote = pathColumn.editingNote;
|
|
174
175
|
// ** HOOKS FOR CREATE **//
|
|
175
176
|
// add beforeSave hook to save virtual column to path column
|
|
176
|
-
resourceConfig.hooks.create.beforeSave.push((
|
|
177
|
+
resourceConfig.hooks.create.beforeSave.push((_l) => __awaiter(this, [_l], void 0, function* ({ record }) {
|
|
177
178
|
if (record[virtualColumn.name]) {
|
|
178
179
|
record[pathColumnName] = record[virtualColumn.name];
|
|
179
180
|
delete record[virtualColumn.name];
|
|
@@ -181,7 +182,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
181
182
|
return { ok: true };
|
|
182
183
|
}));
|
|
183
184
|
// in afterSave hook, aremove tag adminforth-not-yet-used from the file
|
|
184
|
-
resourceConfig.hooks.create.afterSave.push((
|
|
185
|
+
resourceConfig.hooks.create.afterSave.push((_m) => __awaiter(this, [_m], void 0, function* ({ record }) {
|
|
185
186
|
process.env.HEAVY_DEBUG && console.log('πΎπΎ after save ', record === null || record === void 0 ? void 0 : record.id);
|
|
186
187
|
if (record[pathColumnName]) {
|
|
187
188
|
const s3 = new S3({
|
|
@@ -205,7 +206,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
205
206
|
}));
|
|
206
207
|
// ** HOOKS FOR SHOW **//
|
|
207
208
|
// add show hook to get presigned URL
|
|
208
|
-
resourceConfig.hooks.show.afterDatasourceResponse.push((
|
|
209
|
+
resourceConfig.hooks.show.afterDatasourceResponse.push((_o) => __awaiter(this, [_o], void 0, function* ({ response }) {
|
|
209
210
|
const record = response[0];
|
|
210
211
|
if (!record) {
|
|
211
212
|
return { ok: true };
|
|
@@ -223,8 +224,8 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
223
224
|
return { ok: true };
|
|
224
225
|
}));
|
|
225
226
|
// ** HOOKS FOR LIST **//
|
|
226
|
-
if (((
|
|
227
|
-
resourceConfig.hooks.list.afterDatasourceResponse.push((
|
|
227
|
+
if (((_j = this.options.preview) === null || _j === void 0 ? void 0 : _j.showInList) || ((_k = this.options.preview) === null || _k === void 0 ? void 0 : _k.showInList) === undefined) {
|
|
228
|
+
resourceConfig.hooks.list.afterDatasourceResponse.push((_p) => __awaiter(this, [_p], void 0, function* ({ response }) {
|
|
228
229
|
const s3 = new S3({
|
|
229
230
|
credentials: {
|
|
230
231
|
accessKeyId: this.options.s3AccessKeyId,
|
|
@@ -242,7 +243,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
242
243
|
}
|
|
243
244
|
// ** HOOKS FOR DELETE **//
|
|
244
245
|
// add delete hook which sets tag adminforth-candidate-for-cleanup to true
|
|
245
|
-
resourceConfig.hooks.delete.afterSave.push((
|
|
246
|
+
resourceConfig.hooks.delete.afterSave.push((_q) => __awaiter(this, [_q], void 0, function* ({ record }) {
|
|
246
247
|
if (record[pathColumnName]) {
|
|
247
248
|
const s3 = new S3({
|
|
248
249
|
credentials: {
|
|
@@ -274,7 +275,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
274
275
|
}));
|
|
275
276
|
// ** HOOKS FOR EDIT **//
|
|
276
277
|
// beforeSave
|
|
277
|
-
resourceConfig.hooks.edit.beforeSave.push((
|
|
278
|
+
resourceConfig.hooks.edit.beforeSave.push((_r) => __awaiter(this, [_r], void 0, function* ({ record }) {
|
|
278
279
|
// null is when value is removed
|
|
279
280
|
if (record[virtualColumn.name] || record[virtualColumn.name] === null) {
|
|
280
281
|
record[pathColumnName] = record[virtualColumn.name];
|
|
@@ -282,7 +283,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
282
283
|
return { ok: true };
|
|
283
284
|
}));
|
|
284
285
|
// add edit postSave hook to delete old file and remove tag from new file
|
|
285
|
-
resourceConfig.hooks.edit.afterSave.push((
|
|
286
|
+
resourceConfig.hooks.edit.afterSave.push((_s) => __awaiter(this, [_s], void 0, function* ({ record, oldRecord }) {
|
|
286
287
|
if (record[virtualColumn.name] || record[virtualColumn.name] === null) {
|
|
287
288
|
const s3 = new S3({
|
|
288
289
|
credentials: {
|
|
@@ -371,7 +372,6 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
371
372
|
let previewUrl;
|
|
372
373
|
if ((_b = this.options.preview) === null || _b === void 0 ? void 0 : _b.previewUrl) {
|
|
373
374
|
previewUrl = this.options.preview.previewUrl({ s3Path });
|
|
374
|
-
return;
|
|
375
375
|
}
|
|
376
376
|
else if (this.options.s3ACL === 'public-read') {
|
|
377
377
|
previewUrl = `https://${this.options.s3Bucket}.s3.${this.options.s3Region}.amazonaws.com/${s3Path}`;
|
package/index.ts
CHANGED
|
@@ -123,6 +123,7 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
123
123
|
generateImages: this.options.generation ? true : false,
|
|
124
124
|
pathColumnLabel: resourceConfig.columns[pathColumnIndex].label,
|
|
125
125
|
fieldsForContext: this.options.generation?.fieldsForContext,
|
|
126
|
+
maxWidth: this.options.preview?.maxWidth,
|
|
126
127
|
};
|
|
127
128
|
// define components which will be imported from other components
|
|
128
129
|
this.componentPath('imageGenerator.vue');
|
|
@@ -413,7 +414,6 @@ export default class UploadPlugin extends AdminForthPlugin {
|
|
|
413
414
|
let previewUrl;
|
|
414
415
|
if (this.options.preview?.previewUrl) {
|
|
415
416
|
previewUrl = this.options.preview.previewUrl({ s3Path });
|
|
416
|
-
return;
|
|
417
417
|
} else if (this.options.s3ACL === 'public-read') {
|
|
418
418
|
previewUrl = `https://${this.options.s3Bucket}.s3.${this.options.s3Region}.amazonaws.com/${s3Path}`;
|
|
419
419
|
} else {
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -71,6 +71,11 @@ export type PluginOptions = {
|
|
|
71
71
|
*/
|
|
72
72
|
showInShow?: boolean,
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Maximum width of the preview image
|
|
76
|
+
*/
|
|
77
|
+
maxWidth?: string,
|
|
78
|
+
|
|
74
79
|
/**
|
|
75
80
|
* Used to display preview (if it is image) in list and show views.
|
|
76
81
|
* Defaulted to the AWS S3 presigned URL if resource is private or public URL if resource is public.
|