mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge remote-tracking branch 'origin/master' into lens_restructure
# Conflicts: # package.json # src/main/index.ts # src/renderer/api/__test__/parseAPI.test.ts # src/renderer/components/chart/bar-chart.tsx # src/renderer/components/chart/chart.tsx # src/renderer/components/chart/pie-chart.tsx # src/renderer/utils/__tests__/arrays.test.ts # src/renderer/utils/arrays.ts # yarn.lock
This commit is contained in:
commit
f4922811cc
38 files changed
+281
-265
No files matched your search
@@ -122,7 +122,6 @@
|
||||
id="checkbox-allow-telemetry"
|
||||
switch
|
||||
v-model="preferences.allowTelemetry"
|
||||
:disabled="licenceData && licenceData.status === 'valid'"
|
||||
@input="onSave"
|
||||
>
|
||||
Allow telemetry & usage tracking
|
||||
|
||||
@@ -47,6 +47,11 @@ export default new Vuex.Store({
|
||||
this.commit("savePreferences", userStore.getPreferences());
|
||||
},
|
||||
savePreferences(state, prefs) {
|
||||
if (prefs.allowTelemetry) {
|
||||
tracker.event("telemetry", "enabled")
|
||||
} else {
|
||||
tracker.event("telemetry", "disabled")
|
||||
}
|
||||
state.preferences = prefs;
|
||||
userStore.setPreferences(prefs);
|
||||
this.dispatch("destroyWebviews")
|
||||
|
||||
Whitespace-only changes.
@@ -156,9 +156,12 @@ export class HelmRelease implements ItemObject {
|
||||
}
|
||||
|
||||
getChart(withVersion = false) {
|
||||
return withVersion ?
|
||||
this.chart :
|
||||
this.chart.substr(0, this.chart.lastIndexOf("-"));
|
||||
let chart = this.chart
|
||||
if(!withVersion && this.getVersion() != "" ) {
|
||||
const search = new RegExp(`-${this.getVersion()}`)
|
||||
chart = chart.replace(search, "");
|
||||
}
|
||||
return chart
|
||||
}
|
||||
|
||||
getRevision() {
|
||||
@@ -170,7 +173,7 @@ export class HelmRelease implements ItemObject {
|
||||
}
|
||||
|
||||
getVersion() {
|
||||
const versions = this.chart.match(/(\d+)[^-]*$/)
|
||||
const versions = this.chart.match(/(v?\d+)[^-].*$/)
|
||||
if (versions) {
|
||||
return versions[0]
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { autobind } from "../../utils";
|
||||
import { IAffinity, WorkloadKubeObject } from "../workload-kube-object";
|
||||
import { IPodContainer } from "./pods.api";
|
||||
import { KubeApi } from "../kube-api";
|
||||
import { JsonApiParams } from "../json-api";
|
||||
|
||||
@autobind()
|
||||
export class Job extends WorkloadKubeObject {
|
||||
@@ -88,6 +89,13 @@ export class Job extends WorkloadKubeObject {
|
||||
const containers: IPodContainer[] = get(this, "spec.template.spec.containers", [])
|
||||
return [...containers].map(container => container.image)
|
||||
}
|
||||
|
||||
delete() {
|
||||
const params: JsonApiParams = {
|
||||
query: { propagationPolicy: "Background" }
|
||||
}
|
||||
return super.delete(params)
|
||||
}
|
||||
}
|
||||
|
||||
export const jobApi = new KubeApi({
|
||||
|
||||
@@ -56,7 +56,21 @@ export const metricsApi = {
|
||||
};
|
||||
|
||||
export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
|
||||
if (!metrics?.data?.result) {
|
||||
return {
|
||||
data: {
|
||||
resultType: "",
|
||||
result: [{
|
||||
metric: {},
|
||||
values: []
|
||||
} as IMetricsResult],
|
||||
},
|
||||
status: "",
|
||||
}
|
||||
}
|
||||
|
||||
const { result } = metrics.data;
|
||||
|
||||
if (result.length) {
|
||||
if (frames > 0) {
|
||||
// fill the gaps
|
||||
@@ -81,13 +95,16 @@ export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
|
||||
}
|
||||
|
||||
export function isMetricsEmpty(metrics: { [key: string]: IMetrics }) {
|
||||
return Object.values(metrics).every(metric => !metric.data.result.length);
|
||||
return Object.values(metrics).every(metric => !metric?.data?.result?.length);
|
||||
}
|
||||
|
||||
export function getItemMetrics(metrics: { [key: string]: IMetrics }, itemName: string) {
|
||||
export function getItemMetrics(metrics: { [key: string]: IMetrics }, itemName: string): { [key: string]: IMetrics } {
|
||||
if (!metrics) return;
|
||||
const itemMetrics = { ...metrics };
|
||||
for (const metric in metrics) {
|
||||
if (!metrics[metric]?.data?.result) {
|
||||
continue
|
||||
}
|
||||
const results = metrics[metric].data.result;
|
||||
const result = results.find(res => Object.values(res.metric)[0] == itemName);
|
||||
itemMetrics[metric].data.result = result ? [result] : [];
|
||||
|
||||
@@ -7,6 +7,7 @@ import { IKubeObjectRef, KubeJsonApi, KubeJsonApiData, KubeJsonApiDataList } fro
|
||||
import { apiKube } from "./index";
|
||||
import { kubeWatchApi } from "./kube-watch-api";
|
||||
import { apiManager } from "./api-manager";
|
||||
import { split } from "../utils/arrays";
|
||||
|
||||
export interface IKubeApiOptions<T extends KubeObject> {
|
||||
kind: string; // resource type within api-group, e.g. "Namespace"
|
||||
@@ -32,20 +33,45 @@ export interface IKubeApiLinkRef {
|
||||
namespace?: string;
|
||||
}
|
||||
|
||||
export class KubeApi<T extends KubeObject = any> {
|
||||
static matcher = /(\/apis?.*?)\/(?:(.*?)\/)?(v.*?)(?:\/namespaces\/(.+?))?\/([^\/]+)(?:\/([^\/?]+))?.*$/
|
||||
export interface IKubeApiLinkBase extends IKubeApiLinkRef {
|
||||
apiBase: string;
|
||||
apiGroup: string;
|
||||
apiVersionWithGroup: string;
|
||||
}
|
||||
|
||||
static parseApi(apiPath = "") {
|
||||
export class KubeApi<T extends KubeObject = any> {
|
||||
static parseApi(apiPath = ""): IKubeApiLinkBase {
|
||||
apiPath = new URL(apiPath, location.origin).pathname;
|
||||
const [, apiPrefix, apiGroup = "", apiVersion, namespace, resource, name] = apiPath.match(KubeApi.matcher) || [];
|
||||
const [, prefix, ...parts] = apiPath.split("/");
|
||||
const apiPrefix = `/${prefix}`;
|
||||
|
||||
const [left, right, found] = split(parts, "namespaces");
|
||||
let apiGroup, apiVersion, namespace, resource, name;
|
||||
|
||||
if (found) {
|
||||
if (left.length == 0) {
|
||||
throw new Error(`invalid apiPath: ${apiPath}`)
|
||||
}
|
||||
|
||||
apiVersion = left.pop();
|
||||
apiGroup = left.join("/");
|
||||
[namespace, resource, name] = right;
|
||||
} else {
|
||||
[apiGroup, apiVersion, resource] = left;
|
||||
}
|
||||
const apiVersionWithGroup = [apiGroup, apiVersion].filter(v => v).join("/");
|
||||
const apiBase = [apiPrefix, apiGroup, apiVersion, resource].filter(v => v).join("/");
|
||||
|
||||
if (!apiBase) {
|
||||
throw new Error(`invalid apiPath: ${apiPath}`)
|
||||
}
|
||||
|
||||
return {
|
||||
apiBase,
|
||||
apiPrefix, apiGroup,
|
||||
apiVersion, apiVersionWithGroup,
|
||||
namespace, resource, name,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static createLink(ref: IKubeApiLinkRef): string {
|
||||
@@ -55,7 +81,7 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
namespace = `namespaces/${namespace}`
|
||||
}
|
||||
return [apiPrefix, apiVersion, namespace, resource, name]
|
||||
.filter(v => !!v)
|
||||
.filter(v => v)
|
||||
.join("/")
|
||||
}
|
||||
|
||||
@@ -130,8 +156,9 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
if (KubeObject.isJsonApiData(data)) {
|
||||
return new KubeObjectConstructor(data);
|
||||
}
|
||||
|
||||
// process items list response
|
||||
else if (KubeObject.isJsonApiDataList(data)) {
|
||||
if (KubeObject.isJsonApiDataList(data)) {
|
||||
const { apiVersion, items, metadata } = data;
|
||||
this.setResourceVersion(namespace, metadata.resourceVersion);
|
||||
this.setResourceVersion("", metadata.resourceVersion);
|
||||
@@ -141,10 +168,12 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
...item,
|
||||
}))
|
||||
}
|
||||
|
||||
// custom apis might return array for list response, e.g. users, groups, etc.
|
||||
else if (Array.isArray(data)) {
|
||||
if (Array.isArray(data)) {
|
||||
return data.map(data => new KubeObjectConstructor(data));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -162,16 +191,19 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
|
||||
async create({ name = "", namespace = "default" } = {}, data?: Partial<T>): Promise<T> {
|
||||
const apiUrl = this.getUrl({ namespace });
|
||||
return this.request.post(apiUrl, {
|
||||
data: merge({
|
||||
kind: this.kind,
|
||||
apiVersion: this.apiVersionWithGroup,
|
||||
metadata: {
|
||||
name,
|
||||
namespace
|
||||
}
|
||||
}, data)
|
||||
}).then(this.parseResponse);
|
||||
|
||||
return this.request
|
||||
.post(apiUrl, {
|
||||
data: merge({
|
||||
kind: this.kind,
|
||||
apiVersion: this.apiVersionWithGroup,
|
||||
metadata: {
|
||||
name,
|
||||
namespace
|
||||
}
|
||||
}, data)
|
||||
})
|
||||
.then(this.parseResponse);
|
||||
}
|
||||
|
||||
async update({ name = "", namespace = "default" } = {}, data?: Partial<T>): Promise<T> {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { KubeJsonApiData, KubeJsonApiDataList } from "./kube-json-api";
|
||||
import { autobind, formatDuration } from "../utils";
|
||||
import { ItemObject } from "../item.store";
|
||||
import { apiKube } from "./index";
|
||||
import { JsonApiParams } from "./json-api";
|
||||
import { resourceApplierApi } from "./endpoints/resource-applier.api";
|
||||
|
||||
export type IKubeObjectConstructor<T extends KubeObject = any> = (new (data: KubeJsonApiData | any) => T) & {
|
||||
@@ -153,7 +154,7 @@ export class KubeObject implements ItemObject {
|
||||
});
|
||||
}
|
||||
|
||||
delete() {
|
||||
return apiKube.del(this.selfLink);
|
||||
delete(params?: JsonApiParams) {
|
||||
return apiKube.del(this.selfLink, params);
|
||||
}
|
||||
}
|
||||
@@ -82,15 +82,15 @@ export class ClusterStore extends KubeObjectStore<Cluster> {
|
||||
this.liveMetrics = await this.loadMetrics({ start, end, step, range });
|
||||
}
|
||||
|
||||
getMetricsValues(source: Partial<IClusterMetrics>) {
|
||||
const metrics =
|
||||
this.metricType === MetricType.CPU ? source.cpuUsage :
|
||||
this.metricType === MetricType.MEMORY ? source.memoryUsage
|
||||
: null;
|
||||
if (!metrics) {
|
||||
getMetricsValues(source: Partial<IClusterMetrics>): [number, string][] {
|
||||
switch (this.metricType) {
|
||||
case MetricType.CPU:
|
||||
return normalizeMetrics(source.cpuUsage).data.result[0].values
|
||||
case MetricType.MEMORY:
|
||||
return normalizeMetrics(source.memoryUsage).data.result[0].values
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
return normalizeMetrics(metrics).data.result[0].values;
|
||||
}
|
||||
|
||||
resetMetrics() {
|
||||
|
||||
@@ -34,7 +34,7 @@ export class NamespaceSelect extends React.Component<Props> {
|
||||
private unsubscribe = noop;
|
||||
|
||||
async componentDidMount() {
|
||||
if (isAllowedResource("namespaces") && !namespaceStore.isLoaded) {
|
||||
if (!namespaceStore.isLoaded) {
|
||||
await namespaceStore.loadAll();
|
||||
}
|
||||
this.unsubscribe = namespaceStore.subscribe();
|
||||
|
||||
@@ -4,6 +4,7 @@ import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { Namespace, namespacesApi } from "../../api/endpoints";
|
||||
import { IQueryParams, navigation, setQueryParams } from "../../navigation";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { isAllowedResource } from "../..//api/rbac";
|
||||
|
||||
@autobind()
|
||||
export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
@@ -43,6 +44,16 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
}
|
||||
|
||||
protected loadItems(namespaces?: string[]) {
|
||||
if (!isAllowedResource("namespaces")) {
|
||||
if (namespaces) {
|
||||
return Promise.all(namespaces.map(name => this.getDummyNamespace(name)))
|
||||
}
|
||||
else {
|
||||
return new Promise<Namespace[]>(() => {
|
||||
return []
|
||||
})
|
||||
}
|
||||
}
|
||||
if (namespaces) {
|
||||
return Promise.all(namespaces.map(name => this.api.get({ name })))
|
||||
}
|
||||
@@ -51,6 +62,19 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
}
|
||||
}
|
||||
|
||||
protected getDummyNamespace(name: string) {
|
||||
return new Namespace({
|
||||
kind: "Namespace",
|
||||
apiVersion: "v1",
|
||||
metadata: {
|
||||
name: name,
|
||||
uid: "",
|
||||
resourceVersion: "",
|
||||
selfLink: `/api/v1/namespaces/${name}`
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setContext(namespaces: string[]) {
|
||||
this.contextNs.replace(namespaces);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ export const IngressCharts = observer(() => {
|
||||
if (!metrics) return null;
|
||||
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
||||
|
||||
const values = Object.values(metrics).map(metric =>
|
||||
normalizeMetrics(metric).data.result[0].values
|
||||
);
|
||||
const values = Object.values(metrics)
|
||||
.map(normalizeMetrics)
|
||||
.map(({ data }) => data.result[0].values);
|
||||
const [
|
||||
bytesSentSuccess,
|
||||
bytesSentFailure,
|
||||
|
||||
@@ -96,7 +96,7 @@ export class DeploymentScaleDialog extends Component<Props> {
|
||||
<Trans>Desired number of replicas</Trans>: {desiredReplicas}
|
||||
</div>
|
||||
<div className="slider-container">
|
||||
<Slider value={desiredReplicas} max={scaleMax} onChange={onChange}/>
|
||||
<Slider value={desiredReplicas} max={scaleMax} onChange={onChange as any /** see: https://github.com/mui-org/material-ui/issues/20191 */}/>
|
||||
</div>
|
||||
</div>
|
||||
{warning &&
|
||||
|
||||
@@ -17,9 +17,9 @@ export const ContainerCharts = () => {
|
||||
if (!metrics) return null;
|
||||
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
||||
|
||||
const values = Object.values(metrics).map(metric =>
|
||||
normalizeMetrics(metric).data.result[0].values
|
||||
);
|
||||
const values = Object.values(metrics)
|
||||
.map(normalizeMetrics)
|
||||
.map(({ data }) => data.result[0].values);
|
||||
const [
|
||||
cpuUsage,
|
||||
cpuRequests,
|
||||
|
||||
@@ -28,9 +28,9 @@ export const PodCharts = observer(() => {
|
||||
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
|
||||
|
||||
const options = tabId == 0 ? cpuOptions : memoryOptions;
|
||||
const values = Object.values(metrics).map(metric =>
|
||||
normalizeMetrics(metric).data.result[0].values
|
||||
);
|
||||
const values = Object.values(metrics)
|
||||
.map(normalizeMetrics)
|
||||
.map(({ data }) => data.result[0].values);
|
||||
const [
|
||||
cpuUsage,
|
||||
cpuRequests,
|
||||
|
||||
@@ -120,8 +120,11 @@ const SecretKey = (props: SecretKeyProps) => {
|
||||
setSecret(secret)
|
||||
}
|
||||
|
||||
if (!secret) {
|
||||
return (
|
||||
if (secret?.data?.[key]) {
|
||||
return <>{base64.decode(secret.data[key])}</>
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
secretKeyRef({name}.{key})
|
||||
<Icon
|
||||
@@ -131,7 +134,5 @@ const SecretKey = (props: SecretKeyProps) => {
|
||||
onClick={showKey}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
return <>{base64.decode(secret.data[key])}</>
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -139,7 +139,7 @@ export function BarChart(props: Props) {
|
||||
}
|
||||
};
|
||||
const options = merge(barOptions, customOptions);
|
||||
if (!chartData.datasets.length) {
|
||||
if (chartData.datasets.length == 0) {
|
||||
return <NoMetrics/>
|
||||
}
|
||||
return (
|
||||
@@ -159,10 +159,15 @@ export const memoryOptions: ChartOptions = {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: value => {
|
||||
value = parseFloat(String(value));
|
||||
if (!value) return 0;
|
||||
return value < 1 ? value.toFixed(3) : bytesToUnits(value);
|
||||
callback: (value: number | string): string => {
|
||||
if (typeof value == "string") {
|
||||
const float = parseFloat(value);
|
||||
if (float < 1) {
|
||||
return float.toFixed(3);
|
||||
}
|
||||
return bytesToUnits(parseInt(value));
|
||||
}
|
||||
return `${value}`;
|
||||
},
|
||||
stepSize: 1
|
||||
}
|
||||
@@ -184,11 +189,12 @@ export const cpuOptions: ChartOptions = {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
callback: (value: number) => {
|
||||
if (value == 0) return 0;
|
||||
if (value < 10) return value.toFixed(3);
|
||||
if (value < 100) return value.toFixed(2);
|
||||
return value.toFixed(1);
|
||||
callback: (value: number | string): string => {
|
||||
const float = parseFloat(`${value}`);
|
||||
if (float == 0) return "0";
|
||||
if (float < 10) return float.toFixed(3);
|
||||
if (float < 100) return float.toFixed(2);
|
||||
return float.toFixed(1);
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "./chart.scss";
|
||||
import React from "react";
|
||||
import ChartJS from "chart.js";
|
||||
import ChartJS, {ChartData, ChartOptions} from "chart.js";
|
||||
import { isEqual, remove } from "lodash";
|
||||
import { cssNames } from "../../utils";
|
||||
import { StatusBrick } from "../status-brick";
|
||||
@@ -17,7 +17,7 @@ export interface ChartDataSets extends ChartJS.ChartDataSets {
|
||||
|
||||
export interface ChartProps {
|
||||
data: ChartData;
|
||||
options?: ChartJS.ChartOptions; // Passed to ChartJS instance
|
||||
options?: ChartOptions; // Passed to ChartJS instance
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
type?: ChartKind;
|
||||
|
||||
@@ -5,7 +5,10 @@ import { Chart, ChartProps } from "./chart";
|
||||
import { cssNames } from "../../utils";
|
||||
import { themeStore } from "../../theme.store";
|
||||
|
||||
export class PieChart extends React.Component<ChartProps> {
|
||||
interface Props extends ChartProps {
|
||||
}
|
||||
|
||||
export class PieChart extends React.Component<Props> {
|
||||
render() {
|
||||
const { data, className, options, ...chartProps } = this.props
|
||||
const { contentColor } = themeStore.activeTheme.colors;
|
||||
|
||||
@@ -119,12 +119,12 @@ export class Dock extends React.Component<Props> {
|
||||
/>
|
||||
<div className="toolbar flex gaps align-center box grow">
|
||||
<div className="dock-menu box grow">
|
||||
<MenuActions usePortal triggerIcon={{ material: "add", tooltip: <Trans>New tab</Trans> }} closeOnScroll={false}>
|
||||
<MenuItem onClick={() => createTerminalTab()}>
|
||||
<MenuActions usePortal triggerIcon={{ material: "add", className: "new-dock-tab", tooltip: <Trans>New tab</Trans> }} closeOnScroll={false}>
|
||||
<MenuItem className="create-terminal-tab" onClick={() => createTerminalTab()}>
|
||||
<Icon small svg="terminal" size={15}/>
|
||||
<Trans>Terminal session</Trans>
|
||||
</MenuItem>
|
||||
<MenuItem onClick={() => createResourceTab()}>
|
||||
<MenuItem className="create-resource-tab" onClick={() => createResourceTab()}>
|
||||
<Icon small material="create"/>
|
||||
<Trans>Create resource</Trans>
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,161 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"> <image id="image0" width="512" height="512" x="0" y="0"
|
||||
href="data:image/png;base64,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
|
||||
1XPH56f6Avtuvpj+ovel5OXgq4K/1P7a/try9fG/ff6+3p/Q3/tG+mbo7Zp32u/2v5/8vnkgYuDx
|
||||
h+wPgx8LP2l/OvCZ/bnlS/yXZ4PzvpK+ln6z+tb4PfT7w6HsoSEJT8obkQI4bKCpqQBv9wPQEwEY
|
||||
NwEo00c19Ygho/8DRgj+F4/q7hFzAUwaAMT7AIQ3Aewe1iDLsNwYR2C+GB9AnZwU498mS3VyHM1F
|
||||
rcekScnQ0DtMP5KsAL51Dg0N1g8NfavEmr2P6ZgPo1p+RMeIMDmPFdPSba/ODoD/sn8BcJ0Q6U6Z
|
||||
H8IAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAASNQTFRF////
|
||||
hpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCb
|
||||
hpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCb
|
||||
hpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCb
|
||||
hpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCb
|
||||
hpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCbhpCb
|
||||
////f/Q5igAAAF90Uk5TAAAVQ26QsMjc7vMka6bhKITbEmwnmfcmpP2lFJX7AWPvZCC/XPEHmxjK
|
||||
GSw4PjfyLfAa4xwGnL5lE+2UmvZyc9cziSOn4kWxssvf4JFEF4o02CmWXckIIsCL5BZw3fSQaiOm
|
||||
AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+QDHAczCg2f+2gAAAxo
|
||||
elRYdFJhdyBwcm9maWxlIHR5cGUgaWNjAABYha2Za64jKxKE/9cqZgk8kgSWAwkpzf43MB9lu9un
|
||||
7dbVlcanUdkUBUk+IoLq679m13/45Jz1CuezQtNYQw1qIcW7S5fuKjWVJFVSCqWVXkYKoW7hNl/C
|
||||
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
|
||||
NjsGcDG9WP066hbAzY/Sg9WvmZudAvg4vVd9W+8SwIrf/xs7GysdAriQXqv+zbcPYNnvf4+h1cXW
|
||||
AdxKb1UNt9oGsHY7PVU13F5rGcAn6aWq47hlAHfSQ1XHnXYB3E3vVC13WwVwLz1TtdxrFYB//2Fs
|
||||
LbUJ4H56peq53yKAufRI1TPXIoAH6ZGq50GLAD5Nj1Q9h80BTKQ3qqaJxgBOpSeqps8aA5hMT1RN
|
||||
k40BTKUnqqapxgA+T09UTQ8bAzhJT1RNJ40BfJGeqJq+bAzAvwc41rYaA7ianqiaZhsDSC9UXQYA
|
||||
ZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcA
|
||||
cAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAG
|
||||
AGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBnAHAGAGcAcAYAZwBwBgBn
|
||||
AHAGADeCAZT+pJ/yEjAAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgD
|
||||
gDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4Az
|
||||
ADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4
|
||||
A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOA
|
||||
MwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMA
|
||||
OAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgD
|
||||
gDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4Az
|
||||
ADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4
|
||||
A4BjB/D/S//w/sUADMAADMAADMAADMAADMAADMAADMAADMAADMAADMAADCA98N/SNzSAsPQNDSAs
|
||||
fUMDCEvf0ADC0jc0gLD0DQ0gLH1DAwhL39AAwtI3NICw9A0NICx9QwMIS9/QAMLSNzSAsPQNDSAs
|
||||
fUMDCEvf0ADC0jc0gLD0DQ0gLH1DAwhL39AAwtI3NICw9A0NICx9QwMIS9/QAMLSNzSAsPQNDSAs
|
||||
fUMDCEvf0ADC0jc0gLD0DQ0gLH1DAwhL39AAwtI3NICw9A0NICx9QwMIS9/QAMLSNzSAsPQNDSAs
|
||||
fUMDCEvf0ADC0jc0gLD0DQ0gLH1DAwhL39AAwtI3NICw9A0NICx9QwPQGDEAOAOAMwA4A4AzADgD
|
||||
gDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4Az
|
||||
ADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4
|
||||
A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzADgDgDMAOAOAMwA4A4AzALjGAK6mF6qm
|
||||
2cYAttITVdNWYwBfpCeqpi8bAzhJT1RNJ40BfJ6eqJoeNgYwlZ6omh41BjCZnqiaJhsDeJyeqJo+
|
||||
awxgIj1RNX3VGEA5TG9UPYelOYAH6ZGq50GLAObSI1XP2RYB3E+PVD33WwRQTqdXqpbTpU0AX6dn
|
||||
qpZ7rQK4m56pWp60CqDcSe9UHd+UdgEcp4eqjuOWAazdTi9VDbfXWgZQbqWnqoZbpW0Ai6vprerf
|
||||
6retAyjz6bHq33xpH8DKRnqt+rax3CGAsp6eq759V7oEcHMmvVf92rrZKYBylB6sfh2VbgFs7qQX
|
||||
q087mx0DKNt76c3qz9526RpA2U2PVn++L90DKDfSq9WXG2WQAC49Te9WP04uDRRAue4XhMfC4fUy
|
||||
WADl4Fp6u4Z37aAMGkDZn02v17Bm98vgAZQrFjDiZq+UYQIo+/7FkJG2tV+GC6AcLKTfoMEtHJRh
|
||||
AyjvXE6/QoO6/H4ZPoDyg58IjagbP5Q+Aihl198LjKC97593y4ECKD/+lH6Nuvrpx9JfAGXzyH8N
|
||||
jJSto83SZwClrK37PcGRsbG+9l93HDiAUpYv+G3xkbA6v/zfVxwigGcJnDuffpyanD+3+KIbDhVA
|
||||
KRPH/s/Rl9qd44kXX3DIAJ558vNS+pV6vqWfnzSeb/gAnjkzN+9XBV4yv8zPnWlzu14C+Nuvj397
|
||||
9PDp7zN/pF/O9sfM708fPvrt8a9t79YYgCRJkiRJkiRJkiRJGnl/AWNYpuT+rvp8AAAAJXRFWHRk
|
||||
YXRlOmNyZWF0ZQAyMDIwLTAzLTI4VDA3OjUxOjEwKzAwOjAwJ6kuaQAAACV0RVh0ZGF0ZTptb2Rp
|
||||
ZnkAMjAyMC0wMy0yOFQwNzo1MToxMCswMDowMFb0ltUAAAAodEVYdGljYzpjb3B5cmlnaHQAQ29w
|
||||
eXJpZ2h0IEFwcGxlIEluYy4sIDIwMjAKut6wAAAAF3RFWHRpY2M6ZGVzY3JpcHRpb24ARGlzcGxh
|
||||
eRcblbgAAAAASUVORK5CYII=" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><style>.cls-2{fill:#3c90ce;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-2" d="M256,496C123.67,496,16,388.33,16,256S123.67,16,256,16,496,123.67,496,256,388.33,496,256,496Zm0-470C129.17,26,26,129.18,26,256S129.17,486,256,486,486,382.82,486,256,382.83,26,256,26Z"/><path class="cls-2" d="M403.22,282l65.66-81.68A220.52,220.52,0,0,0,351.61,57.81Z"/><path class="cls-2" d="M476,256a220.86,220.86,0,0,0-4-41.5L334.74,385.3H434A219,219,0,0,0,476,256Z"/><path class="cls-2" d="M247.63,121.17,139.38,69.48A220,220,0,0,0,38.81,221Z"/><path class="cls-2" d="M140.75,184.81,37.07,234.35C36.38,241.48,36,248.69,36,256A219.13,219.13,0,0,0,91,401.4Z"/><path class="cls-2" d="M210.57,396.65l63.2,78.57a219.52,219.52,0,0,0,151.38-78.57Z"/><path class="cls-2" d="M124.21,307.38l-23.91,104A219.33,219.33,0,0,0,256,476c1.26,0,2.5-.07,3.76-.1Z"/><path class="cls-2" d="M364.52,164.42,338.67,52.12A220.21,220.21,0,0,0,151.16,62.54Z"/><path class="cls-2" d="M351.71,276.74c-.46-.11-1.12-.29-1.58-.37a45.28,45.28,0,0,0-5.2-.42,50.71,50.71,0,0,1-9.73-1.6,6.13,6.13,0,0,1-2.35-2.36l-2.19-.63a70.52,70.52,0,0,0-11.31-48.85l1.93-1.73a4.3,4.3,0,0,1,1-3.08,50.88,50.88,0,0,1,8.07-5.67,43.85,43.85,0,0,0,4.51-2.63c.35-.26.83-.67,1.2-1,2.6-2.08,3.2-5.66,1.33-8s-5.49-2.57-8.09-.49c-.38.29-.88.67-1.21,1a43.42,43.42,0,0,0-3.58,3.79,51.27,51.27,0,0,1-7.32,6.63,6.1,6.1,0,0,1-3.3.36l-2.06,1.47a71.09,71.09,0,0,0-45.06-21.77c-.05-.72-.11-2-.12-2.42a4.33,4.33,0,0,1-1.78-2.72,50.16,50.16,0,0,1,.62-9.84,45.29,45.29,0,0,0,.74-5.17c0-.43,0-1.07,0-1.54,0-3.33-2.43-6-5.43-6s-5.43,2.7-5.43,6c0,.05,0,.1,0,.15,0,.45,0,1,0,1.39a45.29,45.29,0,0,0,.74,5.17,50.87,50.87,0,0,1,.61,9.84,5.9,5.9,0,0,1-1.77,2.81l-.12,2.29a71.38,71.38,0,0,0-9.82,1.51,69.83,69.83,0,0,0-35.46,20.26c-.6-.41-1.65-1.16-2-1.39a4.32,4.32,0,0,1-3.23-.31,50.46,50.46,0,0,1-7.31-6.61,45,45,0,0,0-3.58-3.79c-.33-.29-.83-.67-1.2-1a6.42,6.42,0,0,0-3.78-1.42,5.22,5.22,0,0,0-4.33,1.91c-1.87,2.34-1.27,5.93,1.33,8l.09.06c.35.29.79.66,1.12.91a46.81,46.81,0,0,0,4.5,2.63,49.61,49.61,0,0,1,8.07,5.67,6,6,0,0,1,1.09,3.13l1.74,1.55a70.25,70.25,0,0,0-11.07,49l-2.28.66a7.61,7.61,0,0,1-2.33,2.36,51.5,51.5,0,0,1-9.73,1.6,45.38,45.38,0,0,0-5.21.41c-.41.08-1,.23-1.45.34h0l-.08,0c-3.2.78-5.26,3.72-4.6,6.61a5.75,5.75,0,0,0,7,4h.08l.1,0c.45-.1,1-.21,1.41-.32a45.65,45.65,0,0,0,4.87-1.87,51.49,51.49,0,0,1,9.46-2.78,6.07,6.07,0,0,1,3.12,1.1l2.37-.4A70.59,70.59,0,0,0,225,322.21l-1,2.37a5.46,5.46,0,0,1,.48,3.07,53.5,53.5,0,0,1-4.92,8.83,46,46,0,0,0-2.91,4.33c-.21.41-.48,1-.69,1.47a5.73,5.73,0,0,0,2.31,7.71c2.69,1.3,6-.07,7.49-3.06v0h0c.21-.42.5-1,.67-1.38a45,45,0,0,0,1.57-5c1.43-3.61,2.22-7.4,4.2-9.75a4.31,4.31,0,0,1,2.34-1.14l1.23-2.23a70.15,70.15,0,0,0,40.78,2.93,71.11,71.11,0,0,0,9.31-2.8l1.16,2.09a4.26,4.26,0,0,1,2.77,1.68,50.16,50.16,0,0,1,3.72,9.12,44.6,44.6,0,0,0,1.58,5c.18.4.47,1,.67,1.39,1.45,3,4.81,4.38,7.51,3.07s3.7-4.72,2.3-7.71c-.2-.43-.49-1.05-.7-1.46A45.8,45.8,0,0,0,302,336.4a51.18,51.18,0,0,1-4.82-8.62,4.27,4.27,0,0,1,.42-3.2,20.73,20.73,0,0,1-.9-2.19A70.66,70.66,0,0,0,328,283c.7.11,1.92.33,2.32.41a4.28,4.28,0,0,1,3-1.13,50.68,50.68,0,0,1,9.47,2.79,45.66,45.66,0,0,0,4.87,1.88c.39.1,1,.2,1.4.3l.11,0h.08a5.72,5.72,0,0,0,7-4C357,280.45,354.91,277.51,351.71,276.74Zm-51.57-55.29-23.2,16.45-.08,0a4.79,4.79,0,0,1-6.56-.88,4.71,4.71,0,0,1-1.05-2.77h0l-1.61-28.43A56.44,56.44,0,0,1,300.14,221.45Zm-43.7,31.16h8.73l5.43,6.79-2,8.46-7.84,3.77L253,267.85,251,259.39Zm-8.22-45.84a56.58,56.58,0,0,1,5.79-1l-1.61,28.47-.12.06a4.79,4.79,0,0,1-7.59,3.67l-.05,0-23.35-16.55A55.92,55.92,0,0,1,248.22,206.77Zm-35.39,25.3,21.32,19.07,0,.12a4.79,4.79,0,0,1-1.88,8.22l0,.09-27.32,7.89A55.83,55.83,0,0,1,212.83,232.07Zm28.54,50.65L230.51,309A56.27,56.27,0,0,1,208,280.73L236,276l0,.06A4.37,4.37,0,0,1,237,276a4.78,4.78,0,0,1,4.33,6.67Zm32,33.74a56.07,56.07,0,0,1-30.62-1.58L256.56,290h0a4.77,4.77,0,0,1,4-2.53A4.86,4.86,0,0,1,265,290h.1l13.82,25Q276.24,315.82,273.41,316.46Zm17.81-7.4-11-26.5,0-.05a4.78,4.78,0,0,1,2.32-6.2,4.65,4.65,0,0,1,1.83-.48,5.05,5.05,0,0,1,1.1.08l.05-.05,28.26,4.77A56,56,0,0,1,291.22,309.06Zm25.59-41.69-27.46-7.91,0-.12a4.79,4.79,0,0,1-3.4-5.68,4.7,4.7,0,0,1,1.52-2.54v-.06l21.2-19a56.92,56.92,0,0,1,8.17,35.28Z"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -117,12 +117,11 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
||||
try {
|
||||
await Promise.all(stores.map(store => store.loadAll()));
|
||||
const subscriptions = stores.map(store => store.subscribe());
|
||||
|
||||
await when(() => this.isUnmounting);
|
||||
subscriptions.forEach(dispose => dispose()); // unsubscribe all
|
||||
} catch(error) {
|
||||
console.log("catched", error)
|
||||
}
|
||||
await when(() => this.isUnmounting);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@@ -226,7 +226,7 @@ class SidebarNavItem extends React.Component<SidebarNavItemProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isHidden, subMenus = [], icon, text, url, children, className } = this.props;
|
||||
const { id, isHidden, subMenus = [], icon, text, url, children, className } = this.props;
|
||||
if (isHidden) {
|
||||
return null;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ class SidebarNavItem extends React.Component<SidebarNavItemProps> {
|
||||
if (extendedView) {
|
||||
const isActive = this.isActive();
|
||||
return (
|
||||
<div className={cssNames("SidebarNavItem", className)}>
|
||||
<div id={id} className={cssNames("SidebarNavItem", className)}>
|
||||
<div className={cssNames("nav-item", { active: isActive })} onClick={this.toggleSubMenu}>
|
||||
{icon}
|
||||
<span className="link-text">{text}</span>
|
||||
|
||||
Whitespace-only changes.
Whitespace-only changes.
Reference in new issue
Block a user