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

fix(*): Improved layout of note details in mobile view #1290

Merged
merged 18 commits into from
Jul 4, 2022
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
5 changes: 4 additions & 1 deletion e2e/integration/RecordingAttendanceOfChild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ describe("Scenario: Recording attendance of a child - E2E test", function () {
cy.contains("mat-card", "School Class")
.eq(0)
.click({ scrollBehavior: "center" });
cy.get(".mat-body-1").invoke("text").as("childName");
cy.get(".child-block > span > span ")
.first()
.invoke("text")
.as("childName");
cy.get(".group-select-option").contains("Present").click();
cy.get('[fxflex=""] > .ng-star-inserted > .mat-focus-indicator').click();
cy.contains("button", "Save").click();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<div>
<span class="indicator {{ value.style }}">&nbsp;</span>
<mat-form-field class="compact-form-field">
<mat-select
[(ngModel)]="value"
(ngModelChange)="valueChange.emit(value)"
[disabled]="disabled"
[compareWith]="compareFn"
>
<mat-option *appConfigurableEnum="let s of statusID" [value]="s">
<span class="indicator {{ s.style }}">&nbsp;</span>
{{ s.label }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-form-field class="compact-form-field">
<div [class]="value.style" class="indicator indicator__prefix" matPrefix></div>
<mat-select
[(ngModel)]="value"
(ngModelChange)="valueChange.emit(value)"
[disabled]="disabled"
[compareWith]="compareFn"
>
<mat-option *appConfigurableEnum="let s of statusID" [value]="s">
<span class="indicator indicator__option" [class]="s.style"></span>{{ s.label }}
</mat-option>
</mat-select>
</mat-form-field>
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
// The indicator is a round, colored shape with a small margin on the right
// it is used as prefix in the form field and for the individual options
.indicator {
width: 14px;
height: 14px;
display: inline-block;
vertical-align: text-top;
width: 1em;
height: 1em;
border-radius: 50%;

margin-right: 8px;
margin-right: 0.5em;

// when the indicator is used as prefix in a form field
// it should be center-aligned with the content, but is baseline-aligned
// without this small margin
&__prefix {
margin-bottom: -0.15em;
}

// when the indicator is used inside the option-field it has `display: inline`
// which causes the field not to draw correctly
&__option {
display: inline-block;
vertical-align: middle;
}
}

.compact-form-field {
margin-bottom: -10px;
margin-top: -10px;
mat-form-field {
// don't allow this to overflow
max-width: 100%;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
(mouseleave)="hideTooltip()"
(click)="showDetailsPage()"
[ngClass]="{ inactive: !entity.isActive }"
class="truncate-text"
class="truncate-text container"
>
<img [src]="entity.photo?.photo?.value" class="child-pic" alt=""/>
<span class="mat-body-1">{{ entity?.name }}</span>
<span style="font-size: x-small" *ngIf="entity?.projectNumber"
> ({{ entity?.projectNumber }})</span
>
<span class="font-size-rel">{{ entity?.name }}</span>
<span class="subnote" *ngIf="entity?.projectNumber"> ({{ entity?.projectNumber }})</span>
</span>

<div style="position: absolute" *ngIf="tooltipVisible">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,25 @@
.inactive {
color: grey;
}

.container {
display: flex;
align-items: center;
font-size: 1em;
}

.font-size-rel {
font-size: 1em;
margin-right: 3px;
font-weight: 500;
color: #262626;
}

.subnote {
font-size: 0.7em;
position: relative;
top: 0.2em;
color: #5e5e5e;
}


Original file line number Diff line number Diff line change
@@ -1,31 +1,74 @@
<div fxLayout="col" fxLayoutGap="4px" fxLayoutAlign="start baseline">
<div class="actions" fxFlex="40px" *ngIf="!disabled">
<button mat-icon-button (click)="remove.emit()">
<fa-icon icon="times"></fa-icon>
</button>
</div>
<!-- If feasible, this whole setup should be replaced with a more simple setup that
automatically adapts to the screen size without having to rely on two different layout techniques for
small and big screens.
-->
<div *ngIf="!mobile">
<!-- Desktop view: display the information as table -->
<table class="table">
<tr *ngFor="let childId of entity.children">
<td>
<button mat-icon-button>
<fa-icon *ngIf="!disabled" icon="trash" (click)="remove.emit(childId)"></fa-icon>
</button>
</td>
<td><app-child-block [entityId]="childId"></app-child-block></td>
<td>
<app-attendance-status-select
[(value)]="entity.getAttendance(childId).status"
(valueChange)="change.emit(childId)"
[disabled]="disabled"
>
</app-attendance-status-select>
</td>
<td class="full-width">
<mat-form-field class="adjust-top">
<input
matInput
i18n-placeholder
placeholder="Remarks"
name="remarks"
type="text"
[(ngModel)]="entity.getAttendance(childId).remarks"
[disabled]="disabled"
(input)="change.emit(childId)"
/>
</mat-form-field>
</td>
</tr>
</table>
</div>

<div fxFlex="250px">
<app-attendance-status-select
[(value)]="attendance.status"
(valueChange)="change.emit(attendance)"
[disabled]="disabled"
>
</app-attendance-status-select>
</div>
<div *ngIf="mobile" class="attendance-blocks">
<!-- Mobile view / smaller screen: display the information using a flex-layout -->
<div *ngFor="let childId of entity.children" class="attendance-item">
<div class="attendance-item--header">
<app-child-block [entityId]="childId"></app-child-block>

<app-child-block [entityId]="childId" fxFlex> </app-child-block>
<button mat-icon-button>
<fa-icon *ngIf="!disabled" icon="trash" (click)="remove.emit(childId)"></fa-icon>
</button>
</div>

<mat-form-field class="dense-form-field" fxFlex>
<input
matInput
i18n-placeholder
placeholder="Remarks"
name="remarks"
type="text"
[(ngModel)]="attendance.remarks"
[disabled]="disabled"
(input)="change.emit(attendance)"
/>
</mat-form-field>
<div class="attendance-item--content">
<app-attendance-status-select
[(value)]="entity.getAttendance(childId).status"
(valueChange)="change.emit(childId)"
[disabled]="disabled"
>
</app-attendance-status-select>

<mat-form-field>
<input
matInput
i18n-placeholder
placeholder="Remarks"
name="remarks"
type="text"
[(ngModel)]="entity.getAttendance(childId).remarks"
(input)="change.emit(childId)"
[disabled]="disabled"
/>
</mat-form-field>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,86 @@
.hide-remarks {
display: none;
$border: 1px solid lightgray;

.table {

border-spacing: 0 4px;

> tr > td {

padding-left: 0.5em;
padding-right: 0.5em;

&:first-child {
border-radius: 4px 0 0 4px;
border-left: $border;
border-top: $border;
border-bottom: $border;
}

&:last-child {
border-radius: 0 4px 4px 0;
border-right: $border;
border-top: $border;
border-bottom: $border;
}

&:not(:first-child):not(:last-child) {
border-top: $border;
border-bottom: $border;
}
}
}

.adjust-top {
position: relative;
top: 4px;
padding-right: 1em;
width: 100%;
}

.full-width {
width: 100%;
}

.attendance-item {
/* Align the items in one column */
display: flex;
flex-direction: column;
width: 100%;
gap: 1em;

border: $border;

padding: 1em;
box-sizing: border-box;

&--header {
/* Header: Display the child name on the right, the delete item on the left */
align-self: center;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
}

/* Content: Display all items as a column; allow the items to wrap to the next line */
&--content {
display: flex;
flex-wrap: wrap;
width: 100%;
gap: 1em;
align-items: baseline;

/* This field should be the biggest, allow it to grow */
> mat-form-field {
flex-grow: 1;
}
}
}

.dense-form-field {
margin-top: -1em;
.attendance-blocks {
display: flex;
align-items: center;
flex-direction: column;
gap: 0.5em;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { ChildMeetingNoteAttendanceComponent } from "./child-meeting-note-attendance.component";
import { EventAttendance } from "../../../attendance/model/event-attendance";
import { EventNote } from "../../../attendance/model/event-note";

describe("ChildMeetingAttendanceComponent", () => {
let component: ChildMeetingNoteAttendanceComponent;

beforeEach(() => {
component = new ChildMeetingNoteAttendanceComponent();
component.childId = "child1";
component.attendance = new EventAttendance();
component.entity = EventNote.create(new Date());
});

it("should create", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { EventAttendance } from "../../../attendance/model/event-attendance";
import { Note } from "../../model/note";
import { FormGroup } from "@angular/forms";

/**
* Display a single participant's attendance status in a compact row.
Expand All @@ -10,9 +12,9 @@ import { EventAttendance } from "../../../attendance/model/event-attendance";
styleUrls: ["./child-meeting-note-attendance.component.scss"],
})
export class ChildMeetingNoteAttendanceComponent {
@Input() childId: string;
@Input() mobile = false;
@Input() entity: Note;
@Input() disabled: boolean = false;
@Input() attendance: EventAttendance;
@Output() change = new EventEmitter();
@Output() remove = new EventEmitter();
@Output() change = new EventEmitter<string>();
@Output() remove = new EventEmitter<string>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ <h1>{{ entity.date | date }}: {{ entity.subject }}</h1>

<!-- Participants and groups -->
<app-entity-select
style="margin-top: 12px"
class="form-section"
entityType="Child"
[(selection)]="entity.children"
(selectionChange)="entityForm.form.markAsDirty()"
Expand All @@ -185,19 +185,19 @@ <h1>{{ entity.date | date }}: {{ entity.subject }}</h1>
</mat-option>
</app-entity-select>


<div *ngIf="entity.category?.isMeeting">
<app-child-meeting-note-attendance
*ngFor="let childId of entity.children"
[childId]="childId"
[attendance]="entity.getAttendance(childId)"
(change)="entityForm.form.markAsDirty()"
(remove)="entity.removeChild(childId); entityForm.form.markAsDirty()"
[mobile]="mobile"
[entity]="entity"
[disabled]="formDialogWrapper.readonly"
>
</app-child-meeting-note-attendance>
(change)="entityForm.form.markAsDirty()"
(remove)="entity.removeChild($event); entityForm.form.markAsDirty()"
></app-child-meeting-note-attendance>
</div>

<app-entity-select
class="form-section"
entityType="School"
[(selection)]="entity.schools"
(selectionChange)="entityForm.form.markAsDirty()"
Expand All @@ -208,5 +208,6 @@ <h1>{{ entity.date | date }}: {{ entity.subject }}</h1>
placeholder="Add group ..."
>
</app-entity-select>

</form>
</app-form-dialog-wrapper>
Loading