Improve the property selector to allow modify colors and delete the properties right there
This commit is contained in:
parent
0d177980ea
commit
57ac32b33a
4 changed files with 77 additions and 8 deletions
|
@ -26,6 +26,7 @@
|
||||||
.octo-propertylist {
|
.octo-propertylist {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.octo-propertyrow {
|
.octo-propertyrow {
|
||||||
|
|
|
@ -40,7 +40,7 @@ export default class PropertyValueElement extends React.Component<Props, State>
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
const {card, propertyTemplate, readOnly, emptyDisplayValue} = this.props
|
const {card, propertyTemplate, readOnly, emptyDisplayValue, boardTree} = this.props
|
||||||
const propertyValue = card.properties[propertyTemplate.id]
|
const propertyValue = card.properties[propertyTemplate.id]
|
||||||
const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate)
|
const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate)
|
||||||
const finalDisplayValue = displayValue || emptyDisplayValue
|
const finalDisplayValue = displayValue || emptyDisplayValue
|
||||||
|
@ -76,6 +76,12 @@ export default class PropertyValueElement extends React.Component<Props, State>
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
mutator.changePropertyValue(card, propertyTemplate.id, value)
|
mutator.changePropertyValue(card, propertyTemplate.id, value)
|
||||||
}}
|
}}
|
||||||
|
onChangeColor={(option: IPropertyOption, colorId: string): void => {
|
||||||
|
mutator.changePropertyOptionColor(boardTree.board, propertyTemplate, option, colorId)
|
||||||
|
}}
|
||||||
|
onDeleteOption={(option: IPropertyOption): void => {
|
||||||
|
mutator.deletePropertyOption(boardTree, propertyTemplate, option)
|
||||||
|
}}
|
||||||
onCreate={
|
onCreate={
|
||||||
async (value) => {
|
async (value) => {
|
||||||
const option: IPropertyOption = {
|
const option: IPropertyOption = {
|
||||||
|
|
|
@ -5,4 +5,16 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: rgba(var(--main-fg), 0.1),
|
background-color: rgba(var(--main-fg), 0.1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.value-menu-option {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
.octo-label-container {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.MenuWrapper {
|
||||||
|
display: flex;
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
import React, {CSSProperties} from 'react'
|
import React, {CSSProperties} from 'react'
|
||||||
import {ActionMeta, ValueType} from 'react-select'
|
import {injectIntl, IntlShape} from 'react-intl'
|
||||||
import CreatableSelect from 'react-select/creatable';
|
import {ActionMeta, ValueType, FormatOptionLabelMeta} from 'react-select'
|
||||||
import boardCard from 'src/components/boardCard';
|
import CreatableSelect from 'react-select/creatable'
|
||||||
|
|
||||||
import {IPropertyOption} from '../blocks/board'
|
import {IPropertyOption} from '../blocks/board'
|
||||||
|
import {Constants} from '../constants'
|
||||||
|
|
||||||
|
import Menu from './menu'
|
||||||
|
import MenuWrapper from './menuWrapper'
|
||||||
|
import Button from './buttons/button'
|
||||||
|
import OptionsIcon from './icons/options'
|
||||||
|
import DeleteIcon from './icons/delete'
|
||||||
|
|
||||||
import './valueSelector.scss'
|
import './valueSelector.scss'
|
||||||
|
|
||||||
|
@ -13,13 +21,49 @@ type Props = {
|
||||||
value: IPropertyOption;
|
value: IPropertyOption;
|
||||||
onCreate?: (value: string) => void
|
onCreate?: (value: string) => void
|
||||||
onChange?: (value: string) => void
|
onChange?: (value: string) => void
|
||||||
|
onChangeColor?: (option: IPropertyOption, color: string) => void
|
||||||
|
onDeleteOption?: (option: IPropertyOption) => void
|
||||||
|
intl: IntlShape
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ValueSelector extends React.Component<Props> {
|
class ValueSelector extends React.Component<Props> {
|
||||||
public shouldComponentUpdate(): boolean {
|
public shouldComponentUpdate(): boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderLabel = (option: IPropertyOption, meta: FormatOptionLabelMeta<IPropertyOption>): React.ReactNode => {
|
||||||
|
if (meta.context === 'value') {
|
||||||
|
return <span className={`octo-label ${option.color}`} >{option.value}</span>
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className='value-menu-option'>
|
||||||
|
<div className='octo-label-container'>
|
||||||
|
<div className={`octo-label ${option.color}`}>{option.value}</div>
|
||||||
|
</div>
|
||||||
|
<MenuWrapper stopPropagationOnToggle={true}>
|
||||||
|
<Button><OptionsIcon/></Button>
|
||||||
|
<Menu position='left'>
|
||||||
|
<Menu.Text
|
||||||
|
id='delete'
|
||||||
|
icon={<DeleteIcon/>}
|
||||||
|
name={this.props.intl.formatMessage({id: 'BoardComponent.delete', defaultMessage: 'Delete'})}
|
||||||
|
onClick={() => this.props.onDeleteOption(option)}
|
||||||
|
/>
|
||||||
|
<Menu.Separator/>
|
||||||
|
{Constants.menuColors.map((color) => (
|
||||||
|
<Menu.Color
|
||||||
|
key={color.id}
|
||||||
|
id={color.id}
|
||||||
|
name={color.name}
|
||||||
|
onClick={() => this.props.onChangeColor(option, color.id)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</Menu>
|
||||||
|
</MenuWrapper>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<CreatableSelect
|
<CreatableSelect
|
||||||
|
@ -34,8 +78,8 @@ export default class ValueSelector extends React.Component<Props> {
|
||||||
}),
|
}),
|
||||||
option: (provided: CSSProperties, state: {isFocused: boolean}): CSSProperties => ({
|
option: (provided: CSSProperties, state: {isFocused: boolean}): CSSProperties => ({
|
||||||
...provided,
|
...provided,
|
||||||
background: state.isFocused ? 'rgb(var(--button-bg))' : 'rgb(var(--main-bg))',
|
background: state.isFocused ? 'rgba(var(--main-fg), 0.1)' : 'rgb(var(--main-bg))',
|
||||||
color: state.isFocused ? 'rgb(var(--button-fg))' : 'rgb(var(--main-fg))',
|
color: state.isFocused ? 'rgb(var(--main-fg))' : 'rgb(var(--main-fg))',
|
||||||
padding: '2px 8px',
|
padding: '2px 8px',
|
||||||
}),
|
}),
|
||||||
control: (): CSSProperties => ({
|
control: (): CSSProperties => ({
|
||||||
|
@ -56,9 +100,13 @@ export default class ValueSelector extends React.Component<Props> {
|
||||||
marginBottom: 0,
|
marginBottom: 0,
|
||||||
marginTop: 0,
|
marginTop: 0,
|
||||||
}),
|
}),
|
||||||
|
menuList: (provided: CSSProperties): CSSProperties => ({
|
||||||
|
...provided,
|
||||||
|
overflowY: 'unset',
|
||||||
|
}),
|
||||||
}}
|
}}
|
||||||
|
formatOptionLabel={this.renderLabel}
|
||||||
className='ValueSelector'
|
className='ValueSelector'
|
||||||
hideSelectedOptions={true}
|
|
||||||
options={this.props.options}
|
options={this.props.options}
|
||||||
getOptionLabel={(o: IPropertyOption) => o.value}
|
getOptionLabel={(o: IPropertyOption) => o.value}
|
||||||
getOptionValue={(o: IPropertyOption) => o.id}
|
getOptionValue={(o: IPropertyOption) => o.id}
|
||||||
|
@ -75,3 +123,5 @@ export default class ValueSelector extends React.Component<Props> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default injectIntl(ValueSelector)
|
||||||
|
|
Loading…
Reference in a new issue