Skip to main content
Glama
change_set.ts3.52 kB
import * as _ from "lodash-es"; import { computed, ComputedRef, Ref, ref } from "vue"; import { useQuery, useQueryClient } from "@tanstack/vue-query"; import { RouteLocationNormalizedLoadedGeneric, Router } from "vue-router"; import { ChangeSetId, ChangeSetStatus } from "@/api/sdf/dal/change_set"; import { WorkspaceMetadata } from "@/api/sdf/dal/workspace"; import { BifrostActionViewList, EntityKind, } from "@/workers/types/entity_kind_types"; import { useMakeKeyForHead } from "@/store/realtime/heimdall"; import { ApprovalData, Context, UserId } from "../types"; import { routes, useApi } from "../api_composables"; import { reset } from "./navigation_stack"; /** * USED in Workspace.vue * Which is why we are passing `ctx` and not using `inject` * Because Workspace is the one who `provides` it (catch-22) */ export const useChangeSets = ( ctx: ComputedRef<Context>, enabled?: ComputedRef<boolean> | Ref<boolean>, ) => { if (!enabled) enabled = ref(true); const changeSetApi = useApi(ctx.value); const changeSetQuery = useQuery<WorkspaceMetadata | null>({ enabled, queryKey: ["changesets"], staleTime: 5000, queryFn: async () => { const call = changeSetApi.endpoint<WorkspaceMetadata>(routes.ChangeSets); const response = await call.get(); if (changeSetApi.ok(response)) { return response.data; } return null; }, }); const headChangeSetId = computed(() => { return changeSetQuery.data.value?.defaultChangeSetId ?? ""; }); const defaultApprovers = computed( () => changeSetQuery.data.value?.approvers || [], ); const openChangeSets = computed(() => { const changeSets = _.keyBy(changeSetQuery.data.value?.changeSets, "id"); return Object.values(changeSets).filter((cs) => [ ChangeSetStatus.Open, ChangeSetStatus.NeedsApproval, ChangeSetStatus.NeedsAbandonApproval, ChangeSetStatus.Rejected, ChangeSetStatus.Approved, ].includes(cs.status), ); }); const changeSet = computed(() => { if (!changeSetQuery.data.value) return; const changeSets = _.keyBy(changeSetQuery.data.value?.changeSets, "id"); return changeSets[ctx.value.changeSetId.value]; }); return { openChangeSets, changeSet, headChangeSetId, defaultApprovers }; }; export const useApplyChangeSet = (ctx: Context) => { const api = useApi(ctx); const queryClient = useQueryClient(); const makeKeyForHead = useMakeKeyForHead(); const applyInFlight = computed(() => api.inFlight.value); const performApply = async () => { const call = api.endpoint<BifrostActionViewList>(routes.ApplyChangeSet); const { req } = await call.post({}); if (api.ok(req)) { const actionsKey = makeKeyForHead(EntityKind.ActionViewList).value; queryClient.setQueryData(actionsKey, req.data); } return { success: api.ok(req), req }; }; return { performApply, applyInFlight }; }; export const navigateToExistingChangeSet = async ( changeSetId: ChangeSetId, route: RouteLocationNormalizedLoadedGeneric, router: Router, ) => { const name = route.name; await router.push({ name, params: { ...route.params, changeSetId, }, query: route.query, }); reset(); }; export const approverForChangeSet = ( userId: UserId, approvalData: ApprovalData, ) => approvalData.requirements.some((r) => Object.values(r.approverGroups) .flat() .concat(r.approverIndividuals) .includes(userId), );

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