Skip to content

Enable header row display in tables#241

Merged
rossjones merged 11 commits into
mainfrom
table-header-display
Jun 18, 2025
Merged

Enable header row display in tables#241
rossjones merged 11 commits into
mainfrom
table-header-display

Conversation

@rossjones
Copy link
Copy Markdown
Contributor

@rossjones rossjones commented Jun 10, 2025

Allows tables to have a table header row (THEAD) that contains values from the following list:

  • No headers
  • Base26 representation of the column index
  • The selected header row from the source file
  • The target header titles from the domain object (target).

There are obvious contraints on their use (e.g. can't use target mode until mapping done, can't use source until a sheet is selected with a header range).

Comment thread lib/importer/src/session.js Outdated
@rossjones rossjones force-pushed the table-header-display branch from dd56a89 to 4035cf8 Compare June 10, 2025 16:48
A quick outline of how the header rows can be optionally shown whenever
a table is shown.
@rossjones rossjones changed the title Outline of interface for displaying headers in tables Enable header row display in tables Jun 13, 2025
for (var cell of selection.rightCells) { cell.node.classList.add(CellSelectedRightClassName); }
selection.focus.node.scrollIntoViewIfNeeded(false);

const headerRowCellCount = document.querySelectorAll('th[role="col"]').length
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible for there to be more than one table per page. So we should use table.querySelectorAll to scope it to just the table in question.

selection.focus.node.scrollIntoViewIfNeeded(false);

const headerRowCellCount = document.querySelectorAll('th[role="col"]').length
const headerRowOffset = headerRowCellCount > 0 ? 1 : 0;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to set this to the number of header rows instead of just assuming there is only one? I ask because in other contexts we have used multiple header rows to contain e.g. per-column guidance, and its conceivable that we might do that again.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the expected behaviour when a headerRange spans multiple rows? Presumably we don't know whether it is guidance or an extension of the header row text, or something else. I've fixed that use-case with the row count, but it isn't handled very elegantly elsewhere (e.g. we don't do anything with subsequent rows)

Comment thread lib/importer/nunjucks/importer/macros/range_selector.njk Outdated
Comment thread lib/importer/src/session.js Outdated
Comment on lines +101 to +103
for (var i = range[0]; i <= range[1]; i++) {
headers.push(base26.toBase26(i + 1))
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is where we want to be using the index of the source column rather than assuming that this just starts from zero?

Copy link
Copy Markdown
Contributor Author

@rossjones rossjones Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't iterating from 0, it's the first element in range, a two-element array with the start position and the end position. It's calculated in calculateHeaderRange . I've updated the range to be an object so that the iterations are for (var i = range.start; i <= range.end; i++) { instead.

Comment on lines +116 to +120
if (!Object.prototype.hasOwnProperty.call(session.headerRange, "start") ||
!Object.prototype.hasOwnProperty.call(session.headerRange, "end")) {
console.warn("HeaderRowDisplay: No header range available for source headers")
return null
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will the headerRange be if the user skips the selection step? And/or, what if there is no selection step in this journey? See also my comment in the ticket about what we should do there.

Comment thread lib/importer/src/session.js Outdated
Comment on lines +188 to +192
// With no specified headers, try and default to the first row.
const r = sheets_lib.GetRows(session)
if (r) {
return [0, r[0].length]
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it is really a default header selection. Should we be handling that elsewhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the default header selection is the entirety of the first row (where the length is constrained by the library to cells with data). This is the same logic, but we should probably formalise it somewhere

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think I was imagining making it so that headerRange was always a valid range, i.e. just the first row or null row but with "column A-Z" type label,s so that this function just collapsed down to line 180.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked this, and the default header row is selected if the user submits at "select a header" without a selection. This is just defensive and should probably belong in the backend rather than the frontend, but will move that in next refactor.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think I was imagining making it so that headerRange was always a valid range, i.e. just the first row or null row but with "column A-Z" type label,s so that this function just collapsed down to line 180.

Ah for some reason this comment didn't show up. Yeah, I think the null row makes the most sense as we don't want to add random text as column headings if the user doesn't choose anything. Will have to see where that breaks other logic and see if we can force the headers to have a row index that doesn't exist.

@rossjones rossjones merged commit c687edc into main Jun 18, 2025
5 checks passed
@rossjones rossjones deleted the table-header-display branch June 18, 2025 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants