1
1
mirror of https://github.com/n8n-io/n8n.git synced 2024-08-17 00:50:42 +03:00

refactor(editor): Migrate tags.store to use composition API (no-changelog) (#9891)

This commit is contained in:
Ricardo Espinoza 2024-07-02 14:15:20 -04:00 committed by GitHub
parent 873b7e59dc
commit 8debac755e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 107 additions and 98 deletions

View File

@ -30,7 +30,7 @@ const initialState = {
areTagsEnabled: true, areTagsEnabled: true,
}, },
[STORES.TAGS]: { [STORES.TAGS]: {
tags: { tagsById: {
1: { 1: {
id: '1', id: '1',
name: 'tag1', name: 'tag1',

View File

@ -413,7 +413,7 @@ async function onWorkflowMenuSelect(action: WORKFLOW_MENU_ACTIONS): Promise<void
instanceId: rootStore.instanceId, instanceId: rootStore.instanceId,
}, },
tags: (tags ?? []).map((tagId) => { tags: (tags ?? []).map((tagId) => {
const { usageCount, ...tag } = tagsStore.getTagById(tagId); const { usageCount, ...tag } = tagsStore.tagsById[tagId];
return tag; return tag;
}), }),

View File

@ -103,7 +103,7 @@ export default defineComponent({
}, },
tags() { tags() {
const tags = this.tagIds const tags = this.tagIds
.map((tagId: string) => this.tagsStore.getTagById(tagId)) .map((tagId: string) => this.tagsStore.tagsById[tagId])
.filter(Boolean); // if tag has been deleted from store .filter(Boolean); // if tag has been deleted from store
let toDisplay: TagEl[] = this.limit ? tags.slice(0, this.limit) : tags; let toDisplay: TagEl[] = this.limit ? tags.slice(0, this.limit) : tags;

View File

@ -130,7 +130,7 @@ export default defineComponent({
}); });
const appliedTags = computed<string[]>(() => { const appliedTags = computed<string[]>(() => {
return props.modelValue.filter((id: string) => tagsStore.getTagById(id)); return props.modelValue.filter((id: string) => tagsStore.tagsById[id]);
}); });
watch( watch(

View File

@ -72,7 +72,7 @@ export default defineComponent({
return this.tagsStore.isLoading; return this.tagsStore.isLoading;
}, },
tags(): ITag[] { tags(): ITag[] {
return this.tagIds.map((tagId: string) => this.tagsStore.getTagById(tagId)).filter(Boolean); // if tag is deleted from store return this.tagIds.map((tagId: string) => this.tagsStore.tagsById[tagId]).filter(Boolean); // if tag is deleted from store
}, },
hasTags(): boolean { hasTags(): boolean {
return this.tags.length > 0; return this.tags.length > 0;
@ -110,7 +110,7 @@ export default defineComponent({
}, },
async onUpdate(id: string, name: string, cb: (tag: boolean, error?: Error) => void) { async onUpdate(id: string, name: string, cb: (tag: boolean, error?: Error) => void) {
const tag = this.tagsStore.getTagById(id); const tag = this.tagsStore.tagsById[id];
const oldName = tag.name; const oldName = tag.name;
try { try {
@ -144,11 +144,11 @@ export default defineComponent({
}, },
async onDelete(id: string, cb: (deleted: boolean, error?: Error) => void) { async onDelete(id: string, cb: (deleted: boolean, error?: Error) => void) {
const tag = this.tagsStore.getTagById(id); const tag = this.tagsStore.tagsById[id];
const name = tag.name; const name = tag.name;
try { try {
const deleted = await this.tagsStore.delete(id); const deleted = await this.tagsStore.deleteTagById(id);
if (!deleted) { if (!deleted) {
throw new Error(this.$locale.baseText('tagsManager.couldNotDeleteTag')); throw new Error(this.$locale.baseText('tagsManager.couldNotDeleteTag'));
} }

View File

@ -1,105 +1,114 @@
import { createTag, deleteTag, getTags, updateTag } from '@/api/tags'; import * as tagsApi from '@/api/tags';
import { STORES } from '@/constants'; import { STORES } from '@/constants';
import type { ITag, ITagsState } from '@/Interface'; import type { ITag } from '@/Interface';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { useRootStore } from './root.store'; import { useRootStore } from './root.store';
import { computed, ref } from 'vue';
import { useWorkflowsStore } from './workflows.store'; import { useWorkflowsStore } from './workflows.store';
export const useTagsStore = defineStore(STORES.TAGS, { export const useTagsStore = defineStore(STORES.TAGS, () => {
state: (): ITagsState => ({ const tagsById = ref<Record<string, ITag>>({});
tags: {}, const loading = ref(false);
loading: false, const fetchedAll = ref(false);
fetchedAll: false, const fetchedUsageCount = ref(false);
fetchedUsageCount: false,
}),
getters: {
allTags(): ITag[] {
return Object.values(this.tags).sort((a, b) => a.name.localeCompare(b.name));
},
isLoading(): boolean {
return this.loading;
},
hasTags(): boolean {
return Object.keys(this.tags).length > 0;
},
getTagById() {
return (id: string) => this.tags[id];
},
},
actions: {
setAllTags(tags: ITag[]): void {
this.tags = tags.reduce((accu: { [id: string]: ITag }, tag: ITag) => {
accu[tag.id] = tag;
return accu; const rootStore = useRootStore();
}, {}); const workflowsStore = useWorkflowsStore();
this.fetchedAll = true;
},
upsertTags(tags: ITag[]): void {
tags.forEach((tag) => {
const tagId = tag.id;
const currentTag = this.tags[tagId];
if (currentTag) {
const newTag = {
...currentTag,
...tag,
};
this.tags = {
...this.tags,
[tagId]: newTag,
};
} else {
this.tags = {
...this.tags,
[tagId]: tag,
};
}
});
},
deleteTag(id: string): void {
const { [id]: deleted, ...rest } = this.tags;
this.tags = rest;
},
async fetchAll(params?: { force?: boolean; withUsageCount?: boolean }): Promise<ITag[]> { // Computed
const { force = false, withUsageCount = false } = params || {};
if (!force && this.fetchedAll && this.fetchedUsageCount === withUsageCount) { const allTags = computed(() => {
return Object.values(this.tags); return Object.values(tagsById.value).sort((a, b) => a.name.localeCompare(b.name));
});
const isLoading = computed(() => loading.value);
const hasTags = computed(() => Object.keys(tagsById.value).length > 0);
// Methods
const setAllTags = (loadedTags: ITag[]) => {
tagsById.value = loadedTags.reduce((accu: { [id: string]: ITag }, tag: ITag) => {
accu[tag.id] = tag;
return accu;
}, {});
fetchedAll.value = true;
};
const upsertTags = (toUpsertTags: ITag[]) => {
toUpsertTags.forEach((toUpsertTag) => {
const tagId = toUpsertTag.id;
const currentTag = tagsById.value[tagId];
if (currentTag) {
const newTag = {
...currentTag,
...toUpsertTag,
};
tagsById.value = {
...tagsById.value,
[tagId]: newTag,
};
} else {
tagsById.value = {
...tagsById.value,
[tagId]: toUpsertTag,
};
} }
});
};
this.loading = true; const deleteTag = (id: string) => {
const rootStore = useRootStore(); const { [id]: deleted, ...rest } = tagsById.value;
const tags = await getTags(rootStore.restApiContext, Boolean(withUsageCount)); tagsById.value = rest;
this.setAllTags(tags); };
this.loading = false;
return tags; const fetchAll = async (params?: { force?: boolean; withUsageCount?: boolean }) => {
}, const { force = false, withUsageCount = false } = params || {};
async create(name: string): Promise<ITag> { if (!force && fetchedAll.value && fetchedUsageCount.value === withUsageCount) {
const rootStore = useRootStore(); return Object.values(tagsById.value);
const tag = await createTag(rootStore.restApiContext, { name }); }
this.upsertTags([tag]);
return tag; loading.value = true;
}, const retrievedTags = await tagsApi.getTags(rootStore.restApiContext, Boolean(withUsageCount));
async rename({ id, name }: { id: string; name: string }) { setAllTags(retrievedTags);
const rootStore = useRootStore(); loading.value = false;
const tag = await updateTag(rootStore.restApiContext, id, { name }); return retrievedTags;
this.upsertTags([tag]); };
return tag; const create = async (name: string) => {
}, const createdTag = await tagsApi.createTag(rootStore.restApiContext, { name });
async delete(id: string) { upsertTags([createdTag]);
const rootStore = useRootStore(); return createdTag;
const deleted = await deleteTag(rootStore.restApiContext, id); };
if (deleted) { const rename = async ({ id, name }: { id: string; name: string }) => {
this.deleteTag(id); const updatedTag = await tagsApi.updateTag(rootStore.restApiContext, id, { name });
const workflowsStore = useWorkflowsStore(); upsertTags([updatedTag]);
workflowsStore.removeWorkflowTagId(id); return updatedTag;
} };
return deleted; const deleteTagById = async (id: string) => {
}, const deleted = await tagsApi.deleteTag(rootStore.restApiContext, id);
},
if (deleted) {
deleteTag(id);
workflowsStore.removeWorkflowTagId(id);
}
return deleted;
};
return {
allTags,
isLoading,
hasTags,
tagsById,
fetchAll,
create,
rename,
deleteTagById,
upsertTags,
deleteTag,
};
}); });