mirror of https://github.com/rancher/dashboard.git
Merge branch 'master' into ingress-create
This commit is contained in:
commit
c67a37627e
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
|
|
@ -101,5 +101,12 @@
|
|||
|
||||
--tabbed-border : #{$medium};
|
||||
--tabbed-container-bg : #{$darkest};
|
||||
|
||||
--wm-tabs-bg : #{$medium};
|
||||
--wm-tab-bg : #{$darker};
|
||||
--wm-closer-hover-bg : #{$medium};
|
||||
--wm-tab-active-bg : #{$darker};
|
||||
--wm-body-bg : #{$darker};
|
||||
--wm-border : black;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,4 +140,12 @@ $selected: rgba($primary, .5);
|
|||
--diff-ins-border : #{rgba($success, 0.5)};
|
||||
--diff-chg-ins : #{rgba($success, 0.25)};
|
||||
--diff-chg-del : #{rgba($warning, 0.5)};
|
||||
|
||||
--wm-tabs-bg : #{$medium};
|
||||
--wm-tab-bg : #{$light};
|
||||
--wm-closer-hover-bg : #{$lighter};
|
||||
--wm-tab-active-bg : #{$lighter};
|
||||
--wm-body-bg : #{$lighter};
|
||||
--wm-border : var(--border);
|
||||
--wm-tab-height : 25px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,224 @@
|
|||
<script>
|
||||
import { mapState } from 'vuex';
|
||||
import { screenRect, boundingRect } from '@/utils/position';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return { dragOffset: 0 };
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState('wm', ['tabs', 'active', 'open', 'userHeight']),
|
||||
|
||||
height: {
|
||||
get() {
|
||||
if ( process.server ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @TODO remember across reloads, normalize to fit into current screen
|
||||
// const cached = window.localStorage.getItem('wm-height');
|
||||
|
||||
if ( this.userHeight ) {
|
||||
return this.userHeight;
|
||||
}
|
||||
|
||||
return 200;
|
||||
},
|
||||
|
||||
set(val) {
|
||||
this.$store.commit('wm/setUserHeight', val);
|
||||
this.show();
|
||||
|
||||
return val;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
tabs() {
|
||||
if ( this.open ) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if ( this.open ) {
|
||||
this.show();
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggle() {
|
||||
if ( this.open ) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
},
|
||||
|
||||
switchTo(tab) {
|
||||
this.$store.commit('wm/setActive', tab);
|
||||
},
|
||||
|
||||
show() {
|
||||
document.documentElement.style.setProperty('--wm-height', `${ this.height }px`);
|
||||
this.$store.commit('wm/setOpen', true);
|
||||
},
|
||||
|
||||
hide() {
|
||||
if ( this.tabs.length ) {
|
||||
document.documentElement.style.setProperty('--wm-height', `calc(var(--wm-tab-height) + 2px)`);
|
||||
} else {
|
||||
document.documentElement.style.setProperty('--wm-height', '0');
|
||||
}
|
||||
|
||||
this.$store.commit('wm/setOpen', false);
|
||||
},
|
||||
|
||||
dragStart(event) {
|
||||
console.log('dragStart', event);
|
||||
|
||||
const doc = document.documentElement;
|
||||
|
||||
doc.addEventListener('mousemove', this.dragMove);
|
||||
doc.addEventListener('touchmove', this.dragMove, true);
|
||||
doc.addEventListener('mouseup', this.dragEnd);
|
||||
doc.addEventListener('mouseleave', this.dragEnd);
|
||||
doc.addEventListener('touchend touchcancel', this.dragEnd, true);
|
||||
doc.addEventListener('touchstart', this.dragEnd, true);
|
||||
|
||||
const eventY = event.screenY;
|
||||
const rect = boundingRect(event.target);
|
||||
const offset = eventY - rect.top;
|
||||
|
||||
console.log(offset, eventY, rect);
|
||||
|
||||
this.dragOffset = offset;
|
||||
},
|
||||
|
||||
dragMove(event) {
|
||||
const rect = screenRect();
|
||||
const eventY = event.screenY;
|
||||
|
||||
const neu = rect.height - eventY - this.dragOffset;
|
||||
|
||||
console.log(rect.height, '-', eventY, '-', this.dragOffset, '=', neu);
|
||||
this.height = neu;
|
||||
},
|
||||
|
||||
dragEnd(event) {
|
||||
console.log('dragEnd', event);
|
||||
|
||||
const doc = document.documentElement;
|
||||
|
||||
doc.removeEventListener('mousemove', this.dragMove);
|
||||
doc.removeEventListener('touchmove', this.dragMove, true);
|
||||
doc.removeEventListener('mouseup', this.dragEnd);
|
||||
doc.removeEventListener('mouseleave', this.dragEnd);
|
||||
doc.removeEventListener('touchend touchcancel', this.dragEnd, true);
|
||||
doc.removeEventListener('touchstart', this.dragEnd, true);
|
||||
},
|
||||
|
||||
close(tab) {
|
||||
this.$store.dispatch('wm/close', tab);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="windowmanager">
|
||||
<div ref="tabs" class="tabs">
|
||||
<div
|
||||
v-for="tab in tabs"
|
||||
:key="tab"
|
||||
class="tab"
|
||||
:class="{'active': tab === active}"
|
||||
@click="switchTo(tab)"
|
||||
>
|
||||
{{ tab }}
|
||||
<i class="closer icon icon-x" @click="close(tab)" />
|
||||
</div>
|
||||
<div
|
||||
class="collapser"
|
||||
@click="toggle"
|
||||
@mousedown.prevent.stop="dragStart($event)"
|
||||
@touchstart.prevent.stop="dragStart($event)"
|
||||
>
|
||||
<i class="icon" :class="{'icon-chevron-up': !open, 'icon-chevron-down': open}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
{{ active }} Body
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.windowmanager {
|
||||
display: grid;
|
||||
height: var(--wm-height, 0);
|
||||
|
||||
grid-template-areas:
|
||||
"tabs"
|
||||
"body";
|
||||
|
||||
grid-template-rows: var(--wm-tab-height) auto;
|
||||
|
||||
.tabs {
|
||||
grid-area: tabs;
|
||||
background-color: var(--wm-tabs-bg);
|
||||
border-top: 1px solid var(--wm-border);
|
||||
border-bottom: 1px solid var(--wm-border);
|
||||
|
||||
display: flex;
|
||||
align-content: stretch;
|
||||
|
||||
.tab {
|
||||
border-top: 1px solid var(--wm-border);
|
||||
border-right: 1px solid var(--wm-border);
|
||||
padding: 0 10px;
|
||||
line-height: var(--wm-tab-height);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&.active {
|
||||
position: relative;
|
||||
background-color: var(--wm-body-bg);
|
||||
line-height: calc(var(--wm-tab-height) + 1px);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.collapser {
|
||||
width: var(--wm-tab-height);
|
||||
padding: 0 10px;
|
||||
text-align: center;
|
||||
border-left: 1px solid var(--wm-border);
|
||||
line-height: var(--wm-tab-height);
|
||||
height: calc(var(--wm-tab-height) + 1px);
|
||||
flex-grow: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.closer {
|
||||
padding: 0 0 0 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--wm-closer-hover-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
grid-area: body;
|
||||
background-color: var(--wm-body-bg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { sortBy } from '@/utils/sort';
|
||||
import { clone } from '@/utils/object';
|
||||
import { SCHEMA, COUNT, INGRESS } from '@/config/types';
|
||||
import { SCHEMA, COUNT, INGRESS, API_GROUP } from '@/config/types';
|
||||
import {
|
||||
isBasic,
|
||||
isIgnored,
|
||||
|
|
@ -23,7 +23,15 @@ export function allTypes($store) {
|
|||
for ( const schema of schemas ) {
|
||||
const attrs = schema.attributes || {};
|
||||
const count = counts[schema.id];
|
||||
const group = attrs.group;
|
||||
const groupName = attrs.group || 'core';
|
||||
const api = $store.getters['cluster/byId'](API_GROUP, groupName);
|
||||
|
||||
// Skip non-preferred versions
|
||||
if ( api?.preferredVersion?.version ) {
|
||||
if ( api.preferredVersion.version !== attrs.version ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !attrs.kind ) {
|
||||
// Skip the apiGroups resource
|
||||
|
|
@ -37,7 +45,7 @@ export function allTypes($store) {
|
|||
|
||||
out[schema.id] = {
|
||||
schema,
|
||||
group,
|
||||
group: groupName,
|
||||
id: schema.id,
|
||||
label: singularLabelFor(schema),
|
||||
namespaced: attrs.namespaced,
|
||||
|
|
@ -101,16 +109,6 @@ export function getTree(mode, clusterId, types, namespaces, currentType) {
|
|||
item.route.params.cluster = clusterId;
|
||||
}
|
||||
|
||||
if ( item.aggregateCount ) {
|
||||
let count = 0;
|
||||
|
||||
for ( const type of item.aggregateCount ) {
|
||||
count += matchingCounts(types[type], namespaces);
|
||||
}
|
||||
|
||||
item.count = count;
|
||||
}
|
||||
|
||||
const group = _ensureGroup(root, item.group, item.route);
|
||||
|
||||
group.children.push(item);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import {
|
|||
} from '@/utils/customized';
|
||||
|
||||
import {
|
||||
CONFIG_MAP, NAMESPACE, NODE, POD, SECRET, RIO, RBAC, SERVICE, PV, PVC, INGRESS, WORKLOAD
|
||||
CONFIG_MAP, NAMESPACE, NODE, POD, SECRET, RIO, RBAC, SERVICE, PV, PVC, INGRESS
|
||||
} from '@/config/types';
|
||||
|
||||
import {
|
||||
|
|
@ -53,7 +53,7 @@ export default function() {
|
|||
return out;
|
||||
}, 99, true);
|
||||
|
||||
mapType('', (typeStr, match, schema) => {
|
||||
mapType(/.*/, (typeStr, match, schema) => {
|
||||
return schema.attributes.kind;
|
||||
}, 1);
|
||||
|
||||
|
|
@ -73,6 +73,7 @@ export default function() {
|
|||
mapGroup('certmanager.k8s.io', 'Cert Manager');
|
||||
mapGroup(/^gateway.solo.io(.v\d+)?$/, 'Gloo');
|
||||
mapGroup('gloo.solo.io', 'Gloo');
|
||||
mapGroup(/^(.*\.)?monitoring.coreos.com$/, 'Monitoring');
|
||||
mapGroup(/^(.*\.)?tekton.dev$/, 'Tekton');
|
||||
mapGroup(/^(.*\.)?rio.cattle.io$/, 'Rio');
|
||||
mapGroup(/^(.*\.)?longhorn.rancher.io$/, 'Longhorn');
|
||||
|
|
@ -208,7 +209,6 @@ export default function() {
|
|||
name: 'c-cluster-workloads',
|
||||
params: { resource: 'workload' }
|
||||
},
|
||||
aggregateCount: Object.values(WORKLOAD)
|
||||
});
|
||||
|
||||
virtualType({
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import ActionMenu from '@/components/ActionMenu';
|
|||
import ButtonGroup from '@/components/ButtonGroup';
|
||||
import NamespaceFilter from '@/components/nav/NamespaceFilter';
|
||||
import ClusterSwitcher from '@/components/nav/ClusterSwitcher';
|
||||
import WindowManager from '@/components/nav/WindowManager';
|
||||
import ShellSocket from '@/components/ContainerExec/ShellSocket';
|
||||
import PromptRemove from '@/components/PromptRemove';
|
||||
import Group from '@/components/nav/Group';
|
||||
|
|
@ -30,6 +31,7 @@ export default {
|
|||
ButtonGroup,
|
||||
Group,
|
||||
ShellSocket,
|
||||
WindowManager
|
||||
},
|
||||
|
||||
middleware: ['authenticated'],
|
||||
|
|
@ -212,7 +214,9 @@ export default {
|
|||
</main>
|
||||
|
||||
<div class="wm">
|
||||
<WindowManager />
|
||||
</div>
|
||||
|
||||
<ShellSocket />
|
||||
<ActionMenu />
|
||||
<PromptRemove />
|
||||
|
|
@ -231,8 +235,8 @@ export default {
|
|||
"switcher main main main"
|
||||
"wm wm wm wm";
|
||||
|
||||
grid-template-columns: var(--nav-width) auto 0px var(--header-height);
|
||||
grid-template-rows: var(--header-height) auto var(--footer-height) var(--wm-height, 0px);
|
||||
grid-template-columns: var(--nav-width) auto 0px var(--header-height);
|
||||
grid-template-rows: var(--header-height) auto var(--footer-height) var(--wm-height, 0px);
|
||||
|
||||
&.back-to-rancher {
|
||||
grid-template-columns: var(--nav-width) auto 150px var(--header-height);
|
||||
|
|
@ -360,6 +364,5 @@ export default {
|
|||
|
||||
.wm {
|
||||
grid-area: wm;
|
||||
background-color: red;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ export default {
|
|||
<h1>
|
||||
Cluster: {{ cluster.nameDisplay }}
|
||||
</h1>
|
||||
<div class="text-center" style="margin-top: 200px;">
|
||||
Dashboard wheels...
|
||||
<div class="text-center">
|
||||
<img src="~assets/images/i-cant-believe-its-not-wheels.png" style="width: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ export const actions = {
|
|||
dispatch('cluster/subscribe');
|
||||
|
||||
const res = await allHash({
|
||||
apiGroups: dispatch('cluster/findAll', { type: API_GROUP, opt: { url: 'apiGroups' } }),
|
||||
apiGroups: dispatch('cluster/findAll', { type: API_GROUP, opt: { url: 'apiGroups', watch: false } }),
|
||||
counts: dispatch('cluster/findAll', { type: COUNT, opt: { url: 'counts' } }),
|
||||
namespaces: dispatch('cluster/findAll', { type: NAMESPACE, opt: { url: 'core.v1.namespaces' } })
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
import { addObject, removeObject } from '@/utils/array';
|
||||
|
||||
export const state = function() {
|
||||
return {
|
||||
tabs: [],
|
||||
active: null,
|
||||
open: false,
|
||||
userHeight: null,
|
||||
};
|
||||
};
|
||||
|
||||
export const mutations = {
|
||||
addTab(state, tab) {
|
||||
addObject(state.tabs, tab);
|
||||
state.active = tab;
|
||||
state.open = true;
|
||||
},
|
||||
|
||||
removeTab(state, tab) {
|
||||
removeObject(state.tabs, tab);
|
||||
},
|
||||
|
||||
setOpen(state, open) {
|
||||
state.open = open;
|
||||
},
|
||||
|
||||
setActive(state, tab) {
|
||||
state.active = tab;
|
||||
},
|
||||
|
||||
setUserHeight(state, height) {
|
||||
state.userHeight = height;
|
||||
}
|
||||
};
|
||||
|
||||
export const actions = {
|
||||
close({ state, commit }, tab) {
|
||||
debugger;
|
||||
// @TODO close/disconnect things hook...
|
||||
let idx = state.tabs.indexOf(tab);
|
||||
|
||||
commit('removeTab', tab);
|
||||
if ( idx >= state.tabs.length ) {
|
||||
idx = state.tabs.length - 1;
|
||||
}
|
||||
|
||||
if ( idx >= 0 ) {
|
||||
commit('setActive', state.tabs[idx]);
|
||||
} else {
|
||||
commit('setOpen', false);
|
||||
}
|
||||
},
|
||||
|
||||
open({ commit }, tab) {
|
||||
commit('addTab', tab);
|
||||
}
|
||||
};
|
||||
|
|
@ -394,7 +394,7 @@ function _normalizeType(type) {
|
|||
|
||||
function _addMapping(mappings, match, replace, weight, continueOnMatch) {
|
||||
if ( typeof match === 'string' ) {
|
||||
match = new RegExp(escapeRegex(match), 'i');
|
||||
match = new RegExp(`^${ escapeRegex(match) }$`, 'i');
|
||||
}
|
||||
|
||||
mappings.push({
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const STATE_RECONNECTING = 'reconnecting';
|
|||
export default class Socket extends EventTarget {
|
||||
url;
|
||||
autoReconnect = true;
|
||||
frameTimeout = 32000;
|
||||
frameTimeout = 35000;
|
||||
metadata = {};
|
||||
|
||||
// "Private"
|
||||
|
|
|
|||
Loading…
Reference in New Issue