Sidebar logo update (#814)

* Testing logo ux

* Updated logo on sidebar

* removed unused vars

* adjusted types on icon components
This commit is contained in:
Adil Alimbetov
2020-05-27 14:13:41 +06:00
committed by GitHub
parent 6572ea3ecc
commit f72d97dc17
46 changed files with 208 additions and 130 deletions
-1
View File
@@ -8,7 +8,6 @@ Contributions are welcome, and they are greatly appreciated! Every little bit he
Backstage is released under the Apache2.0 License, and original creations contributed to this repo are accepted under the same license.
# Types of Contributions
## Report bugs
File diff suppressed because one or more lines are too long
@@ -0,0 +1,47 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { FC } from 'react';
import { makeStyles } from '@material-ui/core';
const useStyles = makeStyles({
svg: {
width: 'auto',
height: 28,
},
path: {
fill: '#7df3e1',
},
});
const LogoIcon: FC<{}> = () => {
const classes = useStyles();
return (
<svg
className={classes.svg}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 337.46 428.5"
>
<path
className={classes.path}
d="M303,166.05a80.69,80.69,0,0,0,13.45-10.37c.79-.77,1.55-1.53,2.3-2.3a83.12,83.12,0,0,0,7.93-9.38A63.69,63.69,0,0,0,333,133.23a48.58,48.58,0,0,0,4.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56,0,78.3,115.23,0,190.25l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.69,19.16-18.36,25.52-42.12,13.7-61.87a49.22,49.22,0,0,0-6.8-8.87A89.17,89.17,0,0,0,259,178.29h.15a85.08,85.08,0,0,0,31-5.79A80.88,80.88,0,0,0,303,166.05ZM202.45,225.86c-19.32,18.51-50.4,21.23-75.7,5.9L51.61,186.15l67.45-64.64,76.41,46.38C223,184.58,221.49,207.61,202.45,225.86Zm8.93-82.22-70.65-42.89L205.14,39,274.51,81.1c25.94,15.72,29.31,37,10.55,55A60.69,60.69,0,0,1,211.38,143.64Zm29.86,190c-19.57,18.75-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,282.52v24.67L108.6,373.1a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A87.27,87.27,0,0,1,241.24,333.68Zm0-39c-19.57,18.75-46.17,29.08-74.88,29.08a123.81,123.81,0,0,1-64.1-18.19L0,243.53v24.68l108.6,65.91a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.81,66.42-25.69,12.88-12.34,20-27.13,19.68-41.5v-1.78A87.27,87.27,0,0,1,241.24,294.7Zm0-39c-19.57,18.76-46.17,29.09-74.88,29.09a123.81,123.81,0,0,1-64.1-18.19L0,204.55v24.68l108.6,65.91a111.59,111.59,0,0,0,57.76,16.41c24.92,0,48.8-8.8,66.42-25.68,12.88-12.35,20-27.13,19.68-41.5v-1.82A86.09,86.09,0,0,1,241.24,255.71Zm83.7,25.74a94.15,94.15,0,0,1-60.2,25.86h0V334a81.6,81.6,0,0,0,51.74-22.37c14-13.38,21.14-28.11,21-42.64v-2.19A94.92,94.92,0,0,1,324.94,281.45Zm-83.7,91.21c-19.57,18.76-46.17,29.09-74.88,29.09a123.73,123.73,0,0,1-64.1-18.2L0,321.5v24.68l108.6,65.9a111.6,111.6,0,0,0,57.76,16.42c24.92,0,48.8-8.8,66.42-25.69,12.88-12.34,20-27.13,19.68-41.49v-1.79A86.29,86.29,0,0,1,241.24,372.66ZM327,162.45c-.68.69-1.35,1.38-2.05,2.06a94.37,94.37,0,0,1-10.64,8.65,91.35,91.35,0,0,1-11.6,7,94.53,94.53,0,0,1-26.24,8.71,97.69,97.69,0,0,1-14.16,1.57c.5,1.61.9,3.25,1.25,4.9a53.27,53.27,0,0,1,1.14,12V217h.05a84.41,84.41,0,0,0,25.35-5.55,81,81,0,0,0,26.39-16.82c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,172.17a48.55,48.55,0,0,0,4.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08,1.54-2.25,3.09A96.73,96.73,0,0,1,327,162.45Zm0,77.92c-.69.7-1.31,1.41-2,2.1a94.2,94.2,0,0,1-60.2,25.86h0l0,26.67h0a81.6,81.6,0,0,0,51.74-22.37A73.51,73.51,0,0,0,333,250.13a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74,1.07-1.46,2.15-2.27,3.21A95.68,95.68,0,0,1,327,240.37Zm0-39c-.69.7-1.31,1.41-2,2.1a93.18,93.18,0,0,1-10.63,8.65,91.63,91.63,0,0,1-11.63,7,95.47,95.47,0,0,1-37.94,10.18h0V256h0a81.65,81.65,0,0,0,51.74-22.37c.8-.77,1.5-1.56,2.26-2.34a82.08,82.08,0,0,0,7.93-9.38A63.76,63.76,0,0,0,333,211.15a48.56,48.56,0,0,0,4.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74,1.08-1.46,2.16-2.27,3.22A95.68,95.68,0,0,1,327,201.39Z"
/>
</svg>
);
};
export default LogoIcon;
+7 -21
View File
@@ -16,12 +16,13 @@
import React, { FC, useContext } from 'react';
import PropTypes from 'prop-types';
import { Link, makeStyles, Typography } from '@material-ui/core';
import { Link, makeStyles } from '@material-ui/core';
import HomeIcon from '@material-ui/icons/Home';
import ExploreIcon from '@material-ui/icons/Explore';
import CreateComponentIcon from '@material-ui/icons/AddCircleOutline';
import AccountTreeIcon from '@material-ui/icons/AccountTree';
import LogoFull from './LogoFull';
import LogoIcon from './LogoIcon';
import {
Sidebar,
SidebarPage,
@@ -44,21 +45,9 @@ const useSidebarLogoStyles = makeStyles({
alignItems: 'center',
marginBottom: -14,
},
logoContainer: {
link: {
width: sidebarConfig.drawerWidthClosed,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: sidebarConfig.logoHeight,
fontWeight: 'bold',
marginLeft: 20,
whiteSpace: 'nowrap',
color: '#fff',
},
titleDot: {
color: '#68c5b5',
marginLeft: 24,
},
});
@@ -68,11 +57,8 @@ const SidebarLogo: FC<{}> = () => {
return (
<div className={classes.root}>
<Link href="/" underline="none">
<Typography variant="h6" color="inherit" className={classes.title}>
{isOpen ? 'Backstage' : 'B'}
<span className={classes.titleDot}>.</span>
</Typography>
<Link href="/" underline="none" className={classes.link}>
{isOpen ? <LogoFull /> : <LogoIcon />}
</Link>
</div>
);
+1 -1
View File
@@ -17,6 +17,6 @@
import { createRouter } from '@backstage/plugin-sentry-backend';
import { Logger } from 'winston';
export default async function(logger: Logger) {
export default async function (logger: Logger) {
return await createRouter(logger);
}
@@ -62,7 +62,7 @@ async function buildApp(appDir: string) {
await Task.forItem('executing', cmd, async () => {
process.chdir(appDir);
await exec(cmd).catch((error) => {
await exec(cmd).catch(error => {
process.stdout.write(error.stderr);
process.stdout.write(error.stdout);
throw new Error(`Could not execute command ${chalk.cyan(cmd)}`);
@@ -81,7 +81,7 @@ export async function moveApp(
id: string,
) {
await Task.forItem('moving', id, async () => {
await fs.move(tempDir, destination).catch((error) => {
await fs.move(tempDir, destination).catch(error => {
throw new Error(
`Failed to move app from ${tempDir} to ${destination}: ${error.message}`,
);
@@ -107,7 +107,7 @@ export async function addPluginDependencyToApp(
packageFileJson.dependencies = sortObjectByKeys(dependencies);
const newContents = `${JSON.stringify(packageFileJson, null, 2)}\n`;
await fs.writeFile(packageFile, newContents, 'utf-8').catch((error) => {
await fs.writeFile(packageFile, newContents, 'utf-8').catch(error => {
throw new Error(
`Failed to add plugin as dependency to app: ${packageFile}: ${error.message}`,
);
@@ -119,14 +119,14 @@ export async function addPluginToApp(rootDir: string, pluginName: string) {
const pluginPackage = `@backstage/plugin-${pluginName}`;
const pluginNameCapitalized = pluginName
.split('-')
.map((name) => capitalize(name))
.map(name => capitalize(name))
.join('');
const pluginExport = `export { plugin as ${pluginNameCapitalized} } from '${pluginPackage}';`;
const pluginsFilePath = 'packages/app/src/plugins.ts';
const pluginsFile = resolvePath(rootDir, pluginsFilePath);
await Task.forItem('processing', pluginsFilePath, async () => {
await addExportStatement(pluginsFile, pluginExport).catch((error) => {
await addExportStatement(pluginsFile, pluginExport).catch(error => {
throw new Error(
`Failed to import plugin in app: ${pluginsFile}: ${error.message}`,
);
@@ -148,7 +148,7 @@ async function buildPlugin(pluginFolder: string) {
await Task.forItem('executing', command, async () => {
process.chdir(pluginFolder);
await exec(command).catch((error) => {
await exec(command).catch(error => {
process.stdout.write(error.stderr);
process.stdout.write(error.stdout);
throw new Error(`Could not execute command ${chalk.cyan(command)}`);
@@ -163,7 +163,7 @@ export async function movePlugin(
id: string,
) {
await Task.forItem('moving', id, async () => {
await fs.move(tempDir, destination).catch((error) => {
await fs.move(tempDir, destination).catch(error => {
throw new Error(
`Failed to move plugin from ${tempDir} to ${destination}: ${error.message}`,
);
+1 -1
View File
@@ -48,7 +48,7 @@ export async function buildBundle(options: BuildOptions) {
const previousFileSizes = await measureFileSizesBeforeBuild(paths.targetDist);
await fs.emptyDir(paths.targetDist);
const { stats } = await build(compiler, isCi).catch((error) => {
const { stats } = await build(compiler, isCi).catch(error => {
console.log(chalk.red('Failed to compile.\n'));
throw new Error(`Failed to compile.\n${error.message || error}`);
});
+6 -6
View File
@@ -73,7 +73,7 @@ export async function templatingTask(
destinationDir: string,
context: any,
) {
const files = await recursive(templateDir).catch((error) => {
const files = await recursive(templateDir).catch(error => {
throw new Error(`Failed to read template directory: ${error.message}`);
});
@@ -89,7 +89,7 @@ export async function templatingTask(
const compiled = handlebars.compile(template.toString());
const contents = compiled({ name: basename(destination), ...context });
await fs.writeFile(destination, contents).catch((error) => {
await fs.writeFile(destination, contents).catch(error => {
throw new Error(
`Failed to create file: ${destination}: ${error.message}`,
);
@@ -97,7 +97,7 @@ export async function templatingTask(
});
} else {
await Task.forItem('copying', basename(file), async () => {
await fs.copyFile(file, destinationFile).catch((error) => {
await fs.copyFile(file, destinationFile).catch(error => {
const destination = destinationFile;
throw new Error(
`Failed to copy file to ${destination} : ${error.message}`,
@@ -145,7 +145,7 @@ export async function installWithLocalDeps(dir: string) {
await fs
.writeJSON(pkgJsonPath, pkgJson, { encoding: 'utf8', spaces: 2 })
.catch((error) => {
.catch(error => {
throw new Error(
`Failed to add resolutions to package.json: ${error.message}`,
);
@@ -157,7 +157,7 @@ export async function installWithLocalDeps(dir: string) {
}
await Task.forItem('executing', 'yarn install', async () => {
await exec('yarn install', { cwd: dir }).catch((error) => {
await exec('yarn install', { cwd: dir }).catch(error => {
process.stdout.write(error.stderr);
process.stdout.write(error.stdout);
throw new Error(
@@ -193,7 +193,7 @@ export async function installWithLocalDeps(dir: string) {
await fs
.writeJSON(depJsonPath, depJson, { encoding: 'utf8', spaces: 2 })
.catch((error) => {
.catch(error => {
throw new Error(
`Failed to add resolutions to package.json: ${error.message}`,
);
@@ -4,7 +4,7 @@ import React, { FC } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import * as plugins from './plugins';
const useStyles = makeStyles((theme) => ({
const useStyles = makeStyles(theme => ({
'@global': {
html: {
height: '100%',
+1 -1
View File
@@ -53,7 +53,7 @@ export function withApis<T>(apis: TypesToApiRefs<T>) {
return function withApisWrapper<P extends T>(
WrappedComponent: React.ComponentType<P>,
) {
const Hoc: FC<Omit<P, keyof T>> = (props) => {
const Hoc: FC<Omit<P, keyof T>> = props => {
const apiHolder = useContext(Context);
if (!apiHolder) {
@@ -33,7 +33,7 @@ export class PublishSubject<T>
private isClosed = false;
private terminatingError?: Error;
private readonly observable = new ObservableImpl<T>((subscriber) => {
private readonly observable = new ObservableImpl<T>(subscriber => {
if (this.isClosed) {
if (this.terminatingError) {
subscriber.error(this.terminatingError);
@@ -61,7 +61,7 @@ export class PublishSubject<T>
if (this.isClosed) {
throw new Error('PublishSubject is closed');
}
this.subscribers.forEach((subscriber) => subscriber.next(value));
this.subscribers.forEach(subscriber => subscriber.next(value));
}
error(error: Error) {
@@ -70,7 +70,7 @@ export class PublishSubject<T>
}
this.isClosed = true;
this.terminatingError = error;
this.subscribers.forEach((subscriber) => subscriber.error(error));
this.subscribers.forEach(subscriber => subscriber.error(error));
}
complete() {
@@ -78,7 +78,7 @@ export class PublishSubject<T>
throw new Error('PublishSubject is closed');
}
this.isClosed = true;
this.subscribers.forEach((subscriber) => subscriber.complete());
this.subscribers.forEach(subscriber => subscriber.complete());
}
subscribe(observer: ZenObservable.Observer<T>): ZenObservable.Subscription;
@@ -126,7 +126,7 @@ export class BehaviorSubject<T>
this.currentValue = value;
}
private readonly observable = new ObservableImpl<T>((subscriber) => {
private readonly observable = new ObservableImpl<T>(subscriber => {
if (this.isClosed) {
if (this.terminatingError) {
subscriber.error(this.terminatingError);
@@ -157,7 +157,7 @@ export class BehaviorSubject<T>
throw new Error('BehaviorSubject is closed');
}
this.currentValue = value;
this.subscribers.forEach((subscriber) => subscriber.next(value));
this.subscribers.forEach(subscriber => subscriber.next(value));
}
error(error: Error) {
@@ -166,7 +166,7 @@ export class BehaviorSubject<T>
}
this.isClosed = true;
this.terminatingError = error;
this.subscribers.forEach((subscriber) => subscriber.error(error));
this.subscribers.forEach(subscriber => subscriber.error(error));
}
complete() {
@@ -174,7 +174,7 @@ export class BehaviorSubject<T>
throw new Error('BehaviorSubject is closed');
}
this.isClosed = true;
this.subscribers.forEach((subscriber) => subscriber.complete());
this.subscribers.forEach(subscriber => subscriber.complete());
}
subscribe(observer: ZenObservable.Observer<T>): ZenObservable.Subscription;
@@ -27,20 +27,20 @@ function resolveTheme(
themes: AppTheme[],
) {
if (themeId !== undefined) {
const selectedTheme = themes.find((theme) => theme.id === themeId);
const selectedTheme = themes.find(theme => theme.id === themeId);
if (selectedTheme) {
return selectedTheme;
}
}
if (shouldPreferDark) {
const darkTheme = themes.find((theme) => theme.variant === 'dark');
const darkTheme = themes.find(theme => theme.variant === 'dark');
if (darkTheme) {
return darkTheme;
}
}
const lightTheme = themes.find((theme) => theme.variant === 'light');
const lightTheme = themes.find(theme => theme.variant === 'light');
if (lightTheme) {
return lightTheme;
}
@@ -147,7 +147,7 @@ describe('FeatureFlags', () => {
it('should get the correct values', () => {
const getByName = (name: string) =>
featureFlags.getRegisteredFlags().find((flag) => flag.name === name);
featureFlags.getRegisteredFlags().find(flag => flag.name === name);
expect(getByName('registered-flag-0')).toBeUndefined();
expect(getByName('registered-flag-1')).toEqual({
+3 -3
View File
@@ -127,12 +127,12 @@ export interface FeatureFlagsRegistryItem {
export class FeatureFlagsRegistry extends Array<FeatureFlagsRegistryItem> {
static from(entries: FeatureFlagsRegistryItem[]) {
Array.from(entries).forEach((entry) => validateFlagName(entry.name));
Array.from(entries).forEach(entry => validateFlagName(entry.name));
return new FeatureFlagsRegistry(...entries);
}
push(...entries: FeatureFlagsRegistryItem[]): number {
Array.from(entries).forEach((entry) => validateFlagName(entry.name));
Array.from(entries).forEach(entry => validateFlagName(entry.name));
return super.push(...entries);
}
@@ -143,7 +143,7 @@ export class FeatureFlagsRegistry extends Array<FeatureFlagsRegistryItem> {
)[]
): FeatureFlagsRegistryItem[] {
const _concat = super.concat(...entries);
Array.from(_concat).forEach((entry) => validateFlagName(entry.name));
Array.from(_concat).forEach(entry => validateFlagName(entry.name));
return _concat;
}
@@ -31,7 +31,7 @@ const defaultProps = {
showLineNumbers: false,
};
const CodeSnippet: FC<Props> = (props) => {
const CodeSnippet: FC<Props> = props => {
const { text, language, showLineNumbers } = {
...defaultProps,
...props,
@@ -25,7 +25,7 @@ describe('<HorizontalScrollGrid />', () => {
jest.spyOn(window.performance, 'now').mockReturnValue(5);
jest
.spyOn(window, 'requestAnimationFrame')
.mockImplementation((cb) => cb(20));
.mockImplementation(cb => cb(20));
});
afterEach(() => {
@@ -25,7 +25,7 @@ import {
import React, { FC, useState } from 'react';
import { PendingAuthRequest } from '../../api';
const useItemStyles = makeStyles<Theme>((theme) => ({
const useItemStyles = makeStyles<Theme>(theme => ({
root: {
paddingLeft: theme.spacing(3),
},
@@ -29,7 +29,7 @@ import { useObservable } from 'react-use';
import LoginRequestListItem from './LoginRequestListItem';
import { useApi, oauthRequestApiRef } from '../../api';
const useStyles = makeStyles<Theme>((theme) => ({
const useStyles = makeStyles<Theme>(theme => ({
dialog: {
paddingTop: theme.spacing(1),
},
@@ -53,7 +53,7 @@ export const OAuthRequestDialog: FC<OAuthRequestDialogProps> = () => {
);
const handleRejectAll = () => {
requests.forEach((request) => request.reject());
requests.forEach(request => request.reject());
};
return (
@@ -69,7 +69,7 @@ export const OAuthRequestDialog: FC<OAuthRequestDialogProps> = () => {
<DialogContent classes={{ root: classes.contentList }}>
<List>
{requests.map((request) => (
{requests.map(request => (
<LoginRequestListItem
key={request.provider.title}
request={request}
@@ -19,7 +19,7 @@ import { BackstageTheme } from '@backstage/theme';
import classNames from 'classnames';
import React, { FC } from 'react';
const useStyles = makeStyles<BackstageTheme>((theme) => ({
const useStyles = makeStyles<BackstageTheme>(theme => ({
status: {
fontWeight: 500,
'&::before': {
@@ -63,26 +63,26 @@ const useStyles = makeStyles<BackstageTheme>((theme) => ({
},
}));
export const StatusOK: FC<{}> = (props) => {
export const StatusOK: FC<{}> = props => {
const classes = useStyles(props);
return <span className={classNames(classes.status, classes.ok)} {...props} />;
};
export const StatusWarning: FC<{}> = (props) => {
export const StatusWarning: FC<{}> = props => {
const classes = useStyles(props);
return (
<span className={classNames(classes.status, classes.warning)} {...props} />
);
};
export const StatusError: FC<{}> = (props) => {
export const StatusError: FC<{}> = props => {
const classes = useStyles(props);
return (
<span className={classNames(classes.status, classes.error)} {...props} />
);
};
export const StatusPending: FC<{}> = (props) => {
export const StatusPending: FC<{}> = props => {
const classes = useStyles(props);
return (
<span
@@ -93,7 +93,7 @@ export const StatusPending: FC<{}> = (props) => {
);
};
export const StatusRunning: FC<{}> = (props) => {
export const StatusRunning: FC<{}> = props => {
const classes = useStyles(props);
return (
<span
@@ -104,7 +104,7 @@ export const StatusRunning: FC<{}> = (props) => {
);
};
export const StatusAborted: FC<{}> = (props) => {
export const StatusAborted: FC<{}> = props => {
const classes = useStyles(props);
return (
<span
@@ -36,7 +36,7 @@ describe('<StructuredMetadataTable />', () => {
<StructuredMetadataTable metadata={metadata} />,
);
const keys = Object.keys(metadata);
keys.forEach((value) => {
keys.forEach(value => {
expect(getByText(startCase(value))).toBeInTheDocument();
expect(getByText(metadata[value])).toBeInTheDocument();
});
@@ -49,7 +49,7 @@ describe('<StructuredMetadataTable />', () => {
);
const keys = Object.keys(metadata);
keys.forEach((value) => {
keys.forEach(value => {
expect(getByText(startCase(value))).toBeInTheDocument();
expect(getByText(metadata[value].toString())).toBeInTheDocument();
});
@@ -61,10 +61,10 @@ describe('<StructuredMetadataTable />', () => {
<StructuredMetadataTable metadata={metadata} />,
);
const keys = Object.keys(metadata);
keys.forEach((value) => {
keys.forEach(value => {
expect(getByText(startCase(value))).toBeInTheDocument();
});
metadata.arrayField.forEach((value) => {
metadata.arrayField.forEach(value => {
expect(getByText(value)).toBeInTheDocument();
});
});
@@ -85,7 +85,7 @@ describe('<StructuredMetadataTable />', () => {
);
const keys = Object.keys(metadata.config);
keys.forEach((value) => {
keys.forEach(value => {
expect(
getByText(startCase(value), { exact: false }),
).toBeInTheDocument();
@@ -26,7 +26,7 @@ interface IErrorPageProps {
statusMessage: string;
}
const useStyles = makeStyles<BackstageTheme>((theme) => ({
const useStyles = makeStyles<BackstageTheme>(theme => ({
container: {
padding: theme.spacing(8),
},
+5 -5
View File
@@ -26,7 +26,7 @@ import {
} from './config';
import { SidebarDivider } from './Items';
const useStyles = makeStyles<BackstageTheme>((theme) => ({
const useStyles = makeStyles<BackstageTheme>(theme => ({
introCard: {
color: '#b5b5b5',
// XXX (@koroeskohr): should I be using a Mui theme variable?
@@ -74,7 +74,7 @@ type IntroCardProps = {
onClose: () => void;
};
export const IntroCard: FC<IntroCardProps> = (props) => {
export const IntroCard: FC<IntroCardProps> = props => {
const classes = useStyles();
const { text, onClose } = props;
const handleClose = () => onClose();
@@ -109,7 +109,7 @@ type SidebarIntroCardProps = {
onDismiss: () => void;
};
const SidebarIntroCard: FC<SidebarIntroCardProps> = (props) => {
const SidebarIntroCard: FC<SidebarIntroCardProps> = props => {
const { text, onDismiss } = props;
const [collapsing, setCollapsing] = useState(false);
const startDismissing = () => {
@@ -138,10 +138,10 @@ export const SidebarIntro: FC = () => {
});
const dismissStarred = () => {
setDismissedIntro((state) => ({ ...state, starredItemsDismissed: true }));
setDismissedIntro(state => ({ ...state, starredItemsDismissed: true }));
};
const dismissRecentlyViewed = () => {
setDismissedIntro((state) => ({
setDismissedIntro(state => ({
...state,
recentlyViewedItemsDismissed: true,
}));
+5 -5
View File
@@ -29,7 +29,7 @@ import { NavLink } from 'react-router-dom';
import { sidebarConfig, SidebarContext } from './config';
import { IconComponent } from '../../icons';
const useStyles = makeStyles<Theme>((theme) => {
const useStyles = makeStyles<Theme>(theme => {
const {
selectedIndicatorWidth,
drawerWidthClosed,
@@ -139,7 +139,7 @@ export const SidebarItem: FC<SidebarItemProps> = ({
<NavLink
className={clsx(classes.root, classes.closed)}
activeClassName={classes.selected}
isActive={(match) => Boolean(match && !disableSelected)}
isActive={match => Boolean(match && !disableSelected)}
exact
to={to}
onClick={onClick}
@@ -153,7 +153,7 @@ export const SidebarItem: FC<SidebarItemProps> = ({
<NavLink
className={clsx(classes.root, classes.open)}
activeClassName={classes.selected}
isActive={(match) => Boolean(match && !disableSelected)}
isActive={match => Boolean(match && !disableSelected)}
exact
to={to}
onClick={onClick}
@@ -175,11 +175,11 @@ type SidebarSearchFieldProps = {
onSearch: (input: string) => void;
};
export const SidebarSearchField: FC<SidebarSearchFieldProps> = (props) => {
export const SidebarSearchField: FC<SidebarSearchFieldProps> = props => {
const [input, setInput] = useState('');
const classes = useStyles();
const handleEnter: KeyboardEventHandler = (ev) => {
const handleEnter: KeyboardEventHandler = ev => {
if (ev.key === 'Enter') {
props.onSearch(input);
}
+1 -1
View File
@@ -44,7 +44,7 @@ export const SidebarPinStateContext = createContext<SidebarPinStateContextType>(
},
);
export const SidebarPage: FC<{}> = (props) => {
export const SidebarPage: FC<{}> = props => {
const [isPinned, setIsPinned] = useState(LocalStorage.getSidebarPinState());
useEffect(() => {
+1 -1
View File
@@ -12,7 +12,7 @@ module.exports = {
'@storybook/addon-storysource',
'storybook-dark-mode/register',
],
webpackFinal: async (config) => {
webpackFinal: async config => {
const coreSrc = path.resolve(__dirname, '../../core/src');
// Mirror config in packages/cli/src/lib/bundler
+1 -1
View File
@@ -22,7 +22,7 @@ const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 3003;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch((err) => {
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
+4 -4
View File
@@ -20,7 +20,7 @@ const ARTIFICIAL_TIMEOUT = 800;
let inMemoryStore = [...mock];
export const MockComponentFactory: ComponentFactory = {
getAllComponents(): Promise<Component[]> {
return new Promise((resolve) =>
return new Promise(resolve =>
setTimeout(() => resolve(inMemoryStore), ARTIFICIAL_TIMEOUT),
);
},
@@ -28,7 +28,7 @@ export const MockComponentFactory: ComponentFactory = {
return new Promise((resolve, reject) =>
setTimeout(() => {
const mockComponent = inMemoryStore.find(
(component) => component.name === name,
component => component.name === name,
);
if (mockComponent) return resolve(mockComponent);
return reject({ code: 'Component not found!' });
@@ -36,10 +36,10 @@ export const MockComponentFactory: ComponentFactory = {
);
},
removeComponentByName(name: string): Promise<boolean> {
return new Promise((resolve) =>
return new Promise(resolve =>
setTimeout(() => {
inMemoryStore = inMemoryStore.filter(
(component) => component.name !== name,
component => component.name !== name,
);
resolve(true);
}, ARTIFICIAL_TIMEOUT),
@@ -80,7 +80,7 @@ const Settings = () => {
value={token}
fullWidth
variant="outlined"
onChange={(e) => setToken(e.target.value)}
onChange={e => setToken(e.target.value)}
/>
</ListItem>
<ListItem>
@@ -90,7 +90,7 @@ const Settings = () => {
label="Owner"
variant="outlined"
value={owner}
onChange={(e) => setOwner(e.target.value)}
onChange={e => setOwner(e.target.value)}
/>
</ListItem>
<ListItem>
@@ -100,7 +100,7 @@ const Settings = () => {
fullWidth
variant="outlined"
value={repo}
onChange={(e) => setRepo(e.target.value)}
onChange={e => setRepo(e.target.value)}
/>
</ListItem>
<ListItem>
@@ -35,7 +35,7 @@ const BuildName: FC<{ build?: BuildWithSteps }> = ({ build }) => (
</IconLink>
</Box>
);
const useStyles = makeStyles((theme) => ({
const useStyles = makeStyles(theme => ({
neutral: {},
failed: {
position: 'relative',
@@ -50,8 +50,8 @@ export const ActionOutput: FC<{
const [messages, setMessages] = useState([]);
useEffect(() => {
fetch(url)
.then((res) => res.json())
.then((actionOutput) => {
.then(res => res.json())
.then(actionOutput => {
if (typeof actionOutput !== 'undefined') {
setMessages(
actionOutput.map(({ message }: { message: string }) => message),
@@ -26,7 +26,7 @@ export const useAsyncPolling = (
while (isPolling.current === true) {
await pollingFn();
await new Promise((resolve) => setTimeout(resolve, interval));
await new Promise(resolve => setTimeout(resolve, interval));
}
};
+1 -1
View File
@@ -29,7 +29,7 @@ export function useSettings() {
if (
stateFromStorage &&
Object.keys(stateFromStorage).some(
(k) => (settings as any)[k] !== stateFromStorage[k],
k => (settings as any)[k] !== stateFromStorage[k],
)
)
dispatch({
+1 -1
View File
@@ -22,7 +22,7 @@ const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 3003;
const enableCors = yn(process.env.PLUGIN_CORS, { default: false });
const logger = getRootLogger();
startStandaloneServer({ port, enableCors, logger }).catch((err) => {
startStandaloneServer({ port, enableCors, logger }).catch(err => {
logger.error(err);
process.exit(1);
});
@@ -49,7 +49,7 @@ describe('AuditView', () => {
apis = ApiRegistry.from([
[lighthouseApiRef, new LighthouseRestApi('https://lighthouse')],
]);
id = websiteResponse.audits.find((a) => a.status === 'COMPLETED')
id = websiteResponse.audits.find(a => a.status === 'COMPLETED')
?.id as string;
useParams.mockReturnValue({ id });
});
@@ -101,7 +101,7 @@ describe('AuditView', () => {
await rendered.findByTestId('audit-sidebar');
websiteResponse.audits.forEach((a) => {
websiteResponse.audits.forEach(a => {
expect(
rendered.queryByText(formatTime(a.timeCreated)),
).toBeInTheDocument();
@@ -119,14 +119,14 @@ describe('AuditView', () => {
await rendered.findByTestId('audit-sidebar');
const audit = websiteResponse.audits.find((a) => a.id === id) as Audit;
const audit = websiteResponse.audits.find(a => a.id === id) as Audit;
const auditElement = rendered.getByText(formatTime(audit.timeCreated));
expect(auditElement.parentElement?.parentElement?.className).toContain(
'selected',
);
const notSelectedAudit = websiteResponse.audits.find(
(a) => a.id !== id,
a => a.id !== id,
) as Audit;
const notSelectedAuditElement = rendered.getByText(
formatTime(notSelectedAudit.timeCreated),
@@ -147,7 +147,7 @@ describe('AuditView', () => {
await rendered.findByTestId('audit-sidebar');
websiteResponse.audits.forEach((a) => {
websiteResponse.audits.forEach(a => {
expect(
rendered.getByText(formatTime(a.timeCreated)).parentElement
?.parentElement,
@@ -186,7 +186,7 @@ describe('AuditView', () => {
describe.skip('when a loading audit is accessed', () => {
it('shows a loading view', async () => {
id = websiteResponse.audits.find((a) => a.status === 'RUNNING')
id = websiteResponse.audits.find(a => a.status === 'RUNNING')
?.id as string;
useParams.mockReturnValueOnce({ id });
@@ -206,7 +206,7 @@ describe('AuditView', () => {
describe.skip('when a failed audit is accessed', () => {
it('shows an error message', async () => {
id = websiteResponse.audits.find((a) => a.status === 'FAILED')
id = websiteResponse.audits.find(a => a.status === 'FAILED')
?.id as string;
useParams.mockReturnValueOnce({ id });
@@ -165,7 +165,7 @@ describe('CreateAudit', () => {
fireEvent.click(rendered.getByText(/Create Audit/));
await wait(() => expect(rendered.getByLabelText(/URL/)).toBeEnabled());
await new Promise((r) => setTimeout(r, 0));
await new Promise(r => setTimeout(r, 0));
expect(errorApi.post).toHaveBeenCalledWith(expect.any(Error));
});
@@ -28,7 +28,7 @@ import { BackstageTheme } from '@backstage/theme';
import { Progress } from '@backstage/core';
import { ComponentIdValidators } from '../../util/validate';
const useStyles = makeStyles<BackstageTheme>((theme) => ({
const useStyles = makeStyles<BackstageTheme>(theme => ({
form: {
alignItems: 'flex-start',
display: 'flex',
+1 -1
View File
@@ -1,3 +1,3 @@
# sentry-backend
Simple plugin forwarding requests to [Sentry](https://sentry.io) API.
Simple plugin forwarding requests to [Sentry](https://sentry.io) API.
@@ -22,7 +22,7 @@ import { BackstageTheme } from '@backstage/theme';
function stripText(text: string, maxLength: number) {
return text.length > maxLength ? `${text.substr(0, maxLength)}...` : text;
}
const useStyles = makeStyles<BackstageTheme>((theme) => ({
const useStyles = makeStyles<BackstageTheme>(theme => ({
root: {
minWidth: 260,
position: 'relative',
@@ -24,16 +24,16 @@ import { ErrorGraph } from '../ErrorGraph/ErrorGraph';
const columns: TableColumn[] = [
{
title: 'Error',
render: (data) => <ErrorCell sentryIssue={data as SentryIssue} />,
render: data => <ErrorCell sentryIssue={data as SentryIssue} />,
},
{
title: 'Graph',
render: (data) => <ErrorGraph sentryIssue={data as SentryIssue} />,
render: data => <ErrorGraph sentryIssue={data as SentryIssue} />,
},
{
title: 'First seen',
field: 'firstSeen',
render: (data) => {
render: data => {
const { firstSeen } = data as SentryIssue;
return format(firstSeen);
},
@@ -41,7 +41,7 @@ const columns: TableColumn[] = [
{
title: 'Last seen',
field: 'lastSeen',
render: (data) => {
render: data => {
const { lastSeen } = data as SentryIssue;
return format(lastSeen);
},
+1 -1
View File
@@ -33,7 +33,7 @@ function getMockIssues(number: number): SentryIssue[] {
}
export class MockSentryApi implements SentryApi {
fetchIssues(): Promise<SentryIssue[]> {
return new Promise((resolve) => {
return new Promise(resolve => {
setTimeout(() => resolve(getMockIssues(14)), 800);
});
}
@@ -105,14 +105,14 @@ export default class Radar extends React.Component {
static adjustEntries(entries, activeEntry, quadrants, rings, radius) {
let seed = 42;
entries.forEach((entry, idx) => {
const quadrant = quadrants.find((q) => {
const quadrant = quadrants.find(q => {
const match =
typeof entry.quadrant === 'object'
? entry.quadrant.id
: entry.quadrant;
return q.id === match;
});
const ring = rings.find((r) => {
const ring = rings.find(r => {
const match =
typeof entry.ring === 'object' ? entry.ring.id : entry.ring;
return r.id === match;
@@ -190,7 +190,7 @@ export default class Radar extends React.Component {
return (
<svg
ref={(node) => {
ref={node => {
this.node = node;
}}
width={width}
@@ -205,7 +205,7 @@ export default class Radar extends React.Component {
quadrants={quadrants}
rings={rings}
activeEntry={activeEntry}
onEntryMouseEnter={(entry) => this._setActiveEntry(entry)}
onEntryMouseEnter={entry => this._setActiveEntry(entry)}
onEntryMouseLeave={() => this._clearActiveEntry()}
/>
</svg>
@@ -49,16 +49,16 @@ class RadarBubble extends React.PureComponent {
this._updatePosition();
}
_setRect = (rect) => {
_setRect = rect => {
this.rect = rect;
};
_setNode = (node) => {
_setNode = node => {
this.node = node;
};
_setText = (text) => {
_setText = text => {
this.text = text;
};
_setPath = (path) => {
_setPath = path => {
this.path = path;
};
@@ -84,7 +84,7 @@ class RadarGrid extends React.PureComponent {
/>,
];
const ringNodes = rings.map((r) => r.outerRadius).map(makeRingNode);
const ringNodes = rings.map(r => r.outerRadius).map(makeRingNode);
return axisNodes.concat(ringNodes);
}
@@ -88,7 +88,7 @@ class RadarLegend extends React.PureComponent {
<div className={classes.quadrant}>
<h2 className={classes.quadrantHeading}>{quadrant.name}</h2>
<div className={classes.rings}>
{rings.map((ring) =>
{rings.map(ring =>
RadarLegend._renderRing(
ring,
RadarLegend._getSegment(segments, quadrant, ring),
@@ -117,7 +117,7 @@ class RadarLegend extends React.PureComponent {
<p>(empty)</p>
) : (
<ol className={classes.ringList}>
{entries.map((entry) => {
{entries.map(entry => {
let node = <span className={classes.entry}>{entry.title}</span>;
if (entry.url) {
@@ -175,7 +175,7 @@ class RadarLegend extends React.PureComponent {
return (
<g>
{quadrants.map((quadrant) =>
{quadrants.map(quadrant =>
RadarLegend._renderQuadrant(
segments,
quadrant,
@@ -46,16 +46,16 @@ export default class RadarPlot extends React.PureComponent {
rings={rings}
entries={entries}
onEntryMouseEnter={
onEntryMouseEnter && ((entry) => onEntryMouseEnter(entry))
onEntryMouseEnter && (entry => onEntryMouseEnter(entry))
}
onEntryMouseLeave={
onEntryMouseLeave && ((entry) => onEntryMouseLeave(entry))
onEntryMouseLeave && (entry => onEntryMouseLeave(entry))
}
/>
<g transform={`translate(${width / 2}, ${height / 2})`}>
<RadarGrid radius={radius} rings={rings} />
<RadarFooter x={-0.5 * width} y={0.5 * height} />
{entries.map((entry) => (
{entries.map(entry => (
<RadarEntry
key={entry.id}
x={entry.x}