UX Overhaul Part 1 (#3047)

Co-authored-by: Joseph Milazzo <joseph.v.milazzo@gmail.com>
This commit is contained in:
Robbie Davis 2024-08-09 13:55:31 -04:00 committed by GitHub
parent 5934d516f3
commit ff79710ac6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
324 changed files with 11589 additions and 4598 deletions

View file

@ -1,7 +1,7 @@
<ng-container *transloco="let t; read: 'all-collections'">
<app-side-nav-companion-bar [hasFilter]="false" (filterOpen)="filterOpen.emit($event)">
<h2 title>{{t('title')}}</h2>
<h6 subtitle>{{t('item-count', {num: collections.length | number})}}</h6>
<h4 title>{{t('title')}}</h4>
<h5 subtitle>{{t('item-count', {num: collections.length | number})}}</h5>
</app-side-nav-companion-bar>
<app-bulk-operations [actionCallback]="bulkActionCallback"></app-bulk-operations>
@ -27,7 +27,7 @@
<ng-template #noData>
{{t('no-data')}}
@if(isAdmin$ | async) {
@if(accountService.isAdmin$ | async) {
{{t('create-one-part-1')}} <a [href]="WikiLink.Collections" rel="noopener noreferrer" target="_blank">{{t('create-one-part-2')}}<i class="fa fa-external-link-alt ms-1" aria-hidden="true"></i></a>
}
</ng-template>

View file

@ -76,7 +76,6 @@ export class AllCollectionsComponent implements OnInit {
collections: UserCollection[] = [];
collectionTagActions: ActionItem<UserCollection>[] = [];
jumpbarKeys: Array<JumpKey> = [];
isAdmin$: Observable<boolean> = of(false);
filterOpen: EventEmitter<boolean> = new EventEmitter();
trackByIdentity = (index: number, item: UserCollection) => `${item.id}_${item.title}_${item.owner}_${item.promoted}`;
user!: User;
@ -116,12 +115,6 @@ export class AllCollectionsComponent implements OnInit {
.filter(action => this.collectionService.actionListFilter(action, user));
this.cdRef.markForCheck();
});
this.isAdmin$ = this.accountService.currentUser$.pipe(takeUntilDestroyed(this.destroyRef), map(user => {
if (!user) return false;
return this.accountService.hasAdminRole(user);
}));
}
loadCollection(item: UserCollection) {

View file

@ -2,10 +2,10 @@
<div #companionBar>
<app-side-nav-companion-bar *ngIf="series !== undefined" [hasFilter]="true" (filterOpen)="filterOpen.emit($event)" [filterActive]="filterActive">
<ng-container title>
<h2 *ngIf="collectionTag !== undefined">
<app-card-actionables [disabled]="actionInProgress" (actionHandler)="performAction($event)" [actions]="collectionTagActions" [labelBy]="collectionTag.title" iconClass="fa-ellipsis-v"></app-card-actionables>
<h4 *ngIf="collectionTag !== undefined">
{{collectionTag.title}}<span class="ms-1" *ngIf="collectionTag.promoted">(<i aria-hidden="true" class="fa fa-angle-double-up"></i>)</span>
</h2>
<app-card-actionables [disabled]="actionInProgress" (actionHandler)="performAction($event)" [actions]="collectionTagActions" [labelBy]="collectionTag.title" iconClass="fa-ellipsis-v"></app-card-actionables>
</h4>
</ng-container>
</app-side-nav-companion-bar>
</div>

View file

@ -1,34 +0,0 @@
<ng-container *transloco="let t; read: 'import-mal-collection-modal'">
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">{{t('title')}}</h4>
<button type="button" class="btn-close" aria-label="Close" (click)="ngbModal.close()"></button>
</div>
<div class="modal-body scrollable-modal">
<p>{{t('description')}}</p>
<ul>
@for(stack of stacks; track stack.url) {
<li class="mb-2">
<div>
<a [href]="stack.url" rel="noreferrer noopener" target="_blank">{{stack.title}}</a>
<button class="btn btn-primary float-end" [disabled]="collectionMap && collectionMap.hasOwnProperty(stack.url)" (click)="importStack(stack)">Track</button>
</div>
<div>by {{stack.author}} • {{t('series-count', {num: stack.seriesCount | number})}} • <span><i class="fa-solid fa-layer-group me-1" aria-hidden="true"></i>{{t('restack-count', {num: stack.restackCount | number})}}</span></div>
</li>
} @empty {
@if (isLoading) {
<app-loading [loading]="isLoading"></app-loading>
} @else {
<p>{{t('nothing-found')}}</p>
}
}
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)="ngbModal.dismiss()">{{t('close')}}</button>
</div>
</ng-container>

View file

@ -0,0 +1,27 @@
<ng-container *transloco="let t; read: 'import-mal-collection-modal'">
<p>{{t('description')}}</p>
@if (stacks.length === 0) {
<p>{{t('nothing-found')}}</p>
}
<ul>
@for(stack of stacks; track stack.url) {
<li class="mb-2">
<div>
<a [href]="stack.url" rel="noreferrer noopener" target="_blank">{{stack.title}}</a>
<button class="btn btn-primary float-end" [disabled]="collectionMap && collectionMap.hasOwnProperty(stack.url)" (click)="importStack(stack)">{{t('track')}}</button>
</div>
<div>
@if (stack.author) {
by {{stack.author}} •
}
{{t('series-count', {num: stack.seriesCount | number})}} • <span><i class="fa-solid fa-layer-group me-1" aria-hidden="true"></i>{{t('restack-count', {num: stack.restackCount | number})}}</span></div>
</li>
} @empty {
@if (isLoading) {
<app-loading [loading]="isLoading"></app-loading>
}
}
</ul>
</ng-container>

View file

@ -1,35 +1,30 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject} from '@angular/core';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit} from '@angular/core';
import {translate, TranslocoDirective} from "@ngneat/transloco";
import {ReactiveFormsModule} from "@angular/forms";
import {Select2Module} from "ng-select2-component";
import {NgbActiveModal} from "@ng-bootstrap/ng-bootstrap";
import {CollectionTagService} from "../../../_services/collection-tag.service";
import {ToastrService} from "ngx-toastr";
import {ScrobbleProvider, ScrobblingService} from "../../../_services/scrobbling.service";
import {ConfirmService} from "../../../shared/confirm.service";
import {MalStack} from "../../../_models/collection/mal-stack";
import {UserCollection} from "../../../_models/collection-tag";
import {ScrobbleProvider, ScrobblingService} from "../../../_services/scrobbling.service";
import {forkJoin} from "rxjs";
import {ToastrService} from "ngx-toastr";
import {DecimalPipe} from "@angular/common";
import {LoadingComponent} from "../../../shared/loading/loading.component";
import {ConfirmService} from "../../../shared/confirm.service";
import {DecimalPipe} from "@angular/common";
import {DefaultValuePipe} from "../../../_pipes/default-value.pipe";
@Component({
selector: 'app-import-mal-collection-modal',
selector: 'app-import-mal-collection',
standalone: true,
imports: [
TranslocoDirective,
ReactiveFormsModule,
Select2Module,
LoadingComponent,
DecimalPipe,
LoadingComponent
DefaultValuePipe
],
templateUrl: './import-mal-collection-modal.component.html',
styleUrl: './import-mal-collection-modal.component.scss',
templateUrl: './import-mal-collection.component.html',
styleUrl: './import-mal-collection.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ImportMalCollectionModalComponent {
protected readonly ngbModal = inject(NgbActiveModal);
export class ImportMalCollectionComponent {
private readonly collectionService = inject(CollectionTagService);
private readonly cdRef = inject(ChangeDetectorRef);
private readonly toastr = inject(ToastrService);
@ -43,9 +38,8 @@ export class ImportMalCollectionModalComponent {
constructor() {
this.scrobblingService.getMalToken().subscribe(async token => {
if (token.accessToken === '') {
await this.confirmService.alert(translate('toasts.mal-token-required'));
this.ngbModal.dismiss();
return;
await this.confirmService.alert(translate('toasts.mal-token-required'));
return;
}
this.setup();
});
@ -78,6 +72,4 @@ export class ImportMalCollectionModalComponent {
this.toastr.success(translate('toasts.stack-imported'));
})
}
}