Refactor cluster settings to catalog entity settings (#2525)

* fix cluster settings page layout

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* cleanup

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* refactor cluster settings to pluggable entity settings

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix gh actions network timeout on yarn install

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* review changes

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen authored and GitHub committed 2021-04-20 07:05:44 +03:00
1 parent adec401acd
commit 8dde4a1ecb
51 files changed
+437 -336

No files matched your search

@@ -0,0 +1,12 @@
import type { RouteProps } from "react-router";
import { buildURL } from "../../../common/utils/buildUrl";
export interface EntitySettingsRouteParams {
entityId: string;
}
export const entitySettingsRoute: RouteProps = {
path: `/entity/:entityId/settings`,
};
export const entitySettingsURL = buildURL<EntitySettingsRouteParams>(entitySettingsRoute.path);
@@ -0,0 +1,23 @@
.EntitySettings {
$spacing: $padding * 3;
// TODO: move sub-component styles to separate files
.admin-note {
font-size: small;
opacity: 0.5;
margin-left: $margin;
}
.button-area {
margin-top: $margin * 2;
}
.file-loader {
margin-top: $margin * 2;
}
.Input, .Select {
margin-top: $padding;
}
}
@@ -0,0 +1,99 @@
import "./entity-settings.scss";
import React from "react";
import { observable } from "mobx";
import { RouteComponentProps } from "react-router";
import { observer } from "mobx-react";
import { PageLayout } from "../layout/page-layout";
import { navigation } from "../../navigation";
import { Tabs, Tab } from "../tabs";
import { CatalogEntity } from "../../api/catalog-entity";
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
import { entitySettingRegistry } from "../../../extensions/registries";
import { EntitySettingsRouteParams } from "./entity-settings.route";
interface Props extends RouteComponentProps<EntitySettingsRouteParams> {
}
@observer
export class EntitySettings extends React.Component<Props> {
@observable activeTab: string;
get entityId() {
return this.props.match.params.entityId;
}
get entity(): CatalogEntity {
return catalogEntityRegistry.getById(this.entityId);
}
get menuItems() {
if (!this.entity) return [];
return entitySettingRegistry.getItemsForKind(this.entity.kind, this.entity.apiVersion, this.entity.metadata.source);
}
async componentDidMount() {
const { hash } = navigation.location;
this.ensureActiveTab();
document.getElementById(hash.slice(1))?.scrollIntoView();
}
onTabChange = (tabId: string) => {
this.activeTab = tabId;
};
renderNavigation() {
return (
<>
<h2>{this.entity.metadata.name}</h2>
<Tabs className="flex column" scrollable={false} onChange={this.onTabChange} value={this.activeTab}>
<div className="header">Settings</div>
{ this.menuItems.map((setting) => (
<Tab
key={setting.id}
value={setting.id}
label={setting.title}
data-testid={`${setting.id}-tab`}
/>
))}
</Tabs>
</>
);
}
ensureActiveTab() {
if (!this.activeTab) {
this.activeTab = this.menuItems[0]?.id;
}
}
render() {
if (!this.entity) {
console.error("entity not found", this.entityId);
return null;
}
this.ensureActiveTab();
const activeSetting = this.menuItems.find((setting) => setting.id === this.activeTab);
return (
<PageLayout
className="CatalogEntitySettings"
navigation={this.renderNavigation()}
showOnTop={true}
contentGaps={false}
>
<section>
<h2 data-testid={`${activeSetting.id}-header`}>{activeSetting.title}</h2>
<section>
<activeSetting.components.View entity={this.entity} />
</section>
</section>
</PageLayout>
);
}
}
@@ -0,0 +1,4 @@
import "../cluster-settings";
export * from "./entity-settings.route";
export * from "./entity-settings";