<template>
<div class="area-grid">
<GnActionCard
v-for="script in scripts"
:key="script.alias"
:title="script.name"
@click="goToDetail(script.alias)"
>
<template #default>
<div v-if="script.icon" v-html="script.icon" class="script-icon" />
<p v-if="script.description">{{ script.description }}</p>
<div class="script-meta">
<GnBadge :variant="script.state === 'enabled' ? 'success' : 'secondary'"
>{{ script.state }}</GnBadge>
<GnBadge v-if="script.scope" variant="primary">{{ script.scope }}</GnBadge>
<GnBadge v-if="showAreaBadge && areaFor(script)" variant="primary">{{ areaFor(script).display_name }}</GnBadge>
</div>
<small v-if="script.created_by || script.author">{{ script.created_by || script.author }}</small>
</template>
<template #actions>
<GnButton
variant="primary"
icon="ph-play"
:loading="scriptsStore.isRunning(script.alias)"
:disabled="script.state !== 'enabled'"
@click.stop="run(script.alias)"
>
Run
</GnButton>
</template>
</GnActionCard>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
import { useScriptsStore } from "../../stores/scripts";
import { useAreasStore } from "../../stores/areas";
import {
GnBadge,
GnActionCard,
GnButton,
useToast,
} from "gnexus-ui-kit/vue";
const props = defineProps({
scripts: {
type: Array,
required: true,
},
showAreaBadge: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["run-success"]);
const router = useRouter();
const scriptsStore = useScriptsStore();
const areasStore = useAreasStore();
const toast = useToast();
function areaFor(script) {
if (!script.area_id || !props.showAreaBadge) return null;
return areasStore.areas.find((a) => a.id === script.area_id) || null;
}
async function run(alias) {
const result = await scriptsStore.runScript(alias);
if (result?.ok) {
toast.success({
title: `Ran ${alias}`,
text: scriptsStore.lastRunResult?.execTime ? `Exec time: ${scriptsStore.lastRunResult.execTime}` : undefined,
});
emit("run-success", { alias });
} else {
toast.error({ title: `Failed ${alias}`, text: result?.error?.message || "Unknown error" });
}
}
function goToDetail(alias) {
router.push({ name: "script-detail", params: { type: "actions", id: alias } });
}
</script>
<style scoped>
.script-icon {
font-size: 32px;
}
.script-meta {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
}
</style>