main
vue 114 lines 3.36 KB
Raw
1 <template>
2 <div class="h-full">
3 <CardEntity
4 hoverable
5 clickable
6 :embedded
7 class="h-full"
8 main-box-class="grow"
9 card-entity-wrapper-class="h-full"
10 header-box-class="flex-nowrap! items-start"
11 @click.stop="showDetails = true"
12 >
13 <template #headerMain>{{ action.copilot_action_name }}</template>
14 <template #headerExtra>
15 <TechnologyBadge :action />
16 </template>
17 <template #default>
18 <div class="line-clamp-3 text-sm">
19 {{ action.description }}
20 </div>
21 </template>
22 <template #footerMain>
23 <div class="flex flex-wrap items-center gap-2">
24 <Badge v-if="action.category">
25 <template #value>{{ action.category }}</template>
26 </Badge>
27
28 <Badge v-if="action.version" color="primary" type="splitted">
29 <template #label>version</template>
30 <template #value>{{ action.version }}</template>
31 </Badge>
32
33 <Badge v-if="action.script_parameters.length" color="warning" type="splitted">
34 <template #label>params</template>
35 <template #value>{{ action.script_parameters.length }}</template>
36 </Badge>
37
38 <div v-if="action.tags?.length" class="flex items-center gap-1">
39 <Badge v-for="tag of action.tags.slice(0, 2)" :key="tag" size="small">
40 <template #value>{{ tag }}</template>
41 </Badge>
42 <Badge v-if="action.tags.length > 2" size="small">
43 <template #value>+{{ action.tags.length - 2 }}</template>
44 </Badge>
45 </div>
46 </div>
47 </template>
48 <template #footerExtra>
49 <n-button size="small" type="primary" secondary @click.stop="showInvokeModal = true">
50 <template #icon>
51 <Icon :name="PlayIcon" />
52 </template>
53 Invoke
54 </n-button>
55 </template>
56 </CardEntity>
57
58 <!-- Action Details Modal -->
59 <n-modal
60 v-model:show="showDetails"
61 preset="card"
62 :style="{ maxWidth: 'min(800px, 90vw)', minHeight: 'min(600px, 90vh)', overflow: 'hidden' }"
63 :title="`CoPilot Action: ${action.copilot_action_name}`"
64 :bordered="false"
65 segmented
66 >
67 <ActionCardContent :action />
68 </n-modal>
69
70 <!-- Invoke Action Modal -->
71 <n-modal
72 v-model:show="showInvokeModal"
73 preset="card"
74 :style="{ maxWidth: 'min(600px, 90vw)' }"
75 :bordered="false"
76 display-directive="show"
77 segmented
78 >
79 <template #header>
80 <div class="flex flex-col gap-2">
81 <div class="flex">
82 <TechnologyBadge :action />
83 </div>
84 <span class="px-1 text-base">{{ action.copilot_action_name }}</span>
85 </div>
86 </template>
87 <InvokeActionForm :action @success="handleInvokeSuccess" @close="showInvokeModal = false" />
88 </n-modal>
89 </div>
90 </template>
91
92 <script setup lang="ts">
93 import type { CopilotAction } from "@/types/copilotAction.d"
94 import { NButton, NModal, useMessage } from "naive-ui"
95 import { ref } from "vue"
96 import Badge from "@/components/common/Badge.vue"
97 import CardEntity from "@/components/common/cards/CardEntity.vue"
98 import Icon from "@/components/common/Icon.vue"
99 import ActionCardContent from "./ActionCardContent.vue"
100 import InvokeActionForm from "./InvokeActionForm.vue"
101 import TechnologyBadge from "./TechnologyBadge.vue"
102
103 const { action } = defineProps<{ action: CopilotAction; embedded?: boolean }>()
104
105 const showDetails = ref(false)
106 const showInvokeModal = ref(false)
107 const message = useMessage()
108 const PlayIcon = "carbon:play"
109
110 function handleInvokeSuccess() {
111 showInvokeModal.value = false
112 message.success("Action invoked successfully!")
113 }
114 </script>