1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

store subscribing refactoring -- part 4

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2021-01-25 13:30:31 +02:00
parent b690a27ebe
commit 632e77b263
5 changed files with 26 additions and 20 deletions

View File

@ -120,6 +120,7 @@ export class KubeWatchApi {
async function subscribe() { async function subscribe() {
if (isDisposed) return; if (isDisposed) return;
const unsubscribeList = await Promise.all(stores.map(store => store.subscribe())); const unsubscribeList = await Promise.all(stores.map(store => store.subscribe()));
disposers.push(...unsubscribeList); disposers.push(...unsubscribeList);
if (isDisposed) unsubscribe(); if (isDisposed) unsubscribe();
} }
@ -176,6 +177,7 @@ export class KubeWatchApi {
// request above is stale since new request-id has been issued // request above is stale since new request-id has been issued
if (this.requestId !== requestId) { if (this.requestId !== requestId) {
abortController.abort(); abortController.abort();
return; return;
} }
@ -206,7 +208,7 @@ export class KubeWatchApi {
// process received stream events, returns unprocessed buffer chunk if any // process received stream events, returns unprocessed buffer chunk if any
protected processBuffer(events: string[]): string { protected processBuffer(events: string[]): string {
for (let json of events) { for (const json of events) {
try { try {
const kubeEvent: IKubeWatchEvent = JSON.parse(json); const kubeEvent: IKubeWatchEvent = JSON.parse(json);
const message = this.getMessage(kubeEvent); const message = this.getMessage(kubeEvent);

View File

@ -31,6 +31,7 @@ export class ClusterOverview extends React.Component {
kubeWatchApi.subscribeStores([nodesStore, podsStore, eventStore], { kubeWatchApi.subscribeStores([nodesStore, podsStore, eventStore], {
preload: true, preload: true,
}), }),
reaction( reaction(
() => clusterOverviewStore.metricNodeRole, // Toggle Master/Worker node switcher () => clusterOverviewStore.metricNodeRole, // Toggle Master/Worker node switcher
() => this.metricPoller.restart(true) () => this.metricPoller.restart(true)

View File

@ -1,7 +1,6 @@
import "./overview.scss"; import "./overview.scss";
import React from "react"; import React from "react";
import { observable } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { OverviewStatuses } from "./overview-statuses"; import { OverviewStatuses } from "./overview-statuses";
import { RouteComponentProps } from "react-router"; import { RouteComponentProps } from "react-router";
@ -23,23 +22,13 @@ interface Props extends RouteComponentProps<IWorkloadsOverviewRouteParams> {
@observer @observer
export class WorkloadsOverview extends React.Component<Props> { export class WorkloadsOverview extends React.Component<Props> {
@observable isLoading = false;
@observable isUnmounting = false;
componentDidMount() { componentDidMount() {
disposeOnUnmount(this, [ disposeOnUnmount(this, [
kubeWatchApi.subscribeStores([ kubeWatchApi.subscribeStores([
podsStore, deploymentStore, daemonSetStore, statefulSetStore, replicaSetStore, podsStore, deploymentStore, daemonSetStore, statefulSetStore, replicaSetStore,
jobStore, cronJobStore, eventStore, jobStore, cronJobStore, eventStore,
], { ]),
preload: true,
}),
]); ]);
// fixme: reload stores
// namespaceStore.onContextChange(loadStores, {
// fireImmediately: true,
// });
} }
render() { render() {

View File

@ -2,7 +2,7 @@ import "./item-list-layout.scss";
import groupBy from "lodash/groupBy"; import groupBy from "lodash/groupBy";
import React, { ReactNode } from "react"; import React, { ReactNode } from "react";
import { computed, IReactionDisposer, observable, reaction, toJS } from "mobx"; import { computed, observable, reaction, toJS } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { ConfirmDialog, ConfirmDialogParams } from "../confirm-dialog"; import { ConfirmDialog, ConfirmDialogParams } from "../confirm-dialog";
import { Table, TableCell, TableCellProps, TableHead, TableProps, TableRow, TableRowProps, TableSortCallback } from "../table"; import { Table, TableCell, TableCellProps, TableHead, TableProps, TableRow, TableRowProps, TableSortCallback } from "../table";
@ -21,6 +21,7 @@ import { MenuActions } from "../menu/menu-actions";
import { MenuItem } from "../menu"; import { MenuItem } from "../menu";
import { Checkbox } from "../checkbox"; import { Checkbox } from "../checkbox";
import { userStore } from "../../../common/user-store"; import { userStore } from "../../../common/user-store";
import { namespaceStore } from "../+namespaces/namespace.store";
// todo: refactor, split to small re-usable components // todo: refactor, split to small re-usable components
@ -39,6 +40,7 @@ export interface ItemListLayoutProps<T extends ItemObject = ItemObject> {
className: IClassName; className: IClassName;
store: ItemStore<T>; store: ItemStore<T>;
dependentStores?: ItemStore[]; dependentStores?: ItemStore[];
preloadStores?: boolean;
isClusterScoped?: boolean; isClusterScoped?: boolean;
hideFilters?: boolean; hideFilters?: boolean;
searchFilters?: SearchFilter<T>[]; searchFilters?: SearchFilter<T>[];
@ -81,6 +83,7 @@ const defaultProps: Partial<ItemListLayoutProps> = {
isSelectable: true, isSelectable: true,
isConfigurable: false, isConfigurable: false,
copyClassNameFromHeadCells: true, copyClassNameFromHeadCells: true,
preloadStores: true,
dependentStores: [], dependentStores: [],
filterItems: [], filterItems: [],
hasDetailsView: true, hasDetailsView: true,
@ -114,20 +117,30 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
} }
async componentDidMount() { async componentDidMount() {
const { isClusterScoped, isConfigurable, tableId } = this.props; const { isClusterScoped, isConfigurable, tableId, preloadStores } = this.props;
if (isConfigurable && !tableId) { if (isConfigurable && !tableId) {
throw new Error("[ItemListLayout]: configurable list require props.tableId to be specified"); throw new Error("[ItemListLayout]: configurable list require props.tableId to be specified");
} }
// fixme: reload stores if (preloadStores) {
if (!isClusterScoped) { this.loadStores();
// disposeOnUnmount(this, [
// namespaceStore.onContextChange(() => this.loadStores()) if (!isClusterScoped) {
// ]); disposeOnUnmount(this, [
namespaceStore.onContextChange(() => this.loadStores())
]);
}
} }
} }
private loadStores() {
const { store, dependentStores } = this.props;
const stores = Array.from(new Set([store, ...dependentStores]));
stores.forEach(store => store.loadAll());
}
private filterCallbacks: { [type: string]: ItemsFilter } = { private filterCallbacks: { [type: string]: ItemsFilter } = {
[FilterType.SEARCH]: items => { [FilterType.SEARCH]: items => {
const { searchFilters, isSearchable } = this.props; const { searchFilters, isSearchable } = this.props;

View File

@ -46,6 +46,7 @@ export class KubeObjectListLayout extends React.Component<KubeObjectListLayoutPr
<ItemListLayout <ItemListLayout
{...layoutProps} {...layoutProps}
className={cssNames("KubeObjectListLayout", className)} className={cssNames("KubeObjectListLayout", className)}
preloadStores={false} // loading handled in kubeWatchApi.subscribeStores()
detailsItem={this.selectedItem} detailsItem={this.selectedItem}
onDetails={this.onDetails} onDetails={this.onDetails}
renderItemMenu={(item) => { renderItemMenu={(item) => {