mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
added workspace overview as details page (WIP)
Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com>
This commit is contained in:
parent
a0c19eb3c5
commit
f6058d73d1
@ -0,0 +1,2 @@
|
||||
.AddWorkspaceDialog {
|
||||
}
|
||||
84
src/renderer/components/+workspaces/add-workspace-dialog.tsx
Normal file
84
src/renderer/components/+workspaces/add-workspace-dialog.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import "./add-workspace-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
//import { namespaceStore } from "./namespace.store";
|
||||
import { Workspace, WorkspaceId } from "../../../common/workspace-store";
|
||||
import { Input } from "../input";
|
||||
import { systemName } from "../input/input_validators";
|
||||
import { Notifications } from "../notifications";
|
||||
|
||||
interface Props extends DialogProps {
|
||||
onSuccess?(ws: Workspace): void;
|
||||
onError?(error: any): void;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class AddWorkspaceDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable workspace = "";
|
||||
|
||||
static open() {
|
||||
AddWorkspaceDialog.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddWorkspaceDialog.isOpen = false;
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
this.workspace = "";
|
||||
};
|
||||
|
||||
close = () => {
|
||||
AddWorkspaceDialog.close();
|
||||
};
|
||||
|
||||
addWorkspace = async () => {
|
||||
const { workspace } = this;
|
||||
const { onSuccess, onError } = this.props;
|
||||
|
||||
try {
|
||||
// await namespaceStore.create({ name: workspace }).then(onSuccess);
|
||||
this.close();
|
||||
} catch (err) {
|
||||
Notifications.error(err);
|
||||
onError && onError(err);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { ...dialogProps } = this.props;
|
||||
const { workspace } = this;
|
||||
const header = <h5>Create Workspace</h5>;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddWorkspaceDialog"
|
||||
isOpen={AddWorkspaceDialog.isOpen}
|
||||
onOpen={this.reset}
|
||||
close={this.close}
|
||||
>
|
||||
<Wizard header={header} done={this.close}>
|
||||
<WizardStep
|
||||
contentClass="flex gaps column"
|
||||
nextLabel="Create"
|
||||
next={this.addWorkspace}
|
||||
>
|
||||
<Input
|
||||
required autoFocus
|
||||
iconLeft="layers"
|
||||
placeholder={`Workspace`}
|
||||
validators={systemName}
|
||||
value={workspace} onChange={v => this.workspace = v.toLowerCase()}
|
||||
/>
|
||||
</WizardStep>
|
||||
</Wizard>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
export * from "./workspaces.route";
|
||||
export * from "./workspace-list.route";
|
||||
export * from "./workspaces";
|
||||
export * from "./workspace-list";
|
||||
|
||||
52
src/renderer/components/+workspaces/workspace-details.scss
Normal file
52
src/renderer/components/+workspaces/workspace-details.scss
Normal file
@ -0,0 +1,52 @@
|
||||
.WorkspaceDetails {
|
||||
.intro-logo {
|
||||
margin-right: $margin * 2;
|
||||
background: $helmLogoBackground;
|
||||
border-radius: $radius;
|
||||
max-width: 150px;
|
||||
max-height: 100px;
|
||||
padding: $padding;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.intro-contents {
|
||||
.description {
|
||||
font-weight: bold;
|
||||
color: $textColorAccent;
|
||||
padding-bottom: $padding;
|
||||
|
||||
.Button {
|
||||
padding-left: $padding * 3;
|
||||
padding-right: $padding * 3;
|
||||
margin-left: $margin * 2;
|
||||
align-self: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.version {
|
||||
.Select {
|
||||
min-width: 80px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.Icon {
|
||||
margin-right: $margin;
|
||||
}
|
||||
}
|
||||
|
||||
.maintainers {
|
||||
a {
|
||||
display: inline-block;
|
||||
margin-right: $margin;
|
||||
}
|
||||
}
|
||||
|
||||
.DrawerItem {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-description {
|
||||
margin-top: $margin * 2;
|
||||
}
|
||||
}
|
||||
62
src/renderer/components/+workspaces/workspace-details.tsx
Normal file
62
src/renderer/components/+workspaces/workspace-details.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import "./workspace-details.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { WorkspaceItem } from "./workspace-list.store";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
import { Cluster } from "../../../main/cluster";
|
||||
import { observable, autorun } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Drawer, DrawerItem, DrawerTitle } from "../drawer";
|
||||
import { autobind, stopPropagation } from "../../utils";
|
||||
import { MarkdownViewer } from "../markdown-viewer";
|
||||
import { Spinner } from "../spinner";
|
||||
import { Button } from "../button";
|
||||
import { Select, SelectOption } from "../select";
|
||||
import { Badge } from "../badge";
|
||||
|
||||
interface Props {
|
||||
workspace: WorkspaceItem;
|
||||
hideDetails(): void;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class WorkspaceDetails extends Component<Props> {
|
||||
|
||||
renderClusters() {
|
||||
const { workspace } = this.props;
|
||||
const clusters = clusterStore.getByWorkspaceId(workspace.getId());
|
||||
return <div>
|
||||
{clusters.map(cluster => <div>{cluster.contextName}</div>)}
|
||||
</div>
|
||||
}
|
||||
|
||||
render() {
|
||||
const { workspace, hideDetails } = this.props;
|
||||
const title = workspace ? <>Workspace: {workspace.getName()}</> : "";
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
className="WorkspaceDetails"
|
||||
usePortal={true}
|
||||
open={!!workspace}
|
||||
title={title}
|
||||
onClose={hideDetails}
|
||||
>
|
||||
<DrawerItem name={"Description"}>
|
||||
{workspace.getDescription()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={"Id"}>
|
||||
{workspace.getId()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={"Owner Ref"}>
|
||||
{workspace.getOwnerRef()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={"Enabled"} renderBoolean={true}>
|
||||
{workspace.getEnabled()}
|
||||
</DrawerItem>
|
||||
<DrawerTitle title={"Clusters"}/>
|
||||
{this.renderClusters()}
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
}
|
||||
12
src/renderer/components/+workspaces/workspace-list.route.ts
Normal file
12
src/renderer/components/+workspaces/workspace-list.route.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../../../common/utils/buildUrl";
|
||||
|
||||
export const workspaceListRoute: RouteProps = {
|
||||
path: `/workspaces/:workspaceName?`
|
||||
};
|
||||
|
||||
export interface IWorkspaceListRouteParams {
|
||||
workspaceName?: string;
|
||||
}
|
||||
|
||||
export const workspaceListURL = buildURL<IWorkspaceListRouteParams>(workspaceListRoute.path);
|
||||
@ -8,9 +8,21 @@ export class WorkspaceItem {
|
||||
return this.workspace.name;
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
return this.workspace.description;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.workspace.id;
|
||||
}
|
||||
|
||||
getOwnerRef() {
|
||||
return this.workspace.ownerRef;
|
||||
}
|
||||
|
||||
getEnabled() {
|
||||
return this.workspace.enabled ? "True" : "False";
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspaceListStore extends ItemStore<WorkspaceItem> {
|
||||
|
||||
@ -1,22 +1,55 @@
|
||||
import "./workspaces.scss";
|
||||
|
||||
import React from "react";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { observer } from "mobx-react";
|
||||
import { navigation } from "../../navigation";
|
||||
import { workspaceListURL, IWorkspaceListRouteParams } from "./workspace-list.route";
|
||||
import { TabLayout } from "../layout/tab-layout";
|
||||
import { Badge } from "../badge";
|
||||
import { ItemListLayout, ItemListLayoutProps } from "../item-object-list/item-list-layout";
|
||||
import { AddWorkspaceDialog } from "./add-workspace-dialog";
|
||||
import { Workspace, WorkspaceId } from "../../../common/workspace-store";
|
||||
import { WorkspaceItem, workspaceListStore } from "./workspace-list.store";
|
||||
import { WorkspaceDetails } from "./workspace-details";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
id = "id",
|
||||
description = "description",
|
||||
}
|
||||
|
||||
export class WorkspaceList extends React.Component {
|
||||
interface Props extends RouteComponentProps<IWorkspaceListRouteParams> {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class WorkspaceList extends React.Component<Props> {
|
||||
componentDidMount() {
|
||||
workspaceListStore.loadAll();
|
||||
}
|
||||
|
||||
get selectedWorkspace() {
|
||||
const { match: { params: { workspaceName } } } = this.props;
|
||||
|
||||
return workspaceListStore.getByName(workspaceName);
|
||||
}
|
||||
|
||||
showDetails = (workspace: WorkspaceItem) => {
|
||||
if (!workspace) {
|
||||
navigation.merge(workspaceListURL());
|
||||
}
|
||||
else {
|
||||
navigation.merge(workspaceListURL({
|
||||
params: {
|
||||
workspaceName: workspace.getName(),
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
hideDetails = () => {
|
||||
this.showDetails(null);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TabLayout>
|
||||
@ -25,19 +58,32 @@ export class WorkspaceList extends React.Component {
|
||||
className="Workspaces" store={workspaceListStore}
|
||||
sortingCallbacks={{
|
||||
[sortBy.name]: (ws: WorkspaceItem) => ws.getName(),
|
||||
[sortBy.id]: (ws: WorkspaceItem) => ws.getId(),
|
||||
[sortBy.description]: (ws: WorkspaceItem) => ws.getDescription(),
|
||||
}}
|
||||
searchFilters={[]}
|
||||
renderHeaderTitle="Workspaces"
|
||||
renderTableHeader={[
|
||||
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||
{ title: "Id", className: "id", sortBy: sortBy.id },
|
||||
{ title: "Description", className: "description", sortBy: sortBy.description },
|
||||
]}
|
||||
renderTableContents={(item: WorkspaceItem) => [
|
||||
item.getName(),
|
||||
item.getId(),
|
||||
item.getDescription(),
|
||||
]}
|
||||
addRemoveButtons={{
|
||||
addTooltip: "Add Workspace",
|
||||
onAdd: () => AddWorkspaceDialog.open(),
|
||||
}}
|
||||
detailsItem={this.selectedWorkspace}
|
||||
onDetails={this.showDetails}
|
||||
/>
|
||||
{this.selectedWorkspace && (
|
||||
<WorkspaceDetails
|
||||
workspace={this.selectedWorkspace}
|
||||
hideDetails={this.hideDetails}
|
||||
/>
|
||||
)}
|
||||
<AddWorkspaceDialog/>
|
||||
</TabLayout>
|
||||
);
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import { ClustersMenu } from "./clusters-menu";
|
||||
import { BottomBar } from "./bottom-bar";
|
||||
import { LandingPage, landingRoute, landingURL } from "../+landing-page";
|
||||
import { Preferences, preferencesRoute } from "../+preferences";
|
||||
import { WorkspaceList, workspacesRoute } from "../+workspaces";
|
||||
import { WorkspaceList, workspaceListRoute } from "../+workspaces";
|
||||
import { AddCluster, addClusterRoute } from "../+add-cluster";
|
||||
import { ClusterView } from "./cluster-view";
|
||||
import { ClusterSettings, clusterSettingsRoute } from "../+cluster-settings";
|
||||
@ -67,7 +67,7 @@ export class ClusterManager extends React.Component {
|
||||
<Route component={LandingPage} {...landingRoute} />
|
||||
<Route component={Preferences} {...preferencesRoute} />
|
||||
<Route component={Extensions} {...extensionsRoute} />
|
||||
<Route component={WorkspaceList} {...workspacesRoute} />
|
||||
<Route component={WorkspaceList} {...workspaceListRoute} />
|
||||
<Route component={AddCluster} {...addClusterRoute} />
|
||||
<Route component={ClusterView} {...clusterViewRoute} />
|
||||
<Route component={ClusterSettings} {...clusterSettingsRoute} />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user