finos / vuu

Vuu - an open source view server and html 5 based UI system
https://vuu.finos.org
Apache License 2.0
44 stars 27 forks source link

As a user, I would like to control the column layout strategy for the Vuu Table #639

Open heswell opened 1 year ago

heswell commented 1 year ago

The ColumnDescriptor interface describes the Table configuration options that can be specified at the column level. It looks like this.

export interface ColumnDescriptor {
  aggregate?: VuuAggType;
  align?: "left" | "right";
  className?: string;
  editable?: boolean;
  expression?: string;
  flex?: number;
  heading?: string[];
  hidden?: boolean;
  isSystemColumn?: boolean;
  label?: string;
  locked?: boolean;
  minWidth?: number;
  name: string;
  pin?: PinLocation;
  resizeable?: boolean;
  serverDataType?: VuuColumnDataType;
  sortable?: boolean;
  type?: ColumnType;
  width?: number;
}

Of particular interest are the hidden,minWidth, width and flex attributes. When a Table is rendered, it first determines the width available. It then processes the column descriptors and renders each column, using CSS to assign each a width, based on a number of factors. An initial width is assigned to each column, based on configuration values assigned to the column descriptor , with defaults where no such values are provided. It will be rare that the initial width values assigned to columns sum to exactly the available width of the Table. This raises one of two questions

This choice should be offered to the user as a Table configuration option, that we might call columnLayoutStrategy or columnLayout

I would suggest initial values might be

With the following behaviours

static

simply apply the sizes determined by the column configuration (see below). If these sum to less than the available width, leave the extra space empty. If these sum to more than the available width, show a horizontal scrollbar.

fit-end

a common approach when the columns do not fill all the available width - just assign surplus width to the last column.

fit

try and fill the available space where practical. If there is surplus available space, assign it to one or more of the columns. This is where the flex attribute on columns comes in. If user has specified a flex value on any columns, assign surplus space to those columns where flex > 0. Use the flex values to determine the proportion of surplus space to assign to each column. If no column has flex specified, assign space equally across all columns (OR do we assign extra space to final column ? should this be a separate config option ?)

auto

apply default strategy. Initial suggestion would be as follows:

In all cases minWidth must be respected. Currently, there is a default width that is applied by Table when user does not configure a column width, but there is no default min width - we should introduce this.

So, when we assign a width to each column, we start with the width assigned by user, falling back to default, if not provided. Then we apply our column layout strategy to account for the available Table width, which may involve increasing or decreasing the initially assigned value. We must NOT decrease this value beyond the minimum. (We may want to add a maxWidth attribute too).

All of the above must be adjusted if and when user manually resizes a column. Including when we are re-opening a UI where the user has previously sized a column manually - values assigned as a consequence of manual user adjustment should be afforded highest priority.

Resize behaviour that takes column layout strategy into account will be described in a separate ticket.

heswell commented 1 year ago

logic for Fit layout

Fit layout tries to make the columns exactly fit the available space. It may apply adjustments to individual column widths to achieve this. It may not be possible to achieve if the space available is simple too little.

Attributes from the ColumnDescriptor that we will need to take into account

A general principal we should abide by where possible - if user has specified an explicit width for one or more columns, we should strive to respect that width and not adjust it. If user has specified explicit width(s) for some but not all columns, we should target any adjustments to the columns with no explicit width. If the user has specified an explicit width for all columns, (but has also specified a Fit layout) then we can assume it's ok to adjust the widths. We will give priority to the flex attribute, where present, as it is a clear instruction by user to allow adjustment to such columns.

First we calculate the combined width of all columns (using the defaultWidth where no width has been explicitly supplied by user)

Scenario 1 - columns do not fill all the available width of table - we have surplus space

1) make an initial pass through columns using variables to track:

Subsequent logic will depend on these criteria, which can be handled in this order:

1.1) Some or all columns have a flex value

assign the extra space to those columns with flex value. The flex value should determine how much of the surplus space each column gets. eg

1.2) All columns have an explicit width value

divide extra space evenly across all columns

1.3) Some columns have an explicit width value, some do not

divide extra space evenly across just those columns with no explicit width ( i.e with the default width)

Note: in all of the above, we should also respect maxWidth, so we never exceed that for any given column. It may be specified per column (by user) or at the table level.

Scenario 2 - combined width of columns is greater than width of table - we don't have enough space.

1) Calculate the combined minimum width of all columns using minWidth (use the minWidth of each column specified by user or the default minWidth) If the combined minWidth of all columns is still greater than the availableWidth then nothing we do can make all the columns fit within the viewport - fallback to static layout.

Otherwise apply the same logic as for Scenario 1, but in reverse, i.e reduce the column widths rather than increasing them but using the same logic