Mise à jour articles et produits

This commit is contained in:
Rampeur
2025-08-19 05:12:16 +02:00
parent 977104aac2
commit ed6104ed21
137 changed files with 1498 additions and 681 deletions
+12
View File
@@ -0,0 +1,12 @@
export interface ArticleListConfig {
type: string;
filters: ArticleListFilters;
}
export interface ArticleListFilters {
tag?: string,
author?: string,
favorited?: string,
limit?: number,
offset?: number
}
@@ -0,0 +1,6 @@
import { Article } from './article.model';
export interface ArticleList {
articles: Array<Article>;
articlesCount: number;
}
+28
View File
@@ -0,0 +1,28 @@
import { Profile } from './profile.model';
import { PageLinks, PageMeta } from './shared.model';
import { Tag } from './tag.model';
export interface Article {
slug: string;
title: string;
description: string;
body: string;
author: Profile;
createdAt: string;
updatedAt: string;
tagList: Tag[];
favorited: boolean;
favoritesCount: number;
}
export interface ArticlePageData {
article: Article;
_links: PageLinks;
_meta: PageMeta;
}
export interface ArticlesPageData {
articles: Array<Article>;
_links: PageLinks;
_meta: PageMeta;
}
+10
View File
@@ -0,0 +1,10 @@
import { Article } from './article.model';
export interface Email {
from: string;
to: string;
subject: string;
text: string;
html: string;
article?: Article;
}
+8
View File
@@ -1,5 +1,8 @@
export * from './aeronef.model';
export * from './aeronef-list.model';
export * from './article.model';
export * from './article-list.model';
export * from './article-list-config.model';
export * from './application.model';
export * from './application-list.model';
export * from './application-list-config.model';
@@ -11,7 +14,12 @@ export * from './errors.model';
export * from './jump.model';
export * from './jump-list.model';
export * from './jump-list-config.model';
export * from './menu.model';
export * from './product.model';
export * from './product-list.model';
export * from './product-list-config.model';
export * from './profile.model';
export * from './qcm.model';
export * from './shared.model';
export * from './tag.model';
export * from './user.model';
+1 -11
View File
@@ -1,7 +1,7 @@
import { FormControl } from '@angular/forms';
import { Profile } from './profile.model';
import { PageLinks, PageMeta } from './shared.model';
import { ColumnDefinition, PageLinks, PageMeta } from './shared.model';
export interface Jump {
slug: string;
@@ -200,16 +200,6 @@ export interface JumpsPageData {
jumpsByModuleCount: number;*/
}
export interface ColumnDefinition {
key: string;
type: string;
label: string;
required?: boolean;
pattern?: string;
min?: number;
step?: number;
}
export const jumpColumns: Array<ColumnDefinition> = [
{
key: 'isSelected',
+2
View File
@@ -1,10 +1,12 @@
import { Badge } from './badge.model';
export interface Menu {
parent?: string;
state: string;
name: string;
type: string;
icon: string;
icontype?: string;
desc?: string;
badge?: Badge[];
color?: string;
@@ -0,0 +1,18 @@
export interface ProductListConfig {
type: string;
filters: ProductListFilters;
}
export interface ProductListFilters {
slug?: string;
name?: string;
numero?: number;
barcode?: number;
poid?: number;
sachets?: string;
molecules?: string;
numeroRangeStart?: number;
numeroRangeEnd?: number;
sachetsRangeStart?: number;
sachetsRangeEnd?: number;
}
@@ -0,0 +1,6 @@
import { Product } from './product.model';
export interface ProductList {
products: Array<Product>;
productsCount: number;
}
+86
View File
@@ -0,0 +1,86 @@
import { FormControl } from '@angular/forms';
import { ColumnDefinition, PageLinks, PageMeta } from './shared.model';
export interface Product {
slug: string;
name: string;
numero: number;
barcode: number;
poid?: number;
sachets?: string;
molecules?: string;
isSelected?: boolean;
createdAt: string;
updatedAt: string;
}
export interface ProductForm {
slug: FormControl<string>;
name: FormControl<string>;
numero: FormControl<number>;
barcode: FormControl<number>;
poid: FormControl<number>;
sachets: FormControl<Array<number>>;
molecules: FormControl<Array<string>>;
}
export interface ProductPageData {
product: Product;
_links: PageLinks;
_meta: PageMeta;
}
export interface ProductsPageData {
products: Array<Product>;
_links: PageLinks;
_meta: PageMeta;
}
export const productColumns: Array<ColumnDefinition> = [
{
key: 'isSelected',
type: 'isSelected',
label: ''
},
{
key: 'name',
type: 'text',
label: 'Libellé',
required: true
},
{
key: 'numero',
type: 'numeric',
label: 'Numéro',
required: true,
min: 0,
step: 1
},
{
key: 'barcode',
type: 'numeric',
label: 'Code EAN13',
required: true,
min: 0,
step: 1
},
{
key: 'poid',
type: 'numeric',
label: 'Poid',
min: 0,
step: 1
},
{
key: 'sachets',
type: 'text',
label: 'Sachets'
},
{
key: 'molecules',
type: 'text',
label: 'Molécules'
}
];
+10
View File
@@ -28,3 +28,13 @@ export interface ReduceRow {
key: string[];
value: number;
}
export interface ColumnDefinition {
key: string;
type: string;
label: string;
required?: boolean;
pattern?: string;
min?: number;
step?: number;
}
+5
View File
@@ -0,0 +1,5 @@
export interface Tag {
name: string;
createdAt: string;
updatedAt: string;
}
+1 -1
View File
@@ -5,9 +5,9 @@ export interface User {
firstname: string;
lastname: string;
phone: string;
token: string;
licence?: number;
poids?: number;
image?: string;
bg_image?: string;
token: string;
}
@@ -0,0 +1,12 @@
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router';
import { take } from 'rxjs/operators';
import { ArticlePageData } from 'src/app/core/models';
import { ArticlesService } from 'src/app/core/services';
export const articleResolver: ResolveFn<ArticlePageData> = (
route: ActivatedRouteSnapshot
) => {
return inject(ArticlesService).get(route.params['slug']).pipe(take(1));
};
@@ -0,0 +1,10 @@
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { take } from 'rxjs/operators';
import { Article } from 'src/app/core/models';
import { ArticlesService } from 'src/app/core/services';
export const articlesResolver: ResolveFn<Array<Article>> = () => {
return inject(ArticlesService).getAll().pipe(take(1));
};
+4
View File
@@ -1,4 +1,6 @@
export * from './aeronefs-page-resolver.service';
export * from './article-resolver.service';
export * from './articles-resolver.service';
export * from './auth-resolver.service';
export * from './canopies-page-resolver.service';
export * from './dropzones-page-resolver.service';
@@ -6,5 +8,7 @@ export * from './jump-resolver.service';
export * from './jumps-page-resolver.service';
export * from './jumps-resolver.service';
export * from './lastjump-resolver.service';
export * from './product-resolver.service';
export * from './products-resolver.service';
export * from './profile-resolver.service';
export * from './qcm-resolver.service';
@@ -0,0 +1,12 @@
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, ResolveFn } from '@angular/router';
import { take } from 'rxjs/operators';
import { ProductPageData } from 'src/app/core/models';
import { ProductsService } from 'src/app/core/services';
export const productResolver: ResolveFn<ProductPageData> = (
route: ActivatedRouteSnapshot
) => {
return inject(ProductsService).get(route.params['slug']).pipe(take(1));
};
@@ -0,0 +1,10 @@
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { take } from 'rxjs/operators';
import { Product } from 'src/app/core/models';
import { ProductsService } from 'src/app/core/services';
export const productsResolver: ResolveFn<Array<Product>> = () => {
return inject(ProductsService).getAll().pipe(take(1));
};
+65
View File
@@ -0,0 +1,65 @@
import { Injectable } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ApiService } from './api.service';
import { Article, ArticleList, ArticleListConfig, ArticleListFilters, ArticlePageData } from '../models';
import { map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ArticlesService {
constructor(
private apiService: ApiService
) { }
query(config: ArticleListConfig): Observable<ArticleList> {
// Convert any filters over to Angular's URLSearchParams
const params: ArticleListFilters = {} as ArticleListFilters;
Object.assign(params, config.filters);
return this.apiService
.get(
'/articles' + ((config.type === 'feed') ? '/feed' : ''),
new HttpParams({ fromObject: <{
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params })
);
}
get(slug: string): Observable<ArticlePageData> {
return this.apiService.get('/articles/' + slug)/*.pipe(map(data => {
data.article.tagList = data.article.tagNameTagTagLists;
delete data.article.tagNameTagTagLists;
return data;
}));*/
}
getAll(): Observable<Array<Article>> {
return this.apiService.get('/articles').pipe(map(data => data.articles));
}
destroy(slug: string) {
return this.apiService.delete('/articles/' + slug);
}
save(article: Article): Observable<Article> {
// If we're updating an existing article
if (article.slug) {
return this.apiService.put('/articles/' + article.slug, { article: article })
.pipe(map(data => data.article));
// Otherwise, create a new article
} else {
return this.apiService.post('/articles/', { article: article })
.pipe(map(data => data.article));
}
}
favorite(slug: string): Observable<Article> {
return this.apiService.post('/articles/' + slug + '/favorite');
}
unfavorite(slug: string): Observable<Article> {
return this.apiService.delete('/articles/' + slug + '/favorite');
}
}
+2
View File
@@ -1,6 +1,7 @@
export * from './aeronefs.service';
export * from './api.service';
export * from './applications.service';
export * from './articles.service';
export * from './calculator.service';
export * from './canopies.service';
export * from './dropzones.service';
@@ -8,6 +9,7 @@ export * from './jumps.service';
export * from './jump-table.service';
export * from './jwt.service';
export * from './pages.service';
export * from './products.service';
export * from './profiles.service';
export * from './qcm.service';
export * from './user.service';
+94
View File
@@ -0,0 +1,94 @@
import { Injectable } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiService } from './api.service';
import {
ProductList, ProductListConfig, ProductListFilters,
Product, ProductPageData
} from 'src/app/core/models';
@Injectable({ providedIn: 'root' })
export class ProductsService {
constructor(
private apiService: ApiService
) { }
query(config: ProductListConfig): Observable<ProductList> {
// Convert any filters over to Angular's URLSearchParams
/*
const params: ProductListFilters = {
date: config.filters.date,
lieu: config.filters.lieu,
oaci: config.filters.oaci,
aeronef: config.filters.aeronef,
imat: config.filters.imat,
hauteur: config.filters.hauteur,
voile: config.filters.voile,
taille: config.filters.taille,
categorie: config.filters.categorie,
module: config.filters.module,
participants: config.filters.participants,
accessoires: config.filters.accessoires,
zone: config.filters.zone,
author: config.filters.author,
limit: config.filters.limit,
offset: config.filters.offset,
numeroRangeStart: config.filters.numeroRangeStart!,
numeroRangeEnd: config.filters.numeroRangeEnd!,
tailleRangeStart: config.filters.tailleRangeStart!,
tailleRangeEnd: config.filters.tailleRangeEnd!,
participantsRangeStart: config.filters.participantsRangeStart!,
participantsRangeEnd: config.filters.participantsRangeEnd!,
hauteurRangeStart: config.filters.hauteurRangeStart!,
hauteurRangeEnd: config.filters.hauteurRangeEnd!
};
*/
const params: ProductListFilters = {} as ProductListFilters;
Object.assign(params, config.filters);
return this.apiService
.get(
'/products' + ((config.type === 'feed') ? '/feed' : ''),
new HttpParams({ fromObject: <{
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params })
);
}
get(slug: string): Observable<ProductPageData> {
return this.apiService.get(`/products/${slug}`);
}
getAll(): Observable<Array<Product>> {
return this.apiService.get('/products').pipe(map(data => data.products));
}
getAllByCategorie(): Observable<Array<Product>> {
return this.apiService.get('/products/allByCategorie').pipe(map(data => data.products));
}
create(product: Product): Observable<Product> {
return this.apiService.post('/products/', { product: product }).pipe(map(data => data.product));
}
update(product: Product): Observable<Product> {
return this.apiService.put(`/products/${product.slug}`, { product: product }).pipe(map(data => data.product));
}
destroy(slug: string): Observable<boolean> {
return this.apiService.delete(`/products/${slug}`).pipe(map(data => data.deleted));
}
save(product: Product): Observable<Product> {
// If we're updating an existing product
if (product.slug) {
return this.apiService.put(`/products/${product.slug}`, { product: product }).pipe(map(data => data.product));
// Otherwise, create a new product
} else {
return this.apiService.post('/products/', { product: product }).pipe(map(data => data.product));
}
}
}
+1 -1
View File
@@ -63,7 +63,7 @@ export class UserService implements OnDestroy {
attemptAuth(type: string, credentials?: { email: string; password: string; }): Observable<{ user: User }> {
const route = (type === 'login') ? '/login' : '';
const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`/users${route}`, { user: credentials });
const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`/user${route}`, { user: credentials });
/*return user$.pipe(map(
(data: any) => {
this.setAuth(data.user);