aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-11-10 22:40:35 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-11-10 22:40:35 -0500
commit39a22deb6a232356bf7b2ef8386679bc8ea2f697 (patch)
tree743eb0a0bb06a8ae85a36778c748880374798f01 /lib
parent00582bef545a912c2f81ea359dc00c92dd991ceb (diff)
much needed QOL updates
Diffstat (limited to 'lib')
-rw-r--r--lib/admin/src/content/computedContent.ts14
-rw-r--r--lib/admin/src/content/useContent.ts40
-rw-r--r--lib/admin/src/posts/computedPosts.ts12
-rw-r--r--lib/admin/src/types.ts22
4 files changed, 72 insertions, 16 deletions
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 <https://www.gnu.org/licenses/>.
-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<ContentMeta
* @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
}
/**
@@ -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 <https://www.gnu.org/licenses/>.
-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<string> => {
+ const _getContent = async (cotentId: string): Promise<string> => {
const url = getUrl();
const response = await axios.get(`${url}&id=${cotentId}`);
return await response.data;
}
const getPostContent = async (post: BlogEntity): Promise<string> => {
- return await getContent(post.id);
+ return await _getContent(post.id);
}
const getAllContent = async (): Promise<ContentMeta[]> => {
@@ -72,15 +73,31 @@ export const useContent = (context : BlogAdminContext): ContentApi => {
return response.data;
}
- const deleteContent = async (content: ContentMeta): Promise<void> => {
+ const deleteContent = async (content: ContentMeta | ContentMeta[]): Promise<void> => {
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<WebMessage<string[]>>(`${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<ContentMeta> => {
+ const uploadContent = async (file: File, name: string, config?:AxiosRequestConfig): Promise<ContentMeta> => {
const url = getUrl();
//Endpoint returns the new content meta for the uploaded content
const { data } = await axios.put<WebMessage<ContentMeta>>(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<ContentMeta> => {
+ const updateContent = async (content: ContentMeta, data: File, config?: AxiosRequestConfig): Promise<ContentMeta> => {
const url = getUrl();
const response = await axios.put<ContentMeta>(`${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<ContentMeta | undefined> => {
+ 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
};
}
diff --git a/lib/admin/src/posts/computedPosts.ts b/lib/admin/src/posts/computedPosts.ts
index 44171a5..640226f 100644
--- a/lib/admin/src/posts/computedPosts.ts
+++ b/lib/admin/src/posts/computedPosts.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 { computed } from "vue";
+import { computed, ref } from "vue";
import { isEqual, find } from 'lodash-es';
import { apiCall } from "@vnuge/vnlib.browser";
import { PostMeta, ComputedPosts, BlogAdminContext } from "../types";
@@ -28,11 +28,12 @@ import { watchAndCompute } from "../helpers";
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], async () => {
+ const items = watchAndCompute([channel, post, trigger], async () => {
return channel.value ? await apiCall(postApi.getPosts) ?? [] : [];
}, [])
@@ -40,11 +41,16 @@ export const useComputedPosts = (context: BlogAdminContext): ComputedPosts => {
return find(items.value, p => isEqual(p.id, post.value));
})
+ const refresh = () => {
+ trigger.value++;
+ }
+
return {
...postApi,
items,
selectedItem,
selectedId:post,
- getQuery: context.getQuery
+ getQuery: context.getQuery,
+ refresh
};
} \ No newline at end of file
diff --git a/lib/admin/src/types.ts b/lib/admin/src/types.ts
index f03c008..60b0064 100644
--- a/lib/admin/src/types.ts
+++ b/lib/admin/src/types.ts
@@ -14,7 +14,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { UseOffsetPaginationReturn } from '@vueuse/core';
-import { AxiosInstance } from 'axios';
+import { AxiosInstance, AxiosRequestConfig } from 'axios';
import { Dictionary } from 'lodash';
import { Ref } from 'vue';
@@ -185,17 +185,29 @@ export interface ContentApi {
*/
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
* @returns A promise that resolves to the content meta object for the uploaded content
*/
- uploadContent(data: File, name: string): Promise<ContentMeta>;
+ uploadContent(data: File, name: string, config?: AxiosRequestConfig): Promise<ContentMeta>;
/**
* Updates the content for a post in the current channel
* @param post The post to update the content for
@@ -221,7 +233,7 @@ export interface ContentApi {
* @param content The content meta object to update
* @param data The new content data file
*/
- updateContent(content: ContentMeta, data: File): Promise<ContentMeta>;
+ updateContent(content: ContentMeta, data: File, config?:AxiosRequestConfig): Promise<ContentMeta>;
}
/**
@@ -244,6 +256,10 @@ export interface ComputedBlogApi<T> extends CanPaginate<T>{
}
export interface ComputedPosts extends PostApi, ComputedBlogApi<PostMeta> {
+ /**
+ * Triggers a refresh of the posts
+ */
+ refresh(): void;
}
/**