1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Move tooltip to bottom, clear store on loadAll cluster scope failure

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2021-11-16 09:36:11 -05:00
parent 28b9e2cbc1
commit 98367158c0
3 changed files with 48 additions and 35 deletions

View File

@ -184,7 +184,17 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
const res = api.list({ reqInit }, this.query); const res = api.list({ reqInit }, this.query);
if (onLoadFailure) { if (onLoadFailure) {
return res.catch(error => (onLoadFailure(error.message), [])); try {
return await res;
} catch (error) {
onLoadFailure(error?.message || error?.toString() || "Unknown error");
// reset the store because we are loading all, so that nothing is displayed
this.items.clear();
this.selectedItemsIds.clear();
return [];
}
} }
return res; return res;
@ -346,7 +356,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
async patch(item: T, patch: Patch): Promise<T> { async patch(item: T, patch: Patch): Promise<T> {
return this.postUpdate( return this.postUpdate(
await this.api.patch( await this.api.patch(
{ {
name: item.getName(), namespace: item.getNs(), name: item.getName(), namespace: item.getNs(),
}, },
patch, patch,
@ -358,7 +368,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
async update(item: T, data: Partial<T>): Promise<T> { async update(item: T, data: Partial<T>): Promise<T> {
return this.postUpdate( return this.postUpdate(
await this.api.update( await this.api.update(
{ {
name: item.getName(), namespace: item.getNs(), name: item.getName(), namespace: item.getNs(),
}, },
data, data,

View File

@ -35,6 +35,7 @@ import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
import { ResourceKindMap, ResourceNames } from "../../utils/rbac"; import { ResourceKindMap, ResourceNames } from "../../utils/rbac";
import { kubeSelectedUrlParam, toggleDetails } from "../kube-detail-params"; import { kubeSelectedUrlParam, toggleDetails } from "../kube-detail-params";
import { Icon } from "../icon"; import { Icon } from "../icon";
import { TooltipPosition } from "../tooltip";
export interface KubeObjectListLayoutProps<K extends KubeObject> extends ItemListLayoutProps<K> { export interface KubeObjectListLayoutProps<K extends KubeObject> extends ItemListLayoutProps<K> {
store: KubeObjectStore<K>; store: KubeObjectStore<K>;
@ -77,7 +78,7 @@ export class KubeObjectListLayout<K extends KubeObject> extends React.Component<
kubeWatchApi.subscribeStores(stores, { kubeWatchApi.subscribeStores(stores, {
preload: true, preload: true,
namespaces: clusterContext.contextNamespaces, namespaces: clusterContext.contextNamespaces,
onLoadFailure: error => this.loadErrors.push(error), onLoadFailure: error => this.loadErrors.push(String(error)),
}), }),
); );
} }
@ -90,13 +91,20 @@ export class KubeObjectListLayout<K extends KubeObject> extends React.Component<
return null; return null;
} }
const tooltip = ( return (
<> <Icon
{this.loadErrors.map((error, index) => <p key={index}>{error}</p>)} material="warning"
</> className="load-error"
tooltip={{
children: (
<>
{this.loadErrors.map((error, index) => <p key={index}>{error}</p>)}
</>
),
preferredPositions: TooltipPosition.BOTTOM,
}}
/>
); );
return <Icon material="warning" className="load-error" tooltip={tooltip}/>;
} }
render() { render() {

View File

@ -112,26 +112,21 @@ export class Tooltip extends React.Component<TooltipProps> {
@boundMethod @boundMethod
refreshPosition() { refreshPosition() {
const { preferredPositions } = this.props; const { preferredPositions = [] } = this.props;
const { elem, targetElem } = this; const { elem, targetElem } = this;
let positions = new Set<TooltipPosition>([ // Start with the preferred positions
TooltipPosition.RIGHT, const positions = new Set([preferredPositions].flat());
TooltipPosition.BOTTOM,
TooltipPosition.TOP,
TooltipPosition.LEFT,
TooltipPosition.TOP_RIGHT,
TooltipPosition.TOP_LEFT,
TooltipPosition.BOTTOM_RIGHT,
TooltipPosition.BOTTOM_LEFT,
]);
if (preferredPositions) { // Then add the default ordering, these won't override the above
positions = new Set([ positions.add(TooltipPosition.RIGHT);
...[preferredPositions].flat(), positions.add(TooltipPosition.BOTTOM);
...positions, positions.add(TooltipPosition.TOP);
]); positions.add(TooltipPosition.LEFT);
} positions.add(TooltipPosition.TOP_RIGHT);
positions.add(TooltipPosition.TOP_LEFT);
positions.add(TooltipPosition.BOTTOM_RIGHT);
positions.add(TooltipPosition.BOTTOM_LEFT);
// reset position first and get all possible client-rect area for tooltip element // reset position first and get all possible client-rect area for tooltip element
this.setPosition({ left: 0, top: 0 }); this.setPosition({ left: 0, top: 0 });
@ -178,35 +173,35 @@ export class Tooltip extends React.Component<TooltipProps> {
const bottomCenter = targetBounds.bottom + offset; const bottomCenter = targetBounds.bottom + offset;
switch (position) { switch (position) {
case "top": case TooltipPosition.TOP:
left = horizontalCenter; left = horizontalCenter;
top = topCenter; top = topCenter;
break; break;
case "bottom": case TooltipPosition.BOTTOM:
left = horizontalCenter; left = horizontalCenter;
top = bottomCenter; top = bottomCenter;
break; break;
case "left": case TooltipPosition.LEFT:
top = verticalCenter; top = verticalCenter;
left = targetBounds.left - tooltipBounds.width - offset; left = targetBounds.left - tooltipBounds.width - offset;
break; break;
case "right": case TooltipPosition.RIGHT:
top = verticalCenter; top = verticalCenter;
left = targetBounds.right + offset; left = targetBounds.right + offset;
break; break;
case "top_left": case TooltipPosition.TOP_LEFT:
left = targetBounds.left; left = targetBounds.left;
top = topCenter; top = topCenter;
break; break;
case "top_right": case TooltipPosition.TOP_RIGHT:
left = targetBounds.right - tooltipBounds.width; left = targetBounds.right - tooltipBounds.width;
top = topCenter; top = topCenter;
break; break;
case "bottom_left": case TooltipPosition.BOTTOM_LEFT:
top = bottomCenter; top = bottomCenter;
left = targetBounds.left; left = targetBounds.left;
break; break;
case "bottom_right": case TooltipPosition.BOTTOM_RIGHT:
top = bottomCenter; top = bottomCenter;
left = targetBounds.right - tooltipBounds.width; left = targetBounds.right - tooltipBounds.width;
break; break;