Revert "Added tests"

This reverts commit e5bc177345.
This commit is contained in:
Harshil Sharma 2023-02-06 16:52:21 +05:30
parent c03539f33c
commit ecb2d445ed
40 changed files with 239 additions and 457 deletions

View file

@ -19,7 +19,6 @@ import {Permission} from '../../../../webapp/src/constants'
import './rhsChannelBoardItem.scss'
import BoardPermissionGate from '../../../../webapp/src/components/permissions/boardPermissionGate'
import {MenuText} from '../../../../webapp/src/widgets/menu/menu'
const windowAny = (window as SuiteWindow)
@ -67,7 +66,7 @@ const RHSChannelBoardItem = (props: Props) => {
teamId={team.id}
permissions={[Permission.ManageBoardRoles]}
>
<MenuText
<Menu.Text
key={`unlinkBoard-${board.id}`}
id='unlinkBoard'
name={intl.formatMessage({id: 'rhs-boards.unlink-board', defaultMessage: 'Unlink board'})}
@ -83,7 +82,7 @@ const RHSChannelBoardItem = (props: Props) => {
permissions={[Permission.ManageBoardRoles]}
invert={true}
>
<MenuText
<Menu.Text
key={`unlinkBoard-${board.id}`}
id='unlinkBoard'
disabled={true}

View file

@ -4,13 +4,12 @@
import React from 'react'
import {useIntl} from 'react-intl'
import {MenuText} from '../widgets/menu/menu'
import {BlockTypes, Block} from '../blocks/block'
import {Card} from '../blocks/card'
import mutator from '../mutator'
import octoClient from '../octoClient'
import {Utils} from '../utils'
import Menu from '../widgets/menu'
import {contentRegistry} from './content/contentRegistry'
@ -32,7 +31,7 @@ const AddContentMenuItem = (props: Props): JSX.Element => {
}
return (
<MenuText
<Menu.Text
key={type}
id={type}
name={handler.getDisplayText(intl)}

View file

@ -26,7 +26,6 @@ import {TOUR_SIDEBAR, SidebarTourSteps} from '../../components/onboardingTour'
import IconButton from '../../widgets/buttons/iconButton'
import SearchForBoardsTourStep from '../../components/onboardingTour/searchForBoards/searchForBoards'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
onBoardTemplateSelectorOpen: () => void
@ -110,13 +109,13 @@ const BoardsSwitcher = (props: Props): JSX.Element => {
icon={<AddIcon/>}
/>
<Menu>
<MenuText
<Menu.Text
id='create-new-board-option'
icon={<CompassIcon icon='plus'/>}
onClick={props.onBoardTemplateSelectorOpen}
name='Create new board'
/>
<MenuText
<Menu.Text
id='createNewCategory'
name={intl.formatMessage({id: 'SidebarCategories.CategoryMenu.CreateNew', defaultMessage: 'Create New Category'})}
icon={

View file

@ -16,7 +16,6 @@ import {IUser} from '../../user'
import {getMe} from '../../store/users'
import {useAppSelector} from '../../store/hooks'
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../../telemetry/telemetryClient'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
cardId: string
@ -47,14 +46,14 @@ export const CardActionsMenu = (props: Props): JSX.Element => {
return (
<Menu position='left'>
<BoardPermissionGate permissions={[Permission.ManageBoardCards]}>
<MenuText
<Menu.Text
icon={<DeleteIcon/>}
id='delete'
name={intl.formatMessage({id: 'CardActionsMenu.delete', defaultMessage: 'Delete'})}
onClick={handleDeleteCard}
/>
{props.onClickDuplicate &&
<MenuText
<Menu.Text
icon={<DuplicateIcon/>}
id='duplicate'
name={intl.formatMessage({id: 'CardActionsMenu.duplicate', defaultMessage: 'Duplicate'})}
@ -62,7 +61,7 @@ export const CardActionsMenu = (props: Props): JSX.Element => {
/>}
</BoardPermissionGate>
{me?.id !== 'single-user' &&
<MenuText
<Menu.Text
icon={<LinkIcon/>}
id='copy'
name={intl.formatMessage({id: 'CardActionsMenu.copyLink', defaultMessage: 'Copy link'})}

View file

@ -7,7 +7,6 @@ import {BlockTypes} from '../../blocks/block'
import {Utils} from '../../utils'
import Button from '../../widgets/buttons/button'
import Menu from '../../widgets/menu'
import {MenuText} from '../../widgets/menu/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {contentRegistry} from '../content/contentRegistry'
@ -28,7 +27,7 @@ function addContentMenu(intl: IntlShape, type: BlockTypes): JSX.Element {
}, [cardDetail, handler])
return (
<MenuText
<Menu.Text
key={type}
id={type}
name={handler.getDisplayText(intl)}

View file

@ -17,7 +17,6 @@ import Tooltip from '../../widgets/tooltip'
import GuestBadge from '../../widgets/guestBadge'
import './comment.scss'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
comment: Block
@ -56,7 +55,7 @@ const Comment: FC<Props> = (props: Props) => {
<MenuWrapper>
<IconButton icon={<OptionsIcon/>}/>
<Menu position='left'>
<MenuText
<Menu.Text
icon={<DeleteIcon/>}
id='delete'
name={intl.formatMessage({id: 'Comment.delete', defaultMessage: 'Delete'})}

View file

@ -16,6 +16,7 @@ import {getCardAttachments, updateAttachments, updateUploadPrecent} from '../sto
import TelemetryClient, {TelemetryActions, TelemetryCategory} from '../telemetry/telemetryClient'
import {Utils} from '../utils'
import CompassIcon from '../widgets/icons/compassIcon'
import Menu from '../widgets/menu'
import {sendFlashMessage} from '../components/flashMessages'
import ConfirmationDialogBox, {ConfirmationDialogBoxProps} from '../components/confirmationDialogBox'
@ -31,8 +32,6 @@ import {Permission} from '../constants'
import {Block, createBlock} from '../blocks/block'
import {AttachmentBlock, createAttachmentBlock} from '../blocks/attachmentBlock'
import {MenuText} from '../widgets/menu/menu'
import BoardPermissionGate from './permissions/boardPermissionGate'
import CardDetail from './cardDetail/cardDetail'
@ -126,7 +125,7 @@ const CardDialog = (props: Props): JSX.Element => {
>
{!isTemplate &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<MenuText
<Menu.Text
id='makeTemplate'
icon={
<CompassIcon

View file

@ -17,16 +17,15 @@ import {getUploadPercent} from '../../store/attachments'
import {useAppSelector} from '../../store/hooks'
import {Permission} from '../../constants'
import './attachmentElement.scss'
import {MenuText} from '../../widgets/menu/menu'
import CompassIcon from '../../widgets/icons/compassIcon'
import MenuWrapper from '../../widgets/menuWrapper'
import IconButton from '../../widgets/buttons/iconButton'
import Menu from '../../widgets/menu'
import Tooltip from '../../widgets/tooltip'
import ArchivedFile from './archivedFile/archivedFile'
import './attachmentElement.scss'
import CompassIcon from './../../widgets/icons/compassIcon'
import MenuWrapper from './../../widgets/menuWrapper'
import IconButton from './../../widgets/buttons/iconButton'
import Menu from './../../widgets/menu'
import Tooltip from './../../widgets/tooltip'
type Props = {
block: AttachmentBlock
onDelete?: (block: Block) => void
@ -172,7 +171,7 @@ const AttachmentElement = (props: Props): JSX.Element|null => {
/>
<div className='delete-menu'>
<Menu position='left'>
<MenuText
<Menu.Text
id='makeTemplate'
icon={
<CompassIcon

View file

@ -19,7 +19,6 @@ import Menu from '../widgets/menu'
import MenuWrapper from '../widgets/menuWrapper'
import {useSortableWithGrip} from '../hooks/sortable'
import {Position} from '../components/cardDetail/cardDetailContents'
import {MenuSubMenu, MenuText} from '../widgets/menu/menu'
import ContentElement from './content/contentElement'
import AddContentMenuItem from './addContentMenuItem'
@ -77,7 +76,7 @@ const ContentBlock = (props: Props): JSX.Element => {
<IconButton icon={<OptionsIcon/>}/>
<Menu>
{index > 0 &&
<MenuText
<Menu.Text
id='moveUp'
name={intl.formatMessage({id: 'ContentBlock.moveUp', defaultMessage: 'Move up'})}
icon={<SortUpIcon/>}
@ -87,7 +86,7 @@ const ContentBlock = (props: Props): JSX.Element => {
}}
/>}
{index < (contentOrder.length - 1) &&
<MenuText
<Menu.Text
id='moveDown'
name={intl.formatMessage({id: 'ContentBlock.moveDown', defaultMessage: 'Move down'})}
icon={<SortDownIcon/>}
@ -96,7 +95,7 @@ const ContentBlock = (props: Props): JSX.Element => {
mutator.changeCardContentOrder(props.card.boardId, card.id, card.fields.contentOrder, contentOrder)
}}
/>}
<MenuSubMenu
<Menu.SubMenu
id='insertAbove'
name={intl.formatMessage({id: 'ContentBlock.insertAbove', defaultMessage: 'Insert above'})}
icon={<AddIcon/>}
@ -110,8 +109,8 @@ const ContentBlock = (props: Props): JSX.Element => {
cords={cords}
/>
))}
</MenuSubMenu>
<MenuText
</Menu.SubMenu>
<Menu.Text
icon={<DeleteIcon/>}
id='delete'
name={intl.formatMessage({id: 'ContentBlock.Delete', defaultMessage: 'Delete'})}

View file

@ -14,8 +14,6 @@ import Menu from '../widgets/menu'
import OptionsIcon from '../widgets/icons/options'
import {MenuText} from '../widgets/menu/menu'
import Dialog from './dialog'
describe('components/dialog', () => {
@ -50,7 +48,7 @@ describe('components/dialog', () => {
onClose={onCloseMethod}
>
<Menu position='left'>
<MenuText
<Menu.Text
id='test'
icon={<OptionsIcon/>}
name='Test'
@ -72,7 +70,7 @@ describe('components/dialog', () => {
<Dialog
onClose={jest.fn()}
toolsMenu={<Menu position='left'>
<MenuText
<Menu.Text
id='test'
icon={<OptionsIcon/>}
name='Test'
@ -96,7 +94,7 @@ describe('components/dialog', () => {
<Dialog
onClose={jest.fn()}
toolsMenu={<Menu position='left'>
<MenuText
<Menu.Text
id='test'
icon={<OptionsIcon/>}
name='Test'

View file

@ -21,7 +21,6 @@ import {Constants} from '../../constants'
import TelemetryClient, {TelemetryCategory, TelemetryActions} from '../../telemetry/telemetryClient'
import './globalHeaderSettingsMenu.scss'
import {MenuSubMenu, MenuText, MenuSwitch} from '../../widgets/menu/menu'
type Props = {
history: History<unknown>
@ -46,12 +45,12 @@ const GlobalHeaderSettingsMenu = (props: Props) => {
<SettingsIcon/>
</div>
<Menu position='left'>
<MenuSubMenu
<Menu.SubMenu
id='import'
name={intl.formatMessage({id: 'Sidebar.import', defaultMessage: 'Import'})}
position='left-bottom'
>
<MenuText
<Menu.Text
id='import_archive'
name={intl.formatMessage({id: 'Sidebar.import-archive', defaultMessage: 'Import archive'})}
onClick={async () => {
@ -61,7 +60,7 @@ const GlobalHeaderSettingsMenu = (props: Props) => {
/>
{
Constants.imports.map((i) => (
<MenuText
<Menu.Text
key={`${i.id}-import`}
id={`${i.id}-import`}
name={i.displayName}
@ -72,15 +71,15 @@ const GlobalHeaderSettingsMenu = (props: Props) => {
/>
))
}
</MenuSubMenu>
<MenuSubMenu
</Menu.SubMenu>
<Menu.SubMenu
id='lang'
name={intl.formatMessage({id: 'Sidebar.set-language', defaultMessage: 'Set language'})}
position='left-bottom'
>
{
Constants.languages.map((language) => (
<MenuText
<Menu.Text
key={language.code}
id={`${language.name}-lang`}
name={language.displayName}
@ -89,8 +88,8 @@ const GlobalHeaderSettingsMenu = (props: Props) => {
/>
))
}
</MenuSubMenu>
<MenuSwitch
</Menu.SubMenu>
<Menu.Switch
id='random-icons'
name={intl.formatMessage({id: 'Sidebar.random-icons', defaultMessage: 'Random icons'})}
isOn={randomIcons}
@ -98,7 +97,7 @@ const GlobalHeaderSettingsMenu = (props: Props) => {
suppressItemClicked={true}
/>
{me?.is_guest !== true &&
<MenuText
<Menu.Text
id='product-tour'
className='product-tour'
name={intl.formatMessage({id: 'Sidebar.product-tour', defaultMessage: 'Product tour'})}

View file

@ -10,7 +10,6 @@ import EmojiIcon from '../widgets/icons/emoji'
import Menu from '../widgets/menu'
import MenuWrapper from '../widgets/menuWrapper'
import './iconSelector.scss'
import {MenuText, MenuSubMenu} from '../widgets/menu/menu'
type Props = {
readonly?: boolean
@ -30,20 +29,20 @@ const IconSelector = React.memo((props: Props) => {
<MenuWrapper>
{props.iconElement}
<Menu>
<MenuText
<Menu.Text
id='random'
icon={<RandomIcon/>}
name={intl.formatMessage({id: 'ViewTitle.random-icon', defaultMessage: 'Random'})}
onClick={props.onAddRandomIcon}
/>
<MenuSubMenu
<Menu.SubMenu
id='pick'
icon={<EmojiIcon/>}
name={intl.formatMessage({id: 'ViewTitle.pick-icon', defaultMessage: 'Pick icon'})}
>
<EmojiPicker onSelect={props.onSelectEmoji}/>
</MenuSubMenu>
<MenuText
</Menu.SubMenu>
<Menu.Text
id='remove'
icon={<DeleteIcon/>}
name={intl.formatMessage({id: 'ViewTitle.remove-icon', defaultMessage: 'Remove icon'})}

View file

@ -23,8 +23,6 @@ import {useHasCurrentBoardPermissions} from '../../hooks/permissions'
import BoardPermissionGate from '../permissions/boardPermissionGate'
import {MenuText, MenuSeparator, MenuColor} from '../../widgets/menu/menu'
import {KanbanCalculation} from './calculation/calculation'
type Props = {
@ -166,7 +164,7 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
<MenuWrapper>
<IconButton icon={<OptionsIcon/>}/>
<Menu>
<MenuText
<Menu.Text
id='hide'
icon={<HideIcon/>}
name={intl.formatMessage({id: 'BoardComponent.hide', defaultMessage: 'Hide'})}
@ -174,15 +172,15 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
/>
{canEditOption &&
<>
<MenuText
<Menu.Text
id='delete'
icon={<DeleteIcon/>}
name={intl.formatMessage({id: 'BoardComponent.delete', defaultMessage: 'Delete'})}
onClick={() => mutator.deletePropertyOption(board.id, board.cardProperties, groupByProperty!, group.option)}
/>
<MenuSeparator/>
<Menu.Separator/>
{Object.entries(Constants.menuColors).map(([key, color]) => (
<MenuColor
<Menu.Color
key={key}
id={key}
name={color}

View file

@ -15,7 +15,6 @@ import {BoardGroup} from '../../blocks/board'
import {BoardView} from '../../blocks/boardView'
import Button from '../../widgets/buttons/button'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
activeView: BoardView
@ -60,7 +59,7 @@ export default function KanbanHiddenColumnItem(props: Props): JSX.Element {
{group.option.value}
</Label>
<Menu>
<MenuText
<Menu.Text
id='show'
icon={<ShowIcon/>}
name={intl.formatMessage({id: 'BoardComponent.show', defaultMessage: 'Show'})}

View file

@ -24,7 +24,6 @@ import CompassIcon from '../../widgets/icons/compassIcon'
import ConfirmationDialogBox from '../confirmationDialogBox'
import BoardPermissionGate from '../permissions/boardPermissionGate'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
teammateNameDisplay?: string
@ -130,7 +129,7 @@ const ChannelPermissionsRow = (props: Props): JSX.Element => {
/>
</button>
<Menu position='left'>
<MenuText
<Menu.Text
id='Unlink'
icon={<DeleteIcon/>}
name={intl.formatMessage({id: 'BoardMember.unlinkChannel', defaultMessage: 'Unlink'})}

View file

@ -21,7 +21,6 @@ import BoardPermissionGate from '../permissions/boardPermissionGate'
import ConfirmationDialogBox from '../confirmationDialogBox'
import mutator from '../../mutator'
import {MenuText} from '../../widgets/menu/menu'
async function updateBoardType(board: Board, newType: string, newMinimumRole: MemberRole) {
if (board.type === newType && board.minimumRole === newMinimumRole) {
@ -111,7 +110,7 @@ const TeamPermissionsRow = (): JSX.Element => {
</button>
<Menu position='left'>
{!board.isTemplate &&
<MenuText
<Menu.Text
id={MemberRole.Editor}
check={board.minimumRole === undefined || board.minimumRole === MemberRole.Editor}
icon={board.type === BoardTypeOpen && board.minimumRole === MemberRole.Editor ? <CheckIcon/> : <div className='empty-icon'/>}
@ -119,21 +118,21 @@ const TeamPermissionsRow = (): JSX.Element => {
onClick={() => setChangeRoleConfirmation(MemberRole.Editor)}
/>}
{!board.isTemplate &&
<MenuText
<Menu.Text
id={MemberRole.Commenter}
check={board.minimumRole === MemberRole.Commenter}
icon={board.type === BoardTypeOpen && board.minimumRole === MemberRole.Commenter ? <CheckIcon/> : <div className='empty-icon'/>}
name={intl.formatMessage({id: 'BoardMember.schemeCommenter', defaultMessage: 'Commenter'})}
onClick={() => setChangeRoleConfirmation(MemberRole.Commenter)}
/>}
<MenuText
<Menu.Text
id={MemberRole.Viewer}
check={board.minimumRole === MemberRole.Viewer}
icon={board.type === BoardTypeOpen && board.minimumRole === MemberRole.Viewer ? <CheckIcon/> : <div className='empty-icon'/>}
name={intl.formatMessage({id: 'BoardMember.schemeViewer', defaultMessage: 'Viewer'})}
onClick={() => updateBoardType(board, BoardTypeOpen, MemberRole.Viewer)}
/>
<MenuText
<Menu.Text
id={MemberRole.None}
check={true}
icon={board.type === BoardTypePrivate ? <CheckIcon/> : <div className='empty-icon'/>}

View file

@ -19,7 +19,6 @@ import {useAppSelector} from '../../store/hooks'
import {getCurrentBoard} from '../../store/boards'
import BoardPermissionGate from '../permissions/boardPermissionGate'
import {MenuText, MenuSeparator} from '../../widgets/menu/menu'
type Props = {
user: IUser
@ -83,7 +82,7 @@ const UserPermissionsRow = (props: Props): JSX.Element => {
parentRef={menuWrapperRef}
>
{(board.minimumRole === MemberRole.Viewer || board.minimumRole === MemberRole.None) &&
<MenuText
<Menu.Text
id={MemberRole.Viewer}
check={true}
icon={currentRole === MemberRole.Viewer ? <CheckIcon/> : <div className='empty-icon'/>}
@ -91,14 +90,14 @@ const UserPermissionsRow = (props: Props): JSX.Element => {
onClick={() => props.onUpdateBoardMember(member, MemberRole.Viewer)}
/>}
{!board.isTemplate && (board.minimumRole === MemberRole.None || board.minimumRole === MemberRole.Commenter || board.minimumRole === MemberRole.Viewer) &&
<MenuText
<Menu.Text
id={MemberRole.Commenter}
check={true}
icon={currentRole === MemberRole.Commenter ? <CheckIcon/> : <div className='empty-icon'/>}
name={intl.formatMessage({id: 'BoardMember.schemeCommenter', defaultMessage: 'Commenter'})}
onClick={() => props.onUpdateBoardMember(member, MemberRole.Commenter)}
/>}
<MenuText
<Menu.Text
id={MemberRole.Editor}
check={true}
icon={currentRole === MemberRole.Editor ? <CheckIcon/> : <div className='empty-icon'/>}
@ -106,15 +105,15 @@ const UserPermissionsRow = (props: Props): JSX.Element => {
onClick={() => props.onUpdateBoardMember(member, MemberRole.Editor)}
/>
{user.is_guest !== true &&
<MenuText
<Menu.Text
id={MemberRole.Admin}
check={true}
icon={currentRole === MemberRole.Admin ? <CheckIcon/> : <div className='empty-icon'/>}
name={intl.formatMessage({id: 'BoardMember.schemeAdmin', defaultMessage: 'Admin'})}
onClick={() => props.onUpdateBoardMember(member, MemberRole.Admin)}
/>}
<MenuSeparator/>
<MenuText
<Menu.Separator/>
<Menu.Text
id='Remove'
name={intl.formatMessage({id: 'ShareBoard.userPermissionsRemoveMemberText', defaultMessage: 'Remove member'})}
onClick={() => props.onDeleteBoardMember(member)}

View file

@ -40,7 +40,6 @@ import octoClient from '../../octoClient'
import {getCurrentBoardId} from '../../store/boards'
import {UserSettings} from '../../userSettings'
import {Archiver} from '../../archiver'
import {MenuText, MenuSubMenu} from '../../widgets/menu/menu'
const iconForViewType = (viewType: IViewType): JSX.Element => {
switch (viewType) {
@ -83,7 +82,7 @@ const SidebarBoardItem = (props: Props) => {
const generateMoveToCategoryOptions = (boardID: string) => {
return props.allCategories.map((category) => (
<MenuText
<Menu.Text
key={category.id}
id={category.id}
name={category.name}
@ -238,7 +237,7 @@ const SidebarBoardItem = (props: Props) => {
position='auto'
parentRef={boardItemRef}
>
<MenuSubMenu
<Menu.SubMenu
key={`moveBlock-${board.id}`}
id='moveBlock'
className='boardMoveToCategorySubmenu'
@ -247,28 +246,28 @@ const SidebarBoardItem = (props: Props) => {
position='auto'
>
{generateMoveToCategoryOptions(board.id)}
</MenuSubMenu>
</Menu.SubMenu>
{!me?.is_guest &&
<MenuText
<Menu.Text
id='duplicateBoard'
name={intl.formatMessage({id: 'Sidebar.duplicate-board', defaultMessage: 'Duplicate board'})}
icon={<DuplicateIcon/>}
onClick={() => handleDuplicateBoard(board.isTemplate)}
/>}
{!me?.is_guest &&
<MenuText
<Menu.Text
id='templateFromBoard'
name={intl.formatMessage({id: 'Sidebar.template-from-board', defaultMessage: 'New template from board'})}
icon={<AddIcon/>}
onClick={() => handleDuplicateBoard(true)}
/>}
<MenuText
<Menu.Text
id='exportBoardArchive'
name={intl.formatMessage({id: 'ViewHeader.export-board-archive', defaultMessage: 'Export board archive'})}
icon={<CompassIcon icon='export-variant'/>}
onClick={() => Archiver.exportBoardArchive(board)}
/>
<MenuText
<Menu.Text
id='hideBoard'
name={intl.formatMessage({id: 'HideBoard.MenuOption', defaultMessage: 'Hide board'})}
icon={<CloseIcon/>}
@ -278,7 +277,7 @@ const SidebarBoardItem = (props: Props) => {
boardId={board.id}
permissions={[Permission.DeleteBoard]}
>
<MenuText
<Menu.Text
key={`deleteBlock-${board.id}`}
id='deleteBlock'
className='text-danger'

View file

@ -44,8 +44,6 @@ import ConfirmationDialogBox, {ConfirmationDialogBoxProps} from '../confirmation
import SidebarCategoriesTourStep from '../../components/onboardingTour/sidebarCategories/sidebarCategories'
import ManageCategoriesTourStep from '../../components/onboardingTour/manageCategories/manageCategories'
import {MenuText, MenuSeparator} from '../../widgets/menu/menu'
import DeleteBoardDialog from './deleteBoardDialog'
import SidebarBoardItem from './sidebarBoardItem'
@ -320,23 +318,23 @@ const SidebarCategory = (props: Props) => {
{
props.categoryBoards.type === 'custom' &&
<React.Fragment>
<MenuText
<Menu.Text
id='updateCategory'
name={intl.formatMessage({id: 'SidebarCategories.CategoryMenu.Update', defaultMessage: 'Rename Category'})}
icon={<CompassIcon icon='pencil-outline'/>}
onClick={handleUpdateCategory}
/>
<MenuText
<Menu.Text
id='deleteCategory'
className='text-danger'
name={intl.formatMessage({id: 'SidebarCategories.CategoryMenu.Delete', defaultMessage: 'Delete Category'})}
icon={<DeleteIcon/>}
onClick={() => setShowDeleteCategoryDialog(true)}
/>
<MenuSeparator/>
<Menu.Separator/>
</React.Fragment>
}
<MenuText
<Menu.Text
id='createNewCategory'
name={intl.formatMessage({id: 'SidebarCategories.CategoryMenu.CreateNew', defaultMessage: 'Create New Category'})}
icon={<CreateNewFolder/>}

View file

@ -26,7 +26,6 @@ import CheckIcon from '../../widgets/icons/check'
import {Constants} from '../../constants'
import TelemetryClient, {TelemetryCategory, TelemetryActions} from '../../telemetry/telemetryClient'
import {MenuSubMenu, MenuText, MenuSwitch} from '../../widgets/menu/menu'
type Props = {
activeTheme: string
@ -86,12 +85,12 @@ const SidebarSettingsMenu = (props: Props) => {
/>
</div>
<Menu position='top'>
<MenuSubMenu
<Menu.SubMenu
id='import'
name={intl.formatMessage({id: 'Sidebar.import', defaultMessage: 'Import'})}
position='top'
>
<MenuText
<Menu.Text
id='import_archive'
name={intl.formatMessage({id: 'Sidebar.import-archive', defaultMessage: 'Import archive'})}
onClick={async () => {
@ -101,7 +100,7 @@ const SidebarSettingsMenu = (props: Props) => {
/>
{
Constants.imports.map((i) => (
<MenuText
<Menu.Text
key={`${i.id}-import`}
id={`${i.id}-import`}
name={i.displayName}
@ -112,8 +111,8 @@ const SidebarSettingsMenu = (props: Props) => {
/>
))
}
</MenuSubMenu>
<MenuText
</Menu.SubMenu>
<Menu.Text
id='export'
name={intl.formatMessage({id: 'Sidebar.export-archive', defaultMessage: 'Export archive'})}
onClick={async () => {
@ -123,14 +122,14 @@ const SidebarSettingsMenu = (props: Props) => {
}
}}
/>
<MenuSubMenu
<Menu.SubMenu
id='lang'
name={intl.formatMessage({id: 'Sidebar.set-language', defaultMessage: 'Set language'})}
position='top'
>
{
Constants.languages.map((language) => (
<MenuText
<Menu.Text
key={language.code}
id={`${language.name}-lang`}
name={language.displayName}
@ -139,8 +138,8 @@ const SidebarSettingsMenu = (props: Props) => {
/>
))
}
</MenuSubMenu>
<MenuSubMenu
</Menu.SubMenu>
<Menu.SubMenu
id='theme'
name={intl.formatMessage({id: 'Sidebar.set-theme', defaultMessage: 'Set theme'})}
position='top'
@ -148,7 +147,7 @@ const SidebarSettingsMenu = (props: Props) => {
{
themes.map((theme) =>
(
<MenuText
<Menu.Text
key={theme.id}
id={theme.id}
name={intl.formatMessage({id: `Sidebar.${theme.id}`, defaultMessage: theme.displayName})}
@ -158,8 +157,8 @@ const SidebarSettingsMenu = (props: Props) => {
),
)
}
</MenuSubMenu>
<MenuSwitch
</Menu.SubMenu>
<Menu.Switch
id='random-icons'
name={intl.formatMessage({id: 'Sidebar.random-icons', defaultMessage: 'Random icons'})}
isOn={randomIcons}

View file

@ -19,8 +19,6 @@ import ModalWrapper from '../modalWrapper'
import {IAppWindow} from '../../types'
import {MenuLabel, MenuText, MenuSeparator} from '../../widgets/menu/menu'
import RegistrationLink from './registrationLink'
import './sidebarUserMenu.scss'
@ -57,8 +55,8 @@ const SidebarUserMenu = () => {
</div>
<Menu>
{user && user.username !== 'single-user' && <>
<MenuLabel><b>{user.username}</b></MenuLabel>
<MenuText
<Menu.Label><b>{user.username}</b></Menu.Label>
<Menu.Text
id='logout'
name={intl.formatMessage({id: 'Sidebar.logout', defaultMessage: 'Log out'})}
onClick={async () => {
@ -67,14 +65,14 @@ const SidebarUserMenu = () => {
history.push('/login')
}}
/>
<MenuText
<Menu.Text
id='changePassword'
name={intl.formatMessage({id: 'Sidebar.changePassword', defaultMessage: 'Change password'})}
onClick={async () => {
history.push('/change_password')
}}
/>
<MenuText
<Menu.Text
id='invite'
name={intl.formatMessage({id: 'Sidebar.invite-users', defaultMessage: 'Invite users'})}
onClick={async () => {
@ -82,10 +80,10 @@ const SidebarUserMenu = () => {
}}
/>
<MenuSeparator/>
<Menu.Separator/>
</>}
<MenuText
<Menu.Text
id='about'
name={intl.formatMessage({id: 'Sidebar.about', defaultMessage: 'About Focalboard'})}
onClick={async () => {

View file

@ -82,175 +82,4 @@ describe('components/standardProperties/statusProperty/EditStatusPropertyDialog'
const {container} = render(component)
expect(container).toMatchSnapshot()
})
test('no value in any column', () => {
const noValueConfig: StatusCategory[] = [
{
id: 'category_id_1',
title: 'Not Started',
options: [],
emptyState: {
icon: (<BlackCheckboxOutline/>),
color: '--sys-dnd-indicator-rgb',
text: {
id: 'statusProperty.configDialog.todo.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses “Not Started”',
},
},
},
{
id: 'category_id_2',
title: 'In progress',
options: [],
emptyState: {
icon: (<ClockOutline/>),
color: '--away-indicator-rgb',
text: {
id: 'statusProperty.configDialog.inProgress.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses “in progress”',
},
},
},
{
id: 'category_id_3',
title: 'Completed',
options: [],
emptyState: {
icon: (<CheckIcon/>),
color: '--online-indicator-rgb',
text: {
id: 'statusProperty.configDialog.complete.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses ”Done”',
},
},
},
]
const component = wrapRBDNDContext(
wrapIntl(
<EditStatusPropertyDialog
valueCategories={noValueConfig}
onClose={() => {}}
onUpdate={() => {}}
/>,
))
const {container} = render(component)
expect(container).toMatchSnapshot()
})
test('5 columns', () => {
const initialValueCategoryValue: StatusCategory[] = [
{
id: 'category_id_1',
title: 'Column 1',
options: [
{id: 'status_id_1', value: 'Pending Design', color: 'propColorPurple'},
{id: 'status_id_2', value: 'TODO', color: 'propColorYellow'},
{id: 'status_id_3', value: 'Pending Specs', color: 'propColorGray'},
],
emptyState: {
icon: (<BlackCheckboxOutline/>),
color: '--sys-dnd-indicator-rgb',
text: {
id: 'statusProperty.configDialog.todo.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses “Not Started”',
},
},
},
{
id: 'category_id_2',
title: 'Column 2',
options: [
{id: 'status_id_4', value: 'In Progress', color: 'propColorBrown'},
{id: 'status_id_5', value: 'In Review', color: 'propColorRed'},
{id: 'status_id_6', value: 'In QA', color: 'propColorPink'},
{id: 'status_id_7', value: 'Awaiting Cherrypick', color: 'propColorOrange'},
],
emptyState: {
icon: (<ClockOutline/>),
color: '--away-indicator-rgb',
text: {
id: 'statusProperty.configDialog.inProgress.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses “in progress”',
},
},
},
{
id: 'category_id_3',
title: 'Column 3',
options: [
{id: 'status_id_20', value: 'Done', color: 'propColorPink'},
{id: 'status_id_21', value: 'Branch Cut', color: 'propColorGreen'},
{id: 'status_id_22', value: 'Released', color: 'propColorDefault'},
],
emptyState: {
icon: (<CheckIcon/>),
color: '--online-indicator-rgb',
text: {
id: 'statusProperty.configDialog.complete.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses ”Done”',
},
},
},
{
id: 'category_id_2',
title: 'Column 4',
options: [
{id: 'status_id_54', value: 'Michael Scott', color: 'propColorOrange'},
],
emptyState: {
icon: (<ClockOutline/>),
color: '--away-indicator-rgb',
text: {
id: 'statusProperty.configDialog.inProgress.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses “in progress”',
},
},
},
{
id: 'category_id_3',
title: 'Column 5',
options: [
{id: 'status_id_22', value: 'Jim Halpert', color: 'propColorDefault'},
],
emptyState: {
icon: (<CheckIcon/>),
color: '--online-indicator-rgb',
text: {
id: 'statusProperty.configDialog.complete.emptyText',
defaultMessage: 'Drag statuses here to consider tasks with these statuses ”Done”',
},
},
},
]
const component = wrapRBDNDContext(
wrapIntl(
<EditStatusPropertyDialog
valueCategories={initialValueCategoryValue}
onClose={() => {}}
onUpdate={() => {}}
/>,
))
const {container} = render(component)
expect(container).toMatchSnapshot()
})
test('0 columns', () => {
const initialValueCategoryValue: StatusCategory[] = []
const component = wrapRBDNDContext(
wrapIntl(
<EditStatusPropertyDialog
valueCategories={initialValueCategoryValue}
onClose={() => {}}
onUpdate={() => {}}
/>,
))
const {container} = render(component)
expect(container).toMatchSnapshot()
})
})

View file

@ -10,7 +10,7 @@ import {Constants} from '../../../constants'
import DragHandle from '../../../widgets/icons/dragHandle'
import EditIcon from '../../../widgets/icons/edit'
import Menu, {MenuColor, MenuText} from '../../../widgets/menu/menu'
import Menu from '../../../widgets/menu/menu'
import MenuWrapper from '../../../widgets/menuWrapper'
import {IPropertyOption} from '../../../blocks/board'
@ -98,7 +98,7 @@ const ValueRow = (props: Props) => {
{
Object.entries(Constants.menuColors).map(
([key, color]: [string, string]) => (
<MenuColor
<Menu.Color
key={key}
id={key}
name={color}
@ -125,13 +125,13 @@ const ValueRow = (props: Props) => {
menuMargin={30}
fixed={true}
>
<MenuText
<Menu.Text
id='editText'
name={'Edit'}
icon={<EditIcon/>}
onClick={handleEditButtonClick}
/>
<MenuText
<Menu.Text
id='deleteOption'
name={'Delete'}
icon={<DeleteIcon/>}

View file

@ -21,8 +21,6 @@ import MenuWrapper from '../../widgets/menuWrapper'
import Editable from '../../widgets/editable'
import Label from '../../widgets/label'
import {MenuText, MenuSeparator, MenuColor} from '../../widgets/menu/menu'
import {useColumnResize} from './tableColumnResizeContext'
type Props = {
@ -124,7 +122,7 @@ const TableGroupHeaderRow = (props: Props): JSX.Element => {
<MenuWrapper>
<IconButton icon={<OptionsIcon/>}/>
<Menu>
<MenuText
<Menu.Text
id='hide'
icon={<HideIcon/>}
name={intl.formatMessage({id: 'BoardComponent.hide', defaultMessage: 'Hide'})}
@ -132,15 +130,15 @@ const TableGroupHeaderRow = (props: Props): JSX.Element => {
/>
{canEditOption &&
<>
<MenuText
<Menu.Text
id='delete'
icon={<DeleteIcon/>}
name={intl.formatMessage({id: 'BoardComponent.delete', defaultMessage: 'Delete'})}
onClick={() => mutator.deletePropertyOption(board.id, board.cardProperties, groupByProperty!, group.option)}
/>
<MenuSeparator/>
<Menu.Separator/>
{Object.entries(Constants.menuColors).map(([key, color]) => (
<MenuColor
<Menu.Color
key={key}
id={key}
name={color}

View file

@ -10,7 +10,6 @@ import {BoardView} from '../../blocks/boardView'
import {Card} from '../../blocks/card'
import mutator from '../../mutator'
import Menu from '../../widgets/menu'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
templateId: string
@ -25,17 +24,17 @@ const TableHeaderMenu: FC<Props> = (props: Props): JSX.Element => {
const intl = useIntl()
return (
<Menu>
<MenuText
<Menu.Text
id='sortAscending'
name={intl.formatMessage({id: 'TableHeaderMenu.sort-ascending', defaultMessage: 'Sort ascending'})}
onClick={() => mutator.changeViewSortOptions(board.id, activeView.id, activeView.fields.sortOptions, [{propertyId: templateId, reversed: false}])}
/>
<MenuText
<Menu.Text
id='sortDescending'
name={intl.formatMessage({id: 'TableHeaderMenu.sort-descending', defaultMessage: 'Sort descending'})}
onClick={() => mutator.changeViewSortOptions(board.id, activeView.id, activeView.fields.sortOptions, [{propertyId: templateId, reversed: true}])}
/>
<MenuText
<Menu.Text
id='insertLeft'
name={intl.formatMessage({id: 'TableHeaderMenu.insert-left', defaultMessage: 'Insert left'})}
onClick={() => {
@ -48,7 +47,7 @@ const TableHeaderMenu: FC<Props> = (props: Props): JSX.Element => {
}
}}
/>
<MenuText
<Menu.Text
id='insertRight'
name={intl.formatMessage({id: 'TableHeaderMenu.insert-right', defaultMessage: 'Insert right'})}
onClick={() => {
@ -63,17 +62,17 @@ const TableHeaderMenu: FC<Props> = (props: Props): JSX.Element => {
/>
{props.templateId !== Constants.titleColumnId &&
<>
<MenuText
<Menu.Text
id='hide'
name={intl.formatMessage({id: 'TableHeaderMenu.hide', defaultMessage: 'Hide'})}
onClick={() => mutator.changeViewVisibleProperties(board.id, activeView.id, activeView.fields.visiblePropertyIds, activeView.fields.visiblePropertyIds.filter((o: string) => o !== templateId))}
/>
<MenuText
<Menu.Text
id='duplicate'
name={intl.formatMessage({id: 'TableHeaderMenu.duplicate', defaultMessage: 'Duplicate'})}
onClick={() => mutator.duplicatePropertyTemplate(board, activeView, templateId)}
/>
<MenuText
<Menu.Text
id='delete'
name={intl.formatMessage({id: 'TableHeaderMenu.delete', defaultMessage: 'Delete'})}
onClick={() => mutator.deleteProperty(board, views, cards, templateId)}

View file

@ -16,7 +16,6 @@ import mutator from '../../mutator'
import {useAppSelector} from '../../store/hooks'
import {getCurrentView} from '../../store/views'
import {getCurrentBoardId} from '../../store/boards'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
addCard: () => void
@ -28,7 +27,7 @@ const EmptyCardButton = (props: Props) => {
const intl = useIntl()
return (
<MenuText
<Menu.Text
icon={<CardIcon/>}
id='empty-template'
name={intl.formatMessage({id: 'ViewHeader.empty-card', defaultMessage: 'Empty card'})}
@ -40,7 +39,7 @@ const EmptyCardButton = (props: Props) => {
<MenuWrapper stopPropagationOnToggle={true}>
<IconButton icon={<OptionsIcon/>}/>
<Menu position='left'>
<MenuText
<Menu.Text
icon={<CheckIcon/>}
id='default'
name={intl.formatMessage({

View file

@ -14,7 +14,6 @@ import Button from '../../widgets/buttons/button'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import propsRegistry from '../../properties'
import {MenuText} from '../../widgets/menu/menu'
import FilterValue from './filterValue'
@ -47,7 +46,7 @@ const FilterEntry = (props: Props): JSX.Element => {
<MenuWrapper>
<Button>{propertyName}</Button>
<Menu>
<MenuText
<Menu.Text
key={'title'}
id={'title'}
name={'Title'}
@ -65,7 +64,7 @@ const FilterEntry = (props: Props): JSX.Element => {
}}
/>
{board.cardProperties.filter((o: IPropertyTemplate) => propsRegistry.get(o.type).canFilter).map((o: IPropertyTemplate) => (
<MenuText
<Menu.Text
key={o.id}
id={o.id}
name={o.name}
@ -90,22 +89,22 @@ const FilterEntry = (props: Props): JSX.Element => {
<Menu>
{propertyType.filterValueType === 'options' &&
<>
<MenuText
<Menu.Text
id='includes'
name={intl.formatMessage({id: 'Filter.includes', defaultMessage: 'includes'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='notIncludes'
name={intl.formatMessage({id: 'Filter.not-includes', defaultMessage: 'doesn\'t include'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isEmpty'
name={intl.formatMessage({id: 'Filter.is-empty', defaultMessage: 'is empty'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isNotEmpty'
name={intl.formatMessage({id: 'Filter.is-not-empty', defaultMessage: 'is not empty'})}
onClick={(id) => props.conditionClicked(id, filter)}
@ -113,12 +112,12 @@ const FilterEntry = (props: Props): JSX.Element => {
</>}
{propertyType.filterValueType === 'person' &&
<>
<MenuText
<Menu.Text
id='includes'
name={intl.formatMessage({id: 'Filter.includes', defaultMessage: 'includes'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='notIncludes'
name={intl.formatMessage({id: 'Filter.not-includes', defaultMessage: 'doesn\'t include'})}
onClick={(id) => props.conditionClicked(id, filter)}
@ -126,12 +125,12 @@ const FilterEntry = (props: Props): JSX.Element => {
</>}
{(propertyType.type === 'person' || propertyType.type === 'multiPerson') &&
<>
<MenuText
<Menu.Text
id='isEmpty'
name={intl.formatMessage({id: 'Filter.is-empty', defaultMessage: 'is empty'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isNotEmpty'
name={intl.formatMessage({id: 'Filter.is-not-empty', defaultMessage: 'is not empty'})}
onClick={(id) => props.conditionClicked(id, filter)}
@ -139,12 +138,12 @@ const FilterEntry = (props: Props): JSX.Element => {
</>}
{propertyType.filterValueType === 'boolean' &&
<>
<MenuText
<Menu.Text
id='isSet'
name={intl.formatMessage({id: 'Filter.is-set', defaultMessage: 'is set'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isNotSet'
name={intl.formatMessage({id: 'Filter.is-not-set', defaultMessage: 'is not set'})}
onClick={(id) => props.conditionClicked(id, filter)}
@ -152,37 +151,37 @@ const FilterEntry = (props: Props): JSX.Element => {
</>}
{propertyType.filterValueType === 'text' &&
<>
<MenuText
<Menu.Text
id='is'
name={intl.formatMessage({id: 'Filter.is', defaultMessage: 'is'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='contains'
name={intl.formatMessage({id: 'Filter.contains', defaultMessage: 'contains'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='notContains'
name={intl.formatMessage({id: 'Filter.not-contains', defaultMessage: 'doesn\'t contain'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='startsWith'
name={intl.formatMessage({id: 'Filter.starts-with', defaultMessage: 'starts with'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='notStartsWith'
name={intl.formatMessage({id: 'Filter.not-starts-with', defaultMessage: 'doesn\'t start with'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='endsWith'
name={intl.formatMessage({id: 'Filter.ends-with', defaultMessage: 'ends with'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='notEndsWith'
name={intl.formatMessage({id: 'Filter.not-ends-with', defaultMessage: 'doesn\'t end with'})}
onClick={(id) => props.conditionClicked(id, filter)}
@ -190,17 +189,17 @@ const FilterEntry = (props: Props): JSX.Element => {
</>}
{propertyType.filterValueType === 'date' &&
<>
<MenuText
<Menu.Text
id='is'
name={intl.formatMessage({id: 'Filter.is', defaultMessage: 'is'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isBefore'
name={intl.formatMessage({id: 'Filter.isbefore', defaultMessage: 'is before'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isAfter'
name={intl.formatMessage({id: 'Filter.isafter', defaultMessage: 'is after'})}
onClick={(id) => props.conditionClicked(id, filter)}
@ -208,12 +207,12 @@ const FilterEntry = (props: Props): JSX.Element => {
</>}
{propertyType.type === 'date' &&
<>
<MenuText
<Menu.Text
id='isSet'
name={intl.formatMessage({id: 'Filter.is-set', defaultMessage: 'is set'})}
onClick={(id) => props.conditionClicked(id, filter)}
/>
<MenuText
<Menu.Text
id='isNotSet'
name={intl.formatMessage({id: 'Filter.is-not-set', defaultMessage: 'is not set'})}
onClick={(id) => props.conditionClicked(id, filter)}

View file

@ -16,8 +16,6 @@ import Menu from '../../widgets/menu'
import Editable from '../../widgets/editable'
import MenuWrapper from '../../widgets/menuWrapper'
import {MenuSwitch} from '../../widgets/menu/menu'
import DateFilter from './dateFilter'
import './filterValue.scss'
@ -105,7 +103,7 @@ const filterValue = (props: Props): JSX.Element|null => {
<Menu>
{template?.options.map((o) => (
<MenuSwitch
<Menu.Switch
key={o.id}
id={o.id}
name={o.value}

View file

@ -12,8 +12,6 @@ import {useAppSelector} from '../../store/hooks'
import {getCurrentBoardTemplates} from '../../store/cards'
import {getCurrentView} from '../../store/views'
import {MenuLabel, MenuSeparator, MenuText} from '../../widgets/menu/menu'
import NewCardButtonTemplateItem from './newCardButtonTemplateItem'
import EmptyCardButton from './emptyCardButton'
@ -48,16 +46,16 @@ const NewCardButton = (props: Props): JSX.Element => {
>
<Menu position='left'>
{cardTemplates.length > 0 && <>
<MenuLabel>
<Menu.Label>
<b>
<FormattedMessage
id='ViewHeader.select-a-template'
defaultMessage='Select a template'
/>
</b>
</MenuLabel>
</Menu.Label>
<MenuSeparator/>
<Menu.Separator/>
</>}
{cardTemplates.map((cardTemplate) => {
@ -78,7 +76,7 @@ const NewCardButton = (props: Props): JSX.Element => {
addCard={props.addCard}
/>
<MenuText
<Menu.Text
icon={<AddIcon/>}
id='add-template'
name={intl.formatMessage({id: 'ViewHeader.add-template', defaultMessage: 'New template'})}

View file

@ -16,7 +16,6 @@ import CheckIcon from '../../widgets/icons/check'
import {useAppSelector} from '../../store/hooks'
import {getCurrentView} from '../../store/views'
import {getCurrentBoardId} from '../../store/boards'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
cardTemplate: Card
@ -33,7 +32,7 @@ const NewCardButtonTemplateItem = (props: Props) => {
const boardId = useAppSelector(getCurrentBoardId)
return (
<MenuText
<Menu.Text
key={cardTemplate.id}
id={cardTemplate.id}
name={displayName}
@ -46,7 +45,7 @@ const NewCardButtonTemplateItem = (props: Props) => {
<MenuWrapper stopPropagationOnToggle={true}>
<IconButton icon={<OptionsIcon/>}/>
<Menu position='left'>
<MenuText
<Menu.Text
icon={<CheckIcon/>}
id='default'
name={intl.formatMessage({id: 'ViewHeader.set-default-template', defaultMessage: 'Set as default'})}
@ -54,7 +53,7 @@ const NewCardButtonTemplateItem = (props: Props) => {
await mutator.setDefaultTemplate(boardId, currentView.id, currentView.fields.defaultTemplateId, cardTemplate.id)
}}
/>
<MenuText
<Menu.Text
icon={<EditIcon/>}
id='edit'
name={intl.formatMessage({id: 'ViewHeader.edit-template', defaultMessage: 'Edit'})}
@ -62,7 +61,7 @@ const NewCardButtonTemplateItem = (props: Props) => {
props.editCardTemplate(cardTemplate.id)
}}
/>
<MenuText
<Menu.Text
icon={<DeleteIcon/>}
id='delete'
name={intl.formatMessage({id: 'ViewHeader.delete-template', defaultMessage: 'Delete'})}

View file

@ -16,7 +16,6 @@ import {Utils} from '../../utils'
import ModalWrapper from '../modalWrapper'
import {sendFlashMessage} from '../flashMessages'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
board: Board
@ -104,35 +103,35 @@ const ViewHeaderActionsMenu = (props: Props) => {
<MenuWrapper label={intl.formatMessage({id: 'ViewHeader.view-header-menu', defaultMessage: 'View header menu'})}>
<IconButton icon={<OptionsIcon/>}/>
<Menu position='left'>
<MenuText
<Menu.Text
id='exportCsv'
name={intl.formatMessage({id: 'ViewHeader.export-csv', defaultMessage: 'Export to CSV'})}
onClick={() => onExportCsvTrigger(board, activeView, cards, intl)}
/>
<MenuText
<Menu.Text
id='exportBoardArchive'
name={intl.formatMessage({id: 'ViewHeader.export-board-archive', defaultMessage: 'Export board archive'})}
onClick={() => Archiver.exportBoardArchive(board)}
/>
{/*
<MenuSeparator/>
<Menu.Separator/>
<MenuText
<Menu.Text
id='testAdd100Cards'
name={intl.formatMessage({id: 'ViewHeader.test-add-100-cards', defaultMessage: 'TEST: Add 100 cards'})}
onClick={() => testAddCards(board, activeView, cards.length, 100)}
/>
<MenuText
<Menu.Text
id='testAdd1000Cards'
name={intl.formatMessage({id: 'ViewHeader.test-add-1000-cards', defaultMessage: 'TEST: Add 1,000 cards'})}
onClick={() => testAddCards(board, activeView, cards.length, 1000)}
/>
<MenuText
<Menu.Text
id='testDistributeCards'
name={intl.formatMessage({id: 'ViewHeader.test-distribute-cards', defaultMessage: 'TEST: Distribute cards'})}
onClick={() => testDistributeCards()}
/>
<MenuText
<Menu.Text
id='testRandomizeIcons'
name={intl.formatMessage({id: 'ViewHeader.test-randomize-icons', defaultMessage: 'TEST: Randomize icons'})}
onClick={() => testRandomizeIcons()}

View file

@ -15,7 +15,6 @@ import MenuWrapper from '../../widgets/menuWrapper'
import CheckIcon from '../../widgets/icons/check'
import propsRegistry from '../../properties'
import {MenuText} from '../../widgets/menu/menu'
type Props = {
properties: readonly IPropertyTemplate[]
@ -53,7 +52,7 @@ const ViewHeaderDisplayByMenu = (props: Props) => {
</Button>
<Menu>
{getDateProperties().length > 0 && getDateProperties().map((date: IPropertyTemplate) => (
<MenuText
<Menu.Text
key={date.id}
id={date.id}
name={date.name}
@ -67,7 +66,7 @@ const ViewHeaderDisplayByMenu = (props: Props) => {
/>
))}
{getDateProperties().length === 0 &&
<MenuText
<Menu.Text
key={'createdDate'}
id={'createdDate'}
name={createdDateName}

View file

@ -17,7 +17,6 @@ import {useAppSelector} from '../../store/hooks'
import {getCurrentViewCardsSortedFilteredAndGrouped} from '../../store/cards'
import {getVisibleAndHiddenGroups} from '../../boardUtils'
import propsRegistry from '../../properties'
import {MenuText, MenuSeparator} from '../../widgets/menu/menu'
type Props = {
properties: readonly IPropertyTemplate[]
@ -70,7 +69,7 @@ const ViewHeaderGroupByMenu = (props: Props) => {
{activeView.fields.viewType === 'table' && activeView.fields.groupById &&
<>
{emptyVisibleGroupsCount > 0 &&
<MenuText
<Menu.Text
key={'hideEmptyGroups'}
id={'hideEmptyGroups'}
name={intl.formatMessage({id: 'GroupBy.hideEmptyGroups', defaultMessage: 'Hide {count} empty groups'}, {count: emptyVisibleGroupsCount})}
@ -78,14 +77,14 @@ const ViewHeaderGroupByMenu = (props: Props) => {
onClick={() => handleToggleGroups(false)}
/>}
{hiddenGroupsCount > 0 &&
<MenuText
<Menu.Text
key={'showHiddenGroups'}
id={'showHiddenGroups'}
name={intl.formatMessage({id: 'GroupBy.showHiddenGroups', defaultMessage: 'Show {count} hidden groups'}, {count: hiddenGroupsCount})}
rightIcon={<ShowIcon/>}
onClick={() => handleToggleGroups(true)}
/>}
<MenuText
<Menu.Text
key={'ungroup'}
id={''}
name={intl.formatMessage({id: 'GroupBy.ungroup', defaultMessage: 'Ungroup'})}
@ -97,10 +96,10 @@ const ViewHeaderGroupByMenu = (props: Props) => {
mutator.changeViewGroupById(activeView.boardId, activeView.id, activeView.fields.groupById, id)
}}
/>
<MenuSeparator/>
<Menu.Separator/>
</>}
{properties?.filter((o: IPropertyTemplate) => propsRegistry.get(o.type).canGroup).map((option: IPropertyTemplate) => (
<MenuText
<Menu.Text
key={option.id}
id={option.id}
name={option.name}

View file

@ -10,7 +10,6 @@ import mutator from '../../mutator'
import Button from '../../widgets/buttons/button'
import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import {MenuSwitch} from '../../widgets/menu/menu'
type Props = {
properties: readonly IPropertyTemplate[]
@ -42,7 +41,7 @@ const ViewHeaderPropertiesMenu = (props: Props) => {
</Button>
<Menu>
{activeView.fields.viewType === 'gallery' &&
<MenuSwitch
<Menu.Switch
key={Constants.titleColumnId}
id={Constants.titleColumnId}
name={intl.formatMessage({id: 'default-properties.title', defaultMessage: 'Title'})}
@ -51,7 +50,7 @@ const ViewHeaderPropertiesMenu = (props: Props) => {
onClick={toggleVisibility}
/>}
{properties?.map((option: IPropertyTemplate) => (
<MenuSwitch
<Menu.Switch
key={option.id}
id={option.id}
name={option.name}
@ -61,7 +60,7 @@ const ViewHeaderPropertiesMenu = (props: Props) => {
/>
))}
{canShowBadges &&
<MenuSwitch
<Menu.Switch
key={Constants.badgesColumnId}
id={Constants.badgesColumnId}
name={intl.formatMessage({id: 'default-properties.badges', defaultMessage: 'Comments and description'})}

View file

@ -13,7 +13,6 @@ import Menu from '../../widgets/menu'
import MenuWrapper from '../../widgets/menuWrapper'
import SortDownIcon from '../../widgets/icons/sortDown'
import SortUpIcon from '../../widgets/icons/sortUp'
import {MenuText, MenuSeparator} from '../../widgets/menu/menu'
type Props = {
properties: readonly IPropertyTemplate[]
@ -65,19 +64,19 @@ const ViewHeaderSortMenu = (props: Props) => {
<Menu>
{(activeView.fields.sortOptions?.length > 0) &&
<>
<MenuText
<Menu.Text
id='manual'
name='Manual'
onClick={onManualSort}
/>
<MenuText
<Menu.Text
id='revert'
name='Revert'
onClick={onRevertSort}
/>
<MenuSeparator/>
<Menu.Separator/>
</>
}
@ -90,7 +89,7 @@ const ViewHeaderSortMenu = (props: Props) => {
}
}
return (
<MenuText
<Menu.Text
key={option.id}
id={option.id}
name={option.name}

View file

@ -19,10 +19,8 @@ import DuplicateIcon from '../widgets/icons/duplicate'
import GalleryIcon from '../widgets/icons/gallery'
import TableIcon from '../widgets/icons/table'
import Menu from '../widgets/menu'
import {MenuText, MenuSeparator, MenuSubMenu} from '../widgets/menu/menu'
import BoardPermissionGate from './permissions/boardPermissionGate'
import './viewMenu.scss'
type Props = {
@ -275,7 +273,7 @@ const ViewMenu = (props: Props) => {
<Menu>
<div className='view-list'>
{views.map((view: BoardView) => (
<MenuText
<Menu.Text
key={view.id}
id={view.id}
name={view.title}
@ -284,11 +282,11 @@ const ViewMenu = (props: Props) => {
/>))}
</div>
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<MenuSeparator/>
<Menu.Separator/>
</BoardPermissionGate>
{!props.readonly &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<MenuText
<Menu.Text
id='__duplicateView'
name={duplicateViewText}
icon={<DuplicateIcon/>}
@ -298,7 +296,7 @@ const ViewMenu = (props: Props) => {
}
{!props.readonly && views.length > 1 &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<MenuText
<Menu.Text
id='__deleteView'
name={deleteViewText}
icon={<DeleteIcon/>}
@ -308,38 +306,38 @@ const ViewMenu = (props: Props) => {
}
{!props.readonly &&
<BoardPermissionGate permissions={[Permission.ManageBoardProperties]}>
<MenuSubMenu
<Menu.SubMenu
id='__addView'
name={addViewText}
icon={<AddIcon/>}
>
<div className='subMenu'>
<MenuText
<Menu.Text
id='board'
name={boardText}
icon={<BoardIcon/>}
onClick={handleAddViewBoard}
/>
<MenuText
<Menu.Text
id='table'
name={tableText}
icon={<TableIcon/>}
onClick={handleAddViewTable}
/>
<MenuText
<Menu.Text
id='gallery'
name={galleryText}
icon={<GalleryIcon/>}
onClick={handleAddViewGallery}
/>
<MenuText
<Menu.Text
id='calendar'
name='Calendar'
icon={<CalendarIcon/>}
onClick={handleAddViewCalendar}
/>
</div>
</MenuSubMenu>
</Menu.SubMenu>
</BoardPermissionGate>
}
</Menu>

View file

@ -1,6 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {CSSProperties, useCallback, useEffect, useRef, useState} from 'react'
import React, {CSSProperties} from 'react'
import SeparatorOption from './separatorOption'
import SwitchOption from './switchOption'
@ -21,74 +21,71 @@ type Props = {
menuMargin?: number
}
const MenuColor = ColorOption
const MenuSubMenu = SubMenuOption
const MenuSwitch = SwitchOption
const MenuSeparator = SeparatorOption
const MenuText = TextOption
const MenuTextInput = textInputOption
const MenuLabel = LabelOption
export default class Menu extends React.PureComponent<Props> {
static Color = ColorOption
static SubMenu = SubMenuOption
static Switch = SwitchOption
static Separator = SeparatorOption
static Text = TextOption
static TextInput = textInputOption
static Label = LabelOption
const Menu = (props: Props): JSX.Element => {
const menuRef = useRef<HTMLDivElement>(null)
const [hovering, setHovering] = useState<React.ReactNode>(null)
const [menuStyle, setMenuStyle] = useState<CSSProperties>({})
menuRef: React.RefObject<HTMLDivElement>
const {position, menuMargin, fixed, children} = props
constructor(props: Props) {
super(props)
this.menuRef = React.createRef<HTMLDivElement>()
}
public state = {
hovering: null,
menuStyle: {},
}
public render(): JSX.Element {
const {position, fixed, children} = this.props
useEffect(() => {
let style: CSSProperties = {}
if (props.parentRef) {
if (this.props.parentRef) {
const forceBottom = position ? ['bottom', 'left', 'right'].includes(position) : false
style = MenuUtil.openUp(props.parentRef, forceBottom, menuMargin).style
style = MenuUtil.openUp(this.props.parentRef, forceBottom, this.props.menuMargin).style
}
setMenuStyle(style)
}, [props.parentRef, props.position, props.menuMargin])
const onCancel = useCallback(() => {
// No need to do anything, as click bubbled up to MenuWrapper, which closes
}, [])
return (
<div
className={`Menu noselect ${position || 'bottom'} ${fixed ? ' fixed' : ''}`}
style={style}
ref={this.menuRef}
>
<div className='menu-contents'>
<div className='menu-options'>
{React.Children.map(children, (child) => (
<div
onMouseEnter={() => this.setState({hovering: child})}
>
<HoveringContext.Provider value={child === this.state.hovering}>
{child}
</HoveringContext.Provider>
</div>))}
</div>
return (
<div
className={`Menu noselect ${position || 'bottom'} ${fixed ? ' fixed' : ''}`}
style={menuStyle}
ref={menuRef}
>
<div className='menu-contents'>
<div className='menu-options'>
{React.Children.map(children, (child) => (
<div
onMouseEnter={() => setHovering(child)}
>
<HoveringContext.Provider value={child === hovering}>
{child}
</HoveringContext.Provider>
</div>))}
</div>
<div className='menu-spacer hideOnWidescreen'/>
<div className='menu-spacer hideOnWidescreen'/>
<div className='menu-options hideOnWidescreen'>
<MenuText
id='menu-cancel'
name={'Cancel'}
className='menu-cancel'
onClick={onCancel}
/>
<div className='menu-options hideOnWidescreen'>
<Menu.Text
id='menu-cancel'
name={'Cancel'}
className='menu-cancel'
onClick={this.onCancel}
/>
</div>
</div>
</div>
</div>
)
}
)
}
export default Menu
export {
MenuColor,
MenuSubMenu,
MenuSwitch,
MenuSeparator,
MenuText,
MenuTextInput,
MenuLabel,
private onCancel = () => {
// No need to do anything, as click bubbled up to MenuWrapper, which closes
}
}

View file

@ -6,8 +6,9 @@ import CompassIcon from '../../widgets/icons/compassIcon'
import MenuUtil from './menuUtil'
import Menu from '.'
import './subMenuOption.scss'
import {MenuText} from './menu'
export const HoveringContext = React.createContext(false)
@ -76,7 +77,7 @@ function SubMenuOption(props: SubMenuOptionProps): JSX.Element {
<div className='menu-spacer hideOnWidescreen'/>
<div className='menu-options hideOnWidescreen'>
<MenuText
<Menu.Text
id='menu-cancel'
name={'Cancel'}
className='menu-cancel'

View file

@ -6,9 +6,7 @@ import {useIntl, IntlShape} from 'react-intl'
import Menu from '../widgets/menu'
import propsRegistry from '../properties'
import {PropertyType} from '../properties/types'
import './propertyMenu.scss'
import {MenuLabel, MenuSeparator, MenuText, MenuTextInput, MenuSubMenu} from './menu/menu'
type Props = {
propertyId: string
@ -31,15 +29,15 @@ export const PropertyTypes = (props: TypesProps): JSX.Element => {
const intl = useIntl()
return (
<>
<MenuLabel>
<Menu.Label>
<b>{props.label}</b>
</MenuLabel>
</Menu.Label>
<MenuSeparator/>
<Menu.Separator/>
{
propsRegistry.list().map((p) => (
<MenuText
<Menu.Text
key={p.type}
id={p.type}
name={p.displayName(intl)}
@ -62,7 +60,7 @@ const PropertyMenu = (props: Props) => {
return (
<Menu>
<MenuTextInput
<Menu.TextInput
initialValue={props.propertyName}
onConfirmValue={(n) => {
props.onTypeAndNameChanged(props.propertyType, n)
@ -72,7 +70,7 @@ const PropertyMenu = (props: Props) => {
currentPropertyName = n
}}
/>
<MenuSubMenu
<Menu.SubMenu
id='type'
name={typeMenuTitle(intl, props.propertyType)}
>
@ -80,8 +78,8 @@ const PropertyMenu = (props: Props) => {
label={intl.formatMessage({id: 'PropertyMenu.changeType', defaultMessage: 'Change property type'})}
onTypeSelected={(type: PropertyType) => props.onTypeAndNameChanged(type, currentPropertyName)}
/>
</MenuSubMenu>
<MenuText
</Menu.SubMenu>
<Menu.Text
id='delete'
name={deleteText}
onClick={() => props.onDelete(props.propertyId)}

View file

@ -22,7 +22,6 @@ import CloseIcon from './icons/close'
import Label from './label'
import './valueSelector.scss'
import {MenuText, MenuSeparator, MenuColor} from './menu/menu'
type Props = {
options: IPropertyOption[]
@ -85,15 +84,15 @@ const ValueSelectorLabel = (props: LabelProps): JSX.Element => {
icon={<OptionsIcon/>}
/>
<Menu position='left'>
<MenuText
<Menu.Text
id='delete'
icon={<DeleteIcon/>}
name={intl.formatMessage({id: 'BoardComponent.delete', defaultMessage: 'Delete'})}
onClick={() => props.onDeleteOption(option)}
/>
<MenuSeparator/>
<Menu.Separator/>
{Object.entries(Constants.menuColors).map(([key, color]: [string, string]) => (
<MenuColor
<Menu.Color
key={key}
id={key}
name={color}