From 2eb3f59ddc20f699ade4f9f0fa765b35965e6d26 Mon Sep 17 00:00:00 2001 From: Scott Bishel Date: Thu, 5 Aug 2021 09:24:01 -0600 Subject: [PATCH] [Gh 684] Autosize fix for multi-select columns (#882) * temporary commit * cleanup code * final fixes * remove setting perItemPadding where not necessary * Update webapp/src/octoUtils.tsx Co-authored-by: Hossein * Update webapp/src/components/table/table.tsx Co-authored-by: Hossein Co-authored-by: Hossein --- .../src/components/properties/multiSelect.tsx | 7 +- webapp/src/components/table/table.tsx | 64 +++++++++++++++---- webapp/src/octoUtils.tsx | 10 +++ 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/webapp/src/components/properties/multiSelect.tsx b/webapp/src/components/properties/multiSelect.tsx index c1e3ae9d0..c32da6ec0 100644 --- a/webapp/src/components/properties/multiSelect.tsx +++ b/webapp/src/components/properties/multiSelect.tsx @@ -25,9 +25,7 @@ const MultiSelectProperty = (props: Props): JSX.Element => { const {propertyTemplate, emptyValue, propertyValue, isEditable, onChange, onChangeColor, onDeleteOption, onCreate, onDeleteValue} = props const [open, setOpen] = useState(false) - const values = Array.isArray(propertyValue) ? - propertyValue.map((v) => propertyTemplate.options.find((o) => o!.id === v)).filter((v): v is IPropertyOption => Boolean(v)) : - [] + const values = Array.isArray(propertyValue) && propertyValue.length > 0 ? propertyValue.map((v) => propertyTemplate.options.find((o) => o!.id === v)).filter((v): v is IPropertyOption => Boolean(v)) : [] if (!isEditable || !open) { return ( @@ -44,6 +42,9 @@ const MultiSelectProperty = (props: Props): JSX.Element => { {v.value} ))} + {values.length === 0 && ( + + )} ) } diff --git a/webapp/src/components/table/table.tsx b/webapp/src/components/table/table.tsx index 3ae144122..8fc95f8da 100644 --- a/webapp/src/components/table/table.tsx +++ b/webapp/src/components/table/table.tsx @@ -86,21 +86,63 @@ const Table = (props: Props): JSX.Element => { if (!columnRef?.current) { return } - const {fontDescriptor, padding} = Utils.getFontAndPaddingFromCell(columnRef.current) + + let template: IPropertyTemplate | undefined + const columnFontPadding = Utils.getFontAndPaddingFromCell(columnRef.current) + let perItemPadding = 0 + if (columnID !== Constants.titleColumnId) { + template = visibleProperties.find((t: IPropertyTemplate) => t.id === columnID) + if (!template) { + return + } + if (template.type === 'multiSelect') { + // For multiselect, the padding calculated above depends on the number selected when calculating the padding. + // Need to calculate it manually here. + // DOM Object hierarchy should be {cell -> property -> [value1, value2, etc]} + let valueCount = 0 + if (columnRef?.current?.childElementCount > 0) { + const propertyElement = columnRef.current.children.item(0) as Element + if (propertyElement) { + valueCount = propertyElement.childElementCount + if (valueCount > 0) { + const statusPadding = Utils.getFontAndPaddingFromChildren(propertyElement.children, 0) + perItemPadding = statusPadding.padding / valueCount + } + } + } + + // remove the "value" portion of the original calculation + columnFontPadding.padding -= (perItemPadding * valueCount) + } + } cards.forEach((card) => { - let displayValue = card.title - if (columnID !== Constants.titleColumnId) { - const template = visibleProperties.find((t: IPropertyTemplate) => t.id === columnID) - if (!template) { - return + let thisLen = 0 + if (columnID === Constants.titleColumnId) { + thisLen = Utils.getTextWidth(card.title, columnFontPadding.fontDescriptor) + columnFontPadding.padding + } else if (template) { + const displayValue = (OctoUtils.propertyDisplayValue(card, card.fields.properties[columnID], template as IPropertyTemplate, intl) || '') + switch (template.type) { + case 'select': { + thisLen = Utils.getTextWidth(displayValue.toString().toUpperCase(), columnFontPadding.fontDescriptor) + break } - displayValue = (OctoUtils.propertyDisplayValue(card, card.fields.properties[columnID], template, intl) || '') as string - if (template.type === 'select') { - displayValue = displayValue.toUpperCase() + case 'multiSelect': { + if (displayValue) { + const displayValues = displayValue as string[] + displayValues.forEach((value) => { + thisLen += Utils.getTextWidth(value.toUpperCase(), columnFontPadding.fontDescriptor) + perItemPadding + }) + } + break } + default: { + thisLen = Utils.getTextWidth(displayValue.toString(), columnFontPadding.fontDescriptor) + break + } + } + thisLen += columnFontPadding.padding } - const thisLen = Utils.getTextWidth(displayValue, fontDescriptor) + padding if (thisLen > longestSize) { longestSize = thisLen } @@ -286,7 +328,7 @@ const Table = (props: Props): JSX.Element => { })} - {/* Table header row */} + {/* Table rows */}
{activeView.fields.groupById && visibleGroups.map((group) => { diff --git a/webapp/src/octoUtils.tsx b/webapp/src/octoUtils.tsx index 7cd9dcc7a..3aa8a109a 100644 --- a/webapp/src/octoUtils.tsx +++ b/webapp/src/octoUtils.tsx @@ -30,6 +30,16 @@ class OctoUtils { } break } + case 'multiSelect': { + if (propertyValue?.length) { + const options = propertyTemplate.options.filter((o) => propertyValue.includes(o.id)) + if (!options.length) { + Utils.assertFailure(`Invalid multiSelect option IDs ${propertyValue}, block.title: ${block.title}`) + } + displayValue = options.map((o) => o.value) + } + break + } case 'createdTime': { displayValue = Utils.displayDateTime(new Date(block.createAt), intl) break