Merge branch 'master' of https://github.com/mufaddal7/backstage-1 into feature/EntitySystemDiagramCard

This commit is contained in:
mufaddal motiwala
2022-01-21 18:55:32 +05:30
57 changed files with 281 additions and 129 deletions
+13
View File
@@ -0,0 +1,13 @@
---
'@backstage/plugin-catalog-graph': patch
---
Deprecated the external `catalogEntity` route as this is now imported directly from `@backstage/plugin-catalog-react` instead.
This means you can remove the route binding from your `App.tsx`:
```diff
- bind(catalogGraphPlugin.externalRoutes, {
- catalogEntity: catalogPlugin.routes.catalogEntity,
- });
```
+13
View File
@@ -0,0 +1,13 @@
---
'@backstage/plugin-search': minor
---
Forwarding classes to HomePageSearchBar instead of using className prop. For custom styles of the HomePageSearchBar, use classes prop instead:
```diff
<HomePageSearchBar
- className={searchBar}
+ classes={{ root: classes.searchBar }}
placeholder="Search"
/>
```
+13
View File
@@ -0,0 +1,13 @@
---
'@backstage/plugin-explore': patch
---
Deprecated the external `catalogEntity` route as this is now imported directly from `@backstage/plugin-catalog-react` instead.
This means you can remove the route binding from your `App.tsx`:
```diff
- bind(explorePlugin.externalRoutes, {
- catalogEntity: catalogPlugin.routes.catalogEntity,
- });
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/techdocs-common': patch
---
Fix interpolated string for "Failed to generate docs from ..."
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Code snippets now include a "copy to clipboard" button.
+2
View File
@@ -1,5 +1,7 @@
abc
accessors
addon
addons
Airbrake
Anddddd
Apdex
@@ -1,4 +1,4 @@
name: 'Pull Request Labeler'
name: Automate area labels
on:
- pull_request_target
@@ -1,5 +1,5 @@
# on a review from someone in the reviewers group, remove the awaiting-review label and add the awaiting-author label
name: 'goalie: run cron'
name: Automate review labels - scheduled
on:
schedule:
- cron: '* * * * *'
@@ -1,6 +1,6 @@
# When the target of the PR changes, open, re-open or sync, then re-add the label.
name: 'goalie: update awaiting-review label'
name: Automate review labels
on:
pull_request_target:
types:
@@ -1,4 +1,4 @@
name: 'Stale workflow'
name: Automate staleness
on:
workflow_dispatch:
schedule:
@@ -1,4 +1,4 @@
name: Automatically add new TechDocs Issues and PRs to the GitHub project board
name: Automate TechDocs project board
# Development of TechDocs in Backstage is managed by this Kanban board - https://github.com/orgs/backstage/projects/1
# New issues and PRs with TechDocs in their title or docs-like-code label will be added to the board.
# Caveat: New PRs created from forks will not be added since GitHub Actions don't share credentials with forks.
@@ -1,4 +1,4 @@
name: Deploy Microsite and Storybook
name: Deploy Microsite
on:
push:
@@ -1,4 +1,4 @@
name: Nightly Snapshot Release
name: Deploy Nightly Release
on:
schedule:
@@ -1,4 +1,4 @@
name: Main Master Build
name: Deploy Packages
on:
workflow_dispatch:
@@ -1,4 +1,4 @@
name: Prettier
name: Sync code formatting
on:
push:
@@ -1,4 +1,4 @@
name: 'Dependabot changeset maker'
name: Sync Dependabot changeset
on:
pull_request_target:
paths:
@@ -1,4 +1,4 @@
name: 'Snyk Github Issue Sync'
name: Sync Snyk GitHub issues
on:
schedule:
@@ -1,4 +1,4 @@
name: Snyk Monitoring
name: Sync Snyk Monitoring
on:
workflow_dispatch:
@@ -1,4 +1,4 @@
name: Changeset
name: Sync Version Packages PR
on:
push:
@@ -3,7 +3,7 @@
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: 'CodeQL'
name: Verify CodeQL
on:
push:
@@ -1,4 +1,4 @@
name: Check Markdown files quality
name: Verify Docs Quality
on:
pull_request:
@@ -1,4 +1,4 @@
name: Techdocs E2E Test
name: E2E Test Techdocs
on:
pull_request:
@@ -1,4 +1,4 @@
name: Tugboat E2E Tests
name: E2E Test Tugboat
on: deployment_status
jobs:
set-pending:
@@ -1,4 +1,4 @@
name: FOSSA
name: Verify FOSSA
on:
push:
branches: [master]
@@ -1,4 +1,4 @@
name: Build microsite
name: Verify Microsite
on:
pull_request:
@@ -1,4 +1,4 @@
name: 'test chromatic'
name: Verify Storybook
on:
pull_request:
paths:
@@ -1,4 +1,4 @@
name: Master Build Windows
name: Verify Master Branch on Windows
on:
workflow_dispatch:
+2 -1
View File
@@ -83,4 +83,5 @@
| [Power Home Remodeling](https://www.techatpower.com) | [Ben Langfeld](https://github.com/benlangfeld) | Developer portal to our internal services, build on open-source software (including Kubernetes) in our own datacenters. Our Portal allows our team members to navigate inherant complexity and standardise. |
| [Livspace](https://www.livspace.com) | [Praveen Kumar](https://github.com/praveen-livspace) | Developer portal, service catalog, tech docs, API docs and plugins |
| [Just Eat Takeaway](https://www.justeattakeaway.com) | [Kim Wilson](https://github.com/kwilson541) | Our developer portal which centralises applications, reduces cognitive load and provides teams insights. |
| [Hopin](https://hopin.com) | [Vladimir Glafirov](https://github.com/vglafirov), [Chloe Lee](https://github.com/msfuko) | Developer portal to streamline the development practices. Integrated with service catalog, software templates, application monitoring, tech docs and plugins. |
| [Hopin](https://hopin.com) | [Vladimir Glafirov](https://github.com/vglafirov), [Chloe Lee](https://github.com/msfuko) | Developer portal to streamline the development practices. Integrated with service catalog, software templates, application monitoring, tech docs and plugins. |
| [HBO Max](https://hbomax.com) | [@mdb](https://github.com/mdb), [@nesta219](https://github.com/nesta219), [@nmische](https://github.com/nmische), [@hbomark](https://github.com/hbomark) | Developer portal hosting service catalog and API documentation, as well as cloud infrastructure details, operational visibility tools, and a custom plugin for browsing notable platform change events, such as deployments and configuration updates. |
+11 -2
View File
@@ -64,7 +64,7 @@ cycle will vary based on maintainer schedules.
### Backstage 1.0 (and following versions)
During the first quarter of 2022, we plan to finalize and release version 1.0 of
the Backstage platform (defined by the Core,
the Backstage platform (which includes Core,
[Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview),
[Scaffolder](https://backstage.io/docs/features/software-templates/software-templates-index)
and [TechDocs](https://backstage.io/docs/features/techdocs/techdocs-overview)).
@@ -104,7 +104,16 @@ the maintainers radar, with clear interest expressed by the community.
- **Security Plan (and Strategy):** The purpose of the Security Strategy is to
move another step along the path to maturing the platform, setting the
expectations of any adopters from a security standpoint.
- **Search GA:**.
- **Search 1.0:** Fix the few remaining issues to get Backstage Search platform
up to 1.0 ([here](https://github.com/backstage/backstage/milestone/27) and
[here](https://github.com/backstage/backstage/milestone/28))
- **TechDocs Addon framework and Addons:** Addons are TechDocs features that are
added on top of the base docs like code experience. An example would be a
feature that showed comments on the page. We plan to add an Addon framework
and open source a selection of the Addons that we use internally at Spotify.
Further Addons can then be added by the Community.
- **Composable Homepage 1.0:** Driving this to 1.0 by adding some composable
components.
- **[GraphQL](https://graphql.org/) support:** Introduce the ability to query
Backstage backend services with a standard query language for APIs.
- **Telemetry:** To efficiently generate logging and metrics in such a way that
+1 -1
View File
@@ -3,7 +3,7 @@
## npm
npm packages are published through CI/CD in the
[`.github/workflows/master.yml`](https://github.com/backstage/backstage/blob/master/.github/workflows/master.yml)
[`.github/workflows/deploy_packages.yml`](https://github.com/backstage/backstage/blob/master/.github/workflows/deploy_packages.yml)
workflow. Every commit that is merged to master will be checked for new versions
of all public packages, and any new versions will automatically be published to
npm.
+2 -11
View File
@@ -40,10 +40,7 @@ import {
CatalogIndexPage,
catalogPlugin,
} from '@backstage/plugin-catalog';
import {
CatalogGraphPage,
catalogGraphPlugin,
} from '@backstage/plugin-catalog-graph';
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
import {
CatalogImportPage,
catalogImportPlugin,
@@ -54,7 +51,7 @@ import {
CostInsightsProjectGrowthInstructionsPage,
} from '@backstage/plugin-cost-insights';
import { orgPlugin } from '@backstage/plugin-org';
import { ExplorePage, explorePlugin } from '@backstage/plugin-explore';
import { ExplorePage } from '@backstage/plugin-explore';
import { GcpProjectsPage } from '@backstage/plugin-gcp-projects';
import { GraphiQLPage } from '@backstage/plugin-graphiql';
import { HomepageCompositionRoot } from '@backstage/plugin-home';
@@ -114,15 +111,9 @@ const app = createApp({
createComponent: scaffolderPlugin.routes.root,
viewTechDoc: techdocsPlugin.routes.docRoot,
});
bind(catalogGraphPlugin.externalRoutes, {
catalogEntity: catalogPlugin.routes.catalogEntity,
});
bind(apiDocsPlugin.externalRoutes, {
registerApi: catalogImportPlugin.routes.importPage,
});
bind(explorePlugin.externalRoutes, {
catalogEntity: catalogPlugin.routes.catalogEntity,
});
bind(scaffolderPlugin.externalRoutes, {
registerComponent: catalogImportPlugin.routes.importPage,
});
@@ -150,7 +150,7 @@ export class TechdocsGenerator implements GeneratorBase {
`Failed to generate docs from ${inputDir} into ${outputDir}`,
);
throw new ForwardedError(
'Failed to generate docs from ${inputDir} into ${outputDir}',
`Failed to generate docs from ${inputDir} into ${outputDir}`,
error,
);
}
+1 -1
View File
@@ -49,7 +49,7 @@ export const catalogGraphPlugin: BackstagePlugin<
kind: string;
namespace: string;
},
false
true
>;
}
>;
@@ -20,6 +20,7 @@ import {
CatalogApi,
catalogApiRef,
EntityProvider,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import {
MockAnalyticsApi,
@@ -29,7 +30,7 @@ import {
} from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { catalogEntityRouteRef, catalogGraphRouteRef } from '../../routes';
import { catalogGraphRouteRef } from '../../routes';
import { CatalogGraphCard } from './CatalogGraphCard';
describe('<CatalogGraphCard/>', () => {
@@ -80,7 +81,7 @@ describe('<CatalogGraphCard/>', () => {
test('renders without exploding', async () => {
const { findByText, findAllByTestId } = await renderInTestApp(wrapper, {
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
'/catalog-graph': catalogGraphRouteRef,
},
});
@@ -99,7 +100,7 @@ describe('<CatalogGraphCard/>', () => {
</ApiProvider>,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
'/catalog-graph': catalogGraphRouteRef,
},
},
@@ -111,7 +112,7 @@ describe('<CatalogGraphCard/>', () => {
test('renders link to standalone viewer', async () => {
const { findByText, getByText } = await renderInTestApp(wrapper, {
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
'/catalog-graph': catalogGraphRouteRef,
},
});
@@ -133,7 +134,7 @@ describe('<CatalogGraphCard/>', () => {
</TestApiProvider>,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
'/catalog-graph': catalogGraphRouteRef,
},
},
@@ -23,12 +23,13 @@ import { useAnalytics, useRouteRef } from '@backstage/core-plugin-api';
import {
formatEntityRefTitle,
useEntity,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import { makeStyles, Theme } from '@material-ui/core';
import qs from 'qs';
import React, { MouseEvent, useCallback } from 'react';
import { useNavigate } from 'react-router';
import { catalogEntityRouteRef, catalogGraphRouteRef } from '../../routes';
import { catalogGraphRouteRef } from '../../routes';
import {
ALL_RELATION_PAIRS,
Direction,
@@ -77,7 +78,7 @@ export const CatalogGraphCard = ({
}) => {
const { entity } = useEntity();
const entityName = getEntityName(entity);
const catalogEntityRoute = useRouteRef(catalogEntityRouteRef);
const catalogEntityRoute = useRouteRef(entityRouteRef);
const catalogGraphRoute = useRouteRef(catalogGraphRouteRef);
const navigate = useNavigate();
const classes = useStyles({ height });
@@ -15,7 +15,11 @@
*/
import { RELATION_HAS_PART, RELATION_PART_OF } from '@backstage/catalog-model';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react';
import {
CatalogApi,
catalogApiRef,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import {
MockAnalyticsApi,
renderInTestApp,
@@ -23,7 +27,6 @@ import {
} from '@backstage/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
import { CatalogGraphPage } from './CatalogGraphPage';
const navigate = jest.fn();
@@ -114,7 +117,7 @@ describe('<CatalogGraphPage/>', () => {
wrapper,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
},
},
);
@@ -129,7 +132,7 @@ describe('<CatalogGraphPage/>', () => {
test('should toggle filters', async () => {
const { getByText, queryByText } = await renderInTestApp(wrapper, {
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
},
});
@@ -145,7 +148,7 @@ describe('<CatalogGraphPage/>', () => {
wrapper,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
},
},
);
@@ -160,7 +163,7 @@ describe('<CatalogGraphPage/>', () => {
test('should navigate to entity', async () => {
const { getByText, findAllByTestId } = await renderInTestApp(wrapper, {
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
},
});
@@ -179,7 +182,7 @@ describe('<CatalogGraphPage/>', () => {
</TestApiProvider>,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
},
},
);
@@ -202,7 +205,7 @@ describe('<CatalogGraphPage/>', () => {
</TestApiProvider>,
{
mountedRoutes: {
'/entity/{kind}/{namespace}/{name}': catalogEntityRouteRef,
'/entity/{kind}/{namespace}/{name}': entityRouteRef,
},
},
);
@@ -22,14 +22,16 @@ import {
SupportButton,
} from '@backstage/core-components';
import { useAnalytics, useRouteRef } from '@backstage/core-plugin-api';
import { formatEntityRefTitle } from '@backstage/plugin-catalog-react';
import {
entityRouteRef,
formatEntityRefTitle,
} from '@backstage/plugin-catalog-react';
import { Grid, makeStyles, Paper, Typography } from '@material-ui/core';
import FilterListIcon from '@material-ui/icons/FilterList';
import ZoomOutMap from '@material-ui/icons/ZoomOutMap';
import { ToggleButton } from '@material-ui/lab';
import React, { MouseEvent, useCallback } from 'react';
import { useNavigate } from 'react-router';
import { catalogEntityRouteRef } from '../../routes';
import {
ALL_RELATION_PAIRS,
Direction,
@@ -114,7 +116,7 @@ export const CatalogGraphPage = ({
}) => {
const navigate = useNavigate();
const classes = useStyles();
const catalogEntityRoute = useRouteRef(catalogEntityRouteRef);
const catalogEntityRoute = useRouteRef(entityRouteRef);
const {
maxDepth,
setMaxDepth,
+2
View File
@@ -32,8 +32,10 @@ export const catalogGraphRouteRef = createRouteRef({
* Used to navigate from the graph to an entity.
*
* @public
* @deprecated This route is no longer used and can be removed
*/
export const catalogEntityRouteRef = createExternalRouteRef({
id: 'catalog-entity',
params: ['namespace', 'kind', 'name'],
optional: true,
});
+3 -3
View File
@@ -14,14 +14,14 @@ import { TabProps } from '@material-ui/core';
// Warning: (ae-missing-release-tag) "catalogEntityRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
// @public @deprecated (undocumented)
export const catalogEntityRouteRef: ExternalRouteRef<
{
name: string;
kind: string;
namespace: string;
},
false
true
>;
// Warning: (ae-forgotten-export) The symbol "DomainCardProps" needs to be exported by the entry point index.d.ts
@@ -66,7 +66,7 @@ const explorePlugin: BackstagePlugin<
kind: string;
namespace: string;
},
false
true
>;
}
>;
@@ -15,9 +15,9 @@
*/
import { DomainEntity } from '@backstage/catalog-model';
import { entityRouteRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp } from '@backstage/test-utils';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
import { DomainCard } from './DomainCard';
describe('<DomainCard />', () => {
@@ -38,7 +38,7 @@ describe('<DomainCard />', () => {
<DomainCard entity={entity} />,
{
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
},
},
);
@@ -18,6 +18,7 @@ import {
EntityRefLinks,
entityRouteParams,
getEntityRelations,
entityRouteRef,
} from '@backstage/plugin-catalog-react';
import {
Box,
@@ -28,7 +29,6 @@ import {
Chip,
} from '@material-ui/core';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
import { Button, ItemCardHeader } from '@backstage/core-components';
import { useRouteRef } from '@backstage/core-plugin-api';
@@ -38,7 +38,7 @@ type DomainCardProps = {
};
export const DomainCard = ({ entity }: DomainCardProps) => {
const catalogEntityRoute = useRouteRef(catalogEntityRouteRef);
const catalogEntityRoute = useRouteRef(entityRouteRef);
const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);
const url = catalogEntityRoute(entityRouteParams(entity));
@@ -15,11 +15,10 @@
*/
import { DomainEntity } from '@backstage/catalog-model';
import { catalogApiRef } from '@backstage/plugin-catalog-react';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { catalogEntityRouteRef } from '../../routes';
import { DomainExplorerContent } from './DomainExplorerContent';
describe('<DomainExplorerContent />', () => {
@@ -44,7 +43,7 @@ describe('<DomainExplorerContent />', () => {
const mountedRoutes = {
mountedRoutes: {
'/catalog/:namespace/:kind/:name': catalogEntityRouteRef,
'/catalog/:namespace/:kind/:name': entityRouteRef,
},
};
+4
View File
@@ -23,7 +23,11 @@ export const exploreRouteRef = createRouteRef({
id: 'explore',
});
/**
* @deprecated This route is no longer used and can be removed
*/
export const catalogEntityRouteRef = createExternalRouteRef({
id: 'catalog-entity',
params: ['namespace', 'kind', 'name'],
optional: true,
});
@@ -47,14 +47,12 @@ export default {
};
const useStyles = makeStyles(theme => ({
search: {
searchBar: {
display: 'flex',
maxWidth: '60vw',
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[1],
maxWidth: '60vw',
display: 'flex',
justifyContent: 'space-between',
padding: '8px 0',
borderColor: 'transparent',
borderRadius: '50px',
margin: 'auto',
},
@@ -74,7 +72,7 @@ const useLogoStyles = makeStyles(theme => ({
}));
export const DefaultTemplate = () => {
const { search } = useStyles();
const classes = useStyles();
const { svg, path, container } = useLogoStyles();
return (
@@ -88,7 +86,7 @@ export const DefaultTemplate = () => {
/>
<Grid container item xs={12} alignItems="center" direction="row">
<HomePageSearchBar
className={search}
classes={{root: classes.searchBar}}
placeholder="Search"
/>
</Grid>
-1
View File
@@ -66,7 +66,6 @@ export type FiltersState = {
//
// @public (undocumented)
export const HomePageSearchBar: ({
className: defaultClassName,
...props
}: Partial<Omit<SearchBarBaseProps, 'onChange' | 'onSubmit'>>) => JSX.Element;
@@ -41,27 +41,38 @@ export default {
],
};
export const Default = () => {
return (
<Grid container justifyContent="center" spacing={6}>
<Grid container item xs={12} alignItems="center" direction="row">
<HomePageSearchBar placeholder="Search" />
</Grid>
</Grid>
);
};
const useStyles = makeStyles(theme => ({
search: {
searchBar: {
display: 'flex',
maxWidth: '60vw',
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[1],
maxWidth: '60vw',
display: 'flex',
justifyContent: 'space-between',
padding: '8px 0',
borderColor: 'transparent',
borderRadius: '50px',
margin: 'auto',
},
}));
export const Default = () => {
const { search } = useStyles();
export const CustomStyles = () => {
const classes = useStyles();
return (
<Grid container justifyContent="center" spacing={6}>
<Grid container item xs={12} alignItems="center" direction="row">
<HomePageSearchBar className={search} placeholder="Search" />
<HomePageSearchBar
classes={{ root: classes.searchBar }}
placeholder="Search"
/>
</Grid>
</Grid>
);
@@ -21,7 +21,7 @@ import { SearchBarBase, SearchBarBaseProps } from '../SearchBar';
import { useNavigateToQuery } from '../util';
const useStyles = makeStyles({
searchBar: {
root: {
border: '1px solid #555',
borderRadius: '6px',
fontSize: '1.5em',
@@ -42,18 +42,11 @@ export type HomePageSearchBarProps = Partial<
*
* @public
*/
export const HomePageSearchBar = ({
className: defaultClassName,
...props
}: HomePageSearchBarProps) => {
const classes = useStyles();
export const HomePageSearchBar = ({ ...props }: HomePageSearchBarProps) => {
const classes = useStyles(props);
const [query, setQuery] = useState('');
const handleSearch = useNavigateToQuery();
const className = defaultClassName
? `${classes.searchBar} ${defaultClassName}`
: classes.searchBar;
const handleSubmit = () => {
handleSearch({ query });
};
@@ -67,7 +60,7 @@ export const HomePageSearchBar = ({
return (
<SearchBarBase
className={className}
classes={{ root: classes.root }}
value={query}
onSubmit={handleSubmit}
onChange={handleChange}
@@ -1,5 +1,11 @@
# @backstage/plugin-tech-insights-backend
## 0.2.1
### Patch Changes
- ad0a7eb088: Fixed invalid access that caused an immediate crash with a `TypeError` when loading the package.
## 0.2.0
### Minor Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-tech-insights-backend",
"version": "0.2.0",
"version": "0.2.1",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -28,7 +28,8 @@ import { DateTime } from 'luxon';
import { Logger } from 'winston';
import { parseEntityName, stringifyEntityRef } from '@backstage/catalog-model';
import { isMaxItems, isTtl } from '../fact/factRetrievers/utils';
import Transaction = Knex.Transaction;
type Transaction = Knex.Transaction;
export type RawDbFactRow = {
id: string;
@@ -47,6 +47,7 @@ import {
simplifyMkdocsFooter,
scrollIntoAnchor,
transform as transformer,
copyToClipboard,
} from '../transformers';
import { TechDocsSearch } from './TechDocsSearch';
@@ -215,6 +216,8 @@ export const useTechDocsReaderDom = (entityRef: EntityName): Element | null => {
--md-code-fg-color: ${theme.palette.text.primary};
--md-code-bg-color: ${theme.palette.background.paper};
--md-accent-fg-color: ${theme.palette.primary.main};
--md-default-fg-color--lightest: ${theme.palette.textVerySubtle};
}
.md-main__inner { margin-top: 0; }
.md-sidebar { position: fixed; bottom: 100px; width: 20rem; }
@@ -372,6 +375,7 @@ export const useTechDocsReaderDom = (entityRef: EntityName): Element | null => {
async (transformedElement: Element) =>
transformer(transformedElement, [
scrollIntoAnchor(),
copyToClipboard(),
addLinkClickListener({
baseUrl: window.location.origin,
onClick: (event: MouseEvent, url: string) => {
@@ -0,0 +1,49 @@
/*
* 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 { createTestShadowDom } from '../../test-utils';
import { copyToClipboard } from './copyToClipboard';
const clipboardSpy = jest.fn();
Object.defineProperty(navigator, 'clipboard', {
value: {
writeText: clipboardSpy,
},
});
describe('copyToClipboard', () => {
it('calls navigator.clipboard.writeText when clipboard button has been clicked', async () => {
const expectedClipboard = 'function foo() {return "bar";}';
const shadowDom = await createTestShadowDom(
`
<!DOCTYPE html>
<html>
<body>
<code><span>${expectedClipboard}</span></code>
</body>
</html>
`,
{
preTransformers: [],
postTransformers: [copyToClipboard()],
},
);
shadowDom.querySelector('button')?.click();
expect(clipboardSpy).toHaveBeenCalledWith(expectedClipboard);
});
});
@@ -0,0 +1,39 @@
/*
* Copyright 2022 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 type { Transformer } from './transformer';
/**
* Recreates copy-to-clipboard functionality attached to <code> snippets that
* is native to mkdocs-material theme.
*/
export const copyToClipboard = (): Transformer => {
return dom => {
Array.from(dom.querySelectorAll('code')).forEach(codeElem => {
const button = document.createElement('button');
const toBeCopied = codeElem.textContent || '';
button.className = 'md-clipboard md-icon';
button.title = 'Copy to clipboard';
button.innerHTML =
'<svg viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg>';
button.addEventListener('click', () =>
navigator.clipboard.writeText(toBeCopied),
);
codeElem?.parentElement?.prepend(button);
});
return dom;
};
};
@@ -18,6 +18,7 @@ export * from './addBaseUrl';
export * from './addGitFeedbackLink';
export * from './rewriteDocLinks';
export * from './addLinkClickListener';
export * from './copyToClipboard';
export * from './removeMkdocsHeader';
export * from './simplifyMkdocsFooter';
export * from './onCssReady';
+21 -34
View File
@@ -901,12 +901,7 @@
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e"
integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==
"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.13", "@babel/parser@^7.12.7", "@babel/parser@^7.13.16", "@babel/parser@^7.14.2", "@babel/parser@^7.14.5", "@babel/parser@^7.14.9":
version "7.14.9"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.14.9.tgz#596c1ad67608070058ebf8df50c1eaf65db895a4"
integrity sha512-RdUTOseXJ8POjjOeEBEvNMIZU/nm4yu2rufRkcibzkkg7DmQvXU8v3M4Xk9G7uuI86CDGkKcuDWgioqZm+mScQ==
"@babel/parser@^7.14.0", "@babel/parser@^7.16.3", "@babel/parser@^7.16.7":
"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.13", "@babel/parser@^7.12.7", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.2", "@babel/parser@^7.14.5", "@babel/parser@^7.14.9", "@babel/parser@^7.16.3", "@babel/parser@^7.16.7":
version "7.16.7"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.7.tgz#d372dda9c89fcec340a82630a9f533f2fe15877e"
integrity sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==
@@ -5450,9 +5445,9 @@
"@rollup/pluginutils" "^3.0.8"
"@rollup/plugin-node-resolve@^13.0.0":
version "13.0.0"
resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.0.tgz#352f07e430ff377809ec8ec8a6fd636547162dc4"
integrity sha512-41X411HJ3oikIDivT5OKe9EZ6ud6DXudtfNrGbC4nniaxx2esiWjkLOzgnZsWq1IM8YIeL2rzRGLZLBjlhnZtQ==
version "13.1.3"
resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz#2ed277fb3ad98745424c1d2ba152484508a92d79"
integrity sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==
dependencies:
"@rollup/pluginutils" "^3.1.0"
"@types/resolve" "1.17.1"
@@ -6680,9 +6675,9 @@
store2 "^2.12.0"
"@sucrase/jest-plugin@^2.1.1":
version "2.1.1"
resolved "https://registry.npmjs.org/@sucrase/jest-plugin/-/jest-plugin-2.1.1.tgz#b1e5192e7057fec159151b6aed96eb5b3c08d5c4"
integrity sha512-1j+exUcbLRgka2lq/i0IVOYcmrMW1wYPtxJY/+RvZkAQG9GD7lygj5OiHWFKWmynltAg9+x1d5NWQQYNdBTkpQ==
version "2.2.0"
resolved "https://registry.npmjs.org/@sucrase/jest-plugin/-/jest-plugin-2.2.0.tgz#a176ae754a4e142fd50f9952dc6a8d161a1db951"
integrity sha512-eBWmp771YXm0wIftlse4siG98J3HRnZBojhSrvPGYgj+R9Kbf1QeJGMr6iNC0e/0qlKkw01Ig3H8KjPVwUqiGQ==
dependencies:
sucrase "^3.18.0"
@@ -7286,9 +7281,9 @@
integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==
"@types/d3-selection@*", "@types/d3-selection@^3.0.1":
version "3.0.1"
resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.1.tgz#e57b01ab69b18b380f68db97b76ceefe62f17191"
integrity sha512-aJ1d1SCUtERHH65bB8NNoLpUOI3z8kVcfg2BGm4rMMUwuZF4x6qnIEKjT60Vt0o7gP/a/xkRVs4D9CpDifbyRA==
version "3.0.2"
resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.2.tgz#23e48a285b24063630bbe312cc0cfe2276de4a59"
integrity sha512-d29EDd0iUBrRoKhPndhDY6U/PYxOWqgIZwKTooy2UkBfU7TNZNpRho0yLWPxlatQrFWk2mnTu71IZQ4+LRgKlQ==
"@types/d3-shape@^1":
version "1.3.5"
@@ -8398,9 +8393,9 @@
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
"@types/unzipper@^0.10.3":
version "0.10.4"
resolved "https://registry.npmjs.org/@types/unzipper/-/unzipper-0.10.4.tgz#db5be3e1f7d37fdfae290024ffe4f46bdcfa47f2"
integrity sha512-mryXpAwwQadmfjKWoR7NXnELZVlU90xTON1v3Pq2AcOmuAPFkPh09E0X8fpbx2zofoR5zmOIxGqmWOhD0qXE7g==
version "0.10.5"
resolved "https://registry.npmjs.org/@types/unzipper/-/unzipper-0.10.5.tgz#36a963cf025162b4ac31642590cb4192971d633b"
integrity sha512-NrLJb29AdnBARpg9S/4ktfPEisbJ0AvaaAr3j7Q1tg8AgcEUsq2HqbNzvgLRoWyRtjzeLEv7vuL39u1mrNIyNA==
dependencies:
"@types/node" "*"
@@ -8534,9 +8529,9 @@
"@types/yargs-parser" "*"
"@types/yarnpkg__lockfile@^1.1.4":
version "1.1.4"
resolved "https://registry.npmjs.org/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.4.tgz#445251eb00bd9c1e751f82c7c6bf4f714edfd464"
integrity sha512-/emrKCfQMQmFCqRqqBJ0JueHBT06jBRM3e8OgnvDUcvuExONujIk2hFA5dNsN9Nt41ljGVDdChvCydATZ+KOZw==
version "1.1.5"
resolved "https://registry.npmjs.org/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.5.tgz#9639020e1fb65120a2f4387db8f1e8b63efdf229"
integrity sha512-8NYnGOctzsI4W0ApsP/BIHD/LnxpJ6XaGf2AZmz4EyDYJMxtprN4279dLNI1CPZcwC9H18qYcaFv4bXi0wmokg==
"@types/yauzl@^2.9.1":
version "2.9.2"
@@ -18344,9 +18339,9 @@ jscodeshift-find-imports@^2.0.2:
integrity sha512-HxOzjWDOFFSCf8EKSTQGqCxXeRFqZszOywnZ0HuMB9YPDFHVpxftGRsY+QS+Qq8o2qUojlmNU3JEHts5DWYS1A==
jscodeshift@^0.13.0:
version "0.13.0"
resolved "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.13.0.tgz#4b3835c3755ea86bc4910ac80acd4acd230b53ee"
integrity sha512-FNHLuwh7TeI0F4EzNVIRwUSxSqsGWM5nTv596FK4NfBnEEKFpIcyFeG559DMFGHSTIYA5AY4Fqh2cBrJx0EAwg==
version "0.13.1"
resolved "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.13.1.tgz#69bfe51e54c831296380585c6d9e733512aecdef"
integrity sha512-lGyiEbGOvmMRKgWk4vf+lUrCWO/8YR8sUR3FKF1Cq5fovjZDlIcw3Hu5ppLHAnEXshVffvaM0eyuY/AbOeYpnQ==
dependencies:
"@babel/core" "^7.13.16"
"@babel/parser" "^7.13.16"
@@ -18358,7 +18353,7 @@ jscodeshift@^0.13.0:
"@babel/preset-typescript" "^7.13.0"
"@babel/register" "^7.13.16"
babel-core "^7.0.0-bridge.0"
colors "^1.1.2"
chalk "^4.1.2"
flow-parser "0.*"
graceful-fs "^4.2.4"
micromatch "^3.1.10"
@@ -24829,7 +24824,7 @@ resolve-url@^0.2.1:
resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
resolve@^1.1.6:
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.9.0:
version "1.21.0"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz#b51adc97f3472e6a5cf4444d34bc9d6b9037591f"
integrity sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==
@@ -24838,14 +24833,6 @@ resolve@^1.1.6:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.9.0:
version "1.20.0"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
dependencies:
is-core-module "^2.2.0"
path-parse "^1.0.6"
resolve@^2.0.0-next.3:
version "2.0.0-next.3"
resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"