Refonte qualité (shared / back / front) #1
@@ -3,14 +3,15 @@ import {
|
||||
signal,
|
||||
computed,
|
||||
inject,
|
||||
DestroyRef,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ChangeDetectionStrategy,
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { ApiService } from '../../core/api.service';
|
||||
import { CategoryService } from '../../core/category.service';
|
||||
import { ApiEntry, ApiEntryListItem, Category } from '@datacat/shared';
|
||||
@@ -416,6 +417,7 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
private apiService = inject(ApiService);
|
||||
private categoryService = inject(CategoryService);
|
||||
private fb = inject(FormBuilder);
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
api = signal<ApiEntry | null>(null);
|
||||
versions = signal<ApiEntryListItem[]>([]);
|
||||
@@ -462,12 +464,16 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
|
||||
private pollInterval: ReturnType<typeof setInterval> | null = null;
|
||||
private routeSub: Subscription | null = null;
|
||||
private id = '';
|
||||
|
||||
ngOnInit() {
|
||||
this.categoryService.list().subscribe((res) => this.categories.set(res.items));
|
||||
this.routeSub = this.route.paramMap.subscribe((params) => {
|
||||
this.categoryService
|
||||
.list()
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((res) => this.categories.set(res.items));
|
||||
this.route.paramMap
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe((params) => {
|
||||
this.id = params.get('id') ?? '';
|
||||
this.api.set(null);
|
||||
this.versions.set([]);
|
||||
@@ -481,7 +487,6 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.routeSub?.unsubscribe();
|
||||
this.clearPoll();
|
||||
}
|
||||
|
||||
@@ -498,11 +503,17 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
|
||||
onSetCurrent() {
|
||||
this.settingCurrent.set(true);
|
||||
this.apiService.setCurrent(this.id).subscribe({
|
||||
this.apiService
|
||||
.setCurrent(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (entry) => {
|
||||
this.api.set(entry);
|
||||
this.settingCurrent.set(false);
|
||||
this.apiService.getVersions(this.id).subscribe({
|
||||
this.apiService
|
||||
.getVersions(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (v) => this.versions.set(v),
|
||||
error: () => {},
|
||||
});
|
||||
@@ -513,7 +524,10 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
|
||||
onRegenerate() {
|
||||
this.regenerating.set(true);
|
||||
this.apiService.regenerate(this.id).subscribe({
|
||||
this.apiService
|
||||
.regenerate(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (entry) => {
|
||||
this.api.set(entry);
|
||||
this.regenerating.set(false);
|
||||
@@ -568,7 +582,9 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
versionPatch: raw.versionPatch ?? 0,
|
||||
categoryId: raw.categoryId || null,
|
||||
description: raw.description || null,
|
||||
}).subscribe({
|
||||
})
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (updated) => { this.api.set(updated); this.savingInfo.set(false); this.editingInfo.set(false); },
|
||||
error: () => this.savingInfo.set(false),
|
||||
});
|
||||
@@ -587,7 +603,9 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
contactTechnicalName: raw.contactTechnicalName ?? '',
|
||||
contactTechnicalEntity: raw.contactTechnicalEntity ?? '',
|
||||
contactTechnicalEmail: raw.contactTechnicalEmail ?? '',
|
||||
}).subscribe({
|
||||
})
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (updated) => { this.api.set(updated); this.savingContacts.set(false); this.editingContacts.set(false); },
|
||||
error: () => this.savingContacts.set(false),
|
||||
});
|
||||
@@ -599,7 +617,10 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
/* Calculer la cible de redirection avant la suppression */
|
||||
const otherVersions = this.versions().filter((v) => v.id !== this.id);
|
||||
const redirectTarget = otherVersions.find((v) => v.isCurrent) ?? otherVersions[0];
|
||||
this.apiService.delete(this.id).subscribe({
|
||||
this.apiService
|
||||
.delete(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: () => {
|
||||
if (redirectTarget) {
|
||||
this.router.navigate(['/catalog', redirectTarget.id]);
|
||||
@@ -627,17 +648,26 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
|
||||
private loadApi() {
|
||||
this.loading.set(true);
|
||||
this.apiService.get(this.id).subscribe({
|
||||
this.apiService
|
||||
.get(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (entry) => {
|
||||
this.api.set(entry);
|
||||
this.loading.set(false);
|
||||
this.startPollIfPending();
|
||||
this.apiService.getVersions(this.id).subscribe({
|
||||
this.apiService
|
||||
.getVersions(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (v) => this.versions.set(v),
|
||||
error: () => {},
|
||||
});
|
||||
if (entry.categoryId) {
|
||||
this.categoryService.browse(entry.categoryId).subscribe({
|
||||
this.categoryService
|
||||
.browse(entry.categoryId)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (data) => this.categoryBreadcrumb.set(data.breadcrumb),
|
||||
error: () => {},
|
||||
});
|
||||
@@ -658,7 +688,10 @@ export class ApiDetailComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private pollStatus() {
|
||||
this.apiService.get(this.id).subscribe({
|
||||
this.apiService
|
||||
.get(this.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (entry) => {
|
||||
this.api.set(entry);
|
||||
if (entry.status !== 'PENDING') this.clearPoll();
|
||||
|
||||
@@ -327,7 +327,10 @@ export class BrowseComponent implements OnInit {
|
||||
loadBrowse() {
|
||||
this.loading.set(true);
|
||||
this.error.set(null);
|
||||
this.categoryService.browse(this.categoryId()).subscribe({
|
||||
this.categoryService
|
||||
.browse(this.categoryId())
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (data) => {
|
||||
this.browseData.set(data);
|
||||
this.loading.set(false);
|
||||
@@ -385,7 +388,9 @@ export class BrowseComponent implements OnInit {
|
||||
forkJoin({
|
||||
apis: this.apiService.list({ search: raw || undefined, page: this.searchPage(), limit: this.searchLimit }),
|
||||
categories: this.categoryService.list(raw || undefined),
|
||||
}).subscribe({
|
||||
})
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: ({ apis, categories }) => {
|
||||
this.searchResults.set(apis.items);
|
||||
this.searchTotal.set(apis.total);
|
||||
|
||||
@@ -4,9 +4,11 @@ import {
|
||||
computed,
|
||||
effect,
|
||||
inject,
|
||||
DestroyRef,
|
||||
OnInit,
|
||||
ChangeDetectionStrategy,
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@@ -154,6 +156,7 @@ import { ApiEntryListItem, ApiType } from '@datacat/shared';
|
||||
})
|
||||
export class CatalogComponent implements OnInit {
|
||||
private apiService = inject(ApiService);
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
apis = signal<ApiEntryListItem[]>([]);
|
||||
loading = signal(false);
|
||||
@@ -221,6 +224,7 @@ export class CatalogComponent implements OnInit {
|
||||
page: this.page(),
|
||||
limit: this.limit,
|
||||
})
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (res) => {
|
||||
this.apis.set(res.items);
|
||||
|
||||
@@ -3,10 +3,11 @@ import {
|
||||
signal,
|
||||
computed,
|
||||
inject,
|
||||
DestroyRef,
|
||||
OnInit,
|
||||
ChangeDetectionStrategy,
|
||||
} from '@angular/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
|
||||
import { Router, RouterLink, ActivatedRoute } from '@angular/router';
|
||||
@@ -507,6 +508,7 @@ export class UploadComponent implements OnInit {
|
||||
private categoryService = inject(CategoryService);
|
||||
private router = inject(Router);
|
||||
private route = inject(ActivatedRoute);
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
step = signal(1);
|
||||
selectedFiles = signal<File[]>([]);
|
||||
@@ -628,7 +630,10 @@ export class UploadComponent implements OnInit {
|
||||
const preselectedCategoryId = params.get('categoryId');
|
||||
const fromId = params.get('from');
|
||||
|
||||
this.categoryService.list().subscribe({
|
||||
this.categoryService
|
||||
.list()
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (res) => {
|
||||
this.categories.set(res.items);
|
||||
if (preselectedCategoryId) {
|
||||
@@ -638,11 +643,17 @@ export class UploadComponent implements OnInit {
|
||||
});
|
||||
|
||||
if (fromId) {
|
||||
this.apiService.get(fromId).subscribe({
|
||||
this.apiService
|
||||
.get(fromId)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (api) => this.prefillFromApi(api),
|
||||
error: () => {},
|
||||
});
|
||||
this.apiService.getVersions(fromId).subscribe({
|
||||
this.apiService
|
||||
.getVersions(fromId)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (versions) => this.existingVersions.set(versions),
|
||||
error: () => {},
|
||||
});
|
||||
@@ -748,7 +759,10 @@ export class UploadComponent implements OnInit {
|
||||
formData.append('files', f);
|
||||
}
|
||||
|
||||
this.apiService.validate(formData).subscribe({
|
||||
this.apiService
|
||||
.validate(formData)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
this.validating.set(false);
|
||||
this.validationDone.set(true);
|
||||
@@ -826,7 +840,10 @@ export class UploadComponent implements OnInit {
|
||||
formData.append('contactTechnicalEntity', raw.contactTechnicalEntity ?? '');
|
||||
formData.append('contactTechnicalEmail', raw.contactTechnicalEmail ?? '');
|
||||
|
||||
this.apiService.upload(formData).subscribe({
|
||||
this.apiService
|
||||
.upload(formData)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (entry) => {
|
||||
this.uploading.set(false);
|
||||
this.router.navigate(['/catalog', entry.id]);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Component, signal, inject, ChangeDetectionStrategy, input, output } from '@angular/core';
|
||||
import { Component, signal, inject, DestroyRef, ChangeDetectionStrategy, input, output } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CategoryService } from '../../core/category.service';
|
||||
import { CategoryWithCounts } from '@datacat/shared';
|
||||
@@ -49,6 +50,7 @@ import { CategoryWithCounts } from '@datacat/shared';
|
||||
})
|
||||
export class CategoryDeleteModalComponent {
|
||||
private categoryService = inject(CategoryService);
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
category = input.required<CategoryWithCounts>();
|
||||
confirmed = output<void>();
|
||||
@@ -65,7 +67,10 @@ export class CategoryDeleteModalComponent {
|
||||
const cat = this.category();
|
||||
this.deleteLoading.set(true);
|
||||
this.deleteError.set(null);
|
||||
this.categoryService.delete(cat.id).subscribe({
|
||||
this.categoryService
|
||||
.delete(cat.id)
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.deleteLoading.set(false);
|
||||
this.confirmed.emit();
|
||||
|
||||
@@ -3,11 +3,13 @@ import {
|
||||
signal,
|
||||
computed,
|
||||
inject,
|
||||
DestroyRef,
|
||||
OnInit,
|
||||
ChangeDetectionStrategy,
|
||||
input,
|
||||
output,
|
||||
} from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CategoryService } from '../../core/category.service';
|
||||
import { Category } from '@datacat/shared';
|
||||
@@ -79,6 +81,7 @@ import { Category } from '@datacat/shared';
|
||||
})
|
||||
export class CategoryFormModalComponent implements OnInit {
|
||||
private categoryService = inject(CategoryService);
|
||||
private destroyRef = inject(DestroyRef);
|
||||
|
||||
mode = input<'create' | 'edit'>('create');
|
||||
category = input<Category | null>(null);
|
||||
@@ -133,7 +136,10 @@ export class CategoryFormModalComponent implements OnInit {
|
||||
this.formDescription.set(cat.description ?? '');
|
||||
} else {
|
||||
this.formParentId.set(this.parentId());
|
||||
this.categoryService.list().subscribe({
|
||||
this.categoryService
|
||||
.list()
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe({
|
||||
next: (res) => this.allCategories.set(res.items),
|
||||
error: () => this.allCategories.set([]),
|
||||
});
|
||||
@@ -159,7 +165,7 @@ export class CategoryFormModalComponent implements OnInit {
|
||||
? this.categoryService.create({ name, description, parentId: this.formParentId() ?? undefined })
|
||||
: this.categoryService.update(this.editingCategoryId()!, { name, description });
|
||||
|
||||
obs.subscribe({
|
||||
obs.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
||||
next: () => {
|
||||
this.formLoading.set(false);
|
||||
this.saved.emit();
|
||||
|
||||
Reference in New Issue
Block a user