mirror of https://github.com/rancher/dashboard.git
Masthead & other detail cleanup & text wrapping behavior
This commit is contained in:
parent
9fb5315b0c
commit
9b1c5431c6
|
|
@ -1,7 +0,0 @@
|
|||
# ASSETS
|
||||
|
||||
**This directory is not required, you can delete it if you don't want to use it.**
|
||||
|
||||
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
|
||||
|
||||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
|
||||
|
|
@ -104,7 +104,7 @@ $spacing-property-map: (
|
|||
}
|
||||
|
||||
.text-normal {
|
||||
font-weight: normal;
|
||||
font-size: initial;
|
||||
}
|
||||
|
||||
.text-italic {
|
||||
|
|
@ -139,6 +139,10 @@ $spacing-property-map: (
|
|||
display: block !important;
|
||||
}
|
||||
|
||||
.inline {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1234,6 +1234,7 @@ promptRemove:
|
|||
|
||||
rbac:
|
||||
roleBinding:
|
||||
noData: There are no members associated with this resource.
|
||||
user:
|
||||
label: User
|
||||
role:
|
||||
|
|
@ -1317,7 +1318,7 @@ resourceTable:
|
|||
namespace: Group by Namespace
|
||||
project: Group by Project
|
||||
groupLabel:
|
||||
namespace: "<span>Namespace:</span> {name}"
|
||||
namespace: "<span>Namespace:</span> {name/&}"
|
||||
notInANamespace: Not Namespaced
|
||||
notInAProject: Not in a Project
|
||||
project: "<span>Project:</span> {name}"
|
||||
|
|
@ -1325,9 +1326,15 @@ resourceTable:
|
|||
workspace: "<span>Workspace:</span> {name}"
|
||||
|
||||
resourceTabs:
|
||||
tabs:
|
||||
conditions: Conditions
|
||||
events: Recent Events
|
||||
conditions:
|
||||
tab: Conditions
|
||||
events:
|
||||
tab: Recent Events
|
||||
related:
|
||||
tab: Related Resources
|
||||
from: Referred To By
|
||||
to: Refers To
|
||||
|
||||
|
||||
resourceYaml:
|
||||
errors:
|
||||
|
|
@ -1560,6 +1567,7 @@ tableHeaders:
|
|||
resources: Resources
|
||||
restarts: Restarts
|
||||
rioImage: Image
|
||||
role: Role
|
||||
roles: Roles
|
||||
scale: Scale
|
||||
selector: Selector
|
||||
|
|
@ -1569,6 +1577,7 @@ tableHeaders:
|
|||
started: Started
|
||||
state: State
|
||||
status: Status
|
||||
subject: Subject
|
||||
success: Success
|
||||
summary: Summary
|
||||
target: Target
|
||||
|
|
@ -1867,7 +1876,7 @@ workload:
|
|||
podIP: Pod IP
|
||||
podRestarts: Pod Restarts
|
||||
workload: Workload
|
||||
pods: Pods
|
||||
pods: Pods by State
|
||||
runs: Runs
|
||||
gaugeStates:
|
||||
active: Active
|
||||
|
|
|
|||
|
|
@ -140,10 +140,10 @@ export default {
|
|||
|
||||
<template>
|
||||
<div :class="{'force-wrap': true, 'with-copy':copy}">
|
||||
<h4 v-if="labelKey" v-t="labelKey" />
|
||||
<h4 v-else-if="label">
|
||||
<h5 v-if="labelKey" v-t="labelKey" />
|
||||
<h5 v-else-if="label">
|
||||
{{ label }}
|
||||
</h4>
|
||||
</h5>
|
||||
|
||||
<span v-if="isEmpty" v-t="'detailText.empty'" class="text-italic" />
|
||||
<span v-else-if="isBinary" class="text-italic">{{ t('detailText.binary', {n: size}) }}</span>
|
||||
|
|
@ -169,7 +169,7 @@ export default {
|
|||
.with-copy {
|
||||
border: solid thin var(--border);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 20px;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
background-color: var(--input-bg);
|
||||
border-radius: var(--border-radius);
|
||||
|
|
|
|||
|
|
@ -135,10 +135,9 @@ export default {
|
|||
$spacing: 5px;
|
||||
|
||||
&:not(.empty) {
|
||||
border-top: 1px solid var(--border);
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin: 20px 0;
|
||||
padding: 20px 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tags {
|
||||
|
|
|
|||
|
|
@ -67,14 +67,21 @@ export default {
|
|||
|
||||
const cluster = this.$store.getters['clusterId'];
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
const out = [];
|
||||
|
||||
return this.filteredRelationships.map((r) => {
|
||||
for ( const r of this.filteredRelationships) {
|
||||
const state = r.state || 'active';
|
||||
const stateColor = colorForState(state, r.error, r.transitioning);
|
||||
const type = r[`${ this.direction }Type`];
|
||||
const schema = this.$store.getters[`${ inStore }/schemaFor`](type);
|
||||
|
||||
let name = r[`${ this.direction }Id`];
|
||||
|
||||
// Skip things like toType/toNamspace+selector for now
|
||||
if ( !name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let namespace = null;
|
||||
const idx = name.indexOf('/');
|
||||
const key = `${ type }/${ namespace }/${ name }`;
|
||||
|
|
@ -95,7 +102,7 @@ export default {
|
|||
}
|
||||
};
|
||||
|
||||
return {
|
||||
out.push({
|
||||
type,
|
||||
real: this.$store.getters[`${ inStore }/byId`](type, r[`${ this.direction }Id`]),
|
||||
id: r[`${ this.direction }Id`],
|
||||
|
|
@ -113,16 +120,18 @@ export default {
|
|||
stateDisplay: stateDisplay(state),
|
||||
stateBackground: stateColor.replace('text-', 'bg-'),
|
||||
groupByLabel: namespace,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
headers() {
|
||||
return [
|
||||
STATE,
|
||||
TYPE,
|
||||
NAME,
|
||||
NAMESPACE,
|
||||
TYPE,
|
||||
];
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -291,8 +291,8 @@ export default {
|
|||
{{ parent.displayName }}:
|
||||
</nuxt-link>
|
||||
<t :k="'resourceDetail.header.' + realMode" :subtype="resourceSubtype" :name="value.nameDisplay" />
|
||||
<BadgeState v-if="!isCreate && parent.showState" class="masthead-state" :value="value" />
|
||||
</h1>
|
||||
<BadgeState v-if="!isCreate && parent.showState" :value="value" />
|
||||
</div>
|
||||
<div v-if="!isCreate" class="subheader">
|
||||
<span v-if="isNamespace && project">{{ t("resourceDetail.masthead.project") }}: {{ project.nameDisplay }}</span>
|
||||
|
|
@ -302,31 +302,33 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
<slot name="right">
|
||||
<div class="actions">
|
||||
<ButtonGroup
|
||||
v-if="showSensitiveToggle"
|
||||
:value="!!hideSensitiveData"
|
||||
icon-size="lg"
|
||||
:options="sensitiveOptions"
|
||||
@input="toggleSensitiveData"
|
||||
/>
|
||||
<div class="actions-container">
|
||||
<div class="actions">
|
||||
<ButtonGroup
|
||||
v-if="showSensitiveToggle"
|
||||
:value="!!hideSensitiveData"
|
||||
icon-size="lg"
|
||||
:options="sensitiveOptions"
|
||||
@input="toggleSensitiveData"
|
||||
/>
|
||||
|
||||
<ButtonGroup
|
||||
v-if="viewOptions && isView"
|
||||
v-model="currentView"
|
||||
:options="viewOptions"
|
||||
/>
|
||||
<ButtonGroup
|
||||
v-if="viewOptions && isView"
|
||||
v-model="currentView"
|
||||
:options="viewOptions"
|
||||
/>
|
||||
|
||||
<button
|
||||
v-if="isView"
|
||||
ref="actions"
|
||||
aria-haspopup="true"
|
||||
type="button"
|
||||
class="btn btn-sm role-multi-action actions"
|
||||
@click="showActions"
|
||||
>
|
||||
<i class="icon icon-actions" />
|
||||
</button>
|
||||
<button
|
||||
v-if="isView"
|
||||
ref="actions"
|
||||
aria-haspopup="true"
|
||||
type="button"
|
||||
class="btn btn-sm role-multi-action actions"
|
||||
@click="showActions"
|
||||
>
|
||||
<i class="icon icon-actions" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</slot>
|
||||
</header>
|
||||
|
|
@ -343,6 +345,13 @@ export default {
|
|||
|
||||
<style lang='scss' scoped>
|
||||
.masthead {
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
HEADER {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.primaryheader {
|
||||
|
|
@ -351,7 +360,7 @@ export default {
|
|||
align-items: center;
|
||||
|
||||
h1 {
|
||||
margin-right: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +382,7 @@ export default {
|
|||
justify-content: flex-end;
|
||||
align-items:center;
|
||||
& .btn-group {
|
||||
margin-right: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -381,4 +390,10 @@ export default {
|
|||
margin: 3px 0 0 0;
|
||||
}
|
||||
|
||||
.masthead-state {
|
||||
font-size: initial;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -58,24 +58,28 @@ export default {
|
|||
<template>
|
||||
<header>
|
||||
<TypeDescription :resource="resource" />
|
||||
<h1>
|
||||
{{ typeDisplay }} <Favorite v-if="isExplorer" :resource="resource" />
|
||||
</h1>
|
||||
<div class="actions">
|
||||
<n-link
|
||||
v-if="isCreatable"
|
||||
:to="createLocation"
|
||||
class="btn role-primary"
|
||||
>
|
||||
{{ t("resourceList.head.create") }}
|
||||
</n-link>
|
||||
<n-link
|
||||
v-else-if="isYamlCreatable"
|
||||
:to="yamlCreateLocation"
|
||||
class="btn role-primary"
|
||||
>
|
||||
{{ t("resourceList.head.createFromYaml") }}
|
||||
</n-link>
|
||||
<div class="title">
|
||||
<h1 class="m-0">
|
||||
{{ typeDisplay }} <Favorite v-if="isExplorer" :resource="resource" />
|
||||
</h1>
|
||||
</div>
|
||||
<div class="actions-container">
|
||||
<div class="actions">
|
||||
<n-link
|
||||
v-if="isCreatable"
|
||||
:to="createLocation"
|
||||
class="btn role-primary"
|
||||
>
|
||||
{{ t("resourceList.head.create") }}
|
||||
</n-link>
|
||||
<n-link
|
||||
v-else-if="isYamlCreatable"
|
||||
:to="yamlCreateLocation"
|
||||
class="btn role-primary"
|
||||
>
|
||||
{{ t("resourceList.head.createFromYaml") }}
|
||||
</n-link>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
export default {
|
||||
inject: ['addTab', 'removeTab'],
|
||||
inject: ['addTab', 'removeTab', 'sideTabs'],
|
||||
|
||||
props: {
|
||||
label: {
|
||||
|
|
@ -71,7 +71,9 @@ export default {
|
|||
:aria-hidden="!active"
|
||||
role="tabpanel"
|
||||
>
|
||||
<h2>{{ label }}</h2>
|
||||
<h2 v-if="sideTabs">
|
||||
{{ label }}
|
||||
</h2>
|
||||
<slot />
|
||||
</section>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ export default {
|
|||
const tabs = this.tabs;
|
||||
|
||||
return {
|
||||
sideTabs: this.sideTabs,
|
||||
|
||||
addTab(tab) {
|
||||
const existing = findBy(tabs, 'name', tab.name);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ import Conditions from '@/components/form/Conditions';
|
|||
import { EVENT } from '@/config/types';
|
||||
import SortableTable from '@/components/SortableTable';
|
||||
import { _VIEW } from '@/config/query-params';
|
||||
import RelatedResources from '@/components/RelatedResources';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Tabbed,
|
||||
Tab,
|
||||
Conditions,
|
||||
SortableTable
|
||||
SortableTable,
|
||||
RelatedResources,
|
||||
},
|
||||
|
||||
mixins: [CreateEditView],
|
||||
|
|
@ -54,17 +56,15 @@ export default {
|
|||
|
||||
computed: {
|
||||
showConditions() {
|
||||
return this.isView && !!this.value?.status?.conditions;
|
||||
const inStore = this.$store.getters['currentProduct'].inStore;
|
||||
|
||||
return this.isView && this.value?.type && this.$store.getters[`${ inStore }/pathExistsInSchema`](this.value.type, 'status.conditions');
|
||||
},
|
||||
|
||||
showEvents() {
|
||||
return this.isView && !this.$fetchState.pending && this.hasEvents && this.events.length;
|
||||
},
|
||||
|
||||
hasCustomTabs() {
|
||||
return !!Object.keys(this.$slots).length;
|
||||
},
|
||||
|
||||
eventHeaders() {
|
||||
return [
|
||||
{
|
||||
|
|
@ -114,14 +114,14 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<Tabbed v-if="hasCustomTabs || showConditions || showEvents" v-bind="$attrs">
|
||||
<Tabbed v-bind="$attrs">
|
||||
<slot />
|
||||
|
||||
<Tab v-if="showConditions" :label="t('resourceTabs.tabs.conditions')" name="conditions" :weight="-1">
|
||||
<Tab v-if="showConditions" label-key="resourceTabs.conditions.tab" name="conditions" :weight="-1">
|
||||
<Conditions :value="value" />
|
||||
</Tab>
|
||||
|
||||
<Tab v-if="showEvents" :label="t('resourceTabs.tabs.events')" name="events" :weight="-2">
|
||||
<Tab v-if="showEvents" label-key="resourceTabs.events.tab" name="events" :weight="-2">
|
||||
<SortableTable
|
||||
:rows="events"
|
||||
:headers="eventHeaders"
|
||||
|
|
@ -132,5 +132,13 @@ export default {
|
|||
default-sort-by="date"
|
||||
/>
|
||||
</Tab>
|
||||
|
||||
<Tab name="related" label-key="resourceTabs.related.tab" :weight="-3">
|
||||
<h3 v-t="'resourceTabs.related.from'" />
|
||||
<RelatedResources :ignore-types="[value.type]" :value="value" direction="from" />
|
||||
|
||||
<h3 v-t="'resourceTabs.related.to'" class="mt-20" />
|
||||
<RelatedResources :ignore-types="[value.type]" :value="value" direction="to" />
|
||||
</Tab>
|
||||
</Tabbed>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ export default {
|
|||
<div v-for="(row,idx) in parsedRows" :key="idx" class="mb-20">
|
||||
<DetailText :value="row.value" :label="row.key" :binary="row.binary" />
|
||||
</div>
|
||||
<div v-if="!parsedRows.length">
|
||||
<div v-t="'sortableTable.noRows'" class="m-20 text-center" />
|
||||
</div>
|
||||
</Tab>
|
||||
</ResourceTabs>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@ import { base64Decode } from '@/utils/crypto';
|
|||
import CreateEditView from '@/mixins/create-edit-view';
|
||||
import ResourceTabs from '@/components/form/ResourceTabs';
|
||||
import DetailText from '@/components/DetailText';
|
||||
import RelatedResources from '@/components/RelatedResources';
|
||||
import Tab from '@/components/Tabbed/Tab';
|
||||
import { WORKLOAD_TYPES } from '@/config/types';
|
||||
|
||||
const types = [
|
||||
TYPES.OPAQUE,
|
||||
|
|
@ -23,7 +21,6 @@ export default {
|
|||
components: {
|
||||
ResourceTabs,
|
||||
DetailText,
|
||||
RelatedResources,
|
||||
Tab,
|
||||
},
|
||||
|
||||
|
|
@ -143,18 +140,6 @@ export default {
|
|||
return rows;
|
||||
},
|
||||
|
||||
hasRelatedWorkloads() {
|
||||
const { relationships = [] } = this.value.metadata;
|
||||
|
||||
for (const r in relationships) {
|
||||
if (r.rel === 'owner' && WORKLOAD_TYPES.includes(r.fromType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
dataLabel() {
|
||||
switch (this.value._type) {
|
||||
case TYPES.TLS:
|
||||
|
|
@ -219,13 +204,23 @@ export default {
|
|||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div v-for="(row,idx) in parsedRows" :key="idx" class="mb-20">
|
||||
<div v-for="(row,idx) in parsedRows" :key="idx" class="entry">
|
||||
<DetailText :value="row.value" :label="row.key" :conceal="true" />
|
||||
</div>
|
||||
<div v-if="!parsedRows.length">
|
||||
<div v-t="'sortableTable.noRows'" class="m-20 text-center" />
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab v-if="hasRelatedWorkloads" name="workloads" label-key="secret.relatedWorkloads">
|
||||
<RelatedResources :ignore-types="['pod']" :value="value" rel="uses" direction="from" />
|
||||
</Tab>
|
||||
</ResourceTabs>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.entry {
|
||||
margin-top: 10px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -20,19 +20,6 @@ export default {
|
|||
|
||||
mixins: [CreateEditView],
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'view'
|
||||
}
|
||||
},
|
||||
|
||||
async fetch() {
|
||||
const hash = {
|
||||
pods: this.value.pods(),
|
||||
|
|
@ -195,7 +182,7 @@ export default {
|
|||
<template>
|
||||
<Loading v-if="$fetchState.pending" />
|
||||
<div v-else>
|
||||
<h3 class="mt-20">
|
||||
<h3>
|
||||
{{ isJob || isCronJob ? t('workload.detailTop.runs') :t('workload.detailTop.pods') }}
|
||||
</h3>
|
||||
<div v-if="pods" class="gauges mb-20">
|
||||
|
|
@ -220,7 +207,7 @@ export default {
|
|||
/>
|
||||
</template>
|
||||
</div>
|
||||
<ResourceTabs>
|
||||
<ResourceTabs :value="value">
|
||||
<Tab v-if="jobs && jobs.length" name="jobs" :label="t('tableHeaders.jobs')">
|
||||
<ResourceTable
|
||||
:rows="jobs"
|
||||
|
|
@ -247,11 +234,11 @@ export default {
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.gauges {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
&>*{
|
||||
<style lang='scss' scoped>
|
||||
.gauges {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
&>*{
|
||||
flex: 1;
|
||||
margin-right: $column-gutter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,11 +333,6 @@ export default {
|
|||
margin-bottom: 20px;
|
||||
align-items: center;
|
||||
|
||||
H1 {
|
||||
grid-area: title;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.type-banner {
|
||||
grid-area: type-banner;
|
||||
}
|
||||
|
|
@ -350,9 +345,10 @@ export default {
|
|||
grid-area: title;
|
||||
}
|
||||
|
||||
.actions {
|
||||
.actions-container {
|
||||
grid-area: actions;
|
||||
margin-left: auto;
|
||||
height: 100%;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { _EDIT, _YAML } from '@/config/query-params';
|
||||
import impl from './impl';
|
||||
|
||||
export default {
|
||||
|
|
@ -6,12 +7,12 @@ export default {
|
|||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: _EDIT,
|
||||
},
|
||||
|
||||
as: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: _YAML,
|
||||
},
|
||||
|
||||
value: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue