Skip to content

Commit

Permalink
Improve tests sticky header & responsive table #693
Browse files Browse the repository at this point in the history
  • Loading branch information
hupf authored Jun 25, 2024
1 parent faf3260 commit d383971
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 127 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[allowEmpty]="true"
[value]="valueId"
[disabled]="disabled"
[width]="width"
(valueChange)="onGradeChange($event)"
data-testid="grade-select"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
:host ::ng-deep select {
min-width: 13ch;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class GradeSelectComponent {
@Input() valueId: Option<number>; // the selected key from the options list
@Input() gradeId: Option<number>; // the id of the grade itself
@Input() disabled: boolean = false;
@Input() width: string = "13ch";

@Output() gradeIdSelected = new EventEmitter<{
id: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<th
*ngFor="let test of data.tests"
container="body"
class="grade h-100 test-info-desktop"
class="test-grade grade test-info-desktop"
[ngClass]="test.Id === selectedTest?.Id ? 'selected' : ''"
>
<bkd-test-table-header
Expand All @@ -29,7 +29,7 @@
<th
*ngFor="let test of data.tests"
container="body"
class="grade h-100 header-mobile test-info-mobile"
class="test-grade header-mobile test-info-mobile"
colspan="3"
[ngClass]="test.Id === selectedTest?.Id ? 'selected' : ''"
>
Expand All @@ -43,7 +43,7 @@
</th>
</tr>
<tr>
<th class="primary-column-width sticky" (click)="state.sortBy('FullName')">
<th class="sticky student-name" (click)="state.sortBy('FullName')">
<div class="d-flex">
<div class="column-title">
{{ "tests.student.name" | translate }}
Expand All @@ -54,7 +54,7 @@
</div>
</th>
<th
class="secondary-column-width sticky sticky-col-2 desktop"
class="sticky student-grade desktop"
(click)="state.sortBy('FinalGrade')"
[ngClass]="{ selected: selectedTest === undefined }"
>
Expand All @@ -68,7 +68,7 @@
</div>
</th>
<th
class="secondary-column-width border-end sticky sticky-col-3 desktop"
class="border-end sticky student-average desktop"
(click)="state.sortBy('TestsMean')"
>
<div class="d-flex">
Expand All @@ -83,7 +83,7 @@
<th
*ngFor="let test of data.tests"
container="body"
class="grade h-100"
class="test-grade"
[ngClass]="test.Id === selectedTest?.Id ? 'selected' : ''"
>
<div class="d-flex">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@
display: none;
}

@include media-breakpoint-up(sm) {
:host.sticky.shown {
display: table-header-group;
}
}

tr th {
border-top: none;
vertical-align: top;
Expand All @@ -30,11 +24,12 @@ tr th.test-info-desktop {
display: none !important;
}

.point-input-container {
width: 5em;
}
// Desktop view
@media (min-width: ($bkd-tests-mobile-breakpoint + 1)) {
:host.sticky.shown {
display: table-header-group;
}

@include media-breakpoint-up(sm) {
tr th.test-info-mobile {
display: none !important;
}
Expand All @@ -48,27 +43,6 @@ tr th.test-info-desktop {
padding-top: calc($spacer / 4);
padding-bottom: calc($spacer / 4);
border-top: initial;
min-width: 100px;
max-width: 100px;
}

tr th.grade {
min-width: 300px;
max-width: 300px;
}

th.sticky {
position: sticky;
left: 0;
background-color: $white;
}

th.sticky.sticky-col-2 {
left: 300px;
}

th.sticky.sticky-col-3 {
left: 447px;
}

// FIREFOX HACK: Sadly, the sticky cells inside the fixed positioned sticky
Expand All @@ -77,7 +51,7 @@ tr th.test-info-desktop {
// `fixed` and give them a fixed height via JavaScript (see
// TestEditGradesHeaderStickyDirective).
:host.sticky {
margin-left: 547px;
margin-left: var(--test-columns-offset);

th.sticky {
position: fixed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ export class TestEditGradesHeaderComponent {
}

getColumnWidths(): ReadonlyArray<ReadonlyArray<number>> {
return this.getColumns().map((columns) =>
return this.getRowsAndColumns().map((columns) =>
columns.map((column) => column.getBoundingClientRect().width),
);
}

setColumnWidths(columnWidths: ReadonlyArray<ReadonlyArray<number>>): void {
const rows = this.getColumns();
const rows = this.getRowsAndColumns();

if (
rows.length !== columnWidths.length ||
Expand All @@ -128,7 +128,7 @@ export class TestEditGradesHeaderComponent {
* FIREFOX HACK: See TestEditGradesHeaderStickyDirective
*/
getStickyColumnsHeights(): ReadonlyArray<ReadonlyArray<number>> {
return this.getColumns(".sticky").map((columns) =>
return this.getRowsAndColumns(".sticky").map((columns) =>
columns.map((column) => column.getBoundingClientRect().height),
);
}
Expand All @@ -139,7 +139,7 @@ export class TestEditGradesHeaderComponent {
setStickyColumnHeights(
columnHeights: ReadonlyArray<ReadonlyArray<number>>,
): void {
const rows = this.getColumns(".sticky");
const rows = this.getRowsAndColumns(".sticky");

if (
rows.length !== columnHeights.length ||
Expand All @@ -155,9 +155,19 @@ export class TestEditGradesHeaderComponent {
column.style.height = `${columnHeights[i][j]}px`;
}),
);

// Since the sticky elements will be `fixed`, set the max height on the row
// as well
this.getRows().forEach((row, i) => {
const rowHeight = columnHeights[i].reduce(
(acc, height) => Math.max(acc, height),
0,
);
row.style.height = `${rowHeight}px`;
});
}

private getColumns(
private getRowsAndColumns(
customColumnsSelector?: string,
): ReadonlyArray<ReadonlyArray<HTMLTableCellElement>> {
return this.getRows().map((row) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,115 @@
* Common table styles for the TestEditGradesComponent & the TestEditGradesHeaderComponent
*/

th.grade.selected,
td.grade.selected {
display: table-cell !important;
}
:host {
--student-name-column-width: 225px;
--student-grade-column-width: 147px;
--student-average-column-width: 100px;
--test-grade-column-width: 300px;

th.grade,
td.grade,
.desktop {
display: none !important;
--student-grade-column-offset: var(--student-name-column-width);
--student-average-column-offset: calc(
var(--student-grade-column-offset) + var(--student-grade-column-width)
);
--test-columns-offset: calc(
var(--student-average-column-offset) + var(--student-average-column-width)
);
}

.desktop.selected {
display: table-cell !important;
}
$student-name-width-breakpoint: 1000px;
$student-average-breakpoint: 1200px;

.mobile {
display: block !important;
@media (min-width: $student-name-width-breakpoint) {
:host {
// Student name column should be narrower below 1000px and wider above
--student-name-column-width: 275px;
}
}

th,
td {
padding: $spacer;
}

@include media-breakpoint-up(sm) {
th.grade,
td.grade,
.desktop {
display: table-cell !important;
td {
vertical-align: middle;
}

// Mobile view
@media (max-width: ($bkd-tests-mobile-breakpoint)) {
.desktop:not(.selected),
.student-grade:not(.selected),
.student-average,
.test-grade:not(.selected) {
display: none;
}

.student-name {
// Make sure the student name is going to ellipse also on mobile
max-width: var(--student-name-column-width);
}
}

// Desktop view
@media (min-width: ($bkd-tests-mobile-breakpoint + 1)) {
.mobile {
display: none !important;
display: none;
}

.primary-column-width {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
min-width: 300px;
max-width: 300px;
.student-name {
width: var(--student-name-column-width);
min-width: var(--student-name-column-width);
max-width: var(--student-name-column-width);
}

.student-grade {
width: var(--student-grade-column-width);
min-width: var(--student-grade-column-width);
max-width: var(--student-grade-column-width);
}

.student-average {
width: var(--student-average-column-width);
min-width: var(--student-average-column-width);
max-width: var(--student-average-column-width);
}

.secondary-column-width {
min-width: 100px;
max-width: 100px;
.test-grade {
min-width: var(--test-grade-column-width);
max-width: var(--test-grade-column-width);
}

th.sticky,
td.sticky {
position: sticky;
left: 0;
background-color: $white;
}

th.sticky.student-grade,
td.sticky.student-grade {
left: var(--student-grade-column-offset);
}

th.sticky.student-average,
td.sticky.student-average {
left: var(--student-average-column-offset);
}
}

@media (max-width: $student-average-breakpoint) {
// Since table filter cell uses colspan, we only reduce the average column's
// width to 1px to hide it (but not its border)
:host {
--student-average-column-width: 1px;
}
.student-average {
padding: 0;
overflow: hidden;
}
}
@media (min-width: ($student-average-breakpoint + 1)) {
.student-average-inline {
display: none;
}
}
Loading

0 comments on commit d383971

Please sign in to comment.