209 lines
6.5 KiB
JavaScript
209 lines
6.5 KiB
JavaScript
import { computed, ref, watch } from 'vue';
|
|
import { defineStore } from 'pinia';
|
|
import { useAuthStore } from '@/stores/authStore.js';
|
|
import { useClient } from '@/plugins/api.js';
|
|
|
|
export const useWorkspaceStore = defineStore('workspace', () => {
|
|
const authStore = useAuthStore();
|
|
const client = useClient();
|
|
|
|
const workspaces = ref([]);
|
|
const activeWorkspaceId = ref(null);
|
|
const isLoading = ref(false);
|
|
const isCreating = ref(false);
|
|
const invitesByWorkspace = ref({});
|
|
const membersByWorkspace = ref({});
|
|
const isInvitesLoading = ref(false);
|
|
const isMembersLoading = ref(false);
|
|
const isInviting = ref(false);
|
|
const error = ref(null);
|
|
|
|
const activeWorkspace = computed(() =>
|
|
workspaces.value.find(workspace => workspace.id === activeWorkspaceId.value) ?? null
|
|
);
|
|
|
|
async function fetchWorkspaces() {
|
|
if (!authStore.isAuthenticated) {
|
|
workspaces.value = [];
|
|
activeWorkspaceId.value = null;
|
|
error.value = null;
|
|
return;
|
|
}
|
|
|
|
isLoading.value = true;
|
|
error.value = null;
|
|
|
|
try {
|
|
const response = await client.get('/api/workspaces');
|
|
workspaces.value = response.data ?? [];
|
|
|
|
if (!workspaces.value.some(workspace => workspace.id === activeWorkspaceId.value)) {
|
|
activeWorkspaceId.value = workspaces.value[0]?.id ?? null;
|
|
}
|
|
} catch (fetchError) {
|
|
console.error('Failed to fetch workspaces:', fetchError);
|
|
workspaces.value = [];
|
|
activeWorkspaceId.value = null;
|
|
error.value = 'Failed to load workspaces.';
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
}
|
|
|
|
async function createWorkspace(payload) {
|
|
if (!authStore.isAuthenticated) {
|
|
throw new Error('You must be authenticated to create a workspace.');
|
|
}
|
|
|
|
if (isCreating.value) {
|
|
throw new Error('A workspace creation request is already in progress.');
|
|
}
|
|
|
|
isCreating.value = true;
|
|
error.value = null;
|
|
|
|
try {
|
|
const response = await client.post('/api/workspaces', payload);
|
|
|
|
if (response.data) {
|
|
workspaces.value = [...workspaces.value, response.data]
|
|
.sort((left, right) => left.name.localeCompare(right.name));
|
|
activeWorkspaceId.value = response.data.id;
|
|
|
|
try {
|
|
await client.post('/api/clients', {
|
|
workspaceId: response.data.id,
|
|
name: response.data.name,
|
|
});
|
|
} catch (hiddenClientError) {
|
|
console.error('Failed to provision operational client for workspace:', hiddenClientError);
|
|
}
|
|
}
|
|
|
|
return response.data;
|
|
} catch (createError) {
|
|
console.error('Failed to create workspace:', createError);
|
|
error.value = 'Failed to create workspace.';
|
|
throw createError;
|
|
} finally {
|
|
isCreating.value = false;
|
|
}
|
|
}
|
|
|
|
function setActiveWorkspace(workspaceId) {
|
|
if (workspaces.value.some(workspace => workspace.id === workspaceId)) {
|
|
activeWorkspaceId.value = workspaceId;
|
|
}
|
|
}
|
|
|
|
async function fetchInvites(workspaceId = activeWorkspaceId.value) {
|
|
if (!authStore.isAuthenticated || !workspaceId) {
|
|
invitesByWorkspace.value = {};
|
|
return [];
|
|
}
|
|
|
|
isInvitesLoading.value = true;
|
|
|
|
try {
|
|
const response = await client.get(`/api/workspaces/${workspaceId}/invites`);
|
|
invitesByWorkspace.value = {
|
|
...invitesByWorkspace.value,
|
|
[workspaceId]: response.data ?? [],
|
|
};
|
|
|
|
return invitesByWorkspace.value[workspaceId];
|
|
} catch (fetchError) {
|
|
console.error('Failed to fetch workspace invites:', fetchError);
|
|
throw fetchError;
|
|
} finally {
|
|
isInvitesLoading.value = false;
|
|
}
|
|
}
|
|
|
|
async function fetchMembers(workspaceId = activeWorkspaceId.value) {
|
|
if (!authStore.isAuthenticated || !workspaceId) {
|
|
membersByWorkspace.value = {};
|
|
return [];
|
|
}
|
|
|
|
isMembersLoading.value = true;
|
|
|
|
try {
|
|
const response = await client.get(`/api/workspaces/${workspaceId}/members`);
|
|
membersByWorkspace.value = {
|
|
...membersByWorkspace.value,
|
|
[workspaceId]: response.data ?? [],
|
|
};
|
|
|
|
return membersByWorkspace.value[workspaceId];
|
|
} catch (fetchError) {
|
|
console.error('Failed to fetch workspace members:', fetchError);
|
|
throw fetchError;
|
|
} finally {
|
|
isMembersLoading.value = false;
|
|
}
|
|
}
|
|
|
|
async function inviteMember(payload) {
|
|
if (!authStore.isAuthenticated || !activeWorkspaceId.value) {
|
|
throw new Error('You must be authenticated to invite a workspace member.');
|
|
}
|
|
|
|
if (isInviting.value) {
|
|
throw new Error('A workspace invite request is already in progress.');
|
|
}
|
|
|
|
isInviting.value = true;
|
|
|
|
try {
|
|
const response = await client.post(`/api/workspaces/${activeWorkspaceId.value}/invites`, payload);
|
|
invitesByWorkspace.value = {
|
|
...invitesByWorkspace.value,
|
|
[activeWorkspaceId.value]: [response.data, ...(invitesByWorkspace.value[activeWorkspaceId.value] ?? [])],
|
|
};
|
|
|
|
return response.data;
|
|
} catch (inviteError) {
|
|
console.error('Failed to create workspace invite:', inviteError);
|
|
throw inviteError;
|
|
} finally {
|
|
isInviting.value = false;
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => authStore.isAuthenticated,
|
|
async isAuthenticated => {
|
|
if (!isAuthenticated) {
|
|
workspaces.value = [];
|
|
activeWorkspaceId.value = null;
|
|
error.value = null;
|
|
return;
|
|
}
|
|
|
|
await fetchWorkspaces();
|
|
},
|
|
{ immediate: true }
|
|
);
|
|
|
|
return {
|
|
workspaces,
|
|
activeWorkspaceId,
|
|
activeWorkspace,
|
|
isLoading,
|
|
isCreating,
|
|
invitesByWorkspace,
|
|
membersByWorkspace,
|
|
isInvitesLoading,
|
|
isMembersLoading,
|
|
isInviting,
|
|
error,
|
|
fetchWorkspaces,
|
|
createWorkspace,
|
|
fetchInvites,
|
|
fetchMembers,
|
|
inviteMember,
|
|
setActiveWorkspace,
|
|
};
|
|
});
|