Skip to main content
Glama
qualifications.store.ts5.01 kB
import { defineStore } from "pinia"; import * as _ from "lodash-es"; import { addStoreHooks } from "@si/vue-lib/pinia"; import { Qualification } from "@/api/sdf/dal/qualification"; import { useWorkspacesStore } from "@/store/workspaces.store"; import { ComponentId } from "@/api/sdf/dal/component"; import { DiagramStatusIcon } from "@/components/ModelingDiagram/diagram_types"; import { useChangeSetsStore } from "./change_sets.store"; import { useRealtimeStore } from "./realtime/realtime.store"; import handleStoreError from "./errors"; export type QualificationStatus = "success" | "failure" | "running" | "warning"; // TODO: align these key names with the status (ex: succeeded -> success) type QualificationStats = { total: number; succeeded: number; warned: number; failed: number; running: number; }; export const qualificationStatusToIconMap: Record< QualificationStatus | "notexists", DiagramStatusIcon > = { success: { icon: "check-hex-outline", tone: "success" }, warning: { icon: "check-hex-outline", tone: "warning" }, failure: { icon: "x-hex-outline", tone: "error" }, running: { icon: "loader", tone: "info" }, notexists: { icon: "none" }, }; export const statusIconsForComponent = ( qualificationStatus?: QualificationStatus, hasResource?: boolean, ) => { const statusIcons: DiagramStatusIcon[] = _.compact([ { ...qualificationStatusToIconMap[qualificationStatus ?? "notexists"], tabSlug: "qualifications", }, hasResource ? { icon: "check-hex", tone: "success", tabSlug: "resource" } : { icon: "none" }, ]); return statusIcons; }; export const useQualificationsStore = () => { const changeSetsStore = useChangeSetsStore(); const changeSetId = changeSetsStore.selectedChangeSetId; const realtimeStore = useRealtimeStore(); const workspacesStore = useWorkspacesStore(); const workspaceId = workspacesStore.selectedWorkspacePk; return addStoreHooks( workspaceId, changeSetId, defineStore( `ws${workspaceId || "NONE"}/cs${changeSetId || "NONE"}/qualifications`, { state: () => ({ qualificationStatsByComponentId: {} as Record< ComponentId, QualificationStats >, // NOTE(victor) Use the qualificationsByComponentId getter, it has validation data qualificationsByComponentId: {} as Record< ComponentId, Qualification[] >, checkedQualificationsAt: null as Date | null, }), getters: { // single status per component qualificationStatusByComponentId(): Record< ComponentId, QualificationStatus > { return _.mapValues(this.qualificationStatsByComponentId, (cs) => { if (cs.running) return "running"; if (cs.failed > 0) return "failure"; if (cs.warned > 0) return "warning"; return "success"; }); }, qualificationStatusForComponentId: (state) => (componentId: ComponentId): QualificationStatus => { const stats = state.qualificationStatsByComponentId[componentId]; if (stats) { if (stats.running) { return "running"; } if (stats.failed > 0) { return "failure"; } if (stats.warned > 0) { return "warning"; } } return "success"; }, // stats/totals by component componentStats(): Record<QualificationStatus | "total", number> { const grouped = _.groupBy(this.qualificationStatusByComponentId); return { failure: grouped.failure?.length || 0, success: grouped.success?.length || 0, warning: grouped.warning?.length || 0, running: grouped.running?.length || 0, total: _.keys(this.qualificationStatusByComponentId).length, }; }, // roll up to single status for the workspace overallStatus(): QualificationStatus { if (this.componentStats.running > 0) return "running"; if (this.componentStats.failure > 0) return "failure"; return "success"; }, }, actions: { registerRequestsBegin(requestUlid: string, actionName: string) { realtimeStore.inflightRequests.set(requestUlid, actionName); }, registerRequestsEnd(requestUlid: string) { realtimeStore.inflightRequests.delete(requestUlid); }, }, async onActivated() { if (!changeSetId) return; const actionUnsub = this.$onAction(handleStoreError); return () => { actionUnsub(); realtimeStore.unsubscribe(this.$id); }; }, }, ), )(); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server