Skip to content

Commit

Permalink
feat(octra): sort projects by name ascending
Browse files Browse the repository at this point in the history
  • Loading branch information
julianpoemp committed Jan 30, 2025
1 parent 0f58bd7 commit f159067
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,48 +38,85 @@ <h1>{{ 'g.projects' | transloco }}</h1>
{{ 'projects-list.introduction' | transloco }}
</p>
<div class="table-wrapper flex overflow-y-auto h-100">
@if (projects?.list) {
<table class="table table-striped table-hover">
<thead>
<tr>
<th></th>
<th>{{ 'g.name' | transloco }}</th>
<th>{{ 'g.description' | transloco }}</th>
<th class="text-center">{{ 'g.free tasks' | transloco }}</th>
<th class="text-center">{{ 'g.action' | transloco }}</th>
</tr>
</thead>
<tbody>
@for (project of projects?.list; track project) {
<tr
[ngClass]="{
deactivated: getFreeAnnotationTasks(project) < 1
}"
@if (shownProjects) {
<div class="list-group">
<div class="list-group-item">
<div class="row g-0">
<div class="col"></div>
<div class="col-auto text-right">
<ngb-pagination
[size]="'sm'"
[page]="currentPage.page"
[collectionSize]="currentPage.collectionSize"
[pageSize]="itemsPerPage"
(pageChange)="showProjects($event)"
></ngb-pagination>
</div>
</div>
</div>
@for (project of shownProjects; track project) {
<div class="list-group-item list-group-item-action">
<div
class="row g-1 align-items-center justify-items-center justify-content-center"
>
<td>
<div class="col-auto project-name">
@if (project.active) {
<i class="bi bi-check-circle" style="color: green"></i>
} @if (!project.active) {
<i class="bi bi-dash-circle" style="color: red"></i>
}
</td>
<td>{{ project.name }}</td>
<td class="description">{{ project.public_description }}</td>
<td class="text-center">{{ getFreeAnnotationTasks(project) }}</td>
<td class="text-center">
</div>
<div
class="col align-items-center justify-items-center justify-content-center"
>
<span class="project-name"
>{{ project.name }} ({{ project.shortname }})</span
>
</div>
</div>
<div class="row">
<div class="col text-muted project-description">
{{ project.public_description }}
</div>
</div>
<div class="row">
<div class="col mb-2">
<span
class="rounded-pill text-white property-pill me-1"
style="background-color: purple"
>
<i class="bi bi-list-ol"></i> {{ 'g.free tasks' | transloco }}:
{{ getFreeAnnotationTasks(project) }}
</span>

@if (project.enddate) {
<span class="rounded-pill text-white property-pill me-1 bg-info">
<i class="bi bi-calendar-day"></i>
{{ 'p.available until' | transloco }}:
{{
project.enddate
| luxonShortDateTime
: {
locale: (authStoreService.me$ | async).locale
}
}}
</span>
}
</div>
<div class="col-md-2">
<button
class="btn btn-primary btn-sm"
class="btn btn-primary btn-sm w-100"
size="sm"
[disabled]="projectStarting"
(click)="onProjectClick(project)"
>
{{ 'g.start' | transloco }}
</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
}
</div>
} @else {
<div class="text-center mt-5">
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
flex-direction: column;
overflow-y: auto;
height: 100%;
border: 1px solid lightgray;
}

table tbody tr td {
Expand All @@ -37,3 +36,18 @@ table tbody tr {
.description {
font-size: 0.9em;
}

.project-name {
font-weight: bold;
font-size: 0.9em;
}

.project-description {
color: gray;
font-size: 0.85em;
}

.property-pill {
font-size: 0.7rem;
padding: 3px 10px;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AsyncPipe, NgClass } from '@angular/common';
import { AsyncPipe } from '@angular/common';
import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { TranslocoPipe } from '@jsverse/transloco';
Expand All @@ -9,6 +9,7 @@ import { OctraAPIService } from '@octra/ngx-octra-api';
import { DefaultComponent } from '../../../component/default.component';
import { ErrorModalComponent } from '../../../modals/error-modal/error-modal.component';
import { OctraModalService } from '../../../modals/octra-modal.service';
import { LuxonShortDateTimePipe } from '../../../shared';
import { AppStorageService } from '../../../shared/service/appstorage.service';
import { RootState } from '../../../store';
import {
Expand All @@ -17,16 +18,24 @@ import {
} from '../../../store/authentication';
import { AnnotationActions } from '../../../store/login-mode/annotation/annotation.actions';
import { AnnotationStoreService } from '../../../store/login-mode/annotation/annotation.store.service';
import { NgbPagination } from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'octra-projects-list',
templateUrl: './projects-list.component.html',
styleUrls: ['./projects-list.component.scss'],
imports: [NgClass, AsyncPipe, TranslocoPipe],
imports: [AsyncPipe, TranslocoPipe, LuxonShortDateTimePipe, NgbPagination],
})
export class ProjectsListComponent extends DefaultComponent implements OnInit {
projects?: ProjectListDto;
shownProjects?: ProjectDto[];

projectStarting = false;
itemsPerPage = 20;
currentPage?: {
page: number;
collectionSize: number;
};

constructor(
private api: OctraAPIService,
Expand Down Expand Up @@ -60,22 +69,23 @@ export class ProjectsListComponent extends DefaultComponent implements OnInit {
),
{
next: () => {
this.loadProjects();
this.loadProjects(1);
},
}
);
this.loadProjects();
this.loadProjects(1);
}

private loadProjects() {
loadProjects(page: number) {
this.projects = undefined;

this.subscribe(
this.api.listProjects({
manageable: false,
start: 1,
start: page,
representation: 'page',
length: 3,
order: "asc",
order_by: "name"
}),
{
next: (projects) => {
Expand All @@ -95,27 +105,7 @@ export class ProjectsListComponent extends DefaultComponent implements OnInit {
return false;
}),
};

this.projects?.list?.sort((a, b) => {
if (a.active && !b.active) {
return 1;
} else if (a.active && b.active) {
const annotationStatisticsA =
a.statistics!.tasks.find((c) => c.type === 'annotation')?.status
.free ?? 0;
const annotationStatisticsB =
b.statistics!.tasks.find((c) => c.type === 'annotation')?.status
.free ?? 0;

if (annotationStatisticsA > annotationStatisticsB) {
return 1;
} else if (annotationStatisticsA < annotationStatisticsB) {
return annotationStatisticsA === 0 ? -1 : 1;
}
return 0;
}
return -1;
});
this.showProjects(page);
},
error: (error: HttpErrorResponse) => {
if (error.status === 401) {
Expand All @@ -137,6 +127,14 @@ export class ProjectsListComponent extends DefaultComponent implements OnInit {
);
}

showProjects(page: number) {
this.shownProjects = this.projects.list.slice((page - 1) * this.itemsPerPage, page * this.itemsPerPage);
this.currentPage = {
page,
collectionSize: this.projects.list.length
};
}

onProjectClick(project: ProjectDto) {
this.projectStarting = true;
this.appStorage.startOnlineAnnotation(project);
Expand Down
1 change: 1 addition & 0 deletions apps/octra/src/app/core/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from '../obj/statistics/KeyStatisticElem';
export * from '../obj/statistics/MouseStatisticElem';
export * from '../obj/statistics/StatisticElement';
export * from './functions';
export * from './luxon-date.pipe';
export * from './Logger';
47 changes: 47 additions & 0 deletions apps/octra/src/app/core/shared/luxon-date.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DateTime } from 'luxon';

@Pipe({
name: 'luxonShortDateTime',
standalone: true,
})
export class LuxonShortDateTimePipe implements PipeTransform {
constructor() {}

transform(
value: string | Date | DateTime | number | undefined,
options: { locale: string | undefined }
): unknown {
if (!value) {
return '';
}

let dateTime: DateTime;

if (value instanceof Date) {
dateTime = DateTime.fromJSDate(value);
} else if (value instanceof DateTime) {
dateTime = value;
} else if (typeof value === 'string') {
dateTime = DateTime.fromISO(value);
} else {
dateTime = DateTime.fromMillis(value);
}

const loc = options.locale ?? 'en-GB';
return dateTime.toLocaleString(
{
...DateTime.DATETIME_SHORT,
day: '2-digit',
month: '2-digit',
year: '2-digit',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short',
},
{
locale: loc,
}
);
}
}
3 changes: 2 additions & 1 deletion apps/octra/src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@
"selected level": "Ausgewähltes level",
"sign up": "Neu registrieren",
"username or email": "Nutzername oder E-Mail",
"nothing found": "Nicht gefunden"
"nothing found": "Nicht gefunden",
"available until": "Verfügbar bis"
},
"projects-list": {
"introduction": "Wähle ein Projekt, für das Du transkribieren möchtest und klicke auf \"START\".",
Expand Down
3 changes: 2 additions & 1 deletion apps/octra/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@
"selected level": "Selected level",
"sign up": "Sign up",
"username or email": "Username or E-Mail",
"nothing found": "Nothing found"
"nothing found": "Nothing found",
"available until": "Available until"
},
"projects-list": {
"introduction": "Please select a project that you want to transcribe and click on \"START\".",
Expand Down
4 changes: 4 additions & 0 deletions apps/octra/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -527,3 +527,7 @@ ngx-jodit {
.version-popover {
min-width: 300px;
}

ul.pagination.pagination-sm{
margin-bottom: 0 !important;
}

0 comments on commit f159067

Please sign in to comment.