diff options
Diffstat (limited to 'lib/admin/src')
-rw-r--r-- | lib/admin/src/channels/computedChannels.ts | 65 | ||||
-rw-r--r-- | lib/admin/src/channels/index.ts | 3 | ||||
-rw-r--r-- | lib/admin/src/channels/useChannels.ts (renamed from lib/admin/src/channels/channels.ts) | 51 | ||||
-rw-r--r-- | lib/admin/src/content/computedContent.ts | 92 | ||||
-rw-r--r-- | lib/admin/src/content/index.ts | 3 | ||||
-rw-r--r-- | lib/admin/src/content/useContent.ts | 31 | ||||
-rw-r--r-- | lib/admin/src/index.ts | 60 | ||||
-rw-r--r-- | lib/admin/src/ordering/index.ts | 4 | ||||
-rw-r--r-- | lib/admin/src/posts/computedPosts.ts | 56 | ||||
-rw-r--r-- | lib/admin/src/posts/index.ts | 3 | ||||
-rw-r--r-- | lib/admin/src/posts/usePost.ts | 68 | ||||
-rw-r--r-- | lib/admin/src/types.ts | 163 |
12 files changed, 160 insertions, 439 deletions
diff --git a/lib/admin/src/channels/computedChannels.ts b/lib/admin/src/channels/computedChannels.ts deleted file mode 100644 index dbf7cd5..0000000 --- a/lib/admin/src/channels/computedChannels.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2023 Vaughn Nugent -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -import { apiCall } from '@vnuge/vnlib.browser'; -import { Ref, computed, ref, watch } from 'vue' -import { find, isEmpty, isEqual } from 'lodash-es'; -import { BlogChannel, ChannelApi, ComputedBlogApi, BlogAdminContext } from '../types.js' -import { useChannels } from './channels.js'; - -export interface ComputedChannels extends ChannelApi, ComputedBlogApi<BlogChannel> { - readonly editChannel: Readonly<Ref<BlogChannel | undefined>>; -} - -/** - * Create a computed channels object to manage channels - * @param channelUrl the path to the channel api - * @returns The computed channels object - */ -export const useComputedChannels = (context: BlogAdminContext): ComputedChannels => { - - const channels = useChannels(context) - const { channel, channelEdit } = context.getQuery() - - const items = ref<BlogChannel[]>([]); - - const loadChannels = async () => { - items.value = await apiCall(channels.getChannels) ?? []; - } - - const selectedItem = computed<BlogChannel | undefined>(() => { - return find(items.value, c => isEqual(c.id, channel.value)); - }); - - const editChannel = computed<BlogChannel | undefined>(() => { - return find(items.value, c => isEqual(c.id, channelEdit.value)); - }) - - //Initial load - loadChannels(); - - //Load channels when the edit id changes to empty - watch(channelEdit, (newId) => isEmpty(newId) ? loadChannels() : null); - - return { - ...channels, - items, - selectedItem, - editChannel, - selectedId:channel, - getQuery: context.getQuery, - } -} - diff --git a/lib/admin/src/channels/index.ts b/lib/admin/src/channels/index.ts index d45eb72..8a14ab3 100644 --- a/lib/admin/src/channels/index.ts +++ b/lib/admin/src/channels/index.ts @@ -13,5 +13,4 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -export * from './channels' -export * from './computedChannels'
\ No newline at end of file +export * from './useChannels'
\ No newline at end of file diff --git a/lib/admin/src/channels/channels.ts b/lib/admin/src/channels/useChannels.ts index 3efb6b7..b9201b3 100644 --- a/lib/admin/src/channels/channels.ts +++ b/lib/admin/src/channels/useChannels.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 <https://www.gnu.org/licenses/>. -import { isEqual, toSafeInteger } from 'lodash-es'; +import { isArray, isEqual, toSafeInteger } from 'lodash-es'; import { BlogChannel, ChannelFeed, ChannelApi, BlogAdminContext } from '../types.js' /** @@ -31,29 +31,40 @@ export const useChannels = (context: BlogAdminContext): ChannelApi => { return channel; } - const getChannels = async (): Promise<BlogChannel[]> => { - const { data } = await axios.get(getUrl()); - return data; - } - const deleteChannel = async (channel: BlogChannel) => { //Call delete with the channel id query await axios.delete(`${getUrl()}?channel=${channel.id}`); } - const addChannel = async (channel: BlogChannel, feed?: ChannelFeed): Promise<BlogChannel> => { - //Clone the item to avoid modifying the original - const add = sanitizeNumbers({ ...channel, feed }); - //Call post with the channel data - return await axios.post(getUrl(), add); - } - - const updateChannel = async (channel: BlogChannel, feed?: ChannelFeed): Promise<BlogChannel> => { - //Manually assign the feed or null, and clone the item to avoid modifying the original - const update = sanitizeNumbers({ ...channel, feed }); - //Call put with the channel data - return await axios.patch(getUrl(), update); - } + return { + async getAllItems() { + const { data } = await axios.get(getUrl()); + return data; + }, + + async add(item: BlogChannel, feed?: ChannelFeed) { + //Clone the item to avoid modifying the original + const add = sanitizeNumbers({ ...item, feed }); + //Call post with the channel data + return await axios.post(getUrl(), add); + }, - return { getChannels, deleteChannel, addChannel, updateChannel }; + async update(item: BlogChannel, feed?: ChannelFeed){ + //Manually assign the feed or null, and clone the item to avoid modifying the original + const update = sanitizeNumbers({ ...item, feed }); + //Call put with the channel data + return await axios.patch(getUrl(), update); + }, + + async delete(item: BlogChannel | BlogChannel[]){ + //invoke delete for each item + if(isArray(item)){ + await Promise.all(item.map(deleteChannel)); + } + else{ + //Call delete with the channel id query + await deleteChannel(item) + } + }, + }; } diff --git a/lib/admin/src/content/computedContent.ts b/lib/admin/src/content/computedContent.ts deleted file mode 100644 index 75a25f8..0000000 --- a/lib/admin/src/content/computedContent.ts +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2023 Vaughn Nugent -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -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"; -import { watchAndCompute } from "../helpers.js"; -import { useContent } from "./useContent.js"; - -export interface ComputedContent extends ContentApi, ComputedBlogApi<ContentMeta> { - /** - * Gets the raw content for a the currently selected post - */ - getSelectedPostContent(): Promise<string | undefined>; - /** - * Filter post items by the given reactive filter - * @param filter The reactive filter used to filter the content - */ - createReactiveSearch(filter: Ref<string>): Ref<ContentMeta[] | undefined>; - /** - * triggers a refresh of the content - */ - refresh(): void -} - -/** - * Gets a computed object with the content and selected content - * @param context The blog admin context - * @returns A computed object with the content and selected content - */ -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, trigger], async () => { - //Get all content if the channel is set, otherwise return empty array - return channel.value ? await apiCall(contentApi.getAllContent) ?? [] : []; - }, []); - - const selectedItem = computed<ContentMeta | undefined>(() => { - if (!isNil(channel.value) && content.value && content.value !== 'new') { - return find(items.value, c => isEqual(c.id, content.value)); - } - return {} as ContentMeta; - }) - - const getSelectedPostContent = async (): Promise<string | undefined> => { - if (!isNil(channel.value) && post.value && post.value !== 'new') { - return await apiCall(() => contentApi.getPostContent({ id: post.value } as BlogEntity)); - } - return ''; - } - - const createReactiveSearch = (sec: Ref<string>): Ref<ContentMeta[] | undefined> => { - return computed(() => { - return filter(items.value, c => includes(toLower(c.name), toLower(sec.value)) || includes(toLower(c.id), toLower(sec.value))); - }) - } - - const refresh = () => { - trigger.value++; - } - - return { - ...contentApi, - items, - selectedItem, - getSelectedPostContent, - createReactiveSearch, - selectedId: content, - getQuery: context.getQuery, - refresh - }; -} diff --git a/lib/admin/src/content/index.ts b/lib/admin/src/content/index.ts index 802c002..d014136 100644 --- a/lib/admin/src/content/index.ts +++ b/lib/admin/src/content/index.ts @@ -13,5 +13,4 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -export * from './useContent' -export * from './computedContent'
\ No newline at end of file +export * from './useContent'
\ No newline at end of file diff --git a/lib/admin/src/content/useContent.ts b/lib/admin/src/content/useContent.ts index 47d27b8..f125b54 100644 --- a/lib/admin/src/content/useContent.ts +++ b/lib/admin/src/content/useContent.ts @@ -14,9 +14,11 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. 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"; +import { get } from '@vueuse/core'; +import { type WebMessage } from "@vnuge/vnlib.browser" +import { type AxiosRequestConfig } from 'axios'; +import { type MaybeRef } from 'vue'; +import type { PostMeta, ContentMeta, ContentApi, BlogEntity, BlogAdminContext } from "../types"; /** @@ -25,15 +27,13 @@ import { PostMeta, ContentMeta, ContentApi, BlogEntity, BlogAdminContext } from * @param channel The channel to get the content for * @returns A content api object */ -export const useContent = (context : BlogAdminContext): ContentApi => { +export const useContent = (context : BlogAdminContext, channel: MaybeRef<string>): ContentApi => { const axios = context.getAxios(); - const { channel } = context.getQuery(); - const getUrl = (): string => { const url = context.getContentUrl(); //Return the url with the channel id query - return `${url}?channel=${channel.value}`; + return `${url}?channel=${get(channel)}`; } const getContentType = (file: File): string => { @@ -67,7 +67,7 @@ export const useContent = (context : BlogAdminContext): ContentApi => { return await _getContent(post.id); } - const getAllContent = async (): Promise<ContentMeta[]> => { + const getAllItems = async (): Promise<ContentMeta[]> => { const url = getUrl(); const response = await axios.get<ContentMeta[]>(url); return response.data; @@ -155,19 +155,26 @@ export const useContent = (context : BlogAdminContext): ContentApi => { } const getContent = async (id: string): Promise<ContentMeta | undefined> => { - const index = await getAllContent(); + const index = await getAllItems(); return index.find(x => x.id === id); } + const downloadContent = async (content: ContentMeta): Promise<Blob> => { + const url = getUrl(); + const { data } = await axios.get(`${url}&id=${content.id}`, { responseType: 'blob' }); + return data; + } + return { getPostContent, - getAllContent, - deleteContent, + getAllItems, + delete:deleteContent, uploadContent, updateContentName, updatePostContent, updateContent, getPublicUrl, - getContent + getContent, + downloadContent, }; } diff --git a/lib/admin/src/index.ts b/lib/admin/src/index.ts index 7733f5c..61d2c63 100644 --- a/lib/admin/src/index.ts +++ b/lib/admin/src/index.ts @@ -14,71 +14,36 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. //Export apis and types -export * from './types'; + export * from './ordering' export * from './feedProperties' -export * from './posts' -export * from './content' -export * from './channels' +export { usePosts } from './posts' +export { useContent } from './content' +export { useChannels } from './channels' + +export type * from './types'; -import { MaybeRef } from "vue"; import { get } from '@vueuse/core' -import { useRouteQuery } from "@vueuse/router"; -import { QueryState, QueryType, SortType, BlogAdminContext } from "./types"; -import { RouteLocationNormalized, Router } from 'vue-router'; -import { AxiosInstance } from 'axios'; +import type { MaybeRef } from "vue"; +import type { BlogAdminContext } from "./types"; +import type { Axios } from 'axios'; export interface BlogAdminConfig { - readonly axios: AxiosInstance; - readonly router: Router; - readonly route: RouteLocationNormalized; + readonly axios: Axios; readonly postUrl: MaybeRef<string>; readonly contentUrl: MaybeRef<string>; readonly channelUrl: MaybeRef<string>; readonly defaultPageSize?: number; } -const createQueryState = (router :Router , route : RouteLocationNormalized): QueryState => { - - //setup filter search query - const search = useRouteQuery<string>(QueryType.Filter, '', { mode: 'replace', route, router }); - - //Get sort order query - const sort = useRouteQuery<SortType>(QueryType.Sort, SortType.CreatedTime, { mode: 'replace', route, router }); - - //Selected channel id - const channel = useRouteQuery<string>(QueryType.Channel, '', { mode: 'replace', route, router }); - - //Edits are in push mode because they are used to navigate to edit pages - - const channelEdit = useRouteQuery<string>(QueryType.ChannelEdit, '', { mode: 'push', route, router }); - - const content = useRouteQuery<string>(QueryType.Content, '', { mode: 'push', route, router }); - //Get the selected post id from the route - const post = useRouteQuery<string>(QueryType.Post, '', { mode: 'push', route, router }); - - return { - post, - channel, - content, - channelEdit, - search, - sort - } -} - /** * Create a blog context object from the given configuration * @param param0 The blog configuration object * @returns A blog context object to pass to the blog admin components */ -export const createBlogContext = ({ channelUrl, postUrl, contentUrl, router, route, axios }: BlogAdminConfig): BlogAdminContext => { - - const queryState = createQueryState(router, route); - - const getQuery = (): QueryState => queryState; +export const createBlogContext = ({ channelUrl, postUrl, contentUrl, axios }: BlogAdminConfig): BlogAdminContext => { - const getAxios = () : AxiosInstance => axios; + const getAxios = (): Axios => axios; const getPostUrl = (): string => get(postUrl) @@ -88,7 +53,6 @@ export const createBlogContext = ({ channelUrl, postUrl, contentUrl, router, rou return{ getAxios, - getQuery, getPostUrl, getChannelUrl, getContentUrl, diff --git a/lib/admin/src/ordering/index.ts b/lib/admin/src/ordering/index.ts index a2f266f..c252573 100644 --- a/lib/admin/src/ordering/index.ts +++ b/lib/admin/src/ordering/index.ts @@ -16,7 +16,7 @@ import { MaybeRefOrGetter, computed } from 'vue'; import { useOffsetPagination } from '@vueuse/core'; import { filter, includes, isEmpty, orderBy, slice, toLower } from 'lodash-es'; -import { CanPaginate, NamedBlogEntity, SortedFilteredPaged } from '../types'; +import type { CanPaginate, NamedBlogEntity, SortedFilteredPaged } from '../types'; /** * Allows filtering, sorting, and paginating a collection of blog items @@ -26,7 +26,7 @@ import { CanPaginate, NamedBlogEntity, SortedFilteredPaged } from '../types'; export const useFilteredPages = <T extends NamedBlogEntity>(pageable: CanPaginate<T>, pageSize: MaybeRefOrGetter<number>): SortedFilteredPaged<T> => { //Get filterable items, and the query state to filter by - const { sort, search } = pageable.getQuery(); + const { sort, search } = pageable; const filtered = computed<T[]>(() => { diff --git a/lib/admin/src/posts/computedPosts.ts b/lib/admin/src/posts/computedPosts.ts deleted file mode 100644 index 640226f..0000000 --- a/lib/admin/src/posts/computedPosts.ts +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2023 Vaughn Nugent -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -import { computed, ref } from "vue"; -import { isEqual, find } from 'lodash-es'; -import { apiCall } from "@vnuge/vnlib.browser"; -import { PostMeta, ComputedPosts, BlogAdminContext } from "../types"; -import { usePostApi } from "./usePost"; -import { watchAndCompute } from "../helpers"; - -/** - * Creates a computed post api for reactive blog apis - * @param context The blog admin context - * @returns The computed post api - */ -export const useComputedPosts = (context: BlogAdminContext): ComputedPosts => { - //Post api around the post url and channel - const postApi = usePostApi(context); - const trigger = ref(0); - - const { channel, post } = context.getQuery(); - - //Get all posts - const items = watchAndCompute([channel, post, trigger], async () => { - return channel.value ? await apiCall(postApi.getPosts) ?? [] : []; - }, []) - - const selectedItem = computed<PostMeta | undefined>(() => { - return find(items.value, p => isEqual(p.id, post.value)); - }) - - const refresh = () => { - trigger.value++; - } - - return { - ...postApi, - items, - selectedItem, - selectedId:post, - getQuery: context.getQuery, - refresh - }; -}
\ No newline at end of file diff --git a/lib/admin/src/posts/index.ts b/lib/admin/src/posts/index.ts index 0105265..9bb70d4 100644 --- a/lib/admin/src/posts/index.ts +++ b/lib/admin/src/posts/index.ts @@ -13,5 +13,4 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -export * from './usePost' -export * from './computedPosts'
\ No newline at end of file +export * from './usePost'
\ No newline at end of file diff --git a/lib/admin/src/posts/usePost.ts b/lib/admin/src/posts/usePost.ts index 1d93b6b..421ff83 100644 --- a/lib/admin/src/posts/usePost.ts +++ b/lib/admin/src/posts/usePost.ts @@ -14,28 +14,23 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. import { isArray, orderBy } from 'lodash-es'; -import { WebMessage } from "@vnuge/vnlib.browser" -import { PostMeta, PostApi, BlogAdminContext } from "../types"; +import { get } from '@vueuse/core'; +import { type WebMessage } from "@vnuge/vnlib.browser" +import { type MaybeRef } from 'vue'; +import type { PostMeta, PostApi, BlogAdminContext } from "../types"; /** * Gets a reactive post api for the given channel * @param context The blog admin context * @returns The configured post api */ -export const usePostApi = (context : BlogAdminContext): PostApi => { +export const usePosts = (context: BlogAdminContext, channel: MaybeRef<string>): PostApi => { const axios = context.getAxios(); - const { channel } = context.getQuery(); - const getUrl = (): string => { const url = context.getPostUrl(); //Return the url with the channel id query - return `${url}?channel=${channel.value}`; - } - - const getPosts = async (): Promise<PostMeta[]> => { - const { data } = await axios.get(getUrl()); - return isArray(data) ? orderBy(data, 'date', 'desc') : []; + return `${url}?channel=${get(channel)}`; } const deletePost = (post: PostMeta): Promise<void> => { @@ -43,28 +38,39 @@ export const usePostApi = (context : BlogAdminContext): PostApi => { return axios.delete(`${getUrl()}&post=${post.id}`); } - const publishPost = async (post: PostMeta): Promise<PostMeta> => { - //Call post with the post data - const { data } = await axios.post<WebMessage<PostMeta>>(getUrl(), post); - return data.getResultOrThrow(); - } + return { + + async delete(item: PostMeta | PostMeta[]){ + //invoke delete for each item + if(isArray(item)){ + await Promise.all(item.map(deletePost)); + } + else{ + //Call delete with the post id query + await deletePost(item) + } + }, - const updatePost = async (post: PostMeta): Promise<PostMeta> => { - //Call patch with the updated post content, must have an id set as an existing post - const { data } = await axios.patch<WebMessage<PostMeta>>(getUrl(), post); - return data.getResultOrThrow(); - } + async add(item: PostMeta) { + //Call post with the post data + const { data } = await axios.post<WebMessage<PostMeta>>(getUrl(), item); + return data.getResultOrThrow(); + }, - const getSinglePost = async (postId: string): Promise<PostMeta> => { - const { data } = await axios.get(`${getUrl()}&post=${postId}`); - return data; - } + async getAllItems(){ + const { data } = await axios.get(getUrl()); + return isArray(data) ? orderBy(data, 'date', 'desc') : []; + }, - return { - getPosts, - deletePost, - publishPost, - updatePost, - getSinglePost + async update(item: PostMeta) { + //Call patch with the updated post content, must have an id set as an existing post + const { data } = await axios.patch<WebMessage<PostMeta>>(getUrl(), item); + return data.getResultOrThrow(); + }, + + async getSinglePost(postId: string) { + const { data } = await axios.get(`${getUrl()}&post=${postId}`); + return data; + } }; }
\ No newline at end of file diff --git a/lib/admin/src/types.ts b/lib/admin/src/types.ts index 60b0064..e352d34 100644 --- a/lib/admin/src/types.ts +++ b/lib/admin/src/types.ts @@ -13,25 +13,10 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -import { UseOffsetPaginationReturn } from '@vueuse/core'; -import { AxiosInstance, AxiosRequestConfig } from 'axios'; -import { Dictionary } from 'lodash'; -import { Ref } from 'vue'; - -export enum QueryType { - Post = 'post', - Channel = 'channel', - Content = 'content', - ChannelEdit = 'ecid', - Filter = 'filter', - Sort = 'sort', - PageSize = 'size', -} - -export enum SortType { - CreatedTime = 'created', - ModifiedTime = 'date', -} +import type { UseOffsetPaginationReturn } from '@vueuse/core'; +import type { Axios, AxiosRequestConfig } from 'axios'; +import type { Dictionary } from 'lodash'; +import type { Ref } from 'vue'; /** * A base blog entity that has a globally unique id and a date @@ -110,60 +95,46 @@ export interface PostMeta extends NamedBlogEntity, XmlPropertyContainer { html_description?: string; } -/** - * Represents the channel api and its operations - */ -export interface ChannelApi { - /** - * Gets all blog channels from the server - * @returns An array of blog channels - */ - getChannels: () => Promise<BlogChannel[]>; +export interface BlogApi<T extends BlogEntity> { /** - * Delets a blog channel from the catalog - * @param channel The channel to delete + * Gets all blog entities from the server + * @returns An array of entities */ - deleteChannel: (channel: BlogChannel) => Promise<void>; + getAllItems(): Promise<T[]>; + /** - * Adds a channel to the catalog - * @param channel The channel to add + * Deletes an entity from the server + * @param item The entity to delete */ - addChannel: (channel: BlogChannel, feed?: ChannelFeed) => Promise<BlogChannel>; + delete(item: T): Promise<void>; + /** - * Updates a channel in the catalog - * @param channel The channel to update + * Deletes an array of entities from the server + * @param item The entities to delete */ - updateChannel: (channel: BlogChannel, feed?: ChannelFeed) => Promise<BlogChannel>; -} + delete(item: T[]): Promise<void>; -export interface PostApi { /** - * Gets all blog posts from the server - * @param channel The channel to get posts from - * @returns An array of blog posts - */ - getPosts: () => Promise<PostMeta[]>; - /** - * Deletes a post from the given channel by its id - * @param channel The channel the post belongs to - * @param post The post to delete - * @returns The response from the server + * Adds an entity to the server + * @param item The entity to add */ - deletePost: (post: PostMeta) => Promise<void>; + add(item: T): Promise<T>; + /** - * Publishes a new post to the given channel - * @param channel The blog channel to publish to - * @param post The post to publish - * @returns The response from the server + * Updates an entity on the server + * @param item The entity to update */ - publishPost: (post: PostMeta) => Promise<PostMeta>; - /** - * Updates a post in the given channel - * @param channel The channel the post belongs to - * @param post The post to update - * @returns The response from the server - */ - updatePost: (post: PostMeta) => Promise<PostMeta>; + update(item: T): Promise<T>; +} + +/** + * Represents the channel api and its operations + */ +export interface ChannelApi extends BlogApi<BlogChannel> { + add(item: BlogChannel, feed?: ChannelFeed): Promise<BlogChannel>; +} + +export interface PostApi extends BlogApi<PostMeta> { /** * Gets the post meta data for a single post by its id * @param postId The id of the post to get @@ -174,34 +145,33 @@ export interface PostApi { export interface ContentApi { /** + * Gets all blog entities from the server + * @returns An array of entities + */ + getAllItems(): Promise<ContentMeta[]>; + /** + * Deletes an entity from the server + * @param item The entity to delete + */ + delete(item: ContentMeta): Promise<void>; + /** + * Deletes an array of entities from the server + * @param item The entities to delete + */ + delete(item: ContentMeta[]): Promise<void>; + /** * Gets the content for a post as text * @param post The post to get the content for * @returns A promise that resolves to the content string */ getPostContent(post: BlogEntity): Promise<string>; /** - * Gets all content meta objects for the current channel - * @returns A promise that resolves to an array of content meta objects - */ - getAllContent(): Promise<ContentMeta[]>; - /** * Gets a single content meta object by its id * @param id The id of the content meta object to get * @returns A promise that resolves to the content meta object */ getContent(id: string): Promise<ContentMeta | undefined>; /** - * Deletes a content meta object from the server in the current channel - * @param content The content meta object to delete - * @returns A promise that resolves when the content has been deleted - */ - deleteContent(content: ContentMeta): Promise<void>; - /** - * Deletes an array of content meta objects from the server in the current channel - * @param content The content items to delete - */ - deleteContent(content: ContentMeta[]): Promise<void>; - /** * Uploads a content file to the server in the current channel * @param content The content file to upload * @param name The name of the content file @@ -234,6 +204,11 @@ export interface ContentApi { * @param data The new content data file */ updateContent(content: ContentMeta, data: File, config?:AxiosRequestConfig): Promise<ContentMeta>; + /** + * Downloads the content data file for the given content meta object + * @param content The content meta object to download + */ + downloadContent(content: ContentMeta): Promise<Blob>; } /** @@ -244,46 +219,20 @@ export interface CanPaginate<T> { * A reactive collection of items within the store */ readonly items: Readonly<Ref<T[]>>; - /** - * Gets the global query state - */ - getQuery(): Readonly<QueryState> -} - -export interface ComputedBlogApi<T> extends CanPaginate<T>{ - readonly selectedId: Ref<string>; - readonly selectedItem : Readonly<Ref<T | undefined>>; -} -export interface ComputedPosts extends PostApi, ComputedBlogApi<PostMeta> { - /** - * Triggers a refresh of the posts - */ - refresh(): void; -} + readonly sort: Readonly<Ref<string>>; -/** - * The current state of the query - */ -export interface QueryState { - readonly post: Ref<string>; - readonly channel: Ref<string>; - readonly content: Ref<string>; - readonly channelEdit: Ref<string>; - readonly search: Ref<string>; - readonly sort: Ref<SortType>; + readonly search: Readonly<Ref<string>>; } - export interface SortedFilteredPaged<T>{ readonly items : Readonly<Ref<T[]>>; readonly pagination: UseOffsetPaginationReturn; } export interface BlogAdminContext { - getQuery(): QueryState; getPostUrl(): string; getContentUrl(): string; getChannelUrl(): string; - getAxios(): AxiosInstance; + getAxios(): Axios; }
\ No newline at end of file |