336 lines
14 KiB
JavaScript
Vendored
336 lines
14 KiB
JavaScript
Vendored
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;
|
||
}
|