From f72d97dc171424785f9f7ae694c0c88241f4c52c Mon Sep 17 00:00:00 2001 From: Adil Alimbetov Date: Wed, 27 May 2020 14:13:41 +0600 Subject: [PATCH] Sidebar logo update (#814) * Testing logo ux * Updated logo on sidebar * removed unused vars * adjusted types on icon components --- CONTRIBUTING.md | 1 - packages/app/src/components/Root/LogoFull.tsx | 46 ++++++++++++++++++ packages/app/src/components/Root/LogoIcon.tsx | 47 +++++++++++++++++++ packages/app/src/components/Root/Root.tsx | 28 +++-------- packages/backend/src/plugins/sentry.ts | 2 +- .../cli/src/commands/create-app/createApp.ts | 4 +- .../commands/create-plugin/createPlugin.ts | 10 ++-- packages/cli/src/lib/bundler/bundle.ts | 2 +- packages/cli/src/lib/tasks.ts | 12 ++--- .../default-app/packages/app/src/App.tsx | 2 +- packages/core/src/api/apis/ApiProvider.tsx | 2 +- .../api/apis/implementations/lib/subjects.ts | 16 +++---- .../core/src/api/app/AppThemeProvider.tsx | 6 +-- .../core/src/api/app/FeatureFlags.test.tsx | 2 +- packages/core/src/api/app/FeatureFlags.tsx | 6 +-- .../components/CodeSnippet/CodeSnippet.tsx | 2 +- .../HorizontalScrollGrid.test.jsx | 2 +- .../LoginRequestListItem.tsx | 2 +- .../OAuthRequestDialog/OAuthRequestDialog.tsx | 6 +-- .../core/src/components/Status/Status.tsx | 14 +++--- .../StructuredMetadataTable.test.jsx | 10 ++-- .../core/src/layout/ErrorPage/ErrorPage.tsx | 2 +- packages/core/src/layout/Sidebar/Intro.tsx | 10 ++-- packages/core/src/layout/Sidebar/Items.tsx | 10 ++-- packages/core/src/layout/Sidebar/Page.tsx | 2 +- packages/storybook/.storybook/main.js | 2 +- plugins/auth-backend/src/run.ts | 2 +- plugins/catalog/src/data/mock-factory.ts | 8 ++-- .../src/components/Settings/Settings.tsx | 6 +-- .../BuildWithStepsPage/BuildWithStepsPage.tsx | 2 +- .../lib/ActionOutput/ActionOutput.tsx | 4 +- plugins/circleci/src/state/useAsyncPolling.ts | 2 +- plugins/circleci/src/state/useSettings.ts | 2 +- plugins/identity-backend/src/run.ts | 2 +- .../src/components/AuditView/index.test.tsx | 14 +++--- .../src/components/CreateAudit/index.test.tsx | 2 +- .../RegisterComponentForm.tsx | 2 +- plugins/sentry-backend/README.md | 2 +- .../src/components/ErrorCell/ErrorCell.tsx | 2 +- .../SentryIssuesTable/SentryIssuesTable.tsx | 8 ++-- plugins/sentry/src/data/mock-api.ts | 2 +- .../tech-radar/src/components/Radar/Radar.jsx | 8 ++-- .../components/RadarBubble/RadarBubble.jsx | 8 ++-- .../src/components/RadarGrid/RadarGrid.jsx | 2 +- .../components/RadarLegend/RadarLegend.jsx | 6 +-- .../src/components/RadarPlot/RadarPlot.jsx | 6 +-- 46 files changed, 208 insertions(+), 130 deletions(-) create mode 100644 packages/app/src/components/Root/LogoFull.tsx create mode 100644 packages/app/src/components/Root/LogoIcon.tsx diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f4b31a74b2..43c1f0d7b8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 diff --git a/packages/app/src/components/Root/LogoFull.tsx b/packages/app/src/components/Root/LogoFull.tsx new file mode 100644 index 0000000000..d2b1bf1080 --- /dev/null +++ b/packages/app/src/components/Root/LogoFull.tsx @@ -0,0 +1,46 @@ +/* + * 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: 30, + }, + path: { + fill: '#7df3e1', + }, +}); +const LogoFull: FC<{}> = () => { + const classes = useStyles(); + + return ( + + + + ); +}; + +export default LogoFull; diff --git a/packages/app/src/components/Root/LogoIcon.tsx b/packages/app/src/components/Root/LogoIcon.tsx new file mode 100644 index 0000000000..d70be3dd32 --- /dev/null +++ b/packages/app/src/components/Root/LogoIcon.tsx @@ -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 ( + + + + ); +}; + +export default LogoIcon; diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index c26336c18b..3c5ec4ae3a 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -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 (
- - - {isOpen ? 'Backstage' : 'B'} - . - + + {isOpen ? : }
); diff --git a/packages/backend/src/plugins/sentry.ts b/packages/backend/src/plugins/sentry.ts index ddb7ddd540..34506ee3de 100644 --- a/packages/backend/src/plugins/sentry.ts +++ b/packages/backend/src/plugins/sentry.ts @@ -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); } diff --git a/packages/cli/src/commands/create-app/createApp.ts b/packages/cli/src/commands/create-app/createApp.ts index e28cb376b9..a42271435b 100644 --- a/packages/cli/src/commands/create-app/createApp.ts +++ b/packages/cli/src/commands/create-app/createApp.ts @@ -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}`, ); diff --git a/packages/cli/src/commands/create-plugin/createPlugin.ts b/packages/cli/src/commands/create-plugin/createPlugin.ts index 1441b16d05..3a91044500 100644 --- a/packages/cli/src/commands/create-plugin/createPlugin.ts +++ b/packages/cli/src/commands/create-plugin/createPlugin.ts @@ -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}`, ); diff --git a/packages/cli/src/lib/bundler/bundle.ts b/packages/cli/src/lib/bundler/bundle.ts index f24da5b0c8..c7860c0f42 100644 --- a/packages/cli/src/lib/bundler/bundle.ts +++ b/packages/cli/src/lib/bundler/bundle.ts @@ -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}`); }); diff --git a/packages/cli/src/lib/tasks.ts b/packages/cli/src/lib/tasks.ts index 721e1a355b..6b752a36cc 100644 --- a/packages/cli/src/lib/tasks.ts +++ b/packages/cli/src/lib/tasks.ts @@ -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}`, ); diff --git a/packages/cli/templates/default-app/packages/app/src/App.tsx b/packages/cli/templates/default-app/packages/app/src/App.tsx index c32efd2a6b..84bc1b2e7d 100644 --- a/packages/cli/templates/default-app/packages/app/src/App.tsx +++ b/packages/cli/templates/default-app/packages/app/src/App.tsx @@ -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%', diff --git a/packages/core/src/api/apis/ApiProvider.tsx b/packages/core/src/api/apis/ApiProvider.tsx index 46f89cfa0d..1c5abf1c56 100644 --- a/packages/core/src/api/apis/ApiProvider.tsx +++ b/packages/core/src/api/apis/ApiProvider.tsx @@ -53,7 +53,7 @@ export function withApis(apis: TypesToApiRefs) { return function withApisWrapper

( WrappedComponent: React.ComponentType

, ) { - const Hoc: FC> = (props) => { + const Hoc: FC> = props => { const apiHolder = useContext(Context); if (!apiHolder) { diff --git a/packages/core/src/api/apis/implementations/lib/subjects.ts b/packages/core/src/api/apis/implementations/lib/subjects.ts index b33df70a65..5b424b7e55 100644 --- a/packages/core/src/api/apis/implementations/lib/subjects.ts +++ b/packages/core/src/api/apis/implementations/lib/subjects.ts @@ -33,7 +33,7 @@ export class PublishSubject private isClosed = false; private terminatingError?: Error; - private readonly observable = new ObservableImpl((subscriber) => { + private readonly observable = new ObservableImpl(subscriber => { if (this.isClosed) { if (this.terminatingError) { subscriber.error(this.terminatingError); @@ -61,7 +61,7 @@ export class PublishSubject 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 } 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 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): ZenObservable.Subscription; @@ -126,7 +126,7 @@ export class BehaviorSubject this.currentValue = value; } - private readonly observable = new ObservableImpl((subscriber) => { + private readonly observable = new ObservableImpl(subscriber => { if (this.isClosed) { if (this.terminatingError) { subscriber.error(this.terminatingError); @@ -157,7 +157,7 @@ export class BehaviorSubject 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 } 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 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): ZenObservable.Subscription; diff --git a/packages/core/src/api/app/AppThemeProvider.tsx b/packages/core/src/api/app/AppThemeProvider.tsx index 6e68fe9ba0..775d8293ba 100644 --- a/packages/core/src/api/app/AppThemeProvider.tsx +++ b/packages/core/src/api/app/AppThemeProvider.tsx @@ -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; } diff --git a/packages/core/src/api/app/FeatureFlags.test.tsx b/packages/core/src/api/app/FeatureFlags.test.tsx index ca4a819f13..99974f9b1d 100644 --- a/packages/core/src/api/app/FeatureFlags.test.tsx +++ b/packages/core/src/api/app/FeatureFlags.test.tsx @@ -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({ diff --git a/packages/core/src/api/app/FeatureFlags.tsx b/packages/core/src/api/app/FeatureFlags.tsx index 6af10f228e..11c084d3ed 100644 --- a/packages/core/src/api/app/FeatureFlags.tsx +++ b/packages/core/src/api/app/FeatureFlags.tsx @@ -127,12 +127,12 @@ export interface FeatureFlagsRegistryItem { export class FeatureFlagsRegistry extends Array { 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[] { const _concat = super.concat(...entries); - Array.from(_concat).forEach((entry) => validateFlagName(entry.name)); + Array.from(_concat).forEach(entry => validateFlagName(entry.name)); return _concat; } diff --git a/packages/core/src/components/CodeSnippet/CodeSnippet.tsx b/packages/core/src/components/CodeSnippet/CodeSnippet.tsx index fc7c262882..c77dc5bd43 100644 --- a/packages/core/src/components/CodeSnippet/CodeSnippet.tsx +++ b/packages/core/src/components/CodeSnippet/CodeSnippet.tsx @@ -31,7 +31,7 @@ const defaultProps = { showLineNumbers: false, }; -const CodeSnippet: FC = (props) => { +const CodeSnippet: FC = props => { const { text, language, showLineNumbers } = { ...defaultProps, ...props, diff --git a/packages/core/src/components/HorizontalScrollGrid/HorizontalScrollGrid.test.jsx b/packages/core/src/components/HorizontalScrollGrid/HorizontalScrollGrid.test.jsx index 36079854fd..d7f1e2387a 100644 --- a/packages/core/src/components/HorizontalScrollGrid/HorizontalScrollGrid.test.jsx +++ b/packages/core/src/components/HorizontalScrollGrid/HorizontalScrollGrid.test.jsx @@ -25,7 +25,7 @@ describe('', () => { jest.spyOn(window.performance, 'now').mockReturnValue(5); jest .spyOn(window, 'requestAnimationFrame') - .mockImplementation((cb) => cb(20)); + .mockImplementation(cb => cb(20)); }); afterEach(() => { diff --git a/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx b/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx index 8e3d98c998..d97956c1f0 100644 --- a/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx +++ b/packages/core/src/components/OAuthRequestDialog/LoginRequestListItem.tsx @@ -25,7 +25,7 @@ import { import React, { FC, useState } from 'react'; import { PendingAuthRequest } from '../../api'; -const useItemStyles = makeStyles((theme) => ({ +const useItemStyles = makeStyles(theme => ({ root: { paddingLeft: theme.spacing(3), }, diff --git a/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx b/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx index 617cce2aee..bde12ccb04 100644 --- a/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx +++ b/packages/core/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx @@ -29,7 +29,7 @@ import { useObservable } from 'react-use'; import LoginRequestListItem from './LoginRequestListItem'; import { useApi, oauthRequestApiRef } from '../../api'; -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles(theme => ({ dialog: { paddingTop: theme.spacing(1), }, @@ -53,7 +53,7 @@ export const OAuthRequestDialog: FC = () => { ); const handleRejectAll = () => { - requests.forEach((request) => request.reject()); + requests.forEach(request => request.reject()); }; return ( @@ -69,7 +69,7 @@ export const OAuthRequestDialog: FC = () => { - {requests.map((request) => ( + {requests.map(request => ( ((theme) => ({ +const useStyles = makeStyles(theme => ({ status: { fontWeight: 500, '&::before': { @@ -63,26 +63,26 @@ const useStyles = makeStyles((theme) => ({ }, })); -export const StatusOK: FC<{}> = (props) => { +export const StatusOK: FC<{}> = props => { const classes = useStyles(props); return ; }; -export const StatusWarning: FC<{}> = (props) => { +export const StatusWarning: FC<{}> = props => { const classes = useStyles(props); return ( ); }; -export const StatusError: FC<{}> = (props) => { +export const StatusError: FC<{}> = props => { const classes = useStyles(props); return ( ); }; -export const StatusPending: FC<{}> = (props) => { +export const StatusPending: FC<{}> = props => { const classes = useStyles(props); return ( = (props) => { ); }; -export const StatusRunning: FC<{}> = (props) => { +export const StatusRunning: FC<{}> = props => { const classes = useStyles(props); return ( = (props) => { ); }; -export const StatusAborted: FC<{}> = (props) => { +export const StatusAborted: FC<{}> = props => { const classes = useStyles(props); return ( ', () => { , ); 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('', () => { ); 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('', () => { , ); 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('', () => { ); const keys = Object.keys(metadata.config); - keys.forEach((value) => { + keys.forEach(value => { expect( getByText(startCase(value), { exact: false }), ).toBeInTheDocument(); diff --git a/packages/core/src/layout/ErrorPage/ErrorPage.tsx b/packages/core/src/layout/ErrorPage/ErrorPage.tsx index 14241c1ee7..747f2f6036 100644 --- a/packages/core/src/layout/ErrorPage/ErrorPage.tsx +++ b/packages/core/src/layout/ErrorPage/ErrorPage.tsx @@ -26,7 +26,7 @@ interface IErrorPageProps { statusMessage: string; } -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles(theme => ({ container: { padding: theme.spacing(8), }, diff --git a/packages/core/src/layout/Sidebar/Intro.tsx b/packages/core/src/layout/Sidebar/Intro.tsx index 595697c466..b4bb56588e 100644 --- a/packages/core/src/layout/Sidebar/Intro.tsx +++ b/packages/core/src/layout/Sidebar/Intro.tsx @@ -26,7 +26,7 @@ import { } from './config'; import { SidebarDivider } from './Items'; -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles(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 = (props) => { +export const IntroCard: FC = props => { const classes = useStyles(); const { text, onClose } = props; const handleClose = () => onClose(); @@ -109,7 +109,7 @@ type SidebarIntroCardProps = { onDismiss: () => void; }; -const SidebarIntroCard: FC = (props) => { +const SidebarIntroCard: FC = 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, })); diff --git a/packages/core/src/layout/Sidebar/Items.tsx b/packages/core/src/layout/Sidebar/Items.tsx index bd5faa5631..4696f53a37 100644 --- a/packages/core/src/layout/Sidebar/Items.tsx +++ b/packages/core/src/layout/Sidebar/Items.tsx @@ -29,7 +29,7 @@ import { NavLink } from 'react-router-dom'; import { sidebarConfig, SidebarContext } from './config'; import { IconComponent } from '../../icons'; -const useStyles = makeStyles((theme) => { +const useStyles = makeStyles(theme => { const { selectedIndicatorWidth, drawerWidthClosed, @@ -139,7 +139,7 @@ export const SidebarItem: FC = ({ Boolean(match && !disableSelected)} + isActive={match => Boolean(match && !disableSelected)} exact to={to} onClick={onClick} @@ -153,7 +153,7 @@ export const SidebarItem: FC = ({ 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 = (props) => { +export const SidebarSearchField: FC = props => { const [input, setInput] = useState(''); const classes = useStyles(); - const handleEnter: KeyboardEventHandler = (ev) => { + const handleEnter: KeyboardEventHandler = ev => { if (ev.key === 'Enter') { props.onSearch(input); } diff --git a/packages/core/src/layout/Sidebar/Page.tsx b/packages/core/src/layout/Sidebar/Page.tsx index 79df2852d9..750f764c2d 100644 --- a/packages/core/src/layout/Sidebar/Page.tsx +++ b/packages/core/src/layout/Sidebar/Page.tsx @@ -44,7 +44,7 @@ export const SidebarPinStateContext = createContext( }, ); -export const SidebarPage: FC<{}> = (props) => { +export const SidebarPage: FC<{}> = props => { const [isPinned, setIsPinned] = useState(LocalStorage.getSidebarPinState()); useEffect(() => { diff --git a/packages/storybook/.storybook/main.js b/packages/storybook/.storybook/main.js index 5f9bde16c3..b8f78f5d2c 100644 --- a/packages/storybook/.storybook/main.js +++ b/packages/storybook/.storybook/main.js @@ -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 diff --git a/plugins/auth-backend/src/run.ts b/plugins/auth-backend/src/run.ts index 0a684c379e..a2c2601258 100644 --- a/plugins/auth-backend/src/run.ts +++ b/plugins/auth-backend/src/run.ts @@ -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); }); diff --git a/plugins/catalog/src/data/mock-factory.ts b/plugins/catalog/src/data/mock-factory.ts index bf39fa436c..19f04195f9 100644 --- a/plugins/catalog/src/data/mock-factory.ts +++ b/plugins/catalog/src/data/mock-factory.ts @@ -20,7 +20,7 @@ const ARTIFICIAL_TIMEOUT = 800; let inMemoryStore = [...mock]; export const MockComponentFactory: ComponentFactory = { getAllComponents(): Promise { - 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 { - return new Promise((resolve) => + return new Promise(resolve => setTimeout(() => { inMemoryStore = inMemoryStore.filter( - (component) => component.name !== name, + component => component.name !== name, ); resolve(true); }, ARTIFICIAL_TIMEOUT), diff --git a/plugins/circleci/src/components/Settings/Settings.tsx b/plugins/circleci/src/components/Settings/Settings.tsx index e853bb46bb..f0ed3f2ceb 100644 --- a/plugins/circleci/src/components/Settings/Settings.tsx +++ b/plugins/circleci/src/components/Settings/Settings.tsx @@ -80,7 +80,7 @@ const Settings = () => { value={token} fullWidth variant="outlined" - onChange={(e) => setToken(e.target.value)} + onChange={e => setToken(e.target.value)} /> @@ -90,7 +90,7 @@ const Settings = () => { label="Owner" variant="outlined" value={owner} - onChange={(e) => setOwner(e.target.value)} + onChange={e => setOwner(e.target.value)} /> @@ -100,7 +100,7 @@ const Settings = () => { fullWidth variant="outlined" value={repo} - onChange={(e) => setRepo(e.target.value)} + onChange={e => setRepo(e.target.value)} /> diff --git a/plugins/circleci/src/pages/BuildWithStepsPage/BuildWithStepsPage.tsx b/plugins/circleci/src/pages/BuildWithStepsPage/BuildWithStepsPage.tsx index 8493913576..75d09610b5 100644 --- a/plugins/circleci/src/pages/BuildWithStepsPage/BuildWithStepsPage.tsx +++ b/plugins/circleci/src/pages/BuildWithStepsPage/BuildWithStepsPage.tsx @@ -35,7 +35,7 @@ const BuildName: FC<{ build?: BuildWithSteps }> = ({ build }) => ( ); -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles(theme => ({ neutral: {}, failed: { position: 'relative', diff --git a/plugins/circleci/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx b/plugins/circleci/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx index e8e1bfe958..dd526c1b5f 100644 --- a/plugins/circleci/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx +++ b/plugins/circleci/src/pages/BuildWithStepsPage/lib/ActionOutput/ActionOutput.tsx @@ -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), diff --git a/plugins/circleci/src/state/useAsyncPolling.ts b/plugins/circleci/src/state/useAsyncPolling.ts index 2f8de0c2fe..7ea0755368 100644 --- a/plugins/circleci/src/state/useAsyncPolling.ts +++ b/plugins/circleci/src/state/useAsyncPolling.ts @@ -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)); } }; diff --git a/plugins/circleci/src/state/useSettings.ts b/plugins/circleci/src/state/useSettings.ts index 5482abeb8b..c8dc9ce39b 100644 --- a/plugins/circleci/src/state/useSettings.ts +++ b/plugins/circleci/src/state/useSettings.ts @@ -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({ diff --git a/plugins/identity-backend/src/run.ts b/plugins/identity-backend/src/run.ts index 0a684c379e..a2c2601258 100644 --- a/plugins/identity-backend/src/run.ts +++ b/plugins/identity-backend/src/run.ts @@ -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); }); diff --git a/plugins/lighthouse/src/components/AuditView/index.test.tsx b/plugins/lighthouse/src/components/AuditView/index.test.tsx index 330b88517a..4e261fcf39 100644 --- a/plugins/lighthouse/src/components/AuditView/index.test.tsx +++ b/plugins/lighthouse/src/components/AuditView/index.test.tsx @@ -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 }); diff --git a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx index b337698485..79897539c4 100644 --- a/plugins/lighthouse/src/components/CreateAudit/index.test.tsx +++ b/plugins/lighthouse/src/components/CreateAudit/index.test.tsx @@ -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)); }); diff --git a/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx b/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx index fe4ba7845a..d279afac25 100644 --- a/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx +++ b/plugins/register-component/src/components/RegisterComponentForm/RegisterComponentForm.tsx @@ -28,7 +28,7 @@ import { BackstageTheme } from '@backstage/theme'; import { Progress } from '@backstage/core'; import { ComponentIdValidators } from '../../util/validate'; -const useStyles = makeStyles((theme) => ({ +const useStyles = makeStyles(theme => ({ form: { alignItems: 'flex-start', display: 'flex', diff --git a/plugins/sentry-backend/README.md b/plugins/sentry-backend/README.md index 412306dc8b..efd4c1b472 100644 --- a/plugins/sentry-backend/README.md +++ b/plugins/sentry-backend/README.md @@ -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. diff --git a/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx b/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx index 408014b790..617bdb3ce9 100644 --- a/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx +++ b/plugins/sentry/src/components/ErrorCell/ErrorCell.tsx @@ -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((theme) => ({ +const useStyles = makeStyles(theme => ({ root: { minWidth: 260, position: 'relative', diff --git a/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx b/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx index 3e5ed98dba..e861c6bbe5 100644 --- a/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx +++ b/plugins/sentry/src/components/SentryIssuesTable/SentryIssuesTable.tsx @@ -24,16 +24,16 @@ import { ErrorGraph } from '../ErrorGraph/ErrorGraph'; const columns: TableColumn[] = [ { title: 'Error', - render: (data) => , + render: data => , }, { title: 'Graph', - render: (data) => , + render: data => , }, { 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); }, diff --git a/plugins/sentry/src/data/mock-api.ts b/plugins/sentry/src/data/mock-api.ts index e26cce1762..215e9f7734 100644 --- a/plugins/sentry/src/data/mock-api.ts +++ b/plugins/sentry/src/data/mock-api.ts @@ -33,7 +33,7 @@ function getMockIssues(number: number): SentryIssue[] { } export class MockSentryApi implements SentryApi { fetchIssues(): Promise { - return new Promise((resolve) => { + return new Promise(resolve => { setTimeout(() => resolve(getMockIssues(14)), 800); }); } diff --git a/plugins/tech-radar/src/components/Radar/Radar.jsx b/plugins/tech-radar/src/components/Radar/Radar.jsx index ee956bfb89..11f763f465 100644 --- a/plugins/tech-radar/src/components/Radar/Radar.jsx +++ b/plugins/tech-radar/src/components/Radar/Radar.jsx @@ -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 ( { + 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()} /> diff --git a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.jsx b/plugins/tech-radar/src/components/RadarBubble/RadarBubble.jsx index 83487d637e..072f80ca20 100644 --- a/plugins/tech-radar/src/components/RadarBubble/RadarBubble.jsx +++ b/plugins/tech-radar/src/components/RadarBubble/RadarBubble.jsx @@ -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; }; diff --git a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.jsx b/plugins/tech-radar/src/components/RadarGrid/RadarGrid.jsx index f48a8e9514..ce6c046242 100644 --- a/plugins/tech-radar/src/components/RadarGrid/RadarGrid.jsx +++ b/plugins/tech-radar/src/components/RadarGrid/RadarGrid.jsx @@ -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); } diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.jsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.jsx index 5fb7b5a1ba..674dd34cbb 100644 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.jsx +++ b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.jsx @@ -88,7 +88,7 @@ class RadarLegend extends React.PureComponent {

{quadrant.name}

- {rings.map((ring) => + {rings.map(ring => RadarLegend._renderRing( ring, RadarLegend._getSegment(segments, quadrant, ring), @@ -117,7 +117,7 @@ class RadarLegend extends React.PureComponent {

(empty)

) : (
    - {entries.map((entry) => { + {entries.map(entry => { let node = {entry.title}; if (entry.url) { @@ -175,7 +175,7 @@ class RadarLegend extends React.PureComponent { return ( - {quadrants.map((quadrant) => + {quadrants.map(quadrant => RadarLegend._renderQuadrant( segments, quadrant, diff --git a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.jsx b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.jsx index afa4c4cd95..b93d20cbff 100644 --- a/plugins/tech-radar/src/components/RadarPlot/RadarPlot.jsx +++ b/plugins/tech-radar/src/components/RadarPlot/RadarPlot.jsx @@ -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)) } /> - {entries.map((entry) => ( + {entries.map(entry => (