From fc40abac9e42cabec9573ebc8b1f28c571dde10a Mon Sep 17 00:00:00 2001 From: Rares Mardare Date: Fri, 19 Jan 2024 13:25:18 +0200 Subject: [PATCH] Improved alert group table columns layout calculation (#3712) # What this PR does Improves calculations across columns width ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/3681 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- CHANGELOG.md | 4 ++ .../src/pages/incidents/Incidents.tsx | 55 +++++++++++++++---- grafana-plugin/src/utils/types.ts | 1 + 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec09838..a37d65c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Improved alert group table columns spacing ([#3712](https://github.com/grafana/oncall/pull/3712)) + ## v1.3.90 (2024-01-18) ### Changed diff --git a/grafana-plugin/src/pages/incidents/Incidents.tsx b/grafana-plugin/src/pages/incidents/Incidents.tsx index 6c6c80d2..89d74697 100644 --- a/grafana-plugin/src/pages/incidents/Incidents.tsx +++ b/grafana-plugin/src/pages/incidents/Incidents.tsx @@ -110,6 +110,8 @@ class Incidents extends React.Component store.alertGroupStore.incidentsCursor = cursorQuery || undefined; + this.rootElRef = React.createRef(); + this.state = { selectedIncidentIds: [], affectedRows: {}, @@ -123,6 +125,7 @@ class Incidents extends React.Component }; } + private rootElRef: React.RefObject; private pollingIntervalId: NodeJS.Timer = undefined; componentDidMount() { @@ -531,7 +534,7 @@ class Incidents extends React.Component const tableColumns = this.getTableColumns(); return ( -
+
{this.renderBulkActions()} title: 'ID', key: 'id', render: this.renderId, - width: isHorizontalScrolling ? '100px' : '10%', + width: 150, }, Status: { title: 'Status', key: 'time', render: this.renderStatus, - width: '140px', + width: 140, }, Alerts: { title: 'Alerts', key: 'alerts', render: this.renderAlertsCounter, - width: '100px', + width: 100, }, Integration: { title: 'Integration', key: 'integration', render: this.renderSource, - width: isHorizontalScrolling ? undefined : '15%', + grow: 1.7, }, Title: { title: 'Title', key: 'title', render: this.renderTitle, - width: isHorizontalScrolling ? undefined : '35%', className: 'u-max-width-1000', + grow: 3.5, }, Created: { title: 'Created', key: 'created', render: this.renderStartedAt, - width: isHorizontalScrolling ? undefined : '10%', + grow: 1, }, Team: { title: 'Team', key: 'team', render: (item: AlertType) => this.renderTeam(item, store.grafanaTeamStore.items), - width: isHorizontalScrolling ? undefined : '10%', + grow: 1, }, Users: { title: 'Users', key: 'users', render: renderRelatedUsers, - width: isHorizontalScrolling ? undefined : '15%', + grow: 1.5, }, }; @@ -825,15 +828,45 @@ class Incidents extends React.Component return Object.keys(columnMapping).map((col) => columnMapping[col]); } + const visibleColumns = store.alertGroupStore.columns.filter((col) => col.isVisible); + const visibleColumnsWidth = visibleColumns + .filter((col) => col.type === AlertGroupColumnType.DEFAULT) + .reduce((total, current) => { + const column = columnMapping[current.name]; + return typeof column.width === 'number' ? total + column.width : total; + }, 0); + + const columnsGrowSum = visibleColumns.reduce((total, current) => { + const column = columnMapping[current.name]; + return total + (column?.grow || 1); + }, 0); + + // we set the total width based on the number of columns in the table (200xColCount) + const totalContainerWidth = isHorizontalScrolling + ? 200 * visibleColumns.length + : this.rootElRef?.current?.offsetWidth; + const remainingContainerWidth = totalContainerWidth - visibleColumnsWidth; + const mappedColumns: TableColumn[] = store.alertGroupStore.columns .filter((col) => col.isVisible) .map((column: AlertGroupColumn): TableColumn => { + // each column has a grow property, simillar to flex-grow + // and that dictates how much space it should take relative to the other columns + // we also keep in mind the remaining fixed width columns + // (such as Status/Alerts which always take up the same amount of space) + const grow = columnMapping[column.name]?.grow || 1; + const growWidth = (grow / columnsGrowSum) * remainingContainerWidth; + const columnWidth = columnMapping[column.name]?.width || growWidth; + if (column.type === AlertGroupColumnType.DEFAULT && columnMapping[column.name]) { - return columnMapping[column.name]; + return { + ...columnMapping[column.name], + width: columnWidth, + }; } return { - width: isHorizontalScrolling ? '200px' : '10%', + width: columnWidth, title: capitalize(column.name), key: column.id, render: (item: AlertType) => this.renderCustomColumn(column, item), diff --git a/grafana-plugin/src/utils/types.ts b/grafana-plugin/src/utils/types.ts index 1a13a546..164644a7 100644 --- a/grafana-plugin/src/utils/types.ts +++ b/grafana-plugin/src/utils/types.ts @@ -6,4 +6,5 @@ export interface TableColumn { key: string; render: (value: any, record: any, index: number) => React.ReactNode | RenderedCell; className?: string; + grow?: number; }