Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dropdown Menus #1396

Merged
merged 70 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
fd75d7c
Add internal version of DropdownButton and MenuItem
labkey-alan Jan 18, 2024
7efd907
useOverlayTriggerState - return mouseOut instead of mouseLeave
labkey-alan Jan 18, 2024
191b7fb
useOverlayPositioning - Add warning when targetRef is not passed
labkey-alan Jan 18, 2024
3b1e690
ProductNavigation.tsx: add TODO
labkey-alan Jan 18, 2024
becec74
ProductMenu: add TODO
labkey-alan Jan 18, 2024
eca071c
Delete MultiMenuButton (unused)
labkey-alan Jan 18, 2024
027a956
Add styling for internal version of Dropdown Menus
labkey-alan Jan 18, 2024
f661e9d
PageMenu, ExportMenu, ViewMenu - use internal version of DropdownMenu…
labkey-alan Jan 18, 2024
e169668
DisableableButton - use onMouseOut
labkey-alan Jan 18, 2024
4664550
SubMenu/SubMenuItem: Add FIXMEs
labkey-alan Jan 18, 2024
8975845
ManageDropdownButton - Use internal DropdownButton, remove id prop
labkey-alan Jan 18, 2024
34299ae
QueryModel: don't return id as part of PaginationData
labkey-alan Jan 18, 2024
f7fe635
Remove SplitButtonGroup, add SplitButton
labkey-alan Jan 19, 2024
d4e134d
Export DropdownButton, SplitButton, MenuItem, MenuHeader, MenuDivider
labkey-alan Jan 19, 2024
98b7c14
MenuItem: add title prop
labkey-alan Jan 19, 2024
4c45bfc
GridPanel: use internal SplitButton and MenuItem
labkey-alan Jan 19, 2024
a054421
SplitButton: support href
labkey-alan Jan 19, 2024
54f3199
SampleAliquotViewSelector: add TODO, use ===
labkey-alan Jan 19, 2024
65db9b9
Update release notes
labkey-alan Jan 19, 2024
010c8d6
BarChartViewer: Use internal DropdownButton, MenuItem
labkey-alan Jan 19, 2024
a7599bc
SampleAliquotViewSelector: Use internal DropdownButton, MenuItem
labkey-alan Jan 19, 2024
fb3c274
FindAndSearchDropdown: Use internal DropdownButton, MenuItem
labkey-alan Jan 19, 2024
91ac5fd
VisGraphControls: Use internal DropdownButton, MenuItem
labkey-alan Jan 19, 2024
98f76f7
DropdownButton: Don't use nbsp in toggle
labkey-alan Jan 22, 2024
0439a73
DropdownButton: Don't add margin to caret if title is empty
labkey-alan Jan 22, 2024
cd62d8f
BarChartViewer: Add className to dropdown
labkey-alan Jan 22, 2024
bd1a21c
SampleAliquotViewSelector: Add className
labkey-alan Jan 22, 2024
46fe683
ManageDropdownButton: Remove all props
labkey-alan Jan 22, 2024
cbd8cd3
BarChartViewer - add className to chart menu
labkey-alan Jan 22, 2024
ff65c8f
SplitButton: Fix onClick type
labkey-alan Jan 22, 2024
05ee37b
SplitButton: Add additional classNames to assist test locators
labkey-alan Jan 23, 2024
83e6bcd
SelectionMenuItem, DisableableMenuItem: convert to internal version o…
labkey-alan Jan 23, 2024
5249c13
DisableableMenuItem: update portal id
labkey-alan Jan 23, 2024
9f0c57b
Add DropdownAnchor: replaces Dropdown and Dropdown.Toggle from react …
labkey-alan Jan 23, 2024
9478a7f
use DropdownAnchor
labkey-alan Jan 23, 2024
72aec89
Add optional rel prop to MenuItem
labkey-alan Jan 23, 2024
fd87dcf
Add displayName to dropdown components
labkey-alan Jan 23, 2024
0b4bfdc
Update releaseNotes
labkey-alan Jan 23, 2024
0ff0452
Add classNames to user menu, settings menu, help menu
labkey-alan Jan 24, 2024
8c72f1a
UserMenuGroup: fix className
labkey-alan Jan 24, 2024
4480736
DropdownButton: className -> buttonClassName
labkey-alan Jan 24, 2024
42b6477
SplitButton: Refactor to simplify DOM
labkey-alan Jan 24, 2024
92d17c2
cleanup
labkey-alan Jan 24, 2024
5caf22a
UserMenuGroup: Update class names
labkey-alan Jan 24, 2024
1a7b6a2
Fix navbar styles
labkey-alan Jan 24, 2024
92fa168
ManageDropdownButton.spec.tsx - delete tests, they're no longer relevant
labkey-alan Jan 24, 2024
bb5b457
ChartMenu: Use internal versions of DropdownButton and MenuItem
labkey-alan Jan 24, 2024
16e25e1
renderers.tsx - Use internal MenuItem
labkey-alan Jan 24, 2024
be5bb1b
ResponsiveMenuButton: Add TODO
labkey-alan Jan 24, 2024
6601abd
ResponsiveMenuButtonGroup: Add TODO
labkey-alan Jan 24, 2024
562dedd
GroupManagementPage: use internal version of MenuItem
labkey-alan Jan 24, 2024
fb19957
UserManagement - use internal version of MenuItem
labkey-alan Jan 24, 2024
e618546
SubMenu: Add TODO
labkey-alan Jan 24, 2024
457ef32
SelectionMenuItem.spec.tsx don't use MenuItem
labkey-alan Jan 24, 2024
9c2d216
UserMenuGroup.spec.tsx - User internal components
labkey-alan Jan 24, 2024
579cdd2
ServerNotifications: Add TODO
labkey-alan Jan 24, 2024
7e9905b
PageMenu.spec.tsx - use internal components
labkey-alan Jan 24, 2024
1fae2c1
Picklist menu items: User internal MenuItem
labkey-alan Jan 24, 2024
7565a87
UsersGridPanel: Use internal MenuItem
labkey-alan Jan 24, 2024
996a1ea
DropdownButton: Add optional onClick prop
labkey-alan Jan 24, 2024
a56f683
Fix issue with popover size
labkey-alan Jan 25, 2024
eaef4a3
Update styling for toolbar menus
labkey-alan Jan 25, 2024
ae907fd
PR Feedback
labkey-alan Jan 25, 2024
9e24b21
Fix tests
labkey-alan Jan 25, 2024
a50d235
SchemaBrowserRoutes - Remove test code
labkey-alan Jan 25, 2024
2c82731
DisableableMenuItem - add displayName
labkey-alan Jan 25, 2024
f280415
preventDocumentHandler: Fix issue with tests
labkey-alan Jan 25, 2024
6630169
ManageDropdownButton: Add displayName
labkey-alan Jan 25, 2024
a525f25
Prep for release
labkey-alan Jan 26, 2024
90f7c99
Prep for release
labkey-alan Jan 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/components",
"version": "3.10.0",
"version": "3.11.0",
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
"sideEffects": false,
"files": [
Expand Down
13 changes: 13 additions & 0 deletions packages/components/releaseNotes/components.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# @labkey/components
Components, models, actions, and utility functions for LabKey applications and pages.

### version 3.11.0
*Released*: 29 January 2024
- Remove MultiMenuButton
- it was unused
- Add DropdownButton
- Add DropdownAnchor
- Add SplitButton
- Add MenuItem
- Add MenuHeader
- Add MenuDivider
- Update usages of react-bootstrap DropdownButton, SplitButton, MenuItem to internal versions
- ManageDropdownMenu: remove all props

### version 3.10.0
*Released*: 26 January 2024
- Add `AuditSettings` panel for configuring whether user comments are required for data changes
Expand Down
11 changes: 7 additions & 4 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ import { LockIcon } from './internal/components/base/LockIcon';
import { ExpandableFilterToggle } from './internal/components/base/ExpandableFilterToggle';
import { DragDropHandle } from './internal/components/base/DragDropHandle';
import { FieldExpansionToggle } from './internal/components/base/FieldExpansionToggle';
import { MultiMenuButton } from './internal/components/menus/MultiMenuButton';
import { SubMenu } from './internal/components/menus/SubMenu';
import { SubMenuItem } from './internal/components/menus/SubMenuItem';
import { SelectionMenuItem } from './internal/components/menus/SelectionMenuItem';
Expand Down Expand Up @@ -165,7 +164,6 @@ import { RequiresPermission } from './internal/components/base/Permissions';
import { PaginationButtons } from './internal/components/buttons/PaginationButtons';
import { ManageDropdownButton } from './internal/components/buttons/ManageDropdownButton';
import { WizardNavButtons } from './internal/components/buttons/WizardNavButtons';
import { SplitButtonGroup } from './internal/components/buttons/SplitButtonGroup';
import { ToggleButtons, ToggleIcon } from './internal/components/buttons/ToggleButtons';
import { DisableableButton } from './internal/components/buttons/DisableableButton';
import { ResponsiveMenuButton } from './internal/components/buttons/ResponsiveMenuButton';
Expand Down Expand Up @@ -838,6 +836,7 @@ import { getFolderTestAPIWrapper } from './internal/components/container/FolderA
import { OverlayTrigger, useOverlayTriggerState } from './internal/OverlayTrigger';
import { Tooltip } from './internal/Tooltip';
import { Popover } from './internal/Popover';
import { DropdownAnchor, DropdownButton, MenuDivider, MenuItem, MenuHeader, SplitButton } from './internal/dropdowns';

// See Immer docs for why we do this: https://immerjs.github.io/immer/docs/installation#pick-your-immer-version
enableMapSet();
Expand Down Expand Up @@ -1511,12 +1510,10 @@ export {
parseCsvString,
quoteValueWithDelimiters,
// buttons and menus
MultiMenuButton,
SubMenu,
SubMenuItem,
SelectionMenuItem,
ManageDropdownButton,
SplitButtonGroup,
PaginationButtons,
ToggleButtons,
ToggleIcon,
Expand Down Expand Up @@ -1681,6 +1678,12 @@ export {
Popover,
OverlayTrigger,
useOverlayTriggerState,
DropdownAnchor,
DropdownButton,
MenuDivider,
MenuItem,
MenuHeader,
SplitButton,
};

// Due to babel-loader & typescript babel plugins we need to export/import types separately. The babel plugins require
Expand Down
10 changes: 5 additions & 5 deletions packages/components/src/internal/OverlayTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { usePortalRef } from './hooks';

interface OverlayTriggerState<T extends Element = HTMLDivElement> {
onMouseEnter: () => void;
onMouseLeave: () => void;
onMouseOut: () => void;
onClick: () => void;
portalEl: HTMLElement;
show: boolean;
Expand Down Expand Up @@ -54,7 +54,7 @@ export function useOverlayTriggerState<T extends Element = HTMLDivElement>(

setShow(true);
}, [delay, hoverEventsEnabled]);
const onMouseLeave = useCallback(() => {
const onMouseOut = useCallback(() => {
if (!hoverEventsEnabled) return;

setTimeoutId(currentId => {
Expand All @@ -72,7 +72,7 @@ export function useOverlayTriggerState<T extends Element = HTMLDivElement>(
return {
onClick,
onMouseEnter,
onMouseLeave,
onMouseOut,
portalEl,
show,
targetRef,
Expand Down Expand Up @@ -117,7 +117,7 @@ export const OverlayTrigger: FC<Props> = ({
overlay,
triggerType = 'hover',
}) => {
const { onMouseEnter, onMouseLeave, onClick, portalEl, show, targetRef } = useOverlayTriggerState(
const { onMouseEnter, onMouseOut, onClick, portalEl, show, targetRef } = useOverlayTriggerState(
id,
triggerType === 'hover',
triggerType === 'click',
Expand All @@ -128,7 +128,7 @@ export const OverlayTrigger: FC<Props> = ({
const clonedContent = cloneElement(overlay, { targetRef });

return (
<div className={className_} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} onClick={onClick}>
<div className={className_} onMouseEnter={onMouseEnter} onMouseLeave={onMouseOut} onClick={onClick}>
{clonedChild}

{show && createPortal(clonedContent, portalEl)}
Expand Down
43 changes: 23 additions & 20 deletions packages/components/src/internal/announcements/ThreadBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC, useCallback, useMemo, useState } from 'react';
import { Dropdown, MenuItem, Modal } from 'react-bootstrap';
import { Modal } from 'react-bootstrap';
import moment from 'moment';
import { User, UserWithPermissions } from '@labkey/api';

Expand All @@ -9,6 +9,8 @@ import { Alert } from '../components/base/Alert';

import { UserLink } from '../components/user/UserLink';

import { DropdownAnchor, MenuItem } from '../dropdowns';

import { AnnouncementModel } from './model';
import { ThreadEditor, ThreadEditorProps } from './ThreadEditor';
import { ThreadAttachments } from './ThreadAttachments';
Expand Down Expand Up @@ -106,23 +108,22 @@ const ThreadBlockHeader: FC<ThreadBlockHeaderProps> = props => {
{isEdited ? ' (Edited)' : ''}
</span>
{(onDelete || onEdit) && (
<Dropdown className="thread-block-header__menu" componentClass="span" id="thread-block-header-menu">
<Dropdown.Toggle useAnchor={true}>
<i className="fa fa-ellipsis-v" />
</Dropdown.Toggle>
<Dropdown.Menu className="pull-right">
{onEdit !== undefined && (
<MenuItem className="thread-block-header__menu-edit" onClick={onEdit}>
Edit Comment
</MenuItem>
)}
{onDelete !== undefined && (
<MenuItem className="thread-block-header__menu-delete" onClick={onShowDelete}>
Delete {isThread ? 'Thread' : 'Reply'}
</MenuItem>
)}
</Dropdown.Menu>
</Dropdown>
<DropdownAnchor
className="thread-block-header__menu"
title={<i className="fa fa-ellipsis-v" />}
pullRight
>
{onEdit !== undefined && (
<MenuItem className="thread-block-header__menu-edit" onClick={onEdit}>
Edit Comment
</MenuItem>
)}
{onDelete !== undefined && (
<MenuItem className="thread-block-header__menu-delete" onClick={onShowDelete}>
Delete {isThread ? 'Thread' : 'Reply'}
</MenuItem>
)}
</DropdownAnchor>
)}
</div>
{showDeleteModal && isThread && <DeleteThreadModal cancel={onCancelDelete} onDelete={onDelete} />}
Expand Down Expand Up @@ -229,7 +230,7 @@ export const ThreadBlock: FC<ThreadBlockProps> = props => {
{error !== undefined && <Alert>{error}</Alert>}
<div className="thread-block-body__content" dangerouslySetInnerHTML={threadBody} />

<ThreadAttachments attachments={thread.attachments ?? []} containerPath={containerPath}/>
<ThreadAttachments attachments={thread.attachments ?? []} containerPath={containerPath} />

{allowReply && (
<span className="clickable-text thread-block__reply" onClick={onReply}>
Expand All @@ -238,7 +239,9 @@ export const ThreadBlock: FC<ThreadBlockProps> = props => {
)}
{showReplyToggle && (
<span className="clickable-text thread-block__toggle-reply" onClick={onToggleResponses}>
{showResponses ? 'Hide all replies' : `Show all replies (${thread.responses.length.toLocaleString()})`}
{showResponses
? 'Hide all replies'
: `Show all replies (${thread.responses.length.toLocaleString()})`}
</span>
)}
{showRecent && (
Expand Down
15 changes: 5 additions & 10 deletions packages/components/src/internal/announcements/ThreadEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import React, {
useState,
} from 'react';
import classNames from 'classnames';
import { Dropdown, MenuItem } from 'react-bootstrap';

import { generateId, handleFileInputChange } from '../util/utils';
import { isLoading, LoadingState } from '../../public/LoadingState';
Expand All @@ -23,6 +22,7 @@ import { AnnouncementsAPIWrapper } from './APIWrapper';

import { RemoveAttachmentModal, ThreadAttachments } from './ThreadAttachments';
import { Attachment, AnnouncementModel } from './model';
import { DropdownAnchor, MenuItem } from '../dropdowns';

// Check if a line starts with any spaces, a number, followed by a period and a space.
const orderedBulletRe = /^\s*\d+. /;
Expand Down Expand Up @@ -160,7 +160,6 @@ interface ThreadEditorToolbarProps {
}

const ThreadEditorToolbar: FC<ThreadEditorToolbarProps> = memo(({ inputRef, setBody, setView, view }) => {
const id = useMemo(() => generateId() + '-thread-editor-dropdown', []);
const bold = useCallback(() => {
const [body, selectionStart, selectionEnd] = applyTemplate(inputRef.current, '**', '**');
setBody(body, selectionStart, selectionEnd);
Expand Down Expand Up @@ -188,14 +187,10 @@ const ThreadEditorToolbar: FC<ThreadEditorToolbarProps> = memo(({ inputRef, setB
return (
<div className="thread-editor-toolbar editor-toolbar">
<div className="editor-toolbar__section insert-menu">
<Dropdown componentClass="div" id={id}>
<Dropdown.Toggle useAnchor={true}>{view}</Dropdown.Toggle>

<Dropdown.Menu>
<MenuItem onClick={setEditMode}>{EditorView.edit}</MenuItem>
<MenuItem onClick={setPreviewMode}>{EditorView.preview}</MenuItem>
</Dropdown.Menu>
</Dropdown>
<DropdownAnchor title={view}>
<MenuItem onClick={setEditMode}>{EditorView.edit}</MenuItem>
<MenuItem onClick={setPreviewMode}>{EditorView.preview}</MenuItem>
</DropdownAnchor>
</div>

<div className="editor-toolbar__section">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { FC, memo, useCallback, useEffect, useMemo, useState } from 'react';
import { MenuItem } from 'react-bootstrap';
import { List } from 'immutable';

import { BasePermissionsCheckPage } from '../permissions/BasePermissionsCheckPage';
Expand Down Expand Up @@ -32,6 +31,8 @@ import { AUDIT_KEY } from '../../app/constants';

import { NotFound } from '../base/NotFound';

import { MenuItem } from '../../dropdowns';

import { useAdministrationSubNav } from './useAdministrationSubNav';

import { GroupAssignments } from './GroupAssignments';
Expand Down Expand Up @@ -174,7 +175,7 @@ export const GroupManagementPageImpl: FC<GroupManagementPageProps> = memo(props
return (
<>
<CreatedModified row={row} useServerDate={false} />
<ManageDropdownButton collapsed id="admin-page-manage" pullRight>
<ManageDropdownButton>
<MenuItem
href={AppURL.create(AUDIT_KEY)
.addParam(AUDIT_EVENT_TYPE_PARAM, GROUP_AUDIT_QUERY.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*/
import React, { FC, PureComponent, ReactNode } from 'react';
import { List } from 'immutable';
import { MenuItem } from 'react-bootstrap';
import { PermissionRoles, Project, Utils } from '@labkey/api';

import { User } from '../base/models/User';
Expand Down Expand Up @@ -36,6 +35,8 @@ import { NotFound } from '../base/NotFound';

import { isProductProjectsEnabled } from '../../app/utils';

import { MenuItem } from '../../dropdowns';

import { useAdministrationSubNav } from './useAdministrationSubNav';

import { isLoginAutoRedirectEnabled, showPremiumFeatures } from './utils';
Expand Down Expand Up @@ -269,7 +270,7 @@ export class UserManagement extends PureComponent<UserManagementProps, State> {

renderButtons = (): ReactNode => {
return (
<ManageDropdownButton collapsed id="user-management-page-manage" pullRight>
<ManageDropdownButton>
<MenuItem
href={AppURL.create(AUDIT_KEY).addParam(AUDIT_EVENT_TYPE_PARAM, USER_AUDIT_QUERY.value).toHref()}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface Props {

export const DisableableButton: FC<Props> = memo(props => {
const { bsStyle = 'default', children, className = '', disabledMsg, onClick, title } = props;
const { onMouseEnter, onMouseLeave, portalEl, show, targetRef } = useOverlayTriggerState<HTMLButtonElement>(
const { onMouseEnter, onMouseOut, portalEl, show, targetRef } = useOverlayTriggerState<HTMLButtonElement>(
'disabled-button-overlay',
disabledMsg !== undefined,
false
Expand All @@ -36,7 +36,7 @@ export const DisableableButton: FC<Props> = memo(props => {
disabled={disabledMsg !== undefined}
onClick={onClick}
onPointerEnter={onMouseEnter}
onPointerLeave={onMouseLeave}
onPointerLeave={onMouseOut}
type="button"
ref={targetRef}
>
Expand Down

This file was deleted.

Loading