Skip to main content
Glama
ActionsList.vue5.52 kB
<template> <TreeNode :enableGroupToggle="displayActions.length > 0" styleAsGutter> <template #label> <div :class=" clsx( 'flex flex-row gap-2xs justify-between place-items-center bg-neutral-100 dark:bg-neutral-700 text-sm', changeSet ? 'py-2xs px-xs' : 'py-xs', ) " > <template v-if="changeSet"> <div class="flex flex-col flex-grow min-w-0"> <Timestamp :date="changeSet.appliedAt" :timeClasses=" themeClasses('text-neutral-500', 'text-neutral-400') " class="text-sm" dateClasses="font-bold" showTimeIfToday size="long" /> <div :class=" clsx( 'text-xs truncate', themeClasses('text-neutral-500', 'text-neutral-400'), ) " > <span class="font-bold">Change Set:</span> {{ changeSet.name }} </div> </div> <div class="flex-none font-bold"> {{ displayActions.length }} Action(s) </div> <!-- TODO(Wendy) - maybe a PillCounter makes more sense here? --> <!-- <PillCounter v-tooltip="{ content: 'Actions', placement: 'left' }" :count="displayActions.length" class="flex-none font-bold cursor-pointer" size="lg" /> --> </template> <template v-else> <div class="grow-0 mx-[.66em]"> <Icon class="attributes-panel-item__type-icon" name="bullet-list" size="sm" /> </div> <div class="grow">{{ displayActions.length }} Action(s)</div> <div class="grow-0 flex flex-row mr-xs"> <div v-for="(cnt, actionKind) in countActionsByKind(displayActions)" :key="actionKind" class="flex flex-row mx-2xs p-2xs rounded dark:bg-neutral-900 bg-neutral-200" > <div class="mx-2xs">{{ cnt }}</div> <StatusIndicatorIcon :status="actionKind.toString()" size="sm" type="action" /> </div> </div> </template> </div> </template> <div v-for="action in displayActions" :key="action.id" :class=" clsx( 'border-b', themeClasses('border-neutral-100', 'border-neutral-700'), ) " > <ActionCard :action="action" :noInteraction="props.noInteraction" :selected="isSelected(action)" :slim="props.slim" @click="props.clickAction && props.clickAction(action, $event)" @history="openHistory" @remove="actionsStore.CANCEL([action.id])" /> </div> </TreeNode> </template> <script lang="ts" setup> import clsx from "clsx"; import { Icon, Timestamp, TreeNode, themeClasses, } from "@si/vue-lib/design-system"; import { PropType, computed } from "vue"; import { useActionsStore, ActionView, ActionHistoryView, FuncRunId, ActionProposedView, } from "@/store/actions.store"; import { DefaultMap } from "@/utils/defaultmap"; import { ChangeSet } from "@/api/sdf/dal/change_set"; import ActionCard from "./ActionCard.vue"; import StatusIndicatorIcon from "../StatusIndicatorIcon.vue"; export type ActionsListKind = "proposed" | "history"; const actionsStore = useActionsStore(); type clickFn = ( action: ActionHistoryView | ActionProposedView, e: MouseEvent, ) => void; const props = defineProps({ actions: { type: Array<ActionView> }, kind: { type: String as PropType<ActionsListKind> }, noInteraction: { type: Boolean }, selectedActionIds: { type: Array<string> }, selectedFuncRunIds: { type: Array<string> }, slim: { type: Boolean }, clickAction: { type: Function as PropType<clickFn>, default: undefined, }, changeSet: { type: Object as PropType<ChangeSet> }, }); const selectedIds = computed<string[]>(() => { if (props.kind === "proposed") { return props.selectedActionIds || []; } return props.selectedFuncRunIds || []; }); const isSelected = (action: ActionView) => { let id: string; if (props.kind === "history") { const a = action as ActionHistoryView; id = a.funcRunId; } else { id = action.id; } return selectedIds.value.includes(id); }; const displayActions = computed(() => { // Use the actions prop if it is present if (props.actions && props.kind === "proposed") return props.actions as ActionProposedView[]; if (props.actions && props.kind === "history") return props.actions as ActionHistoryView[]; // Otherwise grab actions based on the kind prop if (props.kind === "proposed") { return actionsStore.proposedActions; } else if (props.kind === "history") { return actionsStore.historyActions; } else return actionsStore.actions; }); function countActionsByKind(actions: ActionView[]): Record<string, number> { const counts = new DefaultMap<string, number>(() => 0); for (const action of actions) { counts.set(action.kind, counts.get(action.kind) + 1); } return Object.fromEntries(counts); } const emit = defineEmits<{ (e: "history", id: FuncRunId, tabSlug: string): void; }>(); function openHistory(id: FuncRunId, slug: string) { emit("history", id, slug); } </script>

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