mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-21 22:24:59 +00:00
Compare commits
64 Commits
integrate_
...
integratio
Author | SHA1 | Date | |
---|---|---|---|
57a9f52fa1 | |||
bf0a24b38e | |||
|
026ac91e69 | ||
176b68417a | |||
1d2299e143 | |||
20ef04683d | |||
b9674d7d28 | |||
ffec80c5fd | |||
7f28effc1e | |||
80672a038c | |||
06abefd576 | |||
|
3799627bf1 | ||
8295788d7f | |||
|
4ae9b29924 | ||
|
1a025ead1b | ||
|
c9cc0dd2a9 | ||
|
10c9526b49 | ||
|
53cad32910 | ||
|
2a40645604 | ||
|
da505ed106 | ||
|
fe4b9647b9 | ||
|
1d7ef9300c | ||
|
bb9e175849 | ||
|
5a3fd2712c | ||
|
0a183c8cfc | ||
|
60328032d8 | ||
|
71900010f6 | ||
|
3599508a3b | ||
|
b1c15ec8ce | ||
|
4f39676e97 | ||
|
84a460c4e7 | ||
|
494573e5b4 | ||
|
c16fc77d01 | ||
|
282539ae6b | ||
|
50f1d3cd10 | ||
|
4e04714a42 | ||
|
8992b99d56 | ||
|
62536ab2ff | ||
|
b189726380 | ||
|
a63c26482e | ||
|
c208797daf | ||
|
0366d0cb17 | ||
|
2b7fa630fc | ||
|
a41b959fbd | ||
|
e4d9129af2 | ||
|
72fc6e05cc | ||
|
47a2af6f19 | ||
|
1bd01aefae | ||
|
c6b6fa5bf6 | ||
|
36d582c8ab | ||
|
df544bdfa4 | ||
|
12e17fac82 | ||
|
b2d84a7677 | ||
|
ebb679dbbb | ||
|
61bb595bba | ||
|
c7aafc6730 | ||
|
24b675ce97 | ||
|
3c888238c5 | ||
|
1bd00535ce | ||
|
d616e00660 | ||
|
5d5ad9e4f7 | ||
|
28af73db19 | ||
|
364aff36a4 | ||
|
3f1b5b2319 |
@@ -139,10 +139,9 @@ class CalendarController extends AbstractController
|
||||
|
||||
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item created!'));
|
||||
|
||||
$params = $this->buildParamsToUrl($user, $accompanyingPeriod); //TODO useful?
|
||||
$params['id'] = $entity->getId();
|
||||
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
|
||||
|
||||
return $this->redirectToRoute('chill_calendar_calendar_show', $params);
|
||||
return $this->redirectToRoute('chill_calendar_calendar', $params);
|
||||
} elseif ($form->isSubmitted() and !$form->isValid()) {
|
||||
$this->addFlash('error', $this->get('translator')->trans('This form contains errors'));
|
||||
}
|
||||
@@ -241,8 +240,7 @@ class CalendarController extends AbstractController
|
||||
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item updated!'));
|
||||
|
||||
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
|
||||
$params['id'] = $id;
|
||||
return $this->redirectToRoute('chill_calendar_calendar_show', $params);
|
||||
return $this->redirectToRoute('chill_calendar_calendar', $params);
|
||||
} elseif ($form->isSubmitted() and !$form->isValid()) {
|
||||
$this->addFlash('error', $this->get('translator')->trans('This form contains errors'));
|
||||
}
|
||||
@@ -304,7 +302,7 @@ class CalendarController extends AbstractController
|
||||
$em->flush();
|
||||
|
||||
$this->addFlash('success', $this->get('translator')
|
||||
->trans("The calendar has been successfully removed."));
|
||||
->trans("The calendar item has been successfully removed."));
|
||||
|
||||
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
|
||||
return $this->redirectToRoute('chill_calendar_calendar', $params);
|
||||
|
@@ -48,13 +48,13 @@ class CalendarType extends AbstractType
|
||||
->add('comment', CommentType::class, [
|
||||
'required' => false
|
||||
])
|
||||
->add('cancelReason', EntityType::class, [
|
||||
'required' => false,
|
||||
'class' => CancelReason::class,
|
||||
'choice_label' => function (CancelReason $entity) {
|
||||
return $entity->getCanceledBy();
|
||||
},
|
||||
])
|
||||
// ->add('cancelReason', EntityType::class, [
|
||||
// 'required' => false,
|
||||
// 'class' => CancelReason::class,
|
||||
// 'choice_label' => function (CancelReason $entity) {
|
||||
// return $entity->getCanceledBy();
|
||||
// },
|
||||
// ])
|
||||
->add('sendSMS', ChoiceType::class, [
|
||||
'required' => false,
|
||||
'choices' => [
|
||||
|
@@ -0,0 +1 @@
|
||||
require('./scss/calendar.scss');
|
@@ -0,0 +1,10 @@
|
||||
div#calendarControls {
|
||||
height: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
div#fullCalendar{
|
||||
|
||||
}
|
@@ -1,18 +1,21 @@
|
||||
<template>
|
||||
<concerned-groups></concerned-groups>
|
||||
<calendar-user-selector
|
||||
v-bind:users="users"
|
||||
v-bind:calendarEvents="calendarEvents"
|
||||
v-bind:updateEventsSource="updateEventsSource"
|
||||
v-bind:showMyCalendar="showMyCalendar"
|
||||
v-bind:toggleMyCalendar="toggleMyCalendar" >
|
||||
</calendar-user-selector>
|
||||
<h2 class="chill-red">{{ $t('choose_your_date') }}</h2>
|
||||
<FullCalendar ref="fullCalendar" :options="calendarOptions">
|
||||
<template v-slot:eventContent='arg'>
|
||||
<b>{{ arg.timeText }}</b>
|
||||
</template>
|
||||
</FullCalendar>
|
||||
<teleport to="#calendarControls">
|
||||
<calendar-user-selector
|
||||
v-bind:users="users"
|
||||
v-bind:calendarEvents="calendarEvents"
|
||||
v-bind:updateEventsSource="updateEventsSource"
|
||||
v-bind:showMyCalendar="showMyCalendar"
|
||||
v-bind:toggleMyCalendar="toggleMyCalendar" >
|
||||
</calendar-user-selector>
|
||||
</teleport>
|
||||
<teleport to="#fullCalendar">
|
||||
<FullCalendar ref="fullCalendar" :options="calendarOptions">
|
||||
<template v-slot:eventContent='arg'>
|
||||
<b>{{ arg.timeText }}</b>
|
||||
</template>
|
||||
</FullCalendar>
|
||||
</teleport>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<h2 class="chill-red">{{ $t('choose_your_calendar_user') }}</h2>
|
||||
<div>
|
||||
<div class="calendar__controls">
|
||||
<h2 class="chill-red">{{ $t('choose_your_calendar_user') }}</h2>
|
||||
<VueMultiselect
|
||||
name="field"
|
||||
id="calendarUserSelector"
|
||||
@@ -196,3 +196,12 @@ export default {
|
||||
|
||||
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
div.calendar__controls {
|
||||
background-color: 'black';
|
||||
height: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
|
@@ -2,7 +2,7 @@ const calendarUserSelectorMessages = {
|
||||
fr: {
|
||||
choose_your_calendar_user: "Afficher les plages de disponibilités",
|
||||
select_user: "Sélectionnez des calendriers",
|
||||
show_my_calendar: "Affichez mon calendrier"
|
||||
show_my_calendar: "Afficher mon calendrier"
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -40,10 +40,6 @@
|
||||
|
||||
.. location
|
||||
|
||||
{%- if form.cancelReason is defined -%}
|
||||
{{ form_row(form.cancelReason) }}
|
||||
{% endif %}
|
||||
|
||||
{%- if form.comment is defined -%}
|
||||
{{ form_row(form.comment) }}
|
||||
{% endif %}
|
||||
@@ -52,8 +48,7 @@
|
||||
{{ form_row(form.sendSMS) }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
..calendarRange
|
||||
<div id="fullCalendar"></div>
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
|
@@ -36,3 +36,7 @@
|
||||
{{ parent() }}
|
||||
{{ encore_entry_link_tags('vue_calendar') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block block_post_menu %}
|
||||
<div id="calendarControls"></div>
|
||||
{% endblock %}
|
@@ -24,22 +24,25 @@
|
||||
<div class="item-bloc">
|
||||
<div class="item-row main">
|
||||
<div class="item-col">
|
||||
|
||||
{% if calendar.startDate %}
|
||||
<h3>{{ calendar.startDate|format_datetime('long') }} </h3>
|
||||
{% endif %}
|
||||
|
||||
{% if calendar.endDate %}
|
||||
<h3>{{ calendar.endDate|format_datetime('long') }}</h3>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div class="duration">
|
||||
<p>
|
||||
<i class="fa fa-fw fa-hourglass-end"></i>
|
||||
{{ calendar.endDate.diff(calendar.startDate)|date("%H:%M")}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{% if calendar.startDate and calendar.endDate %}
|
||||
{% if calendar.endDate.diff(calendar.startDate).days >= 1 %}
|
||||
<h3>{{ "From the day"|trans }} {{ calendar.startDate|format_datetime('medium', 'short') }} </h3>
|
||||
<h3>{{ "to the day"|trans }} {{ calendar.endDate|format_datetime('medium', 'short') }}</h3>
|
||||
{% else %}
|
||||
<h3>{{ calendar.startDate|format_date('full') }} </h3>
|
||||
<h3>{{ calendar.startDate|format_datetime('none', 'short', locale='fr') }} - {{ calendar.endDate|format_datetime('none', 'short', locale='fr') }}</h3>
|
||||
|
||||
<div class="duration">
|
||||
<p>
|
||||
<i class="fa fa-fw fa-hourglass-end"></i>
|
||||
{{ calendar.endDate.diff(calendar.startDate)|date("%H:%M")}}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if context == 'user' and calendar.accompanyingPeriod is not empty %}
|
||||
<div class="accompanyingPeriodLink" style="margin-top: 1rem">
|
||||
@@ -66,7 +69,7 @@
|
||||
|
||||
{% if calendar.mainUser is not empty %}
|
||||
<li>
|
||||
<b>{{ 'main user concerned'|trans }}{{ calendar.mainUser.usernameCanonical }}</b>
|
||||
<b>{{ 'main user concerned'|trans }}: {{ calendar.mainUser.usernameCanonical }}</b>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<h1>{{ "Calendar item creation"|trans ~ ' :' }}</h1>
|
||||
<h1>{{ "Calendar item creation"|trans }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
@@ -34,16 +34,8 @@
|
||||
{{ form_row(form.endDate) }}
|
||||
{% endif %}
|
||||
|
||||
{%- if form.calendarRange is defined -%}
|
||||
{{ form_row(form.calendarRange) }}
|
||||
{% endif %}
|
||||
|
||||
.. location
|
||||
|
||||
{%- if form.cancelReason is defined -%}
|
||||
{{ form_row(form.cancelReason) }}
|
||||
{% endif %}
|
||||
|
||||
{%- if form.comment is defined -%}
|
||||
{{ form_row(form.comment) }}
|
||||
{% endif %}
|
||||
@@ -52,19 +44,16 @@
|
||||
{{ form_row(form.sendSMS) }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
..calendarRange
|
||||
|
||||
|
||||
<div id="fullCalendar"></div>
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a
|
||||
class="btn btn-cancel"
|
||||
{%- if context == 'person' -%}
|
||||
href="{{ chill_return_path_or('chill_activity_activity_list', { 'person_id': person.id } )}}"
|
||||
href="{{ chill_return_path_or('chill_calendar_calendar', { 'person_id': person.id } )}}"
|
||||
{%- else -%}
|
||||
href="{{ chill_return_path_or('chill_activity_activity_list', { 'accompanying_period_id': accompanyingCourse.id } )}}"
|
||||
href="{{ chill_return_path_or('chill_calendar_calendar', { 'accompanying_period_id': accompanyingCourse.id } )}}"
|
||||
{%- endif -%}
|
||||
>
|
||||
{{ 'Cancel'|trans|chill_return_path_label }}
|
||||
|
@@ -34,4 +34,6 @@
|
||||
<link rel="stylesheet" href="{{ asset('build/vue_calendar.css') }}"/>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block block_post_menu %}
|
||||
<div id="calendarControls"></div>
|
||||
{% endblock %}
|
||||
|
@@ -11,11 +11,18 @@
|
||||
|
||||
<h2 class="chill-red">{{ 'Calendar data'|trans }}</h2>
|
||||
|
||||
<dt class="inline">{{ 'start date'|trans }}</dt>
|
||||
<dd>{{ entity.startDate|format_datetime('long') }}</dd>
|
||||
|
||||
<dt class="inline">{{ 'end date'|trans }}</dt>
|
||||
<dd>{{ entity.endDate|format_datetime('long') }}</dd>
|
||||
{% if entity.endDate.diff(entity.startDate).days >= 1 %}
|
||||
<dt>{{ "From the day"|trans }} {{ entity.startDate|format_datetime('medium', 'short') }}
|
||||
{{ "to the day"|trans }} {{ entity.endDate|format_datetime('medium', 'short') }}
|
||||
</dt>
|
||||
<dd></dd>
|
||||
{% else %}
|
||||
<dt>
|
||||
{{ entity.startDate|format_date('full') }},
|
||||
{{ entity.startDate|format_datetime('none', 'short', locale='fr') }} - {{ entity.endDate|format_datetime('none', 'short', locale='fr') }}
|
||||
</dt>
|
||||
<dd></dd>
|
||||
{% endif %}
|
||||
|
||||
<dt class="inline">{{ 'cancel reason'|trans }}</dt>
|
||||
<dd>
|
||||
|
@@ -1,10 +1,10 @@
|
||||
// this file loads all assets from the Chill calendar bundle
|
||||
module.exports = function(encore, entries) {
|
||||
//entries.push(__dirname + '/Resources/public/index.js');
|
||||
entries.push(__dirname + '/Resources/public/chill/index.js');
|
||||
|
||||
encore.addAliases({
|
||||
ChillCalendarAssets: __dirname + '/Resources/public'
|
||||
});
|
||||
|
||||
|
||||
encore.addEntry('vue_calendar', __dirname + '/Resources/public/vuejs/Calendar/index.js');
|
||||
};
|
||||
|
@@ -6,7 +6,7 @@ Are you sure you want to remove the calendar item?: Êtes-vous sûr de vouloir s
|
||||
Concerned groups: Parties concernées
|
||||
Calendar data: Données du rendez-vous
|
||||
Update calendar: Modifier le rendez-vous
|
||||
main user concerned: Utilisateur principal
|
||||
main user concerned: Utilisateur concerné
|
||||
Main user: Utilisateur principal
|
||||
Calendar item creation: Création du rendez-vous
|
||||
start date: début du rendez-vous
|
||||
@@ -18,3 +18,7 @@ sendSMS: Envoi d'un SMS
|
||||
Send s m s: Envoi d'un SMS ?
|
||||
Cancel reason: Motif d'annulation
|
||||
Add a new calendar: Ajouter un nouveau rendez-vous
|
||||
"Success : calendar item updated!": "Rendez-vous mis à jour"
|
||||
The calendar item has been successfully removed.: Le rendez-vous a été supprimé
|
||||
From the day: Du
|
||||
to the day: au
|
@@ -54,9 +54,20 @@ class HouseholdMemberSelectionContext implements DocGeneratorContextInterface
|
||||
*/
|
||||
public function getData($entity): array {
|
||||
$datas = array(
|
||||
'setValue' => array(),
|
||||
'setValues' => array(),
|
||||
'cloneRowAndSetValues' => array()
|
||||
); // TODO CREER UNE CLASSE POUR CA
|
||||
);
|
||||
|
||||
$persons = $entity->getAccompanyingPeriodWork()->getPersons();
|
||||
|
||||
if(sizeof($persons) > 0) {
|
||||
$firstPerson = $persons[0];
|
||||
|
||||
$datas['setValues'][] = array(
|
||||
'firstPersonFirstName' => $firstPerson->getFirstName(),
|
||||
'firstPersonLastName' => $firstPerson->getLastName(),);
|
||||
}
|
||||
|
||||
|
||||
if(get_class($entity) == AccompanyingPeriodWorkEvaluation::class) {
|
||||
$values = array();
|
||||
|
@@ -4,8 +4,12 @@ namespace Chill\DocGeneratorBundle\Controller;
|
||||
|
||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument;
|
||||
use Chill\PersonBundle\Entity\SocialWork\Evaluation;
|
||||
use GuzzleHttp\Exception\TransferException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\HeaderUtils;
|
||||
@@ -57,8 +61,11 @@ class DocGeneratorTemplateController extends AbstractController
|
||||
*/
|
||||
public function generateDocFromTemplateAction(
|
||||
\ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface $tempUrlGenerator,
|
||||
DocGeneratorTemplate $template, string $entityClassName, int $entityId): Response
|
||||
{
|
||||
DocGeneratorTemplate $template,
|
||||
string $entityClassName,
|
||||
int $entityId,
|
||||
Request $request
|
||||
): Response {
|
||||
$getUrlGen = $tempUrlGenerator->generate(
|
||||
'GET',
|
||||
$template->getFile());
|
||||
@@ -77,7 +84,10 @@ class DocGeneratorTemplateController extends AbstractController
|
||||
|
||||
$templateProcessor = new TemplateProcessor($tmpfname);
|
||||
|
||||
// TODO foreach ($datas['setValue'] as $key => $value) {
|
||||
foreach ($datas['setValues'] as $setValuesConf) {
|
||||
$templateProcessor->setValues($setValuesConf);
|
||||
}
|
||||
|
||||
foreach ($datas['cloneRowAndSetValues'] as $cloneRowAndSetValues) {
|
||||
$templateProcessor->cloneRowAndSetValues($cloneRowAndSetValues[0], $cloneRowAndSetValues[1]);
|
||||
}
|
||||
@@ -105,18 +115,31 @@ class DocGeneratorTemplateController extends AbstractController
|
||||
]);
|
||||
|
||||
if ($putResponse->getStatusCode() == 201) {
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$storedObject = new StoredObject();
|
||||
$storedObject
|
||||
// currently, only docx is supported
|
||||
->setType('application/vnd.openxmlformats-officedocument.wordprocessingml.document')
|
||||
->setFilename($genDocName);
|
||||
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$em->persist($storedObject);
|
||||
|
||||
// Only for evaluation
|
||||
if ($entity instanceof AccompanyingPeriodWorkEvaluation) {
|
||||
$doc = new AccompanyingPeriodWorkEvaluationDocument();
|
||||
$doc
|
||||
->setStoredObject($storedObject)
|
||||
->setTemplate($template)
|
||||
;
|
||||
$entity->addDocument($doc);
|
||||
$em->persist($doc);
|
||||
}
|
||||
|
||||
$em->flush();
|
||||
|
||||
return $this->redirectToRoute('chill_wopi_file_edit', [
|
||||
'fileId' => $genDocName
|
||||
'fileId' => $genDocName,
|
||||
'returnPath' => $request->query->get('returnPath', "/")
|
||||
]);
|
||||
}
|
||||
} catch (TransferException $e) {
|
||||
|
@@ -4,11 +4,11 @@ namespace Chill\DocGeneratorBundle\Entity;
|
||||
|
||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
* @ORM\Table(name="chill_docgen_template")
|
||||
|
||||
*/
|
||||
class DocGeneratorTemplate
|
||||
{
|
||||
@@ -16,11 +16,13 @@ class DocGeneratorTemplate
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private int $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json_array")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private array $name = [];
|
||||
|
||||
|
@@ -8,12 +8,11 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
use ChampsLibres\AsyncUploaderBundle\Model\AsyncFileInterface;
|
||||
use ChampsLibres\AsyncUploaderBundle\Validator\Constraints\AsyncFileExists;
|
||||
use DateTimeInterface;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* Represent a document stored in an object store
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* @ORM\Entity()
|
||||
* @ORM\Table("chill_doc.stored_object")
|
||||
* @AsyncFileExists(
|
||||
@@ -26,11 +25,13 @@ class StoredObject implements AsyncFileInterface
|
||||
* @ORM\Id()
|
||||
* @ORM\GeneratedValue()
|
||||
* @ORM\Column(type="integer")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private $filename;
|
||||
|
||||
@@ -48,16 +49,19 @@ class StoredObject implements AsyncFileInterface
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="datetime", name="creation_date")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private DateTimeInterface $creationDate;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", name="type")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private string $type = '';
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="json_array", name="datas")
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private array $datas = [];
|
||||
|
||||
|
@@ -120,7 +120,8 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
|
||||
* @var Collection
|
||||
* @ORM\OneToMany(
|
||||
* targetEntity=AccompanyingPeriodWorkEvaluationDocument::class,
|
||||
* mappedBy="accompanyingPeriodWorkEvaluation"
|
||||
* mappedBy="accompanyingPeriodWorkEvaluation",
|
||||
* cascade={"remove"}
|
||||
* )
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
@@ -135,6 +136,7 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
|
||||
*
|
||||
* @Serializer\Groups({"read"})
|
||||
* @Serializer\Groups({"write"})
|
||||
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
||||
*
|
||||
* @var mixed
|
||||
*
|
||||
@@ -382,6 +384,22 @@ class AccompanyingPeriodWorkEvaluation implements TrackUpdateInterface, TrackCre
|
||||
return $this->documents;
|
||||
}
|
||||
|
||||
public function addDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
|
||||
{
|
||||
if (!$this->documents->contains($document)) {
|
||||
$this->documents[] = $document;
|
||||
$document->setAccompanyingPeriodWorkEvaluation($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
|
||||
{
|
||||
$this->documents->removeElement($document);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Arbitrary data, used for client
|
||||
*
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
|
||||
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
|
||||
use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface;
|
||||
@@ -37,7 +38,7 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
* inversedBy="documents"
|
||||
* )
|
||||
*/
|
||||
private ?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation;
|
||||
private ?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
@@ -45,13 +46,13 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
* )
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?User $createdBy;
|
||||
private ?User $createdBy = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?\DateTimeImmutable $createdAt;
|
||||
private ?\DateTimeImmutable $createdAt = null;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
@@ -59,18 +60,29 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
* )
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?User $updatedBy;
|
||||
private ?User $updatedBy = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="date_immutable", nullable=true, options={"default": null})
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?DateTimeImmutable $updatedAt;
|
||||
private ?\DateTimeImmutable $updatedAt = null;
|
||||
|
||||
// TODO: indiquer le document généré par le module "document"
|
||||
private ?StoredObject $storedObject;
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity=StoredObject::class
|
||||
* )
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?StoredObject $storedObject = null;
|
||||
|
||||
// TODO: ajouter gabarit
|
||||
/**
|
||||
* @ORM\ManyToOne(
|
||||
* targetEntity=DocGeneratorTemplate::class
|
||||
* )
|
||||
* @Serializer\Groups({"read"})
|
||||
*/
|
||||
private ?DocGeneratorTemplate $template = null;
|
||||
|
||||
/**
|
||||
* @return AccompanyingPeriodWorkEvaluation|null
|
||||
@@ -86,6 +98,14 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
*/
|
||||
public function setAccompanyingPeriodWorkEvaluation(?AccompanyingPeriodWorkEvaluation $accompanyingPeriodWorkEvaluation): AccompanyingPeriodWorkEvaluationDocument
|
||||
{
|
||||
// if an evaluation is already associated, we cannot change the association (removing the association,
|
||||
// by setting a null value, is allowed.
|
||||
if ($this->accompanyingPeriodWorkEvaluation instanceof AccompanyingPeriodWorkEvaluation
|
||||
&& $accompanyingPeriodWorkEvaluation instanceof AccompanyingPeriodWorkEvaluation) {
|
||||
if ($this->accompanyingPeriodWorkEvaluation !== $accompanyingPeriodWorkEvaluation) {
|
||||
throw new \RuntimeException("It is not allowed to change the evaluation for a document");
|
||||
}
|
||||
}
|
||||
$this->accompanyingPeriodWorkEvaluation = $accompanyingPeriodWorkEvaluation;
|
||||
return $this;
|
||||
}
|
||||
@@ -172,4 +192,22 @@ class AccompanyingPeriodWorkEvaluationDocument implements \Chill\MainBundle\Doct
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DocGeneratorTemplate|null
|
||||
*/
|
||||
public function getTemplate(): ?DocGeneratorTemplate
|
||||
{
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DocGeneratorTemplate|null $template
|
||||
* @return AccompanyingPeriodWorkEvaluationDocument
|
||||
*/
|
||||
public function setTemplate(?DocGeneratorTemplate $template): AccompanyingPeriodWorkEvaluationDocument
|
||||
{
|
||||
$this->template = $template;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -68,12 +68,15 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="record_actions">
|
||||
<ul class="record_actions" v-if="availableForCheckGoal.length > 0">
|
||||
<li>
|
||||
<button :title="$t('add_an_objective')" class="btn btn-create"
|
||||
@click="toggleAddObjective"></button>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>
|
||||
<span class="chill-no-data-statement">{{ $t('no_goals_available') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div><!-- empty for results --></div>
|
||||
</div>
|
||||
@@ -102,11 +105,14 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="record_actions">
|
||||
<ul class="record_actions" v-if="evaluationsForAction.length > 0">
|
||||
<li>
|
||||
<button :title="$t('add_an_evaluation')" class="btn btn-create" @click="toggleAddEvaluation"></button>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>
|
||||
<span class="chill-no-data-statement">{{ $t('no_evaluations_available') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -255,6 +261,8 @@ const i18n = {
|
||||
choose_thirdparties: "Choisir des tiers",
|
||||
fix_these_errors: "Veuillez corriger les erreurs suivantes :",
|
||||
available_evaluations_text: "Évaluations disponibles pour ajout :",
|
||||
no_evaluations_available: "Aucune évaluation disponible",
|
||||
no_goals_available: "Aucun objectif disponible",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -19,8 +19,20 @@
|
||||
<dt v-if="evaluation.warningInterval">{{ $t('warningInterval') }} :</dt>
|
||||
<dd v-if="evaluation.warningInterval">{{ evaluation.warningInterval }}</dd>
|
||||
|
||||
<dt v-if="evaluation.documents && evaluation.documents.length > 0">{{ $t('documents') }} :</dt>
|
||||
<dd v-if="evaluation.documents && evaluation.documents.length > 0">{{ evaluation.documents.length }}</dd>
|
||||
<template v-if="evaluation.documents.length > 0">
|
||||
<dt>{{ $t('documents') }} :</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li v-for="d in evaluation.documents">
|
||||
{{ d.template.name.fr }}
|
||||
<a :href="buildEditLink(d.storedObject)" class="btn btn-action btn-sm">
|
||||
<i class="fa fa-edit"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
||||
</template>
|
||||
|
||||
</dl>
|
||||
<dl class="item-details">
|
||||
@@ -82,7 +94,7 @@ export default {
|
||||
computed: {
|
||||
pickedEvaluations() {
|
||||
return this.$store.state.evaluationsPicked;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
removeEvaluation(e) {
|
||||
@@ -95,7 +107,11 @@ export default {
|
||||
},
|
||||
submitForm() {
|
||||
this.toggleEditEvaluation();
|
||||
}
|
||||
},
|
||||
buildEditLink(storedObject) {
|
||||
return `/fr/chill_wopi/edit/${storedObject.filename}?returnPath=` + encodeURIComponent(
|
||||
window.location.pathname + window.location.search + window.location.hash);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@@ -17,6 +17,10 @@
|
||||
'layout': '@ChillPerson/menu.html.twig',
|
||||
'args' : { 'accompanyingCourse': accompanyingCourse }
|
||||
}) }}
|
||||
|
||||
{% block block_post_menu %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add a link between evaluation document, stored object, and document template
|
||||
*/
|
||||
final class Version20210820093927 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add a link between evaluation document, stored object, and document template';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD template_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD storedObject_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD CONSTRAINT FK_33EC92296C99C13A FOREIGN KEY (storedObject_id) REFERENCES chill_doc.stored_object (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document ADD CONSTRAINT FK_33EC92295DA0FB8 FOREIGN KEY (template_id) REFERENCES chill_docgen_template (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_33EC92296C99C13A ON chill_person_accompanying_period_work_evaluation_document (storedObject_id)');
|
||||
$this->addSql('CREATE INDEX IDX_33EC92295DA0FB8 ON chill_person_accompanying_period_work_evaluation_document (template_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP CONSTRAINT FK_33EC92296C99C13A');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP CONSTRAINT FK_33EC92295DA0FB8');
|
||||
$this->addSql('DROP INDEX IDX_33EC92296C99C13A');
|
||||
$this->addSql('DROP INDEX IDX_33EC92295DA0FB8');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP template_id');
|
||||
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation_document DROP storedObject_id');
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\Migrations\Person;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Add missing sequence for evaluation documents
|
||||
*/
|
||||
final class Version20210820100407 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add missing sequence for evaluation documents';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql('CREATE SEQUENCE chill_person_social_work_eval_doc_id_seq INCREMENT BY 1 MINVALUE 1000 START 1000');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('DROP SEQUENCE chill_person_social_work_eval_doc_id_seq');
|
||||
}
|
||||
}
|
6
src/Bundle/ChillWopiBundle/chill.webpack.config.js
Normal file
6
src/Bundle/ChillWopiBundle/chill.webpack.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// this file loads all assets from the Chill person bundle
|
||||
module.exports = function(encore, entries)
|
||||
{
|
||||
encore.addEntry('page_wopi_editor', __dirname + '/src/Resources/public/page/editor/index.js');
|
||||
//home/julien/dev/département-vendee/chill/vendor/chill-project/chill-bundles/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js
|
||||
};
|
@@ -16,6 +16,7 @@ use Chill\WopiBundle\Service\Controller\ResponderInterface;
|
||||
use Exception;
|
||||
use loophp\psr17\Psr17Interface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
@@ -61,7 +62,7 @@ final class Test
|
||||
$storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
|
||||
|
||||
if (null === $storedObject) {
|
||||
throw new Exception(sprintf('Unable to find object named %s', $fileId));
|
||||
throw new NotFoundHttpException(sprintf('Unable to find object named %s', $fileId));
|
||||
}
|
||||
|
||||
if ([] === $discoverExtension = $this->wopiDiscovery->discoverMimeType($storedObject->getType())) {
|
||||
@@ -86,6 +87,7 @@ final class Test
|
||||
],
|
||||
UrlGeneratorInterface::ABSOLUTE_URL
|
||||
),
|
||||
'closebutton' => 1
|
||||
]
|
||||
)
|
||||
);
|
||||
@@ -93,7 +95,7 @@ final class Test
|
||||
return $this
|
||||
->responder
|
||||
->render(
|
||||
'@Wopi/Editor/page.html.twig',
|
||||
'@ChillWopi/Editor/page.html.twig',
|
||||
$configuration
|
||||
);
|
||||
|
||||
|
@@ -0,0 +1,46 @@
|
||||
require('./index.scss');
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function(e) {
|
||||
let frameholder = document.getElementById('frameholder');
|
||||
let office_frame = document.createElement('iframe');
|
||||
office_frame.name = 'office_frame';
|
||||
office_frame.id = 'office_frame';
|
||||
|
||||
// The title should be set for accessibility
|
||||
office_frame.title = 'Office Frame';
|
||||
|
||||
// This attribute allows true fullscreen mode in slideshow view
|
||||
// when using PowerPoint's 'view' action.
|
||||
office_frame.setAttribute('allowfullscreen', 'true');
|
||||
|
||||
// The sandbox attribute is needed to allow automatic redirection to the O365 sign-in page in the business user flow
|
||||
office_frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation allow-popups-to-escape-sandbox');
|
||||
frameholder.appendChild(office_frame);
|
||||
|
||||
document.getElementById('office_form').submit();
|
||||
console.log(office_frame);
|
||||
|
||||
const url = new URL(editor_url);
|
||||
const editor_domain = url.origin;
|
||||
|
||||
window.addEventListener("message", function(message) {
|
||||
if (message.origin !== editor_domain) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = JSON.parse(message.data);
|
||||
|
||||
if ('UI_Close' === data.MessageId) {
|
||||
closeEditor();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function closeEditor() {
|
||||
let
|
||||
params = new URLSearchParams(window.location.search),
|
||||
returnPath = params.get('returnPath');
|
||||
|
||||
window.location.assign(returnPath);
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
-ms-content-zooming: none;
|
||||
}
|
||||
|
||||
#office_frame {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
<style type="text/css">
|
||||
#office_frame {
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form id="office_form" name="office_form" target="office_frame" action="{{ server }}" method="post">
|
||||
<input name="access_token" value="{{ access_token }}" type="hidden" />
|
||||
<input name="access_token_ttl" value="{{ access_token_ttl }}" type="hidden" />
|
||||
</form>
|
||||
|
||||
<span id="frameholder"></span>
|
||||
|
||||
<script type="text/javascript">
|
||||
var frameholder = document.getElementById('frameholder');
|
||||
var office_frame = document.createElement('iframe');
|
||||
office_frame.name = 'office_frame';
|
||||
office_frame.id = 'office_frame';
|
||||
|
||||
// The title should be set for accessibility
|
||||
office_frame.title = 'Office Frame';
|
||||
|
||||
// This attribute allows true fullscreen mode in slideshow view
|
||||
// when using PowerPoint's 'view' action.
|
||||
office_frame.setAttribute('allowfullscreen', 'true');
|
||||
|
||||
// The sandbox attribute is needed to allow automatic redirection to the O365 sign-in page in the business user flow
|
||||
office_frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation allow-popups-to-escape-sandbox');
|
||||
frameholder.appendChild(office_frame);
|
||||
|
||||
document.getElementById('office_form').submit();
|
||||
</script>
|
@@ -0,0 +1,33 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<!-- Enable IE Standards mode -->
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
|
||||
<title></title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||
|
||||
<link rel="shortcut icon" href="{{ favIconUrl }}" />
|
||||
<script type="text/javascript">
|
||||
const editor_url = "{{ server|escape('js') }}";
|
||||
</script>
|
||||
{{ encore_entry_link_tags('page_wopi_editor') }}
|
||||
{{ encore_entry_script_tags('page_wopi_editor') }}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<form id="office_form" name="office_form" target="office_frame" action="{{ server }}" method="post">
|
||||
<input name="access_token" value="{{ access_token }}" type="hidden" />
|
||||
<input name="access_token_ttl" value="{{ access_token_ttl }}" type="hidden" />
|
||||
</form>
|
||||
|
||||
<span id="frameholder"></span>
|
||||
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user