mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
1 parent
4a8079debc
commit
5a76c2f331
8 files changed
+87
-98
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { debounce } from "lodash";
|
||||
import { action, comparer, IReactionDisposer, IReactionOptions, observable, reaction, toJS, when } from "mobx";
|
||||
import { autobind, createStorage } from "../../utils";
|
||||
import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../kube-object.store";
|
||||
@@ -7,14 +8,14 @@ import { apiManager } from "../../api/api-manager";
|
||||
import { isAllowedResource } from "../../../common/rbac";
|
||||
import { clusterStore, getHostedCluster } from "../../../common/cluster-store";
|
||||
|
||||
const storage = createStorage<string[]>("context_namespaces", []);
|
||||
const storage = createStorage<string[]>("context_namespaces");
|
||||
|
||||
export const namespaceUrlParam = createPageParam<string[]>({
|
||||
name: "namespaces",
|
||||
isSystem: true,
|
||||
multiValues: true,
|
||||
get defaultValue() {
|
||||
return storage.get(); // initial namespaces coming from URL or local-storage (default)
|
||||
return storage.get() ?? []; // initial namespaces coming from URL or local-storage (default)
|
||||
}
|
||||
});
|
||||
|
||||
@@ -51,9 +52,9 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
await getHostedCluster().whenReady; // wait for cluster-state from main
|
||||
this.isReady = true;
|
||||
|
||||
this.setContext(this.initNamespaces);
|
||||
this.onSelectedNamespacesChange();
|
||||
this.onAllowedNamespacesChange();
|
||||
this.setContext(this.initialNamespaces);
|
||||
this.autoLoadAllowedNamespaces();
|
||||
this.autoUpdateUrlAndLocalStorage();
|
||||
}
|
||||
|
||||
public onContextChange(callback: (contextNamespaces: string[]) => void, opts: IReactionOptions = {}): IReactionDisposer {
|
||||
@@ -63,7 +64,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
});
|
||||
}
|
||||
|
||||
private onSelectedNamespacesChange(): IReactionDisposer {
|
||||
private autoUpdateUrlAndLocalStorage(): IReactionDisposer {
|
||||
return this.onContextChange(namespaces => {
|
||||
storage.set(namespaces); // save to local-storage
|
||||
namespaceUrlParam.set(namespaces, { replaceHistory: true }); // update url
|
||||
@@ -73,7 +74,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
});
|
||||
}
|
||||
|
||||
private onAllowedNamespacesChange(): IReactionDisposer {
|
||||
private autoLoadAllowedNamespaces(): IReactionDisposer {
|
||||
return reaction(() => this.allowedNamespaces, () => this.loadAll(), {
|
||||
fireImmediately: true,
|
||||
equals: comparer.identity,
|
||||
@@ -84,28 +85,19 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
return toJS(getHostedCluster().allowedNamespaces);
|
||||
}
|
||||
|
||||
get initNamespaces() {
|
||||
const allowedNamespaces = new Set(this.allowedNamespaces);
|
||||
const lastUsedNamespaces = new Set(storage.get());
|
||||
private get initialNamespaces(): string[] {
|
||||
const allowed = new Set(this.allowedNamespaces);
|
||||
const prevSelected = storage.get();
|
||||
|
||||
// remove previously saved, but currently disallowed namespaces
|
||||
lastUsedNamespaces.forEach(namespace => {
|
||||
if (!allowedNamespaces.has(namespace)) {
|
||||
lastUsedNamespaces.delete(namespace);
|
||||
}
|
||||
});
|
||||
|
||||
// return previously saved and currently allowed namespaces
|
||||
if (lastUsedNamespaces.size) {
|
||||
return Array.from(lastUsedNamespaces);
|
||||
if (Array.isArray(prevSelected)) {
|
||||
return prevSelected.filter(namespace => allowed.has(namespace));
|
||||
}
|
||||
|
||||
// otherwise select "default" or first allowed namespace
|
||||
else {
|
||||
if (allowedNamespaces.has("default")) {
|
||||
return ["default"];
|
||||
} else if (allowedNamespaces.size) {
|
||||
return [Array.from(allowedNamespaces)[0]];
|
||||
}
|
||||
if (allowed.has("default")) {
|
||||
return ["default"];
|
||||
} else if (allowed.size) {
|
||||
return [Array.from(allowed)[0]];
|
||||
}
|
||||
|
||||
return [];
|
||||
@@ -132,17 +124,18 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
return super.subscribe(apis);
|
||||
}
|
||||
|
||||
async loadAll() {
|
||||
return super.loadAll({
|
||||
// prevent multiple loading from different sources (e.g. items-list-layout, namespace-select)
|
||||
private loadAllLazy = debounce(() => {
|
||||
super.loadAll({
|
||||
namespaces: this.allowedNamespaces,
|
||||
});
|
||||
}, 250);
|
||||
|
||||
async loadAll() {
|
||||
this.loadAllLazy();
|
||||
}
|
||||
|
||||
protected async loadItems({ isAdmin, namespaces }: KubeObjectStoreLoadingParams) {
|
||||
if (isAdmin) {
|
||||
return this.api.list();
|
||||
}
|
||||
|
||||
protected async loadItems({ namespaces }: KubeObjectStoreLoadingParams) {
|
||||
if (!isAllowedResource("namespaces")) {
|
||||
return namespaces.map(getDummyNamespace);
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ export class RoleBindingsStore extends KubeObjectStore<RoleBinding> {
|
||||
return clusterRoleBindingApi.get(params);
|
||||
}
|
||||
|
||||
protected async loadItems({ isAdmin, namespaces }: KubeObjectStoreLoadingParams): Promise<RoleBinding[]> {
|
||||
protected async loadItems(params: KubeObjectStoreLoadingParams): Promise<RoleBinding[]> {
|
||||
const items = await Promise.all([
|
||||
super.loadItems({ isAdmin, namespaces, api: clusterRoleBindingApi }),
|
||||
super.loadItems({ isAdmin, namespaces, api: roleBindingApi }),
|
||||
super.loadItems({ ...params, api: clusterRoleBindingApi }),
|
||||
super.loadItems({ ...params, api: roleBindingApi }),
|
||||
]);
|
||||
|
||||
return items.flat();
|
||||
|
||||
@@ -24,10 +24,10 @@ export class RolesStore extends KubeObjectStore<Role> {
|
||||
return clusterRoleApi.get(params);
|
||||
}
|
||||
|
||||
protected async loadItems({ isAdmin, namespaces }: KubeObjectStoreLoadingParams): Promise<Role[]> {
|
||||
protected async loadItems(params: KubeObjectStoreLoadingParams): Promise<Role[]> {
|
||||
const items = await Promise.all([
|
||||
super.loadItems({ isAdmin, namespaces, api: clusterRoleApi }),
|
||||
super.loadItems({ isAdmin, namespaces, api: roleApi }),
|
||||
super.loadItems({ ...params, api: clusterRoleApi }),
|
||||
super.loadItems({ ...params, api: roleApi }),
|
||||
]);
|
||||
|
||||
return items.flat();
|
||||
|
||||
@@ -48,7 +48,6 @@ export class WorkloadsOverview extends React.Component<Props> {
|
||||
if (this.isUnmounting) break;
|
||||
|
||||
try {
|
||||
store.reset();
|
||||
await store.loadAll();
|
||||
unsubscribeMap.get(store)?.(); // unsubscribe previous watcher
|
||||
unsubscribeMap.set(store, store.subscribe());
|
||||
|
||||
@@ -112,11 +112,11 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
this.loadStores();
|
||||
|
||||
if (!this.props.isClusterScoped) {
|
||||
disposeOnUnmount(this, [
|
||||
namespaceStore.onContextChange(() => this.loadStores(), {
|
||||
fireImmediately: true,
|
||||
})
|
||||
namespaceStore.onContextChange(() => this.loadStores())
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,6 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
||||
}
|
||||
|
||||
try {
|
||||
store.reset();
|
||||
await store.loadAll();
|
||||
this.watchDisposers.push(store.subscribe());
|
||||
} catch (error) {
|
||||
@@ -195,9 +194,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
||||
};
|
||||
|
||||
@computed get isReady() {
|
||||
const { isReady, store } = this.props;
|
||||
|
||||
return typeof isReady == "boolean" ? isReady : store.isLoaded;
|
||||
return this.props.isReady ?? this.props.store.isLoaded;
|
||||
}
|
||||
|
||||
@computed get filters() {
|
||||
@@ -330,12 +327,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
||||
}
|
||||
|
||||
renderNoItems() {
|
||||
const { allItems, items, filters } = this;
|
||||
const allItemsCount = allItems.length;
|
||||
const itemsCount = items.length;
|
||||
const isFiltered = filters.length > 0 && allItemsCount > itemsCount;
|
||||
|
||||
if (isFiltered) {
|
||||
if (this.filters.length > 0) {
|
||||
return (
|
||||
<NoItems>
|
||||
No items found.
|
||||
|
||||
Reference in new issue
Block a user