aboutsummaryrefslogtreecommitdiff
path: root/lib/admin/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/admin/src')
-rw-r--r--lib/admin/src/channels/computedChannels.ts65
-rw-r--r--lib/admin/src/channels/index.ts3
-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.ts92
-rw-r--r--lib/admin/src/content/index.ts3
-rw-r--r--lib/admin/src/content/useContent.ts31
-rw-r--r--lib/admin/src/index.ts60
-rw-r--r--lib/admin/src/ordering/index.ts4
-rw-r--r--lib/admin/src/posts/computedPosts.ts56
-rw-r--r--lib/admin/src/posts/index.ts3
-rw-r--r--lib/admin/src/posts/usePost.ts68
-rw-r--r--lib/admin/src/types.ts163
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