Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tests sticky header & responsive table #709

Merged
merged 2 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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