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:
commit
3fbaf36009
18 changed files with 71 additions and 43 deletions
|
@ -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"
|
||||
/>
|
||||
|
|
|
@ -58,7 +58,7 @@ const CardDetailProperties = React.memo((props: Props) => {
|
|||
contents={contents}
|
||||
comments={comments}
|
||||
propertyTemplate={propertyTemplate}
|
||||
emptyDisplayValue='Empty'
|
||||
showEmptyPlaceholder={true}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -167,7 +167,7 @@ const GalleryCard = React.memo((props: Props) => {
|
|||
readOnly={true}
|
||||
card={card}
|
||||
propertyTemplate={template}
|
||||
emptyDisplayValue=''
|
||||
showEmptyPlaceholder={false}
|
||||
/>
|
||||
</Tooltip>
|
||||
))}
|
||||
|
|
|
@ -123,7 +123,7 @@ const KanbanCard = React.memo((props: Props) => {
|
|||
contents={contents}
|
||||
comments={comments}
|
||||
propertyTemplate={template}
|
||||
emptyDisplayValue=''
|
||||
showEmptyPlaceholder={false}
|
||||
/>
|
||||
</Tooltip>
|
||||
))}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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%;
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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"
|
||||
/>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -46,7 +46,7 @@ const MultiSelectProperty = (props: Props): JSX.Element => {
|
|||
{values.length === 0 && (
|
||||
<Label
|
||||
color='empty'
|
||||
>{''}</Label>
|
||||
>{emptyValue}</Label>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -140,7 +140,7 @@ const TableRow = React.memo((props: Props) => {
|
|||
contents={contents}
|
||||
comments={comments}
|
||||
propertyTemplate={template}
|
||||
emptyDisplayValue=''
|
||||
showEmptyPlaceholder={false}
|
||||
/>
|
||||
</div>)
|
||||
})}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue