diff --git a/assets/images/i-cant-believe-its-not-wheels.png b/assets/images/i-cant-believe-its-not-wheels.png
new file mode 100644
index 0000000000..899cd8dae8
Binary files /dev/null and b/assets/images/i-cant-believe-its-not-wheels.png differ
diff --git a/assets/styles/themes/_dark.scss b/assets/styles/themes/_dark.scss
index 237f7d6785..52e9af34f7 100644
--- a/assets/styles/themes/_dark.scss
+++ b/assets/styles/themes/_dark.scss
@@ -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;
}
diff --git a/assets/styles/themes/_light.scss b/assets/styles/themes/_light.scss
index 8f1730dfed..6344fd29fa 100644
--- a/assets/styles/themes/_light.scss
+++ b/assets/styles/themes/_light.scss
@@ -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;
}
diff --git a/components/nav/WindowManager/Window.vue b/components/nav/WindowManager/Window.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/components/nav/WindowManager/index.vue b/components/nav/WindowManager/index.vue
new file mode 100644
index 0000000000..4a6bbc527a
--- /dev/null
+++ b/components/nav/WindowManager/index.vue
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+ {{ tab }}
+
+
+
+
+
+
+
+ {{ active }} Body
+
+
+
+
+
diff --git a/config/nav-cluster.js b/config/nav-cluster.js
index 2e82a8def4..d00a2e96ab 100644
--- a/config/nav-cluster.js
+++ b/config/nav-cluster.js
@@ -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);
diff --git a/config/type-config.js b/config/type-config.js
index 949db78b45..313d8fc0c3 100644
--- a/config/type-config.js
+++ b/config/type-config.js
@@ -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({
diff --git a/layouts/default.vue b/layouts/default.vue
index 303602fe5d..c3698d1fe8 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -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 {
+
+
@@ -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;
}
diff --git a/pages/c/_cluster/index.vue b/pages/c/_cluster/index.vue
index 308eb6d720..950aa8af4c 100644
--- a/pages/c/_cluster/index.vue
+++ b/pages/c/_cluster/index.vue
@@ -20,8 +20,8 @@ export default {
Cluster: {{ cluster.nameDisplay }}
-
- Dashboard wheels...
+
+
diff --git a/store/index.js b/store/index.js
index 656547f36e..662ef4f4a6 100644
--- a/store/index.js
+++ b/store/index.js
@@ -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' } })
});
diff --git a/store/wm.js b/store/wm.js
new file mode 100644
index 0000000000..c0da2f6ffd
--- /dev/null
+++ b/store/wm.js
@@ -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);
+ }
+};
diff --git a/utils/customized.js b/utils/customized.js
index 387e46bd72..a8a41206c8 100644
--- a/utils/customized.js
+++ b/utils/customized.js
@@ -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({
diff --git a/utils/socket.js b/utils/socket.js
index cf24bec7ae..eeb257add3 100644
--- a/utils/socket.js
+++ b/utils/socket.js
@@ -24,7 +24,7 @@ const STATE_RECONNECTING = 'reconnecting';
export default class Socket extends EventTarget {
url;
autoReconnect = true;
- frameTimeout = 32000;
+ frameTimeout = 35000;
metadata = {};
// "Private"