mirror of https://github.com/rancher/dashboard.git
220 lines
4.7 KiB
Vue
220 lines
4.7 KiB
Vue
<script>
|
|
import { NORMAN } from '@shell/config/types';
|
|
|
|
export default {
|
|
props: {
|
|
value: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
|
|
useMuted: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
|
|
showLabels: {
|
|
type: Boolean,
|
|
default: false,
|
|
}
|
|
},
|
|
|
|
async fetch() {
|
|
this.loadData();
|
|
},
|
|
|
|
data() {
|
|
// Load from cache immediately if possible
|
|
return { principal: null };
|
|
},
|
|
|
|
computed: {
|
|
showBoth() {
|
|
const p = this.principal;
|
|
|
|
return p.name && p.loginName && p.name.trim().toLowerCase() !== p.loginName.trim().toLowerCase();
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
async loadData() {
|
|
this.principal = this.$store.getters['rancher/byId'](NORMAN.PRINCIPAL, this.value);
|
|
|
|
if ( this.principal ) {
|
|
return;
|
|
}
|
|
|
|
const principalId = escape(this.value).replace(/\//g, '%2F');
|
|
|
|
try {
|
|
this.principal = await this.$store.dispatch('rancher/find', {
|
|
type: NORMAN.PRINCIPAL,
|
|
id: this.value,
|
|
opt: { url: `/v3/principals/${ principalId }` }
|
|
});
|
|
} catch (e) {
|
|
console.error('Failed to fetch principal', this.value, principalId); // eslint-disable-line no-console
|
|
}
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
value() {
|
|
this.loadData();
|
|
}
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="principal"
|
|
:class="{'showLabels': showLabels}"
|
|
>
|
|
<template v-if="!principal && $fetchState.pending">
|
|
<div class="avatar">
|
|
<div class="empty">
|
|
<i class="icon icon-spinner icon-lg" />
|
|
</div>
|
|
</div>
|
|
<div
|
|
v-clean-html="t('principal.loading', null, true)"
|
|
class="name"
|
|
:class="{'text-muted': useMuted}"
|
|
/>
|
|
<div class="description" />
|
|
</template>
|
|
|
|
<template v-else-if="principal">
|
|
<div class="avatar">
|
|
<img
|
|
:src="principal.avatarSrc"
|
|
:class="{'round': principal.roundAvatar}"
|
|
:alt="t('principal.alt.avatar')"
|
|
>
|
|
</div>
|
|
<div
|
|
v-if="showLabels"
|
|
class="name"
|
|
>
|
|
<table>
|
|
<tbody>
|
|
<tr><th>{{ t('principal.name') }}: </th><td>{{ principal.name || principal.loginName }}</td></tr>
|
|
<tr><th>{{ t('principal.loginName') }}: </th><td>{{ principal.loginName }}</td></tr>
|
|
<tr><th>{{ t('principal.type') }}: </th><td>{{ principal.displayType }}</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<template v-else>
|
|
<div class="name">
|
|
<template v-if="showBoth">
|
|
{{ principal.name }}
|
|
<span
|
|
v-if="principal.loginName"
|
|
:class="{'text-muted': useMuted}"
|
|
>({{ principal.loginName }})</span>
|
|
</template>
|
|
<template v-else-if="principal.name">
|
|
{{ principal.name }}
|
|
</template>
|
|
<template v-else>
|
|
{{ principal.loginName }}
|
|
</template>
|
|
</div>
|
|
<div
|
|
class="description"
|
|
:class="{'text-muted': useMuted}"
|
|
>
|
|
{{ principal.displayType }}
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<div class="avatar">
|
|
<div
|
|
class="empty"
|
|
:class="{'text-muted': useMuted}"
|
|
>
|
|
<i class="icon icon-warning icon-lg" />
|
|
</div>
|
|
</div>
|
|
<div
|
|
v-t="'principal.error'"
|
|
class="name text-error"
|
|
/>
|
|
<div
|
|
class="description"
|
|
:class="{'text-muted': useMuted}"
|
|
>
|
|
{{ value }}
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
$size: 40px;
|
|
|
|
.principal {
|
|
display: grid;
|
|
grid-template-areas:
|
|
"avatar name"
|
|
"avatar description";
|
|
grid-template-columns: $size auto;
|
|
grid-template-rows: auto math.div($size, 2);
|
|
column-gap: 10px;
|
|
|
|
th {
|
|
text-align: left;
|
|
font-weight: normal;
|
|
padding-right: 10px;
|
|
}
|
|
|
|
&.showLabels {
|
|
grid-template-areas:
|
|
"avatar name";
|
|
grid-template-columns: 60px auto;
|
|
grid-template-rows: 60px;
|
|
column-gap: 0;
|
|
.name {
|
|
line-height: unset;
|
|
}
|
|
|
|
table tr td:not(:first-of-type) {
|
|
padding-left: 10px;
|
|
}
|
|
}
|
|
|
|
.avatar {
|
|
grid-area: avatar;
|
|
text-align: center;
|
|
|
|
DIV.empty {
|
|
border: 1px solid var(--border);
|
|
line-height: $size;
|
|
}
|
|
|
|
IMG {
|
|
width: $size;
|
|
height: $size;
|
|
}
|
|
|
|
DIV.round, IMG.round {
|
|
border-radius: 50%;
|
|
}
|
|
}
|
|
|
|
.name {
|
|
grid-area: name;
|
|
line-height: math.div($size, 2);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.description {
|
|
grid-area: description;
|
|
line-height: math.div($size, 2);
|
|
}
|
|
}
|
|
</style>
|