diff --git a/api/src/App.js b/api/src/App.js index 9380accb8..eb3ea3b4d 100644 --- a/api/src/App.js +++ b/api/src/App.js @@ -168,11 +168,7 @@ export default class App extends AppBase { //...scriptSha1Generate([`${__dirname}/front/index.html`]), ], 'default-src': ["'none'"], - 'style-src': [ - "'self'", - ...styleSha1Generate([`${__dirname}/front/index.html`]), - 'cdnjs.cloudflare.com', - ], + 'style-src': ["'self'", ...styleSha1Generate([`${__dirname}/front/index.html`]), 'cdnjs.cloudflare.com'], 'worker-src': ['blob:'], 'frame-src': [ 'https://app.videas.fr/', diff --git a/api/src/models/TableHumanresources.js b/api/src/models/TableHumanresources.js index cfa96021f..4f17ce2c4 100644 --- a/api/src/models/TableHumanresources.js +++ b/api/src/models/TableHumanresources.js @@ -305,6 +305,19 @@ export default (sequelizeInstance, Model) => { } else situation.category_id = findCategory.id } + let findHRToDBByMatricule = await Model.findOne({ + where: { + backup_id: backupId, + matricule: list[i].hmatricule, + }, + logging: false, + }) + + if (list[i].hmatricule !== '' && findHRToDBByMatricule) { + importSituation.push(list[i].hmatricule + ' no add by matricule already existing') + continue + } + switch (code) { case 'MHFJS': code = 'MHFJ' @@ -397,7 +410,7 @@ export default (sequelizeInstance, Model) => { // prepare person const options = { first_name: list[i].prenom || '', - last_name: list[i].nom_usage || list[i].nom_marital || '', + last_name: list[i].nom_usage || list[i].nom_marital || list[i].nom || '', matricule: list[i].hmatricule || '', backup_id: backupId, registration_number: list[i].hRegMatricule, diff --git a/api/src/models/TableTj.js b/api/src/models/TableTj.js index 0bcf3330a..eff432c19 100644 --- a/api/src/models/TableTj.js +++ b/api/src/models/TableTj.js @@ -1,5 +1,5 @@ import { groupBy, sumBy } from 'lodash' -import { preformatHumanResources } from '../utils/ventilator' +import { listCategories } from '../utils/ventilator' export default (sequelizeInstance, Model) => { Model.getAll = async () => { @@ -15,7 +15,7 @@ export default (sequelizeInstance, Model) => { for (let i = 0; i < list.length; i++) { list[i].users = await Model.models.UserVentilations.getUserVentilationsWithLabel(list[i].label) const getBackupId = await Model.models.HRBackups.findByLabel(list[i].label) - const agents = getBackupId ? preformatHumanResources(await Model.models.HumanResources.getCache(getBackupId)) : [] + const agents = getBackupId ? listCategories(await Model.models.HumanResources.getCache(getBackupId)) : [] const group = groupBy( agents.filter((a) => a.category), 'category.label' diff --git a/api/src/routes-api/RouteCalculator.js b/api/src/routes-api/RouteCalculator.js index 56711fee5..d7326415d 100644 --- a/api/src/routes-api/RouteCalculator.js +++ b/api/src/routes-api/RouteCalculator.js @@ -117,7 +117,7 @@ export default class RouteCalculator extends Route { case 'stocks': { const activites = await this.models.Activities.getByMonth(dateStart, backupId, contentieuxId, false) - if (activites.length) { + if (activites && activites.length) { const acti = activites[0] if (acti.stock !== null) { list.push(acti.stock) diff --git a/api/src/routes-api/RouteContentieuxOptions.js b/api/src/routes-api/RouteContentieuxOptions.js index e8b123901..2c98518ed 100644 --- a/api/src/routes-api/RouteContentieuxOptions.js +++ b/api/src/routes-api/RouteContentieuxOptions.js @@ -10,7 +10,7 @@ export default class RouteContentieuxOptions extends Route { * Constructeur * @param {*} params */ - constructor(params) { + constructor (params) { super({ ...params, model: 'ContentieuxOptions' }) } @@ -26,7 +26,7 @@ export default class RouteContentieuxOptions extends Route { }), accesses: [Access.canVewContentieuxOptions], }) - async getAll(ctx) { + async getAll (ctx) { let { juridictionId, backupId } = this.body(ctx) const backups = await this.model.models.OptionsBackups.getBackup(ctx.state.user.id, juridictionId) backupId = backups.find((b) => b.id === backupId) ? backupId : backups.length ? backups[backups.length - 1].id : null @@ -44,7 +44,7 @@ export default class RouteContentieuxOptions extends Route { path: 'remove-backup/:backupId', accesses: [Access.canVewContentieuxOptions], }) - async removeBackup(ctx) { + async removeBackup (ctx) { const { backupId } = ctx.params await this.model.models.OptionsBackups.removeBackup(backupId) @@ -68,7 +68,7 @@ export default class RouteContentieuxOptions extends Route { }), accesses: [Access.canVewContentieuxOptions], }) - async duplicateBackup(ctx) { + async duplicateBackup (ctx) { const { backupId, backupName, backupStatus, type, juridictionId } = this.body(ctx) if (await this.models.OptionsBackups.haveAccess(backupId, juridictionId, ctx.state.user.id)) { @@ -96,7 +96,7 @@ export default class RouteContentieuxOptions extends Route { }), accesses: [Access.canVewContentieuxOptions], }) - async saveBackup(ctx) { + async saveBackup (ctx) { const { backupId, list, backupName, juridictionId, backupStatus, type } = this.body(ctx) if ( (backupId && (await this.models.OptionsBackups.haveAccess(backupId, juridictionId, ctx.state.user.id))) || @@ -104,7 +104,7 @@ export default class RouteContentieuxOptions extends Route { ) { const newId = await this.model.models.OptionsBackups.saveBackup(ctx.state.user.id, list, backupId, backupName, juridictionId, backupStatus, type) - await this.model.models.HistoriesContentieuxUpdate.addHistory(ctx.state.user.id, newId) + if (newId !== null) await this.model.models.HistoriesContentieuxUpdate.addHistory(ctx.state.user.id, newId) this.sendOk(ctx, newId) } else { @@ -126,7 +126,7 @@ export default class RouteContentieuxOptions extends Route { }), accesses: [Access.canVewContentieuxOptions], }) - async renameBackup(ctx) { + async renameBackup (ctx) { const { backupId, backupName, juridictionId } = this.body(ctx) if (await this.models.OptionsBackups.haveAccess(backupId, juridictionId, ctx.state.user.id)) { @@ -144,7 +144,7 @@ export default class RouteContentieuxOptions extends Route { @Route.Get({ accesses: [Access.isAdmin], }) - async getAllAdmin(ctx) { + async getAllAdmin (ctx) { const list = await this.models.OptionsBackups.adminGetAll() const juridictions = await this.models.HRBackups.findAll({ @@ -170,7 +170,7 @@ export default class RouteContentieuxOptions extends Route { }), accesses: [Access.isAdmin], }) - async updateBackup(ctx) { + async updateBackup (ctx) { const { id, juridictions } = this.body(ctx) await this.model.models.OptionsBackupJuridictions.changeRules(id, juridictions) @@ -185,7 +185,7 @@ export default class RouteContentieuxOptions extends Route { path: 'get-backup-details/:backupId', accesses: [Access.canVewContentieuxOptions], }) - async getBackupDetails(ctx) { + async getBackupDetails (ctx) { const { backupId } = ctx.params if (await this.models.OptionsBackups.haveAccessWithoutJuridiction(backupId, ctx.state.user.id)) { @@ -207,7 +207,7 @@ export default class RouteContentieuxOptions extends Route { }), accesses: [Access.canVewContentieuxOptions], }) - async getLastUpdate(ctx) { + async getLastUpdate (ctx) { const { backupId, juridictionId } = this.body(ctx) if (await this.models.OptionsBackups.haveAccess(backupId, juridictionId, ctx.state.user.id)) { diff --git a/api/src/routes/RouteIndex.js b/api/src/routes/RouteIndex.js index acb88b969..37bd7deeb 100644 --- a/api/src/routes/RouteIndex.js +++ b/api/src/routes/RouteIndex.js @@ -53,7 +53,7 @@ export default class RouteIndex extends Route { //stream.on('error', (streamErr) => res.end(streamErr)) } else { const src = createReadStream(file) - ctx.type = mime.getType(file) + ctx.type = mime.getType(file) || 'text/html' ctx.body = src } } else { diff --git a/api/src/utils/ventilator.js b/api/src/utils/ventilator.js index a2d0c6da5..2697123c8 100644 --- a/api/src/utils/ventilator.js +++ b/api/src/utils/ventilator.js @@ -5,7 +5,6 @@ import { findAllIndisponibilities } from './indisponibilities' import { fixDecimal } from './number' export const preformatHumanResources = (list, dateSelected, referentielList, fonctionsIds) => { - console.log('fonctionsIds', fonctionsIds) return orderBy( list.map((h) => { const indisponibilities = dateSelected ? findAllIndisponibilities(h, dateSelected) : [] @@ -63,3 +62,18 @@ export const preformatHumanResources = (list, dateSelected, referentielList, fon return isFiltered }) } + +export const listCategories = (list) => { + return list.map((h) => { + let currentSituation + const situations = h.situations || [] + if (situations.length) { + currentSituation = situations[0] + } + + return { + ...h, + category: currentSituation && currentSituation.category, + } + }) +} diff --git a/front/src/app/components/date-select/date-select.component.scss b/front/src/app/components/date-select/date-select.component.scss index 7e77fe6b4..009238d9d 100644 --- a/front/src/app/components/date-select/date-select.component.scss +++ b/front/src/app/components/date-select/date-select.component.scss @@ -155,6 +155,13 @@ opacity: 0.7; } + &.bottom-popin { + input { + left: -20px; + top: 100%; + } + } + p.title-select { color: fColor(titleSelect); white-space: nowrap; diff --git a/front/src/app/components/input-button/input-button.component.scss b/front/src/app/components/input-button/input-button.component.scss index d429db07f..2839dabec 100644 --- a/front/src/app/components/input-button/input-button.component.scss +++ b/front/src/app/components/input-button/input-button.component.scss @@ -28,6 +28,23 @@ background-color: fColor(darkModeBgMenu); border: 1px solid fColor(darkModeBgMenu); + &.search-bar { + .input { + .input-container { + input { + &::placeholder { + color: white; + opacity: 1; + } + } + + img { + filter: brightness(0) invert(1); + } + } + } + } + p, mat-icon, input { diff --git a/front/src/app/components/options-backup-panel/options-backup-panel.component.ts b/front/src/app/components/options-backup-panel/options-backup-panel.component.ts index d8699f630..9f2899967 100644 --- a/front/src/app/components/options-backup-panel/options-backup-panel.component.ts +++ b/front/src/app/components/options-backup-panel/options-backup-panel.component.ts @@ -163,9 +163,15 @@ export class OptionsBackupPanelComponent .onSaveDatas(isCopy, this.category) .then((x) => { if (isCopy && x !== null) { - //this.router.navigate(['/temps-moyens']) this.contentieuxOptionsService.optionsIsModify.next(false) } + if ( + isCopy === false && + x !== null && + this.contentieuxOptionsService.openedFromCockpit.getValue().value !== + true + ) + this.router.navigate(['/temps-moyens']) }) if ( this.contentieuxOptionsService.openedFromCockpit.getValue().value === true diff --git a/front/src/app/components/panel-activities/progression-bar/progression-bar.component.html b/front/src/app/components/panel-activities/progression-bar/progression-bar.component.html index 72ab13caa..3969854c4 100644 --- a/front/src/app/components/panel-activities/progression-bar/progression-bar.component.html +++ b/front/src/app/components/panel-activities/progression-bar/progression-bar.component.html @@ -1,5 +1,5 @@
-
DDG
+
DDG
diff --git a/front/src/app/components/panel-activities/progression-bar/progression-bar.component.scss b/front/src/app/components/panel-activities/progression-bar/progression-bar.component.scss index 00bfbabd5..708426e7e 100644 --- a/front/src/app/components/panel-activities/progression-bar/progression-bar.component.scss +++ b/front/src/app/components/panel-activities/progression-bar/progression-bar.component.scss @@ -18,6 +18,7 @@ .ddg { opacity: 1 !important; + z-index: 1; transform: rotate(-45deg); position: absolute; left: -16px; diff --git a/front/src/app/components/tooltips/tooltips.component.scss b/front/src/app/components/tooltips/tooltips.component.scss index a2e9c499a..6a6486d2f 100644 --- a/front/src/app/components/tooltips/tooltips.component.scss +++ b/front/src/app/components/tooltips/tooltips.component.scss @@ -16,6 +16,21 @@ } } + &.right .tooltip-text { + right: 0; + left: inherit; + + >div { + position: relative; + transform: translateX(0); + } + + .triangle { + right: 55px; + left: inherit; + } + } + &.top .tooltip-text { bottom: calc(85% + 4px); diff --git a/front/src/app/components/wrapper/wrapper.component.ts b/front/src/app/components/wrapper/wrapper.component.ts index 37571d1fb..5220e9e9a 100644 --- a/front/src/app/components/wrapper/wrapper.component.ts +++ b/front/src/app/components/wrapper/wrapper.component.ts @@ -297,6 +297,7 @@ export class WrapperComponent extends MainClass implements OnDestroy { */ onChangeHRBackup(id: number) { this.humanResourceService.backupId.next(id) + this.router.navigate(['/panorama']) } /** diff --git a/front/src/app/routes/average-etp/average-etp.page.scss b/front/src/app/routes/average-etp/average-etp.page.scss index 9522315e3..7d065f30f 100644 --- a/front/src/app/routes/average-etp/average-etp.page.scss +++ b/front/src/app/routes/average-etp/average-etp.page.scss @@ -409,6 +409,6 @@ .sticky-bar { position: sticky; top: 0; - z-index: 10; + z-index: 1; } } \ No newline at end of file diff --git a/front/src/app/routes/average-etp/average-etp.page.ts b/front/src/app/routes/average-etp/average-etp.page.ts index 036884a9e..0bdeb66fb 100644 --- a/front/src/app/routes/average-etp/average-etp.page.ts +++ b/front/src/app/routes/average-etp/average-etp.page.ts @@ -297,7 +297,6 @@ export class AverageEtpPage extends MainClass implements AfterViewInit { * Import d'un référentiel */ async import() { - this.enableImport = false let form = document.getElementById('form') as HTMLFormElement let name = (document.getElementById('name') as HTMLTextAreaElement)?.value || '' @@ -307,6 +306,7 @@ export class AverageEtpPage extends MainClass implements AfterViewInit { else if (!file) { alert('Vous devez saisir une fichier !') } else if (name.length > 0 && type.length > 0) { + this.enableImport = true await this.contentieuxOptionsService.createEmpy( false, name, diff --git a/front/src/app/routes/calculator/calculator.page.html b/front/src/app/routes/calculator/calculator.page.html index a3e4213d6..18e84d5bc 100644 --- a/front/src/app/routes/calculator/calculator.page.html +++ b/front/src/app/routes/calculator/calculator.page.html @@ -22,11 +22,11 @@
+ class="bg-white calculator bottom-popin" [max]="dateStop" [dateClass]="dateClass" [dateType]="'month'" + [min]="minDateSelectable" [icon]="'chevron_left'" (isOpen)="lockLoader.next($event)">
@@ -34,12 +34,12 @@
+ (click)="tabSelected=0;unselectTemplate();documentation.path=docLinks[0];$event.stopPropagation()">

Données brutes

+ (click)="tabSelected=1;unselectTemplate();logChartView();documentation.path=docLinks[1];$event.stopPropagation()">

Graphiques

@@ -122,8 +122,8 @@

ETPT
EAM

- +
@@ -146,8 +146,8 @@ - + @@ -179,14 +179,14 @@ + class="bg-white calculator popup bottom-popin" [max]="optionDateStop" [min]="minDateSelectable" + [dateClass]="dateClass" [dateType]="'month'" [icon]="'none'"> + class="bg-white calculator popup bottom-popin" [dateClass]="dateClass" [dateType]="'month'" + [min]="optionDateStart" [icon]="'none'"> @@ -249,9 +249,10 @@
diff --git a/front/src/app/routes/calculator/calculator.page.scss b/front/src/app/routes/calculator/calculator.page.scss index 56315d3a2..9d7aa7aa7 100644 --- a/front/src/app/routes/calculator/calculator.page.scss +++ b/front/src/app/routes/calculator/calculator.page.scss @@ -157,6 +157,10 @@ height: 190px; overflow: auto; + @media screen and (max-height: 680px) { + height: 100px; + } + .color-greffe { color: #a558a0; } @@ -290,6 +294,7 @@ #circle { width: 60px; height: 60px; + min-height: 60px; background: #ececfe; border-radius: 70px; margin: auto; @@ -298,6 +303,10 @@ justify-content: center; margin-bottom: 18px; + @media screen and (max-height: 680px) { + display: none; + } + i { font-size: 24px; color: #8585f6; @@ -573,7 +582,7 @@ .contentieux-header-calculator { display: flex; - + font-weight: bold; min-height: 80px; .width-contentieux { diff --git a/front/src/app/routes/calculator/calculator.page.ts b/front/src/app/routes/calculator/calculator.page.ts index 2916ddf45..2788f2a96 100644 --- a/front/src/app/routes/calculator/calculator.page.ts +++ b/front/src/app/routes/calculator/calculator.page.ts @@ -23,7 +23,7 @@ import { ContentieuxOptionsService } from 'src/app/services/contentieux-options/ import { HumanResourceService } from 'src/app/services/human-resource/human-resource.service' import { ReferentielService } from 'src/app/services/referentiel/referentiel.service' import { UserService } from 'src/app/services/user/user.service' -import { getTime, month } from 'src/app/utils/dates' +import { getTime, isDateBiggerThan, month } from 'src/app/utils/dates' import { userCanViewContractuel, userCanViewGreffier, @@ -53,6 +53,7 @@ import { } from 'src/app/constants/log-codes' import { BehaviorSubject } from 'rxjs' import { HRCategoryInterface } from 'src/app/interfaces/hr-category' +import { sleep } from 'src/app/utils' /** * Page du calculateur @@ -126,6 +127,14 @@ export class CalculatorPage path: 'https://docs.a-just.beta.gouv.fr/documentation-deploiement/calculateur/quest-ce-que-cest', printSubTitle: true, } + /** + * Documentation list + */ + docLinks: string[] = [ + 'https://docs.a-just.beta.gouv.fr/guide-dutilisateur-a-just/cockpit/les-donnees-brutes', + 'https://docs.a-just.beta.gouv.fr/guide-dutilisateur-a-just/cockpit/les-vues-graphiques', + 'https://docs.a-just.beta.gouv.fr/guide-dutilisateur-a-just/cockpit/comparer-son-activite', + ] /** * Mémorisation de la dernière categorie */ @@ -160,45 +169,80 @@ export class CalculatorPage introSteps: IntroJSStep[] = [ { target: '#wrapper-contener', - title: 'A quoi sert le cockpit ?', + title: 'À quoi sert le cockpit ?', intro: - "Le cockpit vous permet de visualiser en un coup d’œil quelques indicateurs simples, calculés à partir des données d’effectifs et d’activité renseignées dans A-JUST et, si vous le souhaitez, de les comparer à un référentiel que vous auriez renseigné.

Vous pouvez sélectionner la catégorie d'agents souhaitée et également restreindre si besoin les calculs à une ou plusieurs fonctions.

Vous pourrez exporter ces restitutions en PDF pour les enregistrer.", + "

Le cockpit vous permet de visualiser en un coup d’œil quelques indicateurs simples, calculés à partir des données d’effectifs et d’activité renseignées dans A-JUST et, si vous le souhaitez, de les comparer à une autre période ou à un référentiel que vous auriez renseigné.


Des visualisations graphiques vous sont également proposées.


Vous pouvez sélectionner la catégorie d'agents souhaitée, restreindre si besoin les calculs à une ou plusieurs fonctions et exporter ces restitutions en PDF pour les enregistrer et/ou les partager.

", }, { target: '.sub-main-header', title: 'Choisir la période', intro: - 'sur laquelle effectuer les calculs. Certaines des données étant des moyennes, elles seront d’autant plus représentatives que la période sélectionnée sera longue.', - }, - { - target: 'aj-referentiel-calculator:first-child .item.actual', - title: 'Les données renseignées', - intro: - "Vous pouvez visualiser, pour chaque contentieux ou sous-contentieux :", + 'Certaines données affichées étant des valeurs moyennes, elles seront d’autant plus représentatives que la période sélectionnée sera longue.', }, { - target: 'aj-referentiel-calculator:first-child .item.activity', - title: "Les données de l'activité constatée", + target: '.switch-tab .brut', + title: 'Les données brutes', intro: - 'Cette section permet de visualiser deux indicateurs simples, calculés à partir des « Données renseignées » :
Vous pourrez aussi visualiser le temps de traitement moyen par dossier observé sur la période antérieure qui constitue une clé de projection pour les simulations.', - }, - { - target: 'aj-referentiel-calculator:first-child .item.calculate', - title: "Les données de l'activité calculée", - intro: - 'Les données de l\'activité calculée permettent, si vous le souhaitez, de comparer les indicateurs de l’activité constatée, décrits précédemment, à ceux d\'un référentiel théorique que vous avez la faculté de saisir dans la page "Temps moyens".
J\'accède aux temps moyens
', + '

Cette section permet de visualiser deux indicateurs simples, sur la période, calculés pour chaque contentieux et sous contentieux, à partir des données renseignées dans A-JUST :

Vous retrouvez également :

', + beforeLoad: async (intro: any) => { + const itemToClick = document.querySelector('.switch-tab .brut') + if (itemToClick) { + // @ts-ignore + itemToClick.click() + await sleep(200) + } + }, }, { - target: '.ref-button', - title: 'Enregistrez les temps moyens constatés', + target: '.switch-tab .analytique', + title: 'Les graphiques', intro: - "comme référentiel, si vous souhaitez comparer leur évolution dans la juridiction d'une période à l'autre.", + '

Pour chaque contentieux, une représentation visuelle des indicateurs, comprenant le détail des données et leurs évolutions entre le début et la fin de la période.

', + beforeLoad: async (intro: any) => { + const itemToClick = document.querySelector('.switch-tab .analytique') + if (itemToClick) { + // @ts-ignore + itemToClick.click() + await sleep(200) + } + }, }, { - target: 'aj-options-backup-panel', - title: 'Mes temps moyens de comparaison', + target: '.drop-down', + title: 'Comparez votre juridiction', intro: - 'Si vous avez renseigné des temps moyens de référence, il vous suffit de sélectionner le référentiel de votre choix dans ce menu déroulant.', + '

Vous pouvez choisir de mettre en perspective les indicateurs de la période choisie avec ceux d’une autre période ou d’un référentiel de temps afin de visualiser les évolutions ou les taux de couverture et DTES de votre juridiction susceptibles de résulter de temps moyens de comparaison renseignés.

Cliquez ici pour créer ou importer un référentiel de temps moyen dans A-JUST.

', + beforeLoad: async (intro: any) => { + const itemToClick = document.querySelector('button.compare') + if (itemToClick) { + // @ts-ignore + itemToClick.click() + await sleep(200) + + const introTooltip = document.querySelector('.introjs-tooltip') + if (introTooltip) { + // @ts-ignore + introTooltip.style.visibility = 'hidden' + } + setTimeout(() => { + const introTooltip = document.querySelector('.introjs-tooltip') + if (introTooltip) { + introTooltip.classList.add('introjs-bottom-left-aligned') + introTooltip.classList.remove('introjs-floating') + // @ts-ignore + introTooltip.style.left = '0px' + // @ts-ignore + introTooltip.style.top = '170px' + // @ts-ignore + introTooltip.style.marginLeft = '-20px' + // @ts-ignore + introTooltip.style.marginTop = '0' + // @ts-ignore + introTooltip.style.visibility = 'visible' + } + }, 380) + } + }, }, ] /** @@ -261,6 +305,15 @@ export class CalculatorPage * Title created from popup while compare loaded */ createdTitle: null | string = null + /** + * Date minimum selectionnable + */ + minDateSelectable: Date = new Date(2021, 0, 1) + /** + * Detect if last month is loading + */ + checkLastMonthLoading: boolean = false + /** * Constructeur * @param humanResourceService @@ -451,23 +504,22 @@ export class CalculatorPage /** * Demande au serveur quelle est la dernière date des datas */ - onCheckLastMonth() { + async onCheckLastMonth(force = false) { if ( - this.calculatorService.dateStart.getValue() === null && - this.referentiel.length + ((!force && this.calculatorService.dateStart.getValue() === null) || + force) && + !this.checkLastMonthLoading ) { - this.activitiesService.getLastMonthActivities().then((date) => { - if (date === null) { - date = new Date() - } - - date = new Date(date ? date : '') + this.checkLastMonthLoading = true + return this.activitiesService.getLastMonthActivities().then((date) => { + date = new Date(date || null) const max = month(date, 0, 'lastday') this.maxDateSelectionDate = max const min = month(max, -11) this.calculatorService.dateStart.next(min) this.calculatorService.dateStop.next(max) + this.checkLastMonthLoading = false this.onLoadComparaisons() }) } @@ -478,6 +530,12 @@ export class CalculatorPage */ onLoadComparaisons(selectedByLabel: string | null = null) { this.backupSettingsService.list([BACKUP_SETTING_COMPARE]).then((l) => { + // clean list from brokens saves + l = l.filter( + (item) => + item.datas && (item.datas.dateStart || item.datas.referentielId) + ) + let refs = this.referentiels let indexRef = -1 do { @@ -605,10 +663,14 @@ export class CalculatorPage this.isLoading = false this.lastCategorySelected = this.categorySelected - if (this.firstLoading === false) + if ( + this.firstLoading === false && + this.location.path() === '/cockpit' + ) { this.appService.notification( 'Les données du cockpit ont été mis à jour !' ) + } this.firstLoading = false }) .catch(() => { @@ -1092,217 +1154,278 @@ export class CalculatorPage this.optionDateStop, false ) + + let dateEndIsPast = false + if (!this.maxDateSelectionDate) { + await this.onCheckLastMonth(true) + } + + if (this.dateStop && this.maxDateSelectionDate) { + dateEndIsPast = isDateBiggerThan( + this.dateStop, + this.maxDateSelectionDate, + true + ) + } + if ( + !dateEndIsPast && + this.optionDateStop && + this.maxDateSelectionDate + ) { + dateEndIsPast = isDateBiggerThan( + this.optionDateStop, + this.maxDateSelectionDate, + true + ) + } + console.log( + dateEndIsPast, + this.dateStop, + this.maxDateSelectionDate, + isDateBiggerThan( + this.dateStop || new Date(), + this.maxDateSelectionDate || new Date(), + true + ), + this.optionDateStop, + this.maxDateSelectionDate, + isDateBiggerThan( + this.optionDateStop || new Date(), + this.maxDateSelectionDate || new Date(), + true + ) + ) + this.appService.appLoading.next(false) const nextRangeString = `${this.getRealValue( this.optionDateStart )} - ${this.getRealValue(this.optionDateStop)}` this.compareAtString = nextRangeString - const value2DTES: (number | null)[] = (resultCalcul.list || []).map( - (d: CalculatorInterface) => d.realDTESInMonths - ) - const variationsDTES = getVariations(value2DTES, value1DTES) - list.push({ - title: 'DTES', - type: 'verticals-lines', - description: 'de la période
(calculé sur les 12 mois précédents)', - lineMax: - Math.max( - ...value1DTES.map((m) => m || 0), - ...value2DTES.map((m) => m || 0) - ) * 1.1, - values: value1DTES.map((v, index) => [ - value2DTES[index] || 0, - v || 0, - ]), - variations: [ - { - label: 'Variation', - values: variationsDTES, - subTitle: '%', - showArrow: true, - }, - { label: nextRangeString, values: value2DTES, subTitle: 'mois' }, - { label: actualRangeString, values: value1DTES, subTitle: 'mois' }, - ], - }) + if (!dateEndIsPast) { + const value2DTES: (number | null)[] = (resultCalcul.list || []).map( + (d: CalculatorInterface) => d.realDTESInMonths + ) + const variationsDTES = getVariations(value2DTES, value1DTES) + list.push({ + title: 'DTES', + type: 'verticals-lines', + description: + 'de la période
(calculé sur les 12 mois précédents)', + lineMax: + Math.max( + ...value1DTES.map((m) => m || 0), + ...value2DTES.map((m) => m || 0) + ) * 1.1, + values: value1DTES.map((v, index) => [ + value2DTES[index] || 0, + v || 0, + ]), + variations: [ + { + label: 'Variation', + values: variationsDTES, + subTitle: '%', + showArrow: true, + }, + { label: nextRangeString, values: value2DTES, subTitle: 'mois' }, + { + label: actualRangeString, + values: value1DTES, + subTitle: 'mois', + }, + ], + }) + } - const value2TempsMoyen: (number | null)[] = ( - resultCalcul.list || [] - ).map((d: CalculatorInterface) => - this.categorySelected === MAGISTRATS - ? d.magRealTimePerCase - : d.fonRealTimePerCase - ) - const stringValue2TempsMoyen = (value2TempsMoyen || []).map((d) => - d === null - ? 'N/R' - : `${this.getHours(d) || 0}h${this.getMinutes(d) || 0} ` - ) - const variationsTempsMoyen = getVariations( - value2TempsMoyen, - value1TempsMoyen - ) - list.push({ - title: 'Temps moyen', - type: 'verticals-lines', - description: 'sur la période', - lineMax: - Math.max( - ...value1TempsMoyen.map((m) => m || 0), - ...value2TempsMoyen.map((m) => m || 0) - ) * 1.1, - values: value1TempsMoyen.map((v, index) => [ - value2TempsMoyen[index] || 0, - v || 0, - ]), - variations: [ - { - label: 'Variation', - values: variationsTempsMoyen, - subTitle: '%', - showArrow: true, - }, - { - label: nextRangeString, - values: stringValue2TempsMoyen, - subTitle: 'heures', - }, - { - label: actualRangeString, - values: stringValue1TempsMoyen, - subTitle: 'heures', - }, - ], - }) + if (!dateEndIsPast) { + const value2TempsMoyen: (number | null)[] = ( + resultCalcul.list || [] + ).map((d: CalculatorInterface) => + this.categorySelected === MAGISTRATS + ? d.magRealTimePerCase + : d.fonRealTimePerCase + ) + const stringValue2TempsMoyen = (value2TempsMoyen || []).map((d) => + d === null + ? 'N/R' + : `${this.getHours(d) || 0}h${this.getMinutes(d) || 0} ` + ) + const variationsTempsMoyen = getVariations( + value2TempsMoyen, + value1TempsMoyen + ) + list.push({ + title: 'Temps moyen', + type: 'verticals-lines', + description: 'sur la période', + lineMax: + Math.max( + ...value1TempsMoyen.map((m) => m || 0), + ...value2TempsMoyen.map((m) => m || 0) + ) * 1.1, + values: value1TempsMoyen.map((v, index) => [ + value2TempsMoyen[index] || 0, + v || 0, + ]), + variations: [ + { + label: 'Variation', + values: variationsTempsMoyen, + subTitle: '%', + showArrow: true, + }, + { + label: nextRangeString, + values: stringValue2TempsMoyen, + subTitle: 'heures', + }, + { + label: actualRangeString, + values: stringValue1TempsMoyen, + subTitle: 'heures', + }, + ], + }) + } - const value2TauxCouverture: (number | null)[] = ( - resultCalcul.list || [] - ).map((d: CalculatorInterface) => d.realCoverage) - const variationsCouverture = getVariations( - value2TauxCouverture, - value1TauxCouverture, - false - ) - list.push({ - title: 'Taux de couverture', - type: 'progress', - description: 'moyen sur la période', - lineMax: 0, - values: value1TauxCouverture.map((v, index) => [ - Math.floor((value1TauxCouverture[index] || 0) * 100), - v === null ? null : Math.floor((v || 0) * 100), - ]), - variations: [ - { - label: 'Variation', - values: variationsCouverture, - subTitle: 'pts', - showArrow: true, - }, - { - label: nextRangeString, - values: value2TauxCouverture.map((t) => - t === null ? 'N/R' : Math.floor(t * 100) + ' %' - ), - }, - { - label: actualRangeString, - values: value1TauxCouverture.map((t) => - t === null ? 'N/R' : Math.floor(t * 100) + ' %' - ), - }, - ], - }) + if (!dateEndIsPast) { + const value2TauxCouverture: (number | null)[] = ( + resultCalcul.list || [] + ).map((d: CalculatorInterface) => d.realCoverage) + const variationsCouverture = getVariations( + value2TauxCouverture, + value1TauxCouverture, + false + ) + list.push({ + title: 'Taux de couverture', + type: 'progress', + description: 'moyen sur la période', + lineMax: 0, + values: value1TauxCouverture.map((v, index) => [ + Math.floor((value1TauxCouverture[index] || 0) * 100), + v === null ? null : Math.floor((v || 0) * 100), + ]), + variations: [ + { + label: 'Variation', + values: variationsCouverture, + subTitle: 'pts', + showArrow: true, + }, + { + label: nextRangeString, + values: value2TauxCouverture.map((t) => + t === null ? 'N/R' : Math.floor(t * 100) + ' %' + ), + }, + { + label: actualRangeString, + values: value1TauxCouverture.map((t) => + t === null ? 'N/R' : Math.floor(t * 100) + ' %' + ), + }, + ], + }) + } - const value2Stock: (number | null)[] = (resultCalcul.list || []).map( - (d: CalculatorInterface) => d.lastStock - ) - const variationsStock = getVariations(value2Stock, value1Stock) - list.push({ - title: 'Stock', - type: 'verticals-lines', - description: 'en fin de période', - lineMax: - Math.max( - ...value1Stock.map((m) => m || 0), - ...value2Stock.map((m) => m || 0) - ) * 1.1, - values: value1Stock.map((v, index) => [ - value2Stock[index] || 0, - v || 0, - ]), - variations: [ - { - label: 'Variation', - values: variationsStock, - subTitle: '%', - showArrow: true, - }, - { label: nextRangeString, values: value2Stock }, - { label: actualRangeString, values: value1Stock }, - ], - }) + if (!dateEndIsPast) { + const value2Stock: (number | null)[] = (resultCalcul.list || []).map( + (d: CalculatorInterface) => d.lastStock + ) + const variationsStock = getVariations(value2Stock, value1Stock) + list.push({ + title: 'Stock', + type: 'verticals-lines', + description: 'en fin de période', + lineMax: + Math.max( + ...value1Stock.map((m) => m || 0), + ...value2Stock.map((m) => m || 0) + ) * 1.1, + values: value1Stock.map((v, index) => [ + value2Stock[index] || 0, + v || 0, + ]), + variations: [ + { + label: 'Variation', + values: variationsStock, + subTitle: '%', + showArrow: true, + }, + { label: nextRangeString, values: value2Stock }, + { label: actualRangeString, values: value1Stock }, + ], + }) + } - const value2Entrees: (number | null)[] = (resultCalcul.list || []).map( - (d: CalculatorInterface) => + if (!dateEndIsPast) { + const value2Entrees: (number | null)[] = ( + resultCalcul.list || [] + ).map((d: CalculatorInterface) => d.totalIn ? Math.floor(d.totalIn) : d.totalIn - ) - const variationsEntrees = getVariations(value2Entrees, value1Entrees) - list.push({ - title: 'Entrées', - type: 'verticals-lines', - description: 'moyennes
sur la période', - lineMax: - Math.max( - ...value1Entrees.map((m) => m || 0), - ...value2Entrees.map((m) => m || 0) - ) * 1.1, - values: value1Entrees.map((v, index) => [ - value2Entrees[index] || 0, - v || 0, - ]), - variations: [ - { - label: 'Variation', - values: variationsEntrees, - subTitle: '%', - showArrow: true, - }, - { label: nextRangeString, values: value2Entrees }, - { label: actualRangeString, values: value1Entrees }, - ], - }) + ) + const variationsEntrees = getVariations(value2Entrees, value1Entrees) + list.push({ + title: 'Entrées', + type: 'verticals-lines', + description: 'moyennes
sur la période', + lineMax: + Math.max( + ...value1Entrees.map((m) => m || 0), + ...value2Entrees.map((m) => m || 0) + ) * 1.1, + values: value1Entrees.map((v, index) => [ + value2Entrees[index] || 0, + v || 0, + ]), + variations: [ + { + label: 'Variation', + values: variationsEntrees, + subTitle: '%', + showArrow: true, + }, + { label: nextRangeString, values: value2Entrees }, + { label: actualRangeString, values: value1Entrees }, + ], + }) + } - const value2Sorties: (number | null)[] = (resultCalcul.list || []).map( - (d: CalculatorInterface) => + if (!dateEndIsPast) { + const value2Sorties: (number | null)[] = ( + resultCalcul.list || [] + ).map((d: CalculatorInterface) => d.totalOut ? Math.floor(d.totalOut) : d.totalOut - ) - const variationsSorties = getVariations(value2Sorties, value1Sorties) - list.push({ - title: 'Sorties', - type: 'verticals-lines', - description: 'moyennes
sur la période', - lineMax: - Math.max( - ...value1Sorties.map((m) => m || 0), - ...value2Sorties.map((m) => m || 0) - ) * 1.1, - values: value1Sorties.map((v, index) => [ - value2Sorties[index] || 0, - v || 0, - ]), - variations: [ - { - label: 'Variation', - values: variationsSorties, - subTitle: '%', - showArrow: true, - }, - { label: nextRangeString, values: value2Sorties }, - { label: actualRangeString, values: value1Sorties }, - ], - }) + ) + const variationsSorties = getVariations(value2Sorties, value1Sorties) + list.push({ + title: 'Sorties', + type: 'verticals-lines', + description: 'moyennes
sur la période', + lineMax: + Math.max( + ...value1Sorties.map((m) => m || 0), + ...value2Sorties.map((m) => m || 0) + ) * 1.1, + values: value1Sorties.map((v, index) => [ + value2Sorties[index] || 0, + v || 0, + ]), + variations: [ + { + label: 'Variation', + values: variationsSorties, + subTitle: '%', + showArrow: true, + }, + { label: nextRangeString, values: value2Sorties }, + { label: actualRangeString, values: value1Sorties }, + ], + }) + } if (this.canViewMagistrat) { const value2ETPTSiege: (number | null)[] = ( @@ -1460,6 +1583,9 @@ export class CalculatorPage const refSelected = this.backups.find((b) => b.selected) if (!refSelected) { this.compareTemplates = null + if ([0, 1].includes(this.tabSelected)) { + this.documentation.path = this.docLinks[this.tabSelected] + } return } const refDetails = await this.contentieuxOptionsService.loadDetails( @@ -1669,6 +1795,7 @@ export class CalculatorPage } this.compareTemplates = list + this.documentation.path = this.docLinks[2] } this.appService.notification('Les données du cockpit ont été mis à jour !') } @@ -1716,6 +1843,9 @@ export class CalculatorPage unselectTemplate() { this.showPicker = false this.compareTemplates = null + if ([0, 1].includes(this.tabSelected)) { + this.documentation.path = this.docLinks[this.tabSelected] + } this.referentiels = this.referentiels.map((x) => { x.selected = false return x diff --git a/front/src/app/routes/calculator/view-analytics/graphs-verticals-lines/graphs-verticals-lines.component.ts b/front/src/app/routes/calculator/view-analytics/graphs-verticals-lines/graphs-verticals-lines.component.ts index 590d3c686..8b50aa1ef 100644 --- a/front/src/app/routes/calculator/view-analytics/graphs-verticals-lines/graphs-verticals-lines.component.ts +++ b/front/src/app/routes/calculator/view-analytics/graphs-verticals-lines/graphs-verticals-lines.component.ts @@ -18,6 +18,7 @@ import { OPACITY_20 } from 'src/app/constants/colors' import { MainClass } from 'src/app/libs/main-class' import { CalculatorService } from 'src/app/services/calculator/calculator.service' import { UserService } from 'src/app/services/user/user.service' +import { getRandomInt } from 'src/app/utils/numbers' /** * Composant de la page en vue analytique @@ -108,6 +109,14 @@ export class GraphsVerticalsLinesComponent * is multiple graph printed */ isMultipleGraphPrinted: boolean = false + /** + * Wait serveur loading + */ + isLoading: boolean = false + /** + * timeout + */ + timeout: any /** * Constructor @@ -128,25 +137,26 @@ export class GraphsVerticalsLinesComponent this.width$.subscribe((w) => { this.width = w this.draw() - this.drawMultiple() + //this.drawMultiple() }) ) this.watch(this.line.subscribe(() => this.draw())) - this.watch( - this.calculatorService.dateStart.subscribe(() => this.refreshDatas()) + // Le composant est maintenant recharger complétement car il est détruit + /*this.watch( + this.calculatorService.dateStart.subscribe(() => this.clearDatas()) ) this.watch( - this.calculatorService.dateStop.subscribe(() => this.refreshDatas()) + this.calculatorService.dateStop.subscribe(() => this.clearDatas()) ) this.watch( this.calculatorService.selectedFonctionsIds.subscribe(() => - this.refreshDatas() + this.clearDatas() ) - ) + )*/ } ngAfterViewInit() { - this.drawMultiple() + //this.drawMultiple() } ngOnDestroy() { @@ -176,11 +186,7 @@ export class GraphsVerticalsLinesComponent this.type && this.line.getValue().length === 0 ) { - this.calculatorService - .rangeValues(this.referentielId, this.type) - .then((lines) => { - this.line.next(lines) - }) + this.startLoading() } if (changes['maxValue'] || changes['showLines']) { @@ -191,14 +197,35 @@ export class GraphsVerticalsLinesComponent refreshDatas() { this.line.next([]) if (this.showLines && this.referentielId && this.type) { - this.calculatorService - .rangeValues(this.referentielId, this.type) - .then((lines) => { - this.line.next(lines) - }) + this.startLoading() } } + clearDatas() { + this.line.next([]) + this.draw() + } + + startLoading() { + if (this.timeout) { + clearTimeout(this.timeout) + } + + this.timeout = setTimeout(() => { + if (this.referentielId && this.type && !this.isLoading) { + this.isLoading = true + this.calculatorService + .rangeValues(this.referentielId, this.type) + .then((lines) => { + this.isLoading = false + this.timeout = null + this.line.next(lines) + this.draw() + }) + } + }, getRandomInt(700)) + } + draw() { const canvas = this.domCanvas?.nativeElement if (canvas) { @@ -264,7 +291,8 @@ export class GraphsVerticalsLinesComponent ctx.clearRect(0, 0, this.width * 200, this.height * 200) ctx.beginPath() - if (this.referentielId) { + if (this.referentielId && !this.isLoading) { + this.isLoading = true this.graphs.map((g, index) => { this.calculatorService .rangeValues( @@ -275,6 +303,7 @@ export class GraphsVerticalsLinesComponent ) .then((line) => { line = line.map((v: any) => +v || 0) + this.isLoading = false ctx.strokeStyle = g.color ctx.lineWidth = 1 diff --git a/front/src/app/routes/calculator/view-analytics/view-analytics.component.html b/front/src/app/routes/calculator/view-analytics/view-analytics.component.html index b93c4a107..09cecaed9 100644 --- a/front/src/app/routes/calculator/view-analytics/view-analytics.component.html +++ b/front/src/app/routes/calculator/view-analytics/view-analytics.component.html @@ -1,7 +1,7 @@
- +
-
+

DTES

de la période

@@ -41,7 +41,7 @@
-
+

Taux de couverture

moyens sur la période

@@ -76,7 +76,7 @@
-
+

Stock

sur la période

@@ -103,15 +103,14 @@ + (updateMax)="onUpdateMax($event)"> + [showLines]="true"> @@ -122,7 +121,7 @@
-
+

Entrées

sur la période

@@ -176,7 +175,7 @@
-
+

Sorties

sur la période

@@ -394,54 +393,56 @@
-
-
-

Temps moyen Siège

-

par dossier observé

-
-
-

Fin de période

+ +
+
+

Temps moyen Siège

+

par dossier observé

+
+
+

Fin de période

+
+
-
-
-
-

(calculé sur les 12 mois - précédents)

-
-
-
-

- {{ datasFilted[index].magRealTimePerCase === null ? 'N/R' : - decimalToStringDate(datasFilted[index].magRealTimePerCase) }} -

+
+

(calculé sur les 12 mois + précédents)

+
+
+
+

+ {{ datasFilted[index].magRealTimePerCase === null ? 'N/R' : + decimalToStringDate(datasFilted[index].magRealTimePerCase) }} +

+
-
-
-
-

Temps moyen Greffe

-

par dossier observé

-
-
-

Fin de période

+
+
+

Temps moyen Greffe

+

par dossier observé

+
+
+

Fin de période

+
+
-
-
-
-

(calculé sur les 12 mois - précédents)

-
-
-
-

- {{ datasFilted[index].fonRealTimePerCase === null ? 'N/R' : - decimalToStringDate(datasFilted[index].fonRealTimePerCase) }} -

+
+

(calculé sur les 12 mois + précédents)

+
+
+
+

+ {{ datasFilted[index].fonRealTimePerCase === null ? 'N/R' : + decimalToStringDate(datasFilted[index].fonRealTimePerCase) }} +

+
-
+
\ No newline at end of file diff --git a/front/src/app/routes/calculator/view-analytics/view-analytics.component.ts b/front/src/app/routes/calculator/view-analytics/view-analytics.component.ts index 53477deef..c392daa52 100644 --- a/front/src/app/routes/calculator/view-analytics/view-analytics.component.ts +++ b/front/src/app/routes/calculator/view-analytics/view-analytics.component.ts @@ -13,6 +13,9 @@ import { userCanViewMagistrat, } from 'src/app/utils/user' import { OPACITY_20 } from 'src/app/constants/colors' +import { CalculatorService } from 'src/app/services/calculator/calculator.service' +import { isDateBiggerThan, month } from 'src/app/utils/dates' +import { ActivitiesService } from 'src/app/services/activities/activities.service' /** * Composant de la page en vue analytique @@ -39,6 +42,10 @@ export class ViewAnalyticsComponent * Type of category selected */ @Input() categorySelected: string = '' + /** + * maxDateSelectionDate + */ + @Input() maxDateSelectionDate: Date | null = null /** * Define max DTES */ @@ -111,6 +118,10 @@ export class ViewAnalyticsComponent * Opacité background des contentieux */ OPACITY = OPACITY_20 + /** + * End date + */ + dateStop: Date | null = null /** * Constructor @@ -119,7 +130,9 @@ export class ViewAnalyticsComponent private humanResourceService: HumanResourceService, private referentielService: ReferentielService, private kpiService: KPIService, - public userService: UserService + public userService: UserService, + private calculatorService: CalculatorService, + private activitiesService: ActivitiesService ) { super() } @@ -142,6 +155,17 @@ export class ViewAnalyticsComponent this.canViewContractuel = userCanViewContractuel(u) }) ) + + this.watch( + this.calculatorService.dateStop.subscribe((d) => { + this.dateStop = d + this.activitiesService.getLastMonthActivities().then((date) => { + date = new Date(date ? date : '') + const max = month(date, 0, 'lastday') + this.maxDateSelectionDate = max + }) + }) + ) } /** @@ -280,4 +304,16 @@ export class ViewAnalyticsComponent round(num: number) { return Math.round(num) } + + /** + * Check if the end date is after max selection date + * @returns + */ + dateEndIsPast() { + if (this.dateStop && this.maxDateSelectionDate) { + return isDateBiggerThan(this.dateStop, this.maxDateSelectionDate, true) + } + + return false + } } diff --git a/front/src/app/routes/help-center/help-center.page.html b/front/src/app/routes/help-center/help-center.page.html index ef43bfe7b..465692df1 100644 --- a/front/src/app/routes/help-center/help-center.page.html +++ b/front/src/app/routes/help-center/help-center.page.html @@ -75,13 +75,16 @@

Être recontacté ?

Questions fréquentes

- +
arrow_forward
-
-
+
@@ -136,14 +139,25 @@

Être recontacté ?

Aide

-

{{doc.title}}

- + + + +
diff --git a/front/src/app/routes/help-center/help-center.page.scss b/front/src/app/routes/help-center/help-center.page.scss index 52a245e23..abee810f4 100644 --- a/front/src/app/routes/help-center/help-center.page.scss +++ b/front/src/app/routes/help-center/help-center.page.scss @@ -488,6 +488,7 @@ display: flex; align-items: flex-end; z-index: 1; + position: relative; .tab { min-height: 40px; @@ -498,6 +499,7 @@ font-weight: bold; color: black; cursor: pointer; + position: relative; &.selected { border: solid 1px #ddd; @@ -507,6 +509,58 @@ border-top: solid 2px #000091; border-bottom: none; } + + &.blue { + &::before { + content: ''; + height: 0px; + width: 100%; + border-bottom: 8px solid #96b8f0; + opacity: 0.4; + position: absolute; + bottom: 0px; + left: 0px; + } + } + + &.green { + &::before { + content: ''; + height: 0px; + width: 100%; + border-bottom: 8px solid #00fb90; + position: absolute; + bottom: 0px; + left: 0px; + opacity: 0.3; + } + } + + &.red { + &::before { + content: ''; + height: 0px; + width: 100%; + border-bottom: 8px solid #a558a0; + opacity: 0.5; + position: absolute; + bottom: 0px; + left: 0px; + } + } + + &.yellow { + &::before { + content: ''; + height: 0px; + width: 100%; + border-bottom: 8px solid #f6e157; + opacity: 0.5; + position: absolute; + bottom: 0px; + left: 0px; + } + } } a { @@ -516,7 +570,7 @@ } >iframe { - padding-top: 18px; + top: -16px; position: relative; flex: 1; border-radius: 4px; diff --git a/front/src/app/routes/help-center/help-center.page.ts b/front/src/app/routes/help-center/help-center.page.ts index a9a2330ff..07443d17d 100644 --- a/front/src/app/routes/help-center/help-center.page.ts +++ b/front/src/app/routes/help-center/help-center.page.ts @@ -152,18 +152,22 @@ export class HelpCenterPage implements OnInit, AfterViewInit { { url: 'https://docs.a-just.beta.gouv.fr/tout-savoir-en-un-coup-doeil/', title: "Tout savoir en un coup d'oeil", + color: 'blue', }, { - url: 'https://docs.a-just.beta.gouv.fr/soulager-les-equipes/', + url: 'https://docs.a-just.beta.gouv.fr/prenez-en-main-votre-espace/', title: 'Prenez en main votre espace', + color: 'green', }, { - url: 'https://docs.a-just.beta.gouv.fr/gagner-du-temps/', + url: 'https://docs.a-just.beta.gouv.fr/pilotez-votre-juridiction/', title: 'Pilotez votre juridiction', + color: 'red', }, { - url: 'https://docs.a-just.beta.gouv.fr/construire-le-futur/', + url: 'https://docs.a-just.beta.gouv.fr/cas-dusage/', title: 'Cas d’usage', + color: 'yellow', }, ] /** diff --git a/front/src/app/routes/human-resource/human-resource.page.html b/front/src/app/routes/human-resource/human-resource.page.html index 2a5de8c1c..a1cd9638e 100644 --- a/front/src/app/routes/human-resource/human-resource.page.html +++ b/front/src/app/routes/human-resource/human-resource.page.html @@ -18,7 +18,7 @@
- - + (onRemove)="onRemoveSituation(h.id)" [forceToShowContentieuxDetail]="duringPrint" [isPast]="false">
@@ -79,7 +79,7 @@ [dateStart]="h.dateStart" [dateStop]="h.dateStop" [dateEndToJuridiction]="currentHR && currentHR.dateEnd" [canRemoveSituation]="!duringPrint && h.situationForTheFirstTime" (editVentilation)="onSelectSituationToEdit(h)" [canEditSituation]="!duringPrint" (addIndispiniblity)="onAddIndispiniblity($event)" - (onRemove)="onRemoveSituation(h.id)" [forceToShowContentieuxDetail]="duringPrint"> + (onRemove)="onRemoveSituation(h.id)" [forceToShowContentieuxDetail]="duringPrint" [isPast]="true">
diff --git a/front/src/app/routes/human-resource/human-resource.page.ts b/front/src/app/routes/human-resource/human-resource.page.ts index 5fc62e151..247e9457b 100644 --- a/front/src/app/routes/human-resource/human-resource.page.ts +++ b/front/src/app/routes/human-resource/human-resource.page.ts @@ -16,7 +16,7 @@ import { HRCategoryService } from 'src/app/services/hr-category/hr-category.serv import { HRFonctionService } from 'src/app/services/hr-fonction/hr-function.service' import { HumanResourceService } from 'src/app/services/human-resource/human-resource.service' import { copy } from 'src/app/utils' -import { dateAddDays, today } from 'src/app/utils/dates' +import { dateAddDays, isDateBiggerThan, today } from 'src/app/utils/dates' import { AddVentilationComponent } from './add-ventilation/add-ventilation.component' import { AppService } from 'src/app/services/app/app.service' import { sum } from 'lodash' @@ -140,6 +140,10 @@ export class HumanResourcePage extends MainClass implements OnInit, OnDestroy { firstName: new FormControl(''), matricule: new FormControl(''), }) + /** + * showActuelPanel + */ + showActuelPanel: boolean = false /** * Constructeur @@ -534,6 +538,23 @@ export class HumanResourcePage extends MainClass implements OnInit, OnDestroy { actualHistoryDateStop: this.actualHistoryDateStop, }) */ + if ( + this.actualHistoryDateStart && + this.currentHR.dateEnd && + isDateBiggerThan(this.actualHistoryDateStart, this.currentHR.dateEnd) + ) { + this.showActuelPanel = false + } else if ( + !this.actualHistoryDateStart && + this.actualHistoryDateStop && + this.currentHR.dateStart && + isDateBiggerThan(this.currentHR.dateStart, this.actualHistoryDateStop) + ) { + this.showActuelPanel = false + } else { + this.showActuelPanel = true + } + this.preOpenSituation() } diff --git a/front/src/app/routes/human-resource/indispo-profil/indispo-profil.component.html b/front/src/app/routes/human-resource/indispo-profil/indispo-profil.component.html index 09dbd885e..6b5016fbf 100644 --- a/front/src/app/routes/human-resource/indispo-profil/indispo-profil.component.html +++ b/front/src/app/routes/human-resource/indispo-profil/indispo-profil.component.html @@ -9,7 +9,7 @@
-

Pas d'indisponiblité en cours

+

Pas d'indisponibilité en cours

event_busy diff --git a/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.html b/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.html index c3a9100f6..9c943b86f 100644 --- a/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.html +++ b/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.html @@ -1,13 +1,30 @@
-

- Du {{ dateStart | date: 'dd' }} {{ getShortMonthString(dateStart) }} - {{ getFullYear(dateStart) }} -

-

- Au {{ dateStop | date: 'dd' }} {{ getShortMonthString(dateStop) }} - {{ getFullYear(dateStop) }} -

+ +

+ Du {{ dateStart | date: 'dd' }} {{ getShortMonthString(dateStart) }} + {{ getFullYear(dateStart) }} +

+

+ Au {{ dateStop | date: 'dd' }} {{ getShortMonthString(dateStop) }} + {{ getFullYear(dateStop) }} +

+
+ + +

+ {{ + dateStart && dateStart.getTime() > getToday().getTime() + ? 'À partir du' + : 'Depuis le' + }} {{ dateStart | date: 'dd' }} {{ getShortMonthString(dateStart) }} + {{ getFullYear(dateStart) }} +

+

+ Jusqu'au {{ dateStop | date: 'dd' }} {{ getShortMonthString(dateStop) }} + {{ getFullYear(dateStop) }} +

+

{{ fonction.code }}

{{ timeWorked }}

diff --git a/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.ts b/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.ts index 25cd7ae54..2f89acd78 100644 --- a/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.ts +++ b/front/src/app/routes/human-resource/panel-history-ventilation/panel-history-ventilation.component.ts @@ -25,7 +25,8 @@ import { etpLabel } from 'src/app/utils/referentiel' }) export class PanelHistoryVentilationComponent extends MainClass - implements OnChanges { + implements OnChanges +{ /** * Date de début de situation */ @@ -43,8 +44,8 @@ export class PanelHistoryVentilationComponent */ @Input() fonction: HRFonctionInterface | null = null /** - * Category de la situation - */ + * Category de la situation + */ @Input() category: HRCategoryInterface | null = null /** * ETP de la situation @@ -74,6 +75,10 @@ export class PanelHistoryVentilationComponent * Force to show sub contentieux */ @Input() forceToShowContentieuxDetail: boolean = false + /** + * Date is Past + */ + @Input() isPast: boolean = false /** * Event lors du souhait de modifier la situation */ diff --git a/front/src/app/routes/panorama/panorama.page.ts b/front/src/app/routes/panorama/panorama.page.ts index 8b1166c96..9abcbc5ec 100644 --- a/front/src/app/routes/panorama/panorama.page.ts +++ b/front/src/app/routes/panorama/panorama.page.ts @@ -33,7 +33,8 @@ import { IntroJSStep } from 'src/app/components/intro-js/intro-js.component' }) export class PanoramaPage extends MainClass - implements OnInit, OnDestroy, AfterViewInit { + implements OnInit, OnDestroy, AfterViewInit +{ /** * Dom du contenu scrollable */ @@ -150,13 +151,17 @@ export class PanoramaPage target: '#wrapper-contener', title: 'Panorama', intro: - 'Cette page vous offre un aperçu en un coup d’œil de la mise à jour des informations enregistrées dans l’espace ' + (this.isTJ() ? 'du TJ' : 'de la CA') + '.', + 'Cette page vous offre un aperçu en un coup d’œil de la mise à jour des informations enregistrées dans l’espace ' + + (this.isTJ() ? 'du TJ' : 'de la CA') + + '.', }, { target: '.effectifs-panels', title: "Les données d'effectifs", intro: - "Récapitulent l'ensemble des ressources humaines à date, la situation des agents de la " + (this.isTJ() ? 'juridiction' : 'cour d\'appel') + " et les éventuels changements dans les 15 derniers et 15 prochains jours.", + "Récapitulent l'ensemble des ressources humaines à date, la situation des agents de la " + + (this.isTJ() ? 'juridiction' : "cour d'appel") + + ' et les éventuels changements dans les 15 derniers et 15 prochains jours.', }, { target: '.wordforce-composition', @@ -168,14 +173,16 @@ export class PanoramaPage target: '.records-update', title: 'Pourcentage et date de mise à jour', intro: - 'Ici, visualisez et priorisez les tâches à effectuer, pour vous ou vos équipes.

Veillez à ce que ces données soient à jour et actualisées afin de disposer d’une vision précise et fine de la mobilisation des ressources humaines dans la ' + (this.isTJ() ? 'juridiction' : 'cour d\'appel') + '.', + 'Ici, visualisez et priorisez les tâches à effectuer, pour vous ou vos équipes.

Veillez à ce que ces données soient à jour et actualisées afin de disposer d’une vision précise et fine de la mobilisation des ressources humaines dans la ' + + (this.isTJ() ? 'juridiction' : "cour d'appel") + + '.', }, { target: 'workforce-change', title: 'Changements récents', intro: "Cet espace rassemble les arrivées, départs ou indisponibilités enregistrés dans le ventilateur pour les 15 derniers et 15 prochains jours. Vous pouvez ainsi pré-renseigner dans la fiche des agents une date prévisionnelle de départ, de retour d’indisponibilité ou d'arrivée et la modifier si vous découvrez qu’elle a évolué.", - } + }, ] stepsOnlyForTJ: IntroJSStep[] = [ @@ -200,7 +207,9 @@ export class PanoramaPage target: 'activities-last-modifications', title: 'Dernières modifications', intro: - "Effectuées sur vos données d’activité par les différents agents de la " + (this.isTJ() ? 'juridiction' : 'cour d\'appel') + " utilisateurs d'A-JUST.", + 'Effectuées sur vos données d’activité par les différents agents de la ' + + (this.isTJ() ? 'juridiction' : "cour d'appel") + + " utilisateurs d'A-JUST.", }, ] @@ -216,7 +225,7 @@ export class PanoramaPage */ constructor( public userService: UserService, - public humanResourceService: HumanResourceService, + public humanResourceService: HumanResourceService ) { super() } @@ -233,13 +242,21 @@ export class PanoramaPage this.canViewVentilation = this.userService.canViewVentilation() this.canViewActivities = this.userService.canViewActivities() - if (this.userService.isCa()) this.introSteps = [...this.introSteps, this.lastStep] - else this.introSteps = [...this.introSteps, ...this.stepsOnlyForTJ, this.lastStep] + if (this.userService.isCa()) + this.introSteps = [...this.introSteps, this.lastStep] + else + this.introSteps = [ + ...this.introSteps, + ...this.stepsOnlyForTJ, + this.lastStep, + ] - // @ts-ignore - this.introSteps[this.introSteps.length - 1]['actions'][ - 'onClickToIntro' - ].enable = this.canViewVentilation + try { + // @ts-ignore + this.introSteps[this.introSteps.length - 1]['actions'][ + 'onClickToIntro' + ].enable = this.canViewVentilation + } catch (err) {} }) ) diff --git a/front/src/app/routes/reaffectator/reaffectator.page.html b/front/src/app/routes/reaffectator/reaffectator.page.html index 387d22b1a..b729e9054 100644 --- a/front/src/app/routes/reaffectator/reaffectator.page.html +++ b/front/src/app/routes/reaffectator/reaffectator.page.html @@ -17,7 +17,7 @@ [datas]="formReferentiel" (valueChange)="onSelectedReferentielIdsChanged($event)" [defaultAllValue]="'Tous'">
-
diff --git a/front/src/app/routes/reaffectator/reaffectator.page.ts b/front/src/app/routes/reaffectator/reaffectator.page.ts index b064cae92..dd99fa5fb 100644 --- a/front/src/app/routes/reaffectator/reaffectator.page.ts +++ b/front/src/app/routes/reaffectator/reaffectator.page.ts @@ -301,19 +301,25 @@ export class ReaffectatorPage target: '#wrapper-contener', title: 'À quoi sert le simulateur des affectations ?', intro: - '

Cet écran qui se présente comme le ventilateur en mode « nuit », c’est-à-dire simulation, vous permet d’adapter finement l’affectation de vos effectifs, à ressources constantes, sur les différents contentieux, en visualisant instantanément l’impact de votre projet de réorganisation sur les délais de traitement du contentieux que vous voulez renforcer mais aussi sur les autres matières que vous allez de ce fait nécessairement dégarnir.

Toutes vos actions sur cet écran n’ont aucun impact sur la ventilation actuelle de vos agents : ce sont que des projections

', + '

Cet écran qui se présente comme le ventilateur en mode « nuit », c’est-à-dire simulation, vous permet d’adapter finement l’affectation de vos effectifs, à ressources constantes, sur les différents contentieux, en visualisant instantanément l’impact de votre projet de réorganisation sur les délais de traitement du contentieux que vous voulez renforcer mais aussi sur les autres matières que vous allez de ce fait nécessairement dégarnir.

Toutes vos actions sur cet écran n’ont aucun impact sur la ventilation actuelle de vos agents : ce ne sont que des projections.

', }, { target: '#content .container .title', - title: 'Choisissez le calendrier, et la catégorie d’agent', + title: 'Choisissez la date et la catégorie d’agent', intro: - "

Afin de déterminer le champ d’application des hypothèses que vous allez jouer. Comme dans le ventilateur, en modifiant la date dans le calendrier, vous affichez la liste des agents présents, selon leur catégorie et les ETPT mobilisés sur les différents contentieux à la date choisie. Vous pouvez aussi choisir de n'afficher que les données d'ETPT relatives à certains contentieux, ou à certaines fonctions.

", + '

afin de déterminer le champ d’application des hypothèses que vous allez jouer. Comme dans le ventilateur, en modifiant la date dans le calendrier, vous affichez la liste des agents présents selon leur catégorie ainsi que la ventilation de leur ETPT sur les différents contentieux à la date choisie. Vous pouvez filtrer par fonction ou contentieux selon vos besoins.

', + }, + { + target: '#content .container .title .search-bar', + title: 'Rechercher', + intro: + '

Vous pouvez également rechercher un agent de façon nominative

', }, { target: '#content .container .indicators', title: 'Vos indicateurs d’impact affichent', intro: - "

pour chaque contentieux, la situation à la date choisie, en termes d’ETPT affectés, de taux de couverture et de DTES exprimé en nombre de mois.

Ces indicateurs sont construits en lien avec les données d'activité et d’effectifs présentes dans A-JUST. Pour obtenir une projection précise et fine, il convient de compléter et mettre à jour ces éléments en fonction des informations locales dont vous disposez.

", + "

pour chaque contentieux, la situation à la date choisie :

  • des ETPT affectés
  • du taux de couverture et du DTES exprimé en nombre de mois
issue des données d'activité et d’effectifs enregistrées dans A-JUST. La projection sera d’autant plus précise et fine que vous aurez actualisé ces éléments, en fonction des informations dont vous disposez, dans le ventilateur et l'écran de données d’activité.
Vous pouvez renseigner la valeur cible d’ETPT que vous souhaitez atteindre dans un contentieux.

", }, { target: '#wrapper-contener', diff --git a/front/src/app/routes/simulator/charts/dtes-chart/dtes-chart.component.ts b/front/src/app/routes/simulator/charts/dtes-chart/dtes-chart.component.ts index 689a40625..1560a9445 100644 --- a/front/src/app/routes/simulator/charts/dtes-chart/dtes-chart.component.ts +++ b/front/src/app/routes/simulator/charts/dtes-chart/dtes-chart.component.ts @@ -464,7 +464,7 @@ export class DtesChartComponent { var percent = Math.round( (dataset['data'][tooltipItem['index']] / dataset['_meta'][0]['total']) * - 100 + 100 ) return '(' + percent + '%)' }, @@ -519,8 +519,8 @@ export class DtesChartComponent { z: 1, display: true, mirror: true, - labelOffset: -15, - padding: -3, + labelOffset: 0, + padding: 20, callback: (value: any, index: any, values: any) => index == values.length - 1 ? '' : value, }, @@ -622,16 +622,21 @@ export class DtesChartComponent { let higuerYPosition = value.y ? value.y : 0 let higuerXPosition = value.x ? value.x : 0 - if (value.pointIndex !== null) - // xScale.top - { + if (value.pointIndex !== null) { + // xScale.top higuerYPosition = Math.min( - this.myChart.getDatasetMeta(0).data[value.pointIndex as number].y | 0, - this.myChart.getDatasetMeta(1).data[value.pointIndex as number].y | 0, - this.myChart.getDatasetMeta(2).data[value.pointIndex as number].y | 0, - this.myChart.getDatasetMeta(3).data[value.pointIndex as number].y | 0, + this.myChart.getDatasetMeta(0).data[value.pointIndex as number] + .y | 0, + this.myChart.getDatasetMeta(1).data[value.pointIndex as number] + .y | 0, + this.myChart.getDatasetMeta(2).data[value.pointIndex as number] + .y | 0, + this.myChart.getDatasetMeta(3).data[value.pointIndex as number] + .y | 0 ) - higuerXPosition = this.myChart.getDatasetMeta(0).data[value.pointIndex as number].x | 0 + higuerXPosition = + this.myChart.getDatasetMeta(0).data[value.pointIndex as number] + .x | 0 } this.myChart.tooltip.active = false @@ -643,7 +648,9 @@ export class DtesChartComponent { tooltipElTriangle.style.left = Number(String(higuerXPosition).replace('px', '')) + 4 + 'px' tooltipElTriangle.style.top = - Number(String(higuerYPosition - 130 + 'px').replace('px', '')) + 128 + 'px' //68 + Number(String(higuerYPosition - 130 + 'px').replace('px', '')) + + 128 + + 'px' //68 this.tooltip.projectedStock = this.myChart.data.datasets[0].data[value.pointIndex as number] @@ -679,11 +686,8 @@ export class DtesChartComponent { } this.myChart.update() - } }) - - } /** @@ -768,4 +772,3 @@ export class DtesChartComponent { return getLongMonthString(month.split(' ')[0]) + ' 20' + month.split(' ')[1] } } - diff --git a/front/src/app/routes/simulator/simulator.page.html b/front/src/app/routes/simulator/simulator.page.html index 155bd19bb..ef014e50a 100644 --- a/front/src/app/routes/simulator/simulator.page.html +++ b/front/src/app/routes/simulator/simulator.page.html @@ -70,7 +70,8 @@
- +

Greffe

@@ -80,32 +81,31 @@
-
+

Entrées moyennes mensuelles

Sorties mensuelles possibles

-
+

Stock

-
+

ETPT siège

-
+

ETPT greffe

ETPT EAM

-
+

Taux de couverture

-
+

DTES

-
+

Temps moyen / dossier

@@ -120,7 +120,7 @@ + [header]="{type:'fin', label: stopRealValue,colorClass: categorySelected === 'GREFFE'? 'color-pink':'color-blue',elementColorClass:categorySelected === 'GREFFE'? 'pink-bg':'grey-bg'}"> @@ -205,9 +205,10 @@ -
- +
+
- +
-
- +
+
- +
-
+
+ [ngClass]="{disable: categorySelected !== 'GREFFE', 'greffe': categorySelected === 'GREFFE'}" #etpFon />
- +
-
- +
+
- +
-
- +
+
-
+
-
+
-
+
@@ -520,7 +531,8 @@
-
+
-
+

Entrées mensuelles

Sorties mensuelles

-
+

Stock

-
+

ETPT siège

-
+

ETPT greffe

-
+

ETPT EAM

-
+

Taux de couverture

DTES

-
+

Temps moyen / dossier

@@ -677,7 +692,8 @@
-
+
-
+
-
Vous pouvez effectuer une simulation sans données pré-alimentées en renseignant les données d’effectifs et d’activité correspondantes. Ce peut être utile notamment pour jouer des scenarii sur des activités qui ne sont pas recensées en tant que telles dans A-JUST comme les activités administratives ou le soutien (gestion des scellés par ex.), ou des contentieux qui ne seraient pas isolés spécialement dans A-JUST.”

', + '

Vous pouvez effectuer une simulation sans données pré-alimentées en renseignant les données d’effectifs et d’activité correspondantes. Ce peut être utile notamment pour jouer des scenarii sur des activités qui ne sont pas recensées en tant que telles dans A-JUST comme les activités administratives ou le soutien (gestion des scellés par ex.), ou des contentieux qui ne seraient pas isolés spécialement dans A-JUST.

', + beforeLoad: async (intro: any) => { + const itemToClick = document.querySelector('aj-back-button a') + if (itemToClick) { + // @ts-ignore + itemToClick.click() + await sleep(200) + } + }, }, { target: '.categories-switch', @@ -531,7 +539,7 @@ export class SimulatorPage target: '.date-bar-container', title: 'Configurez votre hypothèse :', intro: - '

Commencez par choisir la catégorie d’effectifs pour laquelle vous souhaitez jouer un scénario. Ensuite, déterminez une date de début et de fin de période, c’est à dire la date future à lesquelles vous souhaitez vous projeter (ex : atteindre un stock de X dossier dans 12 mois).

', + '

Commencez par choisir la catégorie d’effectifs pour laquelle vous souhaitez jouer un scénario. Ensuite, déterminez une date de début et de fin de période, c’est à dire la date future à laquelle vous souhaitez vous projeter (ex : atteindre un stock de X dossier dans 12 mois).

', beforeLoad: async (intro: any) => { if (this.periodSelector) { const now = today() diff --git a/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.html b/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.html index 02332dc03..1ad90fe71 100644 --- a/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.html +++ b/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.html @@ -26,11 +26,10 @@
-
+
-
+
@@ -39,11 +38,10 @@
-
+
-
+
\ No newline at end of file diff --git a/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.scss b/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.scss index 07a1207d0..a90568115 100644 --- a/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.scss +++ b/front/src/app/routes/simulator/situation-displayer/situation-displayer.component.scss @@ -38,6 +38,17 @@ } } + &.color-pink { + background-color: #fee7fc7d !important; + + &::before { + background-color: #fee7fc7d !important; + } + + &::after { + background-color: #fee7fc7d !important; + } + } .line-title { padding: 30px 0px; @@ -79,6 +90,10 @@ background-color: #ececfe !important; } + &.pink-bg { + background-color: #fee7fcdc !important; + } + &.grey-bg { background-color: #e9edfe; diff --git a/front/src/app/styles/form.scss b/front/src/app/styles/form.scss index 18fc1397a..167835acc 100644 --- a/front/src/app/styles/form.scss +++ b/front/src/app/styles/form.scss @@ -87,6 +87,16 @@ input[type='radio'] { content: ' '; display: inline-block; } + + &.pink { + &:checked:before { + background-color: fColor(cpink) !important; + } + + &:after { + border: 1px solid fColor(cpink) !important; + } + } } input[type=submit] { diff --git a/front/src/app/utils/dates.ts b/front/src/app/utils/dates.ts index ab24a9b2d..d7ffe7590 100644 --- a/front/src/app/utils/dates.ts +++ b/front/src/app/utils/dates.ts @@ -397,11 +397,15 @@ export function isFirstDayOfMonth(date = new Date()) { */ export function isDateBiggerThan( firstDate: string | Date, - secondDate: string | Date + secondDate: string | Date, + strict: boolean = false ): boolean { firstDate = new Date(firstDate) secondDate = new Date(secondDate) + if (strict) { + return firstDate.getTime() > secondDate.getTime() + } return firstDate.getTime() >= secondDate.getTime() } diff --git a/front/src/app/utils/referentiel.ts b/front/src/app/utils/referentiel.ts index b3d68ce07..fd9c87616 100644 --- a/front/src/app/utils/referentiel.ts +++ b/front/src/app/utils/referentiel.ts @@ -235,13 +235,13 @@ export function referentielMappingColorCAActivity( case 'Social': return `rgb(212, 231, 232)` case 'Famille': - return `rgb(210, 227, 243)` + return `rgba(210, 227, 243, 1)` case 'CTX JCP': - return `rgb(211, 224, 243)` + return `rgba(198, 219, 242, 1)` case 'Civil Ns': - return `rgb(213, 216, 235)` + return `rgba(208, 213, 248, 1)` case 'Comm.': - return `rgb(218, 212, 237)` + return `rgba(222, 237, 239, 1)` case 'PP': return `rgb(255, 248, 213)` case 'Jld Civil': @@ -264,13 +264,13 @@ export function referentielMappingColorCAActivity( case 'Social': return `rgba(3, 131, 143, ${opacity})` case 'Famille': - return `rgba(1, 118, 190, ${opacity})` + return `rgba(4, 134, 213, ${opacity})` case 'CTX JCP': // Protection - return `rgba(22, 100, 192, ${opacity})` + return `rgba(5, 89, 189, ${opacity})` case 'Civil Ns': return `rgba(40, 53, 146, ${opacity})` case 'Comm.': - return `rgba(38, 190, 206, ${opacity})` + return `rgba(3, 167, 184, ${opacity})` case 'PP': return `rgba(251, 202, 12, ${opacity})` case 'Jld Civil': diff --git "a/front/src/assets/Calculatrice_de_ventilation_du_temps_par_activit\303\251_A-JUST_MAG_et_GRF.xlsx" "b/front/src/assets/Calculatrice_de_ventilation_du_temps_par_activit\303\251_A-JUST_MAG_et_GRF.xlsx" index 8853f6dab..fe1ccfab2 100644 Binary files "a/front/src/assets/Calculatrice_de_ventilation_du_temps_par_activit\303\251_A-JUST_MAG_et_GRF.xlsx" and "b/front/src/assets/Calculatrice_de_ventilation_du_temps_par_activit\303\251_A-JUST_MAG_et_GRF.xlsx" differ diff --git "a/front/src/assets/Feuille_de_temps_Mod\303\250le.xlsx" "b/front/src/assets/Feuille_de_temps_Mod\303\250le.xlsx" index fedc9e85a..0f402746e 100644 Binary files "a/front/src/assets/Feuille_de_temps_Mod\303\250le.xlsx" and "b/front/src/assets/Feuille_de_temps_Mod\303\250le.xlsx" differ diff --git a/package.json b/package.json index 8aababce0..e30b5a7d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "a-just", - "version": "1.7.2", + "version": "1.8.1", "engines": { "node": "16.15.1" },