<template>
<GnTable
:columns="columns"
:rows="scripts"
:caption="caption"
>
<template #cell-alias="{ row }">
<router-link
:to="{ name: 'script-detail', params: { type: row.type || scriptType, id: row.alias } }"
class="script-link"
>
{{ row.alias }}
</router-link>
</template>
<template #cell-scope="{ row }">
<router-link
v-if="row.scope"
:to="{ name: 'script-detail', params: { type: 'scopes', id: row.scope } }"
class="scope-link"
>
<span class="scope-label">Scope</span>
<span class="scope-name">{{ row.scope }}</span>
<i class="ph ph-arrow-right"></i>
</router-link>
<span v-else class="muted">—</span>
</template>
<template #cell-area="{ row }">
<GnBadge v-if="row.area_id" variant="primary">{{ areaNameFor(row) }}</GnBadge>
<span v-else class="muted">—</span>
</template>
<template #cell-state="{ row }">
<GnBadge :variant="row.state === 'enabled' ? 'success' : 'secondary'">{{ row.state }}</GnBadge>
</template>
<template v-if="showActions" #cell-actions="{ row }">
<GnButton
v-if="row.state === 'enabled'"
variant="secondary"
icon="ph-pause"
@click="toggle(row.alias, false, row)"
>
Disable
</GnButton>
<GnButton
v-else
variant="primary"
icon="ph-play"
@click="toggle(row.alias, true, row)"
>
Enable
</GnButton>
</template>
</GnTable>
</template>
<script setup>
import { computed } from "vue";
import { useScriptsStore } from "../../stores/scripts";
import { useAreasStore } from "../../stores/areas";
import { GnTable, GnBadge, GnButton } from "gnexus-ui-kit/vue";
const props = defineProps({
scripts: { type: Array, required: true },
scriptType: { type: String, default: "regular" },
showArea: { type: Boolean, default: false },
showScope: { type: Boolean, default: true },
showFilename: { type: Boolean, default: true },
showActions: { type: Boolean, default: true },
caption: { type: String, default: "Scripts" },
});
const scriptsStore = useScriptsStore();
const areasStore = useAreasStore();
const areaById = computed(() => {
const map = {};
for (const a of areasStore.areas) {
map[a.id] = a;
}
return map;
});
function areaNameFor(row) {
if (!row.area_id) return null;
return areaById.value[row.area_id]?.display_name || `Area ${row.area_id}`;
}
const columns = computed(() => {
const cols = [
{ key: "alias", label: "Alias" },
{ key: "name", label: "Name" },
];
if (props.showScope) {
cols.push({ key: "scope", label: "Scope" });
}
if (props.showArea) {
cols.push({ key: "area", label: "Area" });
}
cols.push({ key: "state", label: "State" });
if (props.showFilename) {
cols.push({ key: "filename", label: "File" });
}
if (props.showActions) {
cols.push({ key: "actions", label: "Actions" });
}
return cols;
});
function toggle(alias, enabled, row) {
const type = row.type || props.scriptType;
if (type === "action") {
scriptsStore.setActionState(alias, enabled);
} else if (type === "regular") {
scriptsStore.setRegularState(alias, enabled);
}
}
</script>
<style scoped>
.script-link {
color: var(--color-primary);
text-decoration: none;
}
.scope-link {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border: 1px solid var(--color-primary);
color: var(--color-primary);
text-decoration: none;
font-size: 13px;
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.scope-link:hover {
background: var(--color-primary);
color: var(--color-bg);
}
.scope-label {
text-transform: uppercase;
font-size: 11px;
font-weight: 700;
opacity: 0.8;
}
.muted {
color: var(--color-muted);
}
</style>