Skip to content
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,566 changes: 2,341 additions & 3,225 deletions package-lock.json

Large diffs are not rendered by default.

37 changes: 21 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "knowledgebuilder",
"version": "1.8.430",
"version": "1.8.433",
"license": "MIT",
"description": "An AI-powered web-based Learning app for English, Chinese, and Knowledge Bank part.",
"author": {
Expand All @@ -23,16 +23,16 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^21.2.17",
"@angular/animations": "21.2.21",
"@angular/cdk": "^21.2.14",
"@angular/common": "^21.2.17",
"@angular/compiler": "^21.2.17",
"@angular/core": "^21.2.17",
"@angular/forms": "^21.2.17",
"@angular/common": "21.2.21",
"@angular/compiler": "21.2.21",
"@angular/core": "21.2.21",
"@angular/forms": "21.2.21",
"@angular/material": "^21.2.14",
"@angular/material-date-fns-adapter": "^21.2.14",
"@angular/platform-browser": "^21.2.17",
"@angular/router": "^21.2.17",
"@angular/platform-browser": "21.2.21",
"@angular/router": "21.2.21",
"@jsverse/transloco": "^8.2.1",
"@types/dompurify": "^3.0.5",
"angular-auth-oidc-client": "^21.0.2",
Expand All @@ -51,10 +51,10 @@
"@angular-eslint/builder": "^21.1.0",
"@angular-eslint/eslint-plugin": "^21.1.0",
"@angular-eslint/eslint-plugin-template": "^21.1.0",
"@angular/build": "^21.2.17",
"@angular/cli": "^21.2.17",
"@angular/compiler-cli": "^21.2.17",
"@angular/platform-browser": "^21.2.17",
"@angular/build": "21.2.21",
"@angular/cli": "21.2.21",
"@angular/compiler-cli": "21.2.21",
"@angular/platform-browser": "21.2.21",
"@types/howler": "^2.2.11",
"@types/katex": "^0.16.7",
"@types/marked": "^5.0.2",
Expand All @@ -72,15 +72,20 @@
},
"overrides": {
"@babel/core": "^7.29.7",
"fast-uri": "^3.1.3",
"fast-uri": "^3.1.5",
"flatted": "^3.4.2",
"hono": "^4.12.28",
"js-yaml": "^4.3.0",
"postcss": "^8.5.16",
"js-yaml": "^4.3.1",
"nanoid": "^3.3.18",
"postcss": "^8.5.18",
"rollup": "^4.62.2",
"sucrase": {
"glob": "^10.5.0"
},
"yaml": "^2.9.0"
"yaml": "^2.9.0",
"undici": "^7.29.0",
"ip-address": "^10.3.1",
"brace-expansion@^1.0.0": "^1.1.16",
"brace-expansion@^2.0.0": "^2.1.4"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ <h2 mat-dialog-title>{{ t('chineseExercises.optionsOfReciting') }}</h2>
</mat-form-field>

<mat-form-field class="control-full-width">
<mat-label>{{ t('chineseExercises.count') }}</mat-label>
<mat-label>{{ t('count') }}</mat-label>
<input matInput type="number" [(ngModel)]="countOfItems" name="reciteCount" [disabled]="data.disableCount">
<span matSuffix>{{data.reciteContentCount}}</span>
</mat-form-field>

<div class="control-full-width">
<mat-checkbox [(ngModel)]="printEntryDate" name="reciteEntryDate"> {{ t('chineseExercises.printEntryDate') }} </mat-checkbox>
<mat-checkbox [(ngModel)]="printEntryDate" name="reciteEntryDate"> {{ t('printEntryDate') }} </mat-checkbox>
</div>

<div class="control-full-width">
Expand All @@ -34,7 +34,7 @@ <h2 mat-dialog-title>{{ t('chineseExercises.optionsOfReciting') }}</h2>
</div>

<mat-form-field class="control-full-width">
<mat-label>{{ t('chineseExercises.execDate') }}</mat-label>
<mat-label>{{ t('execDate') }}</mat-label>
<input matInput [(ngModel)]="execDate" name="reciteExecDate" [matDatepicker]="picker" [disabled]="selectedExecDateModel() !== 2">
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div *transloco="let t">
<h2 mat-dialog-title>{{ t('chineseExercises.selectByRating') }}</h2>
<h2 mat-dialog-title>{{ t('selectByRating') }}</h2>
<mat-dialog-content class="control-full-width">
<mat-form-field class="control-full-width">
<mat-label>{{ t('selection.ratingOperator') }}</mat-label>
Expand Down
28 changes: 14 additions & 14 deletions src/app/pages/chinese-exercises/chinese-exercises.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@ <h5>{{ t('chineseExercises.title') }}</h5>
</span>
<span class="toolbar-spacer"></span>
<mat-form-field class="page-toolbar-item">
<mat-label>{{ t('chineseExercises.files') }}</mat-label>
<mat-label>{{ t('files') }}</mat-label>
<mat-select matNativeControl [(value)]="selectedFile" (selectionChange)="onFileSelectionChanged($event)"
[disabled]="isLoadingContents" [placeholder]="isLoadingContents ? t('loading') : t('chineseExercises.files')">
[disabled]="isLoadingContents" [placeholder]="isLoadingContents ? t('loading') : t('files')">
@if (isLoadingContents) {
<mat-option disabled>
<mat-spinner diameter="18"></mat-spinner>
{{ t('loading') }}
</mat-option>
}
<mat-option value="">{{ t('chineseExercises.none') }}</mat-option>
<mat-option value="">{{ t('none') }}</mat-option>
@for (file of allFiles; track file.id ) {
<mat-option [value]="file">{{file.nameChinese}}</mat-option>
}
</mat-select>
</mat-form-field>
<span class="toolbar-item-count"><small>{{ t('chineseExercises.items') }}: {{reciteContentCount}}</small></span>
<span class="toolbar-item-count"><small>{{ t('items') }}: {{reciteContentCount}}</small></span>
<section style="padding-left: 8px;">
<div class="example-button-container">
<button mat-fab [matMenuTriggerFor]="selectMenu" [matTooltip]="t('chineseExercises.select')" [disabled]="!selectedFile">
<button mat-fab [matMenuTriggerFor]="selectMenu" [matTooltip]="t('select')" [disabled]="!selectedFile">
<mat-icon>query_builder</mat-icon>
</button>
</div>
</section>
<mat-menu #selectMenu="matMenu">
<button mat-menu-item (click)="onSelectByRating()">{{ t('chineseExercises.selectByRating') }}</button>
<button mat-menu-item (click)="onSelectByRating()">{{ t('selectByRating') }}</button>
</mat-menu>
<section style="padding-left: 8px;">
<div class="example-button-container">
Expand All @@ -47,14 +47,14 @@ <h5>{{ t('chineseExercises.title') }}</h5>

<div class="container">
<mat-form-field class="w-full">
<mat-label>{{ t('chineseExercises.filter') }}</mat-label>
<mat-label>{{ t('filter') }}</mat-label>
<input matInput (keyup)="applyFilter($event)" #input>
</mat-form-field>

<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8 w-full">
<!-- ID Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by ID"> {{ t('chineseExercises.id') }} </th>
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by ID"> {{ t('id') }} </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
Expand All @@ -78,7 +78,7 @@ <h5>{{ t('chineseExercises.title') }}</h5>

<!-- Subject Column -->
<ng-container matColumnDef="subject">
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by subject"> {{ t('chineseExercises.subject') }} </th>
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by subject"> {{ t('subject') }} </th>
<td mat-cell *matCellDef="let element"> {{element.subject}} </td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
Expand All @@ -92,25 +92,25 @@ <h5>{{ t('chineseExercises.title') }}</h5>

<!-- Content Column -->
<ng-container matColumnDef="content">
<th mat-header-cell *matHeaderCellDef> {{ t('chineseExercises.content') }} </th>
<th mat-header-cell *matHeaderCellDef> {{ t('content') }} </th>
<td mat-cell *matCellDef="let element">
<mat-form-field class="control-full-width">
<textarea matNativeControl readonly [ngModel]="getDisplayContentText(element)"></textarea>
</mat-form-field>
</td>
<td mat-footer-cell *matFooterCellDef> {{ t('chineseExercises.totalRecords') }}: {{reciteContentCount}} </td>
<td mat-footer-cell *matFooterCellDef> {{ t('totalRecords') }}: {{reciteContentCount}} </td>
</ng-container>

<!-- Source column -->
<ng-container matColumnDef="source">
<th mat-header-cell *matHeaderCellDef> {{ t('chineseExercises.source') }} </th>
<th mat-header-cell *matHeaderCellDef> {{ t('source') }} </th>
<td mat-cell *matCellDef="let element">{{element.source ?? ''}}</td>
<td mat-footer-cell *matFooterCellDef> {{ t('chineseExercises.totalSelections') }}: {{selection.selected.length}} </td>
<td mat-footer-cell *matFooterCellDef> {{ t('totalSelections') }}: {{selection.selected.length}} </td>
</ng-container>

<!-- Rating Column -->
<ng-container matColumnDef="rating">
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by rating"> {{ t('chineseExercises.rating') }} </th>
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by rating"> {{ t('rating') }} </th>
<td mat-cell *matCellDef="let element">
<mat-button-toggle-group [ngModel]="getRating(element.id)" aria-label="Rating"
(change)="onContentRatingChanged(element, $event)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h2 mat-dialog-title>{{ t('englishListening.checkResult') }}</h2>

<!-- Inputted Column -->
<ng-container matColumnDef="inputted">
<th mat-header-cell *matHeaderCellDef> {{ t('englishListening.inputted') }} </th>
<th mat-header-cell *matHeaderCellDef> {{ t('inputted') }} </th>
<td mat-cell *matCellDef="let element"> {{element.inputted}} </td>
</ng-container>

Expand All @@ -21,6 +21,6 @@ <h2 mat-dialog-title>{{ t('englishListening.checkResult') }}</h2>
</div>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button (click)="onCloseClick()" cdkFocusInitial>{{ t('englishListening.close') }}</button>
<button mat-button (click)="onCloseClick()" cdkFocusInitial>{{ t('close') }}</button>
</mat-dialog-actions>
</div>
12 changes: 6 additions & 6 deletions src/app/pages/english-listening/english-listening.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ <h5>{{ t('englishListening.pageTitle') }}</h5>
</span>
<span class="toolbar-spacer"></span>
<mat-form-field class="page-toolbar-item">
<mat-label>{{ t('englishListening.files') }}</mat-label>
<mat-label>{{ t('files') }}</mat-label>
<mat-select matNativeControl [(value)]="selectedFile" (selectionChange)="onFileSelectionChanged($event)">
<mat-option value="">{{ t('englishListening.none') }}</mat-option>
<mat-option value="">{{ t('none') }}</mat-option>
@for (file of allFiles; track file.id ) {
<mat-option [value]="file">{{file.nameEnglish}}</mat-option>
}
Expand All @@ -21,7 +21,7 @@ <h5>{{ t('englishListening.pageTitle') }}</h5>

<div class="container">
<mat-form-field class="w-full">
<mat-label>{{ t('englishListening.filter') }}</mat-label>
<mat-label>{{ t('filter') }}</mat-label>
<input matInput (keyup)="applyFilter($event)" #input>
</mat-form-field>

Expand Down Expand Up @@ -73,7 +73,7 @@ <h5>{{selectedLesson?.title}}</h5>

<div class="container">
<mat-form-field class="w-full">
<mat-label>{{ t('englishListening.filter') }}</mat-label>
<mat-label>{{ t('filter') }}</mat-label>
<input matInput (keyup)="applySectionFilter($event)" #input>
</mat-form-field>

Expand Down Expand Up @@ -192,11 +192,11 @@ <h5 style="height: 56px; line-height: 56px;">{{currentItemTitle}}</h5>
<mat-divider [vertical]="true" style="height: 80%"></mat-divider>
}
<span class="function-control-flex-container">
<button mat-fab class="toolbar-fab-button" matTooltip="{{ t('englishListening.toggleAnswer') }}"
<button mat-fab class="toolbar-fab-button" matTooltip="{{ t('toggleAnswer') }}"
(click)="onToggleAnswer()"><mat-icon color="primary">forum</mat-icon></button>
<button mat-fab class="toolbar-fab-button" matTooltip="{{ t('englishListening.toggleScripts') }}"
(click)="onToggleScripts()"><mat-icon color="primary">article</mat-icon></button>
<button mat-fab class="toolbar-fab-button" matTooltip="{{ t('englishListening.print') }}"
<button mat-fab class="toolbar-fab-button" matTooltip="{{ t('print') }}"
[useExistingCss]="true" printSectionId="print-section" ngxPrint><mat-icon
color="primary">print</mat-icon></button>
<button mat-fab class="toolbar-fab-button" matTooltip="{{ t('englishListening.returnToSectionDetail') }}"
Expand Down
10 changes: 5 additions & 5 deletions src/app/pages/formula-recites/formula-recites-llm-dialog.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div *transloco="let t">
<h2 mat-dialog-title>{{ t('formulaRecites.chatWithAI') }}</h2>
<h2 mat-dialog-title>{{ t('chatWithAI') }}</h2>
<mat-dialog-content>
<mat-form-field class="control-full-width">
<mat-label>{{ t('formulaRecites.mode') }}</mat-label>
<mat-label>{{ t('mode') }}</mat-label>
<mat-select matNativeControl [(value)]="mode">
@for (lvl of allAIModes; track lvl.value ) {
<mat-option [value]="lvl.value">{{getAIModeName(lvl.value)}}</mat-option>
Expand All @@ -18,12 +18,12 @@ <h2 mat-dialog-title>{{ t('formulaRecites.chatWithAI') }}</h2>
<textarea matInput rows="5" [(ngModel)]="data.content" readonly="true"></textarea>
</mat-form-field>
<mat-form-field class="control-full-width">
<mat-label>{{ t('formulaRecites.aiReply') }}</mat-label>
<mat-label>{{ t('aiReply') }}</mat-label>
<textarea matInput placeholder="AI replys..." rows="8" [(ngModel)]="aireply" readonly="true"></textarea>
</mat-form-field>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button (click)="onSubmit()" [disabled]="submitting" cdkFocusInitial>{{ t('formulaRecites.submit') }}</button>
<button mat-button (click)="onNoClick()">{{ t('formulaRecites.close') }}</button>
<button mat-button (click)="onSubmit()" [disabled]="submitting" cdkFocusInitial>{{ t('submit') }}</button>
<button mat-button (click)="onNoClick()">{{ t('close') }}</button>
</mat-dialog-actions>
</div>
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<div *transloco="let t">
<h2 mat-dialog-title>{{ t('formulaRecites.optionsOfPrinting') }}</h2>
<h2 mat-dialog-title>{{ t('optionsOfPrinting') }}</h2>
<mat-dialog-content>
<mat-form-field class="control-full-width">
<mat-label>{{ t('formulaRecites.subTitle') }}</mat-label>
<input matInput type="name" [(ngModel)]="subtitle">
<span matTextPrefix>{{data.filename}}</span>
</mat-form-field>
<mat-form-field class="control-full-width">
<mat-label>{{ t('formulaRecites.count') }}</mat-label>
<mat-label>{{ t('count') }}</mat-label>
<input matInput type="number" [(ngModel)]="countOfItems" [disabled]="data.disableCount">
<span matSuffix>{{data.reciteContentCount}}</span>
</mat-form-field>
<mat-checkbox class="control-full-width" [(ngModel)]="printEntryDate">{{ t('formulaRecites.printEntryDate') }}</mat-checkbox>
<mat-checkbox class="control-full-width" [(ngModel)]="printEntryDate">{{ t('printEntryDate') }}</mat-checkbox>
<div class="control-full-width">
<mat-label>{{ t('formulaRecites.execDateOption') }}</mat-label>
<mat-radio-group aria-label="Select an option" class="control-full-width" [(ngModel)]="selectedExecDateModel">
Expand All @@ -21,7 +21,7 @@ <h2 mat-dialog-title>{{ t('formulaRecites.optionsOfPrinting') }}</h2>
</mat-radio-group>
</div>
<mat-form-field class="control-full-width">
<mat-label>{{ t('formulaRecites.execDate') }}</mat-label>
<mat-label>{{ t('execDate') }}</mat-label>
<input matInput [(ngModel)]="execDate" [matDatepicker]="picker" [disabled]="selectedExecDateModel() !== 2">
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
Expand Down
12 changes: 6 additions & 6 deletions src/app/pages/formula-recites/formula-recites.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ <h5>{{ t('formulaRecites.title') }}</h5>
</span>
<span class="toolbar-spacer"></span>
<mat-form-field class="page-toolbar-item">
<mat-label>{{ t('formulaRecites.files') }}</mat-label>
<mat-label>{{ t('files') }}</mat-label>
<mat-select matNativeControl [(value)]="selectedFile" (selectionChange)="onFileSelectionChanged($event)">
<mat-option value="">{{ t('formulaRecites.none') }}</mat-option>
<mat-option value="">{{ t('none') }}</mat-option>
@for (file of allFiles; track file.id ) {
<mat-option [value]="file">{{file.nameChinese}}</mat-option>
}
</mat-select>
</mat-form-field>
<span class="toolbar-item-count" matSuffix><small>{{ t('formulaRecites.items') }}: {{reciteContentCount}}</small></span>
<span class="toolbar-item-count" matSuffix><small>{{ t('items') }}: {{reciteContentCount}}</small></span>
<section style="padding-left: 8px;">
<div class="example-button-container">
<button mat-fab (click)="onPrintWithOptions()" [disabled]="!selectedFile">
Expand All @@ -28,7 +28,7 @@ <h5>{{ t('formulaRecites.title') }}</h5>

<div class="container">
<mat-form-field class="w-full">
<mat-label>{{ t('formulaRecites.filter') }}</mat-label>
<mat-label>{{ t('filter') }}</mat-label>
<input matInput (keyup)="applyFilter($event)" #input>
</mat-form-field>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 w-full">
Expand Down Expand Up @@ -56,7 +56,7 @@ <h5>{{ t('formulaRecites.title') }}</h5>

<!-- AI Column -->
<ng-container matColumnDef="ai">
<th mat-header-cell *matHeaderCellDef> {{ t('formulaRecites.ai') }} </th>
<th mat-header-cell *matHeaderCellDef> {{ t('ai') }} </th>
<td mat-cell *matCellDef="let element">
<button mat-mini-fab aria-label="Play" (click)="onLLMExplain(element)" [disabled]="!usercode.isUserCodeEntered">
<mat-icon>help_outline</mat-icon>
Expand Down Expand Up @@ -87,7 +87,7 @@ <h5>{{ t('formulaRecites.title') }}</h5>

<!-- Source Column -->
<ng-container matColumnDef="source">
<th mat-header-cell *matHeaderCellDef> {{ t('formulaRecites.source') }} </th>
<th mat-header-cell *matHeaderCellDef> {{ t('source') }} </th>
<td mat-cell *matCellDef="let element">
<div>{{element.source}}</div>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function createMockTranslocoService() {
selectTranslate: vi.fn().mockReturnValue(of('')),
_loadDependencies: vi.fn().mockReturnValue(of(null)),
translate: vi.fn((key: string) => {
if (key === 'formulaRecites.explain') {
if (key === 'explain') {
return '讲解';
}
if (key === 'formulaRecites.generateQuiz') {
Expand All @@ -59,7 +59,7 @@ function createMockTranslocoService() {
if (key === 'translateExercises.englishToChinese') {
return '英译中';
}
if (key === 'translateExercises.explain') {
if (key === 'explain') {
return '讲解';
}
if (key === 'translateExercises.correct') {
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/formula-recites/formula-recites.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ export class FormulaRecitesLLMDialogComponent {
getAIModeName(mode: FormulaReciteAIModeEnum): string {
switch (mode) {
case FormulaReciteAIModeEnum.Explain:
return this.transloco.translate('formulaRecites.explain');
return this.transloco.translate('explain');
default:
return this.transloco.translate('formulaRecites.generateQuiz');
}
Expand Down
Loading
Loading