-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Permettre aux prescripteurs de télécharger les attestations…
- Loading branch information
Showing
27 changed files
with
558 additions
and
16 deletions.
There are no files selected for viewing
14 changes: 14 additions & 0 deletions
14
api/db/migrations/20241107142820_add-attestations-management-feature.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { ORGANIZATION_FEATURE } from '../../src/shared/domain/constants.js'; | ||
|
||
const up = async function (knex) { | ||
await knex('features').insert({ | ||
key: ORGANIZATION_FEATURE.ATTESTATIONS_MANAGEMENT.key, | ||
description: ORGANIZATION_FEATURE.ATTESTATIONS_MANAGEMENT.description, | ||
}); | ||
}; | ||
|
||
const down = async function (knex) { | ||
await knex('features').where({ key: ORGANIZATION_FEATURE.ATTESTATIONS_MANAGEMENT.key }).delete(); | ||
}; | ||
|
||
export { down, up }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import PixButton from '@1024pix/pix-ui/components/pix-button'; | ||
import PixMultiSelect from '@1024pix/pix-ui/components/pix-multi-select'; | ||
import { on } from '@ember/modifier'; | ||
import { action } from '@ember/object'; | ||
import Component from '@glimmer/component'; | ||
import { tracked } from '@glimmer/tracking'; | ||
import { t } from 'ember-intl'; | ||
|
||
export default class AttestationsSixthGrade extends Component { | ||
@tracked selectedDivisions = []; | ||
|
||
@action | ||
onSubmit(event) { | ||
event.preventDefault(); | ||
|
||
this.args.onSubmit(this.selectedDivisions); | ||
} | ||
|
||
@action | ||
onSelectDivision(value) { | ||
this.selectedDivisions = value; | ||
} | ||
|
||
get isDisabled() { | ||
return !this.selectedDivisions.length; | ||
} | ||
|
||
<template> | ||
<h1 class="attestations-page__title">{{t "pages.attestations.title"}}</h1> | ||
|
||
<p class="attestations-page__text"> | ||
{{t "pages.attestations.description"}} | ||
</p> | ||
|
||
<form class="attestations-page__action" {{on "submit" this.onSubmit}}> | ||
<PixMultiSelect | ||
@isSearchable={{true}} | ||
@options={{@divisions}} | ||
@values={{this.selectedDivisions}} | ||
@onChange={{this.onSelectDivision}} | ||
@placeholder={{t "pages.attestations.placeholder"}} | ||
> | ||
<:label>{{t "pages.attestations.select-label"}}</:label> | ||
<:default as |option|>{{option.label}}</:default> | ||
</PixMultiSelect> | ||
<PixButton @type="submit" id="download_attestations" @size="small" @isDisabled={{this.isDisabled}}> | ||
{{t "pages.attestations.download-attestations-button"}} | ||
</PixButton> | ||
</form> | ||
</template> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import Controller from '@ember/controller'; | ||
import { action } from '@ember/object'; | ||
import { service } from '@ember/service'; | ||
|
||
export const SIXTH_GRADE_ATTESTATION_KEY = 'SIXTH_GRADE'; | ||
export const SIXTH_GRADE_ATTESTATION_FILE_NAME = 'attestations'; | ||
|
||
export default class AuthenticatedAttestationsController extends Controller { | ||
@service fileSaver; | ||
@service session; | ||
@service currentUser; | ||
@service notifications; | ||
|
||
@action | ||
async downloadSixthGradeAttestationsFile(selectedDivisions) { | ||
try { | ||
const organizationId = this.currentUser.organization.id; | ||
const formatedDivisionsForQuery = selectedDivisions | ||
.map((division) => `divisions[]=${encodeURIComponent(division)}`) | ||
.join('&'); | ||
|
||
const url = `/api/organizations/${organizationId}/attestations/${SIXTH_GRADE_ATTESTATION_KEY}?${formatedDivisionsForQuery}`; | ||
|
||
const token = this.session.isAuthenticated ? this.session.data.authenticated.access_token : ''; | ||
|
||
await this.fileSaver.save({ url, token, fileName: SIXTH_GRADE_ATTESTATION_FILE_NAME }); | ||
} catch (error) { | ||
this.notifications.sendError(error.message, { autoClear: false }); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import Route from '@ember/routing/route'; | ||
import { service } from '@ember/service'; | ||
|
||
export default class AuthenticatedAttestationsRoute extends Route { | ||
@service currentUser; | ||
@service router; | ||
|
||
beforeModel() { | ||
if (!this.currentUser.canAccessAttestationsPage) { | ||
this.router.replaceWith('application'); | ||
} | ||
} | ||
|
||
async model() { | ||
const divisions = await this.currentUser.organization.divisions; | ||
const options = divisions.map(({ name }) => ({ label: name, value: name })); | ||
return { options }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
.attestations-page { | ||
display: flex; | ||
flex-direction: column; | ||
|
||
&__title { | ||
@extend %pix-title-m; | ||
|
||
margin: var(--pix-spacing-8x) 0; | ||
} | ||
|
||
&__text { | ||
@extend %pix-body-m; | ||
|
||
margin-bottom: var(--pix-spacing-8x); | ||
|
||
} | ||
|
||
&__action { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: var(--pix-spacing-4x); | ||
align-items: end | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{{page-title (t "pages.attestations.title")}} | ||
|
||
<div class="attestations-page"> | ||
<Attestations::SixthGrade @divisions={{@model.options}} @onSubmit={{this.downloadSixthGradeAttestationsFile}} /> | ||
</div> |
70 changes: 70 additions & 0 deletions
70
orga/tests/integration/components/attestations/sixth-grade-test.gjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { render } from '@1024pix/ember-testing-library'; | ||
import { click } from '@ember/test-helpers'; | ||
import { t } from 'ember-intl/test-support'; | ||
import SixthGrade from 'pix-orga/components/attestations/sixth-grade'; | ||
import { module, test } from 'qunit'; | ||
import sinon from 'sinon'; | ||
|
||
import setupIntlRenderingTest from '../../../helpers/setup-intl-rendering'; | ||
|
||
module('Integration | Component | Attestations | Sixth-grade', function (hooks) { | ||
setupIntlRenderingTest(hooks); | ||
|
||
test('it should display all basics informations', async function (assert) { | ||
// given | ||
const onSubmit = sinon.stub(); | ||
const divisions = []; | ||
|
||
// when | ||
const screen = await render(<template><SixthGrade @divisions={{divisions}} @onSubmit={{onSubmit}} /></template>); | ||
// then | ||
assert.ok(screen.getByRole('heading', { name: t('pages.attestations.title') })); | ||
assert.ok(screen.getByText(t('pages.attestations.description'))); | ||
assert.ok(screen.getByRole('textbox', { name: t('pages.attestations.select-label') })); | ||
assert.ok(screen.getByPlaceholderText(t('pages.attestations.placeholder'))); | ||
assert.ok(screen.getByRole('button', { name: t('pages.attestations.download-attestations-button') })); | ||
}); | ||
|
||
test('download button is disabled if there is no selected divisions', async function (assert) { | ||
// given | ||
const onSubmit = sinon.stub(); | ||
const divisions = []; | ||
|
||
// when | ||
const screen = await render(<template><SixthGrade @divisions={{divisions}} @onSubmit={{onSubmit}} /></template>); | ||
|
||
// then | ||
const downloadButton = await screen.getByRole('button', { | ||
name: t('pages.attestations.download-attestations-button'), | ||
}); | ||
assert.dom(downloadButton).isDisabled(); | ||
}); | ||
|
||
test('it should call onSubmit action with selected divisions', async function (assert) { | ||
// given | ||
const onSubmit = sinon.stub(); | ||
|
||
const divisions = [{ label: 'division1', value: 'division1' }]; | ||
|
||
// when | ||
const screen = await render(<template><SixthGrade @divisions={{divisions}} @onSubmit={{onSubmit}} /></template>); | ||
|
||
const multiSelect = await screen.getByRole('textbox', { name: t('pages.attestations.select-label') }); | ||
await click(multiSelect); | ||
|
||
const firstDivisionOption = await screen.findByRole('checkbox', { name: 'division1' }); | ||
await click(firstDivisionOption); | ||
|
||
const downloadButton = await screen.getByRole('button', { | ||
name: t('pages.attestations.download-attestations-button'), | ||
}); | ||
|
||
// we need to get out of input choice to click on download button, so we have to click again on the multiselect to close it | ||
await click(multiSelect); | ||
await click(downloadButton); | ||
|
||
// then | ||
sinon.assert.calledWithExactly(onSubmit, ['division1']); | ||
assert.ok(true); | ||
}); | ||
}); |
Oops, something went wrong.