jcloud/dashboard/src2/pages/PlayPage.vue
2025-04-12 17:39:38 +08:00

159 lines
4.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="p-5" v-if="play">
<Button :route="{ name: `${object.pagetype} Detail Plays` }">
<template #prefix>
<i-lucide-arrow-left class="inline-block h-4 w-4" />
</template>
所有剧本
</Button>
<div class="mt-3">
<div>
<div class="flex items-center">
<h2 class="text-lg font-medium text-gray-900">{{ play.play }}</h2>
<Badge class="ml-2" :label="play.status" />
<div class="ml-auto space-x-2">
<Button
@click="$resources.play.reload()"
:loading="$resources.play.loading"
>
<template #icon>
<i-lucide-refresh-ccw class="h-4 w-4" />
</template>
</Button>
<Dropdown v-if="dropdownOptions.length" :options="dropdownOptions">
<template v-slot="{ open }">
<Button>
<template #icon>
<i-lucide-more-horizontal class="h-4 w-4" />
</template>
</Button>
</template>
</Dropdown>
</div>
</div>
<div>
<div class="mt-4 grid grid-cols-5 gap-4">
<div>
<div class="text-sm font-medium text-gray-500">创建时间</div>
<div class="mt-2 text-sm text-gray-900">
{{ $format.date(play.creation) }}
</div>
</div>
<div>
<div class="text-sm font-medium text-gray-500">创建者</div>
<div class="mt-2 text-sm text-gray-900">
{{ play.owner }}
</div>
</div>
<div>
<div class="text-sm font-medium text-gray-500">持续时间</div>
<div class="mt-2 text-sm text-gray-900">
{{ $format.duration(play.duration) }}
</div>
</div>
<div>
<div class="text-sm font-medium text-gray-500">开始时间</div>
<div class="mt-2 text-sm text-gray-900">
{{ $format.date(play.start) }}
</div>
</div>
<div>
<div class="text-sm font-medium text-gray-500">结束时间</div>
<div class="mt-2 text-sm text-gray-900">
{{ $format.date(play.end) }}
</div>
</div>
</div>
</div>
</div>
<div class="mt-8 space-y-4">
<JobStep v-for="task in play.tasks" :step="task" :key="task.name" />
</div>
</div>
</div>
</template>
<script>
import { FeatherIcon, Tooltip } from 'jingrow-ui';
import { duration } from '../utils/format';
import { getObject } from '../objects';
import JobStep from '../components/JobStep.vue';
export default {
name: 'PlayPage',
props: ['id', 'objectType'],
components: { Tooltip, FeatherIcon, JobStep },
resources: {
play() {
return {
type: 'document',
pagetype: 'Ansible Play',
name: this.id,
transform(play) {
for (let task of play.tasks) {
task.title = task.task;
task.duration = duration(task.duration);
task.isOpen = false;
}
return play;
},
onSuccess() {
this.lastLoaded = Date.now();
}
};
}
},
computed: {
object() {
return getObject(this.objectType);
},
play() {
return this.$resources.play.pg;
},
dropdownOptions() {
return [
{
label: '在桌面查看',
icon: 'external-link',
condition: () => this.$team.pg?.is_desk_user,
onClick: () => {
window.open(
`${window.location.protocol}//${window.location.host}/app/ansible-play/${this.id}`,
'_blank'
);
}
}
].filter(option => option.condition?.() ?? true);
}
},
mounted() {
this.$socket.emit('pg_subscribe', 'Ansible Play', this.id);
this.$socket.on('ansible_play_update', data => {
if (data.id === this.id) {
this.reload();
}
});
// 每分钟重新加载 play以防 socket 不工作
this.reloadInterval = setInterval(() => {
this.reload();
}, 1000 * 60);
},
beforeUnmount() {
this.$socket.emit('pg_unsubscribe', 'Ansible Play', this.id);
this.$socket.off('ansible_play_update');
clearInterval(this.reloadInterval);
},
methods: {
reload() {
if (
!this.$resources.play.loading &&
// 如果 play 在 5 秒前加载过,则重新加载
Date.now() - this.lastLoaded > 5000
) {
this.$resources.play.reload();
}
}
}
};
</script>