Initial commit

This commit is contained in:
root
2026-01-04 22:05:37 -05:00
committed by Sebastian Krupinski
commit 4f979ced22
57 changed files with 11076 additions and 0 deletions

208
src/stores/servicesStore.ts Normal file
View File

@@ -0,0 +1,208 @@
import { defineStore } from 'pinia';
import { serviceService } from '@/services/serviceService';
import { ServiceModel } from '@/models/service';
import type { Service } from '@/models/service';
export const useServicesStore = defineStore('jmapc_services', {
state: () => ({
services: [] as ServiceModel[],
loading: false,
error: null as string | null,
}),
getters: {
/**
* Get services filtered by capability
*/
byCapability: (state) => (capability: string) => {
return state.services.filter(s => s.capabilities.includes(capability));
},
/**
* Get mail services
*/
mailServices: (state) => {
return state.services.filter(s => s.hasMail());
},
/**
* Get contact services
*/
contactServices: (state) => {
return state.services.filter(s => s.hasContacts());
},
/**
* Get calendar services
*/
calendarServices: (state) => {
return state.services.filter(s => s.hasCalendars());
},
/**
* Get service by ID
*/
getById: (state) => (id: string) => {
return state.services.find(s => s.id === id);
},
},
actions: {
/**
* Load all services from API
*/
async loadServices(capability?: string) {
this.loading = true;
this.error = null;
try {
const response = await serviceService.list(capability);
this.services = response.services.map(s => new ServiceModel(s));
} catch (error: any) {
this.error = error.message || 'Failed to load services';
throw error;
} finally {
this.loading = false;
}
},
/**
* Load a single service
*/
async loadService(id: string) {
this.loading = true;
this.error = null;
try {
const service = await serviceService.fetch(id);
const model = new ServiceModel(service);
// Update or add to store
const index = this.services.findIndex(s => s.id === id);
if (index >= 0) {
this.services[index] = model;
} else {
this.services.push(model);
}
return model;
} catch (error: any) {
this.error = error.message || 'Failed to load service';
throw error;
} finally {
this.loading = false;
}
},
/**
* Create a new service
*/
async createService(service: Partial<Service>) {
this.loading = true;
this.error = null;
try {
const created = await serviceService.create(service);
const model = new ServiceModel(created);
this.services.push(model);
return model;
} catch (error: any) {
this.error = error.message || 'Failed to create service';
throw error;
} finally {
this.loading = false;
}
},
/**
* Update an existing service
*/
async updateService(id: string, service: Partial<Service>) {
this.loading = true;
this.error = null;
try {
const updated = await serviceService.update(id, service);
const model = new ServiceModel(updated);
const index = this.services.findIndex(s => s.id === id);
if (index >= 0) {
this.services[index] = model;
}
return model;
} catch (error: any) {
this.error = error.message || 'Failed to update service';
throw error;
} finally {
this.loading = false;
}
},
/**
* Delete a service
*/
async deleteService(id: string) {
this.loading = true;
this.error = null;
try {
await serviceService.destroy(id);
this.services = this.services.filter(s => s.id !== id);
} catch (error: any) {
this.error = error.message || 'Failed to delete service';
throw error;
} finally {
this.loading = false;
}
},
/**
* Test connection with provided settings
*/
async testConnection(config: any) {
return serviceService.test(config);
},
/**
* Auto-discover JMAP endpoint
*/
async discover(hostname: string, protocol?: string, port?: number, path?: string) {
return serviceService.discover(hostname, protocol, port, path);
},
/**
* Fetch collections for a service
*/
async fetchCollections(id: string) {
return serviceService.fetchCollections(id);
},
/**
* Refresh collections for a service
*/
async refreshCollections(id: string) {
const result = await serviceService.refreshCollections(id);
// Update local service with fresh collection data
const service = this.getById(id);
if (service && result.success) {
service.collections = {
contacts: result.contacts || [],
calendars: result.calendars || []
};
}
return result;
},
/**
* Clear all services
*/
reset() {
this.services = [];
this.error = null;
this.loading = false;
},
},
});