207 lines
6.6 KiB
JavaScript
207 lines
6.6 KiB
JavaScript
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 updateSource(sourceId, payload) {
|
|
if (!sourceId) {
|
|
return null;
|
|
}
|
|
|
|
error.value = null;
|
|
|
|
try {
|
|
const response = await client.put(`/api/calendar-integrations/sources/${sourceId}`, payload);
|
|
const updatedSource = response.data;
|
|
if (updatedSource) {
|
|
sources.value = sources.value.map(source =>
|
|
source.id === updatedSource.id ? updatedSource : source
|
|
);
|
|
}
|
|
return updatedSource;
|
|
} catch (updateError) {
|
|
console.error('Failed to update calendar source:', updateError);
|
|
error.value = 'Failed to update calendar source.';
|
|
throw updateError;
|
|
}
|
|
}
|
|
|
|
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,
|
|
updateSource,
|
|
refreshSource,
|
|
toggleSourceVisibility,
|
|
};
|
|
});
|