Compare commits

..

1 Commits

Author SHA1 Message Date
Maxime Beauchemin
71cccfc6a0 fix(dashboard): prevent horizontal overflow when filter bar is open
The dashboard content grid item had the default `min-width: auto`,
which prevented it from shrinking below its content's intrinsic width.
When the vertical filter bar was open, this caused the content area to
overflow and produce an unwanted horizontal scrollbar. Adding
`min-width: 0` to StyledContent allows the grid item to properly shrink
within the `auto 1fr` grid layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 16:10:31 +00:00
5 changed files with 101 additions and 118 deletions

View File

@@ -65,6 +65,10 @@ const StyledDatasourceModal = styled(Modal)`
display: flex;
flex-direction: column;
}
.ant-tabs-top {
margin-top: -${({ theme }) => theme.sizeUnit * 4}px;
}
`;
function buildExtraJsonObject(

View File

@@ -38,9 +38,7 @@ import {
} from '../../types';
const CrudButtonWrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
text-align: right;
${({ theme }) => `margin-bottom: ${theme.sizeUnit * 2}px`}
`;
@@ -468,27 +466,24 @@ export default class CRUDCollection extends PureComponent<
return (
<>
{(this.props.toolbarExtra || this.props.allowAddItem) && (
<CrudButtonWrapper>
{this.props.toolbarExtra}
{this.props.allowAddItem && (
<StyledButtonWrapper>
<Button
buttonSize="small"
buttonStyle="secondary"
onClick={this.onAddItem}
data-test="add-item-button"
>
<Icons.PlusOutlined
iconSize="m"
data-test="crud-add-table-item"
/>
{t('Add item')}
</Button>
</StyledButtonWrapper>
)}
</CrudButtonWrapper>
)}
<CrudButtonWrapper>
{this.props.allowAddItem && (
<StyledButtonWrapper>
<Button
buttonSize="small"
buttonStyle="secondary"
onClick={this.onAddItem}
data-test="add-item-button"
>
<Icons.PlusOutlined
iconSize="m"
data-test="crud-add-table-item"
/>
{t('Add item')}
</Button>
</StyledButtonWrapper>
)}
</CrudButtonWrapper>
<Table<CollectionItem>
data-test="crud-table"
columns={tableColumns}

View File

@@ -311,7 +311,6 @@ interface ColumnCollectionTableProps {
columnLabelTooltips?: Record<string, string>;
filterTerm?: string;
filterFields?: string[];
toolbarExtra?: ReactNode;
}
interface StackedFieldProps {
@@ -400,6 +399,11 @@ const EditLockContainer = styled.div`
}
`;
const ColumnButtonWrapper = styled.div`
text-align: right;
${({ theme }) => `margin-bottom: ${theme.sizeUnit * 2}px`}
`;
const StyledLabelWrapper = styled.div`
display: flex;
align-items: center;
@@ -443,6 +447,16 @@ const FieldLabelWithTooltip = styled.div`
`}
`;
const StyledButtonWrapper = styled.span`
${({ theme }) => `
margin-top: ${theme.sizeUnit * 3}px;
margin-left: ${theme.sizeUnit * 3}px;
button>span>:first-of-type {
margin-right: 0;
}
`}
`;
const checkboxGenerator = (
d: boolean,
onChange: (value: boolean) => void,
@@ -518,7 +532,6 @@ function ColumnCollectionTable({
columnLabelTooltips,
filterTerm,
filterFields,
toolbarExtra,
}: ColumnCollectionTableProps): JSX.Element {
return (
<CollectionTable
@@ -553,7 +566,6 @@ function ColumnCollectionTable({
columnLabelTooltips={columnLabelTooltips}
filterTerm={filterTerm}
filterFields={filterFields}
toolbarExtra={toolbarExtra}
stickyHeader
expandFieldset={
<FormContainer>
@@ -1823,7 +1835,6 @@ class DatasourceEditor extends PureComponent<
<div
css={theme => css`
margin-top: ${theme.sizeUnit * 3}px;
margin-bottom: ${theme.sizeUnit * 2}px;
display: flex;
gap: ${theme.sizeUnit * 4}px;
`}
@@ -1843,13 +1854,7 @@ class DatasourceEditor extends PureComponent<
<Divider />
<Fieldset item={datasource} onChange={this.onDatasourceChange} compact>
{this.state.datasourceType === DATASOURCE_TYPES.virtual.key && (
<div
css={css`
.ant-form-item:last-child {
margin-bottom: 0;
}
`}
>
<div>
{this.state.isSqla && (
<>
<Col xs={24} md={12}>
@@ -1892,20 +1897,22 @@ class DatasourceEditor extends PureComponent<
</div>
}
/>
<Field
fieldKey="table_name"
label={t('Name')}
control={
<TextControl
controlId="table_name"
onChange={table => {
this.onDatasourcePropChange('table_name', table);
}}
placeholder={t('Dataset name')}
disabled={!this.state.isEditMode}
/>
}
/>
<div css={{ width: 'calc(100% - 34px)', marginTop: -16 }}>
<Field
fieldKey="table_name"
label={t('Name')}
control={
<TextControl
controlId="table_name"
onChange={table => {
this.onDatasourcePropChange('table_name', table);
}}
placeholder={t('Dataset name')}
disabled={!this.state.isEditMode}
/>
}
/>
</div>
</Col>
<Field
fieldKey="sql"
@@ -2046,15 +2053,7 @@ class DatasourceEditor extends PureComponent<
</div>
)}
{this.state.datasourceType === DATASOURCE_TYPES.physical.key && (
<Col
xs={24}
md={12}
css={css`
.ant-form-item:last-child {
margin-bottom: 0;
}
`}
>
<Col xs={24} md={12}>
{this.state.isSqla && (
<Field
fieldKey="tableSelector"
@@ -2149,24 +2148,18 @@ class DatasourceEditor extends PureComponent<
const sortedMetrics = metrics?.length ? this.sortMetrics(metrics) : [];
return (
<div>
<Input.Search
placeholder={t('Search metrics by key or label')}
value={metricSearchTerm}
onChange={e => this.setState({ metricSearchTerm: e.target.value })}
style={{ marginBottom: 16, width: 300 }}
allowClear
/>
<CollectionTable
tableColumns={['metric_name', 'verbose_name', 'expression']}
sortColumns={['metric_name', 'verbose_name', 'expression']}
filterTerm={metricSearchTerm}
filterFields={['metric_name', 'verbose_name']}
toolbarExtra={
<Input.Search
placeholder={t('Search metrics by key or label')}
value={metricSearchTerm}
onChange={e =>
this.setState({ metricSearchTerm: e.target.value })
}
css={theme => ({
width: theme.sizeUnit * 75,
})}
allowClear
/>
}
columnLabels={{
metric_name: t('Metric Key'),
verbose_name: t('Label'),
@@ -2343,10 +2336,11 @@ class DatasourceEditor extends PureComponent<
<DatasourceContainer data-test="datasource-editor">
{this.renderErrors()}
<Alert
css={theme => ({ marginBottom: theme.sizeUnit * 2 })}
css={theme => ({ marginBottom: theme.sizeUnit * 4 })}
type="warning"
message={
<>
{' '}
<strong>{t('Be careful.')} </strong>
{t(
'Changing these settings will affect all charts using this dataset, including charts owned by other people.',
@@ -2386,35 +2380,29 @@ class DatasourceEditor extends PureComponent<
children: (
<StyledTableTabWrapper>
{this.renderDefaultColumnSettings()}
<Flex
justify="space-between"
align="center"
css={theme => ({
marginBottom: theme.sizeUnit * 4,
})}
>
<Input.Search
placeholder={t('Search columns by name')}
value={this.state.columnSearchTerm}
onChange={e =>
this.setState({ columnSearchTerm: e.target.value })
}
css={theme => ({
width: theme.sizeUnit * 75,
})}
allowClear
/>
<Button
buttonSize="small"
buttonStyle="tertiary"
onClick={this.syncMetadata}
className="sync-from-source"
disabled={this.state.isEditMode}
>
<Icons.DatabaseOutlined iconSize="m" />
{t('Sync columns from source')}
</Button>
</Flex>
<ColumnButtonWrapper>
<StyledButtonWrapper>
<Button
buttonSize="small"
buttonStyle="tertiary"
onClick={this.syncMetadata}
className="sync-from-source"
disabled={this.state.isEditMode}
>
<Icons.DatabaseOutlined iconSize="m" />
{t('Sync columns from source')}
</Button>
</StyledButtonWrapper>
</ColumnButtonWrapper>
<Input.Search
placeholder={t('Search columns by name')}
value={this.state.columnSearchTerm}
onChange={e =>
this.setState({ columnSearchTerm: e.target.value })
}
style={{ marginBottom: 16, width: 300 }}
allowClear
/>
<ColumnCollectionTable
className="columns-table"
columns={this.state.databaseColumns}
@@ -2441,25 +2429,21 @@ class DatasourceEditor extends PureComponent<
children: (
<StyledTableTabWrapper>
{this.renderDefaultColumnSettings()}
<Input.Search
placeholder={t('Search calculated columns by name')}
value={this.state.calculatedColumnSearchTerm}
onChange={e =>
this.setState({
calculatedColumnSearchTerm: e.target.value,
})
}
style={{ marginBottom: 16, width: 300 }}
allowClear
/>
<ColumnCollectionTable
columns={this.state.calculatedColumns}
filterTerm={this.state.calculatedColumnSearchTerm}
filterFields={['column_name']}
toolbarExtra={
<Input.Search
placeholder={t('Search calculated columns by name')}
value={this.state.calculatedColumnSearchTerm}
onChange={e =>
this.setState({
calculatedColumnSearchTerm: e.target.value,
})
}
css={theme => ({
width: theme.sizeUnit * 75,
})}
allowClear
/>
}
onColumnsChange={calculatedColumns =>
this.setColumns({ calculatedColumns })
}
@@ -2542,7 +2526,7 @@ class DatasourceEditor extends PureComponent<
key: TABS_KEYS.SETTINGS,
label: t('Settings'),
children: (
<div css={{ overflow: 'hidden' }}>
<div style={{ overflowX: 'hidden' }}>
<Row gutter={16}>
<Col xs={24} md={12}>
<FormContainer>

View File

@@ -53,7 +53,6 @@ export interface CRUDCollectionProps {
emptyMessage?: ReactNode;
expandFieldset?: ReactNode;
extraButtons?: ReactNode;
toolbarExtra?: ReactNode;
itemGenerator?: () => any;
itemCellProps?: Record<
string,

View File

@@ -119,6 +119,7 @@ const StyledContent = styled.div<{
}>`
grid-column: 2;
grid-row: 2;
min-width: 0;
// @z-index-above-dashboard-header (100) + 1 = 101
${({ fullSizeChartId }) => fullSizeChartId && `z-index: 101;`}
`;