refactor(editor): Migrate templates.store to composition API (#11641)

This commit is contained in:
Ricardo Espinoza 2024-11-08 07:46:03 -05:00 committed by GitHub
parent d55d066bf3
commit aec372793b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 413 additions and 390 deletions

View file

@ -141,6 +141,10 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS); const chainNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_CHAINS);
const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS); const agentNodes = getAiNodesBySubcategory(nodeTypesStore.allLatestNodeTypes, AI_CATEGORY_AGENTS);
const websiteCategoryURL = templatesStore.websiteTemplateRepositoryParameters;
websiteCategoryURL.append('utm_user_role', 'AdvancedAI');
return { return {
value: AI_NODE_CREATOR_VIEW, value: AI_NODE_CREATOR_VIEW,
title: i18n.baseText('nodeCreator.aiPanel.aiNodes'), title: i18n.baseText('nodeCreator.aiPanel.aiNodes'),
@ -154,7 +158,7 @@ export function AIView(_nodes: SimplifiedNodeType[]): NodeView {
icon: 'box-open', icon: 'box-open',
description: i18n.baseText('nodeCreator.aiPanel.linkItem.description'), description: i18n.baseText('nodeCreator.aiPanel.linkItem.description'),
name: 'ai_templates_root', name: 'ai_templates_root',
url: templatesStore.getWebsiteCategoryURL(undefined, 'AdvancedAI'), url: websiteCategoryURL.toString(),
tag: { tag: {
type: 'info', type: 'info',
text: i18n.baseText('nodeCreator.triggerHelperPanel.manualTriggerTag'), text: i18n.baseText('nodeCreator.triggerHelperPanel.manualTriggerTag'),

View file

@ -6,24 +6,17 @@ import type {
ITemplatesCollection, ITemplatesCollection,
ITemplatesCollectionFull, ITemplatesCollectionFull,
ITemplatesQuery, ITemplatesQuery,
ITemplateState,
ITemplatesWorkflow, ITemplatesWorkflow,
ITemplatesWorkflowFull, ITemplatesWorkflowFull,
IWorkflowTemplate, IWorkflowTemplate,
} from '@/Interface'; } from '@/Interface';
import { useSettingsStore } from './settings.store'; import { useSettingsStore } from './settings.store';
import { import * as templatesApi from '@/api/templates';
getCategories,
getCollectionById,
getCollections,
getTemplateById,
getWorkflows,
getWorkflowTemplate,
} from '@/api/templates';
import { getFixedNodesList } from '@/utils/nodeViewUtils'; import { getFixedNodesList } from '@/utils/nodeViewUtils';
import { useRootStore } from '@/stores/root.store'; import { useRootStore } from '@/stores/root.store';
import { useUsersStore } from './users.store'; import { useUsersStore } from './users.store';
import { useWorkflowsStore } from './workflows.store'; import { useWorkflowsStore } from './workflows.store';
import { computed, ref } from 'vue';
const TEMPLATES_PAGE_SIZE = 20; const TEMPLATES_PAGE_SIZE = 20;
@ -33,101 +26,124 @@ function getSearchKey(query: ITemplatesQuery): string {
export type TemplatesStore = ReturnType<typeof useTemplatesStore>; export type TemplatesStore = ReturnType<typeof useTemplatesStore>;
export const useTemplatesStore = defineStore(STORES.TEMPLATES, { export const useTemplatesStore = defineStore(STORES.TEMPLATES, () => {
state: (): ITemplateState => ({ const categories = ref<ITemplatesCategory[]>([]);
categories: [], const collections = ref<Record<string, ITemplatesCollection>>({});
collections: {}, const workflows = ref<Record<string, ITemplatesWorkflow | ITemplatesWorkflowFull>>({});
workflows: {}, const workflowSearches = ref<
collectionSearches: {}, Record<
workflowSearches: {}, string,
currentSessionId: '', {
previousSessionId: '', workflowIds: string[];
currentN8nPath: `${window.location.protocol}//${window.location.host}${window.BASE_PATH}`, totalWorkflows: number;
}), loadingMore?: boolean;
getters: { categories?: ITemplatesCategory[];
allCategories(): ITemplatesCategory[] { }
return Object.values(this.categories).sort((a: ITemplatesCategory, b: ITemplatesCategory) => >
>({});
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}`,
);
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, a.name > b.name ? 1 : -1,
); );
}, });
getTemplateById() {
return (id: string): null | ITemplatesWorkflow => this.workflows[id]; const getTemplatesById = computed(() => {
}, return (id: string): null | ITemplatesWorkflow => workflows.value[id];
getFullTemplateById() { });
const getFullTemplateById = computed(() => {
return (id: string): null | ITemplatesWorkflowFull => { return (id: string): null | ITemplatesWorkflowFull => {
const template = this.workflows[id]; const template = workflows.value[id];
return template && 'full' in template && template.full ? template : null; return template && 'full' in template && template.full ? template : null;
}; };
}, });
getCollectionById() {
return (id: string): null | ITemplatesCollection => this.collections[id]; const getCollectionById = computed(() => collections.value);
},
getCategoryById() { const getCategoryById = computed(() => {
return (id: string): null | ITemplatesCategory => this.categories[id as unknown as number]; return (id: string): null | ITemplatesCategory => categories.value[id as unknown as number];
}, });
getSearchedCollections() {
const getSearchedCollections = computed(() => {
return (query: ITemplatesQuery) => { return (query: ITemplatesQuery) => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const search = this.collectionSearches[searchKey]; const search = collectionSearches.value[searchKey];
if (!search) { if (!search) {
return null; return null;
} }
return search.collectionIds.map((collectionId: string) => this.collections[collectionId]); return search.collectionIds.map((collectionId: string) => collections.value[collectionId]);
}; };
}, });
getSearchedWorkflows() {
const getSearchedWorkflows = computed(() => {
return (query: ITemplatesQuery) => { return (query: ITemplatesQuery) => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const search = this.workflowSearches[searchKey]; const search = workflowSearches.value[searchKey];
if (!search) { if (!search) {
return null; return null;
} }
return search.workflowIds.map((workflowId: string) => this.workflows[workflowId]); return search.workflowIds.map((workflowId: string) => workflows.value[workflowId]);
}; };
}, });
getSearchedWorkflowsTotal() {
const getSearchedWorkflowsTotal = computed(() => {
return (query: ITemplatesQuery) => { return (query: ITemplatesQuery) => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const search = this.workflowSearches[searchKey]; const search = workflowSearches.value[searchKey];
return search ? search.totalWorkflows : 0; return search ? search.totalWorkflows : 0;
}; };
}, });
isSearchLoadingMore() {
const isSearchLoadingMore = computed(() => {
return (query: ITemplatesQuery) => { return (query: ITemplatesQuery) => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const search = this.workflowSearches[searchKey]; const search = workflowSearches.value[searchKey];
return Boolean(search && search.loadingMore); return Boolean(search && search.loadingMore);
}; };
}, });
isSearchFinished() {
const isSearchFinished = computed(() => {
return (query: ITemplatesQuery) => { return (query: ITemplatesQuery) => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const search = this.workflowSearches[searchKey]; const search = workflowSearches.value[searchKey];
return Boolean( return Boolean(
search && !search.loadingMore && search.totalWorkflows === search.workflowIds.length, search && !search.loadingMore && search.totalWorkflows === search.workflowIds.length,
); );
}; };
}, });
hasCustomTemplatesHost(): boolean {
const settingsStore = useSettingsStore(); const hasCustomTemplatesHost = computed(() => {
return settingsStore.templatesHost !== TEMPLATES_URLS.DEFAULT_API_HOST; return settingsStore.templatesHost !== TEMPLATES_URLS.DEFAULT_API_HOST;
}, });
/**
* Constructs URLSearchParams object based on the default parameters for the template repository const websiteTemplateRepositoryParameters = computed(() => {
* and provided additional parameters
*/
websiteTemplateRepositoryParameters(_roleOverride?: string) {
const rootStore = useRootStore();
const userStore = useUsersStore();
const workflowsStore = useWorkflowsStore();
const defaultParameters: Record<string, string> = { const defaultParameters: Record<string, string> = {
...TEMPLATES_URLS.UTM_QUERY, ...TEMPLATES_URLS.UTM_QUERY,
utm_instance: this.currentN8nPath, utm_instance: currentN8nPath.value,
utm_n8n_version: rootStore.versionCli, utm_n8n_version: rootStore.versionCli,
utm_awc: String(workflowsStore.activeWorkflows.length), utm_awc: String(workflowsStore.activeWorkflows.length),
}; };
@ -141,158 +157,119 @@ export const useTemplatesStore = defineStore(STORES.TEMPLATES, {
if (userRole) { if (userRole) {
defaultParameters.utm_user_role = userRole; defaultParameters.utm_user_role = userRole;
} }
return (additionalParameters: Record<string, string> = {}) => {
return new URLSearchParams({ return new URLSearchParams({
...defaultParameters, ...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 = { const websiteTemplateRepositoryURL = computed(
...this.collections, () =>
[collection.id]: { `${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, ...cachedCollection,
...collection, ...collection,
workflows, workflows,
},
}; };
}); });
}, };
addWorkflows(workflows: Array<ITemplatesWorkflow | ITemplatesWorkflowFull>): void {
workflows.forEach((workflow: ITemplatesWorkflow) => {
const cachedWorkflow = this.workflows[workflow.id] || {};
this.workflows = { const addWorkflows = (_workflows: Array<ITemplatesWorkflow | ITemplatesWorkflowFull>): void => {
...this.workflows, _workflows.forEach((workflow) => {
[workflow.id]: { const cachedWorkflow = workflows.value[workflow.id] || {};
...cachedWorkflow, workflows.value[workflow.id.toString()] = { ...cachedWorkflow, ...workflow };
...workflow,
},
};
}); });
}, };
addCollectionSearch(data: {
collections: ITemplatesCollection[]; const addCollectionsSearch = (data: {
_collections: ITemplatesCollection[];
query: ITemplatesQuery; query: ITemplatesQuery;
}): void { }) => {
const collectionIds = data.collections.map((collection) => String(collection.id)); const collectionIds = data._collections.map((collection) => String(collection.id));
const searchKey = getSearchKey(data.query); const searchKey = getSearchKey(data.query);
this.collectionSearches = { collectionSearches.value[searchKey] = {
...this.collectionSearches,
[searchKey]: {
collectionIds, collectionIds,
},
}; };
}, };
addWorkflowsSearch(data: {
const addWorkflowsSearch = (data: {
totalWorkflows: number; totalWorkflows: number;
workflows: ITemplatesWorkflow[]; workflows: ITemplatesWorkflow[];
query: ITemplatesQuery; query: ITemplatesQuery;
}): void { }) => {
const workflowIds = data.workflows.map((workflow) => workflow.id); const workflowIds = data.workflows.map((workflow) => workflow.id);
const searchKey = getSearchKey(data.query); const searchKey = getSearchKey(data.query);
const cachedResults = this.workflowSearches[searchKey]; const cachedResults = workflowSearches.value[searchKey];
if (!cachedResults) { if (!cachedResults) {
this.workflowSearches = { workflowSearches.value[searchKey] = {
...this.workflowSearches,
[searchKey]: {
workflowIds: workflowIds as unknown as string[], workflowIds: workflowIds as unknown as string[],
totalWorkflows: data.totalWorkflows, totalWorkflows: data.totalWorkflows,
categories: this.categories, categories: categories.value,
},
}; };
return; return;
} }
this.workflowSearches = { workflowSearches.value[searchKey] = {
...this.workflowSearches,
[searchKey]: {
workflowIds: [...cachedResults.workflowIds, ...workflowIds] as string[], workflowIds: [...cachedResults.workflowIds, ...workflowIds] as string[],
totalWorkflows: data.totalWorkflows, totalWorkflows: data.totalWorkflows,
categories: this.categories, categories: categories.value,
},
}; };
}, };
setWorkflowSearchLoading(query: ITemplatesQuery): void {
const setWorkflowSearchLoading = (query: ITemplatesQuery): void => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const cachedResults = this.workflowSearches[searchKey]; const cachedResults = workflowSearches.value[searchKey];
if (!cachedResults) { if (!cachedResults) {
return; return;
} }
this.workflowSearches[searchKey] = { workflowSearches.value[searchKey] = {
...this.workflowSearches[searchKey], ...workflowSearches.value[searchKey],
loadingMore: true, loadingMore: true,
}; };
}, };
setWorkflowSearchLoaded(query: ITemplatesQuery): void {
const setWorkflowSearchLoaded = (query: ITemplatesQuery): void => {
const searchKey = getSearchKey(query); const searchKey = getSearchKey(query);
const cachedResults = this.workflowSearches[searchKey]; const cachedResults = workflowSearches.value[searchKey];
if (!cachedResults) { if (!cachedResults) {
return; return;
} }
this.workflowSearches[searchKey] = { workflowSearches.value[searchKey] = {
...this.workflowSearches[searchKey], ...workflowSearches.value[searchKey],
loadingMore: false, loadingMore: false,
}; };
}, };
resetSessionId(): void {
this.previousSessionId = this.currentSessionId; const resetSessionId = (): void => {
this.currentSessionId = ''; previousSessionId.value = currentSessionId.value;
}, currentSessionId.value = '';
setSessionId(): void { };
if (!this.currentSessionId) {
this.currentSessionId = `templates-${Date.now()}`; const setSessionId = (): void => {
if (!currentSessionId.value) {
currentSessionId.value = `templates-${Date.now()}`;
} }
}, };
async fetchTemplateById(templateId: string): Promise<ITemplatesWorkflowFull> {
const settingsStore = useSettingsStore(); const fetchTemplateById = async (templateId: string): Promise<ITemplatesWorkflowFull> => {
const rootStore = useRootStore();
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
const versionCli: string = rootStore.versionCli; const versionCli: string = rootStore.versionCli;
const response = await getTemplateById(apiEndpoint, templateId, { const response = await templatesApi.getTemplateById(apiEndpoint, templateId, {
'n8n-version': versionCli, 'n8n-version': versionCli,
}); });
@ -300,16 +277,17 @@ export const useTemplatesStore = defineStore(STORES.TEMPLATES, {
...response.workflow, ...response.workflow,
full: true, full: true,
}; };
this.addWorkflows([template]); addWorkflows([template]);
return template; return template;
}, };
async fetchCollectionById(collectionId: string): Promise<ITemplatesCollection | null> {
const settingsStore = useSettingsStore(); const fetchCollectionById = async (
const rootStore = useRootStore(); collectionId: string,
): Promise<ITemplatesCollection | null> => {
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
const versionCli: string = rootStore.versionCli; const versionCli: string = rootStore.versionCli;
const response = await getCollectionById(apiEndpoint, collectionId, { const response = await templatesApi.getCollectionById(apiEndpoint, collectionId, {
'n8n-version': versionCli, 'n8n-version': versionCli,
}); });
const collection: ITemplatesCollectionFull = { const collection: ITemplatesCollectionFull = {
@ -317,104 +295,105 @@ export const useTemplatesStore = defineStore(STORES.TEMPLATES, {
full: true, full: true,
}; };
this.addCollections([collection]); addCollections([collection]);
this.addWorkflows(response.collection.workflows); addWorkflows(response.collection.workflows);
return this.getCollectionById(collectionId); return getCollectionById.value[collectionId];
}, };
async getCategories(): Promise<ITemplatesCategory[]> {
const cachedCategories = this.allCategories; const getCategories = async (): Promise<ITemplatesCategory[]> => {
const cachedCategories = allCategories.value;
if (cachedCategories.length) { if (cachedCategories.length) {
return cachedCategories; return cachedCategories;
} }
const settingsStore = useSettingsStore();
const rootStore = useRootStore();
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
const versionCli: string = rootStore.versionCli; const versionCli: string = rootStore.versionCli;
const response = await getCategories(apiEndpoint, { 'n8n-version': versionCli }); const response = await templatesApi.getCategories(apiEndpoint, {
'n8n-version': versionCli,
});
const categories = response.categories; const categories = response.categories;
this.addCategories(categories); addCategories(categories);
return categories; return categories;
}, };
async getCollections(query: ITemplatesQuery): Promise<ITemplatesCollection[]> {
const cachedResults = this.getSearchedCollections(query); const getCollections = async (query: ITemplatesQuery): Promise<ITemplatesCollection[]> => {
const cachedResults = getSearchedCollections.value(query);
if (cachedResults) { if (cachedResults) {
return cachedResults; return cachedResults;
} }
const settingsStore = useSettingsStore();
const rootStore = useRootStore();
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
const versionCli: string = rootStore.versionCli; const versionCli: string = rootStore.versionCli;
const response = await getCollections(apiEndpoint, query, { 'n8n-version': versionCli }); const response = await templatesApi.getCollections(apiEndpoint, query, {
'n8n-version': versionCli,
});
const collections = response.collections; const collections = response.collections;
this.addCollections(collections); addCollections(collections);
this.addCollectionSearch({ query, collections }); addCollectionsSearch({ query, _collections: collections });
collections.forEach((collection) => collections.forEach((collection) => addWorkflows(collection.workflows as ITemplatesWorkflow[]));
this.addWorkflows(collection.workflows as ITemplatesWorkflowFull[]),
);
return collections; return collections;
}, };
async getWorkflows(query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> {
const cachedResults = this.getSearchedWorkflows(query); const getWorkflows = async (query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> => {
const cachedResults = getSearchedWorkflows.value(query);
if (cachedResults) { if (cachedResults) {
this.categories = this.workflowSearches[getSearchKey(query)].categories ?? []; categories.value = workflowSearches.value[getSearchKey(query)].categories ?? [];
return cachedResults; return cachedResults;
} }
const settingsStore = useSettingsStore();
const rootStore = useRootStore();
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
const versionCli: string = rootStore.versionCli; const versionCli: string = rootStore.versionCli;
const payload = await templatesApi.getWorkflows(
const payload = await getWorkflows(
apiEndpoint, apiEndpoint,
{ ...query, page: 1, limit: TEMPLATES_PAGE_SIZE }, { ...query, page: 1, limit: TEMPLATES_PAGE_SIZE },
{ 'n8n-version': versionCli }, { 'n8n-version': versionCli },
); );
this.addWorkflows(payload.workflows); addWorkflows(payload.workflows);
this.addWorkflowsSearch({ ...payload, query }); addWorkflowsSearch({ ...payload, query });
return this.getSearchedWorkflows(query) || []; return getSearchedWorkflows.value(query) || [];
}, };
async getMoreWorkflows(query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> {
if (this.isSearchLoadingMore(query) && !this.isSearchFinished(query)) { const getMoreWorkflows = async (query: ITemplatesQuery): Promise<ITemplatesWorkflow[]> => {
if (isSearchLoadingMore.value(query) && !isSearchFinished.value(query)) {
return []; return [];
} }
const cachedResults = this.getSearchedWorkflows(query) || []; const cachedResults = getSearchedWorkflows.value(query) || [];
const settingsStore = useSettingsStore();
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
this.setWorkflowSearchLoading(query); setWorkflowSearchLoading(query);
try { try {
const payload = await getWorkflows(apiEndpoint, { const payload = await templatesApi.getWorkflows(apiEndpoint, {
...query, ...query,
page: cachedResults.length / TEMPLATES_PAGE_SIZE + 1, page: cachedResults.length / TEMPLATES_PAGE_SIZE + 1,
limit: TEMPLATES_PAGE_SIZE, limit: TEMPLATES_PAGE_SIZE,
}); });
this.setWorkflowSearchLoaded(query); setWorkflowSearchLoaded(query);
this.addWorkflows(payload.workflows); addWorkflows(payload.workflows);
this.addWorkflowsSearch({ ...payload, query }); addWorkflowsSearch({ ...payload, query });
return this.getSearchedWorkflows(query) || []; return getSearchedWorkflows.value(query) || [];
} catch (e) { } catch (e) {
this.setWorkflowSearchLoaded(query); setWorkflowSearchLoaded(query);
throw e; throw e;
} }
}, };
async getWorkflowTemplate(templateId: string): Promise<IWorkflowTemplate> {
const settingsStore = useSettingsStore(); const getWorkflowTemplate = async (templateId: string): Promise<IWorkflowTemplate> => {
const rootStore = useRootStore();
const apiEndpoint: string = settingsStore.templatesHost; const apiEndpoint: string = settingsStore.templatesHost;
const versionCli: string = rootStore.versionCli; const versionCli: string = rootStore.versionCli;
return await getWorkflowTemplate(apiEndpoint, templateId, { 'n8n-version': versionCli }); return await templatesApi.getWorkflowTemplate(apiEndpoint, templateId, {
}, 'n8n-version': versionCli,
});
};
async getFixedWorkflowTemplate(templateId: string): Promise<IWorkflowTemplate | undefined> { const getFixedWorkflowTemplate = async (
const template = await this.getWorkflowTemplate(templateId); templateId: string,
): Promise<IWorkflowTemplate | undefined> => {
const template = await getWorkflowTemplate(templateId);
if (template?.workflow?.nodes) { if (template?.workflow?.nodes) {
template.workflow.nodes = getFixedNodesList(template.workflow.nodes) as INodeUi[]; template.workflow.nodes = getFixedNodesList(template.workflow.nodes) as INodeUi[];
template.workflow.nodes?.forEach((node) => { template.workflow.nodes?.forEach((node) => {
@ -425,6 +404,46 @@ export const useTemplatesStore = defineStore(STORES.TEMPLATES, {
} }
return template; 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,
};
}); });

View file

@ -35,14 +35,14 @@ const collectionId = computed(() => {
return Array.isArray(id) ? id[0] : id; return Array.isArray(id) ? id[0] : id;
}); });
const collection = computed(() => templatesStore.getCollectionById(collectionId.value)); const collection = computed(() => templatesStore.getCollectionById[collectionId.value]);
const collectionWorkflows = computed(() => { const collectionWorkflows = computed(() => {
if (!collection.value || loading.value) { if (!collection.value || loading.value) {
return []; return [];
} }
return collection.value.workflows return collection.value.workflows
.map(({ id }) => templatesStore.getTemplateById(id.toString())) .map(({ id }) => templatesStore.getTemplatesById(id.toString()))
.filter((workflow): workflow is ITemplatesWorkflow => !!workflow); .filter((workflow): workflow is ITemplatesWorkflow => !!workflow);
}); });