mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
refactor(editor): Migrate templates.store
to composition API (#11641)
This commit is contained in:
parent
d55d066bf3
commit
aec372793b
|
@ -141,6 +141,10 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
|
|||
const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS);
|
||||
const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS);
|
||||
|
||||
const websiteCategoryURL = templatesStore.websiteTemplateRepositoryParameters;
|
||||
|
||||
websiteCategoryURL.append('utm_user_role', 'AdvancedAI');
|
||||
|
||||
return {
|
||||
value: AI_NODE_CREATOR_VIEW,
|
||||
title: i18n.baseText('nodeCreator.aiPanel.aiNodes'),
|
||||
|
@ -154,7 +158,7 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
|
|||
icon: 'box-open',
|
||||
description: i18n.baseText('nodeCreator.aiPanel.linkItem.description'),
|
||||
name: 'ai_templates_root',
|
||||
url: templatesStore.getWebsiteCategoryURL(undefined, 'AdvancedAI'),
|
||||
url: websiteCategoryURL.toString(),
|
||||
tag: {
|
||||
type: 'info',
|
||||
text: i18n.baseText('nodeCreator.triggerHelperPanel.manualTriggerTag'),
|
||||
|
|
|
@ -6,24 +6,17 @@ import type {
|
|||
ITemplatesCollection,
|
||||
ITemplatesCollectionFull,
|
||||
ITemplatesQuery,
|
||||
ITemplateState,
|
||||
ITemplatesWorkflow,
|
||||
ITemplatesWorkflowFull,
|
||||
IWorkflowTemplate,
|
||||
} from '@/Interface';
|
||||
import { useSettingsStore } from './settings.store';
|
||||
import {
|
||||
getCategories,
|
||||
getCollectionById,
|
||||
getCollections,
|
||||
getTemplateById,
|
||||
getWorkflows,
|
||||
getWorkflowTemplate,
|
||||
} from '@/api/templates';
|
||||
import * as templatesApi from '@/api/templates';
|
||||
import { getFixedNodesList } from '@/utils/nodeViewUtils';
|
||||
import { useRootStore } from '@/stores/root.store';
|
||||
import { useUsersStore } from './users.store';
|
||||
import { useWorkflowsStore } from './workflows.store';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
const TEMPLATES_PAGE_SIZE = 20;
|
||||
|
||||
|
@ -33,398 +26,424 @@ function getSearchKey(query: ITemplatesQuery): string {
|
|||
|
||||
export type TemplatesStore = ReturnType<typeof useTemplatesStore>;
|
||||
|
||||
export const useTemplatesStore = defineStore(STORES.TEMPLATES, {
|
||||
state: (): ITemplateState => ({
|
||||
categories: [],
|
||||
collections: {},
|
||||
workflows: {},
|
||||
collectionSearches: {},
|
||||
workflowSearches: {},
|
||||
currentSessionId: '',
|
||||
previousSessionId: '',
|
||||
currentN8nPath: `${window.location.protocol}//${window.location.host}${window.BASE_PATH}`,
|
||||
}),
|
||||
getters: {
|
||||
allCategories(): ITemplatesCategory[] {
|
||||
return Object.values(this.categories).sort((a: ITemplatesCategory, b: ITemplatesCategory) =>
|
||||
a.name > b.name ? 1 : -1,
|
||||
);
|
||||
},
|
||||
getTemplateById() {
|
||||
return (id: string): null | ITemplatesWorkflow => this.workflows[id];
|
||||
},
|
||||
getFullTemplateById() {
|
||||
return (id: string): null | ITemplatesWorkflowFull => {
|
||||
const template = this.workflows[id];
|
||||
return template && 'full' in template && template.full ? template : null;
|
||||
};
|
||||
},
|
||||
getCollectionById() {
|
||||
return (id: string): null | ITemplatesCollection => this.collections[id];
|
||||
},
|
||||
getCategoryById() {
|
||||
return (id: string): null | ITemplatesCategory => this.categories[id as unknown as number];
|
||||
},
|
||||
getSearchedCollections() {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = this.collectionSearches[searchKey];
|
||||
if (!search) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return search.collectionIds.map((collectionId: string) => this.collections[collectionId]);
|
||||
};
|
||||
},
|
||||
getSearchedWorkflows() {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = this.workflowSearches[searchKey];
|
||||
if (!search) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return search.workflowIds.map((workflowId: string) => this.workflows[workflowId]);
|
||||
};
|
||||
},
|
||||
getSearchedWorkflowsTotal() {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = this.workflowSearches[searchKey];
|
||||
|
||||
return search ? search.totalWorkflows : 0;
|
||||
};
|
||||
},
|
||||
isSearchLoadingMore() {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = this.workflowSearches[searchKey];
|
||||
|
||||
return Boolean(search && search.loadingMore);
|
||||
};
|
||||
},
|
||||
isSearchFinished() {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = this.workflowSearches[searchKey];
|
||||
|
||||
return Boolean(
|
||||
search && !search.loadingMore && search.totalWorkflows === search.workflowIds.length,
|
||||
);
|
||||
};
|
||||
},
|
||||
hasCustomTemplatesHost(): boolean {
|
||||
const settingsStore = useSettingsStore();
|
||||
return settingsStore.templatesHost !== TEMPLATES_URLS.DEFAULT_API_HOST;
|
||||
},
|
||||
/**
|
||||
* Constructs URLSearchParams object based on the default parameters for the template repository
|
||||
* and provided additional parameters
|
||||
*/
|
||||
websiteTemplateRepositoryParameters(_roleOverride?: string) {
|
||||
const rootStore = useRootStore();
|
||||
const userStore = useUsersStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const defaultParameters: Record<string, string> = {
|
||||
...TEMPLATES_URLS.UTM_QUERY,
|
||||
utm_instance: this.currentN8nPath,
|
||||
utm_n8n_version: rootStore.versionCli,
|
||||
utm_awc: String(workflowsStore.activeWorkflows.length),
|
||||
};
|
||||
const userRole: string | null | undefined =
|
||||
userStore.currentUserCloudInfo?.role ??
|
||||
(userStore.currentUser?.personalizationAnswers &&
|
||||
'role' in userStore.currentUser.personalizationAnswers
|
||||
? userStore.currentUser.personalizationAnswers.role
|
||||
: undefined);
|
||||
|
||||
if (userRole) {
|
||||
defaultParameters.utm_user_role = userRole;
|
||||
export const useTemplatesStore = defineStore(STORES.TEMPLATES, () => {
|
||||
const categories = ref<ITemplatesCategory[]>([]);
|
||||
const collections = ref<Record<string, ITemplatesCollection>>({});
|
||||
const workflows = ref<Record<string, ITemplatesWorkflow | ITemplatesWorkflowFull>>({});
|
||||
const workflowSearches = ref<
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
workflowIds: string[];
|
||||
totalWorkflows: number;
|
||||
loadingMore?: boolean;
|
||||
categories?: ITemplatesCategory[];
|
||||
}
|
||||
return (additionalParameters: Record<string, string> = {}) => {
|
||||
return new URLSearchParams({
|
||||
...defaultParameters,
|
||||
...additionalParameters,
|
||||
});
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Construct the URL for the template repository on the website
|
||||
* @returns {string}
|
||||
*/
|
||||
websiteTemplateRepositoryURL(): string {
|
||||
return `${
|
||||
TEMPLATES_URLS.BASE_WEBSITE_URL
|
||||
}?${this.websiteTemplateRepositoryParameters().toString()}`;
|
||||
},
|
||||
/**
|
||||
* Construct the URL for the template category page on the website for a given category id
|
||||
*/
|
||||
getWebsiteCategoryURL() {
|
||||
return (id?: string, roleOverride?: string) => {
|
||||
const payload: Record<string, string> = {};
|
||||
if (id) {
|
||||
payload.categories = id;
|
||||
}
|
||||
if (roleOverride) {
|
||||
payload.utm_user_role = roleOverride;
|
||||
}
|
||||
return `${TEMPLATES_URLS.BASE_WEBSITE_URL}/?${this.websiteTemplateRepositoryParameters(payload).toString()}`;
|
||||
};
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
addCategories(categories: ITemplatesCategory[]): void {
|
||||
categories.forEach((category: ITemplatesCategory) => {
|
||||
this.categories = {
|
||||
...this.categories,
|
||||
[category.id]: category,
|
||||
};
|
||||
});
|
||||
},
|
||||
addCollections(collections: Array<ITemplatesCollection | ITemplatesCollectionFull>): void {
|
||||
collections.forEach((collection) => {
|
||||
const workflows = (collection.workflows || []).map((workflow) => ({ id: workflow.id }));
|
||||
const cachedCollection = this.collections[collection.id] || {};
|
||||
|
||||
this.collections = {
|
||||
...this.collections,
|
||||
[collection.id]: {
|
||||
...cachedCollection,
|
||||
...collection,
|
||||
workflows,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
addWorkflows(workflows: Array<ITemplatesWorkflow | ITemplatesWorkflowFull>): void {
|
||||
workflows.forEach((workflow: ITemplatesWorkflow) => {
|
||||
const cachedWorkflow = this.workflows[workflow.id] || {};
|
||||
|
||||
this.workflows = {
|
||||
...this.workflows,
|
||||
[workflow.id]: {
|
||||
...cachedWorkflow,
|
||||
...workflow,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
addCollectionSearch(data: {
|
||||
collections: ITemplatesCollection[];
|
||||
query: ITemplatesQuery;
|
||||
}): void {
|
||||
const collectionIds = data.collections.map((collection) => String(collection.id));
|
||||
const searchKey = getSearchKey(data.query);
|
||||
|
||||
this.collectionSearches = {
|
||||
...this.collectionSearches,
|
||||
[searchKey]: {
|
||||
collectionIds,
|
||||
},
|
||||
};
|
||||
},
|
||||
addWorkflowsSearch(data: {
|
||||
totalWorkflows: number;
|
||||
workflows: ITemplatesWorkflow[];
|
||||
query: ITemplatesQuery;
|
||||
}): void {
|
||||
const workflowIds = data.workflows.map((workflow) => workflow.id);
|
||||
const searchKey = getSearchKey(data.query);
|
||||
const cachedResults = this.workflowSearches[searchKey];
|
||||
if (!cachedResults) {
|
||||
this.workflowSearches = {
|
||||
...this.workflowSearches,
|
||||
[searchKey]: {
|
||||
workflowIds: workflowIds as unknown as string[],
|
||||
totalWorkflows: data.totalWorkflows,
|
||||
categories: this.categories,
|
||||
},
|
||||
};
|
||||
|
||||
return;
|
||||
>
|
||||
>({});
|
||||
const collectionSearches = ref<
|
||||
Record<
|
||||
string,
|
||||
{
|
||||
collectionIds: string[];
|
||||
}
|
||||
>
|
||||
>({});
|
||||
const currentSessionId = ref<string>('');
|
||||
const previousSessionId = ref<string>('');
|
||||
const currentN8nPath = ref<string>(
|
||||
`${window.location.protocol}//${window.location.host}${window.BASE_PATH}`,
|
||||
);
|
||||
|
||||
this.workflowSearches = {
|
||||
...this.workflowSearches,
|
||||
[searchKey]: {
|
||||
workflowIds: [...cachedResults.workflowIds, ...workflowIds] as string[],
|
||||
totalWorkflows: data.totalWorkflows,
|
||||
categories: this.categories,
|
||||
},
|
||||
};
|
||||
},
|
||||
setWorkflowSearchLoading(query: ITemplatesQuery): void {
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const userStore = useUsersStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const allCategories = computed(() => {
|
||||
return categories.value.sort((a: ITemplatesCategory, b: ITemplatesCategory) =>
|
||||
a.name > b.name ? 1 : -1,
|
||||
);
|
||||
});
|
||||
|
||||
const getTemplatesById = computed(() => {
|
||||
return (id: string): null | ITemplatesWorkflow => workflows.value[id];
|
||||
});
|
||||
|
||||
const getFullTemplateById = computed(() => {
|
||||
return (id: string): null | ITemplatesWorkflowFull => {
|
||||
const template = workflows.value[id];
|
||||
return template && 'full' in template && template.full ? template : null;
|
||||
};
|
||||
});
|
||||
|
||||
const getCollectionById = computed(() => collections.value);
|
||||
|
||||
const getCategoryById = computed(() => {
|
||||
return (id: string): null | ITemplatesCategory => categories.value[id as unknown as number];
|
||||
});
|
||||
|
||||
const getSearchedCollections = computed(() => {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const cachedResults = this.workflowSearches[searchKey];
|
||||
if (!cachedResults) {
|
||||
return;
|
||||
const search = collectionSearches.value[searchKey];
|
||||
if (!search) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.workflowSearches[searchKey] = {
|
||||
...this.workflowSearches[searchKey],
|
||||
loadingMore: true,
|
||||
};
|
||||
},
|
||||
setWorkflowSearchLoaded(query: ITemplatesQuery): void {
|
||||
return search.collectionIds.map((collectionId: string) => collections.value[collectionId]);
|
||||
};
|
||||
});
|
||||
|
||||
const getSearchedWorkflows = computed(() => {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const cachedResults = this.workflowSearches[searchKey];
|
||||
if (!cachedResults) {
|
||||
return;
|
||||
const search = workflowSearches.value[searchKey];
|
||||
if (!search) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.workflowSearches[searchKey] = {
|
||||
...this.workflowSearches[searchKey],
|
||||
loadingMore: false,
|
||||
return search.workflowIds.map((workflowId: string) => workflows.value[workflowId]);
|
||||
};
|
||||
});
|
||||
|
||||
const getSearchedWorkflowsTotal = computed(() => {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = workflowSearches.value[searchKey];
|
||||
|
||||
return search ? search.totalWorkflows : 0;
|
||||
};
|
||||
});
|
||||
|
||||
const isSearchLoadingMore = computed(() => {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = workflowSearches.value[searchKey];
|
||||
|
||||
return Boolean(search && search.loadingMore);
|
||||
};
|
||||
});
|
||||
|
||||
const isSearchFinished = computed(() => {
|
||||
return (query: ITemplatesQuery) => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const search = workflowSearches.value[searchKey];
|
||||
|
||||
return Boolean(
|
||||
search && !search.loadingMore && search.totalWorkflows === search.workflowIds.length,
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const hasCustomTemplatesHost = computed(() => {
|
||||
return settingsStore.templatesHost !== TEMPLATES_URLS.DEFAULT_API_HOST;
|
||||
});
|
||||
|
||||
const websiteTemplateRepositoryParameters = computed(() => {
|
||||
const defaultParameters: Record<string, string> = {
|
||||
...TEMPLATES_URLS.UTM_QUERY,
|
||||
utm_instance: currentN8nPath.value,
|
||||
utm_n8n_version: rootStore.versionCli,
|
||||
utm_awc: String(workflowsStore.activeWorkflows.length),
|
||||
};
|
||||
const userRole: string | null | undefined =
|
||||
userStore.currentUserCloudInfo?.role ??
|
||||
(userStore.currentUser?.personalizationAnswers &&
|
||||
'role' in userStore.currentUser.personalizationAnswers
|
||||
? userStore.currentUser.personalizationAnswers.role
|
||||
: undefined);
|
||||
|
||||
if (userRole) {
|
||||
defaultParameters.utm_user_role = userRole;
|
||||
}
|
||||
return new URLSearchParams({
|
||||
...defaultParameters,
|
||||
});
|
||||
});
|
||||
|
||||
const websiteTemplateRepositoryURL = computed(
|
||||
() =>
|
||||
`${TEMPLATES_URLS.BASE_WEBSITE_URL}?${websiteTemplateRepositoryParameters.value.toString()}`,
|
||||
);
|
||||
|
||||
const addCategories = (_categories: ITemplatesCategory[]): void => {
|
||||
categories.value = _categories;
|
||||
};
|
||||
|
||||
const addCollections = (
|
||||
_collections: Array<ITemplatesCollection | ITemplatesCollectionFull>,
|
||||
): void => {
|
||||
_collections.forEach((collection) => {
|
||||
const workflows = (collection.workflows || []).map((workflow) => ({ id: workflow.id }));
|
||||
const cachedCollection = collections.value[collection.id] || {};
|
||||
|
||||
collections.value[collection.id] = {
|
||||
...cachedCollection,
|
||||
...collection,
|
||||
workflows,
|
||||
};
|
||||
},
|
||||
resetSessionId(): void {
|
||||
this.previousSessionId = this.currentSessionId;
|
||||
this.currentSessionId = '';
|
||||
},
|
||||
setSessionId(): void {
|
||||
if (!this.currentSessionId) {
|
||||
this.currentSessionId = `templates-${Date.now()}`;
|
||||
}
|
||||
},
|
||||
async fetchTemplateById(templateId: string): Promise<ITemplatesWorkflowFull> {
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await getTemplateById(apiEndpoint, templateId, {
|
||||
'n8n-version': versionCli,
|
||||
});
|
||||
};
|
||||
|
||||
const addWorkflows = (_workflows: Array<ITemplatesWorkflow | ITemplatesWorkflowFull>): void => {
|
||||
_workflows.forEach((workflow) => {
|
||||
const cachedWorkflow = workflows.value[workflow.id] || {};
|
||||
workflows.value[workflow.id.toString()] = { ...cachedWorkflow, ...workflow };
|
||||
});
|
||||
};
|
||||
|
||||
const addCollectionsSearch = (data: {
|
||||
_collections: ITemplatesCollection[];
|
||||
query: ITemplatesQuery;
|
||||
}) => {
|
||||
const collectionIds = data._collections.map((collection) => String(collection.id));
|
||||
const searchKey = getSearchKey(data.query);
|
||||
|
||||
collectionSearches.value[searchKey] = {
|
||||
collectionIds,
|
||||
};
|
||||
};
|
||||
|
||||
const addWorkflowsSearch = (data: {
|
||||
totalWorkflows: number;
|
||||
workflows: ITemplatesWorkflow[];
|
||||
query: ITemplatesQuery;
|
||||
}) => {
|
||||
const workflowIds = data.workflows.map((workflow) => workflow.id);
|
||||
const searchKey = getSearchKey(data.query);
|
||||
const cachedResults = workflowSearches.value[searchKey];
|
||||
if (!cachedResults) {
|
||||
workflowSearches.value[searchKey] = {
|
||||
workflowIds: workflowIds as unknown as string[],
|
||||
totalWorkflows: data.totalWorkflows,
|
||||
categories: categories.value,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
workflowSearches.value[searchKey] = {
|
||||
workflowIds: [...cachedResults.workflowIds, ...workflowIds] as string[],
|
||||
totalWorkflows: data.totalWorkflows,
|
||||
categories: categories.value,
|
||||
};
|
||||
};
|
||||
|
||||
const setWorkflowSearchLoading = (query: ITemplatesQuery): void => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const cachedResults = workflowSearches.value[searchKey];
|
||||
if (!cachedResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
workflowSearches.value[searchKey] = {
|
||||
...workflowSearches.value[searchKey],
|
||||
loadingMore: true,
|
||||
};
|
||||
};
|
||||
|
||||
const setWorkflowSearchLoaded = (query: ITemplatesQuery): void => {
|
||||
const searchKey = getSearchKey(query);
|
||||
const cachedResults = workflowSearches.value[searchKey];
|
||||
if (!cachedResults) {
|
||||
return;
|
||||
}
|
||||
|
||||
workflowSearches.value[searchKey] = {
|
||||
...workflowSearches.value[searchKey],
|
||||
loadingMore: false,
|
||||
};
|
||||
};
|
||||
|
||||
const resetSessionId = (): void => {
|
||||
previousSessionId.value = currentSessionId.value;
|
||||
currentSessionId.value = '';
|
||||
};
|
||||
|
||||
const setSessionId = (): void => {
|
||||
if (!currentSessionId.value) {
|
||||
currentSessionId.value = `templates-${Date.now()}`;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchTemplateById = async (templateId: string): Promise<ITemplatesWorkflowFull> => {
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await templatesApi.getTemplateById(apiEndpoint, templateId, {
|
||||
'n8n-version': versionCli,
|
||||
});
|
||||
|
||||
const template: ITemplatesWorkflowFull = {
|
||||
...response.workflow,
|
||||
full: true,
|
||||
};
|
||||
addWorkflows([template]);
|
||||
|
||||
return template;
|
||||
};
|
||||
|
||||
const fetchCollectionById = async (
|
||||
collectionId: string,
|
||||
): Promise<ITemplatesCollection | null> => {
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await templatesApi.getCollectionById(apiEndpoint, collectionId, {
|
||||
'n8n-version': versionCli,
|
||||
});
|
||||
const collection: ITemplatesCollectionFull = {
|
||||
...response.collection,
|
||||
full: true,
|
||||
};
|
||||
|
||||
addCollections([collection]);
|
||||
addWorkflows(response.collection.workflows);
|
||||
return getCollectionById.value[collectionId];
|
||||
};
|
||||
|
||||
const getCategories = async (): Promise<ITemplatesCategory[]> => {
|
||||
const cachedCategories = allCategories.value;
|
||||
if (cachedCategories.length) {
|
||||
return cachedCategories;
|
||||
}
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await templatesApi.getCategories(apiEndpoint, {
|
||||
'n8n-version': versionCli,
|
||||
});
|
||||
const categories = response.categories;
|
||||
|
||||
addCategories(categories);
|
||||
return categories;
|
||||
};
|
||||
|
||||
const getCollections = async (query: ITemplatesQuery): Promise<ITemplatesCollection[]> => {
|
||||
const cachedResults = getSearchedCollections.value(query);
|
||||
if (cachedResults) {
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await templatesApi.getCollections(apiEndpoint, query, {
|
||||
'n8n-version': versionCli,
|
||||
});
|
||||
const collections = response.collections;
|
||||
|
||||
addCollections(collections);
|
||||
addCollectionsSearch({ query, _collections: collections });
|
||||
collections.forEach((collection) => addWorkflows(collection.workflows as ITemplatesWorkflow[]));
|
||||
|
||||
return collections;
|
||||
};
|
||||
|
||||
const getWorkflows = async (query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> => {
|
||||
const cachedResults = getSearchedWorkflows.value(query);
|
||||
if (cachedResults) {
|
||||
categories.value = workflowSearches.value[getSearchKey(query)].categories ?? [];
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const payload = await templatesApi.getWorkflows(
|
||||
apiEndpoint,
|
||||
{ ...query, page: 1, limit: TEMPLATES_PAGE_SIZE },
|
||||
{ 'n8n-version': versionCli },
|
||||
);
|
||||
|
||||
addWorkflows(payload.workflows);
|
||||
addWorkflowsSearch({ ...payload, query });
|
||||
return getSearchedWorkflows.value(query) || [];
|
||||
};
|
||||
|
||||
const getMoreWorkflows = async (query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> => {
|
||||
if (isSearchLoadingMore.value(query) && !isSearchFinished.value(query)) {
|
||||
return [];
|
||||
}
|
||||
const cachedResults = getSearchedWorkflows.value(query) || [];
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
|
||||
setWorkflowSearchLoading(query);
|
||||
try {
|
||||
const payload = await templatesApi.getWorkflows(apiEndpoint, {
|
||||
...query,
|
||||
page: cachedResults.length / TEMPLATES_PAGE_SIZE + 1,
|
||||
limit: TEMPLATES_PAGE_SIZE,
|
||||
});
|
||||
|
||||
const template: ITemplatesWorkflowFull = {
|
||||
...response.workflow,
|
||||
full: true,
|
||||
};
|
||||
this.addWorkflows([template]);
|
||||
setWorkflowSearchLoaded(query);
|
||||
addWorkflows(payload.workflows);
|
||||
addWorkflowsSearch({ ...payload, query });
|
||||
|
||||
return template;
|
||||
},
|
||||
async fetchCollectionById(collectionId: string): Promise<ITemplatesCollection | null> {
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await getCollectionById(apiEndpoint, collectionId, {
|
||||
'n8n-version': versionCli,
|
||||
return getSearchedWorkflows.value(query) || [];
|
||||
} catch (e) {
|
||||
setWorkflowSearchLoaded(query);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
const getWorkflowTemplate = async (templateId: string): Promise<IWorkflowTemplate> => {
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
return await templatesApi.getWorkflowTemplate(apiEndpoint, templateId, {
|
||||
'n8n-version': versionCli,
|
||||
});
|
||||
};
|
||||
|
||||
const getFixedWorkflowTemplate = async (
|
||||
templateId: string,
|
||||
): Promise<IWorkflowTemplate | undefined> => {
|
||||
const template = await getWorkflowTemplate(templateId);
|
||||
if (template?.workflow?.nodes) {
|
||||
template.workflow.nodes = getFixedNodesList(template.workflow.nodes) as INodeUi[];
|
||||
template.workflow.nodes?.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
delete node.credentials;
|
||||
}
|
||||
});
|
||||
const collection: ITemplatesCollectionFull = {
|
||||
...response.collection,
|
||||
full: true,
|
||||
};
|
||||
}
|
||||
|
||||
this.addCollections([collection]);
|
||||
this.addWorkflows(response.collection.workflows);
|
||||
return this.getCollectionById(collectionId);
|
||||
},
|
||||
async getCategories(): Promise<ITemplatesCategory[]> {
|
||||
const cachedCategories = this.allCategories;
|
||||
if (cachedCategories.length) {
|
||||
return cachedCategories;
|
||||
}
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await getCategories(apiEndpoint, { 'n8n-version': versionCli });
|
||||
const categories = response.categories;
|
||||
return template;
|
||||
};
|
||||
|
||||
this.addCategories(categories);
|
||||
return categories;
|
||||
},
|
||||
async getCollections(query: ITemplatesQuery): Promise<ITemplatesCollection[]> {
|
||||
const cachedResults = this.getSearchedCollections(query);
|
||||
if (cachedResults) {
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
const response = await getCollections(apiEndpoint, query, { 'n8n-version': versionCli });
|
||||
const collections = response.collections;
|
||||
|
||||
this.addCollections(collections);
|
||||
this.addCollectionSearch({ query, collections });
|
||||
collections.forEach((collection) =>
|
||||
this.addWorkflows(collection.workflows as ITemplatesWorkflowFull[]),
|
||||
);
|
||||
|
||||
return collections;
|
||||
},
|
||||
async getWorkflows(query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> {
|
||||
const cachedResults = this.getSearchedWorkflows(query);
|
||||
if (cachedResults) {
|
||||
this.categories = this.workflowSearches[getSearchKey(query)].categories ?? [];
|
||||
return cachedResults;
|
||||
}
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
|
||||
const payload = await getWorkflows(
|
||||
apiEndpoint,
|
||||
{ ...query, page: 1, limit: TEMPLATES_PAGE_SIZE },
|
||||
{ 'n8n-version': versionCli },
|
||||
);
|
||||
|
||||
this.addWorkflows(payload.workflows);
|
||||
this.addWorkflowsSearch({ ...payload, query });
|
||||
return this.getSearchedWorkflows(query) || [];
|
||||
},
|
||||
async getMoreWorkflows(query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> {
|
||||
if (this.isSearchLoadingMore(query) && !this.isSearchFinished(query)) {
|
||||
return [];
|
||||
}
|
||||
const cachedResults = this.getSearchedWorkflows(query) || [];
|
||||
const settingsStore = useSettingsStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
|
||||
this.setWorkflowSearchLoading(query);
|
||||
try {
|
||||
const payload = await getWorkflows(apiEndpoint, {
|
||||
...query,
|
||||
page: cachedResults.length / TEMPLATES_PAGE_SIZE + 1,
|
||||
limit: TEMPLATES_PAGE_SIZE,
|
||||
});
|
||||
|
||||
this.setWorkflowSearchLoaded(query);
|
||||
this.addWorkflows(payload.workflows);
|
||||
this.addWorkflowsSearch({ ...payload, query });
|
||||
|
||||
return this.getSearchedWorkflows(query) || [];
|
||||
} catch (e) {
|
||||
this.setWorkflowSearchLoaded(query);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
async getWorkflowTemplate(templateId: string): Promise<IWorkflowTemplate> {
|
||||
const settingsStore = useSettingsStore();
|
||||
const rootStore = useRootStore();
|
||||
const apiEndpoint: string = settingsStore.templatesHost;
|
||||
const versionCli: string = rootStore.versionCli;
|
||||
return await getWorkflowTemplate(apiEndpoint, templateId, { 'n8n-version': versionCli });
|
||||
},
|
||||
|
||||
async getFixedWorkflowTemplate(templateId: string): Promise<IWorkflowTemplate | undefined> {
|
||||
const template = await this.getWorkflowTemplate(templateId);
|
||||
if (template?.workflow?.nodes) {
|
||||
template.workflow.nodes = getFixedNodesList(template.workflow.nodes) as INodeUi[];
|
||||
template.workflow.nodes?.forEach((node) => {
|
||||
if (node.credentials) {
|
||||
delete node.credentials;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return template;
|
||||
},
|
||||
},
|
||||
return {
|
||||
categories,
|
||||
collections,
|
||||
workflows,
|
||||
workflowSearches,
|
||||
collectionSearches,
|
||||
currentSessionId,
|
||||
previousSessionId,
|
||||
currentN8nPath,
|
||||
allCategories,
|
||||
getTemplatesById,
|
||||
getFullTemplateById,
|
||||
getCollectionById,
|
||||
getCategoryById,
|
||||
getSearchedCollections,
|
||||
getSearchedWorkflows,
|
||||
getSearchedWorkflowsTotal,
|
||||
isSearchLoadingMore,
|
||||
isSearchFinished,
|
||||
hasCustomTemplatesHost,
|
||||
websiteTemplateRepositoryURL,
|
||||
websiteTemplateRepositoryParameters,
|
||||
addCategories,
|
||||
addCollections,
|
||||
addWorkflows,
|
||||
addCollectionsSearch,
|
||||
addWorkflowsSearch,
|
||||
setWorkflowSearchLoading,
|
||||
setWorkflowSearchLoaded,
|
||||
resetSessionId,
|
||||
setSessionId,
|
||||
fetchTemplateById,
|
||||
fetchCollectionById,
|
||||
getCategories,
|
||||
getCollections,
|
||||
getWorkflows,
|
||||
getMoreWorkflows,
|
||||
getWorkflowTemplate,
|
||||
getFixedWorkflowTemplate,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -35,14 +35,14 @@ const collectionId = computed(() => {
|
|||
return Array.isArray(id) ? id[0] : id;
|
||||
});
|
||||
|
||||
const collection = computed(() => templatesStore.getCollectionById(collectionId.value));
|
||||
const collection = computed(() => templatesStore.getCollectionById[collectionId.value]);
|
||||
|
||||
const collectionWorkflows = computed(() => {
|
||||
if (!collection.value || loading.value) {
|
||||
return [];
|
||||
}
|
||||
return collection.value.workflows
|
||||
.map(({ id }) => templatesStore.getTemplateById(id.toString()))
|
||||
.map(({ id }) => templatesStore.getTemplatesById(id.toString()))
|
||||
.filter((workflow): workflow is ITemplatesWorkflow => !!workflow);
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue