Skip to content

Commit

Permalink
feat: add lesson flow template component with rich feature set
Browse files Browse the repository at this point in the history
  • Loading branch information
tkubica-edu committed Aug 20, 2024
1 parent 533aeed commit f246fc3
Show file tree
Hide file tree
Showing 22 changed files with 873 additions and 8 deletions.
8 changes: 4 additions & 4 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "10kb"
"maximumWarning": "10kb",
"maximumError": "200kb"
}
],
"fileReplacements": [
Expand Down Expand Up @@ -211,8 +211,8 @@
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "10kb"
"maximumWarning": "10kb",
"maximumError": "200kb"
}
],
"fileReplacements": [
Expand Down
2 changes: 1 addition & 1 deletion e2e-cypress/cypress.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"projectId": "wirlernenonline",
"testFiles": "**/*.feature",
"baseUrl": "http://localhost:4200",
"baseUrl": "http://localhost:8080",
"video": false,
"screenshotOnRunFailure": true,
"env": {
Expand Down
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"graphql": "^16.9.0",
"jquery": "^3.6.0",
"material-icons": "^1.12.1",
"milligram": "^1.4.1",
"ngx-colors": "^3.5.3",
"ngx-edu-sharing-api": "9999.0.1",
"ngx-edu-sharing-ui": "9999.0.2",
Expand Down
2 changes: 2 additions & 0 deletions src/app/wlo-search/core/view.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class ViewService {
this.route.url.subscribe((_segments) => {
const url = window.location.pathname;
this.isTemplate.next(url.includes('/template'));
this.isLessonFlow.next(url.includes('/lesson_flow'));
});
this.registerStoredItems();
this.registerBehaviorHooks();
Expand Down Expand Up @@ -183,4 +184,5 @@ export class ViewService {
}

isTemplate = new BehaviorSubject<boolean>(false);
isLessonFlow = new BehaviorSubject<boolean>(false);
}
36 changes: 36 additions & 0 deletions src/app/wlo-search/lesson-flow-pattern/activity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import uuid from 'uuid';

export class Activity {
id: string;
name: string;
description?: string;
time: number;
lecturerTask: string;
learnerTask: string;
socialForm: string;
learningFormat: string;
synchronization: string;
learningEnvironment?: string;
interactionPrerequisites?: string;
guidingMedium?: string;

constructor(
name: string,
time?: number,
lecturerTask?: string,
learnerTask?: string,
socialForm?: string,
learningFormat?: string,
synchronization?: string,
) {
this.id = uuid.v4();
this.name = name;
this.description = '';
this.time = time ?? 1;
this.lecturerTask = lecturerTask ?? '';
this.learnerTask = learnerTask ?? '';
this.socialForm = socialForm ?? '';
this.learningFormat = learningFormat ?? '';
this.synchronization = synchronization ?? '';
}
}
16 changes: 16 additions & 0 deletions src/app/wlo-search/lesson-flow-pattern/approach-step-matching.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import uuid from 'uuid';
import { Phase } from './phase';

export class ApproachStepMatching {
id: string;
approachId: string;
stepId: string;
phases: Phase[];

constructor(approachId: string, stepId: string, phases?: Phase[]) {
this.id = uuid.v4();
this.approachId = approachId;
this.stepId = stepId;
this.phases = phases ?? [];
}
}
14 changes: 14 additions & 0 deletions src/app/wlo-search/lesson-flow-pattern/didactic-approach.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import uuid from 'uuid';
import { Phase } from './phase';

export class DidacticApproach {
id: string;
name: string;
phases: Phase[];

constructor(name: string, phases?: Phase[]) {
this.id = uuid.v4();
this.name = name;
this.phases = phases ?? [];
}
}
11 changes: 11 additions & 0 deletions src/app/wlo-search/lesson-flow-pattern/generic-step.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import uuid from 'uuid';

export class GenericStep {
id: string;
name: string;

constructor(name: string) {
this.id = uuid.v4();
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<div class="lesson-flow-template">
<h2>Workshop 3: Maschinenlesbare Unterrichtsmethoden</h2>

<p>Bitte wählen Sie zuerst Ihre Favoriten-Katze aus, bevor Sie fortfahren.</p>

<div class="didactic-approach-form-field" style="text-align: center">
<label id="choose-cat" style="font-size: 15px; margin-bottom: 10px">Wähle deine Katze</label>
<mat-radio-group aria-labelledby="choose-cat" [(ngModel)]="favoriteCat">
<mat-radio-button class="example-radio-button" [value]="image" *ngFor="let image of images">
<img [src]="image" [alt]="image" height="200" />
</mat-radio-button>
</mat-radio-group>
</div>

<hr />

<ng-container *ngIf="favoriteCat">
<p>
Bitte wählen Sie nun den zugrundeliegenden didaktischen Ansatz aus.
<br />
Anschließend bekommen Sie die Möglichkeit, darauf aufbauend ein Template Ihrer individuellen
Unterrichtsmethode zu entfernen.
<br />
Alternativ können Sie auch ein
<a (click)="loadTemplate()" style="cursor: pointer; text-decoration: underline"
>vorhandenes Template</a
>
laden.
</p>

<mat-form-field class="didactic-approach-form-field">
<mat-label>Didaktischer Ansatz</mat-label>
<mat-select [(value)]="selectedApproachId">
<mat-option [value]="approach.value" *ngFor="let approach of approachesOptions">
{{ approach.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>

<mat-form-field class="didactic-approach-form-field">
<mat-label> Geben Sie Ihrem Template einen Namen </mat-label>
<input [(ngModel)]="templateName" type="text" matInput />
</mat-form-field>

<table *ngIf="selectedApproachId" style="background: #fff">
<thead>
<tr>
<th class="text-center border-right" style="width: 40px">Schritt</th>
<th class="text-center border-right" style="width: 150px">Phase</th>
<th class="w-175px text-center border-right">Methode</th>
<th class="text-center border-right" style="width: 275px">Aktivitäten</th>
<th class="text-center border-right" style="width: 100px">
Zeit
<span *ngIf="totalTime > 0">({{ totalTime }} min)</span>
</th>
<th class="text-center border-right">Lehrende</th>
<th class="text-center border-right">Lernende</th>
<th class="text-center border-right">Sozialform</th>
<th class="text-center border-right">Lernformat</th>
<th class="text-center">Synchronizität</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let step of steps">
<tr
*ngFor="
let phase of approachesStepMatchingMap.get(selectedApproachId + separator + step.id)
?.phases;
let phaseIndex = index
"
>
<td
class="font-bold vertical-text text-center bg-gray"
[rowSpan]="
approachesStepMatchingMap.get(selectedApproachId + separator + step.id)?.phases
.length
"
*ngIf="phaseIndex === 0"
>
{{ step.name }}
</td>
<td>
<div class="min-height display-flex flex-center">
{{ phase.name }}
</div>
</td>
<!-- dirty hack due to time constrains -->
<!-- found here: https://stackoverflow.com/a/72065713 -->
<td style="position: relative">
<textarea
[(ngModel)]="phase.method.name"
style="
position: absolute;
top: 1rem;
left: 1.2rem;
width: calc(100% - 2.4rem);
height: calc(100% - 2rem);
min-height: inherit;
"
></textarea>
</td>
<!-- activities -->
<td>
<div
style="display: flex; justify-content: start"
class="text-center"
*ngFor="let activity of phase.method.activities; let activityIndex = index"
>
<input
[(ngModel)]="activity.name"
type="text"
style="display: inline-block; flex-grow: 3; margin-bottom: 0"
[class.input-margin-bottom]="activityIndex !== phase.method.activities.length - 1"
/>
<button
*ngIf="activityIndex === phase.method.activities.length - 1; else removeButton"
class="button button-outline"
style="
margin-left: 5px;
margin-bottom: 0;
padding: 0;
min-width: 38px;
border-radius: 0.4rem;
"
(click)="addActivity(phase.method.activities)"
>
+
</button>
<ng-template #removeButton>
<button
class="button button-outline"
style="
margin-left: 5px;
margin-bottom: 0;
padding: 0;
min-width: 38px;
border-radius: 0.4rem;
"
(click)="removeActivity(phase.method.activities, activityIndex)"
>
-
</button>
</ng-template>
</div>
</td>
<td>
<div
style="display: flex; justify-content: start"
class="text-center"
*ngFor="let activity of phase.method.activities; let activityIndex = index"
>
<input
[(ngModel)]="activity.time"
type="number"
min="1"
max="360"
style="display: inline-block; flex-grow: 3; margin-bottom: 0"
[class.input-margin-bottom]="activityIndex !== phase.method.activities.length - 1"
/>
<span style="line-height: 38px; margin-left: 5px">min</span>
</div>
</td>
<!-- remaining fields -->
<td *ngFor="let activityItem of activityItems">
<div
style="display: flex; justify-content: start"
class="text-center"
*ngFor="let activity of phase.method.activities; let activityIndex = index"
>
<input
[(ngModel)]="activity[activityItem]"
type="text"
style="display: inline-block; flex-grow: 3; margin-bottom: 0"
[class.input-margin-bottom]="activityIndex !== phase.method.activities.length - 1"
/>
</div>
</td>
</tr>
</ng-container>
</tbody>
</table>

<button class="button" (click)="exportJSON()">Export (als JSON)</button>

<button class="button button-outline" (click)="showDebug = !showDebug">
{{ showDebug ? 'Debug-Ansicht ausblenden' : 'Debug-Ansicht einblenden' }}
</button>

<div *ngIf="showDebug">
<h3>Debug-Ansicht:</h3>
<pre>
<ng-container *ngFor="let step of steps;">
{{ approachesStepMatchingMap.get(selectedApproachId + separator + step.id)?.phases | json }}
</ng-container>
</pre>
</div>
</ng-container>
</div>
Loading

0 comments on commit f246fc3

Please sign in to comment.