mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add persistent volumes info to storage class submenu (#2160)
Signed-off-by: vshakirova <vshakirova@mirantis.com>
This commit is contained in:
parent
6876d774a5
commit
0d3505cfac
@ -70,6 +70,10 @@ export class PersistentVolume extends KubeObject {
|
|||||||
getClaimRefName(): string {
|
getClaimRefName(): string {
|
||||||
return this.spec.claimRef?.name ?? "";
|
return this.spec.claimRef?.name ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStorageClassName() {
|
||||||
|
return this.spec.storageClassName || "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const persistentVolumeApi = new KubeApi({
|
export const persistentVolumeApi = new KubeApi({
|
||||||
|
|||||||
@ -10,14 +10,22 @@ import { KubeObjectDetailsProps } from "../kube-object";
|
|||||||
import { StorageClass } from "../../api/endpoints";
|
import { StorageClass } from "../../api/endpoints";
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
import { storageClassStore } from "./storage-class.store";
|
||||||
|
import { VolumeDetailsList } from "../+storage-volumes/volume-details-list";
|
||||||
|
import { volumesStore } from "../+storage-volumes/volumes.store";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<StorageClass> {
|
interface Props extends KubeObjectDetailsProps<StorageClass> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class StorageClassDetails extends React.Component<Props> {
|
export class StorageClassDetails extends React.Component<Props> {
|
||||||
|
async componentDidMount() {
|
||||||
|
volumesStore.reloadAll();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { object: storageClass } = this.props;
|
const { object: storageClass } = this.props;
|
||||||
|
const persistentVolumes = storageClassStore.getPersistentVolumes(storageClass);
|
||||||
|
|
||||||
if (!storageClass) return null;
|
if (!storageClass) return null;
|
||||||
const { provisioner, parameters, mountOptions } = storageClass;
|
const { provisioner, parameters, mountOptions } = storageClass;
|
||||||
@ -55,6 +63,7 @@ export class StorageClassDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<VolumeDetailsList persistentVolumes={persistentVolumes}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,15 @@ import { KubeObjectStore } from "../../kube-object.store";
|
|||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { StorageClass, storageClassApi } from "../../api/endpoints/storage-class.api";
|
import { StorageClass, storageClassApi } from "../../api/endpoints/storage-class.api";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { volumesStore } from "../+storage-volumes/volumes.store";
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class StorageClassStore extends KubeObjectStore<StorageClass> {
|
export class StorageClassStore extends KubeObjectStore<StorageClass> {
|
||||||
api = storageClassApi;
|
api = storageClassApi;
|
||||||
|
|
||||||
|
getPersistentVolumes(storageClass: StorageClass) {
|
||||||
|
return volumesStore.getByStorageClass(storageClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const storageClassStore = new StorageClassStore();
|
export const storageClassStore = new StorageClassStore();
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
@import "../+storage/storage-mixins";
|
||||||
|
|
||||||
|
.VolumeDetailsList {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.Table {
|
||||||
|
margin: 0 (-$margin * 3);
|
||||||
|
|
||||||
|
&.virtual {
|
||||||
|
height: 500px; // applicable for 100+ items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.TableCell {
|
||||||
|
&:first-child {
|
||||||
|
margin-left: $margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: $margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.name {
|
||||||
|
flex-grow: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.status {
|
||||||
|
@include pv-status-colors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
import "./volume-details-list.scss";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { PersistentVolume } from "../../api/endpoints/persistent-volume.api";
|
||||||
|
import { autobind } from "../../../common/utils/autobind";
|
||||||
|
import { TableRow } from "../table/table-row";
|
||||||
|
import { cssNames, prevDefault } from "../../utils";
|
||||||
|
import { showDetails } from "../kube-object/kube-object-details";
|
||||||
|
import { TableCell } from "../table/table-cell";
|
||||||
|
import { Spinner } from "../spinner/spinner";
|
||||||
|
import { DrawerTitle } from "../drawer/drawer-title";
|
||||||
|
import { Table } from "../table/table";
|
||||||
|
import { TableHead } from "../table/table-head";
|
||||||
|
import { volumesStore } from "./volumes.store";
|
||||||
|
import kebabCase from "lodash/kebabCase";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
persistentVolumes: PersistentVolume[];
|
||||||
|
}
|
||||||
|
|
||||||
|
enum sortBy {
|
||||||
|
name = "name",
|
||||||
|
status = "status",
|
||||||
|
capacity = "capacity",
|
||||||
|
}
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class VolumeDetailsList extends React.Component<Props> {
|
||||||
|
private sortingCallbacks = {
|
||||||
|
[sortBy.name]: (volume: PersistentVolume) => volume.getName(),
|
||||||
|
[sortBy.capacity]: (volume: PersistentVolume) => volume.getCapacity(),
|
||||||
|
[sortBy.status]: (volume: PersistentVolume) => volume.getStatus(),
|
||||||
|
};
|
||||||
|
|
||||||
|
@autobind()
|
||||||
|
getTableRow(uid: string) {
|
||||||
|
const { persistentVolumes } = this.props;
|
||||||
|
const volume = persistentVolumes.find(volume => volume.getId() === uid);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow
|
||||||
|
key={volume.getId()}
|
||||||
|
sortItem={volume}
|
||||||
|
nowrap
|
||||||
|
onClick={prevDefault(() => showDetails(volume.selfLink, false))}
|
||||||
|
>
|
||||||
|
<TableCell className="name">{volume.getName()}</TableCell>
|
||||||
|
<TableCell className="capacity">{volume.getCapacity()}</TableCell>
|
||||||
|
<TableCell className={cssNames("status", kebabCase(volume.getStatus()))}>{volume.getStatus()}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { persistentVolumes } = this.props;
|
||||||
|
const virtual = persistentVolumes.length > 100;
|
||||||
|
|
||||||
|
if (!persistentVolumes.length) {
|
||||||
|
return !volumesStore.isLoaded && <Spinner center/>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="VolumeDetailsList flex column">
|
||||||
|
<DrawerTitle title="Persistent Volumes"/>
|
||||||
|
<Table
|
||||||
|
items={persistentVolumes}
|
||||||
|
selectable
|
||||||
|
virtual={virtual}
|
||||||
|
sortable={this.sortingCallbacks}
|
||||||
|
sortByDefault={{ sortBy: sortBy.name, orderBy: "desc" }}
|
||||||
|
sortSyncWithUrl={false}
|
||||||
|
getTableRow={this.getTableRow}
|
||||||
|
className="box grow"
|
||||||
|
>
|
||||||
|
<TableHead>
|
||||||
|
<TableCell className="name" sortBy={sortBy.name}>Name</TableCell>
|
||||||
|
<TableCell className="capacity" sortBy={sortBy.capacity}>Capacity</TableCell>
|
||||||
|
<TableCell className="status" sortBy={sortBy.status}>Status</TableCell>
|
||||||
|
</TableHead>
|
||||||
|
{
|
||||||
|
!virtual && persistentVolumes.map(volume => this.getTableRow(volume.getId()))
|
||||||
|
}
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,7 +26,7 @@
|
|||||||
flex-grow: 3;
|
flex-grow: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status {
|
&.status {
|
||||||
@include pv-status-colors;
|
@include pv-status-colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,10 +2,17 @@ import { KubeObjectStore } from "../../kube-object.store";
|
|||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { PersistentVolume, persistentVolumeApi } from "../../api/endpoints/persistent-volume.api";
|
import { PersistentVolume, persistentVolumeApi } from "../../api/endpoints/persistent-volume.api";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
|
import { StorageClass } from "../../api/endpoints/storage-class.api";
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
export class PersistentVolumesStore extends KubeObjectStore<PersistentVolume> {
|
export class PersistentVolumesStore extends KubeObjectStore<PersistentVolume> {
|
||||||
api = persistentVolumeApi;
|
api = persistentVolumeApi;
|
||||||
|
|
||||||
|
getByStorageClass(storageClass: StorageClass): PersistentVolume[] {
|
||||||
|
return this.items.filter(volume =>
|
||||||
|
volume.getStorageClassName() === storageClass.getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const volumesStore = new PersistentVolumesStore();
|
export const volumesStore = new PersistentVolumesStore();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user