diff --git a/webapp/src/components/viewHeader/viewHeaderGroupByMenu.tsx b/webapp/src/components/viewHeader/viewHeaderGroupByMenu.tsx new file mode 100644 index 000000000..3d652b552 --- /dev/null +++ b/webapp/src/components/viewHeader/viewHeaderGroupByMenu.tsx @@ -0,0 +1,62 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import React from 'react' +import {FormattedMessage} from 'react-intl' + +import {IPropertyTemplate} from '../../blocks/board' +import {BoardView} from '../../blocks/boardView' +import mutator from '../../mutator' +import Button from '../../widgets/buttons/button' +import Menu from '../../widgets/menu' +import MenuWrapper from '../../widgets/menuWrapper' +import CheckIcon from '../../widgets/icons/check' + +type Props = { + properties: readonly IPropertyTemplate[] + activeView: BoardView + groupByPropertyName?: string +} + +const ViewHeaderGroupByMenu = React.memo((props: Props) => { + const {properties, activeView, groupByPropertyName} = props + return ( + + + + {properties.filter((o: IPropertyTemplate) => o.type === 'select').map((option: IPropertyTemplate) => ( + : undefined} + onClick={(id) => { + if (activeView.groupById === id) { + return + } + + mutator.changeViewGroupById(activeView, id) + }} + /> + ))} + + + ) +}) + +export default ViewHeaderGroupByMenu diff --git a/webapp/src/components/viewHeader/viewHeaderSortMenu.tsx b/webapp/src/components/viewHeader/viewHeaderSortMenu.tsx new file mode 100644 index 000000000..f4cbfbbf9 --- /dev/null +++ b/webapp/src/components/viewHeader/viewHeaderSortMenu.tsx @@ -0,0 +1,100 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +import React from 'react' +import {FormattedMessage} from 'react-intl' + +import {IPropertyTemplate} from '../../blocks/board' +import {BoardView, MutableBoardView, ISortOption} from '../../blocks/boardView' +import {Constants} from '../../constants' +import {Card} from '../../blocks/card' +import mutator from '../../mutator' +import Button from '../../widgets/buttons/button' +import Menu from '../../widgets/menu' +import MenuWrapper from '../../widgets/menuWrapper' +import SortDownIcon from '../../widgets/icons/sortDown' +import SortUpIcon from '../../widgets/icons/sortUp' + +type Props = { + properties: readonly IPropertyTemplate[] + activeView: BoardView + orderedCards: Card[] +} +const ViewHeaderSortMenu = React.memo((props: Props) => { + const {properties, activeView, orderedCards} = props + const hasSort = activeView.sortOptions.length > 0 + const sortDisplayOptions = properties.map((o) => ({id: o.id, name: o.name})) + sortDisplayOptions.unshift({id: Constants.titleColumnId, name: 'Name'}) + + return ( + + + + {(activeView.sortOptions.length > 0) && + <> + { + // This sets the manual card order to the currently displayed order + // Note: Perform this as a single update to change both properties correctly + const newView = new MutableBoardView(activeView) + newView.cardOrder = orderedCards.map((o) => o.id) + newView.sortOptions = [] + mutator.updateBlock(newView, activeView, 'reorder') + }} + /> + + { + mutator.changeViewSortOptions(activeView, []) + }} + /> + + + + } + + {sortDisplayOptions.map((option) => { + let rightIcon: JSX.Element | undefined + if (activeView.sortOptions.length > 0) { + const sortOption = activeView.sortOptions[0] + if (sortOption.propertyId === option.id) { + rightIcon = sortOption.reversed ? : + } + } + return ( + { + let newSortOptions: ISortOption[] = [] + if (activeView.sortOptions[0] && activeView.sortOptions[0].propertyId === propertyId) { + // Already sorting by name, so reverse it + newSortOptions = [ + {propertyId, reversed: !activeView.sortOptions[0].reversed}, + ] + } else { + newSortOptions = [ + {propertyId, reversed: false}, + ] + } + mutator.changeViewSortOptions(activeView, newSortOptions) + }} + /> + ) + })} + + + ) +}) + +export default ViewHeaderSortMenu