Add calendar integrations and collaboration updates
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useAuthStore } from '@/features/auth/stores/authStore.js';
|
||||
import { useWorkspaceStore } from '@/features/workspaces/stores/workspaceStore.js';
|
||||
import { useClient } from '@/plugins/api.js';
|
||||
|
||||
export const useCalendarIntegrationsStore = defineStore('calendar-integrations', () => {
|
||||
const authStore = useAuthStore();
|
||||
const workspaceStore = useWorkspaceStore();
|
||||
const client = useClient();
|
||||
|
||||
const sources = ref([]);
|
||||
const events = ref([]);
|
||||
const catalogEntries = ref([]);
|
||||
const hiddenSourceIds = ref(new Set());
|
||||
const isLoadingSources = ref(false);
|
||||
const isLoadingEvents = ref(false);
|
||||
const isLoadingCatalog = ref(false);
|
||||
const isCreatingSource = ref(false);
|
||||
const error = ref(null);
|
||||
|
||||
const visibleSourceIds = computed(() =>
|
||||
new Set(sources.value
|
||||
.filter(source => source.isEnabled && !hiddenSourceIds.value.has(source.id))
|
||||
.map(source => source.id))
|
||||
);
|
||||
|
||||
const visibleEvents = computed(() =>
|
||||
events.value.filter(event => visibleSourceIds.value.has(event.calendarSourceId))
|
||||
);
|
||||
|
||||
function sourceById(sourceId) {
|
||||
return sources.value.find(source => source.id === sourceId) ?? null;
|
||||
}
|
||||
|
||||
async function fetchSources(workspaceId = workspaceStore.activeWorkspaceId) {
|
||||
if (!authStore.isAuthenticated) {
|
||||
sources.value = [];
|
||||
error.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
isLoadingSources.value = true;
|
||||
error.value = null;
|
||||
|
||||
try {
|
||||
const response = await client.get('/api/calendar-integrations/sources', {
|
||||
params: {
|
||||
workspaceId: workspaceId ?? undefined,
|
||||
},
|
||||
});
|
||||
sources.value = response.data ?? [];
|
||||
} catch (fetchError) {
|
||||
console.error('Failed to fetch calendar sources:', fetchError);
|
||||
sources.value = [];
|
||||
error.value = 'Failed to load calendar sources.';
|
||||
} finally {
|
||||
isLoadingSources.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchEvents({ workspaceId = workspaceStore.activeWorkspaceId, startDate, endDate } = {}) {
|
||||
if (!authStore.isAuthenticated) {
|
||||
events.value = [];
|
||||
error.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
isLoadingEvents.value = true;
|
||||
|
||||
try {
|
||||
const response = await client.get('/api/calendar-integrations/events', {
|
||||
params: {
|
||||
workspaceId: workspaceId ?? undefined,
|
||||
startDate,
|
||||
endDate,
|
||||
},
|
||||
});
|
||||
events.value = response.data ?? [];
|
||||
} catch (fetchError) {
|
||||
console.error('Failed to fetch calendar events:', fetchError);
|
||||
events.value = [];
|
||||
error.value = 'Failed to load calendar events.';
|
||||
} finally {
|
||||
isLoadingEvents.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function searchCatalog(filters = {}) {
|
||||
if (!authStore.isAuthenticated) {
|
||||
catalogEntries.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
isLoadingCatalog.value = true;
|
||||
|
||||
try {
|
||||
const response = await client.get('/api/calendar-integrations/catalog', {
|
||||
params: filters,
|
||||
});
|
||||
catalogEntries.value = response.data ?? [];
|
||||
} catch (fetchError) {
|
||||
console.error('Failed to search calendar catalog:', fetchError);
|
||||
catalogEntries.value = [];
|
||||
error.value = 'Failed to load calendar catalog.';
|
||||
} finally {
|
||||
isLoadingCatalog.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function createSource(payload) {
|
||||
isCreatingSource.value = true;
|
||||
error.value = null;
|
||||
|
||||
try {
|
||||
const response = await client.post('/api/calendar-integrations/sources', payload);
|
||||
if (response.data) {
|
||||
sources.value = [...sources.value, response.data]
|
||||
.sort((left, right) => left.displayTitle.localeCompare(right.displayTitle));
|
||||
}
|
||||
return response.data;
|
||||
} catch (createError) {
|
||||
console.error('Failed to create calendar source:', createError);
|
||||
error.value = 'Failed to add calendar source.';
|
||||
throw createError;
|
||||
} finally {
|
||||
isCreatingSource.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshSource(sourceId) {
|
||||
if (!sourceId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await client.post(`/api/calendar-integrations/sources/${sourceId}/refresh`);
|
||||
const refreshedSource = response.data;
|
||||
if (refreshedSource) {
|
||||
sources.value = sources.value.map(source =>
|
||||
source.id === refreshedSource.id ? refreshedSource : source
|
||||
);
|
||||
}
|
||||
return refreshedSource;
|
||||
} catch (refreshError) {
|
||||
console.error('Failed to refresh calendar source:', refreshError);
|
||||
error.value = 'Failed to refresh calendar source.';
|
||||
throw refreshError;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSourceVisibility(sourceId) {
|
||||
const nextHiddenIds = new Set(hiddenSourceIds.value);
|
||||
if (nextHiddenIds.has(sourceId)) {
|
||||
nextHiddenIds.delete(sourceId);
|
||||
} else {
|
||||
nextHiddenIds.add(sourceId);
|
||||
}
|
||||
hiddenSourceIds.value = nextHiddenIds;
|
||||
}
|
||||
|
||||
return {
|
||||
sources,
|
||||
events,
|
||||
catalogEntries,
|
||||
hiddenSourceIds,
|
||||
visibleSourceIds,
|
||||
visibleEvents,
|
||||
isLoadingSources,
|
||||
isLoadingEvents,
|
||||
isLoadingCatalog,
|
||||
isCreatingSource,
|
||||
error,
|
||||
sourceById,
|
||||
fetchSources,
|
||||
fetchEvents,
|
||||
searchCatalog,
|
||||
createSource,
|
||||
refreshSource,
|
||||
toggleSourceVisibility,
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user