1<script> 2import { 3 GlLink, 4 GlModalDirective, 5 GlTable, 6 GlIcon, 7 GlSprintf, 8 GlTooltip, 9 GlPopover, 10} from '@gitlab/ui'; 11import { s__ } from '~/locale'; 12import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; 13import timeagoMixin from '~/vue_shared/mixins/timeago'; 14import { helpPagePath } from '~/helpers/help_page_helper'; 15import { INSTALL_AGENT_MODAL_ID, AGENT_STATUSES } from '../constants'; 16import { getAgentConfigPath } from '../clusters_util'; 17 18export default { 19 components: { 20 GlLink, 21 GlTable, 22 GlIcon, 23 GlSprintf, 24 GlTooltip, 25 GlPopover, 26 TimeAgoTooltip, 27 }, 28 directives: { 29 GlModalDirective, 30 }, 31 mixins: [timeagoMixin], 32 INSTALL_AGENT_MODAL_ID, 33 AGENT_STATUSES, 34 35 troubleshooting_link: helpPagePath('user/clusters/agent/index', { 36 anchor: 'troubleshooting', 37 }), 38 props: { 39 agents: { 40 required: true, 41 type: Array, 42 }, 43 }, 44 computed: { 45 fields() { 46 const tdClass = 'gl-py-5!'; 47 return [ 48 { 49 key: 'name', 50 label: s__('ClusterAgents|Name'), 51 tdClass, 52 }, 53 { 54 key: 'status', 55 label: s__('ClusterAgents|Connection status'), 56 tdClass, 57 }, 58 { 59 key: 'lastContact', 60 label: s__('ClusterAgents|Last contact'), 61 tdClass, 62 }, 63 { 64 key: 'configuration', 65 label: s__('ClusterAgents|Configuration'), 66 tdClass, 67 }, 68 ]; 69 }, 70 }, 71 methods: { 72 getCellId(item) { 73 return `connection-status-${item.name}`; 74 }, 75 getAgentConfigPath, 76 }, 77}; 78</script> 79 80<template> 81 <gl-table 82 :items="agents" 83 :fields="fields" 84 stacked="md" 85 head-variant="white" 86 thead-class="gl-border-b-solid gl-border-b-2 gl-border-b-gray-100" 87 class="gl-mb-4!" 88 data-testid="cluster-agent-list-table" 89 > 90 <template #cell(name)="{ item }"> 91 <gl-link :href="item.webPath" data-testid="cluster-agent-name-link"> 92 {{ item.name }} 93 </gl-link> 94 </template> 95 96 <template #cell(status)="{ item }"> 97 <span :id="getCellId(item)" class="gl-md-pr-5" data-testid="cluster-agent-connection-status"> 98 <span :class="$options.AGENT_STATUSES[item.status].class" class="gl-mr-3"> 99 <gl-icon :name="$options.AGENT_STATUSES[item.status].icon" :size="12" /></span 100 >{{ $options.AGENT_STATUSES[item.status].name }} 101 </span> 102 <gl-tooltip v-if="item.status === 'active'" :target="getCellId(item)" placement="right"> 103 <gl-sprintf :message="$options.AGENT_STATUSES[item.status].tooltip.title" 104 ><template #timeAgo>{{ timeFormatted(item.lastContact) }}</template> 105 </gl-sprintf> 106 </gl-tooltip> 107 <gl-popover 108 v-else 109 :target="getCellId(item)" 110 :title="$options.AGENT_STATUSES[item.status].tooltip.title" 111 placement="right" 112 container="viewport" 113 > 114 <p> 115 <gl-sprintf :message="$options.AGENT_STATUSES[item.status].tooltip.body" 116 ><template #timeAgo>{{ timeFormatted(item.lastContact) }}</template></gl-sprintf 117 > 118 </p> 119 <p class="gl-mb-0"> 120 <gl-link :href="$options.troubleshooting_link" target="_blank" class="gl-font-sm"> 121 {{ s__('ClusterAgents|Learn how to troubleshoot') }}</gl-link 122 > 123 </p> 124 </gl-popover> 125 </template> 126 127 <template #cell(lastContact)="{ item }"> 128 <span data-testid="cluster-agent-last-contact"> 129 <time-ago-tooltip v-if="item.lastContact" :time="item.lastContact" /> 130 <span v-else>{{ s__('ClusterAgents|Never') }}</span> 131 </span> 132 </template> 133 134 <template #cell(configuration)="{ item }"> 135 <span data-testid="cluster-agent-configuration-link"> 136 <gl-link v-if="item.configFolder" :href="item.configFolder.webPath"> 137 {{ getAgentConfigPath(item.name) }} 138 </gl-link> 139 140 <span v-else>{{ getAgentConfigPath(item.name) }}</span> 141 </span> 142 </template> 143 </gl-table> 144</template> 145