From 39a22deb6a232356bf7b2ef8386679bc8ea2f697 Mon Sep 17 00:00:00 2001 From: vnugent Date: Fri, 10 Nov 2023 22:40:35 -0500 Subject: much needed QOL updates --- lib/admin/src/content/computedContent.ts | 14 +++++++++-- lib/admin/src/content/useContent.ts | 40 +++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 10 deletions(-) (limited to 'lib/admin/src/content') diff --git a/lib/admin/src/content/computedContent.ts b/lib/admin/src/content/computedContent.ts index 65c1537..75a25f8 100644 --- a/lib/admin/src/content/computedContent.ts +++ b/lib/admin/src/content/computedContent.ts @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import { Ref, computed } from "vue"; +import { Ref, computed, ref } from "vue"; import { find, filter, includes, isEqual, isNil, toLower } from 'lodash-es'; import { apiCall } from "@vnuge/vnlib.browser" import { ContentMeta, BlogEntity, ContentApi, ComputedBlogApi, BlogAdminContext } from "../types.js"; @@ -30,6 +30,10 @@ export interface ComputedContent extends ContentApi, ComputedBlogApi): Ref; + /** + * triggers a refresh of the content + */ + refresh(): void } /** @@ -41,11 +45,12 @@ export const useComputedContent = (context: BlogAdminContext): ComputedContent = //Get the content api from the context const contentApi = useContent(context); + const trigger = ref(0); const { content, post, channel } = context.getQuery(); //Watch for channel and selected id changes and get the content - const items = watchAndCompute([channel, content, post], async () => { + const items = watchAndCompute([channel, content, post, trigger], async () => { //Get all content if the channel is set, otherwise return empty array return channel.value ? await apiCall(contentApi.getAllContent) ?? [] : []; }, []); @@ -70,6 +75,10 @@ export const useComputedContent = (context: BlogAdminContext): ComputedContent = }) } + const refresh = () => { + trigger.value++; + } + return { ...contentApi, items, @@ -78,5 +87,6 @@ export const useComputedContent = (context: BlogAdminContext): ComputedContent = createReactiveSearch, selectedId: content, getQuery: context.getQuery, + refresh }; } diff --git a/lib/admin/src/content/useContent.ts b/lib/admin/src/content/useContent.ts index d23177c..47d27b8 100644 --- a/lib/admin/src/content/useContent.ts +++ b/lib/admin/src/content/useContent.ts @@ -13,8 +13,9 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import { includes, isEmpty } from 'lodash-es'; +import { includes, isArray, isEmpty, join, map } from 'lodash-es'; import { WebMessage } from "@vnuge/vnlib.browser" +import { AxiosRequestConfig } from 'axios'; import { PostMeta, ContentMeta, ContentApi, BlogEntity, BlogAdminContext } from "../types.js"; @@ -56,14 +57,14 @@ export const useContent = (context : BlogAdminContext): ContentApi => { * @param cotentId The id of the content to get the raw value of * @returns A promise that resolves to the raw content string */ - const getContent = async (cotentId: string): Promise => { + const _getContent = async (cotentId: string): Promise => { const url = getUrl(); const response = await axios.get(`${url}&id=${cotentId}`); return await response.data; } const getPostContent = async (post: BlogEntity): Promise => { - return await getContent(post.id); + return await _getContent(post.id); } const getAllContent = async (): Promise => { @@ -72,15 +73,31 @@ export const useContent = (context : BlogAdminContext): ContentApi => { return response.data; } - const deleteContent = async (content: ContentMeta): Promise => { + const deleteContent = async (content: ContentMeta | ContentMeta[]): Promise => { const url = getUrl(); - await axios.delete(`${url}&id=${content.id}`); + + if(isArray(content)){ + const ids = join(map(content, x => x.id)); + //bulk delete by setting multiple ids + const { data } = await axios.delete>(`${url}&ids=${ids}`); + + //Delete results returns a webmessage that contains the ids of the successfully deleted items + const deleted = data.getResultOrThrow(); + if(deleted.length !== content.length){ + throw { message: 'Some items failed to delete' } + } + } + else{ + await axios.delete(`${url}&id=${content.id}`); + } + } - const uploadContent = async (file: File, name: string): Promise => { + const uploadContent = async (file: File, name: string, config?:AxiosRequestConfig): Promise => { const url = getUrl(); //Endpoint returns the new content meta for the uploaded content const { data } = await axios.put>(url, file, { + ...config, headers: { 'Content-Type': getContentType(file), //Set the content name header as the supplied content name @@ -103,10 +120,11 @@ export const useContent = (context : BlogAdminContext): ContentApi => { return data.getResultOrThrow(); } - const updateContent = async (content: ContentMeta, data: File): Promise => { + const updateContent = async (content: ContentMeta, data: File, config?: AxiosRequestConfig): Promise => { const url = getUrl(); const response = await axios.put(`${url}&id=${content.id}`, data, { + ...config, headers: { 'Content-Type': getContentType(data), //Set the content name header as the supplied content name @@ -136,6 +154,11 @@ export const useContent = (context : BlogAdminContext): ContentApi => { return response.data.result; } + const getContent = async (id: string): Promise => { + const index = await getAllContent(); + return index.find(x => x.id === id); + } + return { getPostContent, getAllContent, @@ -144,6 +167,7 @@ export const useContent = (context : BlogAdminContext): ContentApi => { updateContentName, updatePostContent, updateContent, - getPublicUrl + getPublicUrl, + getContent }; } -- cgit