import mediaLibrary from '../components/MediaLibrary'; import { get as fetchMedia, update as updateMediaDescription, destroy as deleteMedia, updateCategory as updateCategoryForMedia } from '../apis/admin/media-file'; import { index as fetchMediaCategories, destroy as deleteMediaCategory, add as addMediaCategory, update as updateMediaCategory, updateOrder as updateMediaCategoriesOrder } from '../apis/admin/media-category'; export default function(param) { // 如果有存在的媒體庫則先刪除 let previousElement = document.getElementById('media-library'); if (previousElement) { previousElement.remove(); } // new一個新的媒體庫結構 let mediaLibraryElement = document.createElement('media-library'); // 設定vue的子組件屬性映射 mediaLibraryElement.setAttribute(':_d', 'd') // 媒體庫元件append進body document.body.appendChild(mediaLibraryElement); // 初始化Vue let vue = new Vue({ el: mediaLibraryElement, data: { d: { // 文字翻譯 text: param.translations, // 上傳檔案的Url formAction: param.url, // csrf token csrfToken: param.csrfToken, // 是否為單選模式 single: param.single, // 是否顯示選擇按鈕 selectMode: param.selectMode, // 是否為上傳的頁面 isUploadingPage: false, // 媒體列表 medias: [], // 目前點選的媒體 currentSelectedMedia: false, // 選中的媒體列表 selectedMedias: [], // 最後一個取得的媒體ID lastFetchedMediaId: null, // 取得媒體請求的lock fetchingLock: false, // 已取的最後一個媒體 fetchingEnd: false, // 正在取得分類 categoryFetching: false, // 媒體資訊更新失敗訊息 infoErrorMessage: '', // 媒體資訊更新成功訊息 infoSuccessMessage: '', // 媒體分類 categories: [], // 目前正在拖曳的媒體ID currentDraggingMediaIds: null, // 目前所在的媒體分類 currentCategory: 'uncategorized', // 目前正在編輯的分類ID currentEditingCategory: null, // 目前正在編輯的分類輸入框文字 currentEditingCategoryText: '', // 目前正在新增分類 addingNewCategory: false, // 目前正在拖曳的媒體分類ID currentDraggingCategoryId: null, // 目前拖曳媒體分類的指示線 categoryDraggingIndicator: null, // 目前拖曳媒體分類過的媒體分類 currentDraggingOverCategoryId: null, // 分類更新成功訊息 categorySuccessMessage: '', // 分類更新失敗訊息 categoryErrorMessage: '', // 圖片更新成功訊息 imageSuccessMessage: '', // 圖片更新失敗訊息 imageErrorMessage: '', // 視窗高度 windowHeight: null, // 視窗寬度 windowWidth: null, // 手機板下用,只顯示分類 onlyShowCategory: false, // 手機板下用,只顯示媒體資訊 onlyShowMediaInfo: false, } }, computed: { component() { return this.$children[0]; } }, // Vue instance建立完後呼叫 created() { this.$on('resize', (height, width) => { this.d.windowHeight = height; this.d.windowWidth = width; }); // 預設先載入媒體資料 this.fetchMedia(35); // 監聽fetch_medias事件,載入媒體資料 this.$on('fetch_medias', (limit = null) => { this.fetchMedia(limit); }); // 媒體庫子組件觸發的事件,更新拖曳的媒體的分類 this.$on('update_category_for_medias', (mediaCategoryId, mediaIds, isUpdatingDraggingMedias = true) => { // ajax更新媒體的分類 updateCategoryForMedia(mediaIds, mediaCategoryId) .then(response => { let responseBody = response.data; // 被移動的媒體數量 let mediasMovedCount = responseBody.mediaIds.length; // 如果不是在all的分類下 if(this.d.currentCategory != 'all' && responseBody.categoryId != this.d.currentCategory) { // 將media從現有顯示的列表移除 responseBody.mediaIds.forEach((id, i) => { this.component.removeMediaFromList(id); }); } else { responseBody.mediaIds.forEach((id, i) => { this.component.updateCategoryForMedia(id, responseBody.categoryId); }); } for(let categoryId in responseBody.categorySources) { // 從原本分類的數量減去 this.component.substractCategoryCount(categoryId, responseBody.categorySources[categoryId], false); } // 加上數量至目標分類 this.component.addCategoryCount(responseBody.categoryId, mediasMovedCount, false); // 顯示訊息 if(isUpdatingDraggingMedias) { this.showImageMessage(responseBody); } else { this.showInfoMessage(responseBody); } }).catch(error => { // 顯示訊息 if(isUpdatingDraggingMedias) { this.showImageErrorMessage(error); } else { this.showInfoErrorMessage(error) } }); }) // 媒體庫子組件觸發的click事件,更新媒體的描述 this.$on('update_media_description', (e, media) => { // disable按鈕 e.target.disabled = true; // ajax更新媒體描述 updateMediaDescription(media.id, media.description) .then(response => { this.showInfoMessage(response.data); }) .catch(error => { this.showInfoErrorMessage(error); }) .finally(() => { // endable按鈕 e.target.disabled = false; }) }); // 媒體庫子組件觸發的click事件,刪除媒體 this.$on('delete_media', (e, media) => { if(confirm(this.d.text.deleteConfirmation)) { // disable按鈕 e.target.disabled = true; // ajax刪除媒體 deleteMedia(media.id) .then(response => { this.showInfoMessage(response.data); // 將媒體從列表移除 this.component.removeMediaFromList(response.data.id); this.component.substractCategoryCount(response.data.categoryId, 1); }) .catch(error => { this.showInfoErrorMessage(error); }) .finally(() => { // endable按鈕 e.target.disabled = false; }) } }); // ajax載入媒體分類 this.d.categoryFetching = true; fetchMediaCategories() .then(response => { this.d.categories = response.data.mediaCategories; }) .finally(() => { this.d.categoryFetching = false; }); // ajax更新媒體分類名稱 this.$on('update_category_name', (categoryId, name) => { if(name) { updateMediaCategory(categoryId, name) .then(response => { this.showCategoryMessage(response.data); // 更新列表分類名稱 this.component.updateListCategoryName(response.data.id, response.data.name); this.component.cancelCategoryEditing(); }) .catch(error => { this.showCategoryErrorMessage(error); }) } }) // ajax新增媒體分類 this.$on('add_category', name => { if(name) { addMediaCategory(name) .then(response => { this.showCategoryMessage(response.data); this.component.addCategoryToList(response.data.mediaCategory.id, response.data.mediaCategory.name); this.component.cancelCategoryEditing(); this.component.onCancelCategoryAdding(); }) .catch(error => { this.showCategoryErrorMessage(error); }) } }) // ajax刪除媒體分類 this.$on('delete_category', id => { deleteMediaCategory(id) .then(response => { this.showCategoryMessage(response.data); this.component.addCategoryCount('uncategorized', response.data.count, false); this.component.deleteCategoryFromList(response.data.id); }) .catch(error => { this.showCategoryErrorMessage(error) }) }); // ajax更新媒體分類順序 this.$on('update_category_order', ids => { updateMediaCategoriesOrder(ids) .catch(error => { this.showCategoryErrorMessage(error); }) }) }, components: { mediaLibrary }, methods: { // 載入媒體資料 fetchMedia(limit = null) { // 載入動作的lock,避免重複呼叫 this.d.fetchingLock = true; // ajax載入媒體資料 fetchMedia(this.d.currentCategory, this.d.lastFetchedMediaId, limit) .then(response => { let medias = response.data.medias; // 加入至原有列表 this.d.medias = this.d.medias.concat(medias); if(medias.length) { // 紀錄最後一筆媒體的id,供下次使用 this.d.lastFetchedMediaId = medias[medias.length - 1].id; } else { // 已載入至最後的資料 this.d.fetchingEnd = true; } }) .finally(() => { // 釋放載入動作的lock this.d.fetchingLock = false; }); }, // 根據response body顯示訊息 showInfoMessage(responseBody, success = true) { if(responseBody.hasOwnProperty('message')) { this.component.clearInfoMessages(); if(success) { this.component.showInfoSuccessMessage(responseBody.message); } else { this.component.showInfoErrorMessage(responseBody.message); } } }, // 根據error顯示訊息,只顯示http error showInfoErrorMessage(error) { if(error.hasOwnProperty('response')) { this.showInfoMessage(error.response.data, false); } }, // 根據response body顯示分類操作訊息 showCategoryMessage(responseBody, success = true) { if(responseBody.hasOwnProperty('message')) { this.component.clearCategoryMessages(); if(success) { this.component.showCategorySuccessMessage(responseBody.message); } else { this.component.showCategoryErrorMessage(responseBody.message); } } }, // 根據error顯示分類操作訊息,只顯示http error showCategoryErrorMessage(error) { if(error.hasOwnProperty('response')) { this.showCategoryMessage(error.response.data, false); } }, // 根據response body顯示圖片操作訊息 showImageMessage(responseBody, success = true) { if(responseBody.hasOwnProperty('message')) { this.component.clearImageMessages(); if(success) { this.component.showImageSuccessMessage(responseBody.message); } else { this.component.showImageErrorMessage(responseBody.message); } } }, // 根據error顯示圖片操作訊息,只顯示http error showImageErrorMessage(error) { if(error.hasOwnProperty('response')) { this.showImageMessage(error.response.data, false); } }, } }); return vue; }