Navigation refactoring, handling extension page params (#1651)

* decentralizing page url-params management -- PoC / tsc 4.1 random fixes

Signed-off-by: Roman <ixrock@gmail.com>

* fixes, tweak example-extension for demo

Signed-off-by: Roman <ixrock@gmail.com>

* lint fixes, revert tests

Signed-off-by: Roman <ixrock@gmail.com>

* removed occasional changes related to typescript 4.1

Signed-off-by: Roman <ixrock@gmail.com>

* updated example with 2 menu-items targeting same page with different params

Signed-off-by: Roman <ixrock@gmail.com>

* fix: merge page url chunks with native URL()-api, simplified default page-params registration

Signed-off-by: Roman <ixrock@gmail.com>

* fix: make lint happy

Signed-off-by: Roman <ixrock@gmail.com>

* fix: unit-tests

Signed-off-by: Roman <ixrock@gmail.com>

* renaming by jim's request: UrlParam => PageParam (type), createUrlParam => createPageParam (helper)

Signed-off-by: Roman <ixrock@gmail.com>

* fix: reverting NamespaceStore public-api breaking changes

Signed-off-by: Roman <ixrock@gmail.com>

* lint fix

Signed-off-by: Roman <ixrock@gmail.com>

* fine-tuning

Signed-off-by: Roman <ixrock@gmail.com>

* yes, lint always unhappy

Signed-off-by: Roman <ixrock@gmail.com>

* fix build

Signed-off-by: Roman <ixrock@gmail.com>

* small fixes

Signed-off-by: Roman <ixrock@gmail.com>

* fix merge-conflicts

Signed-off-by: Roman <ixrock@gmail.com>

* removed `isSystem` page-param's init field exposed to extensions-api

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman authored and GitHub committed 2020-12-22 15:29:25 +02:00
1 parent 11c611dabe
commit be4e1aa15c
64 files changed
+751 -518

No files matched your search

@@ -7,9 +7,8 @@ import { Trans } from "@lingui/macro";
import { DrawerItem } from "../drawer";
import { cssNames } from "../../utils";
import { Namespace } from "../../api/endpoints";
import { KubeObjectDetailsProps } from "../kube-object";
import { getDetailsUrl, KubeObjectDetailsProps } from "../kube-object";
import { Link } from "react-router-dom";
import { getDetailsUrl } from "../../navigation";
import { Spinner } from "../spinner";
import { resourceQuotaStore } from "../+config-resource-quotas/resource-quotas.store";
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
@@ -1,44 +1,52 @@
import { action, observable, reaction } from "mobx";
import { action, comparer, observable, reaction } from "mobx";
import { autobind, createStorage } from "../../utils";
import { KubeObjectStore } from "../../kube-object.store";
import { Namespace, namespacesApi } from "../../api/endpoints";
import { IQueryParams, navigation, setQueryParams } from "../../navigation";
import { createPageParam } from "../../navigation";
import { apiManager } from "../../api/api-manager";
import { isAllowedResource } from "../../../common/rbac";
import { getHostedCluster } from "../../../common/cluster-store";
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)
}
});
@autobind()
export class NamespaceStore extends KubeObjectStore<Namespace> {
api = namespacesApi;
contextNs = observable.array<string>();
protected storage = createStorage<string[]>("context_ns", this.contextNs);
get initNamespaces() {
const fromUrl = navigation.searchParams.getAsArray("namespaces");
return fromUrl.length ? fromUrl : this.storage.get();
}
constructor() {
super();
this.init();
}
// restore context namespaces
const { initNamespaces: namespaces } = this;
private init() {
this.setContext(this.initNamespaces);
this.setContext(namespaces);
this.updateUrl(namespaces);
// sync with local-storage & url-search-params
reaction(() => this.contextNs.toJS(), namespaces => {
this.storage.set(namespaces);
this.updateUrl(namespaces);
return reaction(() => this.contextNs.toJS(), namespaces => {
storage.set(namespaces); // save to local-storage
namespaceUrlParam.set(namespaces, { replaceHistory: true }); // update url
}, {
fireImmediately: true,
equals: comparer.identity,
});
}
getContextParams(): Partial<IQueryParams> {
get initNamespaces() {
return namespaceUrlParam.get();
}
getContextParams() {
return {
namespaces: this.contextNs
namespaces: this.contextNs.toJS(),
};
}
@@ -47,16 +55,12 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
// if user has given static list of namespaces let's not start watches because watch adds stuff that's not wanted
if (accessibleNamespaces.length > 0) {
return () => { return; };
return Function; // no-op
}
return super.subscribe(apis);
}
protected updateUrl(namespaces: string[]) {
setQueryParams({ namespaces }, { replace: true });
}
protected async loadItems(namespaces?: string[]) {
if (!isAllowedResource("namespaces")) {
if (namespaces) return namespaces.map(this.getDummyNamespace);
@@ -84,6 +88,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
});
}
@action
setContext(namespaces: string[]) {
this.contextNs.replace(namespaces);
}
@@ -94,6 +99,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
return context.every(namespace => this.contextNs.includes(namespace));
}
@action
toggleContext(namespace: string) {
if (this.hasContext(namespace)) this.contextNs.remove(namespace);
else this.contextNs.push(namespace);
@@ -105,6 +111,7 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
this.contextNs.clear();
}
@action
async remove(item: Namespace) {
await super.remove(item);
this.contextNs.remove(item.getName());