From 1bd17d6e50034c159150095f1c51a966293a6726 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sat, 25 Mar 2023 14:54:20 +0100 Subject: [PATCH] feat: remove all namespace leftovers --- src/components/home/contentAuth.vue | 1 - src/components/home/navigation.vue | 5 +- src/components/input/SelectNamespace.vue | 63 ----- .../misc/keyboard-shortcuts/shortcuts.ts | 4 +- src/components/misc/subscription.vue | 16 -- .../namespace/namespace-settings-dropdown.vue | 103 -------- src/components/project/ProjectWrapper.vue | 2 +- .../project/partials/ProjectCard.vue | 2 +- src/components/project/partials/filters.vue | 20 +- .../project/project-settings-dropdown.vue | 3 - .../quick-actions/quick-actions.vue | 40 +-- src/components/sharing/userTeam.vue | 34 +-- .../tasks/partials/projectSearch.vue | 17 -- .../tasks/partials/relatedTasks.vue | 28 +-- .../tasks/partials/singleTaskInProject.vue | 3 - src/composables/useNamespaceSearch.ts | 19 -- src/helpers/getNamespaceTitle.ts | 15 -- src/i18n/lang/en.json | 100 +------- src/modelTypes/INamespace.ts | 18 -- src/modelTypes/IProject.ts | 2 - src/modelTypes/IProjectDuplicate.ts | 2 - src/modelTypes/ITeamNamespace.ts | 6 - src/modelTypes/IUserNamespace.ts | 6 - src/models/namespace.ts | 45 ---- src/models/project.ts | 2 - src/models/projectDuplicateModel.ts | 2 - src/models/teamNamespace.ts | 13 - src/models/teamShareBase.ts | 2 +- src/models/userNamespace.ts | 14 -- src/services/namespace.ts | 30 --- src/services/project.ts | 2 +- src/services/savedFilter.ts | 5 - src/services/teamNamespace.ts | 23 -- src/services/userNamespace.ts | 23 -- src/stores/namespaces.ts | 236 ------------------ src/stores/projects.ts | 13 - src/views/Home.vue | 20 +- src/views/migrate/MigrationHandler.vue | 6 +- src/views/namespaces/NewNamespace.vue | 84 ------- src/views/namespaces/settings/archive.vue | 89 ------- src/views/namespaces/settings/delete.vue | 69 ----- src/views/namespaces/settings/edit.vue | 120 --------- src/views/namespaces/settings/share.vue | 67 ----- src/views/project/NewProject.vue | 1 - src/views/project/settings/background.vue | 5 - src/views/project/settings/duplicate.vue | 26 -- src/views/tasks/TaskDetailView.vue | 18 +- 47 files changed, 44 insertions(+), 1380 deletions(-) delete mode 100644 src/components/input/SelectNamespace.vue delete mode 100644 src/components/namespace/namespace-settings-dropdown.vue delete mode 100644 src/composables/useNamespaceSearch.ts delete mode 100644 src/helpers/getNamespaceTitle.ts delete mode 100644 src/modelTypes/INamespace.ts delete mode 100644 src/modelTypes/ITeamNamespace.ts delete mode 100644 src/modelTypes/IUserNamespace.ts delete mode 100644 src/models/namespace.ts delete mode 100644 src/models/teamNamespace.ts delete mode 100644 src/models/userNamespace.ts delete mode 100644 src/services/namespace.ts delete mode 100644 src/services/teamNamespace.ts delete mode 100644 src/services/userNamespace.ts delete mode 100644 src/stores/namespaces.ts delete mode 100644 src/views/namespaces/NewNamespace.vue delete mode 100644 src/views/namespaces/settings/archive.vue delete mode 100644 src/views/namespaces/settings/delete.vue delete mode 100644 src/views/namespaces/settings/edit.vue delete mode 100644 src/views/namespaces/settings/share.vue diff --git a/src/components/home/contentAuth.vue b/src/components/home/contentAuth.vue index a5b481dd2..5f5bb2799 100644 --- a/src/components/home/contentAuth.vue +++ b/src/components/home/contentAuth.vue @@ -94,7 +94,6 @@ watch(() => route.name as string, (routeName) => { ( [ 'home', - 'namespace.edit', 'teams.index', 'teams.edit', 'tasks.range', diff --git a/src/components/home/navigation.vue b/src/components/home/navigation.vue index 66a0d7e46..e90c2106a 100644 --- a/src/components/home/navigation.vue +++ b/src/components/home/navigation.vue @@ -159,12 +159,10 @@ import type {SortableEvent} from 'sortablejs' import BaseButton from '@/components/base/BaseButton.vue' import ProjectSettingsDropdown from '@/components/project/project-settings-dropdown.vue' -import NamespaceSettingsDropdown from '@/components/namespace/namespace-settings-dropdown.vue' import PoweredByLink from '@/components/home/PoweredByLink.vue' import Logo from '@/components/home/Logo.vue' import {calculateItemPosition} from '@/helpers/calculateItemPosition' -import {getNamespaceTitle} from '@/helpers/getNamespaceTitle' import {getProjectTitle} from '@/helpers/getProjectTitle' import type {IProject} from '@/modelTypes/IProject' import type {INamespace} from '@/modelTypes/INamespace' @@ -172,7 +170,6 @@ import ColorBubble from '@/components/misc/colorBubble.vue' import {useBaseStore} from '@/stores/base' import {useProjectStore} from '@/stores/projects' -import {useNamespaceStore} from '@/stores/namespaces' const drag = ref(false) const dragOptions = { @@ -199,7 +196,7 @@ const activeProjects = computed(() => { }) const namespaceTitles = computed(() => { - return namespaces.value.map((namespace) => getNamespaceTitle(namespace)) + return [] }) const namespaceProjectsCount = computed(() => { diff --git a/src/components/input/SelectNamespace.vue b/src/components/input/SelectNamespace.vue deleted file mode 100644 index e6bbfc31d..000000000 --- a/src/components/input/SelectNamespace.vue +++ /dev/null @@ -1,63 +0,0 @@ - - - \ No newline at end of file diff --git a/src/components/misc/keyboard-shortcuts/shortcuts.ts b/src/components/misc/keyboard-shortcuts/shortcuts.ts index 4b19e5bfb..0ea93fc5b 100644 --- a/src/components/misc/keyboard-shortcuts/shortcuts.ts +++ b/src/components/misc/keyboard-shortcuts/shortcuts.ts @@ -44,8 +44,8 @@ export const KEYBOARD_SHORTCUTS : ShortcutGroup[] = [ combination: 'then', }, { - title: 'keyboardShortcuts.navigation.namespaces', - keys: ['g', 'n'], + title: 'keyboardShortcuts.navigation.projects', + keys: ['g', 'p'], combination: 'then', }, { diff --git a/src/components/misc/subscription.vue b/src/components/misc/subscription.vue index ed32171be..4ef8719e8 100644 --- a/src/components/misc/subscription.vue +++ b/src/components/misc/subscription.vue @@ -73,12 +73,6 @@ const {t} = useI18n({useScope: 'global'}) const tooltipText = computed(() => { if (disabled.value) { - if (props.entity === 'project' && subscriptionEntity.value === 'namespace') { - return t('task.subscription.subscribedProjectThroughParentNamespace') - } - if (props.entity === 'task' && subscriptionEntity.value === 'namespace') { - return t('task.subscription.subscribedTaskThroughParentNamespace') - } if (props.entity === 'task' && subscriptionEntity.value === 'project') { return t('task.subscription.subscribedTaskThroughParentProject') } @@ -87,10 +81,6 @@ const tooltipText = computed(() => { } switch (props.entity) { - case 'namespace': - return props.modelValue !== null ? - t('task.subscription.subscribedNamespace') : - t('task.subscription.notSubscribedNamespace') case 'project': return props.modelValue !== null ? t('task.subscription.subscribedProject') : @@ -130,9 +120,6 @@ async function subscribe() { let message = '' switch (props.entity) { - case 'namespace': - message = t('task.subscription.subscribeSuccessNamespace') - break case 'project': message = t('task.subscription.subscribeSuccessProject') break @@ -153,9 +140,6 @@ async function unsubscribe() { let message = '' switch (props.entity) { - case 'namespace': - message = t('task.subscription.unsubscribeSuccessNamespace') - break case 'project': message = t('task.subscription.unsubscribeSuccessProject') break diff --git a/src/components/namespace/namespace-settings-dropdown.vue b/src/components/namespace/namespace-settings-dropdown.vue deleted file mode 100644 index 6df112eba..000000000 --- a/src/components/namespace/namespace-settings-dropdown.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/project/ProjectWrapper.vue b/src/components/project/ProjectWrapper.vue index b084e3042..14f9244c6 100644 --- a/src/components/project/ProjectWrapper.vue +++ b/src/components/project/ProjectWrapper.vue @@ -46,7 +46,7 @@ - {{ $t('project.archived') }} + {{ $t('project.archivedText') }} diff --git a/src/components/project/partials/ProjectCard.vue b/src/components/project/partials/ProjectCard.vue index 2837962f7..8f4986386 100644 --- a/src/components/project/partials/ProjectCard.vue +++ b/src/components/project/partials/ProjectCard.vue @@ -15,7 +15,7 @@ :class="{'is-visible': background}" :style="{'background-image': background !== null ? `url(${background})` : undefined}" /> - {{ $t('namespace.archived') }} + {{ $t('project.archived') }} -
- -
- -
-
@@ -189,7 +179,6 @@ import {camelCase} from 'camel-case' import type {ILabel} from '@/modelTypes/ILabel' import type {IUser} from '@/modelTypes/IUser' -import type {INamespace} from '@/modelTypes/INamespace' import type {IProject} from '@/modelTypes/IProject' import {useLabelStore} from '@/stores/labels' @@ -201,7 +190,6 @@ import EditLabels from '@/components/tasks/partials/editLabels.vue' import Fancycheckbox from '@/components/input/fancycheckbox.vue' import SelectUser from '@/components/input/SelectUser.vue' import SelectProject from '@/components/input/SelectProject.vue' -import SelectNamespace from '@/components/input/SelectNamespace.vue' import {parseDateOrString} from '@/helpers/time/parseDateOrString' import {dateIsValid, formatISO} from '@/helpers/time/formatDate' @@ -209,7 +197,6 @@ import {objectToSnakeCase} from '@/helpers/case' import UserService from '@/services/user' import ProjectService from '@/services/project' -import NamespaceService from '@/services/namespace' // FIXME: do not use this here for now. instead create new version from DEFAULT_PARAMS import {getDefaultParams} from '@/composables/useTaskList' @@ -240,7 +227,6 @@ const DEFAULT_FILTERS = { assignees: '', labels: '', project_id: '', - namespace: '', } as const const props = defineProps({ @@ -265,23 +251,20 @@ const filters = ref({...DEFAULT_FILTERS}) const services = { users: shallowReactive(new UserService()), projects: shallowReactive(new ProjectService()), - namespace: shallowReactive(new NamespaceService()), } interface Entities { users: IUser[] labels: ILabel[] projects: IProject[] - namespace: INamespace[] } -type EntityType = 'users' | 'labels' | 'projects' | 'namespace' +type EntityType = 'users' | 'labels' | 'projects' const entities: Entities = reactive({ users: [], labels: [], projects: [], - namespace: [], }) onMounted(() => { @@ -328,7 +311,6 @@ function prepareFilters() { prepareDate('reminders') prepareRelatedObjectFilter('users', 'assignees') prepareRelatedObjectFilter('projects', 'project_id') - prepareRelatedObjectFilter('namespace') prepareSingleValue('labels') diff --git a/src/components/project/project-settings-dropdown.vue b/src/components/project/project-settings-dropdown.vue index 8a56a9c6f..8ba552f4f 100644 --- a/src/components/project/project-settings-dropdown.vue +++ b/src/components/project/project-settings-dropdown.vue @@ -96,7 +96,6 @@ import type {ISubscription} from '@/modelTypes/ISubscription' import {isSavedFilter} from '@/services/savedFilter' import {useConfigStore} from '@/stores/config' import {useProjectStore} from '@/stores/projects' -import {useNamespaceStore} from '@/stores/namespaces' const props = defineProps({ project: { @@ -106,7 +105,6 @@ const props = defineProps({ }) const projectStore = useProjectStore() -const namespaceStore = useNamespaceStore() const subscription = ref(null) watchEffect(() => { subscription.value = props.project.subscription ?? null @@ -122,6 +120,5 @@ function setSubscriptionInStore(sub: ISubscription) { subscription: sub, } projectStore.setProject(updatedProject) - namespaceStore.setProjectInNamespaceById(updatedProject) } \ No newline at end of file diff --git a/src/components/quick-actions/quick-actions.vue b/src/components/quick-actions/quick-actions.vue index d04a10d67..111635004 100644 --- a/src/components/quick-actions/quick-actions.vue +++ b/src/components/quick-actions/quick-actions.vue @@ -61,7 +61,6 @@ import {useRouter} from 'vue-router' import TaskService from '@/services/task' import TeamService from '@/services/team' -import NamespaceModel from '@/models/namespace' import TeamModel from '@/models/team' import ProjectModel from '@/models/project' @@ -70,7 +69,6 @@ import QuickAddMagic from '@/components/tasks/partials/quick-add-magic.vue' import {useBaseStore} from '@/stores/base' import {useProjectStore} from '@/stores/projects' -import {useNamespaceStore} from '@/stores/namespaces' import {useLabelStore} from '@/stores/labels' import {useTaskStore} from '@/stores/tasks' @@ -81,7 +79,6 @@ import {success} from '@/message' import type {ITeam} from '@/modelTypes/ITeam' import type {ITask} from '@/modelTypes/ITask' -import type {INamespace} from '@/modelTypes/INamespace' import type {IProject} from '@/modelTypes/IProject' const {t} = useI18n({useScope: 'global'}) @@ -89,7 +86,6 @@ const router = useRouter() const baseStore = useBaseStore() const projectStore = useProjectStore() -const namespaceStore = useNamespaceStore() const labelStore = useLabelStore() const taskStore = useTaskStore() @@ -105,7 +101,6 @@ enum ACTION_TYPE { enum COMMAND_TYPE { NEW_TASK = 'newTask', NEW_PROJECT = 'newProject', - NEW_NAMESPACE = 'newNamespace', NEW_TEAM = 'newTeam', } @@ -147,7 +142,6 @@ const foundProjects = computed(() => { return [] } - const ncache: { [id: ProjectModel['id']]: INamespace } = {} const history = getHistory() const allProjects = [ ...new Set([ @@ -156,15 +150,7 @@ const foundProjects = computed(() => { ]), ] - return allProjects.filter((l) => { - if (typeof l === 'undefined' || l === null) { - return false - } - if (typeof ncache[l.namespaceId] === 'undefined') { - ncache[l.namespaceId] = namespaceStore.getNamespaceById(l.namespaceId) - } - return !ncache[l.namespaceId].isArchived - }) + return allProjects.filter((l) => typeof l !== 'undefined' && l !== null) }) // FIXME: use fuzzysearch @@ -205,7 +191,6 @@ const results = computed(() => { const loading = computed(() => taskService.loading || - namespaceStore.isLoading || projectStore.isLoading || teamService.loading, ) @@ -230,12 +215,6 @@ const commands = computed<{ [key in COMMAND_TYPE]: Command }>(() => ({ placeholder: t('quickActions.newProject'), action: newProject, }, - newNamespace: { - type: COMMAND_TYPE.NEW_NAMESPACE, - title: t('quickActions.cmds.newNamespace'), - placeholder: t('quickActions.newNamespace'), - action: newNamespace, - }, newTeam: { type: COMMAND_TYPE.NEW_TEAM, title: t('quickActions.cmds.newTeam'), @@ -252,7 +231,6 @@ const currentProject = computed(() => Object.keys(baseStore.currentProject).leng ) const hintText = computed(() => { - let namespace if (selectedCmd.value !== null && currentProject.value !== null) { switch (selectedCmd.value.type) { case COMMAND_TYPE.NEW_TASK: @@ -260,12 +238,7 @@ const hintText = computed(() => { title: currentProject.value.title, }) case COMMAND_TYPE.NEW_PROJECT: - namespace = namespaceStore.getNamespaceById( - currentProject.value.namespaceId, - ) - return t('quickActions.createProject', { - title: namespace?.title, - }) + return t('quickActions.createProject') } } const prefixes = @@ -278,7 +251,7 @@ const availableCmds = computed(() => { if (currentProject.value !== null) { cmds.push(commands.value.newTask, commands.value.newProject) } - cmds.push(commands.value.newNamespace, commands.value.newTeam) + cmds.push(commands.value.newTeam) return cmds }) @@ -506,7 +479,6 @@ async function newProject() { } const newProject = await projectStore.createProject(new ProjectModel({ title: query.value, - namespaceId: currentProject.value.namespaceId, })) success({ message: t('project.create.createdSuccess')}) await router.push({ @@ -515,12 +487,6 @@ async function newProject() { }) } -async function newNamespace() { - const newNamespace = new NamespaceModel({ title: query.value }) - await namespaceStore.createNamespace(newNamespace) - success({ message: t('namespace.create.success') }) -} - async function newTeam() { const newTeam = new TeamModel({ name: query.value }) const team = await teamService.create(newTeam) diff --git a/src/components/sharing/userTeam.vue b/src/components/sharing/userTeam.vue index 099887f71..35288cd0e 100644 --- a/src/components/sharing/userTeam.vue +++ b/src/components/sharing/userTeam.vue @@ -139,10 +139,6 @@ import {ref, reactive, computed, shallowReactive, type Ref} from 'vue' import type {PropType} from 'vue' import {useI18n} from 'vue-i18n' -import UserNamespaceService from '@/services/userNamespace' -import UserNamespaceModel from '@/models/userNamespace' -import type {IUserNamespace} from '@/modelTypes/IUserNamespace' - import UserProjectService from '@/services/userProject' import UserProjectModel from '@/models/userProject' import type {IUserProject} from '@/modelTypes/IUserProject' @@ -151,10 +147,6 @@ import UserService from '@/services/user' import UserModel, { getDisplayName } from '@/models/user' import type {IUser} from '@/modelTypes/IUser' -import TeamNamespaceService from '@/services/teamNamespace' -import TeamNamespaceModel from '@/models/teamNamespace' -import type { ITeamNamespace } from '@/modelTypes/ITeamNamespace' - import TeamProjectService from '@/services/teamProject' import TeamProjectModel from '@/models/teamProject' import type { ITeamProject } from '@/modelTypes/ITeamProject' @@ -170,13 +162,15 @@ import Nothing from '@/components/misc/nothing.vue' import {success} from '@/message' import {useAuthStore} from '@/stores/auth' +// FIXME: I think this whole thing can now only manage user/team sharing for projects? Maybe remove a little generalization? + const props = defineProps({ type: { - type: String as PropType<'project' | 'namespace'>, + type: String as PropType<'project'>, default: '', }, shareType: { - type: String as PropType<'user' | 'team' | 'namespace'>, + type: String as PropType<'user' | 'team'>, default: '', }, id: { @@ -191,9 +185,9 @@ const props = defineProps({ const {t} = useI18n({useScope: 'global'}) -// This user service is either a userNamespaceService or a userProjectService, depending on the type we are using -let stuffService: UserNamespaceService | UserProjectService | TeamProjectService | TeamNamespaceService -let stuffModel: IUserNamespace | IUserProject | ITeamProject | ITeamNamespace +// This user service is a userProjectService, depending on the type we are using +let stuffService: UserProjectService | TeamProjectService +let stuffModel: IUserProject | ITeamProject let searchService: UserService | TeamService let sharable: Ref @@ -231,10 +225,6 @@ const sharableName = computed(() => { return t('project.list.title') } - if (props.shareType === 'namespace') { - return t('namespace.namespace') - } - return '' }) @@ -247,11 +237,6 @@ if (props.shareType === 'user') { if (props.type === 'project') { stuffService = shallowReactive(new UserProjectService()) stuffModel = reactive(new UserProjectModel({projectId: props.id})) - } else if (props.type === 'namespace') { - stuffService = shallowReactive(new UserNamespaceService()) - stuffModel = reactive(new UserNamespaceModel({ - namespaceId: props.id, - })) } else { throw new Error('Unknown type: ' + props.type) } @@ -264,11 +249,6 @@ if (props.shareType === 'user') { if (props.type === 'project') { stuffService = shallowReactive(new TeamProjectService()) stuffModel = reactive(new TeamProjectModel({projectId: props.id})) - } else if (props.type === 'namespace') { - stuffService = shallowReactive(new TeamNamespaceService()) - stuffModel = reactive(new TeamNamespaceModel({ - namespaceId: props.id, - })) } else { throw new Error('Unknown type: ' + props.type) } diff --git a/src/components/tasks/partials/projectSearch.vue b/src/components/tasks/partials/projectSearch.vue index 21360e254..d016d3358 100644 --- a/src/components/tasks/partials/projectSearch.vue +++ b/src/components/tasks/partials/projectSearch.vue @@ -11,7 +11,6 @@ @search="findProjects" > @@ -23,10 +22,8 @@ import type {PropType} from 'vue' import {useI18n} from 'vue-i18n' import type {IProject} from '@/modelTypes/IProject' -import type {INamespace} from '@/modelTypes/INamespace' import {useProjectStore} from '@/stores/projects' -import {useNamespaceStore} from '@/stores/namespaces' import ProjectModel from '@/models/project' @@ -54,7 +51,6 @@ watch( ) const projectStore = useProjectStore() -const namespaceStore = useNamespaceStore() const foundProjects = ref([]) function findProjects(query: string) { if (query === '') { @@ -70,17 +66,4 @@ function select(l: IProject | null) { Object.assign(project, l) emit('update:modelValue', project) } - -function namespace(namespaceId: INamespace['id']) { - const namespace = namespaceStore.getNamespaceById(namespaceId) - return namespace !== null - ? namespace.title - : t('project.shared') -} - - \ No newline at end of file diff --git a/src/components/tasks/partials/relatedTasks.vue b/src/components/tasks/partials/relatedTasks.vue index fd7506d48..a4f10ce8b 100644 --- a/src/components/tasks/partials/relatedTasks.vue +++ b/src/components/tasks/partials/relatedTasks.vue @@ -46,11 +46,6 @@ class="different-project" v-if="task.projectId !== projectId" > - - {{ task.differentNamespace }} > - @@ -101,11 +96,6 @@ class="different-project" v-if="t.projectId !== projectId" > - - {{ t.differentNamespace }} > - @@ -168,10 +158,9 @@ import BaseButton from '@/components/base/BaseButton.vue' import Multiselect from '@/components/input/multiselect.vue' import Fancycheckbox from '@/components/input/fancycheckbox.vue' -import {useNamespaceStore} from '@/stores/namespaces' - import {error, success} from '@/message' import {useTaskStore} from '@/stores/tasks' +import {useProjectStore} from '@/stores/projects' const props = defineProps({ taskId: { @@ -196,7 +185,7 @@ const props = defineProps({ }) const taskStore = useTaskStore() -const namespaceStore = useNamespaceStore() +const projectStore = useProjectStore() const route = useRoute() const {t} = useI18n({useScope: 'global'}) @@ -230,24 +219,13 @@ async function findTasks(newQuery: string) { foundTasks.value = await taskService.getAll({}, {s: newQuery}) } -const getProjectAndNamespaceById = (projectId: number) => namespaceStore.getProjectAndNamespaceById(projectId, true) - -const namespace = computed(() => getProjectAndNamespaceById(props.projectId)?.namespace) - function mapRelatedTasks(tasks: ITask[]) { return tasks.map(task => { // by doing this here once we can save a lot of duplicate calls in the template - const { - project, - namespace: taskNamespace, - } = getProjectAndNamespaceById(task.projectId) || {project: null, namespace: null} + const project = projectStore.getProjectById(task.ProjectId) return { ...task, - differentNamespace: - (taskNamespace !== null && - taskNamespace.id !== namespace.value.id && - taskNamespace?.title) || null, differentProject: (project !== null && task.projectId !== props.projectId && diff --git a/src/components/tasks/partials/singleTaskInProject.vue b/src/components/tasks/partials/singleTaskInProject.vue index e45ff9367..4c3647ed9 100644 --- a/src/components/tasks/partials/singleTaskInProject.vue +++ b/src/components/tasks/partials/singleTaskInProject.vue @@ -149,7 +149,6 @@ import {formatDateSince, formatISO, formatDateLong} from '@/helpers/time/formatD import {success} from '@/message' import {useProjectStore} from '@/stores/projects' -import {useNamespaceStore} from '@/stores/namespaces' import {useBaseStore} from '@/stores/base' import {useTaskStore} from '@/stores/tasks' @@ -209,7 +208,6 @@ onBeforeUnmount(() => { const baseStore = useBaseStore() const projectStore = useProjectStore() const taskStore = useTaskStore() -const namespaceStore = useNamespaceStore() const project = computed(() => projectStore.getProjectById(task.value.projectId)) const projectColor = computed(() => project.value !== null ? project.value.hexColor : '') @@ -260,7 +258,6 @@ async function toggleFavorite() { task.value.isFavorite = !task.value.isFavorite task.value = await taskService.update(task.value) emit('task-updated', task.value) - namespaceStore.loadNamespacesIfFavoritesDontExist() } const deferDueDate = ref(null) diff --git a/src/composables/useNamespaceSearch.ts b/src/composables/useNamespaceSearch.ts deleted file mode 100644 index a75ee0ac7..000000000 --- a/src/composables/useNamespaceSearch.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {ref, computed} from 'vue' -import {useNamespaceStore} from '@/stores/namespaces' - -export function useNamespaceSearch() { - const query = ref('') - - const namespaceStore = useNamespaceStore() - const namespaces = computed(() => namespaceStore.searchNamespace(query.value)) - - function findNamespaces(newQuery: string) { - query.value = newQuery - } - - return { - namespaces, - findNamespaces, - } -} - diff --git a/src/helpers/getNamespaceTitle.ts b/src/helpers/getNamespaceTitle.ts deleted file mode 100644 index d13f39ab9..000000000 --- a/src/helpers/getNamespaceTitle.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {i18n} from '@/i18n' -import type {INamespace} from '@/modelTypes/INamespace' - -export const getNamespaceTitle = (n: INamespace) => { - if (n.id === -1) { - return i18n.global.t('namespace.pseudo.sharedProjects.title') - } - if (n.id === -2) { - return i18n.global.t('namespace.pseudo.favorites.title') - } - if (n.id === -3) { - return i18n.global.t('namespace.pseudo.savedFilters.title') - } - return n.title -} diff --git a/src/i18n/lang/en.json b/src/i18n/lang/en.json index 1e7af7eea..63af968c1 100644 --- a/src/i18n/lang/en.json +++ b/src/i18n/lang/en.json @@ -143,7 +143,7 @@ }, "deletion": { "title": "Delete your Vikunja Account", - "text1": "The deletion of your account is permanent and cannot be undone. We will delete all your namespaces, projects, tasks and everything associated with it.", + "text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.", "text2": "To proceed, please enter your password. You will receive an email with further instructions.", "confirm": "Delete my account", "requestSuccess": "The request was successful. You'll receive an email with further instructions.", @@ -165,7 +165,8 @@ } }, "project": { - "archived": "This project is archived. It is not possible to create new or edit tasks for it.", + "archivedText": "This project is archived. It is not possible to create new or edit tasks for it.", + "archived": "Archived", "showArchived": "Show Archived", "title": "Project Title", "color": "Color", @@ -211,7 +212,6 @@ "duplicate": { "title": "Duplicate this project", "label": "Duplicate", - "text": "Select a namespace which should hold the duplicated project:", "success": "The project was successfully duplicated." }, "edit": { @@ -322,66 +322,6 @@ } } }, - "namespace": { - "title": "Namespaces & Projects", - "namespace": "Namespace", - "noneAvailable": "You don't have any namespaces right now.", - "unarchive": "Un-Archive", - "archived": "Archived", - "noProjects": "This namespace does not contain any projects.", - "createProject": "Create a new project in this namespace.", - "namespaces": "Namespaces", - "search": "Type to search for a namespace…", - "create": { - "title": "New namespace", - "titleRequired": "Please specify a title.", - "explanation": "A namespace is a collection of projects you can share and use to organize your projects with. In fact, every project belongs to a namespace.", - "tooltip": "What's a namespace?", - "success": "The namespace was successfully created." - }, - "archive": { - "titleArchive": "Archive \"{namespace}\"", - "titleUnarchive": "Un-Archive \"{namespace}\"", - "archiveText": "You won't be able to edit this namespace or create new projects until you un-archive it. This will also archive all projects in this namespace.", - "unarchiveText": "You will be able to create new projects or edit it.", - "success": "The namespace was successfully archived.", - "unarchiveSuccess": "The namespace was successfully un-archived.", - "description": "If a namespace is archived, you cannot create new projects or edit it." - }, - "delete": { - "title": "Delete \"{namespace}\"", - "text1": "Are you sure you want to delete this namespace and all of its contents?", - "text2": "This includes all projects and tasks and CANNOT BE UNDONE!", - "success": "The namespace was successfully deleted." - }, - "edit": { - "title": "Edit \"{namespace}\"", - "success": "The namespace was successfully updated." - }, - "share": { - "title": "Share \"{namespace}\"" - }, - "attributes": { - "title": "Namespace Title", - "titlePlaceholder": "The namespace title goes here…", - "description": "Description", - "descriptionPlaceholder": "The namespaces description goes here…", - "color": "Color", - "archived": "Is Archived", - "isArchived": "This namespace is archived" - }, - "pseudo": { - "sharedProjects": { - "title": "Shared Projects" - }, - "favorites": { - "title": "Favorites" - }, - "savedFilters": { - "title": "Filters" - } - } - }, "filters": { "title": "Filters", "clear": "Clear Filters", @@ -403,7 +343,7 @@ }, "create": { "title": "New Saved Filter", - "description": "A saved filter is a virtual project which is computed from a set of filters each time it is accessed. Once created, it will appear in a special namespace.", + "description": "A saved filter is a virtual project which is computed from a set of filters each time it is accessed.", "action": "Create new saved filter", "titleRequired": "Please provide a title for the filter." }, @@ -677,19 +617,13 @@ "updated": "Updated" }, "subscription": { - "subscribedProjectThroughParentNamespace": "You can't unsubscribe here because you are subscribed to this project through its namespace.", - "subscribedTaskThroughParentNamespace": "You can't unsubscribe here because you are subscribed to this task through its namespace.", "subscribedTaskThroughParentProject": "You can't unsubscribe here because you are subscribed to this task through its project.", - "subscribedNamespace": "You are currently subscribed to this namespace and will receive notifications for changes.", - "notSubscribedNamespace": "You are not subscribed to this namespace and won't receive notifications for changes.", "subscribedProject": "You are currently subscribed to this project and will receive notifications for changes.", "notSubscribedProject": "You are not subscribed to this project and won't receive notifications for changes.", "subscribedTask": "You are currently subscribed to this task and will receive notifications for changes.", "notSubscribedTask": "You are not subscribed to this task and won't receive notifications for changes.", "subscribe": "Subscribe", "unsubscribe": "Unsubscribe", - "subscribeSuccessNamespace": "You are now subscribed to this namespace", - "unsubscribeSuccessNamespace": "You are now unsubscribed to this namespace", "subscribeSuccessProject": "You are now subscribed to this project", "unsubscribeSuccessProject": "You are now unsubscribed to this project", "subscribeSuccessTask": "You are now subscribed to this task", @@ -766,7 +700,6 @@ "searchPlaceholder": "Type search for a new task to add as related…", "createPlaceholder": "Add this as new related task", "differentProject": "This task belongs to a different project.", - "differentNamespace": "This task belongs to a different namespace.", "noneYet": "No task relations yet.", "delete": "Delete Task Relation", "deleteText1": "Are you sure you want to delete this task relation?", @@ -851,19 +784,19 @@ "delete": { "header": "Delete the team", "text1": "Are you sure you want to delete this team and all of its members?", - "text2": "All team members will lose access to projects and namespaces shared with this team. This CANNOT BE UNDONE!", + "text2": "All team members will lose access to projects shared with this team. This CANNOT BE UNDONE!", "success": "The team was successfully deleted." }, "deleteUser": { "header": "Remove a user from the team", "text1": "Are you sure you want to remove this user from the team?", - "text2": "They will lose access to all projects and namespaces this team has access to. This CANNOT BE UNDONE!", + "text2": "They will lose access to all projects this team has access to. This CANNOT BE UNDONE!", "success": "The user was successfully deleted from the team." }, "leave": { "title": "Leave team", "text1": "Are you sure you want to leave this team?", - "text2": "You will lose access to all projects and namespaces this team has access to. If you change your mind you'll need a team admin to add you again.", + "text2": "You will lose access to all projects this team has access to. If you change your mind you'll need a team admin to add you again.", "success": "You have successfully left the team." } }, @@ -913,9 +846,9 @@ "title": "Navigation", "overview": "Navigate to overview", "upcoming": "Navigate to upcoming tasks", - "namespaces": "Navigate to namespaces & projects", "labels": "Navigate to labels", - "teams": "Navigate to teams" + "teams": "Navigate to teams", + "projects": "Navigate to projects" } }, "update": { @@ -949,7 +882,7 @@ "notification": { "title": "Notifications", "none": "You don't have any notifications. Have a nice day!", - "explainer": "Notifications will appear here when actions on namespaces, projects or tasks you subscribed to happen." + "explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen." }, "quickActions": { "commands": "Commands", @@ -960,14 +893,12 @@ "teams": "Teams", "newProject": "Enter the title of the new project…", "newTask": "Enter the title of the new task…", - "newNamespace": "Enter the title of the new namespace…", "newTeam": "Enter the name of the new team…", "createTask": "Create a task in the current project ({title})", - "createProject": "Create a project in the current namespace ({title})", + "createProject": "Create a project", "cmds": { "newTask": "New task", "newProject": "New project", - "newNamespace": "New namespace", "newTeam": "New team" } }, @@ -1023,16 +954,9 @@ "4017": "Invalid task filter comparator.", "4018": "Invalid task filter concatenator.", "4019": "Invalid task filter value.", - "5001": "The namespace does not exist.", - "5003": "You do not have access to the specified namespace.", - "5006": "The namespace name cannot be empty.", - "5009": "You need to have namespace read access to perform that action.", - "5010": "This team does not have access to that namespace.", - "5011": "This user has already access to that namespace.", - "5012": "The namespace is archived and can therefore only be accessed read only.", "6001": "The team name cannot be empty.", "6002": "The team does not exist.", - "6004": "The team already has access to that namespace or project.", + "6004": "The team already has access to that project.", "6005": "The user is already a member of that team.", "6006": "Cannot delete the last team member.", "6007": "The team does not have access to the project to perform that action.", diff --git a/src/modelTypes/INamespace.ts b/src/modelTypes/INamespace.ts deleted file mode 100644 index 555d7463d..000000000 --- a/src/modelTypes/INamespace.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type {IAbstract} from './IAbstract' -import type {IProject} from './IProject' -import type {IUser} from './IUser' -import type {ISubscription} from './ISubscription' - -export interface INamespace extends IAbstract { - id: number - title: string - description: string - owner: IUser - projects: IProject[] - isArchived: boolean - hexColor: string - subscription: ISubscription - - created: Date - updated: Date -} \ No newline at end of file diff --git a/src/modelTypes/IProject.ts b/src/modelTypes/IProject.ts index 8d6ef81fe..6040d13bb 100644 --- a/src/modelTypes/IProject.ts +++ b/src/modelTypes/IProject.ts @@ -2,7 +2,6 @@ import type {IAbstract} from './IAbstract' import type {ITask} from './ITask' import type {IUser} from './IUser' import type {ISubscription} from './ISubscription' -import type {INamespace} from './INamespace' export interface IProject extends IAbstract { @@ -11,7 +10,6 @@ export interface IProject extends IAbstract { description: string owner: IUser tasks: ITask[] - namespaceId: INamespace['id'] isArchived: boolean hexColor: string identifier: string diff --git a/src/modelTypes/IProjectDuplicate.ts b/src/modelTypes/IProjectDuplicate.ts index ab738d9bc..a498759dd 100644 --- a/src/modelTypes/IProjectDuplicate.ts +++ b/src/modelTypes/IProjectDuplicate.ts @@ -1,9 +1,7 @@ import type {IAbstract} from './IAbstract' import type {IProject} from './IProject' -import type {INamespace} from './INamespace' export interface IProjectDuplicate extends IAbstract { projectId: number - namespaceId: INamespace['id'] project: IProject } \ No newline at end of file diff --git a/src/modelTypes/ITeamNamespace.ts b/src/modelTypes/ITeamNamespace.ts deleted file mode 100644 index e66a98bb6..000000000 --- a/src/modelTypes/ITeamNamespace.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type {ITeamShareBase} from './ITeamShareBase' -import type {INamespace} from './INamespace' - -export interface ITeamNamespace extends ITeamShareBase { - namespaceId: INamespace['id'] -} \ No newline at end of file diff --git a/src/modelTypes/IUserNamespace.ts b/src/modelTypes/IUserNamespace.ts deleted file mode 100644 index e2bd1b468..000000000 --- a/src/modelTypes/IUserNamespace.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type {IUserShareBase} from './IUserShareBase' -import type {INamespace} from './INamespace' - -export interface IUserNamespace extends IUserShareBase { - namespaceId: INamespace['id'] -} \ No newline at end of file diff --git a/src/models/namespace.ts b/src/models/namespace.ts deleted file mode 100644 index 7419d2e64..000000000 --- a/src/models/namespace.ts +++ /dev/null @@ -1,45 +0,0 @@ -import AbstractModel from './abstractModel' -import ProjectModel from './project' -import UserModel from './user' -import SubscriptionModel from '@/models/subscription' - -import type {INamespace} from '@/modelTypes/INamespace' -import type {IUser} from '@/modelTypes/IUser' -import type {IProject} from '@/modelTypes/IProject' -import type {ISubscription} from '@/modelTypes/ISubscription' - -export default class NamespaceModel extends AbstractModel implements INamespace { - id = 0 - title = '' - description = '' - owner: IUser = UserModel - projects: IProject[] = [] - isArchived = false - hexColor = '' - subscription: ISubscription = null - - created: Date = null - updated: Date = null - - constructor(data: Partial = {}) { - super() - this.assignData(data) - - if (this.hexColor !== '' && this.hexColor.substring(0, 1) !== '#') { - this.hexColor = '#' + this.hexColor - } - - this.projects = this.projects.map(l => { - return new ProjectModel(l) - }) - - this.owner = new UserModel(this.owner) - - if(typeof this.subscription !== 'undefined' && this.subscription !== null) { - this.subscription = new SubscriptionModel(this.subscription) - } - - this.created = new Date(this.created) - this.updated = new Date(this.updated) - } -} diff --git a/src/models/project.ts b/src/models/project.ts index c090e2917..01c516b72 100644 --- a/src/models/project.ts +++ b/src/models/project.ts @@ -6,7 +6,6 @@ import SubscriptionModel from '@/models/subscription' import type {IProject} from '@/modelTypes/IProject' import type {IUser} from '@/modelTypes/IUser' import type {ITask} from '@/modelTypes/ITask' -import type {INamespace} from '@/modelTypes/INamespace' import type {ISubscription} from '@/modelTypes/ISubscription' export default class ProjectModel extends AbstractModel implements IProject { @@ -15,7 +14,6 @@ export default class ProjectModel extends AbstractModel implements IPr description = '' owner: IUser = UserModel tasks: ITask[] = [] - namespaceId: INamespace['id'] = 0 isArchived = false hexColor = '' identifier = '' diff --git a/src/models/projectDuplicateModel.ts b/src/models/projectDuplicateModel.ts index 479c91a0d..f490b5838 100644 --- a/src/models/projectDuplicateModel.ts +++ b/src/models/projectDuplicateModel.ts @@ -2,12 +2,10 @@ import AbstractModel from './abstractModel' import ProjectModel from './project' import type {IProjectDuplicate} from '@/modelTypes/IProjectDuplicate' -import type {INamespace} from '@/modelTypes/INamespace' import type {IProject} from '@/modelTypes/IProject' export default class ProjectDuplicateModel extends AbstractModel implements IProjectDuplicate { projectId = 0 - namespaceId: INamespace['id'] = 0 project: IProject = ProjectModel constructor(data : Partial) { diff --git a/src/models/teamNamespace.ts b/src/models/teamNamespace.ts deleted file mode 100644 index 3d583ae80..000000000 --- a/src/models/teamNamespace.ts +++ /dev/null @@ -1,13 +0,0 @@ -import TeamShareBaseModel from './teamShareBase' - -import type {ITeamNamespace} from '@/modelTypes/ITeamNamespace' -import type {INamespace} from '@/modelTypes/INamespace' - -export default class TeamNamespaceModel extends TeamShareBaseModel implements ITeamNamespace { - namespaceId: INamespace['id'] = 0 - - constructor(data: Partial) { - super(data) - this.assignData(data) - } -} \ No newline at end of file diff --git a/src/models/teamShareBase.ts b/src/models/teamShareBase.ts index b0c04d8da..b2dc266a6 100644 --- a/src/models/teamShareBase.ts +++ b/src/models/teamShareBase.ts @@ -6,7 +6,7 @@ import type {ITeam} from '@/modelTypes/ITeam' /** * This class is a base class for common team sharing model. - * It is extended in a way so it can be used for namespaces as well for projects. + * It is extended in a way, so it can be used for projects. */ export default class TeamShareBaseModel extends AbstractModel implements ITeamShareBase { teamId: ITeam['id'] = 0 diff --git a/src/models/userNamespace.ts b/src/models/userNamespace.ts deleted file mode 100644 index 326373837..000000000 --- a/src/models/userNamespace.ts +++ /dev/null @@ -1,14 +0,0 @@ -import UserShareBaseModel from './userShareBase' - -import type {INamespace} from '@/modelTypes/INamespace' -import type {IUserNamespace} from '@/modelTypes/IUserNamespace' - -// This class extends the user share model with a 'rights' parameter which is used in sharing -export default class UserNamespaceModel extends UserShareBaseModel implements IUserNamespace { - namespaceId: INamespace['id'] = 0 - - constructor(data: Partial) { - super(data) - this.assignData(data) - } -} \ No newline at end of file diff --git a/src/services/namespace.ts b/src/services/namespace.ts deleted file mode 100644 index dfc056bb1..000000000 --- a/src/services/namespace.ts +++ /dev/null @@ -1,30 +0,0 @@ -import AbstractService from './abstractService' -import NamespaceModel from '../models/namespace' -import type {INamespace} from '@/modelTypes/INamespace' -import {colorFromHex} from '@/helpers/color/colorFromHex' - -export default class NamespaceService extends AbstractService { - constructor() { - super({ - create: '/namespaces', - get: '/namespaces/{id}', - getAll: '/namespaces', - update: '/namespaces/{id}', - delete: '/namespaces/{id}', - }) - } - - modelFactory(data) { - return new NamespaceModel(data) - } - - beforeUpdate(namespace) { - namespace.hexColor = colorFromHex(namespace.hexColor) - return namespace - } - - beforeCreate(namespace) { - namespace.hexColor = colorFromHex(namespace.hexColor) - return namespace - } -} \ No newline at end of file diff --git a/src/services/project.ts b/src/services/project.ts index 4bd4ae5bc..42892eacf 100644 --- a/src/services/project.ts +++ b/src/services/project.ts @@ -7,7 +7,7 @@ import {colorFromHex} from '@/helpers/color/colorFromHex' export default class ProjectService extends AbstractService { constructor() { super({ - create: '/namespaces/{namespaceId}/projects', + create: '/projects', get: '/projects/{id}', getAll: '/projects', update: '/projects/{id}', diff --git a/src/services/savedFilter.ts b/src/services/savedFilter.ts index e46240d15..eaee321da 100644 --- a/src/services/savedFilter.ts +++ b/src/services/savedFilter.ts @@ -12,7 +12,6 @@ import AbstractService from '@/services/abstractService' import SavedFilterModel from '@/models/savedFilter' import {useBaseStore} from '@/stores/base' -import {useNamespaceStore} from '@/stores/namespaces' import {objectToSnakeCase, objectToCamelCase} from '@/helpers/case' import {success} from '@/message' @@ -81,7 +80,6 @@ export default class SavedFilterService extends AbstractService { export function useSavedFilter(projectId?: MaybeRef) { const router = useRouter() const {t} = useI18n({useScope:'global'}) - const namespaceStore = useNamespaceStore() const filterService = shallowReactive(new SavedFilterService()) @@ -110,13 +108,11 @@ export function useSavedFilter(projectId?: MaybeRef) { async function createFilter() { filter.value = await filterService.create(filter.value) - await namespaceStore.loadNamespaces() router.push({name: 'project.index', params: {projectId: getProjectId(filter.value)}}) } async function saveFilter() { const response = await filterService.update(filter.value) - await namespaceStore.loadNamespaces() success({message: t('filters.edit.success')}) response.filters = objectToSnakeCase(response.filters) filter.value = response @@ -129,7 +125,6 @@ export function useSavedFilter(projectId?: MaybeRef) { async function deleteFilter() { await filterService.delete(filter.value) - await namespaceStore.loadNamespaces() success({message: t('filters.delete.success')}) router.push({name: 'projects.index'}) } diff --git a/src/services/teamNamespace.ts b/src/services/teamNamespace.ts deleted file mode 100644 index 1547a3dfa..000000000 --- a/src/services/teamNamespace.ts +++ /dev/null @@ -1,23 +0,0 @@ -import AbstractService from './abstractService' -import TeamNamespaceModel from '@/models/teamNamespace' -import type {ITeamNamespace} from '@/modelTypes/ITeamNamespace' -import TeamModel from '@/models/team' - -export default class TeamNamespaceService extends AbstractService { - constructor() { - super({ - create: '/namespaces/{namespaceId}/teams', - getAll: '/namespaces/{namespaceId}/teams', - update: '/namespaces/{namespaceId}/teams/{teamId}', - delete: '/namespaces/{namespaceId}/teams/{teamId}', - }) - } - - modelFactory(data) { - return new TeamNamespaceModel(data) - } - - modelGetAllFactory(data) { - return new TeamModel(data) - } -} \ No newline at end of file diff --git a/src/services/userNamespace.ts b/src/services/userNamespace.ts deleted file mode 100644 index 6011899c1..000000000 --- a/src/services/userNamespace.ts +++ /dev/null @@ -1,23 +0,0 @@ -import AbstractService from './abstractService' -import UserNamespaceModel from '@/models/userNamespace' -import type {IUserNamespace} from '@/modelTypes/IUserNamespace' -import UserModel from '@/models/user' - -export default class UserNamespaceService extends AbstractService { - constructor() { - super({ - create: '/namespaces/{namespaceId}/users', - getAll: '/namespaces/{namespaceId}/users', - update: '/namespaces/{namespaceId}/users/{userId}', - delete: '/namespaces/{namespaceId}/users/{userId}', - }) - } - - modelFactory(data) { - return new UserNamespaceModel(data) - } - - modelGetAllFactory(data) { - return new UserModel(data) - } -} \ No newline at end of file diff --git a/src/stores/namespaces.ts b/src/stores/namespaces.ts deleted file mode 100644 index c038a8eb2..000000000 --- a/src/stores/namespaces.ts +++ /dev/null @@ -1,236 +0,0 @@ -import {computed, readonly, ref} from 'vue' -import {defineStore, acceptHMRUpdate} from 'pinia' - -import NamespaceService from '../services/namespace' -import {setModuleLoading} from '@/stores/helper' -import {createNewIndexer} from '@/indexes' -import type {INamespace} from '@/modelTypes/INamespace' -import type {IProject} from '@/modelTypes/IProject' -import {useProjectStore} from '@/stores/projects' - -const {add, remove, search, update} = createNewIndexer('namespaces', ['title', 'description']) - -export const useNamespaceStore = defineStore('namespace', () => { - const projectStore = useProjectStore() - - const isLoading = ref(false) - // FIXME: should be object with id as key - const namespaces = ref([]) - - const getProjectAndNamespaceById = computed(() => (projectId: IProject['id'], ignorePseudoNamespaces = false) => { - for (const n in namespaces.value) { - - if (ignorePseudoNamespaces && namespaces.value[n].id < 0) { - continue - } - - for (const l in namespaces.value[n].projects) { - if (namespaces.value[n].projects[l].id === projectId) { - return { - project: namespaces.value[n].projects[l], - namespace: namespaces.value[n], - } - } - } - } - return null - }) - - const getNamespaceById = computed(() => (namespaceId: INamespace['id']) => { - return namespaces.value.find(({id}) => id == namespaceId) || null - }) - - const searchNamespace = computed(() => { - return (query: string) => ( - search(query) - ?.filter(value => value > 0) - .map(getNamespaceById.value) - .filter(n => n !== null) - || [] - ) - }) - - - function setIsLoading(newIsLoading: boolean) { - isLoading.value = newIsLoading - } - - function setNamespaces(newNamespaces: INamespace[]) { - namespaces.value = newNamespaces - newNamespaces.forEach(n => { - add(n) - - // Check for each project in that namespace if it has a subscription and set it if not - n.projects.forEach(l => { - if (l.subscription === null || l.subscription.entity !== 'project') { - l.subscription = n.subscription - } - }) - }) - } - - function setNamespaceById(namespace: INamespace) { - const namespaceIndex = namespaces.value.findIndex(n => n.id === namespace.id) - - if (namespaceIndex === -1) { - return - } - - if (!namespace.projects || namespace.projects.length === 0) { - namespace.projects = namespaces.value[namespaceIndex].projects - } - - // Check for each project in that namespace if it has a subscription and set it if not - namespace.projects.forEach(l => { - if (l.subscription === null || l.subscription.entity !== 'project') { - l.subscription = namespace.subscription - } - }) - - namespaces.value[namespaceIndex] = namespace - update(namespace) - } - - function setProjectInNamespaceById(project: IProject) { - for (const n in namespaces.value) { - // We don't have the namespace id on the project which means we need to loop over all projects until we find it. - // FIXME: Not ideal at all - we should fix that at the api level. - if (namespaces.value[n].id === project.namespaceId) { - for (const l in namespaces.value[n].projects) { - if (namespaces.value[n].projects[l].id === project.id) { - const namespace = namespaces.value[n] - namespace.projects[l] = project - namespaces.value[n] = namespace - return - } - } - } - } - } - - function addNamespace(namespace: INamespace) { - namespaces.value.push(namespace) - add(namespace) - } - - function removeNamespaceById(namespaceId: INamespace['id']) { - for (const n in namespaces.value) { - if (namespaces.value[n].id === namespaceId) { - remove(namespaces.value[n]) - namespaces.value.splice(n, 1) - return - } - } - } - - function addProjectToNamespace(project: IProject) { - for (const n in namespaces.value) { - if (namespaces.value[n].id === project.namespaceId) { - namespaces.value[n].projects.push(project) - return - } - } - } - - function removeProjectFromNamespaceById(project: IProject) { - for (const n in namespaces.value) { - // We don't have the namespace id on the project which means we need to loop over all projects until we find it. - // FIXME: Not ideal at all - we should fix that at the api level. - if (namespaces.value[n].id === project.namespaceId) { - for (const l in namespaces.value[n].projects) { - if (namespaces.value[n].projects[l].id === project.id) { - namespaces.value[n].projects.splice(l, 1) - return - } - } - } - } - } - - async function loadNamespaces() { - const cancel = setModuleLoading(setIsLoading) - - const namespaceService = new NamespaceService() - try { - // We always load all namespaces and filter them on the frontend - const namespaces = await namespaceService.getAll({}, {is_archived: true}) as INamespace[] - setNamespaces(namespaces) - - // Put all projects in the project state - const projects = namespaces.flatMap(({projects}) => projects) - - projectStore.setProjects(projects) - - return namespaces - } finally { - cancel() - } - } - - function loadNamespacesIfFavoritesDontExist() { - // The first or second namespace should be the one holding all favorites - if (namespaces.value[0].id === -2 || namespaces.value[1]?.id === -2) { - return - } - return loadNamespaces() - } - - function removeFavoritesNamespaceIfEmpty() { - if (namespaces.value[0].id === -2 && namespaces.value[0].projects.length === 0) { - namespaces.value.splice(0, 1) - } - } - - async function deleteNamespace(namespace: INamespace) { - const cancel = setModuleLoading(setIsLoading) - const namespaceService = new NamespaceService() - - try { - const response = await namespaceService.delete(namespace) - removeNamespaceById(namespace.id) - return response - } finally { - cancel() - } - } - - async function createNamespace(namespace: INamespace) { - const cancel = setModuleLoading(setIsLoading) - const namespaceService = new NamespaceService() - - try { - const createdNamespace = await namespaceService.create(namespace) - addNamespace(createdNamespace) - return createdNamespace - } finally { - cancel() - } - } - - return { - isLoading: readonly(isLoading), - namespaces: readonly(namespaces), - - getProjectAndNamespaceById, - getNamespaceById, - searchNamespace, - - setNamespaces, - setNamespaceById, - setProjectInNamespaceById, - addNamespace, - removeNamespaceById, - addProjectToNamespace, - removeProjectFromNamespaceById, - loadNamespaces, - loadNamespacesIfFavoritesDontExist, - removeFavoritesNamespaceIfEmpty, - deleteNamespace, - createNamespace, - } -}) - -// support hot reloading -if (import.meta.hot) { - import.meta.hot.accept(acceptHMRUpdate(useNamespaceStore, import.meta.hot)) -} \ No newline at end of file diff --git a/src/stores/projects.ts b/src/stores/projects.ts index 77cc698f7..96ccc92e0 100644 --- a/src/stores/projects.ts +++ b/src/stores/projects.ts @@ -6,7 +6,6 @@ import ProjectService from '@/services/project' import {setModuleLoading} from '@/stores/helper' import {removeProjectFromHistory} from '@/modules/projectHistory' import {createNewIndexer} from '@/indexes' -import {useNamespaceStore} from './namespaces' import type {IProject} from '@/modelTypes/IProject' @@ -26,7 +25,6 @@ export interface ProjectState { export const useProjectStore = defineStore('project', () => { const baseStore = useBaseStore() - const namespaceStore = useNamespaceStore() const isLoading = ref(false) @@ -100,8 +98,6 @@ export const useProjectStore = defineStore('project', () => { try { const createdProject = await projectService.create(project) - createdProject.namespaceId = project.namespaceId - namespaceStore.addProjectToNamespace(createdProject) setProject(createdProject) return createdProject } finally { @@ -116,21 +112,13 @@ export const useProjectStore = defineStore('project', () => { try { await projectService.update(project) setProject(project) - namespaceStore.setProjectInNamespaceById(project) // the returned project from projectService.update is the same! // in order to not create a manipulation in pinia store we have to create a new copy const newProject = { ...project, - namespaceId: FavoriteProjectsNamespace, } - namespaceStore.removeProjectFromNamespaceById(newProject) - if (project.isFavorite) { - namespaceStore.addProjectToNamespace(newProject) - } - namespaceStore.loadNamespacesIfFavoritesDontExist() - namespaceStore.removeFavoritesNamespaceIfEmpty() return newProject } catch (e) { // Reset the project state to the initial one to avoid confusion for the user @@ -151,7 +139,6 @@ export const useProjectStore = defineStore('project', () => { try { const response = await projectService.delete(project) removeProjectById(project) - namespaceStore.removeProjectFromNamespaceById(project) removeProjectFromHistory({id: project.id}) return response } finally { diff --git a/src/views/Home.vue b/src/views/Home.vue index dbcf52f90..6958ec04c 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -17,22 +17,11 @@ @taskAdded="updateTaskKey" class="is-max-width-desktop" /> -