mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
cleanup Lens repo with tighter linting
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
This commit is contained in:
1 parent
e468105143
commit
b1ff34879a
470 files changed
+8447
-7443
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import "./add-namespace-dialog.scss"
|
||||
import "./add-namespace-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
@@ -23,19 +23,19 @@ export class AddNamespaceDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable namespace = "";
|
||||
|
||||
static open() {
|
||||
static open(): void {
|
||||
AddNamespaceDialog.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
static close(): void {
|
||||
AddNamespaceDialog.isOpen = false;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
close = (): void => {
|
||||
AddNamespaceDialog.close();
|
||||
}
|
||||
|
||||
addNamespace = async () => {
|
||||
addNamespace = async (): Promise<void> => {
|
||||
const { namespace } = this;
|
||||
const { onSuccess, onError } = this.props;
|
||||
try {
|
||||
@@ -47,7 +47,7 @@ export class AddNamespaceDialog extends React.Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
const { ...dialogProps } = this.props;
|
||||
const { namespace } = this;
|
||||
const header = <h5><Trans>Create Namespace</Trans></h5>;
|
||||
@@ -69,11 +69,14 @@ export class AddNamespaceDialog extends React.Component<Props> {
|
||||
iconLeft="layers"
|
||||
placeholder={_i18n._(t`Namespace`)}
|
||||
validators={systemName}
|
||||
value={namespace} onChange={v => this.namespace = v.toLowerCase()}
|
||||
value={namespace}
|
||||
onChange={(v): void => {
|
||||
this.namespace = v.toLowerCase();
|
||||
}}
|
||||
/>
|
||||
</WizardStep>
|
||||
</Wizard>
|
||||
</Dialog>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from "./namespaces.route"
|
||||
export * from "./namespaces"
|
||||
export * from "./namespace-details"
|
||||
export * from "./add-namespace-dialog"
|
||||
export * from "./namespaces.route";
|
||||
export * from "./namespaces";
|
||||
export * from "./namespace-details";
|
||||
export * from "./add-namespace-dialog";
|
||||
@@ -20,18 +20,20 @@ interface Props extends KubeObjectDetailsProps<Namespace> {
|
||||
|
||||
@observer
|
||||
export class NamespaceDetails extends React.Component<Props> {
|
||||
@computed get quotas() {
|
||||
@computed get quotas(): ResourceQuota[] {
|
||||
const namespace = this.props.object.getName();
|
||||
return resourceQuotaStore.getAllByNs(namespace);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
resourceQuotaStore.loadAll();
|
||||
async componentDidMount(): Promise<void> {
|
||||
await resourceQuotaStore.loadAll();
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
const { object: namespace } = this.props;
|
||||
if (!namespace) return;
|
||||
if (!namespace) {
|
||||
return;
|
||||
}
|
||||
const status = namespace.getStatus();
|
||||
return (
|
||||
<div className="NamespaceDetails">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./namespace-select.scss"
|
||||
import "./namespace-select.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed } from "mobx";
|
||||
@@ -11,7 +11,6 @@ import { namespaceStore } from "./namespace.store";
|
||||
import { _i18n } from "../../i18n";
|
||||
import { FilterIcon } from "../item-object-list/filter-icon";
|
||||
import { FilterType } from "../item-object-list/page-filters.store";
|
||||
import { isAllowedResource } from "../../api/rbac"
|
||||
|
||||
interface Props extends SelectProps {
|
||||
showIcons?: boolean;
|
||||
@@ -33,14 +32,14 @@ export class NamespaceSelect extends React.Component<Props> {
|
||||
static defaultProps = defaultProps as object;
|
||||
private unsubscribe = noop;
|
||||
|
||||
async componentDidMount() {
|
||||
async componentDidMount(): Promise<void> {
|
||||
if (!namespaceStore.isLoaded) {
|
||||
await namespaceStore.loadAll();
|
||||
}
|
||||
this.unsubscribe = namespaceStore.subscribe();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
componentWillUnmount(): void {
|
||||
this.unsubscribe();
|
||||
}
|
||||
|
||||
@@ -54,19 +53,28 @@ export class NamespaceSelect extends React.Component<Props> {
|
||||
return options;
|
||||
}
|
||||
|
||||
formatOptionLabel = (option: SelectOption) => {
|
||||
formatOptionLabel = (option: SelectOption): JSX.Element => {
|
||||
const { showIcons } = this.props;
|
||||
const { value, label } = option;
|
||||
return label || (
|
||||
<>
|
||||
{showIcons && <Icon small material="layers"/>}
|
||||
{value}
|
||||
</>
|
||||
);
|
||||
if (label) {
|
||||
return (
|
||||
<>
|
||||
{showIcons && <Icon small material="layers" />}
|
||||
{value}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { className, showIcons, showClusterOption, clusterOptionLabel, customizeOptions, ...selectProps } = this.props;
|
||||
render(): JSX.Element {
|
||||
const {
|
||||
className,
|
||||
showIcons: _showIcons,
|
||||
showClusterOption: _showClusterOption,
|
||||
clusterOptionLabel: _clusterOptionLabel,
|
||||
customizeOptions: _customizeOptions,
|
||||
...selectProps
|
||||
} = this.props;
|
||||
return (
|
||||
<Select
|
||||
className={cssNames("NamespaceSelect", className)}
|
||||
@@ -81,19 +89,23 @@ export class NamespaceSelect extends React.Component<Props> {
|
||||
|
||||
@observer
|
||||
export class NamespaceSelectFilter extends React.Component {
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
const { contextNs, hasContext, toggleContext } = namespaceStore;
|
||||
let placeholder = <Trans>All namespaces</Trans>;
|
||||
if (contextNs.length == 1) placeholder = <Trans>Namespace: {contextNs[0]}</Trans>
|
||||
if (contextNs.length >= 2) placeholder = <Trans>Namespaces: {contextNs.join(", ")}</Trans>
|
||||
if (contextNs.length == 1) {
|
||||
placeholder = <Trans>Namespace: {contextNs[0]}</Trans>;
|
||||
}
|
||||
if (contextNs.length >= 2) {
|
||||
placeholder = <Trans>Namespaces: {contextNs.join(", ")}</Trans>;
|
||||
}
|
||||
return (
|
||||
<NamespaceSelect
|
||||
placeholder={placeholder}
|
||||
closeMenuOnSelect={false}
|
||||
isOptionSelected={() => false}
|
||||
isOptionSelected={(): boolean => false}
|
||||
controlShouldRenderValue={false}
|
||||
onChange={({ value: namespace }: SelectOption) => toggleContext(namespace)}
|
||||
formatOptionLabel={({ value: namespace }: SelectOption) => {
|
||||
onChange={({ value: namespace }: SelectOption): void => toggleContext(namespace)}
|
||||
formatOptionLabel={({ value: namespace }: SelectOption): JSX.Element => {
|
||||
const isSelected = hasContext(namespace);
|
||||
return (
|
||||
<div className="flex gaps align-center">
|
||||
@@ -101,9 +113,9 @@ export class NamespaceSelectFilter extends React.Component {
|
||||
<span>{namespace}</span>
|
||||
{isSelected && <Icon small material="check" className="box right"/>}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { action, observable, reaction } from "mobx";
|
||||
import { autobind, createStorage } from "../../utils";
|
||||
import { autobind, StorageHelper } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { Namespace, namespacesApi } from "../../api/endpoints";
|
||||
import { IQueryParams, navigation, setQueryParams } from "../../navigation";
|
||||
import { QueryParams, navigation, setQueryParams } from "../../navigation";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { isAllowedResource } from "../..//api/rbac";
|
||||
|
||||
@@ -11,9 +11,9 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
api = namespacesApi;
|
||||
contextNs = observable.array<string>();
|
||||
|
||||
protected storage = createStorage<string[]>("context_ns", this.contextNs);
|
||||
protected storage = new StorageHelper<string[]>("context_ns", this.contextNs);
|
||||
|
||||
get initNamespaces() {
|
||||
get initNamespaces(): string[] {
|
||||
const fromUrl = navigation.searchParams.getAsArray("namespaces");
|
||||
return fromUrl.length ? fromUrl : this.storage.get();
|
||||
}
|
||||
@@ -33,36 +33,34 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
});
|
||||
}
|
||||
|
||||
getContextParams(): Partial<IQueryParams> {
|
||||
getContextParams(): Partial<QueryParams> {
|
||||
return {
|
||||
namespaces: this.contextNs
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected updateUrl(namespaces: string[]) {
|
||||
setQueryParams({ namespaces }, { replace: true })
|
||||
protected updateUrl(namespaces: string[]): void {
|
||||
setQueryParams({ namespaces }, { replace: true });
|
||||
}
|
||||
|
||||
protected loadItems(namespaces?: string[]) {
|
||||
protected loadItems(namespaces?: string[]): Promise<Namespace[]> {
|
||||
if (!isAllowedResource("namespaces")) {
|
||||
if (namespaces) {
|
||||
return Promise.all(namespaces.map(name => this.getDummyNamespace(name)))
|
||||
}
|
||||
else {
|
||||
return Promise.all(namespaces.map(name => this.getDummyNamespace(name)));
|
||||
} else {
|
||||
return new Promise<Namespace[]>(() => {
|
||||
return []
|
||||
})
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
if (namespaces) {
|
||||
return Promise.all(namespaces.map(name => this.api.get({ name })))
|
||||
}
|
||||
else {
|
||||
return Promise.all(namespaces.map(name => this.api.get({ name })));
|
||||
} else {
|
||||
return super.loadItems();
|
||||
}
|
||||
}
|
||||
|
||||
protected getDummyNamespace(name: string) {
|
||||
protected getDummyNamespace(name: string): Namespace {
|
||||
return new Namespace({
|
||||
kind: "Namespace",
|
||||
apiVersion: "v1",
|
||||
@@ -72,25 +70,28 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
resourceVersion: "",
|
||||
selfLink: `/api/v1/namespaces/${name}`
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
setContext(namespaces: string[]) {
|
||||
setContext(namespaces: string[]): void {
|
||||
this.contextNs.replace(namespaces);
|
||||
}
|
||||
|
||||
hasContext(namespace: string | string[]) {
|
||||
hasContext(namespace: string | string[]): boolean {
|
||||
const context = Array.isArray(namespace) ? namespace : [namespace];
|
||||
return context.every(namespace => this.contextNs.includes(namespace));
|
||||
}
|
||||
|
||||
toggleContext(namespace: string) {
|
||||
if (this.hasContext(namespace)) this.contextNs.remove(namespace);
|
||||
else this.contextNs.push(namespace);
|
||||
toggleContext(namespace: string): void {
|
||||
if (this.hasContext(namespace)) {
|
||||
this.contextNs.remove(namespace);
|
||||
} else {
|
||||
this.contextNs.push(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
reset() {
|
||||
reset(): void {
|
||||
super.reset();
|
||||
this.contextNs.clear();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { RouteProps } from "react-router"
|
||||
import { RouteProps } from "react-router";
|
||||
import { buildURL } from "../../navigation";
|
||||
|
||||
export const namespacesRoute: RouteProps = {
|
||||
path: "/namespaces"
|
||||
};
|
||||
|
||||
export interface NamespacesRouteParams {
|
||||
}
|
||||
|
||||
export interface INamespacesRouteParams {
|
||||
}
|
||||
|
||||
export const namespacesURL = buildURL<INamespacesRouteParams>(namespacesRoute.path)
|
||||
export const namespacesURL = buildURL<NamespacesRouteParams>(namespacesRoute.path);
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./namespaces.scss"
|
||||
import "./namespaces.scss";
|
||||
|
||||
import * as React from "react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
@@ -9,7 +9,7 @@ import { Badge } from "../badge";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { INamespacesRouteParams } from "./namespaces.route";
|
||||
import { NamespacesRouteParams } from "./namespaces.route";
|
||||
import { namespaceStore } from "./namespace.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@@ -20,25 +20,25 @@ enum sortBy {
|
||||
status = "status",
|
||||
}
|
||||
|
||||
interface Props extends RouteComponentProps<INamespacesRouteParams> {
|
||||
interface Props extends RouteComponentProps<NamespacesRouteParams> {
|
||||
}
|
||||
|
||||
export class Namespaces extends React.Component<Props> {
|
||||
render() {
|
||||
render(): JSX.Element {
|
||||
return (
|
||||
<MainLayout>
|
||||
<KubeObjectListLayout
|
||||
isClusterScoped
|
||||
className="Namespaces" store={namespaceStore}
|
||||
sortingCallbacks={{
|
||||
[sortBy.name]: (ns: Namespace) => ns.getName(),
|
||||
[sortBy.labels]: (ns: Namespace) => ns.getLabels(),
|
||||
[sortBy.age]: (ns: Namespace) => ns.metadata.creationTimestamp,
|
||||
[sortBy.status]: (ns: Namespace) => ns.getStatus(),
|
||||
[sortBy.name]: (ns: Namespace): string => ns.getName(),
|
||||
[sortBy.labels]: (ns: Namespace): string[] => ns.getLabels(),
|
||||
[sortBy.age]: (ns: Namespace): string => ns.metadata.creationTimestamp,
|
||||
[sortBy.status]: (ns: Namespace): string => ns.getStatus(),
|
||||
}}
|
||||
searchFilters={[
|
||||
(item: Namespace) => item.getSearchFields(),
|
||||
(item: Namespace) => item.getStatus()
|
||||
(item: Namespace): string[] => item.getSearchFields(),
|
||||
(item: Namespace): string => item.getStatus()
|
||||
]}
|
||||
renderHeaderTitle={<Trans>Namespaces</Trans>}
|
||||
renderTableHeader={[
|
||||
@@ -47,33 +47,33 @@ export class Namespaces extends React.Component<Props> {
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
||||
]}
|
||||
renderTableContents={(item: Namespace) => [
|
||||
renderTableContents={(item: Namespace): (string | JSX.Element[] | number | React.ReactNode)[] => [
|
||||
item.getName(),
|
||||
item.getLabels().map(label => <Badge key={label} label={label}/>),
|
||||
item.getAge(),
|
||||
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },
|
||||
]}
|
||||
renderItemMenu={(item: Namespace) => {
|
||||
return <NamespaceMenu object={item}/>
|
||||
renderItemMenu={(item: Namespace): JSX.Element => {
|
||||
return <NamespaceMenu object={item}/>;
|
||||
}}
|
||||
addRemoveButtons={{
|
||||
addTooltip: <Trans>Add Namespace</Trans>,
|
||||
onAdd: () => AddNamespaceDialog.open(),
|
||||
onAdd: (): void => AddNamespaceDialog.open(),
|
||||
}}
|
||||
customizeTableRowProps={(item: Namespace) => ({
|
||||
customizeTableRowProps={(item: Namespace): { disabled: boolean } => ({
|
||||
disabled: item.getStatus() === NamespaceStatus.TERMINATING,
|
||||
})}
|
||||
/>
|
||||
<AddNamespaceDialog/>
|
||||
</MainLayout>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function NamespaceMenu(props: KubeObjectMenuProps<Namespace>) {
|
||||
export function NamespaceMenu(props: KubeObjectMenuProps<Namespace>): JSX.Element {
|
||||
return (
|
||||
<KubeObjectMenu {...props}/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
apiManager.registerViews(namespacesApi, {
|
||||
|
||||
Reference in new issue
Block a user