From 211dbcfc1c3df87c881584166f7645ff16307c25 Mon Sep 17 00:00:00 2001 From: Emmanuel Date: Mon, 16 Dec 2024 13:59:10 +0000 Subject: [PATCH] fix: eslint --- eslint.config.mjs | 10 ++++- functions/src/cms4devfest.ts | 6 +-- .../src/emails/template/relancePaiement.ts | 4 +- .../emails/template/step-5-billet-web-url.ts | 2 +- functions/src/generator/lib/generator.ts | 1 + .../lib/template_devfest/convention_en.ts | 2 +- .../lib/template_devfest/convention_fr.ts | 2 +- functions/src/model.ts | 35 +++++++++------ functions/src/utils/document-change.ts | 4 +- functions/src/v3/domain/sendToWebhooks.ts | 2 +- public/src/app/model/company.ts | 6 ++- .../dashboard/dashboard-filter.component.ts | 9 ++-- .../dashboard/dashboard.component.ts | 44 +++++++++++++++---- .../private-dashboard.component.html | 1 - .../private-dashboard.component.ts | 10 ----- public/src/app/ui/filled/filled.component.ts | 6 ++- public/src/environments/environment.type.ts | 4 +- 17 files changed, 94 insertions(+), 54 deletions(-) delete mode 100644 public/src/app/private-dashboard/private-dashboard.component.html delete mode 100644 public/src/app/private-dashboard/private-dashboard.component.ts diff --git a/eslint.config.mjs b/eslint.config.mjs index b6ba310..50baa97 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -7,11 +7,17 @@ export default [ { files: ['**/*.{js,mjs,cjs,ts}'] }, { languageOptions: { globals: globals.browser } }, pluginJs.configs.recommended, - ...tseslint.configs.recommended, + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, { rules: { '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-require-imports': 'off' + '@typescript-eslint/no-require-imports': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-extraneous-class': 'off', + '@typescript-eslint/no-confusing-non-null-assertion': 'off', + '@typescript-eslint/no-empty-function': 'off' } } ]; diff --git a/functions/src/cms4devfest.ts b/functions/src/cms4devfest.ts index 3c4d01d..d688181 100644 --- a/functions/src/cms4devfest.ts +++ b/functions/src/cms4devfest.ts @@ -62,21 +62,21 @@ export const relancePartnaireConventionASigner = functions.https.onCall(async () const configuration = await getConfiguration(firestore); const data = await firestore.collection('companies-2025').get(); const partners = data.docs.map((d) => d.data()).filter((p) => p.status.sign === StatusEnum.PENDING); - relance(relanceConventionSignee, partners, configuration); + relance(relanceConventionSignee, partners as Company[], configuration); }); export const relancePartnaireFacture = functions.https.onCall(async () => { const configuration = await getConfiguration(firestore); const data = await firestore.collection('companies-2025').get(); const partners = data.docs.map((d) => d.data()).filter((p) => p.status.paid === StatusEnum.PENDING); - relance(relancePaiement, partners, configuration); + relance(relancePaiement, partners as Company[], configuration); }); export const relanceInformationPourGeneration = functions.https.onCall(async () => { const configuration = await getConfiguration(firestore); const data = await firestore.collection('companies-2025').get(); const partners = data.docs.map((d) => d.data()).filter((p) => p.status.generated === StatusEnum.PENDING); - relance(relanceInformationsComplementaires, partners, configuration); + relance(relanceInformationsComplementaires, partners as Company[], configuration); }); export const newPartner = functions.firestore.document('companies-2025/{companyId}').onCreate(async (snap) => { diff --git a/functions/src/emails/template/relancePaiement.ts b/functions/src/emails/template/relancePaiement.ts index 3f8d59f..1e8c925 100644 --- a/functions/src/emails/template/relancePaiement.ts +++ b/functions/src/emails/template/relancePaiement.ts @@ -1,6 +1,6 @@ -import { Configuration } from '../../model'; +import { Company, Configuration } from '../../model'; -export default (partner: Record, configuration: Configuration) => { +export default (partner: Company, configuration: Configuration) => { return { subject: `Partenariat ${configuration.gdg.event} ${configuration.convention.edition}: Relance Paiement`, body: ` diff --git a/functions/src/emails/template/step-5-billet-web-url.ts b/functions/src/emails/template/step-5-billet-web-url.ts index 2039cf5..fd0342c 100644 --- a/functions/src/emails/template/step-5-billet-web-url.ts +++ b/functions/src/emails/template/step-5-billet-web-url.ts @@ -34,7 +34,7 @@ ${configuration.mail.signature} ${configuration.convention.edition} }); export default (company: Company, configuration: Configuration) => { - const billetWebUrl = company.billetWebUrl!; + const billetWebUrl = company.billetWebUrl ?? ''; if (company.sponsoring === 'Platinium' || company.sponsoring === 'Gold' || company.sponsoring === 'Silver') { return generateEmailForSponsorWithStand(billetWebUrl, configuration); } diff --git a/functions/src/generator/lib/generator.ts b/functions/src/generator/lib/generator.ts index d1653a7..c714ff2 100644 --- a/functions/src/generator/lib/generator.ts +++ b/functions/src/generator/lib/generator.ts @@ -71,6 +71,7 @@ function generateFile(company: Company, fileName: string, fileModule: { default: PO: company.PO, SPONSORING_TEXT, SPONSORING_NUMBER: total, + INSTALLATION_DATE: configuration.convention.installationdate, START_DATE: configuration.convention.startdate, END_DATE: configuration.convention.enddate, DATE, diff --git a/functions/src/generator/lib/template_devfest/convention_en.ts b/functions/src/generator/lib/template_devfest/convention_en.ts index 1b6fc0a..b8fc093 100644 --- a/functions/src/generator/lib/template_devfest/convention_en.ts +++ b/functions/src/generator/lib/template_devfest/convention_en.ts @@ -42,7 +42,7 @@ As indicated in the invoice, here are the Banking Information of the association - BIC QNTOFRP1XXX <% if (HAS_BOOTH === 'true') { %> -The Partner is committed to install its stand on June, the 5th. A security team will be present the night in the exhibition room. +The Partner is committed to install its stand on <%= INSTALLATION_DATE %>. A security team will be present the night in the exhibition room. <% } %> diff --git a/functions/src/generator/lib/template_devfest/convention_fr.ts b/functions/src/generator/lib/template_devfest/convention_fr.ts index 2a2db84..d130c32 100644 --- a/functions/src/generator/lib/template_devfest/convention_fr.ts +++ b/functions/src/generator/lib/template_devfest/convention_fr.ts @@ -51,7 +51,7 @@ Comme indiqué sur le devis, vous trouverez ci-dessous les informations bancaire - BIC QNTOFRP1XXX <% if (HAS_BOOTH === 'true') { %> -Le partenaire s'engage à installer son stand le mercredi 5 juin après-midi entre 14h et 18h. Une équipe de sécurité sera présente la nuit pour surveiller la zone d'expositions. +Le partenaire s'engage à installer son stand le <%= INSTALLATION_DATE %> après-midi entre 14h et 18h. Une équipe de sécurité sera présente la nuit pour surveiller la zone d'expositions. Le stand doit respecter les contraintes suivante : - ne pas dépasser 2.4m de hauteur sur la panneau du fond diff --git a/functions/src/model.ts b/functions/src/model.ts index 3da2538..36af61f 100644 --- a/functions/src/model.ts +++ b/functions/src/model.ts @@ -1,18 +1,22 @@ import { Timestamp } from 'firebase-admin/firestore'; -export type EmailContent = { subject: string; body: string }; +export interface EmailContent { + subject: string; + body: string; +} -export type Convention = { +export interface Convention { edition: string; startdate: string; enddate: string; -}; + installationdate: string; +} -export type Hosting = { +export interface Hosting { baseurl: string; -}; +} -export type Association = { +export interface Association { address: string; zipcode: string; city: string; @@ -20,9 +24,9 @@ export type Association = { tel: string; accountantemail: string; website: string; -}; +} -export type Email = { +export interface Email { mailgun: string; mailgun_email: 'mailgun@sandbox07d5e9881cce48d691889e3818d67885.mailgun.org'; enabled: string; @@ -31,15 +35,15 @@ export type Email = { from: string; fromname: string; cc: string; -}; +} -export type Mailjet = { +export interface Mailjet { api: string; private: string; -}; +} export type SponsoringType = Record; -export type SponsorshipConfiguration = { +export interface SponsorshipConfiguration { freeTickets: number; name: string; price: number; @@ -47,7 +51,7 @@ export type SponsorshipConfiguration = { considerations: string[]; considerationsEn: string[]; hasBooth: boolean; -}; +} export type Configuration = SponsoringType & { next_value: string; @@ -63,7 +67,10 @@ export type Configuration = SponsoringType & { template_folder: string; }; -export type SponsoringOption = { label: string; price: number }; +export interface SponsoringOption { + label: string; + price: number; +} export type SponsoringOptions = SponsoringOption[]; export interface WorkflowStatus { diff --git a/functions/src/utils/document-change.ts b/functions/src/utils/document-change.ts index 37b4aa1..4797c9d 100644 --- a/functions/src/utils/document-change.ts +++ b/functions/src/utils/document-change.ts @@ -21,8 +21,8 @@ export enum StatusEnum { export async function onDocumentChange(firestore: FirebaseFirestore.Firestore, before: Company, after: Company, id: string, configuration: Configuration) { const document = firestore.doc('companies-2025/' + id); console.log(`onDocumentChange ${id}: ${JSON.stringify(before.status)} -> ${JSON.stringify(after.status)}`); - const status = after.status!; - const beforeStatus = before.status!; + const status = after.status ?? {}; + const beforeStatus = before.status ?? {}; if (status.generated === StatusEnum.PENDING) { if (!!after.address && !!after.zipCode && !!after.city && !!after.siret && !!after.representant && !!after.role) { return document.update({ diff --git a/functions/src/v3/domain/sendToWebhooks.ts b/functions/src/v3/domain/sendToWebhooks.ts index 307880c..1a8db2c 100644 --- a/functions/src/v3/domain/sendToWebhooks.ts +++ b/functions/src/v3/domain/sendToWebhooks.ts @@ -7,7 +7,7 @@ import { Configuration } from '../../model'; export const sendToWebhooks = async (configuration: Configuration, changes: Change) => { const length = configuration.webhooks?.length ?? 0; if (length > 0) { - for (const webhook of configuration.webhooks!) { + for (const webhook of configuration.webhooks ?? []) { console.log(`Sending to webhook ${webhook} information about ${changes.after.data().name}`); await axios.post(webhook, { id: changes.after.id, diff --git a/public/src/app/model/company.ts b/public/src/app/model/company.ts index 062df14..62deff3 100644 --- a/public/src/app/model/company.ts +++ b/public/src/app/model/company.ts @@ -20,7 +20,11 @@ export type Configuration = SponsoringType & { sponsoringOptions?: SponsoringOption[]; } & z.infer; -export type SponsoringOption = { key: string; label: string; price: number }; +export interface SponsoringOption { + key: string; + label: string; + price: number; +} export interface Workflow { id: number; steps: WorkflowStep[]; diff --git a/public/src/app/private-dashboard/dashboard/dashboard-filter.component.ts b/public/src/app/private-dashboard/dashboard/dashboard-filter.component.ts index baf128e..729a3c2 100644 --- a/public/src/app/private-dashboard/dashboard/dashboard-filter.component.ts +++ b/public/src/app/private-dashboard/dashboard/dashboard-filter.component.ts @@ -4,15 +4,18 @@ import { MatExpansionModule } from '@angular/material/expansion'; type FilterValueType = 'sign' | 'generated' | 'validated' | 'paid' | 'received' | 'communicated' | 'code'; -type Option = { value: FilterValueType | string; label: string }; +interface Option { + value: FilterValueType | string; + label: string; +} type Options = Option[]; type OptionWithChecked = Option & { checked: boolean }; -export type Search = { +export interface Search { status: string[]; packs: string[]; types: string[]; -}; +} const PackOptions: Options = [ { value: 'bronze', label: `Bronze` }, diff --git a/public/src/app/private-dashboard/dashboard/dashboard.component.ts b/public/src/app/private-dashboard/dashboard/dashboard.component.ts index 4de3517..dd608fc 100644 --- a/public/src/app/private-dashboard/dashboard/dashboard.component.ts +++ b/public/src/app/private-dashboard/dashboard/dashboard.component.ts @@ -1,5 +1,6 @@ import { CommonModule } from '@angular/common'; -import { AfterViewInit, Component, computed, inject, linkedSignal, signal, viewChild } from '@angular/core'; +import { AfterViewInit, Component, computed, effect, inject, linkedSignal, signal, viewChild } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; import { Timestamp } from '@angular/fire/firestore'; import { Functions, httpsCallable } from '@angular/fire/functions'; import { FormsModule } from '@angular/forms'; @@ -11,11 +12,18 @@ import { MatExpansionModule } from '@angular/material/expansion'; import { MatRadioModule } from '@angular/material/radio'; import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { ActivatedRoute, Router } from '@angular/router'; import { Company, Configuration, WorkflowStatus } from '../../model/company'; import { PartnerService } from '../../services/partner.service'; import { DashboardFilterComponent, Search } from './dashboard-filter.component'; +const DefaultSearchValue = { + status: ['sign', 'generated', 'validated', 'paid', 'received', 'communicated', 'code'], + packs: ['bronze', 'silver', 'gold', 'party'], + types: ['esn', 'other', 'undefined'] +}; + @Component({ selector: 'cms-dashboard', imports: [ @@ -35,12 +43,35 @@ import { DashboardFilterComponent, Search } from './dashboard-filter.component'; styleUrls: ['./dashboard.component.css'] }) export class DashboardComponent implements AfterViewInit { - value = signal({ - status: ['sign', 'generated', 'validated', 'paid', 'received', 'communicated', 'code'], - packs: ['bronze', 'silver', 'gold', 'party'], - types: ['esn', 'other', 'undefined'] + private readonly partnerService: PartnerService = inject(PartnerService); + private readonly functions: Functions = inject(Functions); + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + + private readonly queryParameters = toSignal(this.route.queryParams); + + value = linkedSignal(() => { + const queryParameterValues = this.queryParameters(); + if (queryParameterValues && Object.keys(queryParameterValues).length > 0) { + return { + status: queryParameterValues['status']?.split(',') ?? [], + packs: queryParameterValues['packs']?.split(',') ?? [], + types: queryParameterValues['types']?.split(',') ?? [] + }; + } + return DefaultSearchValue; }); + syncParams = effect(() => { + this.router.navigate([], { + queryParams: { + status: this.value().status?.join(','), + packs: this.value().packs?.join(','), + types: this.value().types?.join(',') + }, + queryParamsHandling: 'merge' + }); + }); readonly sort = viewChild.required(MatSort); onFilterChange = (search: Search) => { @@ -75,9 +106,6 @@ export class DashboardComponent implements AfterViewInit { return dataSource; }); - private readonly partnerService: PartnerService = inject(PartnerService); - private readonly functions: Functions = inject(Functions); - async relance() { const status = this.value().status; if (status[0] === 'generated') { diff --git a/public/src/app/private-dashboard/private-dashboard.component.html b/public/src/app/private-dashboard/private-dashboard.component.html deleted file mode 100644 index 386c7fb..0000000 --- a/public/src/app/private-dashboard/private-dashboard.component.html +++ /dev/null @@ -1 +0,0 @@ -

private-dashboard works!

diff --git a/public/src/app/private-dashboard/private-dashboard.component.ts b/public/src/app/private-dashboard/private-dashboard.component.ts deleted file mode 100644 index 14ca88b..0000000 --- a/public/src/app/private-dashboard/private-dashboard.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; - -@Component({ - selector: 'cms-private-dashboard', - standalone: true, - imports: [CommonModule], - templateUrl: './private-dashboard.component.html' -}) -export class PrivateDashboardComponent {} diff --git a/public/src/app/ui/filled/filled.component.ts b/public/src/app/ui/filled/filled.component.ts index 967b22e..aa5fa0f 100644 --- a/public/src/app/ui/filled/filled.component.ts +++ b/public/src/app/ui/filled/filled.component.ts @@ -3,6 +3,8 @@ import { Component } from '@angular/core'; @Component({ selector: 'cms-filled', imports: [], - template: `

Nous avons bien pris en compte votre souhait de devenir partenaire et nous vous en remercions.

` + template: `

{{ message }}

` }) -export class FilledComponent {} +export class FilledComponent { + message = 'Nous avons bien pris en compte votre souhait de devenir partenaire et nous vous en remercions.'; +} diff --git a/public/src/environments/environment.type.ts b/public/src/environments/environment.type.ts index da36fb0..07813f3 100644 --- a/public/src/environments/environment.type.ts +++ b/public/src/environments/environment.type.ts @@ -1,6 +1,6 @@ -export type Environement = { +export interface Environement { firebase?: Record; emailDomain: string; files: Record; title: string; -}; +}