Skip to content

Commit

Permalink
Merge pull request #79 from raywo-personal/63-implement-a-localizatio…
Browse files Browse the repository at this point in the history
…n-option

63-implement-a-localization-option
  • Loading branch information
raywo authored Jan 15, 2025
2 parents caec1b3 + ca00f02 commit 27e4e56
Show file tree
Hide file tree
Showing 40 changed files with 3,683 additions and 167 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ npm install
npm start
```

**Hint:** Use `npm start-de` to spin up a German version.

## Usage

1. Input participant information, including skills, prior knowledge, and time preferences.
Expand Down
18 changes: 17 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@
"root": "",
"sourceRoot": "src",
"prefix": "app",
"i18n": {
"sourceLocale": "en-US",
"locales": {
"de": {
"translation": "src/locale/messages.de.xlf"
}
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
Expand All @@ -35,7 +43,9 @@
"styles": [
"src/styles.scss"
],
"scripts": []
"scripts": [],
"localize": true,
"i18nMissingTranslation": "warning"
},
"configurations": {
"production": {
Expand All @@ -57,6 +67,9 @@
"optimization": false,
"extractLicenses": false,
"sourceMap": true
},
"de": {
"localize": ["de"]
}
},
"defaultConfiguration": "production"
Expand All @@ -69,6 +82,9 @@
},
"development": {
"buildTarget": "teamify:build:development"
},
"de": {
"buildTarget": "teamify:build:development,de"
}
},
"defaultConfiguration": "development"
Expand Down
1,437 changes: 1,437 additions & 0 deletions messages.xlf

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"start-de": "ng serve --configuration=de",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test",
Expand Down Expand Up @@ -49,4 +50,4 @@
"typescript": "~5.6.3",
"typescript-eslint": "8.18.0"
}
}
}
4 changes: 2 additions & 2 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ <h2 class="sidebar-title">Teamify</h2>

<nav class="sidebar-body" app-navigation></nav>

<footer class="sidebar-footer">
Made by raywo with <i class="bi-heart-fill text-danger"></i>&nbsp;|&nbsp;
<footer class="sidebar-footer" >
<ng-container i18n="@@t.madeByMessage">Made by raywo with</ng-container> <i class="bi-heart-fill text-danger"></i>&nbsp;|&nbsp;
<i class="bi-github"></i>&nbsp;
<a href="https://github.com/raywo-personal/teamify" target="_blank">
Source code
Expand Down
10 changes: 5 additions & 5 deletions src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,31 @@ export const routes: Routes = [
{
path: "time-slots",
component: TimeSlotListComponent,
data: {title: "Time slots", icon: "clock"},
data: {title: $localize`:time slots menu title@@t.timeslots-menu:Time slots`, icon: "clock"},
pathMatch: "full"
},
{
path: "prior-knowledge",
component: PriorKnowledgeListComponent,
data: {title: "Prior knowledge", icon: "book"},
data: {title: $localize`:prior knowledge menu title@@t.priorKnowledge-menu:Prior knowledge`, icon: "book"},
pathMatch: "full"
},
{
path: "persons",
component: PersonListComponent,
data: {title: "Persons", icon: "people"},
data: {title: $localize`:persons menu title@@t.persons-menu:Persons`, icon: "people"},
pathMatch: "full"
},
{
path: "build-teams",
component: GroupingComponent,
data: {title: "Build teams", icon: "people-fill"},
data: {title: $localize`:build teams menu title@@t.buildTeams-menu:Build teams`, icon: "people-fill"},
pathMatch: "full"
},
{
path: "settings",
component: SettingsComponent,
data: {title: "Settings", icon: "gear"},
data: {title: $localize`:settings menu title@@t.settings-menu:Settings`, icon: "gear"},
pathMatch: "full"
},
{
Expand Down
45 changes: 26 additions & 19 deletions src/app/persons/components/person-edit/person-edit.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ <h3>Person</h3>
setCustomValidity
#nameField
>
<label for="name">Name</label>
<div class="invalid-feedback">
<label for="name" i18n="|@@t.personName">Name</label>
<div class="invalid-feedback" i18n="|@@t.personNameError">
Please enter a name (2-50 characters).
</div>
</div>
Expand All @@ -33,17 +33,17 @@ <h3>Person</h3>
name="info"
formControlName="info"
>
<label for="info">Information</label>
<div class="invalid-feedback">
<label for="info" i18n="|@@t.personInformation">Information</label>
<div class="invalid-feedback" i18n="|@@t.personInformationError">
Please enter information (2-150 characters).
</div>
</div>
</div>
</div>

<div class="row mb-3">
<h3>Prior knowledge</h3>
<small class="mb-2">
<h3 i18n="|@@t.priorKnowledge">Prior knowledge</h3>
<small class="mb-2" i18n="|@@t.priorKnowledgeExplanation">
State what prior knowledge the person already has. This will have
influence on the creation of groups.
</small>
Expand All @@ -55,10 +55,12 @@ <h3>Prior knowledge</h3>
} @empty {
<div class="col">
<div class="alert alert-warning">
There is no prior knowledge stored yet.
Consider adding some by
<ng-container i18n="|@@t.priorKnowledgeEmpty">
There is no prior knowledge stored yet.
Consider adding some by
</ng-container>
<a routerLink="/prior-knowledge" class="link-offset-1" (click)="onCancel()">
clicking here
<ng-container i18n="|@@t.byClickingHere">clicking here</ng-container>
</a>.
</div>
</div>
Expand All @@ -69,10 +71,10 @@ <h3>Prior knowledge</h3>

<div class="row">
<div class="col">
<h3>Time slots</h3>
<h3 i18n="|@@t.timeslots">Time slots</h3>
<small class="mb-2">
<p>Select the preferred time slots for the person.</p>
<p>
<p i18n="|@@t.timeSlotExplanation1">Select the preferred time slots for the person.</p>
<p i18n="|@@t.timeSlotExplanation2">
Place them into the buckets according to the person’s preference. If
the person has no specific preference, put the time slots into the
first bucket.
Expand All @@ -81,12 +83,13 @@ <h3>Time slots</h3>

@if (slotCount === 0) {
<div class="alert alert-danger">
<p>
<p i18n="|@@t.timeSlotEmpty">
There is no time slot stored yet. Persons can only be saved if they
have a time slot assigned.
</p>
<a routerLink="/time-slots" class="btn btn-sm btn-primary mt-2"
(click)="onCancel()">
(click)="onCancel()"
i18n="|@@t.addTimeSlots">
Add time slots
</a>.
</div>
Expand All @@ -97,7 +100,7 @@ <h3>Time slots</h3>
@if (slotCount > 0) {
<div class="row mb-4" cdkDropListGroup>
<div class="col-8 slot-target">
<h4 class="h6">Preferred time slots</h4>
<h4 class="h6" i18n="|@@t.preferredTimeSlots">Preferred time slots</h4>

<div class="row">
@for (slot of priorityTimeSlots; track $index) {
Expand All @@ -112,7 +115,7 @@ <h4 class="h6">Preferred time slots</h4>
</div>

<div class="col-4">
<h4 class="h6">Available time slots</h4>
<h4 class="h6" i18n="|@@t.availableTimeslots">Available time slots</h4>
<div
cdkDropList
cdkDropListSortingDisabled
Expand All @@ -137,23 +140,27 @@ <h4 class="h6">Available time slots</h4>
</div>

<div class="offcanvas-footer">
<button type="button" class="btn btn-outline-secondary me-2" (click)="onCancel()">
<button type="button" class="btn btn-outline-secondary me-2"
(click)="onCancel()"
i18n="|@@t.cancel">
Cancel
</button>

<div>
<button [type]="edit() ? 'submit' : 'button'"
class="btn btn-primary"
[disabled]="personForm.invalid"
(click)="onSubmit()">
(click)="onSubmit()"
i18n="|@@t.save">
Save
</button>

@if (!edit()) {
<button type="submit" class="btn btn-primary ms-3"
[disabled]="personForm.invalid"
(click)="onNextAdd()">
Add next person <i class="bi-chevron-right"></i>
<ng-container i18n="|@@t.addNextPerson">Add next person</ng-container>
<i class="bi-chevron-right"></i>
</button>
}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
formControlName="remark"
setCustomValidity
>
<label for="knowledge-remark-{{knowledgeId}}">Remark</label>
<div class="invalid-feedback">
<label for="knowledge-remark-{{knowledgeId}}"
i18n="|@@t.remarkLabel">
Remark
</label>
<div class="invalid-feedback" i18n="|@@t.remarkInvalidFeedback">
Please enter a remark (2-160 characters).
</div>
</div>
Expand Down
24 changes: 16 additions & 8 deletions src/app/persons/components/person-list/person-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
aria-label="Toolbar for working with teams and persons">
<div class="toolbar-buttons">
<button app-add-button
caption="Add person"
caption=" Add person "
i18n-caption="@@t.addPerson"
(click)="onAdd(content)">
</button>

Expand All @@ -13,25 +14,28 @@
@if ((personsCount$ | async)! > 0) {
<button app-delete-button
caption="Clear all persons"
i18n-caption="@@t.clear-all-persons"
confirmationMessage="Are you sure you want to clear all persons?"
i18n-confirmationMessage="@@t.clearAllPersonsConfirmationMessage"
(deleteConfirmed)="onDeleteAll()">
</button>
}
</div>

<div class="d-flex gap-2">
<div class="d-flex align-items-center fit-height gap-2">
<small class="">
({{ (this.filteredPersons$ | async)?.length }} of {{ (this.personsCount$ | async) }} persons)
<small class="" i18n="x of y persons|@@t.xOfYPersons">
({{ (this.filteredPersons$ | async)?.length }} of
{{ (this.personsCount$ | async) }} persons)
</small>
<app-person-search [source]="filterSource$"/>
</div>
<app-person-slot-filter/>
</div>
</div>

<div class="content-area">
<ul class="list-group scrollable-area">
<div class="content-area scrollable-area">
<ul class="list-group">
@for (person of filteredPersons$ | async; track person.id) {
<li class="list-group-item list-group-item-action pointer"
(click)="onEdit(content, person)">
Expand All @@ -43,6 +47,7 @@
</li>
} @empty {
<app-data-not-available-view title="No persons found"
i18n-title="@@t.no-persons-found"
mode="warning"
[messageTemplate]="messageTemplate"/>
}
Expand All @@ -57,6 +62,7 @@ <h4 class="offcanvas-title" id="offcanvas-basic-title">{{ offcanvasTitle }}</h4>
tabindex="-1"
class="btn-close"
aria-label="Close"
i18n-aria-label="Close|@@t.close"
(click)="offcanvas.dismiss('Cross click')">
</button>
</div>
Expand All @@ -72,19 +78,21 @@ <h4 class="offcanvas-title" id="offcanvas-basic-title">{{ offcanvasTitle }}</h4>


<ng-template #messageTemplate>
<p>
<p i18n="|@@t.startCreatingPersons">
Start creating persons by clicking the button below.
</p>

@if ((slotCount$ | async) === 0) {
<app-data-not-available-info text="No time slots are available at the
moment. Please consider creating time slots prior to adding
individuals, so they can be assigned accordingly."/>
individuals, so they can be assigned accordingly."
i18n="|@@t.noTimeSlotsAvailableInfoMessage"/>
}

<button type="button"
class="btn btn-primary"
(click)="onAdd(content)">
(click)="onAdd(content)"
i18n="Add person|@@t.addPerson">
Add person
</button>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<div [formGroup]="timeSlotForm()">
<h5>Priority {{ priority }}</h5>
<h5>
<ng-container i18n="|@@t.priority">Priority</ng-container> {{ priority }}
</h5>

<input type="text"
id="validity-{{priority}}"
Expand Down Expand Up @@ -27,11 +29,11 @@ <h5>Priority {{ priority }}</h5>
[showDragHandle]="true"/>
</div>
} @empty {
<div class="invalid-feedback">
<div class="invalid-feedback" i18n="|@@t.timeSlotEmptyFeedback">
Please select at least one time slot for this priority.
</div>
<div class="empty-list-hint">
<small class="text-muted">No preference given</small>
<small class="text-muted" i18n="|@@t.noPreferenceGivenHint">No preference given</small>
</div>
}
</div>
Expand Down
Loading

0 comments on commit 27e4e56

Please sign in to comment.