|
|
@@ -0,0 +1,89 @@
|
|
|
+import * as documentsApi from '$lib/api/documents';
|
|
|
+import { notificationsStore } from '$lib/stores/notifications.svelte';
|
|
|
+import { ResourceStore } from '$lib/stores/resources.svelte';
|
|
|
+import type { DocumentCR } from '$lib/types/custom-resources';
|
|
|
+import type { KBDocument, KBDocumentStatus } from '$lib/types/entities';
|
|
|
+
|
|
|
+type CRCondition = { type: string; status: 'True' | 'False' | 'Unknown' };
|
|
|
+
|
|
|
+const readyCondition = (conditions: CRCondition[]) =>
|
|
|
+ conditions.find((c) => c.type === 'Ready')?.status;
|
|
|
+
|
|
|
+const statusFromCR = (status: DocumentCR['status']): KBDocumentStatus => {
|
|
|
+ if (!status || typeof status !== 'object') return 'not-deployed';
|
|
|
+ if (status.readyReplicas && status.readyReplicas > 0) return 'running';
|
|
|
+ const ready = readyCondition(status.conditions ?? []);
|
|
|
+ if (ready === 'True') return 'running';
|
|
|
+ if (ready === 'False') return 'degraded';
|
|
|
+ return 'pending';
|
|
|
+};
|
|
|
+
|
|
|
+type CRStatus = DocumentCR['status'];
|
|
|
+
|
|
|
+class DocumentsStore extends ResourceStore<KBDocument, CRStatus> {
|
|
|
+ constructor() {
|
|
|
+ super('Knowledge Base', [
|
|
|
+ {
|
|
|
+ group: 'locostack.com',
|
|
|
+ version: 'v1alpha1',
|
|
|
+ resources: 'documents',
|
|
|
+ },
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected resourceHref(id: string) {
|
|
|
+ return `/workloads/kbs/${id}`;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected apiGet(workspaceId: string, id: string) {
|
|
|
+ return documentsApi.get(workspaceId, id);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected apiGetStatus(workspaceId: string, id: string) {
|
|
|
+ return documentsApi.getStatus(workspaceId, id);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected apiCreate(workspaceId: string, doc: KBDocument) {
|
|
|
+ return documentsApi.create(workspaceId, doc);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected apiUpdate(workspaceId: string, doc: KBDocument) {
|
|
|
+ return documentsApi.update(workspaceId, doc.id, doc);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected apiDelete(workspaceId: string, id: string) {
|
|
|
+ return documentsApi.remove(workspaceId, id);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected onStatusChange(id: string, status: CRStatus, notify = true): void {
|
|
|
+ const item = this.get(id);
|
|
|
+ if (!item) return;
|
|
|
+ const deploymentStatus = statusFromCR(status);
|
|
|
+ notify = notify && item.status !== deploymentStatus;
|
|
|
+ item.status = deploymentStatus;
|
|
|
+ if (notify) {
|
|
|
+ this.#notifyStatusChange(id, item.name, deploymentStatus);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #notifyStatusChange(id: string, name: string, status: string): void {
|
|
|
+ const href = this.resourceHref(id);
|
|
|
+ notificationsStore.push({
|
|
|
+ type: 'success',
|
|
|
+ message: `Document "${name}" is now ${status}`,
|
|
|
+ href,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ async createDocuments(docs: KBDocument[]): Promise<void> {
|
|
|
+ const result = await Promise.allSettled(
|
|
|
+ docs.map((doc) => documentsApi.create(this.workspaceId, doc)),
|
|
|
+ );
|
|
|
+ const added = result.filter((r) => r.status === 'fulfilled').map((r) => r.value);
|
|
|
+ this.list = [...this.list, ...added];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const documentsStore = new DocumentsStore();
|
|
|
+
|
|
|
+export { documentsStore };
|