mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 21:07:28 -08:00
refactor(editor): Migrate tags.store
to use composition API (no-changelog) (#9891)
This commit is contained in:
parent
873b7e59dc
commit
8debac755e
|
@ -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',
|
||||||
|
|
|
@ -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;
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue