Merge branch 'gh-1059-fix-empty-placeholder-in-card-dialog' of https://github.com/kamre/focalboard into kamre-gh-1059-fix-empty-placeholder-in-card-dialog

This commit is contained in:
Chen-I Lim 2021-09-24 16:47:07 -07:00
commit 3fbaf36009
18 changed files with 71 additions and 43 deletions

View file

@ -3,16 +3,14 @@
exports[`components/propertyValueElement should match snapshot, date, array value 1`] = `
<div>
<div
class="DateRange "
class="DateRange empty"
>
<button
class="Button "
type="button"
>
<span>
<span
title="Empty"
/>
Empty
</span>
</button>
</div>
@ -44,7 +42,7 @@ exports[`components/propertyValueElement should match snapshot, person, array va
<div>
<input
class="Editable octo-propertyvalue"
placeholder=""
placeholder="Empty"
spellcheck="true"
title=""
value=""
@ -99,7 +97,7 @@ exports[`components/propertyValueElement should match snapshot, url, array value
>
<input
class="Editable octo-propertyvalue"
placeholder=""
placeholder="Empty"
title="http://localhost"
value="http://localhost"
/>
@ -124,7 +122,7 @@ exports[`components/propertyValueElement should match snapshot, url, array value
>
<input
class="Editable octo-propertyvalue"
placeholder=""
placeholder="Empty"
title="http://localhost"
value="http://localhost"
/>

View file

@ -58,7 +58,7 @@ const CardDetailProperties = React.memo((props: Props) => {
contents={contents}
comments={comments}
propertyTemplate={propertyTemplate}
emptyDisplayValue='Empty'
showEmptyPlaceholder={true}
/>
</div>
)

View file

@ -167,7 +167,7 @@ const GalleryCard = React.memo((props: Props) => {
readOnly={true}
card={card}
propertyTemplate={template}
emptyDisplayValue=''
showEmptyPlaceholder={false}
/>
</Tooltip>
))}

View file

@ -123,7 +123,7 @@ const KanbanCard = React.memo((props: Props) => {
contents={contents}
comments={comments}
propertyTemplate={template}
emptyDisplayValue=''
showEmptyPlaceholder={false}
/>
</Tooltip>
))}

View file

@ -37,17 +37,13 @@ exports[`components/properties/dateRange handle clear 1`] = `
exports[`components/properties/dateRange returns default correctly 1`] = `
<div>
<div
class="DateRange "
class="DateRange empty"
>
<button
class="Button "
type="button"
>
<span>
<span
title="Empty"
/>
</span>
<span />
</button>
</div>
</div>

View file

@ -1,10 +1,6 @@
.DateRange {
width: 100%;
.octo-propertyvalue {
white-space: none;
}
.inputContainer {
display: flex;
@ -43,6 +39,11 @@
margin-bottom: 100px;
}
&.empty .Button {
color: rgba(var(--center-channel-color-rgb), 0.4);
padding: 0 3px;
}
.Button {
width: 100%;
height: 100%;

View file

@ -60,6 +60,7 @@ describe('components/properties/dateRange', () => {
<DateRange
className='octo-propertyvalue'
value={''}
showEmptyPlaceholder={true}
onChange={callback}
/>,
)
@ -68,7 +69,7 @@ describe('components/properties/dateRange', () => {
const fifteenth = Date.UTC(date.getFullYear(), date.getMonth(), 15, 12)
const {getByText, getByTitle} = render(component)
const dayDisplay = getByTitle('Empty')
const dayDisplay = getByText('Empty')
userEvent.click(dayDisplay)
const day = getByText('15')
@ -86,13 +87,14 @@ describe('components/properties/dateRange', () => {
<DateRange
className='octo-propertyvalue'
value={''}
showEmptyPlaceholder={true}
onChange={callback}
/>,
)
// open modal
const {getByText, getByTitle} = render(component)
const dayDisplay = getByTitle('Empty')
const dayDisplay = getByText('Empty')
userEvent.click(dayDisplay)
// select start date
@ -249,6 +251,7 @@ describe('components/properties/dateRange', () => {
<DateRange
className='octo-propertyvalue'
value={''}
showEmptyPlaceholder={true}
onChange={callback}
/>,
)
@ -261,7 +264,7 @@ describe('components/properties/dateRange', () => {
const today = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
const {getByText, getByTitle} = render(component)
const dayDisplay = getByTitle('Empty')
const dayDisplay = getByText('Empty')
userEvent.click(dayDisplay)
const day = getByText('Today')

View file

@ -22,6 +22,7 @@ import {Utils} from '../../../utils'
type Props = {
className: string
value: string
showEmptyPlaceholder?: boolean
onChange: (value: string) => void
}
@ -35,7 +36,7 @@ type DateProperty = {
const loadedLocales: Record<string, any> = {}
function DateRange(props: Props): JSX.Element {
const {className, value, onChange} = props
const {className, value, showEmptyPlaceholder, onChange} = props
const intl = useIntl()
const timeZoneOffset = new Date().getTimezoneOffset() * 60 * 1000
@ -151,12 +152,17 @@ function DateRange(props: Props): JSX.Element {
setShowDialog(false)
}
let buttonText = displayValue
if (!buttonText && showEmptyPlaceholder) {
buttonText = intl.formatMessage({id: 'DateRange.empty', defaultMessage: 'Empty'})
}
return (
<div className={'DateRange '}>
<div className={`DateRange ${displayValue ? '' : 'empty'}`}>
<Button
onClick={() => setShowDialog(true)}
>
{displayValue || <span title={intl.formatMessage({id: 'DateRange.empty', defaultMessage: 'Empty'})}/>}
{buttonText}
</Button>
{showDialog &&

View file

@ -7,7 +7,6 @@ exports[`components/properties/link returns link properties correctly 1`] = `
>
<input
class="Editable octo-propertyvalue"
placeholder=""
title="https://github.com/mattermost/focalboard"
value="https://github.com/mattermost/focalboard"
/>

View file

@ -12,6 +12,7 @@ import LinkIcon from '../../../widgets/icons/Link'
type Props = {
value: string
readonly?: boolean
placeholder?: string
onChange: (value: string) => void
onSave: () => void
onCancel: () => void
@ -38,7 +39,7 @@ const URLProperty = (props: Props): JSX.Element => {
<div className='URLProperty property-link url'>
<Editable
className='octo-propertyvalue'
placeholderText=''
placeholderText={props.placeholder}
value={props.value}
readonly={props.readonly}
onChange={props.onChange}

View file

@ -46,7 +46,7 @@ const MultiSelectProperty = (props: Props): JSX.Element => {
{values.length === 0 && (
<Label
color='empty'
>{''}</Label>
>{emptyValue}</Label>
)}
</div>
)

View file

@ -111,9 +111,9 @@ exports[`components/properties/user not readonly not existing user 1`] = `
class=" css-kpfmlq-ValueContainer"
>
<div
class=" css-1wa3eu0-placeholder"
class=" css-1oswhd8-placeholder"
>
Select...
Empty
</div>
<div
class="css-1shkodo-Input"

View file

@ -3,6 +3,7 @@
import React from 'react'
import Select from 'react-select'
import {CSSObject} from '@emotion/serialize'
import {IUser} from '../../../user'
import {getWorkspaceUsersList, getWorkspaceUsers} from '../../../store/users'
@ -17,6 +18,14 @@ type Props = {
onChange: (value: string) => void,
}
const selectStyles = {
...getSelectBaseStyle(),
placeholder: (provided: CSSObject): CSSObject => ({
...provided,
color: 'rgba(var(--center-channel-color-rgb), 0.4)',
}),
}
const UserProperty = (props: Props): JSX.Element => {
const workspaceUsers = useAppSelector<IUser[]>(getWorkspaceUsersList)
const workspaceUsersById = useAppSelector<{[key:string]: IUser}>(getWorkspaceUsers)
@ -32,7 +41,8 @@ const UserProperty = (props: Props): JSX.Element => {
isClearable={true}
backspaceRemovesValue={true}
className={'UserProperty'}
styles={getSelectBaseStyle()}
styles={selectStyles}
placeholder={'Empty'}
getOptionLabel={(o: IUser) => o.username}
getOptionValue={(a: IUser) => a.id}
value={workspaceUsersById[props.value] || null}

View file

@ -39,7 +39,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate || board.fields.cardProperties[0]}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
@ -57,7 +57,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate || board.fields.cardProperties[0]}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
@ -91,7 +91,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
@ -116,7 +116,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
@ -141,7 +141,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
@ -166,7 +166,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
@ -191,7 +191,7 @@ describe('components/propertyValueElement', () => {
contents={[]}
comments={[comments]}
propertyTemplate={propertyTemplate}
emptyDisplayValue={'empty'}
showEmptyPlaceholder={true}
/>,
)
const {container} = render(component)

View file

@ -31,17 +31,18 @@ type Props = {
contents: Array<ContentBlock|ContentBlock[]>
comments: CommentBlock[]
propertyTemplate: IPropertyTemplate
emptyDisplayValue: string
showEmptyPlaceholder: boolean
}
const PropertyValueElement = (props:Props): JSX.Element => {
const [value, setValue] = useState(props.card.fields.properties[props.propertyTemplate.id] || '')
const [serverValue, setServerValue] = useState(props.card.fields.properties[props.propertyTemplate.id] || '')
const {card, propertyTemplate, readOnly, emptyDisplayValue, board, contents, comments} = props
const {card, propertyTemplate, readOnly, showEmptyPlaceholder, board, contents, comments} = props
const intl = useIntl()
const propertyValue = card.fields.properties[propertyTemplate.id]
const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate, intl)
const emptyDisplayValue = showEmptyPlaceholder ? intl.formatMessage({id: 'PropertyValueElement.empty', defaultMessage: 'Empty'}) : ''
const finalDisplayValue = displayValue || emptyDisplayValue
const editableFields: Array<PropertyType> = ['text', 'number', 'email', 'url', 'phone']
@ -169,6 +170,7 @@ const PropertyValueElement = (props:Props): JSX.Element => {
<DateRange
className='octo-propertyvalue'
value={value.toString()}
showEmptyPlaceholder={showEmptyPlaceholder}
onChange={(newValue) => mutator.changePropertyValue(card, propertyTemplate.id, newValue)}
/>
)
@ -177,6 +179,7 @@ const PropertyValueElement = (props:Props): JSX.Element => {
<URLProperty
value={value.toString()}
readonly={readOnly}
placeholder={emptyDisplayValue}
onChange={setValue}
onSave={saveTextProperty}
onCancel={() => setValue(propertyValue)}
@ -228,7 +231,7 @@ const PropertyValueElement = (props:Props): JSX.Element => {
return (
<Editable
className='octo-propertyvalue'
placeholderText=''
placeholderText={emptyDisplayValue}
value={value.toString()}
onChange={setValue}
onSave={saveTextProperty}

View file

@ -140,7 +140,7 @@ const TableRow = React.memo((props: Props) => {
contents={contents}
comments={comments}
propertyTemplate={template}
emptyDisplayValue=''
showEmptyPlaceholder={false}
/>
</div>)
})}

View file

@ -12,6 +12,13 @@
font-weight: 600;
font-size: 13px;
&.empty {
color: rgba(var(--center-channel-color-rgb), 0.4);
padding: 3px;
text-transform: none;
font-weight: normal;
}
input {
line-height: 20px;
color: rgba(var(--center-channel-color-rgb), 0.8);

View file

@ -125,6 +125,10 @@ const valueSelectorStyle = {
top: 'unset',
transform: 'unset',
}),
placeholder: (provided: CSSObject): CSSObject => ({
...provided,
color: 'rgba(var(--center-channel-color-rgb), 0.4)',
}),
multiValue: (provided: CSSObject): CSSObject => ({
...provided,
margin: 0,