Skip to content

Commit

Permalink
[ORGA] Afficher le décompte des places dans le header de l'application (
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored May 6, 2024
2 parents dbcd7cd + 627c3d1 commit 47d777b
Show file tree
Hide file tree
Showing 19 changed files with 507 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,6 @@ const register = async (server) => {
path: '/api/organizations/{id}/place-statistics',
config: {
pre: [
{
method: securityPreHandlers.checkUserIsAdminInOrganization,
assign: 'isAdminInOrganization',
},
{
method: securityPreHandlers.makeCheckOrganizationHasFeature(ORGANIZATION_FEATURE.PLACES_MANAGEMENT.key),
assign: 'checkOrganizationHasPlacesFeature',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import jsonapiSerializer from 'jsonapi-serializer';

import { organizationPlaceController } from '../../../../../src/prescription/organization-place/application/organization-place-controller.js';
import * as moduleUnderTest from '../../../../../src/prescription/organization-place/application/organization-place-route.js';
import * as organizationPlacesCategories from '../../../../../src/prescription/organization-place/domain/constants/organization-places-categories.js';
import { usecases } from '../../../../../src/prescription/organization-place/domain/usecases/index.js';
import { securityPreHandlers } from '../../../../../src/shared/application/security-pre-handlers.js';
import { ORGANIZATION_FEATURE } from '../../../../../src/shared/domain/constants.js';
import { expect, sinon } from '../../../../test-helper.js';
import { HttpTestServer } from '../../../../tooling/server/http-test-server.js';

Expand Down Expand Up @@ -129,4 +132,68 @@ describe('Unit | Router | organization-place-route', function () {
expect(response.statusCode).to.equal(403);
});
});

describe('GET /api/organizations/{id}/places-statistics', function () {
let checkOrganizationHasPlacesFeature, respondWithError;

beforeEach(function () {
checkOrganizationHasPlacesFeature = sinon.stub();
sinon
.stub(securityPreHandlers, 'makeCheckOrganizationHasFeature')
.withArgs(ORGANIZATION_FEATURE.PLACES_MANAGEMENT.key)
.returns(checkOrganizationHasPlacesFeature);

respondWithError = (_, h) =>
h
.response(
new jsonapiSerializer.Error({
code: 403,
title: 'Forbidden access',
detail: 'Missing or insufficient permissions.',
}),
)
.code(403)
.takeover();
});

it('should return HTTP code 200 when organization has the right feature activated', async function () {
// given
const method = 'GET';
const url = '/api/organizations/1/place-statistics';
const payload = {};

checkOrganizationHasPlacesFeature.resolves(true);

sinon
.stub(organizationPlaceController, 'getOrganizationPlacesStatistics')
.callsFake((_, h) => h.response('ok').code(200));

const httpTestServer = new HttpTestServer();
await httpTestServer.register(moduleUnderTest);
// when
const response = await httpTestServer.request(method, url, payload);

// then
expect(organizationPlaceController.getOrganizationPlacesStatistics).to.have.been.calledOnce;
expect(response.statusCode).to.equal(200);
});

it('should return HTTP code 403 if organization doesnt have the right feature activated', async function () {
// given
const method = 'GET';
const url = '/api/organizations/1/place-statistics';
const payload = {};

checkOrganizationHasPlacesFeature.callsFake(respondWithError);

const httpTestServer = new HttpTestServer();
await httpTestServer.register(moduleUnderTest);

// when
const response = await httpTestServer.request(method, url, payload);

// then
expect(response.statusCode).to.equal(403);
});
});
});
17 changes: 0 additions & 17 deletions orga/app/components/layout/organization-credit-info.hbs

This file was deleted.

10 changes: 0 additions & 10 deletions orga/app/components/layout/organization-credit-info.js

This file was deleted.

44 changes: 44 additions & 0 deletions orga/app/components/layout/organization-places-or-credit-info.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import PixTooltip from '@1024pix/pix-ui/components/pix-tooltip';
import { service } from '@ember/service';
import FaIcon from '@fortawesome/ember-fontawesome/components/fa-icon';
import Component from '@glimmer/component';
import { t } from 'ember-intl';
import { eq } from 'ember-truth-helpers';

export default class OrganizationPlacesOrCreditInfo extends Component {
@service currentUser;

get canShowCredit() {
return this.currentUser.isAdminInOrganization && this.currentUser.organization.credit > 0;
}

<template>
{{#if this.currentUser.prescriber.placesManagement}}
<div class="organization-places-or-credit-info hide-on-mobile">
{{#if (eq @placesCount 0)}}
<span class="organization-places-or-credit-info__warning">
<FaIcon @icon="triangle-exclamation" class="warning-icon" />
{{t "navigation.places.number" count=@placesCount}}</span>
{{else}}
<span>{{t "navigation.places.number" count=@placesCount}}</span>
{{/if}}
{{#if this.currentUser.isAdminInOrganization}}
<a href="/places" class="organization-places-or-credit-info__link">{{t "navigation.places.link"}}</a>
{{/if}}
</div>
{{else if this.canShowCredit}}
<div class="organization-places-or-credit-info hide-on-mobile">
<span>{{t "navigation.credits.number" count=this.currentUser.organization.credit}}</span>

<PixTooltip @id="credit-info-tooltip" @position="bottom-left" @isWide={{true}} @isLight={{true}}>
<:triggerElement>
<FaIcon @icon="circle-info" class="info-icon" tabindex="0" aria-describedby="credit-info-tooltip" />
</:triggerElement>
<:tooltip>
{{t "navigation.credits.tooltip-text" htmlSafe=true}}
</:tooltip>
</PixTooltip>
</div>
{{/if}}
</template>
}
4 changes: 1 addition & 3 deletions orga/app/components/layout/topbar.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<div class="topbar">
<div class="topbar__organization-credit-info hide-on-mobile">
<Layout::OrganizationCreditInfo />
</div>
<Layout::OrganizationPlacesOrCreditInfo @placesCount={{@placesCount}} />
<Layout::UserLoggedMenu class="topbar__user-logged-menu" />
</div>
9 changes: 9 additions & 0 deletions orga/app/routes/authenticated.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default class AuthenticatedRoute extends Route {
@service currentUser;
@service router;
@service session;
@service store;

beforeModel(transition) {
this.session.requireAuthentication(transition, 'login');
Expand All @@ -19,4 +20,12 @@ export default class AuthenticatedRoute extends Route {
return this.router.replaceWith('terms-of-service');
}
}

async model() {
if (this.currentUser.prescriber.placesManagement) {
return await this.store.queryRecord('organization-place-statistic', {
organizationId: this.currentUser.organization.id,
});
} else return null;
}
}
12 changes: 3 additions & 9 deletions orga/app/routes/authenticated/places.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@ export default class AuthenticatedPlacesRoute extends Route {
@service store;

beforeModel() {
if (!this.currentUser.shouldAccessPlacesPage) {
if (!(this.currentUser.isAdminInOrganization && this.currentUser.prescriber.placesManagement)) {
this.router.replaceWith('application');
}
}

async model() {
try {
return await this.store.queryRecord('organization-place-statistic', {
organizationId: this.currentUser.organization.id,
});
} catch (_) {
this.router.replaceWith('application');
}
model() {
return this.modelFor('authenticated');
}
}
2 changes: 1 addition & 1 deletion orga/app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
@import 'components/mission/header';
@import 'components/join-request-form';
@import 'components/layout/footer';
@import 'components/layout/organization-credit-info';
@import 'components/layout/organization-places-or-credit-info';
@import 'components/layout/sidebar';
@import 'components/layout/topbar';
@import 'components/layout/user-logged-menu';
Expand Down
16 changes: 0 additions & 16 deletions orga/app/styles/components/layout/organization-credit-info.scss

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.organization-places-or-credit-info {
@extend %pix-body-s;

display: flex;
flex-direction: column;
padding: 0 30px;
color: var(--pix-neutral-900);
font-weight: var(--pix-font-bold);

&__warning {
color: var(--pix-error-700);
font-weight: var(--pix-font-medium);
}

&__link {
color: var(--pix-neutral-500);
font-weight: var(--pix-font-medium);
text-decoration: underline;
}

.info-icon {
margin: 0 8px;
color: var(--pix-neutral-100);
}

.warning-icon {
margin: 0 var(--pix-spacing-1x);
color: var(--pix-error-700);
}
}
4 changes: 0 additions & 4 deletions orga/app/styles/components/layout/topbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,4 @@
height: 60px;
margin-bottom: var(--pix-spacing-6x);
background-color: var(--pix-neutral-0);

&__organization-credit-info {
padding: 0 30px;
}
}
2 changes: 1 addition & 1 deletion orga/app/templates/authenticated.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<div class="main-content">
<header>
<Layout::Topbar />
<Layout::Topbar @placesCount={{@model.available}} />
</header>

<main class="main-content__body page">
Expand Down

This file was deleted.

Loading

0 comments on commit 47d777b

Please sign in to comment.