mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
fix: app-crash when navigating to catalog from active cluster-view, refactoring catalog-entity-store
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
97ad405f9f
commit
3405c49613
@ -19,11 +19,10 @@
|
|||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { action, autorun, computed, makeObservable, observable } from "mobx";
|
import { action, computed, makeObservable } from "mobx";
|
||||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||||
import { CatalogEntity, CatalogEntityActionContext } from "../../api/catalog-entity";
|
import { CatalogEntity, CatalogEntityActionContext } from "../../api/catalog-entity";
|
||||||
import { ItemObject, ItemStore } from "../../item.store";
|
import { ItemObject, ItemStore } from "../../item.store";
|
||||||
import { autoBind, disposer } from "../../utils";
|
|
||||||
import { CatalogCategory } from "../../../common/catalog";
|
import { CatalogCategory } from "../../../common/catalog";
|
||||||
|
|
||||||
export class CatalogEntityItem implements ItemObject {
|
export class CatalogEntityItem implements ItemObject {
|
||||||
@ -87,43 +86,20 @@ export class CatalogEntityItem implements ItemObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CatalogEntityStore extends ItemStore<CatalogEntityItem> {
|
export class CatalogEntityStore extends ItemStore<CatalogEntityItem> {
|
||||||
dispose = disposer();
|
getEntities(category?: CatalogCategory): CatalogEntityItem[] {
|
||||||
@observable.ref activeCategory?: CatalogCategory;
|
if (!category) {
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
makeObservable(this);
|
|
||||||
autoBind(this);
|
|
||||||
this.bindAutoLoading();
|
|
||||||
}
|
|
||||||
|
|
||||||
@computed get entities() {
|
|
||||||
if (!this.activeCategory) {
|
|
||||||
return catalogEntityRegistry.items.map(entity => new CatalogEntityItem(entity));
|
return catalogEntityRegistry.items.map(entity => new CatalogEntityItem(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
return catalogEntityRegistry.getItemsForCategory(this.activeCategory).map(entity => new CatalogEntityItem(entity));
|
return catalogEntityRegistry.getItemsForCategory(category)
|
||||||
|
.map(entity => new CatalogEntityItem(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bindAutoLoading() {
|
async loadItems(entities: CatalogEntityItem[]) {
|
||||||
const disposer = autorun(() => {
|
|
||||||
this.loadItem(this.activeCategory); // preload active category
|
|
||||||
this.loadItems(this.entities); // preload all available entities
|
|
||||||
});
|
|
||||||
|
|
||||||
this.dispose.push(disposer);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadItem(category: CatalogCategory): Promise<CatalogEntityItem> {
|
|
||||||
return super.loadItem(() => category);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadItems(entities: CatalogEntityItem[] = []) {
|
|
||||||
return super.loadItems(() => entities);
|
return super.loadItems(() => entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadAll() {
|
async loadAll() {
|
||||||
return this.loadItems();
|
return this.loadItems(this.getEntities());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import "./catalog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { ItemListLayout } from "../item-object-list";
|
import { ItemListLayout } from "../item-object-list";
|
||||||
import { autorun, computed, makeObservable, observable } from "mobx";
|
import { computed, makeObservable, observable, reaction } from "mobx";
|
||||||
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
|
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
|
||||||
import { navigate } from "../../navigation";
|
import { navigate } from "../../navigation";
|
||||||
import { kebabCase } from "lodash";
|
import { kebabCase } from "lodash";
|
||||||
@ -64,6 +64,10 @@ export class Catalog extends React.Component {
|
|||||||
return catalogCategoryRegistry.items;
|
return catalogCategoryRegistry.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@computed get items(): CatalogEntityItem[] {
|
||||||
|
return this.catalogEntityStore.getEntities(this.activeCategory);
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props: {}) {
|
constructor(props: {}) {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
@ -71,10 +75,10 @@ export class Catalog extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
() => this.catalogEntityStore.dispose(), // stop all events, loaders, etc.
|
// autofill catalog entities into store
|
||||||
autorun(() => {
|
reaction(() => this.items, items => this.catalogEntityStore.loadItems(items), {
|
||||||
this.catalogEntityStore.activeCategory = this.activeCategory; // sync
|
fireImmediately: true,
|
||||||
}),
|
})
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import React from "react";
|
|||||||
import { computed, makeObservable, reaction } from "mobx";
|
import { computed, makeObservable, reaction } from "mobx";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { ClusterStatus } from "./cluster-status";
|
import { ClusterStatus } from "./cluster-status";
|
||||||
import { initView, lensViews, refreshViews } from "./lens-views";
|
import { hasLoadedView, initView, refreshViews } from "./lens-views";
|
||||||
import { Cluster } from "../../../main/cluster";
|
import { Cluster } from "../../../main/cluster";
|
||||||
import { ClusterStore } from "../../../common/cluster-store";
|
import { ClusterStore } from "../../../common/cluster-store";
|
||||||
import { requestMain } from "../../../common/ipc";
|
import { requestMain } from "../../../common/ipc";
|
||||||
@ -43,50 +43,49 @@ export class ClusterView extends React.Component {
|
|||||||
return getMatchedClusterId();
|
return getMatchedClusterId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get cluster(): Cluster {
|
@computed get cluster(): Cluster | undefined {
|
||||||
return ClusterStore.getInstance().getById(this.clusterId);
|
return ClusterStore.getInstance().getById(this.clusterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get isReady(): boolean {
|
@computed get isReady(): boolean {
|
||||||
const { cluster, clusterId } = this;
|
const { cluster, clusterId } = this;
|
||||||
|
|
||||||
return [
|
return cluster?.ready && cluster?.available && hasLoadedView(clusterId);
|
||||||
cluster?.available,
|
|
||||||
cluster?.ready,
|
|
||||||
lensViews.get(clusterId)?.isLoaded, // cluster's iframe is loaded & ready
|
|
||||||
].every(Boolean);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
this.bindEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
bindEvents() {
|
||||||
disposeOnUnmount(this, [
|
disposeOnUnmount(this, [
|
||||||
reaction(() => this.isReady, () => this.refreshViews(), {
|
reaction(() => this.clusterId, clusterId => {
|
||||||
fireImmediately: true
|
initView(clusterId); // init cluster-view (iframe), requires parent container #lens-views to be in DOM
|
||||||
|
requestMain(clusterActivateHandler, clusterId, false); // activate and fetch cluster's state from main
|
||||||
|
catalogEntityRegistry.activeEntity = catalogEntityRegistry.getById(clusterId);
|
||||||
|
}, {
|
||||||
|
fireImmediately: true,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// show cluster's iframe when ready/connected
|
||||||
|
reaction(() => this.isReady, () => refreshViews(this.clusterId), {
|
||||||
|
fireImmediately: true,
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
renderStatus() {
|
||||||
* Refresh cluster-views (iframes) visibility and catalog's active entity.
|
const { clusterId, cluster, isReady } = this;
|
||||||
*/
|
|
||||||
refreshViews(clusterId = this.clusterId) {
|
if (cluster && !isReady) {
|
||||||
try {
|
return <ClusterStatus clusterId={clusterId} className="box center"/>;
|
||||||
initView(clusterId);
|
|
||||||
requestMain(clusterActivateHandler, clusterId, false);
|
|
||||||
refreshViews(clusterId);
|
|
||||||
catalogEntityRegistry.activeEntity = catalogEntityRegistry.getById(clusterId);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`refreshing cluster-view: ${error}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { clusterId, isReady } = this;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="ClusterView flex align-center">
|
<div className="ClusterView flex align-center">
|
||||||
{!isReady && (
|
{this.renderStatus()}
|
||||||
<ClusterStatus key={clusterId} clusterId={clusterId} className="box center"/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user