1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-11-24 08:22:29 +02:00

Fix Unfurl Bugs (#1668)

This commit is contained in:
Hossein 2021-10-27 14:53:53 -04:00 committed by GitHub
parent 380bd92725
commit 690d424dfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 129 additions and 105 deletions

View File

@ -1,11 +1,14 @@
.FocalboardUnfurl {
display: block;
display: table;
width: 100%;
max-width: 425px;
margin: 0;
table-layout: fixed;
padding: 16px;
border: 1px solid rgba(61, 60, 64, 0.24) !important;
border: 1px solid rgba(var(--center-channel-color-rgb), 0.24) !important;
border-radius: 4px;
box-sizing: border-box;
box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.08);
width: 425px;
box-shadow: 0px 2px 3px var(--elevation-1);
text-decoration: none !important;
color: inherit !important;
@ -28,7 +31,7 @@
overflow: hidden;
.card_title {
color: #3D3C40;
color: var(--center-channel-color);
font-weight: 600;
font-size: 14px;
max-width: 100%;
@ -38,7 +41,7 @@
}
.board_title {
color: rgba(61, 60, 64, 0.56);
color: rgba(var(--center-channel-color-rgb), 0.56);
font-size: 12px;
line-height: 16px;
}
@ -46,7 +49,7 @@
}
.body {
border: 1px solid rgba(61, 60, 64, 0.16);
border: 1px solid rgba(var(--center-channel-color-rgb), 0.16);
border-radius: 4px;
margin-top: 16px;
height: 145px;
@ -71,7 +74,7 @@
white-space: nowrap;
.remainder {
color: rgba(61, 60, 64, 0.48);
color: rgba(var(--center-channel-color-rgb), 0.48);
font-weight: bold;
font-size: 14px;
}
@ -80,11 +83,11 @@
border-radius: 4px;
padding: 2px 4px;
margin-right: 10px;
max-width: 33%;
overflow: hidden;
text-overflow: ellipsis;
overflow-wrap: normal;
&.propColorDefault {
background-color: var(--prop-default);
}

View File

@ -19,6 +19,7 @@ const Timestamp = (window as any).Components.Timestamp
const imageURLForUser = (window as any).Components.imageURLForUser
import './boardsUnfurl.scss'
import '../../../../../webapp/src/styles/labels.scss'
type Props = {
embed: {
@ -52,6 +53,7 @@ const BoardsUnfurl = (props: Props): JSX.Element => {
const [card, setCard] = useState<Card>()
const [content, setContent] = useState<ContentBlock>()
const [board, setBoard] = useState<Board>()
const [loading, setLoading] = useState(true)
useEffect(() => {
const fetchData = async () => {
@ -64,6 +66,7 @@ const BoardsUnfurl = (props: Props): JSX.Element => {
const [firstCard] = cards as Card[]
const [firstBoard] = boards as Board[]
if (!firstCard || !firstBoard) {
setLoading(false)
return null
}
setCard(firstCard)
@ -79,137 +82,155 @@ const BoardsUnfurl = (props: Props): JSX.Element => {
const contentBlock = await octoClient.getBlocksWithBlockID(firstContentBlockID, workspaceID, readToken) as ContentBlock[]
const [firstContentBlock] = contentBlock
if (!firstContentBlock) {
setLoading(false)
return null
}
setContent(firstContentBlock)
}
setLoading(false)
return null
}
fetchData()
}, [originalPath])
if (!card || !board) {
return <></>
}
const propertyKeyArray = Object.keys(card.fields.properties)
const propertyValueArray = Object.values(card.fields.properties)
const options = board.fields.cardProperties
let remainder = 0
let html = ''
const propertiesToDisplay: Array<Record<string, string>> = []
if (card && board) {
// Checkboxes need to be accounted for if they are off or on, if they are on they show up in the card properties so we don't want to count it twice
// Therefore we keep track how many checkboxes there are and subtract it at the end
let totalNumberOfCheckBoxes = 0
// We will just display the first 3 or less select/multi-select properties and do a +n for remainder if any remainder
if (propertyKeyArray.length > 0) {
for (let i = 0; i < propertyKeyArray.length && propertiesToDisplay.length < 3; i++) {
const keyToLookUp = propertyKeyArray[i]
const correspondingOption = options.find((option) => option.id === keyToLookUp)
// We will just display the first 3 or less select/multi-select properties and do a +n for remainder if any remainder
for (let i = 0; i < board.fields.cardProperties.length; i++) {
const optionInBoard = board.fields.cardProperties[i]
let valueToLookUp = card.fields.properties[optionInBoard.id]
if (!correspondingOption) {
// Since these are always set and not included in the card properties
if (['createdTime', 'createdBy', 'updatedTime', 'updatedBy', 'checkbox'].includes(optionInBoard.type)) {
if (valueToLookUp && optionInBoard.type === 'checkbox') {
totalNumberOfCheckBoxes += 1
}
remainder += 1
continue
}
// Check to see if this property is set in the Card or if we have max properties to display
if (propertiesToDisplay.length === 3 || !valueToLookUp) {
continue
}
let valueToLookUp = propertyValueArray[i]
if (Array.isArray(valueToLookUp)) {
valueToLookUp = valueToLookUp[0]
}
const optionSelected = correspondingOption.options.find((option) => option.id === valueToLookUp)
const optionSelected = optionInBoard.options.find((option) => option.id === valueToLookUp)
if (!optionSelected) {
continue
}
propertiesToDisplay.push({optionName: correspondingOption.name, optionValue: optionSelected.value, optionValueColour: optionSelected.color})
propertiesToDisplay.push({optionName: optionInBoard.name, optionValue: optionSelected.value, optionValueColour: optionSelected.color})
}
remainder += (Object.keys(card.fields.properties).length - propertiesToDisplay.length - totalNumberOfCheckBoxes)
html = Utils.htmlFromMarkdown(content?.title || '')
}
const remainder = propertyKeyArray.length - propertiesToDisplay.length
const html: string = Utils.htmlFromMarkdown(content?.title || '')
return (
<IntlProvider
messages={getMessages(locale)}
locale={locale}
>
<a
className='FocalboardUnfurl'
href={`${baseURL}${originalPath}`}
rel='noopener noreferrer'
target='_blank'
>
{!loading && (!card || !board) && <></>}
{!loading && card && board &&
<a
className='FocalboardUnfurl'
href={`${baseURL}${originalPath}`}
rel='noopener noreferrer'
target='_blank'
>
{/* Header of the Card*/}
<div className='header'>
<span className='icon'>{card.fields?.icon}</span>
<div className='information'>
<span className='card_title'>{card.title}</span>
<span className='board_title'>{board.title}</span>
</div>
</div>
{/* Body of the Card*/}
{html !== '' &&
<div className='body'>
<div
dangerouslySetInnerHTML={{__html: html}}
/>
</div>
}
{/* Footer of the Card*/}
<div className='footer'>
<div className='avatar'>
<Avatar
size={'md'}
url={imageURLForUser(card.createdBy)}
className={'avatar-post-preview'}
/>
</div>
<div className='timestamp_properties'>
<div className='properties'>
{propertiesToDisplay.map((property) => (
<div
key={property.optionValue}
className={`property ${property.optionValueColour}`}
title={`${property.optionName}`}
>
{property.optionValue}
</div>
))}
{remainder > 0 &&
<span className='remainder'>
<FormattedMessage
id='BoardsUnfurl.Remainder'
defaultMessage='+{remainder} more'
values={{
remainder,
}}
/>
</span>
}
{/* Header of the Card*/}
<div className='header'>
<span className='icon'>{card.fields?.icon}</span>
<div className='information'>
<span className='card_title'>{card.title}</span>
<span className='board_title'>{board.title}</span>
</div>
<span className='post-preview__time'>
<FormattedMessage
id='BoardsUnfurl.Updated'
defaultMessage='Updated {time}'
values={{
time: (
<Timestamp
value={card.updateAt}
units={[
'now',
'minute',
'hour',
'day',
]}
useTime={false}
day={'numeric'}
/>
),
}}
/>
</span>
</div>
</div>
</a>
{/* Body of the Card*/}
{html !== '' &&
<div className='body'>
<div
dangerouslySetInnerHTML={{__html: html}}
/>
</div>
}
{/* Footer of the Card*/}
<div className='footer'>
<div className='avatar'>
<Avatar
size={'md'}
url={imageURLForUser(card.createdBy)}
className={'avatar-post-preview'}
/>
</div>
<div className='timestamp_properties'>
<div className='properties'>
{propertiesToDisplay.map((property) => (
<div
key={property.optionValue}
className={`property ${property.optionValueColour}`}
title={`${property.optionName}`}
style={{maxWidth: `${(1 / propertiesToDisplay.length) * 100}%`}}
>
{property.optionValue}
</div>
))}
{remainder > 0 &&
<span className='remainder'>
<FormattedMessage
id='BoardsUnfurl.Remainder'
defaultMessage='+{remainder} more'
values={{
remainder,
}}
/>
</span>
}
</div>
<span className='post-preview__time'>
<FormattedMessage
id='BoardsUnfurl.Updated'
defaultMessage='Updated {time}'
values={{
time: (
<Timestamp
value={card.updateAt}
units={[
'now',
'minute',
'hour',
'day',
]}
useTime={false}
day={'numeric'}
/>
),
}}
/>
</span>
</div>
</div>
</a>
}
{loading &&
<div style={{height: '302px'}}/>
}
</IntlProvider>
)
}