diff --git a/CHANGELOG.md b/CHANGELOG.md index 682eae9f..86029b44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline * **(widgets)**: les widgets tiennent désormais compte de l'Ionicon ou bien des icônes SVG renseignées du côté du CMS et les affichent à côté du titre de la Widget #### New features +* **(calendar)** : Il est désormais possible de choisir entre 2 affichages pour la widget des évènements du calendrier : + * Liste verticale (list) + * Slider horizontal (slider) * **(schedule)** : Il est désormais possible de choisir entre 2 affichages pour la widget des prochains cours à venir : * Liste verticale (list) * Slider horizontal (slider) diff --git a/dev/user-frontend-ionic/projects/calendar/README.md b/dev/user-frontend-ionic/projects/calendar/README.md index 2fa0c2d2..55146775 100644 --- a/dev/user-frontend-ionic/projects/calendar/README.md +++ b/dev/user-frontend-ionic/projects/calendar/README.md @@ -1,22 +1,19 @@ # Calendar Module permettant d'afficher un calendrier avec les prochains événements sur la page d'accueil. -## Widget -- `calendar` : Widget qui affiche les prochains évènements de l'agenda de l'utilisateur. - ## Configuration -Exemple dans `app.module.ts` : +Exemple dans `environment.ts` : ```typescript -@NgModule({ - declarations: [AppComponent], - imports: [ - CalendarModule.forRoot({ - numberOfEventsLimit: 3 - }) - ] +CalendarModule.forRoot({ + numberOfEventsLimit: 3, + display: 'slider' }) ``` +## Widget +- `calendar` : Widget qui affiche les prochains évènements de l'agenda de l'utilisateur. + ### Configuration du widget - `numberOfEventsLimit` : nombre maximum des prochains évènements à afficher. +- `display` : ("list" | "slider") : choix de la vue, en liste ou en ligne diff --git a/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.config.ts b/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.config.ts index 839ee16d..6467e988 100644 --- a/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.config.ts +++ b/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.config.ts @@ -41,6 +41,7 @@ import { InjectionToken } from '@angular/core'; export interface CalendarModuleConfig { numberOfEventsLimit: number; + display: "list" | "slider"; } export const CALENDAR_CONFIG = diff --git a/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.module.ts b/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.module.ts index ee08fde1..3256be75 100644 --- a/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.module.ts +++ b/dev/user-frontend-ionic/projects/calendar/src/lib/calendar.module.ts @@ -38,11 +38,12 @@ */ import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core'; -import { ProjectModuleService } from '@multi/shared'; +import { LocalHourPipe, ProjectModuleService, SharedPipeModule } from '@multi/shared'; import { CalendarComponent } from './widget/calendar/calendar.component'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; import { TranslateModule } from '@ngx-translate/core'; +import { CompleteLocalDatePipe } from '@multi/shared'; import { LocalDatePipe } from './common/pipe/local-date.pipe'; import { LocalTimePipe } from './common/pipe/local-time.pipe'; import { CALENDAR_CONFIG, CalendarModuleConfig } from './calendar.config'; @@ -66,14 +67,18 @@ const initModule = (projectModuleService: ProjectModuleService) => imports: [ CommonModule, IonicModule, - TranslateModule + TranslateModule, + SharedPipeModule ], providers: [{ provide: APP_INITIALIZER, useFactory: initModule, deps:[ProjectModuleService], multi: true - }], + }, + CompleteLocalDatePipe, + LocalHourPipe + ], }) export class CalendarModule { static forRoot(config: CalendarModuleConfig): ModuleWithProviders { diff --git a/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.html b/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.html index 42cfbbb5..c75d1740 100644 --- a/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.html +++ b/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.html @@ -37,26 +37,77 @@ ~ termes. --> - - - - - - - {{'CALENDAR.NO_EVENTS' | translate}} + + + + + + + - - - - {{event.startDateTime | localDate}} - {{event.startDateTime | localTime}}-{{event.endDateTime | localTime}} - - - {{event.label}} - {{event.location}} + + + + {{'CALENDAR.NO_EVENTS' | translate}} + + + + + {{event.startDateTime | localDate}} + {{event.startDateTime | localTime}}-{{event.endDateTime | localTime}} + + + {{event.label}} + {{event.location}} + + +
-
-
-
-
-
+ + + + + + + + + + + + + + + + + + {{'CALENDAR.NO_EVENTS' | translate}} + + + + + + + {{event.startDateTime | localHour}} - {{event.endDateTime | localHour}} + + + {{completeLocalDate | slice: 0:completeLocalDate.indexOf(' ')}} + {{completeLocalDate | slice: completeLocalDate.indexOf(' ')}} + + + + {{event.label}} + + + + {{event.location}} + + + + + + + + + + + diff --git a/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.ts b/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.ts index e369e87e..d6d06bfc 100644 --- a/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.ts +++ b/dev/user-frontend-ionic/projects/calendar/src/lib/widget/calendar/calendar.component.ts @@ -37,12 +37,13 @@ * termes. */ -import { AfterViewInit, ChangeDetectorRef, Component, Input } from '@angular/core'; +import { AfterViewInit, ChangeDetectorRef, Component, Inject, Input, TemplateRef, ViewChild } from '@angular/core'; import { ThemeService } from '@multi/shared'; import { Observable } from 'rxjs'; import { finalize, take } from 'rxjs/operators'; import { MailCalendarEvents } from '../../calendar.repository'; import { CalendarService } from '../../calendar.service'; +import { CALENDAR_CONFIG, CalendarModuleConfig } from '../../calendar.config'; @Component({ selector: 'app-calendar-widget', @@ -52,13 +53,16 @@ import { CalendarService } from '../../calendar.service'; export class CalendarComponent implements AfterViewInit{ @Input() widgetColor: string; + @ViewChild('list') list!: TemplateRef; + @ViewChild('slider') slider!: TemplateRef; public isLoading = false; public nextEvents$: Observable; constructor(private calendarService: CalendarService, private themeService: ThemeService, - private changeDetectorRef: ChangeDetectorRef) { + private changeDetectorRef: ChangeDetectorRef, + @Inject(CALENDAR_CONFIG) private config: CalendarModuleConfig) { this.nextEvents$ = this.calendarService.getNextEvents$(); } @@ -80,4 +84,8 @@ export class CalendarComponent implements AfterViewInit{ return this.themeService.isBackgroundFromCmsDarkOrIsDarkTheme(this.widgetColor) ? 'light-font-color' : 'dark-font-color'; } + + getTemplateRef(): TemplateRef { + return this[this?.config.display]; + } } diff --git a/dev/user-frontend-ionic/projects/schedule/src/lib/schedule.module.ts b/dev/user-frontend-ionic/projects/schedule/src/lib/schedule.module.ts index 783367a4..1bc84881 100644 --- a/dev/user-frontend-ionic/projects/schedule/src/lib/schedule.module.ts +++ b/dev/user-frontend-ionic/projects/schedule/src/lib/schedule.module.ts @@ -44,9 +44,8 @@ import { FullCalendarModule } from '@fullcalendar/angular'; // must go before pl import { IonicModule } from '@ionic/angular'; import { EffectsNgModule } from '@ngneat/effects-ng'; import { TranslateModule } from '@ngx-translate/core'; -import { CompleteLocalDatePipe, ProjectModuleService, SharedComponentsModule, SharedPipeModule } from '@multi/shared'; +import { CompleteLocalDatePipe, LocalHourPipe, ProjectModuleService, SharedComponentsModule, SharedPipeModule } from '@multi/shared'; import { EventDetailComponent } from './common/event-detail/event-detail.component'; -import { LocalHourPipe } from './common/pipe/local-hour.pipe'; import { ShortenedDatePipe } from './common/pipe/shortened-date.pipe'; import { HiddenCourseComponent } from './common/select-planning/hidden-course/hidden-course.component'; import { SelectPlanningComponent } from './common/select-planning/select-planning.component'; @@ -81,7 +80,6 @@ const initModule = (projectModuleService: ProjectModuleService) => SchedulePage, ScheduleListPage, ScheduleCalendarComponent, - LocalHourPipe, ShortenedDatePipe, EventDetailComponent, SelectPlanningComponent, @@ -108,7 +106,8 @@ const initModule = (projectModuleService: ProjectModuleService) => deps: [ProjectModuleService], multi: true }, - CompleteLocalDatePipe + CompleteLocalDatePipe, + LocalHourPipe ], }) export class ScheduleModule { diff --git a/dev/user-frontend-ionic/projects/schedule/src/lib/common/pipe/local-hour.pipe.ts b/dev/user-frontend-ionic/projects/shared/src/lib/pipe/local-hour.pipe.ts similarity index 100% rename from dev/user-frontend-ionic/projects/schedule/src/lib/common/pipe/local-hour.pipe.ts rename to dev/user-frontend-ionic/projects/shared/src/lib/pipe/local-hour.pipe.ts diff --git a/dev/user-frontend-ionic/projects/shared/src/lib/pipe/shared-pipe.module.ts b/dev/user-frontend-ionic/projects/shared/src/lib/pipe/shared-pipe.module.ts index 9b9eece5..8fbeb015 100644 --- a/dev/user-frontend-ionic/projects/shared/src/lib/pipe/shared-pipe.module.ts +++ b/dev/user-frontend-ionic/projects/shared/src/lib/pipe/shared-pipe.module.ts @@ -44,17 +44,20 @@ import { TranslateModule } from '@ngx-translate/core'; import { CompleteLocalDatePipe } from './complete-local-date-pipe'; import { RelativeTimePipe } from './relative-time-pipe'; import { TruncatePipe } from './truncate-pipe'; +import { LocalHourPipe } from './local-hour.pipe'; @NgModule({ declarations: [ RelativeTimePipe, TruncatePipe, - CompleteLocalDatePipe + CompleteLocalDatePipe, + LocalHourPipe ], exports: [ RelativeTimePipe, TruncatePipe, - CompleteLocalDatePipe + CompleteLocalDatePipe, + LocalHourPipe ], imports: [ CommonModule, diff --git a/dev/user-frontend-ionic/projects/shared/src/public-api.ts b/dev/user-frontend-ionic/projects/shared/src/public-api.ts index 620098c0..2f1c5043 100644 --- a/dev/user-frontend-ionic/projects/shared/src/public-api.ts +++ b/dev/user-frontend-ionic/projects/shared/src/public-api.ts @@ -70,6 +70,7 @@ export * from './lib/network/network.service'; export * from './lib/notifications/notifications.repository'; export * from './lib/notifications/notifications.service'; export * from './lib/pipe/complete-local-date-pipe'; +export * from './lib/pipe/local-hour.pipe'; export * from './lib/pipe/relative-time-pipe'; export * from './lib/pipe/shared-pipe.module'; export * from './lib/pipe/truncate-pipe'; diff --git a/dev/user-frontend-ionic/src/environments/environment.ts.dist b/dev/user-frontend-ionic/src/environments/environment.ts.dist index 85a833ab..5b7d8328 100644 --- a/dev/user-frontend-ionic/src/environments/environment.ts.dist +++ b/dev/user-frontend-ionic/src/environments/environment.ts.dist @@ -75,7 +75,10 @@ export const environment: any = { appVersion: '1.0.0', enabledModules: [ AuthModule, - CalendarModule.forRoot({ numberOfEventsLimit: 3 }), + CalendarModule.forRoot({ + numberOfEventsLimit: 3, + display: 'list', + }), CardsPageModule.forRoot({ knownErrors: ['NO_PHOTO', 'NO_ACTIVE_CARD', 'UNPAID_FEES'] }), ChatbotModule.forRoot({ chatbotLogoRegex: /_chacha5/i }), ClockingModule, diff --git a/dev/user-frontend-ionic/src/theme/app-theme-dist/styles/calendar/calendar.component.scss b/dev/user-frontend-ionic/src/theme/app-theme-dist/styles/calendar/calendar.component.scss index 634d0b3a..b3656230 100644 --- a/dev/user-frontend-ionic/src/theme/app-theme-dist/styles/calendar/calendar.component.scss +++ b/dev/user-frontend-ionic/src/theme/app-theme-dist/styles/calendar/calendar.component.scss @@ -37,60 +37,175 @@ * termes. */ -.ion-padding { - padding-top: 5px !important; -} - -.events-container { - padding: 0; -} - -.event { - align-items: center; - padding: 0.5rem 0; -} - -hr { - border-top: 2px dashed var(--ion-color-primary-contrast); - margin: 0; -} +.calendar-list-style { -.event-part ion-text { - display: block -} + display: block; -.event-part-date { - flex-grow: 1; - text-align: center; - border-right: 5px solid var(--ion-color-primary-contrast); - margin-right: 5px; -} + .ion-padding { + padding-top: 5px !important; + } -.event-part-info { - flex-grow: 3; -} + .events-container { + padding: 0; + } -.light-font-color{ - color: var(--app-font-color-for-dark-background-from-cms) !important; + .event { + align-items: center; + padding: 0.5rem 0; + } hr { - border-top: 2px dashed var(--app-font-color-for-dark-background-from-cms); + border-top: 2px dashed var(--ion-color-primary-contrast); margin: 0; } + .event-part ion-text { + display: block + } + .event-part-date { - border-right: 5px solid var(--app-font-color-for-dark-background-from-cms); + flex-grow: 1; + text-align: center; + border-right: 5px solid var(--ion-color-primary-contrast); + margin-right: 5px; + } + + .event-part-info { + flex-grow: 3; + } + + .light-font-color{ + color: var(--app-font-color-for-dark-background-from-cms) !important; + + hr { + border-top: 2px dashed var(--app-font-color-for-dark-background-from-cms); + margin: 0; + } + + .event-part-date { + border-right: 5px solid var(--app-font-color-for-dark-background-from-cms); + } } + + .dark-font-color{ + color: var(--app-font-color-for-light-background-from-cms) !important; + + hr { + border-top: 2px dashed var(--app-font-color-for-light-background-from-cms); + } + + .event-part-date { + border-right: 5px solid var(--app-font-color-for-light-background-from-cms); + } + } + } -.dark-font-color{ - color: var(--app-font-color-for-light-background-from-cms) !important; +.calendar-slider-style { + display: block; - hr { - border-top: 2px dashed var(--app-font-color-for-light-background-from-cms); + ion-card { + scroll-snap-align: center; } - .event-part-date { - border-right: 5px solid var(--app-font-color-for-light-background-from-cms); + ion-card.slider-theme-color { + box-shadow: var(--app-border-no-box-shadow); + //border: var(--app-border-width-7) solid var(--app-border-color-primary); + background-color: var(--ion-color-tertiary); + } + + ion-card-content { + padding: 0.7rem 0; + height: 100%; + display: flex; + flex-direction: column; + } + + .events-container { + padding: .5rem 0 0; + display: grid; + gap: 1rem; + grid-auto-flow: column; + grid-template-columns: 10px; + grid-auto-columns: 85%; + overflow-x: auto; + scrollbar-width: none; + scroll-snap-type: x mandatory; + overscroll-behavior-x: contain; + + &::-webkit-scrollbar { + display: none; + } + + &::before, + &::after { + content: ''; + width: 10px; + } + + .event-day-hour { + display: flex; + flex-direction: row; + border-left-width: 4px; + border-left-style: solid; + align-items: center; + flex-wrap: nowrap; + border-color: var(--ion-color-secondary); + + .hour { + padding-left: 1rem; + display: block; + } + + .day { + padding-left: 1rem; + display: block; + + ion-text { + display: block; + } + } + } } + + .card-labels { + margin-right: 0.6rem; + } + + .card-labels-icons { + margin-right: 0.3rem; + } + + .event-label { + padding: 1rem 1rem 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .event-additional { + display: flex; + padding: 0.7rem 0.5rem 0; + justify-content: space-evenly; + flex-wrap: wrap; + flex-grow: 2; + align-items: center; + + ion-row:last-child { + margin-right: 0; + } + } + + .slider-font-color{ + color: var(--app-font-fix-light-color) !important; + } + + .light-font-color{ + color: var(--app-font-color-for-dark-background-from-cms) !important; + } + + .dark-font-color{ + color: var(--app-font-color-for-light-background-from-cms) !important; + } + }