diff options
Diffstat (limited to 'plugins/base/frontend/src/main/components')
6 files changed, 224 insertions, 0 deletions
diff --git a/plugins/base/frontend/src/main/components/app/index.scss b/plugins/base/frontend/src/main/components/app/index.scss new file mode 100644 index 00000000..da5042b1 --- /dev/null +++ b/plugins/base/frontend/src/main/components/app/index.scss @@ -0,0 +1,27 @@ +@import "src/main/scss/index.scss"; + +html, +.app-root { + height: 100%; +} + +.search-root { + margin: 0; + padding: 0; + + background: var(--ring-content-background-color); + + font-family: var(--ring-font-family); + font-size: var(--ring-font-size); + line-height: var(--ring-line-height); +} + +.search-content { + padding-top: 24px; + margin: 0 41px; + position: absolute; + top: 0; + right: 0; + z-index: 8; + background-color: #f4f4f4 +} diff --git a/plugins/base/frontend/src/main/components/app/index.tsx b/plugins/base/frontend/src/main/components/app/index.tsx new file mode 100644 index 00000000..4081dec4 --- /dev/null +++ b/plugins/base/frontend/src/main/components/app/index.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import {WithFuzzySearchFilter} from '../search/search'; +import './index.scss'; + +const App: React.FC = () => { + return <div className="search-content"> + <WithFuzzySearchFilter/> + </div> +} + +export default App diff --git a/plugins/base/frontend/src/main/components/root.tsx b/plugins/base/frontend/src/main/components/root.tsx new file mode 100644 index 00000000..70ed9550 --- /dev/null +++ b/plugins/base/frontend/src/main/components/root.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import {render} from 'react-dom'; +import RedBox from 'redbox-react'; + +import App from "./app"; +import './app/index.scss'; + +const appEl = document.getElementById('searchBar'); +const rootEl = document.createElement('div'); + +let renderApp = () => { + render( + <App/>, + rootEl + ); +}; + +// @ts-ignore +if (module.hot) { + const renderAppHot = renderApp; + const renderError = (error: Error) => { + render( + <RedBox error={error}/>, + rootEl + ); + }; + + renderApp = () => { + try { + renderAppHot(); + } catch (error) { + renderError(error); + } + }; + + // @ts-ignore + module.hot.accept('./app', () => { + setTimeout(renderApp); + }); +} + +renderApp(); +appEl!.appendChild(rootEl); diff --git a/plugins/base/frontend/src/main/components/search/search.scss b/plugins/base/frontend/src/main/components/search/search.scss new file mode 100644 index 00000000..cc5a61ac --- /dev/null +++ b/plugins/base/frontend/src/main/components/search/search.scss @@ -0,0 +1,37 @@ +.search { + button { + border: none; + fill: #637282; + background: #F4F4F4; + + &:focus { + outline: none; + } + } +} + +.popup-wrapper { + min-width: calc(100% - 360px) !important; +} + +.indented { + text-indent: 10px; +} + +.disabled { + color: gray; +} + +.template-wrapper { + display: grid; + grid-template-columns: auto auto; +} + +.template-name { + justify-self: start; +} + +.template-description { + color: gray; + justify-self: end; +}
\ No newline at end of file diff --git a/plugins/base/frontend/src/main/components/search/search.tsx b/plugins/base/frontend/src/main/components/search/search.tsx new file mode 100644 index 00000000..c7b36654 --- /dev/null +++ b/plugins/base/frontend/src/main/components/search/search.tsx @@ -0,0 +1,75 @@ +import React, {useCallback, useState} from 'react'; +import {Select} from '@jetbrains/ring-ui'; +import {List} from '@jetbrains/ring-ui'; +import '@jetbrains/ring-ui/components/input-size/input-size.scss'; +import './search.scss'; +import {IWindow, Option, Props, Page} from "./types"; + +const WithFuzzySearchFilterComponent: React.FC<Props> = ({data}: Props) => { + const [selected, onSelected] = useState<Option>(data[0]); + const onChangeSelected = useCallback( + (option: Option) => { + window.location.replace(`${(window as IWindow).pathToRoot}${option.location}?query=${option.name}`) + onSelected(option); + }, + [data] + ); + + return ( + <div className="search-container"> + <div className="search"> + <Select + selectedLabel="Search" + label="Please type page name" + filter={{fuzzy: true}} + type={Select.Type.CUSTOM} + clear + selected={selected} + data={data} + popupClassName={"popup-wrapper"} + onSelect={onChangeSelected} + customAnchor={({wrapperProps, buttonProps, popup}) => ( + <span {...wrapperProps}> + <button type="button" {...buttonProps}> + <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> + <path d="M19.64 18.36l-6.24-6.24a7.52 7.52 0 1 0-1.28 1.28l6.24 6.24zM7.5 13.4a5.9 5.9 0 1 1 5.9-5.9 5.91 5.91 0 0 1-5.9 5.9z"/> + </svg> + </button> + {popup} + </span> + )} + /> + </div> + </div> + ) +} + +const templateGenerator = (page:Page) => { + let classGenerator = (page:Page) => { + let classes = "" + if(page.level !== undefined) classes = classes + " indented" + if(page.disabled) classes = classes + " disabled" + return classes + } + return <div className="template-wrapper"> + <span className= {classGenerator(page)}>{page.name}</span> + <span className="template-description">{page.description}</span> + </div> +} + +export const WithFuzzySearchFilter = () => { + let data: Option[] = []; + const pages = (window as IWindow).pages; + if (pages) { + data = pages.map((page, i) => ({ + ...page, + label: page.searchKey, + key: i + 1, + type: page.kind, + template: templateGenerator(page), + rgItemType: List.ListProps.Type.CUSTOM + })); + } + + return <WithFuzzySearchFilterComponent data={data}/>; +}; diff --git a/plugins/base/frontend/src/main/components/search/types.ts b/plugins/base/frontend/src/main/components/search/types.ts new file mode 100644 index 00000000..881a16d8 --- /dev/null +++ b/plugins/base/frontend/src/main/components/search/types.ts @@ -0,0 +1,31 @@ +export type Page = { + name: string; + kind: string; + location: string; + searchKey: string; + level: number; + index: string; + description: string; + disabled: boolean; +} + +export type Option = Page & { + label: string; + key: number; + location: string; + name: string; +} + +export type IWindow = typeof window & { + pathToRoot: string + pages: Page[] +} + +export type Props = { + data: Option[] +}; + + +export type State = { + selected: any +} |