101 lines
4.0 KiB
JavaScript
101 lines
4.0 KiB
JavaScript
import { computed, onMounted, onUnmounted, ref } from "vue";
|
|
import { handleProjectSession, pageSizes, requestProjectAPI } from "./ProjectRequest.js";
|
|
import { useProjectMembers } from "./ProjectMembers.js";
|
|
import { useProjectLifecycle } from "./ProjectLifecycle.js";
|
|
|
|
export function useProjectManagement() {
|
|
const projects = ref([]);
|
|
const selectedProject = ref(null);
|
|
const loadingProjects = ref(false);
|
|
const projectError = ref("");
|
|
const projectPageSize = ref(5);
|
|
const projectCursors = ref([""]);
|
|
const projectPage = ref(0);
|
|
const projectHasMore = ref(false);
|
|
const projectNextCursor = ref("");
|
|
const canCreateProject = ref(false);
|
|
const members = useProjectMembers(selectedProject);
|
|
const lifecycle = useProjectLifecycle(selectedProject, canCreateProject,
|
|
computed(() => loadingProjects.value || members.savingMember.value), refreshAfterMutation);
|
|
let generation = 0;
|
|
let controller;
|
|
|
|
async function loadProjects(options = {}) {
|
|
if (members.savingMember.value || (lifecycle.savingProject.value && options.internal !== true)) return;
|
|
const current = ++generation;
|
|
controller?.abort();
|
|
controller = new AbortController();
|
|
loadingProjects.value = true;
|
|
projectError.value = "";
|
|
const selectedID = selectedProject.value?.id;
|
|
projects.value = [];
|
|
selectedProject.value = null;
|
|
projectHasMore.value = false;
|
|
projectNextCursor.value = "";
|
|
canCreateProject.value = false;
|
|
const query = new URLSearchParams({
|
|
page_size: String(projectPageSize.value),
|
|
after: projectCursors.value[projectPage.value],
|
|
});
|
|
try {
|
|
const result = await requestProjectAPI(`/api/v1/projects?${query}`, { signal: controller.signal });
|
|
if (current !== generation) return;
|
|
projects.value = result.items || [];
|
|
canCreateProject.value = Boolean(result.can_create_project);
|
|
projectHasMore.value = Boolean(result.has_more && result.next_cursor);
|
|
projectNextCursor.value = result.next_cursor || "";
|
|
selectedProject.value = projects.value.find((item) => item.id === selectedID) || projects.value[0] || null;
|
|
} catch (error) {
|
|
if (current === generation && error.name !== "AbortError") projectError.value = handleProjectSession(error);
|
|
} finally {
|
|
if (current === generation) loadingProjects.value = false;
|
|
}
|
|
}
|
|
|
|
async function refreshAfterMutation(action) {
|
|
if (action === "create" || action === "delete") {
|
|
projectPage.value = 0;
|
|
projectCursors.value = [""];
|
|
}
|
|
await loadProjects({ internal: true });
|
|
}
|
|
|
|
function selectProject(id) {
|
|
if (loadingProjects.value || lifecycle.savingProject.value || members.savingMember.value || selectedProject.value?.id === id) return;
|
|
selectedProject.value = projects.value.find((item) => item.id === id) || null;
|
|
}
|
|
|
|
async function changeProjectPageSize(value) {
|
|
if (lifecycle.savingProject.value || members.savingMember.value || !pageSizes.includes(Number(value))) return;
|
|
projectPageSize.value = Number(value);
|
|
projectPage.value = 0;
|
|
projectCursors.value = [""];
|
|
await loadProjects();
|
|
}
|
|
|
|
async function nextProjectPage() {
|
|
if (loadingProjects.value || lifecycle.savingProject.value || members.savingMember.value || !projectHasMore.value) return;
|
|
projectCursors.value = [...projectCursors.value.slice(0, projectPage.value + 1), projectNextCursor.value];
|
|
projectPage.value += 1;
|
|
await loadProjects();
|
|
}
|
|
|
|
async function previousProjectPage() {
|
|
if (loadingProjects.value || lifecycle.savingProject.value || members.savingMember.value || projectPage.value === 0) return;
|
|
projectPage.value -= 1;
|
|
await loadProjects();
|
|
}
|
|
|
|
onMounted(loadProjects);
|
|
onUnmounted(() => {
|
|
generation += 1;
|
|
controller?.abort();
|
|
});
|
|
|
|
return {
|
|
...members, ...lifecycle, canCreateProject, projects, selectedProject, loadingProjects, projectError,
|
|
projectPageSize, projectPage, projectHasMore, pageSizes,
|
|
loadProjects, selectProject, changeProjectPageSize, nextProjectPage, previousProjectPage,
|
|
};
|
|
}
|