Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions assets/css/admin.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/js/admin.min.js

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions assets/js/components-vue/MediaManagerV2/ActionsMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const menuEventBus = {
}
};

let nextMenuId = 0;

export default {
name: 'ActionsMenu',
inject: ['userPermissions'],
Expand All @@ -46,6 +48,7 @@ export default {
},
data() {
return {
menuId: ++nextMenuId,
openUpwards: false,
menuPosition: {top: 0, left: 0},
menuElement: null
Expand All @@ -55,7 +58,7 @@ export default {
// Listen for other menus being opened
menuEventBus.$on('menu-opened', (menuId) => {
// If this isn't the menu that was just opened and our menu is open, close it
if (menuId !== this._uid && this.isOpen) {
if (menuId !== this.menuId && this.isOpen) {
this.$emit('close');
}
});
Expand All @@ -64,7 +67,7 @@ export default {
isOpen(newValue) {
if (newValue) {
// Notify other menus that this one is opening
menuEventBus.$emit('menu-opened', this._uid);
menuEventBus.$emit('menu-opened', this.menuId);
this.createMenu();
} else {
this.removeMenu();
Expand All @@ -77,7 +80,7 @@ export default {
window.addEventListener('resize', this.handleResize);
window.addEventListener('scroll', this.handleScroll, true);
},
beforeDestroy() {
beforeUnmount() {
// Clean up event listeners
menuEventBus.$off('menu-opened');
document.removeEventListener('click', this.handleClickOutside);
Expand Down
20 changes: 10 additions & 10 deletions assets/js/components-vue/MediaManagerV2/BucketSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export default {
components: {Button},
inject: ['userPermissions'],
props: {
value: {
modelValue: {
type: [Array, Number, String],
default: () => []
},
Expand Down Expand Up @@ -138,13 +138,13 @@ export default {
mounted() {
document.addEventListener('keydown', this.handleKeydown);
},
beforeDestroy() {
beforeUnmount() {
document.removeEventListener('click', this.closeDropdown);
document.removeEventListener('keydown', this.handleKeydown);
},
watch: {
value: {
handler(newVal) {
modelValue: {
handler() {
this.initializeSelectedBuckets();
},
deep: true
Expand All @@ -159,9 +159,9 @@ export default {
methods: {
initializeSelectedBuckets() {
if (this.singleSelect) {
this.selectedBuckets = this.value ? [this.value] : [];
this.selectedBuckets = this.modelValue ? [this.modelValue] : [];
} else {
this.selectedBuckets = Array.isArray(this.value) ? [...this.value] : [];
this.selectedBuckets = Array.isArray(this.modelValue) ? [...this.modelValue] : [];
}
},
toggleDropdown(event) {
Expand Down Expand Up @@ -205,7 +205,7 @@ export default {
toggleBucket(bucketId) {
if (this.singleSelect) {
this.selectedBuckets = [bucketId];
this.$emit('input', bucketId);
this.$emit('update:modelValue', bucketId);
this.$emit('change', bucketId);
this.closeDropdown();
} else {
Expand All @@ -215,7 +215,7 @@ export default {
} else {
this.selectedBuckets.push(bucketId);
}
this.$emit('input', this.selectedBuckets);
this.$emit('update:modelValue', this.selectedBuckets);
this.$emit('change', this.selectedBuckets);
}
},
Expand All @@ -224,12 +224,12 @@ export default {
},
selectAll() {
this.selectedBuckets = this.buckets.map(bucket => bucket.id);
this.$emit('input', this.selectedBuckets);
this.$emit('update:modelValue', this.selectedBuckets);
this.$emit('change', this.selectedBuckets);
},
deselectAll() {
this.selectedBuckets = [];
this.$emit('input', this.selectedBuckets);
this.$emit('update:modelValue', this.selectedBuckets);
this.$emit('change', this.selectedBuckets);
},
getSelectedBucketLabel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export default {
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
this.$set(this.uploadProgress, i, percent);
this.uploadProgress[i] = percent;
// Update overall progress
let total = 0;
for (let j = 0; j < this.uploadProgress.length; j++) {
Expand All @@ -253,7 +253,7 @@ export default {
}
}
);
this.$set(this.uploadProgress, i, 100);
this.uploadProgress[i] = 100;
} catch (err) {
this.uploadError = `Failed to upload file: ${file.name}`;
break;
Expand Down
35 changes: 19 additions & 16 deletions assets/js/components-vue/MediaManagerV2/MultiSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,21 @@
</div>
</label>
<div class="option-actions" v-if="optionActions.length > 0">
<button
<template
v-for="(action, actionIndex) in optionActions"
:key="actionIndex"
v-if="action.condition ? action.condition(option) : true"
class="option-action-button"
:class="action.class"
@click.stop="handleOptionAction(action, option)"
:title="action.title"
>
<span v-if="action.icon" v-html="action.icon"></span>
<span v-else>{{ action.label }}</span>
</button>
<button
v-if="action.condition ? action.condition(option) : true"
class="option-action-button"
:class="action.class"
@click.stop="handleOptionAction(action, option)"
:title="action.title"
>
<span v-if="action.icon" v-html="action.icon"></span>
<span v-else>{{ action.label }}</span>
</button>
</template>
</div>
</div>
</div>
Expand All @@ -74,7 +77,7 @@
export default {
name: 'MultiSelect',
props: {
value: {
modelValue: {
type: Array,
default: () => []
},
Expand Down Expand Up @@ -137,20 +140,20 @@ export default {
}
},
created() {
this.selectedItems = [...this.value];
this.selectedItems = [...this.modelValue];
},
mounted() {
// Add global event listeners
document.addEventListener('keydown', this.handleKeydown);
// We'll add the click listener in toggleDropdown instead
},
beforeDestroy() {
beforeUnmount() {
// Remove global event listeners
document.removeEventListener('click', this.closeDropdown);
document.removeEventListener('keydown', this.handleKeydown);
},
watch: {
value: {
modelValue: {
handler(newVal) {
this.selectedItems = [...newVal];
},
Expand Down Expand Up @@ -226,18 +229,18 @@ export default {
this.selectedItems.splice(index, 1);
}
}
this.$emit('input', [...this.selectedItems]);
this.$emit('update:modelValue', [...this.selectedItems]);
},
selectAll() {
if (!this.singleSelect) {
this.selectedItems = this.filteredOptions.map(option => option.id);
this.$emit('input', [...this.selectedItems]);
this.$emit('update:modelValue', [...this.selectedItems]);
}
this.close(); // Use close() instead of closeDropdown() to ensure event listener is removed
},
deselectAll() {
this.selectedItems = [];
this.$emit('input', []);
this.$emit('update:modelValue', []);
this.close(); // Use close() instead of closeDropdown() to ensure event listener is removed
},
handleKeydown(event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default {
document.addEventListener('click', this.handleClickOutside);
document.addEventListener('keydown', this.handleKeydown);
},
beforeDestroy() {
beforeUnmount() {
document.removeEventListener('click', this.handleClickOutside);
document.removeEventListener('keydown', this.handleKeydown);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default {
document.addEventListener('click', this.handleClickOutside);
document.addEventListener('keydown', this.handleKeydown);
},
beforeDestroy() {
beforeUnmount() {
document.removeEventListener('click', this.handleClickOutside);
document.removeEventListener('keydown', this.handleKeydown);
},
Expand Down
86 changes: 35 additions & 51 deletions assets/js/components/MediaManagerV2.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import MediaManagerV2Vue from '../components-vue/MediaManagerV2.vue';
import ObjectListItem from '../components-vue/MediaManagerV2/ObjectListItem.vue';
import ObjectGridItem from '../components-vue/MediaManagerV2/ObjectGridItem.vue';
import MultiSelect from '../components-vue/MediaManagerV2/MultiSelect.vue';

class MediaManagerV2 {
constructor(adminController) {
Expand All @@ -13,7 +10,7 @@ class MediaManagerV2 {
waitForVue() {
return new Promise((resolve) => {
const checkVue = () => {
if (window.Vue) {
if (window.Vue && typeof window.Vue.createApp === 'function') {
resolve(window.Vue);
} else {
setTimeout(checkVue, 100);
Expand All @@ -31,63 +28,50 @@ class MediaManagerV2 {
this.adminController.log('Mounting MediaManagerV2');

// Get switch back URL from mount point
const switchBackUrl = mountPoint ? mountPoint.dataset.switchBackUrl : '';
const switchBackUrl = mountPoint.dataset.switchBackUrl || '';

// Get max upload size from mount point
const maxUploadSize = mountPoint ? parseInt(mountPoint.dataset.maxUploadSize) : 10485760; // Default to 10MB if not set
const maxUploadSize = parseInt(mountPoint.dataset.maxUploadSize) || 10485760; // Default to 10MB if not set

// User permissions
const userCanCreateObject = mountPoint ? mountPoint.dataset.userCanCreateObject === 'true' : false;
const userCanEditObject = mountPoint ? mountPoint.dataset.userCanEditObject === 'true' : false;
const userCanReplaceObject = mountPoint ? mountPoint.dataset.userCanReplaceObject === 'true' : false;
const userCanMoveObject = mountPoint ? mountPoint.dataset.userCanMoveObject === 'true' : false;
const userCanCopyObject = mountPoint ? mountPoint.dataset.userCanCopyObject === 'true' : false;
const userCanDeleteObject = mountPoint ? mountPoint.dataset.userCanDeleteObject === 'true' : false;
const userCanRestoreObject = mountPoint ? mountPoint.dataset.userCanRestoreObject === 'true' : false;
const userCanPurgeObject = mountPoint ? mountPoint.dataset.userCanPurgeObject === 'true' : false;
const userCanCreateBucket = mountPoint ? mountPoint.dataset.userCanCreateBucket === 'true' : false;
const userCanEditBucket = mountPoint ? mountPoint.dataset.userCanEditBucket === 'true' : false;
const userCanDeleteBucket = mountPoint ? mountPoint.dataset.userCanDeleteBucket === 'true' : false;
const userCanCreateObject = mountPoint.dataset.userCanCreateObject === 'true';
const userCanEditObject = mountPoint.dataset.userCanEditObject === 'true';
const userCanReplaceObject = mountPoint.dataset.userCanReplaceObject === 'true';
const userCanMoveObject = mountPoint.dataset.userCanMoveObject === 'true';
const userCanCopyObject = mountPoint.dataset.userCanCopyObject === 'true';
const userCanDeleteObject = mountPoint.dataset.userCanDeleteObject === 'true';
const userCanRestoreObject = mountPoint.dataset.userCanRestoreObject === 'true';
const userCanPurgeObject = mountPoint.dataset.userCanPurgeObject === 'true';
const userCanCreateBucket = mountPoint.dataset.userCanCreateBucket === 'true';
const userCanEditBucket = mountPoint.dataset.userCanEditBucket === 'true';
const userCanDeleteBucket = mountPoint.dataset.userCanDeleteBucket === 'true';

// System metadata keys (reserved, read-only in the editor)
const systemMetadataKeys = mountPoint
? JSON.parse(mountPoint.dataset.systemMetadataKeys || '[]')
: [];
const systemMetadataKeys = JSON.parse(mountPoint.dataset.systemMetadataKeys || '[]');

// Permitted dimensions for CKEditor image scaling
const permittedDimensions = mountPoint
? JSON.parse(mountPoint.dataset.permittedDimensions || '[]')
: [];
const permittedDimensions = JSON.parse(mountPoint.dataset.permittedDimensions || '[]');

// Create a new Vue instance with all components
new Vue({
el: '#nails-module-cdn-media-manager-v2',
components: {
MediaManagerV2Vue,
ObjectListItem,
ObjectGridItem,
MultiSelect
},
render: h => h(MediaManagerV2Vue, {
props: {
switchBackUrl,
maxUploadSize,
userCanCreateObject,
userCanEditObject,
userCanReplaceObject,
userCanMoveObject,
userCanCopyObject,
userCanDeleteObject,
userCanRestoreObject,
userCanPurgeObject,
userCanCreateBucket,
userCanEditBucket,
userCanDeleteBucket,
systemMetadataKeys,
permittedDimensions,
}
const { createApp, h } = Vue;
createApp({
render: () => h(MediaManagerV2Vue, {
switchBackUrl,
maxUploadSize,
userCanCreateObject,
userCanEditObject,
userCanReplaceObject,
userCanMoveObject,
userCanCopyObject,
userCanDeleteObject,
userCanRestoreObject,
userCanPurgeObject,
userCanCreateBucket,
userCanEditBucket,
userCanDeleteBucket,
systemMetadataKeys,
permittedDimensions,
})
});
}).mount('#nails-module-cdn-media-manager-v2');
} catch (error) {
this.adminController.log('Error initializing Vue:', error);
}
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@
"dependencies": {
"axios": "^1.20.0",
"lodash": "^4.17.21",
"vue": "^2.7.16",
"vue-loader": "^15.10.1",
"vue-template-compiler": "^2.7.16"
"vue": "^3.5.24",
"vue-loader": "^17.4.2"
},
"peerDependencies": {
"vue": "^2.7.16"
"vue": "^3.5.24"
}
}
2 changes: 1 addition & 1 deletion src/Admin/Controller/MediaManagerV2.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function index(): void

/** @var Asset $oAsset */
$oAsset = Factory::service('Asset');
$oAsset->vue2();
$oAsset->vue3();

Helper::loadView('index');
}
Expand Down
Loading
Loading