From c1f50d6f504054343cda0470f6ae85648ed26a7e Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:09:51 +0300 Subject: [PATCH] D: Improve TSDocs for frontend components --- README.md | 1 + .../frontend/src/app/Navigation/UserMenu.tsx | 2 +- .../frontend/src/components/DomainIcons.tsx | 10 +++++ .../src/components/info/BadgeConstituenta.tsx | 8 ++++ .../src/components/info/BadgeGrammeme.tsx | 4 ++ .../src/components/info/BadgeHelp.tsx | 10 +++++ .../src/components/info/BadgeLocation.tsx | 4 ++ .../src/components/info/BadgeWordForm.tsx | 8 +++- .../components/select/PickConstituenta.tsx | 4 +- .../select/PickMultiConstituenta.tsx | 4 +- .../src/components/select/PickSchema.tsx | 4 +- .../src/components/ui/DataTable/DataTable.tsx | 41 ++++++++++++++++++- .../frontend/src/components/ui/Loader.tsx | 14 +++++-- .../frontend/src/components/ui/MiniButton.tsx | 8 ++++ .../frontend/src/components/ui/Modal.tsx | 23 +++++++++++ .../frontend/src/components/ui/NoData.tsx | 3 ++ .../frontend/src/components/ui/Overlay.tsx | 8 ++++ .../src/components/ui/PDFViewer/PDFViewer.tsx | 11 +++++ .../frontend/src/components/ui/PrettyJSON.tsx | 3 ++ .../frontend/src/components/ui/SearchBar.tsx | 34 ++++++++++++--- .../src/components/ui/SelectMulti.tsx | 3 ++ .../src/components/ui/SelectSingle.tsx | 3 ++ .../frontend/src/components/ui/SelectTree.tsx | 32 +++++++++++---- .../src/components/ui/SelectorButton.tsx | 9 ++++ .../src/components/ui/SubmitButton.tsx | 10 ++++- .../frontend/src/components/ui/TabLabel.tsx | 4 ++ .../frontend/src/components/ui/TextArea.tsx | 8 ++++ .../src/components/ui/TextContent.tsx | 8 ++++ .../frontend/src/components/ui/TextInput.tsx | 6 +++ .../frontend/src/components/ui/TextURL.tsx | 12 ++++++ .../frontend/src/components/ui/Tooltip.tsx | 8 +++- .../frontend/src/components/ui/ValueIcon.tsx | 20 ++++++++- .../src/components/ui/ValueLabeled.tsx | 10 +++++ .../frontend/src/components/ui/ValueStats.tsx | 8 ++++ .../src/pages/LibraryPage/ToolbarSearch.tsx | 8 ++-- .../src/pages/ManualsPage/TopicsDropdown.tsx | 2 +- .../src/pages/ManualsPage/TopicsStatic.tsx | 2 +- .../EditorRSExpression/StatusBar.tsx | 2 +- .../RSFormPage/EditorRSList/EditorRSList.tsx | 4 +- .../ViewConstituents/ConstituentsSearch.tsx | 4 +- 40 files changed, 326 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 9710dad1..d8647431 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ This readme file is used mostly to document project dependencies and conventions - @uiw/react-codemirror - @uiw/codemirror-themes - @lezer/lr + - @dagrejs/dagre
diff --git a/rsconcept/frontend/src/app/Navigation/UserMenu.tsx b/rsconcept/frontend/src/app/Navigation/UserMenu.tsx index f5c32cb6..ec877a86 100644 --- a/rsconcept/frontend/src/app/Navigation/UserMenu.tsx +++ b/rsconcept/frontend/src/app/Navigation/UserMenu.tsx @@ -24,7 +24,7 @@ function UserMenu() { {loading ? ( - + ) : null} {!user && !loading ? ( diff --git a/rsconcept/frontend/src/components/DomainIcons.tsx b/rsconcept/frontend/src/components/DomainIcons.tsx index c4ab334d..956e65ad 100644 --- a/rsconcept/frontend/src/components/DomainIcons.tsx +++ b/rsconcept/frontend/src/components/DomainIcons.tsx @@ -45,6 +45,7 @@ export interface DomIconProps extends IconProps { value: RequestData; } +/** Icon for library item type. */ export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value) { case LibraryItemType.RSFORM: @@ -54,6 +55,7 @@ export function ItemTypeIcon({ value, size = '1.25rem', className }: DomIconProp } } +/** Icon for access policy. */ export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value) { case AccessPolicy.PRIVATE: @@ -65,6 +67,7 @@ export function PolicyIcon({ value, size = '1.25rem', className }: DomIconProps< } } +/** Icon for visibility. */ export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconProps) { if (value) { return ; @@ -73,6 +76,7 @@ export function VisibilityIcon({ value, size = '1.25rem', className }: DomIconPr } } +/** Icon for subfolders. */ export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconProps) { if (value) { return ; @@ -81,6 +85,7 @@ export function SubfoldersIcon({ value, size = '1.25rem', className }: DomIconPr } } +/** Icon for location. */ export function LocationIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value.substring(0, 2) as LocationHead) { case LocationHead.COMMON: @@ -94,6 +99,7 @@ export function LocationIcon({ value, size = '1.25rem', className }: DomIconProp } } +/** Icon for term graph dependency mode. */ export function DependencyIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value) { case DependencyMode.ALL: @@ -109,6 +115,7 @@ export function DependencyIcon({ value, size = '1.25rem', className }: DomIconPr } } +/** Icon for constituenta match mode. */ export function MatchModeIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value) { case CstMatchMode.ALL: @@ -124,6 +131,7 @@ export function MatchModeIcon({ value, size = '1.25rem', className }: DomIconPro } } +/** Icon for expression status. */ export function StatusIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value) { case ExpressionStatus.VERIFIED: @@ -141,6 +149,7 @@ export function StatusIcon({ value, size = '1.25rem', className }: DomIconProps< } } +/** Icon for constituenta type. */ export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps) { switch (value) { case CstType.BASE: @@ -162,6 +171,7 @@ export function CstTypeIcon({ value, size = '1.25rem', className }: DomIconProps } } +/** Icon for relocation direction. */ export function RelocateUpIcon({ value, size = '1.25rem', className }: DomIconProps) { if (value) { return ; diff --git a/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx b/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx index 08eb2216..bc08161b 100644 --- a/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx +++ b/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx @@ -7,11 +7,19 @@ import { CProps } from '../props'; import TooltipConstituenta from './TooltipConstituenta'; interface BadgeConstituentaProps extends CProps.Styling { + /** Prefix for tooltip ID. */ prefixID?: string; + + /** Constituenta to display. */ value: IConstituenta; + + /** Color theme to use. */ theme: IColorTheme; } +/** + * Displays a badge with a constituenta alias and information tooltip. + */ function BadgeConstituenta({ value, prefixID, className, style, theme }: BadgeConstituentaProps) { return (
diff --git a/rsconcept/frontend/src/components/info/BadgeWordForm.tsx b/rsconcept/frontend/src/components/info/BadgeWordForm.tsx index efe36fb7..36cd20e3 100644 --- a/rsconcept/frontend/src/components/info/BadgeWordForm.tsx +++ b/rsconcept/frontend/src/components/info/BadgeWordForm.tsx @@ -3,10 +3,16 @@ import { IWordForm } from '@/models/language'; import BadgeGrammeme from './BadgeGrammeme'; interface BadgeWordFormProps { - keyPrefix?: string; + /** Word form to display. */ form: IWordForm; + + /** Prefix for grammemes keys. */ + keyPrefix?: string; } +/** + * Displays a badge with grammemes of a word form. + */ function BadgeWordForm({ keyPrefix, form }: BadgeWordFormProps) { return (
diff --git a/rsconcept/frontend/src/components/select/PickConstituenta.tsx b/rsconcept/frontend/src/components/select/PickConstituenta.tsx index 365e3d06..e529aba8 100644 --- a/rsconcept/frontend/src/components/select/PickConstituenta.tsx +++ b/rsconcept/frontend/src/components/select/PickConstituenta.tsx @@ -98,8 +98,8 @@ function PickConstituenta({ id={id ? `${id}__search` : undefined} className='clr-input rounded-t-md' noBorder - value={filterText} - onChange={newValue => setFilterText(newValue)} + query={filterText} + onChangeQuery={newValue => setFilterText(newValue)} /> setFilterText(newValue)} + query={filterText} + onChangeQuery={newValue => setFilterText(newValue)} />
{ + /** Callback to determine if the style should be applied. */ when: (rowData: TData) => boolean; + + /** Style to apply. */ style: React.CSSProperties; } export interface DataTableProps extends CProps.Styling, Pick, 'data' | 'columns' | 'onRowSelectionChange' | 'onColumnVisibilityChange'> { + /** Id of the component. */ id?: string; + + /** Indicates that padding should be minimal. */ dense?: boolean; + + /** Number of rows to display. */ rows?: number; + + /** Height of the content. */ contentHeight?: string; + + /** Top position of sticky header (0 if no other sticky elements are present). */ headPosition?: string; + + /** Disable header. */ noHeader?: boolean; + + /** Disable footer. */ noFooter?: boolean; + /** List of styles to conditionally apply to rows. */ conditionalRowStyles?: IConditionalStyle[]; + + /** Component to display when there is no data. */ noDataComponent?: React.ReactNode; + /** Callback to be called when a row is clicked. */ onRowClicked?: (rowData: TData, event: CProps.EventMouse) => void; + + /** Callback to be called when a row is double clicked. */ onRowDoubleClicked?: (rowData: TData, event: CProps.EventMouse) => void; + /** Enable row selection. */ enableRowSelection?: boolean; + + /** Current row selection. */ rowSelection?: RowSelectionState; + /** Enable hiding of columns. */ enableHiding?: boolean; + + /** Current column visibility. */ columnVisibility?: VisibilityState; + /** Enable pagination. */ enablePagination?: boolean; + + /** Number of rows per page. */ paginationPerPage?: number; + + /** List of options to choose from for pagination. */ paginationOptions?: number[]; + + /** Callback to be called when the pagination option is changed. */ onChangePaginationOption?: (newValue: number) => void; + /** Enable sorting. */ enableSorting?: boolean; + + /** Initial sorting. */ initialSorting?: ColumnSort; } /** - * UI element: data representation as a table. + * Dta representation as a table. * * @param headPosition - Top position of sticky header (0 if no other sticky elements are present). * No sticky header if omitted diff --git a/rsconcept/frontend/src/components/ui/Loader.tsx b/rsconcept/frontend/src/components/ui/Loader.tsx index c49403f5..280426dc 100644 --- a/rsconcept/frontend/src/components/ui/Loader.tsx +++ b/rsconcept/frontend/src/components/ui/Loader.tsx @@ -7,18 +7,24 @@ import { useConceptOptions } from '@/context/ConceptOptionsContext'; import AnimateFade from '../wrap/AnimateFade'; interface LoaderProps { - size?: number; + /** Scale of the loader from 1 to 10. */ + scale?: number; + + /** Show a circular loader. */ circular?: boolean; } -function Loader({ size = 10, circular }: LoaderProps) { +/** + * Displays animated loader. + */ +function Loader({ scale = 5, circular }: LoaderProps) { const { colors } = useConceptOptions(); return ( {circular ? ( - + ) : ( - + )} ); diff --git a/rsconcept/frontend/src/components/ui/MiniButton.tsx b/rsconcept/frontend/src/components/ui/MiniButton.tsx index feb0f454..fe55b217 100644 --- a/rsconcept/frontend/src/components/ui/MiniButton.tsx +++ b/rsconcept/frontend/src/components/ui/MiniButton.tsx @@ -5,11 +5,19 @@ import { globals } from '@/utils/constants'; import { CProps } from '../props'; interface MiniButtonProps extends CProps.Button { + /** Icon to display in the button. */ icon: React.ReactNode; + + /** Disable hover effect. */ noHover?: boolean; + + /** Disable padding. */ noPadding?: boolean; } +/** + * Displays small transparent button with an icon. + */ function MiniButton({ icon, noHover, diff --git a/rsconcept/frontend/src/components/ui/Modal.tsx b/rsconcept/frontend/src/components/ui/Modal.tsx index 63a32651..284f2a13 100644 --- a/rsconcept/frontend/src/components/ui/Modal.tsx +++ b/rsconcept/frontend/src/components/ui/Modal.tsx @@ -18,23 +18,46 @@ import MiniButton from './MiniButton'; import Overlay from './Overlay'; export interface ModalProps extends CProps.Styling { + /** Title of the modal window. */ header?: string; + + /** Text of the submit button. */ submitText?: string; + + /** Tooltip for the submit button when the form is invalid. */ submitInvalidTooltip?: string; + /** Indicates that form is readonly. */ readonly?: boolean; + + /** Indicates that submit button is enabled. */ canSubmit?: boolean; + + /** Indicates that the modal window should be scrollable. */ overflowVisible?: boolean; + /** Callback to be called when the modal window is closed. */ hideWindow: () => void; + + /** Callback to be called before submit. */ beforeSubmit?: () => boolean; + + /** Callback to be called after submit. */ onSubmit?: () => void; + + /** Callback to be called after cancel. */ onCancel?: () => void; + /** Help topic to be displayed in the modal window. */ helpTopic?: HelpTopic; + + /** Callback to determine if help should be displayed. */ hideHelpWhen?: () => boolean; } +/** + * Displays a customizable modal window. + */ function Modal({ children, diff --git a/rsconcept/frontend/src/components/ui/NoData.tsx b/rsconcept/frontend/src/components/ui/NoData.tsx index 9b69ab37..5a687988 100644 --- a/rsconcept/frontend/src/components/ui/NoData.tsx +++ b/rsconcept/frontend/src/components/ui/NoData.tsx @@ -2,6 +2,9 @@ import clsx from 'clsx'; import { CProps } from '../props'; +/** + * Wraps content in a div with a centered text. + */ function NoData({ className, children, ...restProps }: CProps.Div) { return (
diff --git a/rsconcept/frontend/src/components/ui/Overlay.tsx b/rsconcept/frontend/src/components/ui/Overlay.tsx index de8b0708..bb4a2d6d 100644 --- a/rsconcept/frontend/src/components/ui/Overlay.tsx +++ b/rsconcept/frontend/src/components/ui/Overlay.tsx @@ -3,11 +3,19 @@ import clsx from 'clsx'; import { CProps } from '../props'; interface OverlayProps extends CProps.Styling { + /** Id of the overlay. */ id?: string; + + /** Classnames for position of the overlay. */ position?: string; + + /** Classname for z-index of the overlay. */ layer?: string; } +/** + * Displays a transparent overlay over the main content. + */ function Overlay({ children, className, diff --git a/rsconcept/frontend/src/components/ui/PDFViewer/PDFViewer.tsx b/rsconcept/frontend/src/components/ui/PDFViewer/PDFViewer.tsx index 2f48bfc0..6e7ecead 100644 --- a/rsconcept/frontend/src/components/ui/PDFViewer/PDFViewer.tsx +++ b/rsconcept/frontend/src/components/ui/PDFViewer/PDFViewer.tsx @@ -5,15 +5,26 @@ import { useMemo } from 'react'; import { useConceptOptions } from '@/context/ConceptOptionsContext'; import useWindowSize from '@/hooks/useWindowSize'; +/** Maximum width of the viewer. */ const MAXIMUM_WIDTH = 1600; + +/** Minimum width of the viewer. */ const MINIMUM_WIDTH = 300; interface PDFViewerProps { + /** PDF file to display. */ file?: string; + + /** Offset from the left side of the window. */ offsetXpx?: number; + + /** Minimum width of the viewer. */ minWidth?: number; } +/** + * Displays a PDF file using an embedded viewer. + */ function PDFViewer({ file, offsetXpx, minWidth = MINIMUM_WIDTH }: PDFViewerProps) { const windowSize = useWindowSize(); const { calculateHeight } = useConceptOptions(); diff --git a/rsconcept/frontend/src/components/ui/PrettyJSON.tsx b/rsconcept/frontend/src/components/ui/PrettyJSON.tsx index 53304125..d0d4fc1e 100644 --- a/rsconcept/frontend/src/components/ui/PrettyJSON.tsx +++ b/rsconcept/frontend/src/components/ui/PrettyJSON.tsx @@ -2,6 +2,9 @@ interface PrettyJsonProps { data: unknown; } +/** + * Displays JSON data in a formatted string. + */ function PrettyJson({ data }: PrettyJsonProps) { return
{JSON.stringify(data, null, 2)}
; } diff --git a/rsconcept/frontend/src/components/ui/SearchBar.tsx b/rsconcept/frontend/src/components/ui/SearchBar.tsx index a2baccb8..49475bbf 100644 --- a/rsconcept/frontend/src/components/ui/SearchBar.tsx +++ b/rsconcept/frontend/src/components/ui/SearchBar.tsx @@ -6,15 +6,37 @@ import Overlay from './Overlay'; import TextInput from './TextInput'; interface SearchBarProps extends CProps.Styling { - value: string; - noIcon?: boolean; + /** Id of the search bar. */ id?: string; + + /** Search query. */ + query: string; + + /** Placeholder text. */ placeholder?: string; - onChange?: (newValue: string) => void; + + /** Callback to be called when the search query changes. */ + onChangeQuery?: (newValue: string) => void; + + /** Disable search icon. */ + noIcon?: boolean; + + /** Disable border. */ noBorder?: boolean; } -function SearchBar({ id, value, noIcon, onChange, noBorder, placeholder = 'Поиск', ...restProps }: SearchBarProps) { +/** + * Displays a search bar with a search icon and text input. + */ +function SearchBar({ + id, + query, + noIcon, + onChangeQuery, + noBorder, + placeholder = 'Поиск', + ...restProps +}: SearchBarProps) { return (
{!noIcon ? ( @@ -29,8 +51,8 @@ function SearchBar({ id, value, noIcon, onChange, noBorder, placeholder = 'По type='search' className={clsx('outline-none bg-transparent', !noIcon && 'pl-10')} noBorder={noBorder} - value={value} - onChange={event => (onChange ? onChange(event.target.value) : undefined)} + value={query} + onChange={event => (onChangeQuery ? onChangeQuery(event.target.value) : undefined)} />
); diff --git a/rsconcept/frontend/src/components/ui/SelectMulti.tsx b/rsconcept/frontend/src/components/ui/SelectMulti.tsx index bf4cf541..80b321b6 100644 --- a/rsconcept/frontend/src/components/ui/SelectMulti.tsx +++ b/rsconcept/frontend/src/components/ui/SelectMulti.tsx @@ -45,6 +45,9 @@ export interface SelectMultiProps = Grou noPortal?: boolean; } +/** + * Displays a multi-select component. + */ function SelectMulti = GroupBase