From c4baa2400946979d04dc9c35ac6eb2e003db0b38 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:29:56 +0200 Subject: [PATCH 1/9] introduce new search-react package Signed-off-by: Emma Indal --- plugins/search-react/.eslintrc.js | 1 + plugins/search-react/README.md | 1 + plugins/search-react/api-report.md | 64 ++++ plugins/search-react/package.json | 53 ++++ plugins/search-react/src/api.ts | 32 ++ .../src/context/SearchContext.test.tsx | 287 ++++++++++++++++++ .../src/context/SearchContext.tsx | 144 +++++++++ .../SearchContextForStorybook.stories.tsx | 52 ++++ plugins/search-react/src/context/index.tsx | 26 ++ plugins/search-react/src/index.ts | 18 ++ plugins/search-react/src/setupTests.ts | 17 ++ 11 files changed, 695 insertions(+) create mode 100644 plugins/search-react/.eslintrc.js create mode 100644 plugins/search-react/README.md create mode 100644 plugins/search-react/api-report.md create mode 100644 plugins/search-react/package.json create mode 100644 plugins/search-react/src/api.ts create mode 100644 plugins/search-react/src/context/SearchContext.test.tsx create mode 100644 plugins/search-react/src/context/SearchContext.tsx create mode 100644 plugins/search-react/src/context/SearchContextForStorybook.stories.tsx create mode 100644 plugins/search-react/src/context/index.tsx create mode 100644 plugins/search-react/src/index.ts create mode 100644 plugins/search-react/src/setupTests.ts diff --git a/plugins/search-react/.eslintrc.js b/plugins/search-react/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/search-react/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/search-react/README.md b/plugins/search-react/README.md new file mode 100644 index 0000000000..9683a4a5f7 --- /dev/null +++ b/plugins/search-react/README.md @@ -0,0 +1 @@ +# search react diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md new file mode 100644 index 0000000000..ee8c7b1224 --- /dev/null +++ b/plugins/search-react/api-report.md @@ -0,0 +1,64 @@ +## API Report File for "@backstage/plugin-search-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ApiRef } from '@backstage/core-plugin-api'; +import { AsyncState } from 'react-use/lib/useAsync'; +import { ComponentProps } from 'react'; +import { JsonObject } from '@backstage/types'; +import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; +import { SearchQuery } from '@backstage/plugin-search-common'; +import { SearchResultSet } from '@backstage/plugin-search-common'; + +// @public (undocumented) +export interface SearchApi { + // (undocumented) + query(query: SearchQuery): Promise; +} + +// Warning: (ae-forgotten-export) The symbol "QueryResultProps" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "SearchApiProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function SearchApiProviderForStorybook( + props: PropsWithChildren, +): JSX.Element; + +// @public (undocumented) +export const searchApiRef: ApiRef; + +// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +export const SearchContext: React_2.Context; + +// @public (undocumented) +export const SearchContextProvider: ({ + initialState, + children, +}: React_2.PropsWithChildren<{ + initialState?: SearchContextState | undefined; +}>) => JSX.Element; + +// Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export const SearchContextProviderForStorybook: ( + props: ComponentProps & QueryResultProps, +) => JSX.Element; + +// @public +export type SearchContextState = { + term: string; + types: string[]; + filters: JsonObject; + pageCursor?: string; +}; + +// @public (undocumented) +export const useSearch: () => SearchContextValue; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json new file mode 100644 index 0000000000..66b6bdfa46 --- /dev/null +++ b/plugins/search-react/package.json @@ -0,0 +1,53 @@ +{ + "name": "@backstage/plugin-search-react", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "web-library" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/search-react" + }, + "keywords": [ + "backstage" + ], + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "clean": "backstage-cli package clean", + "start": "backstage-cli package start" + }, + "dependencies": { + "@backstage/plugin-search-common": "^0.3.2", + "@backstage/core-plugin-api": "^1.0.0", + "@backstage/core-app-api": "^1.0.1-next.0", + "react-use": "^17.3.2", + "@backstage/types": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.13.1 || ^17.0.0", + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/test-utils": "^1.0.0", + "@testing-library/react": "^13.0.0", + "@testing-library/react-hooks": "^8.0.0", + "@testing-library/jest-dom": "^5.16.4" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/search-react/src/api.ts b/plugins/search-react/src/api.ts new file mode 100644 index 0000000000..eb8c9c23db --- /dev/null +++ b/plugins/search-react/src/api.ts @@ -0,0 +1,32 @@ +/* + * 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 { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; +import { createApiRef } from '@backstage/core-plugin-api'; + +/** + * @public + */ +export const searchApiRef = createApiRef({ + id: 'plugin.search.queryservice', +}); + +/** + * @public + */ +export interface SearchApi { + query(query: SearchQuery): Promise; +} diff --git a/plugins/search-react/src/context/SearchContext.test.tsx b/plugins/search-react/src/context/SearchContext.test.tsx new file mode 100644 index 0000000000..b19953f6a5 --- /dev/null +++ b/plugins/search-react/src/context/SearchContext.test.tsx @@ -0,0 +1,287 @@ +/* + * 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 { useApi } from '@backstage/core-plugin-api'; +import { render, screen, waitFor } from '@testing-library/react'; +import { act, renderHook } from '@testing-library/react-hooks'; +import React from 'react'; +import { SearchContextProvider, useSearch } from './SearchContext'; + +jest.mock('@backstage/core-plugin-api', () => ({ + ...jest.requireActual('@backstage/core-plugin-api'), + useApi: jest.fn(), +})); + +describe('SearchContext', () => { + const query = jest.fn(); + + const wrapper = ({ children, initialState }: any) => ( + + {children} + + ); + + const initialState = { + term: '', + filters: {}, + types: ['*'], + }; + + beforeEach(() => { + query.mockResolvedValue({}); + (useApi as jest.Mock).mockReturnValue({ query: query }); + }); + + afterAll(() => { + jest.resetAllMocks(); + }); + + it('Passes children', async () => { + const text = 'text'; + + render( + + {text} + , + ); + + await waitFor(() => { + expect(screen.getByText(text)).toBeInTheDocument(); + }); + }); + + it('Throws error when no context is set', () => { + const { result } = renderHook(() => useSearch()); + + expect(result.error).toEqual( + Error('useSearch must be used within a SearchContextProvider'), + ); + }); + + it('Uses initial state values', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + expect(result.current).toEqual(expect.objectContaining(initialState)); + }); + + it('Resets cursor when term is set (and different from previous)', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState: { + ...initialState, + pageCursor: 'SOMEPAGE', + }, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toEqual('SOMEPAGE'); + + act(() => { + result.current.setTerm('first term'); + }); + + act(() => { + result.current.setPageCursor('OTHERPAGE'); + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toEqual('OTHERPAGE'); + + act(() => { + result.current.setTerm('second term'); + }); + + await waitForNextUpdate(); + + expect(result.current.pageCursor).toEqual(undefined); + }); + + describe('Performs search (and sets results)', () => { + it('When term is set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + const term = 'term'; + + act(() => { + result.current.setTerm(term); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + filters: {}, + types: ['*'], + term, + }); + }); + + it('When filters are set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + const filters = { filter: 'filter' }; + + act(() => { + result.current.setFilters(filters); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + filters, + types: ['*'], + term: '', + }); + }); + + it('When page is set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + act(() => { + result.current.setPageCursor('SOMEPAGE'); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + filters: {}, + types: ['*'], + pageCursor: 'SOMEPAGE', + term: '', + }); + }); + + it('When types is set', async () => { + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + const types = ['type']; + + act(() => { + result.current.setTypes(types); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + types, + filters: {}, + term: '', + }); + }); + + it('provides function for fetch the next page', async () => { + query.mockResolvedValue({ + results: [], + nextPageCursor: 'NEXT', + }); + + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.fetchNextPage).toBeDefined(); + expect(result.current.fetchPreviousPage).toBeUndefined(); + + act(() => { + result.current.fetchNextPage!(); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + types: ['*'], + filters: {}, + term: '', + pageCursor: 'NEXT', + }); + }); + + it('provides function for fetch the previous page', async () => { + query.mockResolvedValue({ + results: [], + previousPageCursor: 'PREVIOUS', + }); + + const { result, waitForNextUpdate } = renderHook(() => useSearch(), { + wrapper, + initialProps: { + initialState, + }, + }); + + await waitForNextUpdate(); + + expect(result.current.fetchNextPage).toBeUndefined(); + expect(result.current.fetchPreviousPage).toBeDefined(); + + act(() => { + result.current.fetchPreviousPage!(); + }); + + await waitForNextUpdate(); + + expect(query).toHaveBeenLastCalledWith({ + types: ['*'], + filters: {}, + term: '', + pageCursor: 'PREVIOUS', + }); + }); + }); +}); diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx new file mode 100644 index 0000000000..217c94cca2 --- /dev/null +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -0,0 +1,144 @@ +/* + * 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 { JsonObject } from '@backstage/types'; +import { useApi, AnalyticsContext } from '@backstage/core-plugin-api'; +import { SearchResultSet } from '@backstage/plugin-search-common'; +import React, { + createContext, + PropsWithChildren, + useCallback, + useContext, + useEffect, + useState, +} from 'react'; +import useAsync, { AsyncState } from 'react-use/lib/useAsync'; +import usePrevious from 'react-use/lib/usePrevious'; +import { searchApiRef } from '../api'; + +type SearchContextValue = { + result: AsyncState; + setTerm: React.Dispatch>; + setTypes: React.Dispatch>; + setFilters: React.Dispatch>; + setPageCursor: React.Dispatch>; + fetchNextPage?: React.DispatchWithoutAction; + fetchPreviousPage?: React.DispatchWithoutAction; +} & SearchContextState; + +/** + * The initial state of `SearchContextProvider`. + * + * @public + */ +export type SearchContextState = { + term: string; + types: string[]; + filters: JsonObject; + pageCursor?: string; +}; + +/** + * @public + */ +export const SearchContext = createContext( + undefined, +); + +const searchInitialState: SearchContextState = { + term: '', + pageCursor: undefined, + filters: {}, + types: [], +}; + +/** + * @public + */ +export const SearchContextProvider = ({ + initialState = searchInitialState, + children, +}: PropsWithChildren<{ initialState?: SearchContextState }>) => { + const searchApi = useApi(searchApiRef); + const [pageCursor, setPageCursor] = useState( + initialState.pageCursor, + ); + const [filters, setFilters] = useState(initialState.filters); + const [term, setTerm] = useState(initialState.term); + const [types, setTypes] = useState(initialState.types); + + const prevTerm = usePrevious(term); + + const result = useAsync( + () => + searchApi.query({ + term, + filters, + pageCursor, + types, + }), + [term, filters, types, pageCursor], + ); + + const hasNextPage = + !result.loading && !result.error && result.value?.nextPageCursor; + const hasPreviousPage = + !result.loading && !result.error && result.value?.previousPageCursor; + const fetchNextPage = useCallback(() => { + setPageCursor(result.value?.nextPageCursor); + }, [result.value?.nextPageCursor]); + const fetchPreviousPage = useCallback(() => { + setPageCursor(result.value?.previousPageCursor); + }, [result.value?.previousPageCursor]); + + useEffect(() => { + // Any time a term is reset, we want to start from page 0. + if (term && prevTerm && term !== prevTerm) { + setPageCursor(undefined); + } + }, [term, prevTerm, initialState.pageCursor]); + + const value: SearchContextValue = { + result, + filters, + setFilters, + term, + setTerm, + types, + setTypes, + pageCursor, + setPageCursor, + fetchNextPage: hasNextPage ? fetchNextPage : undefined, + fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined, + }; + + return ( + + + + ); +}; + +/** + * @public + */ +export const useSearch = () => { + const context = useContext(SearchContext); + if (context === undefined) { + throw new Error('useSearch must be used within a SearchContextProvider'); + } + return context; +}; diff --git a/plugins/search-react/src/context/SearchContextForStorybook.stories.tsx b/plugins/search-react/src/context/SearchContextForStorybook.stories.tsx new file mode 100644 index 0000000000..51297c965f --- /dev/null +++ b/plugins/search-react/src/context/SearchContextForStorybook.stories.tsx @@ -0,0 +1,52 @@ +/* + * 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 { ApiProvider } from '@backstage/core-app-api'; +import { SearchResultSet } from '@backstage/plugin-search-common'; +import { TestApiRegistry } from '@backstage/test-utils'; +import React, { ComponentProps, PropsWithChildren } from 'react'; +import { searchApiRef } from '../api'; +import { SearchContextProvider as RealSearchContextProvider } from './SearchContext'; + +type QueryResultProps = { + mockedResults?: SearchResultSet; +}; + +/** + * Utility context provider only for use in Storybook stories. You should use + * the real `` exported by `@backstage/plugin-search-react` in + * your app instead of this! In some cases (like the search page) it may + * already be provided on your behalf. + */ +export const SearchContextProvider = ( + props: ComponentProps & QueryResultProps, +) => { + return ( + + + + ); +}; + +/** + * Utility api provider only for use in Storybook stories. + * + */ +export function SearchApiProvider(props: PropsWithChildren) { + const { mockedResults, children } = props; + const query: any = () => Promise.resolve(mockedResults || {}); + const apiRegistry = TestApiRegistry.from([searchApiRef, { query }]); + return ; +} diff --git a/plugins/search-react/src/context/index.tsx b/plugins/search-react/src/context/index.tsx new file mode 100644 index 0000000000..f2ea486e9d --- /dev/null +++ b/plugins/search-react/src/context/index.tsx @@ -0,0 +1,26 @@ +/* + * 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. + */ + +export { + SearchContextProvider, + SearchContext, + useSearch, +} from './SearchContext'; +export type { SearchContextState } from './SearchContext'; +export { + SearchContextProvider as SearchContextProviderForStorybook, + SearchApiProvider as SearchApiProviderForStorybook, +} from './SearchContextForStorybook.stories'; diff --git a/plugins/search-react/src/index.ts b/plugins/search-react/src/index.ts new file mode 100644 index 0000000000..498e4d6ce3 --- /dev/null +++ b/plugins/search-react/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2021 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. + */ + +export * from './api'; +export * from './context'; diff --git a/plugins/search-react/src/setupTests.ts b/plugins/search-react/src/setupTests.ts new file mode 100644 index 0000000000..992b60d3a4 --- /dev/null +++ b/plugins/search-react/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2021 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 '@testing-library/jest-dom'; From bc31ff1bbd192a5d21b7b02f63d82536cbb636ca Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:38:19 +0200 Subject: [PATCH 2/9] move home default template story to the app Signed-off-by: Emma Indal --- .../home}/templates/DefaultTemplate.stories.tsx | 12 ++++-------- .../home}/templates/TemplateBackstageLogo.tsx | 0 .../home}/templates/TemplateBackstageLogoIcon.tsx | 0 .../app/src/components/home}/templates/index.ts | 0 storybook/.storybook/main.js | 1 + 5 files changed, 5 insertions(+), 8 deletions(-) rename {plugins/home/src => packages/app/src/components/home}/templates/DefaultTemplate.stories.tsx (95%) rename {plugins/home/src => packages/app/src/components/home}/templates/TemplateBackstageLogo.tsx (100%) rename {plugins/home/src => packages/app/src/components/home}/templates/TemplateBackstageLogoIcon.tsx (100%) rename {plugins/home/src => packages/app/src/components/home}/templates/index.ts (100%) diff --git a/plugins/home/src/templates/DefaultTemplate.stories.tsx b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx similarity index 95% rename from plugins/home/src/templates/DefaultTemplate.stories.tsx rename to packages/app/src/components/home/templates/DefaultTemplate.stories.tsx index e2e570dcf6..b2f6034709 100644 --- a/plugins/home/src/templates/DefaultTemplate.stories.tsx +++ b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx @@ -20,8 +20,8 @@ import { HomePageToolkit, HomePageCompanyLogo, HomePageStarredEntities, -} from '../plugin'; -import { wrapInTestApp, TestApiProvider} from '@backstage/test-utils'; +} from '@backstage/plugin-home'; +import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; import { Content, Page, InfoCard } from '@backstage/core-components'; import { starredEntitiesApiRef, @@ -32,10 +32,9 @@ import { configApiRef } from '@backstage/core-plugin-api'; import { ConfigReader } from '@backstage/config'; import { HomePageSearchBar, - SearchContextProvider, - searchApiRef, searchPlugin, } from '@backstage/plugin-search'; +import { searchApiRef, SearchContextProvider } from '@backstage/plugin-search-react'; import { HomePageStackOverflowQuestions } from '@backstage/plugin-stack-overflow'; import { Grid, makeStyles } from '@material-ui/core'; import React, { ComponentType } from 'react'; @@ -54,10 +53,7 @@ export default { <> Promise.resolve({ results: [] }) }], [ configApiRef, diff --git a/plugins/home/src/templates/TemplateBackstageLogo.tsx b/packages/app/src/components/home/templates/TemplateBackstageLogo.tsx similarity index 100% rename from plugins/home/src/templates/TemplateBackstageLogo.tsx rename to packages/app/src/components/home/templates/TemplateBackstageLogo.tsx diff --git a/plugins/home/src/templates/TemplateBackstageLogoIcon.tsx b/packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx similarity index 100% rename from plugins/home/src/templates/TemplateBackstageLogoIcon.tsx rename to packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx diff --git a/plugins/home/src/templates/index.ts b/packages/app/src/components/home/templates/index.ts similarity index 100% rename from plugins/home/src/templates/index.ts rename to packages/app/src/components/home/templates/index.ts diff --git a/storybook/.storybook/main.js b/storybook/.storybook/main.js index 2356e4e41b..8ed4949cf3 100644 --- a/storybook/.storybook/main.js +++ b/storybook/.storybook/main.js @@ -6,6 +6,7 @@ const WebpackPluginFailBuildOnWarning = require('./webpack-plugin-fail-build-on- */ const BACKSTAGE_CORE_STORIES = [ 'packages/core-components', + 'packages/app', 'plugins/org', 'plugins/search', 'plugins/home', From 09cba0bdaee0b077befe8e46790740298c6fae6a Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:41:59 +0200 Subject: [PATCH 3/9] deprecate search api ref, search api interface and search context in plugin-search Signed-off-by: Emma Indal --- plugins/search/src/apis.ts | 7 + .../SearchContext/SearchContext.test.tsx | 287 ------------------ .../SearchContext/SearchContext.tsx | 9 + .../SearchContextForStorybook.stories.tsx | 48 --- 4 files changed, 16 insertions(+), 335 deletions(-) delete mode 100644 plugins/search/src/components/SearchContext/SearchContext.test.tsx delete mode 100644 plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx diff --git a/plugins/search/src/apis.ts b/plugins/search/src/apis.ts index 908942d87d..62f65dbe4a 100644 --- a/plugins/search/src/apis.ts +++ b/plugins/search/src/apis.ts @@ -21,12 +21,19 @@ import { } from '@backstage/core-plugin-api'; import { ResponseError } from '@backstage/errors'; import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; + import qs from 'qs'; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const searchApiRef = createApiRef({ id: 'plugin.search.queryservice', }); +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export interface SearchApi { query(query: SearchQuery): Promise; } diff --git a/plugins/search/src/components/SearchContext/SearchContext.test.tsx b/plugins/search/src/components/SearchContext/SearchContext.test.tsx deleted file mode 100644 index 6513dc21bb..0000000000 --- a/plugins/search/src/components/SearchContext/SearchContext.test.tsx +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2021 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 { useApi } from '@backstage/core-plugin-api'; -import { render, screen, waitFor } from '@testing-library/react'; -import { act, renderHook } from '@testing-library/react-hooks'; -import React from 'react'; -import { SearchContextProvider, useSearch } from './SearchContext'; - -jest.mock('@backstage/core-plugin-api', () => ({ - ...jest.requireActual('@backstage/core-plugin-api'), - useApi: jest.fn(), -})); - -describe('SearchContext', () => { - const query = jest.fn(); - - const wrapper = ({ children, initialState }: any) => ( - - {children} - - ); - - const initialState = { - term: '', - filters: {}, - types: ['*'], - }; - - beforeEach(() => { - query.mockResolvedValue({}); - (useApi as jest.Mock).mockReturnValue({ query: query }); - }); - - afterAll(() => { - jest.resetAllMocks(); - }); - - it('Passes children', async () => { - const text = 'text'; - - render( - - {text} - , - ); - - await waitFor(() => { - expect(screen.getByText(text)).toBeInTheDocument(); - }); - }); - - it('Throws error when no context is set', () => { - const { result } = renderHook(() => useSearch()); - - expect(result.error).toEqual( - Error('useSearch must be used within a SearchContextProvider'), - ); - }); - - it('Uses initial state values', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current).toEqual(expect.objectContaining(initialState)); - }); - - it('Resets cursor when term is set (and different from previous)', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState: { - ...initialState, - pageCursor: 'SOMEPAGE', - }, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual('SOMEPAGE'); - - act(() => { - result.current.setTerm('first term'); - }); - - act(() => { - result.current.setPageCursor('OTHERPAGE'); - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual('OTHERPAGE'); - - act(() => { - result.current.setTerm('second term'); - }); - - await waitForNextUpdate(); - - expect(result.current.pageCursor).toEqual(undefined); - }); - - describe('Performs search (and sets results)', () => { - it('When term is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const term = 'term'; - - act(() => { - result.current.setTerm(term); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters: {}, - types: ['*'], - term, - }); - }); - - it('When filters are set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const filters = { filter: 'filter' }; - - act(() => { - result.current.setFilters(filters); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters, - types: ['*'], - term: '', - }); - }); - - it('When page is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - act(() => { - result.current.setPageCursor('SOMEPAGE'); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - filters: {}, - types: ['*'], - pageCursor: 'SOMEPAGE', - term: '', - }); - }); - - it('When types is set', async () => { - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - const types = ['type']; - - act(() => { - result.current.setTypes(types); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types, - filters: {}, - term: '', - }); - }); - - it('provides function for fetch the next page', async () => { - query.mockResolvedValue({ - results: [], - nextPageCursor: 'NEXT', - }); - - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.fetchNextPage).toBeDefined(); - expect(result.current.fetchPreviousPage).toBeUndefined(); - - act(() => { - result.current.fetchNextPage!(); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types: ['*'], - filters: {}, - term: '', - pageCursor: 'NEXT', - }); - }); - - it('provides function for fetch the previous page', async () => { - query.mockResolvedValue({ - results: [], - previousPageCursor: 'PREVIOUS', - }); - - const { result, waitForNextUpdate } = renderHook(() => useSearch(), { - wrapper, - initialProps: { - initialState, - }, - }); - - await waitForNextUpdate(); - - expect(result.current.fetchNextPage).toBeUndefined(); - expect(result.current.fetchPreviousPage).toBeDefined(); - - act(() => { - result.current.fetchPreviousPage!(); - }); - - await waitForNextUpdate(); - - expect(query).toHaveBeenLastCalledWith({ - types: ['*'], - filters: {}, - term: '', - pageCursor: 'PREVIOUS', - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchContext/SearchContext.tsx b/plugins/search/src/components/SearchContext/SearchContext.tsx index 100d8a3ac3..d52e43af88 100644 --- a/plugins/search/src/components/SearchContext/SearchContext.tsx +++ b/plugins/search/src/components/SearchContext/SearchContext.tsx @@ -51,6 +51,9 @@ export type SearchContextState = { pageCursor?: string; }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const SearchContext = createContext( undefined, ); @@ -62,6 +65,9 @@ const searchInitialState: SearchContextState = { types: [], }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const SearchContextProvider = ({ initialState = searchInitialState, children, @@ -126,6 +132,9 @@ export const SearchContextProvider = ({ ); }; +/** + * @deprecated import from "@backstage/plugin-search-react" instead + */ export const useSearch = () => { const context = useContext(SearchContext); if (context === undefined) { diff --git a/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx b/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx deleted file mode 100644 index 7d6c35b00c..0000000000 --- a/plugins/search/src/components/SearchContext/SearchContextForStorybook.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2021 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 { ApiProvider } from '@backstage/core-app-api'; -import { SearchResultSet } from '@backstage/plugin-search-common'; -import { TestApiRegistry } from '@backstage/test-utils'; -import React, { ComponentProps, PropsWithChildren } from 'react'; -import { searchApiRef } from '../../apis'; -import { SearchContextProvider as RealSearchContextProvider } from './SearchContext'; - -type QueryResultProps = { - mockedResults?: SearchResultSet; -}; - -/** - * Utility context provider only for use in Storybook stories. You should use - * the real `` exported by `@backstage/plugin-search` in - * your app instead of this! In some cases (like the search page) it may - * already be provided on your behalf. - */ -export const SearchContextProvider = ( - props: ComponentProps & QueryResultProps, -) => { - return ( - - - - ); -}; - -export function SearchApiProvider(props: PropsWithChildren) { - const { mockedResults, children } = props; - const query: any = () => Promise.resolve(mockedResults || {}); - const apiRegistry = TestApiRegistry.from([searchApiRef, { query }]); - return ; -} From 301b4606e3823665e1b60b9cbc9ac1ab488f5954 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:42:57 +0200 Subject: [PATCH 4/9] import from new search-react package Signed-off-by: Emma Indal --- plugins/home/package.json | 2 +- plugins/search/package.json | 1 + .../SearchBar/SearchBar.stories.tsx | 6 +- .../SearchFilter/SearchFilter.stories.tsx | 6 +- .../SearchModal/SearchModal.stories.tsx | 6 +- .../SearchResult/SearchResult.stories.tsx | 7 +- .../SearchType/SearchType.stories.tsx | 6 +- plugins/techdocs/package.json | 2 +- .../src/reader/components/Reader.test.tsx | 2 +- .../components/TechDocsReaderPage.test.tsx | 2 +- .../search/components/TechDocsSearch.test.tsx | 2 +- .../src/search/components/TechDocsSearch.tsx | 5 +- yarn.lock | 99 +++++++++++++++++++ 13 files changed, 125 insertions(+), 21 deletions(-) diff --git a/plugins/home/package.json b/plugins/home/package.json index 43b474704a..e59e7a39bb 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -38,7 +38,7 @@ "@backstage/core-components": "^0.9.3-next.1", "@backstage/core-plugin-api": "^1.0.0", "@backstage/plugin-catalog-react": "^1.0.1-next.2", - "@backstage/plugin-search": "^0.7.5-next.0", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-stack-overflow": "^0.1.0-next.0", "@backstage/theme": "^0.2.15", "@backstage/config": "^1.0.0", diff --git a/plugins/search/package.json b/plugins/search/package.json index c32e830950..4ac891775e 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -39,6 +39,7 @@ "@backstage/core-plugin-api": "^1.0.0", "@backstage/errors": "^1.0.0", "@backstage/plugin-catalog-react": "^1.0.1-next.1", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-search-common": "^0.3.3-next.1", "@backstage/theme": "^0.2.15", "@backstage/types": "^1.0.0", diff --git a/plugins/search/src/components/SearchBar/SearchBar.stories.tsx b/plugins/search/src/components/SearchBar/SearchBar.stories.tsx index c0d4b07965..72c7deb06b 100644 --- a/plugins/search/src/components/SearchBar/SearchBar.stories.tsx +++ b/plugins/search/src/components/SearchBar/SearchBar.stories.tsx @@ -16,7 +16,7 @@ import { Grid, makeStyles, Paper } from '@material-ui/core'; import React, { ComponentType } from 'react'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchBar } from './SearchBar'; export default { @@ -24,13 +24,13 @@ export default { component: SearchBar, decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], }; diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx index c43753e8d2..3c49b76699 100644 --- a/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx +++ b/plugins/search/src/components/SearchFilter/SearchFilter.stories.tsx @@ -16,7 +16,7 @@ import { Grid, Paper } from '@material-ui/core'; import React, { ComponentType } from 'react'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchFilter } from './SearchFilter'; export default { @@ -24,13 +24,13 @@ export default { component: SearchFilter, decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], }; diff --git a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx index aa0ad0479a..a1d9517674 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx @@ -18,7 +18,7 @@ import { wrapInTestApp } from '@backstage/test-utils'; import { Button } from '@material-ui/core'; import React, { ComponentType } from 'react'; import { rootRouteRef } from '../../plugin'; -import { SearchApiProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchApiProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchModal } from './SearchModal'; import { useSearchModal } from './useSearchModal'; @@ -57,9 +57,9 @@ export default { decorators: [ (Story: ComponentType<{}>) => wrapInTestApp( - + - , + , { mountedRoutes: { '/search': rootRouteRef } }, ), ], diff --git a/plugins/search/src/components/SearchResult/SearchResult.stories.tsx b/plugins/search/src/components/SearchResult/SearchResult.stories.tsx index c1685df2c1..4a3d950164 100644 --- a/plugins/search/src/components/SearchResult/SearchResult.stories.tsx +++ b/plugins/search/src/components/SearchResult/SearchResult.stories.tsx @@ -19,7 +19,8 @@ import { List, ListItem } from '@material-ui/core'; import React, { ComponentType } from 'react'; import { MemoryRouter } from 'react-router'; import { DefaultResultListItem } from '../DefaultResultListItem'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; + +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchResult } from './SearchResult'; const mockResults = { @@ -57,9 +58,9 @@ export default { decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], diff --git a/plugins/search/src/components/SearchType/SearchType.stories.tsx b/plugins/search/src/components/SearchType/SearchType.stories.tsx index 596c4a027a..b56f4c089c 100644 --- a/plugins/search/src/components/SearchType/SearchType.stories.tsx +++ b/plugins/search/src/components/SearchType/SearchType.stories.tsx @@ -19,7 +19,7 @@ import CatalogIcon from '@material-ui/icons/MenuBook'; import DocsIcon from '@material-ui/icons/Description'; import UsersGroupsIcon from '@material-ui/icons/Person'; import React, { ComponentType } from 'react'; -import { SearchContextProvider } from '../SearchContext/SearchContextForStorybook.stories'; +import { SearchContextProviderForStorybook } from '@backstage/plugin-search-react'; import { SearchType } from './SearchType'; export default { @@ -27,13 +27,13 @@ export default { component: SearchType, decorators: [ (Story: ComponentType<{}>) => ( - + - + ), ], }; diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 8516c09783..b6901e8edd 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -43,7 +43,7 @@ "@backstage/integration": "^1.1.0-next.1", "@backstage/integration-react": "^1.0.1-next.1", "@backstage/plugin-catalog-react": "^1.0.1-next.2", - "@backstage/plugin-search": "^0.7.5-next.0", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/theme": "^0.2.15", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/plugins/techdocs/src/reader/components/Reader.test.tsx b/plugins/techdocs/src/reader/components/Reader.test.tsx index 6e8609694d..09cd33e286 100644 --- a/plugins/techdocs/src/reader/components/Reader.test.tsx +++ b/plugins/techdocs/src/reader/components/Reader.test.tsx @@ -25,7 +25,7 @@ import React from 'react'; import { TechDocsStorageApi, techdocsStorageApiRef } from '../../api'; import { Reader } from './Reader'; import { ApiProvider } from '@backstage/core-app-api'; -import { searchApiRef } from '@backstage/plugin-search'; +import { searchApiRef } from '@backstage/plugin-search-react'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx index 55637806a3..9fbf5c2195 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage.test.tsx @@ -30,7 +30,7 @@ import { TechDocsStorageApi, } from '../../api'; import { ApiProvider } from '@backstage/core-app-api'; -import { searchApiRef } from '@backstage/plugin-search'; +import { searchApiRef } from '@backstage/plugin-search-react'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); diff --git a/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx b/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx index 06d5ac6aac..5957aecc4d 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearch.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import { ApiProvider } from '@backstage/core-app-api'; -import { searchApiRef } from '@backstage/plugin-search'; +import { searchApiRef } from '@backstage/plugin-search-react'; import { TestApiRegistry, wrapInTestApp } from '@backstage/test-utils'; import { act, diff --git a/plugins/techdocs/src/search/components/TechDocsSearch.tsx b/plugins/techdocs/src/search/components/TechDocsSearch.tsx index 30cc692b7c..f11fa38948 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearch.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearch.tsx @@ -15,7 +15,10 @@ */ import { CompoundEntityRef } from '@backstage/catalog-model'; -import { SearchContextProvider, useSearch } from '@backstage/plugin-search'; +import { + SearchContextProvider, + useSearch, +} from '@backstage/plugin-search-react'; import { makeStyles, CircularProgress, diff --git a/yarn.lock b/yarn.lock index 4919937660..b5f327b6e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1478,6 +1478,22 @@ lodash "^4.17.21" uuid "^8.0.0" +"@backstage/core-app-api@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@backstage/core-app-api/-/core-app-api-1.0.0.tgz#2dae97b050b2f2e5ec1ea42b3d95c57e8bf434d6" + integrity sha512-hmoFMPCxAfHgDPQTHbf6rquiG0SCSycWTUrScpYeLwkH3UOekgX8o8ThKT0t3w7WPx83LwT0NqcbSH6zqI9nag== + dependencies: + "@backstage/config" "^1.0.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/types" "^1.0.0" + "@backstage/version-bridge" "^1.0.0" + "@types/prop-types" "^15.7.3" + prop-types "^15.7.2" + react-router-dom "6.0.0-beta.0" + react-use "^17.2.4" + zen-observable "^0.8.15" + zod "^3.11.6" + "@backstage/core-components@^0.9.0", "@backstage/core-components@^0.9.2": version "0.9.2" resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.9.2.tgz#9a3d79a15039256bbc007e5daa08c983050e0238" @@ -1602,6 +1618,36 @@ react-use "^17.2.4" swr "^1.1.2" +"@backstage/plugin-search-common@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@backstage/plugin-search-common/-/plugin-search-common-0.3.2.tgz#15984ba4c14f8a9119168e8c79344ef8101863dc" + integrity sha512-7vcpRo+5MB/QW/M77zPfcqxw0LzcQCHNXql0uxF+qBwVPJSHz9QB+YBuzGyaAlqfm5UPFXuweLQGqtoB+0DMLg== + dependencies: + "@backstage/plugin-permission-common" "^0.5.3" + "@backstage/types" "^1.0.0" + +"@backstage/test-utils@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@backstage/test-utils/-/test-utils-1.0.0.tgz#dafac18065591a7dda584811cb00812495292ee8" + integrity sha512-dHtIjhoq2b+rpsnwVQnWA/2sDxFMt2HL0OxoyKqG2NRum16A7cTQxgrG3UC3p4dqFYKREg7+aTFIjHBa+Tk/PA== + dependencies: + "@backstage/config" "^1.0.0" + "@backstage/core-app-api" "^1.0.0" + "@backstage/core-plugin-api" "^1.0.0" + "@backstage/plugin-permission-common" "^0.5.3" + "@backstage/plugin-permission-react" "^0.3.4" + "@backstage/theme" "^0.2.15" + "@backstage/types" "^1.0.0" + "@material-ui/core" "^4.12.2" + "@material-ui/icons" "^4.11.2" + "@testing-library/jest-dom" "^5.10.1" + "@testing-library/react" "^12.1.3" + "@testing-library/user-event" "^13.1.8" + cross-fetch "^3.1.5" + react-router "6.0.0-beta.0" + react-router-dom "6.0.0-beta.0" + zen-observable "^0.8.15" + "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -5545,6 +5591,20 @@ lz-string "^1.4.4" pretty-format "^27.0.2" +"@testing-library/dom@^8.5.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz#bc00bdd64c7d8b40841e27a70211399ad3af46f5" + integrity sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^5.0.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.4.4" + pretty-format "^27.0.2" + "@testing-library/jest-dom@^5.10.1": version "5.16.3" resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz#b76851a909586113c20486f1679ffb4d8ec27bfa" @@ -5560,6 +5620,21 @@ lodash "^4.17.15" redent "^3.0.0" +"@testing-library/jest-dom@^5.16.4": + version "5.16.4" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" + integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== + dependencies: + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + "@testing-library/react-hooks@^7.0.2": version "7.0.2" resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" @@ -5571,6 +5646,14 @@ "@types/react-test-renderer" ">=16.9.0" react-error-boundary "^3.1.0" +"@testing-library/react-hooks@^8.0.0": + version "8.0.0" + resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz#7d0164bffce4647f506039de0a97f6fcbd20f4bf" + integrity sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw== + dependencies: + "@babel/runtime" "^7.12.5" + react-error-boundary "^3.1.0" + "@testing-library/react@^12.1.3": version "12.1.4" resolved "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0" @@ -5580,6 +5663,22 @@ "@testing-library/dom" "^8.0.0" "@types/react-dom" "*" +"@testing-library/react@^13.0.0": + version "13.0.0" + resolved "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz#8cdaf4667c6c2b082eb0513731551e9db784e8bc" + integrity sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^8.5.0" + "@types/react-dom" "*" + +"@testing-library/user-event@^13.1.8": + version "13.5.0" + resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" + integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/user-event@^14.0.0": version "14.0.0" resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.0.tgz#3906aa6f0e56fd012d73559f5f05c02e63ba18dd" From a39a931b39605fe3de3e035b7a0a69c729c54d24 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 11:43:22 +0200 Subject: [PATCH 5/9] search api report Signed-off-by: Emma Indal --- plugins/search/api-report.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index 1bdd918802..f524652f51 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -81,17 +81,19 @@ export type HomePageSearchBarProps = Partial< // @public (undocumented) export const Router: () => JSX.Element; +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export interface SearchApi { // (undocumented) query(query: SearchQuery): Promise; } +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "searchApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const searchApiRef: ApiRef; // @public (undocumented) @@ -138,9 +140,10 @@ export const SearchBarNext: ({ // @public export type SearchBarProps = Partial; +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const SearchContextProvider: ({ initialState, children, @@ -322,10 +325,11 @@ export type SidebarSearchProps = { icon?: IconComponent; }; +// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "useSearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const useSearch: () => SearchContextValue; // @public From 6a4f081128a47bc86fbcf4d9885303ca2e8025fe Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 12:08:29 +0200 Subject: [PATCH 6/9] let template logos live in home plugin for now Signed-off-by: Emma Indal --- .../home/templates/DefaultTemplate.stories.tsx | 4 ++-- plugins/home/api-report.md | 13 +++++++++++++ .../home/src/assets}/TemplateBackstageLogo.tsx | 2 +- .../home/src/assets}/TemplateBackstageLogoIcon.tsx | 1 - .../templates => plugins/home/src/assets}/index.ts | 6 +++--- .../CompanyLogo/CompanyLogo.stories.tsx | 2 +- .../homePageComponents/Toolkit/Toolkit.stories.tsx | 2 +- plugins/home/src/index.ts | 1 + 8 files changed, 22 insertions(+), 9 deletions(-) rename {packages/app/src/components/home/templates => plugins/home/src/assets}/TemplateBackstageLogo.tsx (99%) rename {packages/app/src/components/home/templates => plugins/home/src/assets}/TemplateBackstageLogoIcon.tsx (99%) rename {packages/app/src/components/home/templates => plugins/home/src/assets}/index.ts (76%) diff --git a/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx index b2f6034709..8b9c5100b1 100644 --- a/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx +++ b/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx @@ -14,12 +14,12 @@ * limitations under the License. */ -import { TemplateBackstageLogo } from './TemplateBackstageLogo'; -import { TemplateBackstageLogoIcon } from './TemplateBackstageLogoIcon'; import { HomePageToolkit, HomePageCompanyLogo, HomePageStarredEntities, + TemplateBackstageLogo, + TemplateBackstageLogoIcon } from '@backstage/plugin-home'; import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; import { Content, Page, InfoCard } from '@backstage/core-components'; diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 9bd577da7c..21c5592636 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -119,11 +119,24 @@ export const SettingsModal: (props: { children: JSX.Element; }) => JSX.Element; +// Warning: (ae-missing-release-tag) "TemplateBackstageLogo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const TemplateBackstageLogo: (props: { + classes: Classes; +}) => JSX.Element; + +// Warning: (ae-missing-release-tag) "TemplateBackstageLogoIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const TemplateBackstageLogoIcon: () => JSX.Element; + // @public export const WelcomeTitle: () => JSX.Element; // Warnings were encountered during analysis: // +// src/assets/TemplateBackstageLogo.d.ts:7:5 - (ae-forgotten-export) The symbol "Classes" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:6:5 - (ae-forgotten-export) The symbol "RendererProps" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:27:5 - (ae-forgotten-export) The symbol "ComponentParts" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/app/src/components/home/templates/TemplateBackstageLogo.tsx b/plugins/home/src/assets/TemplateBackstageLogo.tsx similarity index 99% rename from packages/app/src/components/home/templates/TemplateBackstageLogo.tsx rename to plugins/home/src/assets/TemplateBackstageLogo.tsx index edce9bb02e..0fc908ee39 100644 --- a/packages/app/src/components/home/templates/TemplateBackstageLogo.tsx +++ b/plugins/home/src/assets/TemplateBackstageLogo.tsx @@ -19,7 +19,7 @@ import React from 'react'; type Classes = { svg: string; path: string; -} +}; export const TemplateBackstageLogo = (props: { classes: Classes }) => { return ( diff --git a/packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx b/plugins/home/src/assets/TemplateBackstageLogoIcon.tsx similarity index 99% rename from packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx rename to plugins/home/src/assets/TemplateBackstageLogoIcon.tsx index 2116b48784..09c4405286 100644 --- a/packages/app/src/components/home/templates/TemplateBackstageLogoIcon.tsx +++ b/plugins/home/src/assets/TemplateBackstageLogoIcon.tsx @@ -43,4 +43,3 @@ export const TemplateBackstageLogoIcon = () => { ); }; - diff --git a/packages/app/src/components/home/templates/index.ts b/plugins/home/src/assets/index.ts similarity index 76% rename from packages/app/src/components/home/templates/index.ts rename to plugins/home/src/assets/index.ts index bfebe73cd8..79de43ca99 100644 --- a/packages/app/src/components/home/templates/index.ts +++ b/plugins/home/src/assets/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * 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. @@ -14,5 +14,5 @@ * limitations under the License. */ -export { TemplateBackstageLogoIcon } from './TemplateBackstageLogoIcon'; -export { TemplateBackstageLogo } from './TemplateBackstageLogo' +export * from './TemplateBackstageLogo'; +export * from './TemplateBackstageLogoIcon'; diff --git a/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx b/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx index ab71eea54e..741ad2e977 100644 --- a/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx +++ b/plugins/home/src/homePageComponents/CompanyLogo/CompanyLogo.stories.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { TemplateBackstageLogo } from '../../templates'; +import { TemplateBackstageLogo } from '../../assets'; import { HomePageCompanyLogo } from '../../plugin'; import { rootRouteRef } from '../../routes'; import { wrapInTestApp, TestApiProvider } from '@backstage/test-utils'; diff --git a/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx b/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx index cad188c5d6..9a82301e49 100644 --- a/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx +++ b/plugins/home/src/homePageComponents/Toolkit/Toolkit.stories.tsx @@ -20,7 +20,7 @@ import { Grid } from '@material-ui/core'; import React, { ComponentType } from 'react'; import { ComponentAccordion } from '../../componentRenderers'; import { HomePageToolkit } from '../../plugin'; -import { TemplateBackstageLogoIcon } from '../../templates'; +import { TemplateBackstageLogoIcon } from '../../assets'; export default { title: 'Plugins/Home/Components/Toolkit', diff --git a/plugins/home/src/index.ts b/plugins/home/src/index.ts index d30b76a7fc..8f137d589b 100644 --- a/plugins/home/src/index.ts +++ b/plugins/home/src/index.ts @@ -33,6 +33,7 @@ export { WelcomeTitle, } from './plugin'; export { SettingsModal, HeaderWorldClock } from './components'; +export * from './assets'; export type { ClockConfig } from './components'; export { createCardExtension } from './extensions'; export type { ComponentRenderer } from './extensions'; From c64c33f74ba07b14c1abaf4638be0d66ff84c623 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 13:16:38 +0200 Subject: [PATCH 7/9] dependency and docs fixups Signed-off-by: Emma Indal --- packages/app/package.json | 3 ++ plugins/home/README.md | 2 +- plugins/search-react/package.json | 6 +-- yarn.lock | 79 ++----------------------------- 4 files changed, 10 insertions(+), 80 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index 4522cabaf1..f8dc6127c8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -10,6 +10,7 @@ "@backstage/app-defaults": "^1.0.1-next.1", "@backstage/catalog-model": "^1.0.1-next.0", "@backstage/cli": "^0.17.0-next.1", + "@backstage/config": "^1.0.0", "@backstage/core-app-api": "^1.0.1-next.0", "@backstage/core-components": "^0.9.3-next.0", "@backstage/core-plugin-api": "^1.0.0", @@ -47,9 +48,11 @@ "@backstage/plugin-rollbar": "^0.4.4-next.0", "@backstage/plugin-scaffolder": "^1.0.1-next.1", "@backstage/plugin-search": "^0.7.5-next.0", + "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-search-common": "^0.3.3-next.1", "@backstage/plugin-sentry": "^0.3.42-next.0", "@backstage/plugin-shortcuts": "^0.2.5-next.0", + "@backstage/plugin-stack-overflow": "^0.1.0-next.0", "@backstage/plugin-tech-radar": "^0.5.11-next.1", "@backstage/plugin-techdocs": "^1.0.1-next.1", "@backstage/plugin-todo": "^0.2.6-next.0", diff --git a/plugins/home/README.md b/plugins/home/README.md index a85994b3cb..0cd307b706 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -93,4 +93,4 @@ Additionally, the API is at a very early state, so contributing with additional ### Homepage Templates -We are hoping that we together can build up a collection of Homepage templates. We therefore put together a place where we can collect all the templates for the Home Plugin in the [storybook](https://backstage.io/storybook/?path=/story/plugins-home-templates). If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example to create your own](/plugins/home/src/templates/DefaultTemplate.stories.tsx), and then open a PR with your suggestion. +We are hoping that we together can build up a collection of Homepage templates. We therefore put together a place where we can collect all the templates for the Home Plugin in the [storybook](https://backstage.io/storybook/?path=/story/plugins-home-templates). If you would like to contribute with a template, start by taking a look at the [DefaultTemplate storybook example to create your own](/packages/app/src/components/home/templates/DefaultTemplate.stories.tsx), and then open a PR with your suggestion. diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 66b6bdfa46..15251b4ac7 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -31,7 +31,7 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/plugin-search-common": "^0.3.2", + "@backstage/plugin-search-common": "^0.3.3-next.1", "@backstage/core-plugin-api": "^1.0.0", "@backstage/core-app-api": "^1.0.1-next.0", "react-use": "^17.3.2", @@ -42,8 +42,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/test-utils": "^1.0.0", - "@testing-library/react": "^13.0.0", + "@backstage/test-utils": "^1.0.1-next.1", + "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", "@testing-library/jest-dom": "^5.16.4" }, diff --git a/yarn.lock b/yarn.lock index b5f327b6e4..223c451347 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1478,22 +1478,6 @@ lodash "^4.17.21" uuid "^8.0.0" -"@backstage/core-app-api@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@backstage/core-app-api/-/core-app-api-1.0.0.tgz#2dae97b050b2f2e5ec1ea42b3d95c57e8bf434d6" - integrity sha512-hmoFMPCxAfHgDPQTHbf6rquiG0SCSycWTUrScpYeLwkH3UOekgX8o8ThKT0t3w7WPx83LwT0NqcbSH6zqI9nag== - dependencies: - "@backstage/config" "^1.0.0" - "@backstage/core-plugin-api" "^1.0.0" - "@backstage/types" "^1.0.0" - "@backstage/version-bridge" "^1.0.0" - "@types/prop-types" "^15.7.3" - prop-types "^15.7.2" - react-router-dom "6.0.0-beta.0" - react-use "^17.2.4" - zen-observable "^0.8.15" - zod "^3.11.6" - "@backstage/core-components@^0.9.0", "@backstage/core-components@^0.9.2": version "0.9.2" resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.9.2.tgz#9a3d79a15039256bbc007e5daa08c983050e0238" @@ -1618,36 +1602,6 @@ react-use "^17.2.4" swr "^1.1.2" -"@backstage/plugin-search-common@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@backstage/plugin-search-common/-/plugin-search-common-0.3.2.tgz#15984ba4c14f8a9119168e8c79344ef8101863dc" - integrity sha512-7vcpRo+5MB/QW/M77zPfcqxw0LzcQCHNXql0uxF+qBwVPJSHz9QB+YBuzGyaAlqfm5UPFXuweLQGqtoB+0DMLg== - dependencies: - "@backstage/plugin-permission-common" "^0.5.3" - "@backstage/types" "^1.0.0" - -"@backstage/test-utils@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@backstage/test-utils/-/test-utils-1.0.0.tgz#dafac18065591a7dda584811cb00812495292ee8" - integrity sha512-dHtIjhoq2b+rpsnwVQnWA/2sDxFMt2HL0OxoyKqG2NRum16A7cTQxgrG3UC3p4dqFYKREg7+aTFIjHBa+Tk/PA== - dependencies: - "@backstage/config" "^1.0.0" - "@backstage/core-app-api" "^1.0.0" - "@backstage/core-plugin-api" "^1.0.0" - "@backstage/plugin-permission-common" "^0.5.3" - "@backstage/plugin-permission-react" "^0.3.4" - "@backstage/theme" "^0.2.15" - "@backstage/types" "^1.0.0" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.11.2" - "@testing-library/jest-dom" "^5.10.1" - "@testing-library/react" "^12.1.3" - "@testing-library/user-event" "^13.1.8" - cross-fetch "^3.1.5" - react-router "6.0.0-beta.0" - react-router-dom "6.0.0-beta.0" - zen-observable "^0.8.15" - "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -5591,20 +5545,6 @@ lz-string "^1.4.4" pretty-format "^27.0.2" -"@testing-library/dom@^8.5.0": - version "8.13.0" - resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz#bc00bdd64c7d8b40841e27a70211399ad3af46f5" - integrity sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^4.2.0" - aria-query "^5.0.0" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.4.4" - pretty-format "^27.0.2" - "@testing-library/jest-dom@^5.10.1": version "5.16.3" resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz#b76851a909586113c20486f1679ffb4d8ec27bfa" @@ -5663,22 +5603,6 @@ "@testing-library/dom" "^8.0.0" "@types/react-dom" "*" -"@testing-library/react@^13.0.0": - version "13.0.0" - resolved "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz#8cdaf4667c6c2b082eb0513731551e9db784e8bc" - integrity sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^8.5.0" - "@types/react-dom" "*" - -"@testing-library/user-event@^13.1.8": - version "13.5.0" - resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" - integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/user-event@^14.0.0": version "14.0.0" resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.0.tgz#3906aa6f0e56fd012d73559f5f05c02e63ba18dd" @@ -12267,6 +12191,7 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: "@backstage/app-defaults" "^1.0.1-next.1" "@backstage/catalog-model" "^1.0.1-next.0" "@backstage/cli" "^0.17.0-next.1" + "@backstage/config" "^1.0.0" "@backstage/core-app-api" "^1.0.1-next.0" "@backstage/core-components" "^0.9.3-next.0" "@backstage/core-plugin-api" "^1.0.0" @@ -12305,8 +12230,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: "@backstage/plugin-scaffolder" "^1.0.1-next.1" "@backstage/plugin-search" "^0.7.5-next.0" "@backstage/plugin-search-common" "^0.3.3-next.1" + "@backstage/plugin-search-react" "^0.0.0" "@backstage/plugin-sentry" "^0.3.42-next.0" "@backstage/plugin-shortcuts" "^0.2.5-next.0" + "@backstage/plugin-stack-overflow" "^0.1.0-next.0" "@backstage/plugin-tech-insights" "^0.1.14-next.0" "@backstage/plugin-tech-radar" "^0.5.11-next.1" "@backstage/plugin-techdocs" "^1.0.1-next.1" From ab230a433f02c0a6c1cf92169839fe826bc40a2c Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 14:19:48 +0200 Subject: [PATCH 8/9] add changesets Signed-off-by: Emma Indal --- .changeset/breezy-mugs-build.md | 5 +++++ .changeset/clever-buckets-doubt.md | 5 +++++ .changeset/rude-bees-rest.md | 5 +++++ .changeset/thirty-sloths-knock.md | 11 +++++++++++ plugins/home/package.json | 1 - 5 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 .changeset/breezy-mugs-build.md create mode 100644 .changeset/clever-buckets-doubt.md create mode 100644 .changeset/rude-bees-rest.md create mode 100644 .changeset/thirty-sloths-knock.md diff --git a/.changeset/breezy-mugs-build.md b/.changeset/breezy-mugs-build.md new file mode 100644 index 0000000000..026932e971 --- /dev/null +++ b/.changeset/breezy-mugs-build.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-home': patch +--- + +Export template logos `TemplateBackstageLogo` and `TemplateBackstageLogoIcon` from package. diff --git a/.changeset/clever-buckets-doubt.md b/.changeset/clever-buckets-doubt.md new file mode 100644 index 0000000000..751db72bf8 --- /dev/null +++ b/.changeset/clever-buckets-doubt.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +imports from `@backstage/plugin-search-react` instead of `@backstage/plugin-search` diff --git a/.changeset/rude-bees-rest.md b/.changeset/rude-bees-rest.md new file mode 100644 index 0000000000..793b130b35 --- /dev/null +++ b/.changeset/rude-bees-rest.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-react': patch +--- + +New search package to hold things the search plugin itself and other frontend plugins (e.g. techdocs, home) depend on. diff --git a/.changeset/thirty-sloths-knock.md b/.changeset/thirty-sloths-knock.md new file mode 100644 index 0000000000..1ad559e368 --- /dev/null +++ b/.changeset/thirty-sloths-knock.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-search': patch +--- + +The following exports has been moved to `@backstage/plugin-search-react` and will be removed in the next release. import from `@backstage/plugin-search-react` instead. + +- `SearchApi` interface. +- `searchApiRef` +- `SearchContext` +- `SearchContextProvider` +- `useSearch` diff --git a/plugins/home/package.json b/plugins/home/package.json index e59e7a39bb..aac39c397a 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -38,7 +38,6 @@ "@backstage/core-components": "^0.9.3-next.1", "@backstage/core-plugin-api": "^1.0.0", "@backstage/plugin-catalog-react": "^1.0.1-next.2", - "@backstage/plugin-search-react": "^0.0.0", "@backstage/plugin-stack-overflow": "^0.1.0-next.0", "@backstage/theme": "^0.2.15", "@backstage/config": "^1.0.0", From b7d035cc29ea5db46fe36f5fd4799cdbaa849c18 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Mon, 11 Apr 2022 16:40:47 +0200 Subject: [PATCH 9/9] feedback fixups Signed-off-by: Emma Indal --- .changeset/rude-bees-rest.md | 2 +- plugins/home/api-report.md | 8 +++---- .../home/src/assets/TemplateBackstageLogo.tsx | 6 ++++- plugins/search-react/README.md | 4 +++- plugins/search-react/api-report.md | 9 +++----- plugins/search-react/package.json | 4 ++-- .../src/context/SearchContext.tsx | 5 +++- plugins/search-react/src/index.ts | 11 +++++++-- plugins/search/api-report.md | 3 --- plugins/search/src/apis.ts | 4 ++-- .../SearchContext/SearchContext.tsx | 4 ++-- yarn.lock | 23 ------------------- 12 files changed, 35 insertions(+), 48 deletions(-) diff --git a/.changeset/rude-bees-rest.md b/.changeset/rude-bees-rest.md index 793b130b35..7ca4e7492c 100644 --- a/.changeset/rude-bees-rest.md +++ b/.changeset/rude-bees-rest.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-search-react': patch +'@backstage/plugin-search-react': minor --- New search package to hold things the search plugin itself and other frontend plugins (e.g. techdocs, home) depend on. diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 21c5592636..a65f8cda5c 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -119,12 +119,13 @@ export const SettingsModal: (props: { children: JSX.Element; }) => JSX.Element; +// Warning: (ae-forgotten-export) The symbol "TemplateBackstageLogoProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "TemplateBackstageLogo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const TemplateBackstageLogo: (props: { - classes: Classes; -}) => JSX.Element; +export const TemplateBackstageLogo: ( + props: TemplateBackstageLogoProps, +) => JSX.Element; // Warning: (ae-missing-release-tag) "TemplateBackstageLogoIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -136,7 +137,6 @@ export const WelcomeTitle: () => JSX.Element; // Warnings were encountered during analysis: // -// src/assets/TemplateBackstageLogo.d.ts:7:5 - (ae-forgotten-export) The symbol "Classes" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:6:5 - (ae-forgotten-export) The symbol "RendererProps" needs to be exported by the entry point index.d.ts // src/extensions.d.ts:27:5 - (ae-forgotten-export) The symbol "ComponentParts" needs to be exported by the entry point index.d.ts ``` diff --git a/plugins/home/src/assets/TemplateBackstageLogo.tsx b/plugins/home/src/assets/TemplateBackstageLogo.tsx index 0fc908ee39..9088cfa58c 100644 --- a/plugins/home/src/assets/TemplateBackstageLogo.tsx +++ b/plugins/home/src/assets/TemplateBackstageLogo.tsx @@ -21,7 +21,11 @@ type Classes = { path: string; }; -export const TemplateBackstageLogo = (props: { classes: Classes }) => { +type TemplateBackstageLogoProps = { + classes: Classes; +}; + +export const TemplateBackstageLogo = (props: TemplateBackstageLogoProps) => { return ( ; -// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts -// -// @public (undocumented) -export const SearchContext: React_2.Context; - // @public (undocumented) export const SearchContextProvider: ({ initialState, @@ -49,7 +44,7 @@ export const SearchContextProviderForStorybook: ( props: ComponentProps & QueryResultProps, ) => JSX.Element; -// @public +// @public (undocumented) export type SearchContextState = { term: string; types: string[]; @@ -57,6 +52,8 @@ export type SearchContextState = { pageCursor?: string; }; +// Warning: (ae-forgotten-export) The symbol "SearchContextValue" needs to be exported by the entry point index.d.ts +// // @public (undocumented) export const useSearch: () => SearchContextValue; diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 15251b4ac7..151660943e 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -44,8 +44,8 @@ "devDependencies": { "@backstage/test-utils": "^1.0.1-next.1", "@testing-library/react": "^12.1.3", - "@testing-library/react-hooks": "^8.0.0", - "@testing-library/jest-dom": "^5.16.4" + "@testing-library/react-hooks": "^7.0.2", + "@testing-library/jest-dom": "^5.10.1" }, "files": [ "dist" diff --git a/plugins/search-react/src/context/SearchContext.tsx b/plugins/search-react/src/context/SearchContext.tsx index 217c94cca2..d6245d5ccf 100644 --- a/plugins/search-react/src/context/SearchContext.tsx +++ b/plugins/search-react/src/context/SearchContext.tsx @@ -40,7 +40,6 @@ type SearchContextValue = { } & SearchContextState; /** - * The initial state of `SearchContextProvider`. * * @public */ @@ -58,6 +57,10 @@ export const SearchContext = createContext( undefined, ); +/** + * The initial state of `SearchContextProvider`. + * + */ const searchInitialState: SearchContextState = { term: '', pageCursor: undefined, diff --git a/plugins/search-react/src/index.ts b/plugins/search-react/src/index.ts index 498e4d6ce3..934cf2e9f1 100644 --- a/plugins/search-react/src/index.ts +++ b/plugins/search-react/src/index.ts @@ -14,5 +14,12 @@ * limitations under the License. */ -export * from './api'; -export * from './context'; +export { searchApiRef } from './api'; +export type { SearchApi } from './api'; +export { + SearchContextProvider, + useSearch, + SearchContextProviderForStorybook, + SearchApiProviderForStorybook, +} from './context'; +export type { SearchContextState } from './context'; diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index f524652f51..d85158c925 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -81,7 +81,6 @@ export type HomePageSearchBarProps = Partial< // @public (undocumented) export const Router: () => JSX.Element; -// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -90,7 +89,6 @@ export interface SearchApi { query(query: SearchQuery): Promise; } -// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "searchApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -140,7 +138,6 @@ export const SearchBarNext: ({ // @public export type SearchBarProps = Partial; -// Warning: (tsdoc-at-sign-in-word) The "@" character looks like part of a TSDoc tag; use a backslash to escape it // Warning: (ae-missing-release-tag) "SearchContextProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) diff --git a/plugins/search/src/apis.ts b/plugins/search/src/apis.ts index 62f65dbe4a..096b11bb5e 100644 --- a/plugins/search/src/apis.ts +++ b/plugins/search/src/apis.ts @@ -25,14 +25,14 @@ import { SearchQuery, SearchResultSet } from '@backstage/plugin-search-common'; import qs from 'qs'; /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export const searchApiRef = createApiRef({ id: 'plugin.search.queryservice', }); /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export interface SearchApi { query(query: SearchQuery): Promise; diff --git a/plugins/search/src/components/SearchContext/SearchContext.tsx b/plugins/search/src/components/SearchContext/SearchContext.tsx index d52e43af88..c87295ab99 100644 --- a/plugins/search/src/components/SearchContext/SearchContext.tsx +++ b/plugins/search/src/components/SearchContext/SearchContext.tsx @@ -52,7 +52,7 @@ export type SearchContextState = { }; /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export const SearchContext = createContext( undefined, @@ -66,7 +66,7 @@ const searchInitialState: SearchContextState = { }; /** - * @deprecated import from "@backstage/plugin-search-react" instead + * @deprecated import from `@backstage/plugin-search-react` instead */ export const SearchContextProvider = ({ initialState = searchInitialState, diff --git a/yarn.lock b/yarn.lock index 223c451347..076b9f222a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5560,21 +5560,6 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/jest-dom@^5.16.4": - version "5.16.4" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" - integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== - dependencies: - "@babel/runtime" "^7.9.2" - "@types/testing-library__jest-dom" "^5.9.1" - aria-query "^5.0.0" - chalk "^3.0.0" - css "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" - lodash "^4.17.15" - redent "^3.0.0" - "@testing-library/react-hooks@^7.0.2": version "7.0.2" resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-7.0.2.tgz#3388d07f562d91e7f2431a4a21b5186062ecfee0" @@ -5586,14 +5571,6 @@ "@types/react-test-renderer" ">=16.9.0" react-error-boundary "^3.1.0" -"@testing-library/react-hooks@^8.0.0": - version "8.0.0" - resolved "https://registry.npmjs.org/@testing-library/react-hooks/-/react-hooks-8.0.0.tgz#7d0164bffce4647f506039de0a97f6fcbd20f4bf" - integrity sha512-uZqcgtcUUtw7Z9N32W13qQhVAD+Xki2hxbTR461MKax8T6Jr8nsUvZB+vcBTkzY2nFvsUet434CsgF0ncW2yFw== - dependencies: - "@babel/runtime" "^7.12.5" - react-error-boundary "^3.1.0" - "@testing-library/react@^12.1.3": version "12.1.4" resolved "https://registry.npmjs.org/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0"