diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index f0b31fb4d0..c2273156ac 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -31,6 +31,7 @@ import { AlertDisplay, OAuthRequestDialog, SignInPage, + defaultAppIcons, defaultAppComponents, } from '@backstage/core-components'; import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs'; @@ -91,6 +92,7 @@ const app = createApp({ apis, plugins: Object.values(plugins), icons: { + ...defaultAppIcons(), // Custom icon example alert: AlarmIcon, }, diff --git a/packages/core-app-api/src/app/createApp.tsx b/packages/core-app-api/src/app/createApp.tsx index 1e53103152..7b93daf40f 100644 --- a/packages/core-app-api/src/app/createApp.tsx +++ b/packages/core-app-api/src/app/createApp.tsx @@ -16,7 +16,10 @@ import { AppConfig } from '@backstage/config'; import { JsonObject } from '@backstage/types'; -import { defaultAppComponents } from '@backstage/core-components'; +import { + defaultAppComponents, + defaultAppIcons, +} from '@backstage/core-components'; import { darkTheme, lightTheme } from '@backstage/theme'; import DarkIcon from '@material-ui/icons/Brightness2'; import LightIcon from '@material-ui/icons/WbSunny'; @@ -25,7 +28,6 @@ import { BrowserRouter } from 'react-router-dom'; import { PrivateAppImpl } from './App'; import { AppThemeProvider } from './AppThemeProvider'; import { defaultApis } from './defaultApis'; -import { defaultAppIcons } from './icons'; import { AppConfigLoader, AppOptions } from './types'; import { AppComponents, BackstagePlugin } from '@backstage/core-plugin-api'; @@ -112,8 +114,22 @@ export function createApp(options?: AppOptions) { ); } + const appIcons = defaultAppIcons(); + const providedIconKeys = Object.keys(options?.icons ?? {}); + const missingIconKeys = Object.keys(appIcons).filter( + key => !providedIconKeys.includes(key), + ); + if (missingIconKeys.length > 0) { + // eslint-disable-next-line no-console + console.warn( + 'DEPRECATION WARNING: The createApp options will soon require all app icons to be provided.' + + 'These icons can be created using defaultAppIcons from @backstage/core-components ' + + 'and then passed along like this: createApp({ icons: ...defaultAppIcons() })' + + `The following icons are missing: ${missingIconKeys.join(', ')}`, + ); + } + const apis = options?.apis ?? []; - const icons = { ...defaultAppIcons, ...options?.icons }; const plugins = options?.plugins ?? []; const components = { ...defaultAppComponents(), @@ -141,7 +157,7 @@ export function createApp(options?: AppOptions) { return new PrivateAppImpl({ apis, - icons, + icons: { ...appIcons, ...options?.icons }, plugins: plugins as BackstagePlugin[], components, themes, diff --git a/packages/core-app-api/src/app/icons.tsx b/packages/core-app-api/src/app/icons.tsx index b234a292b1..f06c9da989 100644 --- a/packages/core-app-api/src/app/icons.tsx +++ b/packages/core-app-api/src/app/icons.tsx @@ -35,30 +35,30 @@ import MuiPeopleIcon from '@material-ui/icons/People'; import MuiPersonIcon from '@material-ui/icons/Person'; import MuiWarningIcon from '@material-ui/icons/Warning'; -type AppIconsKey = - | 'brokenImage' - | 'catalog' - | 'scaffolder' - | 'techdocs' - | 'search' - | 'chat' - | 'dashboard' - | 'docs' - | 'email' - | 'github' - | 'group' - | 'help' - | 'kind:api' - | 'kind:component' - | 'kind:domain' - | 'kind:group' - | 'kind:location' - | 'kind:system' - | 'kind:user' - | 'user' - | 'warning'; +export type AppIcons = { + 'kind:api': IconComponent; + 'kind:component': IconComponent; + 'kind:domain': IconComponent; + 'kind:group': IconComponent; + 'kind:location': IconComponent; + 'kind:system': IconComponent; + 'kind:user': IconComponent; -export type AppIcons = { [key in AppIconsKey]: IconComponent }; + brokenImage: IconComponent; + catalog: IconComponent; + chat: IconComponent; + dashboard: IconComponent; + docs: IconComponent; + email: IconComponent; + github: IconComponent; + group: IconComponent; + help: IconComponent; + scaffolder: IconComponent; + search: IconComponent; + techdocs: IconComponent; + user: IconComponent; + warning: IconComponent; +}; export const defaultAppIcons: AppIcons = { brokenImage: MuiBrokenImageIcon, diff --git a/packages/core-app-api/src/app/index.ts b/packages/core-app-api/src/app/index.ts index ab82774cad..2a16a90bfa 100644 --- a/packages/core-app-api/src/app/index.ts +++ b/packages/core-app-api/src/app/index.ts @@ -15,4 +15,5 @@ */ export { createApp, defaultConfigLoader } from './createApp'; +export type { AppIcons } from './icons'; export * from './types'; diff --git a/packages/core-components/src/defaultAppIcons.tsx b/packages/core-components/src/defaultAppIcons.tsx new file mode 100644 index 0000000000..1d02dd5ad2 --- /dev/null +++ b/packages/core-components/src/defaultAppIcons.tsx @@ -0,0 +1,55 @@ +/* + * Copyright 2020 The Backstage Authors + * + * 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 { IconComponent } from '@backstage/core-plugin-api'; +import MuiApartmentIcon from '@material-ui/icons/Apartment'; +import MuiBrokenImageIcon from '@material-ui/icons/BrokenImage'; +import MuiCategoryIcon from '@material-ui/icons/Category'; +import MuiChatIcon from '@material-ui/icons/Chat'; +import MuiDashboardIcon from '@material-ui/icons/Dashboard'; +import MuiDocsIcon from '@material-ui/icons/Description'; +import MuiEmailIcon from '@material-ui/icons/Email'; +import MuiExtensionIcon from '@material-ui/icons/Extension'; +import MuiGitHubIcon from '@material-ui/icons/GitHub'; +import MuiHelpIcon from '@material-ui/icons/Help'; +import MuiLocationOnIcon from '@material-ui/icons/LocationOn'; +import MuiMemoryIcon from '@material-ui/icons/Memory'; +import MuiMenuBookIcon from '@material-ui/icons/MenuBook'; +import MuiPeopleIcon from '@material-ui/icons/People'; +import MuiPersonIcon from '@material-ui/icons/Person'; +import MuiWarningIcon from '@material-ui/icons/Warning'; + +export const defaultAppIcons = () => ({ + brokenImage: MuiBrokenImageIcon as IconComponent, + // To be confirmed: see https://github.com/backstage/backstage/issues/4970 + catalog: MuiMenuBookIcon as IconComponent, + chat: MuiChatIcon as IconComponent, + dashboard: MuiDashboardIcon as IconComponent, + docs: MuiDocsIcon as IconComponent, + email: MuiEmailIcon as IconComponent, + github: MuiGitHubIcon as IconComponent, + group: MuiPeopleIcon as IconComponent, + help: MuiHelpIcon as IconComponent, + 'kind:api': MuiExtensionIcon as IconComponent, + 'kind:component': MuiMemoryIcon as IconComponent, + 'kind:domain': MuiApartmentIcon as IconComponent, + 'kind:group': MuiPeopleIcon as IconComponent, + 'kind:location': MuiLocationOnIcon as IconComponent, + 'kind:system': MuiCategoryIcon as IconComponent, + 'kind:user': MuiPersonIcon as IconComponent, + user: MuiPersonIcon as IconComponent, + warning: MuiWarningIcon as IconComponent, +}); diff --git a/packages/core-components/src/index.ts b/packages/core-components/src/index.ts index 9bc2436559..3538cd4186 100644 --- a/packages/core-components/src/index.ts +++ b/packages/core-components/src/index.ts @@ -26,3 +26,4 @@ export * from './icons'; export * from './layout'; export * from './overridableComponents'; export { defaultAppComponents } from './defaultAppComponents'; +export { defaultAppIcons } from './defaultAppIcons';