aboutsummaryrefslogtreecommitdiff
path: root/lib/admin/src/content/computedContent.ts
blob: 65c15370d380ee32ece2fbb67b1af076e602df8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// 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 } 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>;
}

/**
 * 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 { content, post, channel } = context.getQuery();

    //Watch for channel and selected id changes and get the content
    const items = watchAndCompute([channel, content, post], 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)));
        })
    }

    return {
        ...contentApi,
        items,
        selectedItem,
        getSelectedPostContent,
        createReactiveSearch,
        selectedId: content,
        getQuery: context.getQuery,
    };
}