From 8e5c63d035ef44a269b8c43430f43f5c8eebfb63 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Fri, 10 Nov 2023 11:46:54 +0100 Subject: Restructure the project to utilize included builds (#3174) * Refactor and simplify artifact publishing * Update Gradle to 8.4 * Refactor and simplify convention plugins and build scripts Fixes #3132 --------- Co-authored-by: Adam <897017+aSemy@users.noreply.github.com> Co-authored-by: Oleg Yukhnevich --- .../src/main/components/app/index.scss | 30 ++++++ .../src/main/components/app/index.tsx | 15 +++ .../src/main/components/assets/clear.svg | 7 ++ .../src/main/components/assets/searchIcon.svg | 7 ++ .../src/main/components/root.tsx | 22 ++++ .../main/components/search/dokkaFuzzyFilter.tsx | 101 ++++++++++++++++++ .../main/components/search/dokkaSearchAnchor.tsx | 32 ++++++ .../src/main/components/search/search.scss | 118 +++++++++++++++++++++ .../src/main/components/search/search.tsx | 74 +++++++++++++ .../src/main/components/search/searchResultRow.tsx | 36 +++++++ .../src/main/components/search/types.ts | 55 ++++++++++ .../src/main/components/utils/hotkey.ts | 62 +++++++++++ .../src/main/components/utils/os.ts | 18 ++++ .../src/main/components/utils/requests.tsx | 11 ++ .../plugin-base-frontend/src/main/scss/index.scss | 10 ++ .../src/main/types/@jetbrains/index.d.ts | 9 ++ 16 files changed, 607 insertions(+) create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/app/index.scss create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/app/index.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/assets/clear.svg create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/assets/searchIcon.svg create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/root.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaFuzzyFilter.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaSearchAnchor.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/search/search.scss create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/search/search.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/search/searchResultRow.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/search/types.ts create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/utils/hotkey.ts create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/utils/os.ts create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/components/utils/requests.tsx create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/scss/index.scss create mode 100644 dokka-subprojects/plugin-base-frontend/src/main/types/@jetbrains/index.d.ts (limited to 'dokka-subprojects/plugin-base-frontend/src') diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/app/index.scss b/dokka-subprojects/plugin-base-frontend/src/main/components/app/index.scss new file mode 100644 index 00000000..9bb25de9 --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/app/index.scss @@ -0,0 +1,30 @@ +/*! + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +@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 { + z-index: 8; +} + +@media screen and (max-width: 759px) { + .search-content { + } +} diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/app/index.tsx b/dokka-subprojects/plugin-base-frontend/src/main/components/app/index.tsx new file mode 100644 index 00000000..ea2a2e42 --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/app/index.tsx @@ -0,0 +1,15 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import React from 'react'; +import {WithFuzzySearchFilter} from '../search/search'; +import './index.scss'; + +const App: React.FC = () => { + return
+ +
+} + +export default App diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/assets/clear.svg b/dokka-subprojects/plugin-base-frontend/src/main/components/assets/clear.svg new file mode 100644 index 00000000..5c652c7f --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/assets/clear.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/assets/searchIcon.svg b/dokka-subprojects/plugin-base-frontend/src/main/components/assets/searchIcon.svg new file mode 100644 index 00000000..ef5f9c4f --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/assets/searchIcon.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/root.tsx b/dokka-subprojects/plugin-base-frontend/src/main/components/root.tsx new file mode 100644 index 00000000..93d070ce --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/root.tsx @@ -0,0 +1,22 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import React from 'react'; +import {render} from 'react-dom'; + +import App from "./app"; +import './app/index.scss'; + + +const renderMainSearch = () => { + render(, document.getElementById('searchBar')); +} + +let renderApp = () => { + renderMainSearch(); + + document.removeEventListener('DOMContentLoaded', renderApp); +}; + +document.addEventListener('DOMContentLoaded', renderApp); diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaFuzzyFilter.tsx b/dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaFuzzyFilter.tsx new file mode 100644 index 00000000..0a7edcb3 --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaFuzzyFilter.tsx @@ -0,0 +1,101 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import Select from '@jetbrains/ring-ui/components/select/select'; +import {Option, OptionWithHighlightComponent, OptionWithSearchResult} from "./types"; +import fuzzyHighlight from '@jetbrains/ring-ui/components/global/fuzzy-highlight.js' +import React from "react"; +import {SearchResultRow} from "./searchResultRow"; +import _ from "lodash"; + +const orderRecords = (records: OptionWithSearchResult[], searchPhrase: string): OptionWithSearchResult[] => { + return records.sort((a: OptionWithSearchResult, b: OptionWithSearchResult) => { + //Prefer higher rank + const byRank = a.rank - b.rank + if(byRank !== 0){ + return byRank + } + //Prefer exact matches + const aIncludes = a.name.toLowerCase().includes(searchPhrase.toLowerCase()) ? 1 : 0 + const bIncludes = b.name.toLowerCase().includes(searchPhrase.toLowerCase()) ? 1 : 0 + const byIncludes = bIncludes - aIncludes + if(byIncludes != 0){ + return byIncludes + } + + //Prefer matches that are closer + const byFirstMatchedPosition = a.highlight.indexOf("**") - b.highlight.indexOf("**") + if(byFirstMatchedPosition == 0) { + return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) + } + return byFirstMatchedPosition + }) +} + +const highlightMatchedPhrases = (records: OptionWithSearchResult[]): OptionWithHighlightComponent[] => { + // @ts-ignore + return records.map(record => { + return { + ...record, + template: + } + }) +} +export class DokkaFuzzyFilterComponent extends Select { + componentDidUpdate(prevProps, prevState) { + super.componentDidUpdate(prevProps, prevState) + if(this.props.filter && this.state.filterValue != this.props.filter.value){ + this.setState({ + filterValue: this.props.filter.value, + }) + } + } + + _showPopup(){ + if(this.props.shouldShowPopup){ + if (!this.node) { + return; + } + + const shownData = this.getListItems(this.filterValue()); + this.setState({ + showPopup: this.props.shouldShowPopup(this.filterValue()), + shownData + }) + } else { + super._showPopup() + } + } + + getListItems(rawFilterString: string, e: Option[]) { + const filterPhrase = (rawFilterString ? rawFilterString : '').trim() + const matchedRecords = this.props.data + .map((record: Option) => { + const searched = record.searchKeys.map((value, index) => { + return { + ...fuzzyHighlight(filterPhrase, value, false), + ...record, + rank: index + } + }).filter((e) => e.matched) + + const first = _.head(searched) + + if(first){ + return first + } + + return { + matched: false, + ...record, + } + + }) + .filter((record: OptionWithSearchResult) => record.matched) + + this.props.onFilter(filterPhrase) + + return highlightMatchedPhrases(orderRecords(matchedRecords, filterPhrase)) + } +} diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaSearchAnchor.tsx b/dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaSearchAnchor.tsx new file mode 100644 index 00000000..f7c6cf46 --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/search/dokkaSearchAnchor.tsx @@ -0,0 +1,32 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import React from "react"; +import Tooltip from '@jetbrains/ring-ui/components/tooltip/tooltip'; +import SearchIcon from 'react-svg-loader!../assets/searchIcon.svg'; +import {CustomAnchorProps} from "./types"; +import {Hotkey} from "../utils/hotkey"; + +const HOTKEY_LETTER = 'k' +const HOTKEY_TOOLTIP_DISPLAY_DELAY = 0.5 * 1000 // seconds + +export const DokkaSearchAnchor = ({wrapperProps, buttonProps, popup}: CustomAnchorProps) => { + const hotkeys = new Hotkey() + hotkeys.registerHotkeyWithAccel(buttonProps.onClick, HOTKEY_LETTER) + + return ( + + + + + {popup} + + ) +} diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/search/search.scss b/dokka-subprojects/plugin-base-frontend/src/main/components/search/search.scss new file mode 100644 index 00000000..6dd07d5b --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/search/search.scss @@ -0,0 +1,118 @@ +/*! + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +$font-color: hsla(0, 0%, 100%, 0.8); +$secondary-font-color: hsla(0, 0%, 100%, 0.6); + +#pages-search { + cursor: pointer; + border: none; + border-radius: 50%; + background: transparent; + fill: #fff; + fill: var(--dark-mode-and-search-icon-color); + + &:focus { + outline: none; + } + + &:hover { + background: var(--white-10); + } +} + +.search { + &, [data-test="ring-select"], [data-test="ring-tooltip"], [data-test="ring-select_focus"], #pages-search { + display: inline-block; + padding: 0; + margin: 0; + font-size: 0; + line-height: 0; + } +} + +.search-hotkey-popup { + background-color: var(--background-color) !important; + padding: 4px; +} + +.popup-wrapper { + min-width: calc(100% - 322px) !important; + + border: 1px solid hsla(0, 0%, 100%, 0.2) !important; + + background-color: #27282c !important; + + [class^="filterWrapper"] { + border-bottom: 1px solid hsla(0, 0%, 100%, 0.2); + } + + input { + color: $font-color !important; + + font-weight: normal !important; + } + + span[data-test-custom="ring-select-popup-filter-icon"] { + color: #fff; + } + + button[data-test="ring-input-clear"] { + color: #fff !important; + } +} + +@media screen and (max-width: 759px) { + .popup-wrapper { + min-width: 100% !important; + } +} + +.template-wrapper { + display: grid; + + height: 32px; + grid-template-columns: auto auto; + + strong { + color: $font-color; + } + + span { + color: $font-color; + + line-height: 32px; + + &.template-description { + color: $secondary-font-color; + justify-self: end; + } + } +} + +@media screen and (max-width: 759px) { + .template-wrapper { + display: flex; + flex-direction: column; + + height: auto; + + span { + line-height: unset; + } + } +} + +.template-name { + justify-self: start; +} + +/* remove fade at the bottom */ +[class^="fade"] { + display: none; +} + +[class*="hover"] { + background-color: hsla(0, 0%, 100%, 0.1) !important; +} diff --git a/dokka-subprojects/plugin-base-frontend/src/main/components/search/search.tsx b/dokka-subprojects/plugin-base-frontend/src/main/components/search/search.tsx new file mode 100644 index 00000000..24545671 --- /dev/null +++ b/dokka-subprojects/plugin-base-frontend/src/main/components/search/search.tsx @@ -0,0 +1,74 @@ +/* + * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +import React, {useCallback, useEffect, useState} from 'react'; +import List from '@jetbrains/ring-ui/components/list/list'; +import Select from '@jetbrains/ring-ui/components/select/select'; +import '@jetbrains/ring-ui/components/input-size/input-size.css'; +import './search.scss'; +import {CustomAnchorProps, IWindow, Option, Props} from "./types"; +import {DokkaSearchAnchor} from "./dokkaSearchAnchor"; +import {DokkaFuzzyFilterComponent} from "./dokkaFuzzyFilter"; +import {relativizeUrlForRequest} from '../utils/requests'; + +const WithFuzzySearchFilterComponent: React.FC = ({ data }: Props) => { + const [selected, onSelected] = useState