mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch 'master' into upgrade-php82
This commit is contained in:
commit
27dbdbcd96
@ -34,6 +34,7 @@ use Psr\Log\LoggerInterface;
|
|||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
@ -64,6 +65,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
|
|
||||||
private OnBehalfOfUserHttpClient $userHttpClient;
|
private OnBehalfOfUserHttpClient $userHttpClient;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
CalendarRepository $calendarRepository,
|
CalendarRepository $calendarRepository,
|
||||||
CalendarRangeRepository $calendarRangeRepository,
|
CalendarRangeRepository $calendarRangeRepository,
|
||||||
@ -74,7 +77,8 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
OnBehalfOfUserHttpClient $userHttpClient,
|
OnBehalfOfUserHttpClient $userHttpClient,
|
||||||
RemoteEventConverter $remoteEventConverter,
|
RemoteEventConverter $remoteEventConverter,
|
||||||
TranslatorInterface $translator,
|
TranslatorInterface $translator,
|
||||||
UrlGeneratorInterface $urlGenerator
|
UrlGeneratorInterface $urlGenerator,
|
||||||
|
Security $security
|
||||||
) {
|
) {
|
||||||
$this->calendarRepository = $calendarRepository;
|
$this->calendarRepository = $calendarRepository;
|
||||||
$this->calendarRangeRepository = $calendarRangeRepository;
|
$this->calendarRangeRepository = $calendarRangeRepository;
|
||||||
@ -86,6 +90,7 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->urlGenerator = $urlGenerator;
|
$this->urlGenerator = $urlGenerator;
|
||||||
$this->userHttpClient = $userHttpClient;
|
$this->userHttpClient = $userHttpClient;
|
||||||
|
$this->security = $security;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int
|
public function countEventsForUser(User $user, DateTimeImmutable $startDate, DateTimeImmutable $endDate): int
|
||||||
@ -133,6 +138,24 @@ class MSGraphRemoteCalendarConnector implements RemoteCalendarConnectorInterface
|
|||||||
|
|
||||||
public function isReady(): bool
|
public function isReady(): bool
|
||||||
{
|
{
|
||||||
|
$user = $this->security->getUser();
|
||||||
|
|
||||||
|
if (!$user instanceof User) {
|
||||||
|
// this is not a user from chill. This is not the role of this class to
|
||||||
|
// restrict access, so we will just say that we do not have to do anything more
|
||||||
|
// here...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $this->mapCalendarToUser->getUserId($user)) {
|
||||||
|
// this user is not mapped with remote calendar. The user will have to wait for
|
||||||
|
// the next calendar subscription iteration
|
||||||
|
$this->logger->debug('mark user ready for msgraph calendar as he does not have any mapping', [
|
||||||
|
'userId' => $user->getId(),
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->tokenStorage->hasToken();
|
return $this->tokenStorage->hasToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,16 @@ class AccompanyingCourseDocumentWorkflowHandler implements EntityWorkflowHandler
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||||
|
{
|
||||||
|
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||||
|
|
||||||
|
$referrer = $this->getRelatedEntity($entityWorkflow)->getCourse()->getUser();
|
||||||
|
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||||
|
|
||||||
|
return $suggestedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||||
{
|
{
|
||||||
return '@ChillDocStore/AccompanyingCourseDocument/_workflow.html.twig';
|
return '@ChillDocStore/AccompanyingCourseDocument/_workflow.html.twig';
|
||||||
|
@ -30,6 +30,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||||
use Symfony\Component\Workflow\Registry;
|
use Symfony\Component\Workflow\Registry;
|
||||||
use Symfony\Component\Workflow\TransitionBlocker;
|
use Symfony\Component\Workflow\TransitionBlocker;
|
||||||
@ -48,11 +49,13 @@ class WorkflowController extends AbstractController
|
|||||||
|
|
||||||
private Registry $registry;
|
private Registry $registry;
|
||||||
|
|
||||||
|
private Security $security;
|
||||||
|
|
||||||
private TranslatorInterface $translator;
|
private TranslatorInterface $translator;
|
||||||
|
|
||||||
private ValidatorInterface $validator;
|
private ValidatorInterface $validator;
|
||||||
|
|
||||||
public function __construct(EntityWorkflowManager $entityWorkflowManager, EntityWorkflowRepository $entityWorkflowRepository, ValidatorInterface $validator, PaginatorFactory $paginatorFactory, Registry $registry, EntityManagerInterface $entityManager, TranslatorInterface $translator)
|
public function __construct(EntityWorkflowManager $entityWorkflowManager, EntityWorkflowRepository $entityWorkflowRepository, ValidatorInterface $validator, PaginatorFactory $paginatorFactory, Registry $registry, EntityManagerInterface $entityManager, TranslatorInterface $translator, Security $security)
|
||||||
{
|
{
|
||||||
$this->entityWorkflowManager = $entityWorkflowManager;
|
$this->entityWorkflowManager = $entityWorkflowManager;
|
||||||
$this->entityWorkflowRepository = $entityWorkflowRepository;
|
$this->entityWorkflowRepository = $entityWorkflowRepository;
|
||||||
@ -61,6 +64,7 @@ class WorkflowController extends AbstractController
|
|||||||
$this->registry = $registry;
|
$this->registry = $registry;
|
||||||
$this->entityManager = $entityManager;
|
$this->entityManager = $entityManager;
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->security = $security;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -291,10 +295,18 @@ class WorkflowController extends AbstractController
|
|||||||
|
|
||||||
if (count($workflow->getEnabledTransitions($entityWorkflow)) > 0) {
|
if (count($workflow->getEnabledTransitions($entityWorkflow)) > 0) {
|
||||||
// possible transition
|
// possible transition
|
||||||
|
|
||||||
|
$usersInvolved = $entityWorkflow->getUsersInvolved();
|
||||||
|
$currentUserFound = array_search($this->security->getUser(), $usersInvolved, true);
|
||||||
|
|
||||||
|
if (false !== $currentUserFound) {
|
||||||
|
unset($usersInvolved[$currentUserFound]);
|
||||||
|
}
|
||||||
|
|
||||||
$transitionForm = $this->createForm(
|
$transitionForm = $this->createForm(
|
||||||
WorkflowStepType::class,
|
WorkflowStepType::class,
|
||||||
$entityWorkflow->getCurrentStep(),
|
$entityWorkflow->getCurrentStep(),
|
||||||
['transition' => true, 'entity_workflow' => $entityWorkflow]
|
['transition' => true, 'entity_workflow' => $entityWorkflow, 'suggested_users' => $usersInvolved]
|
||||||
);
|
);
|
||||||
|
|
||||||
$transitionForm->handleRequest($request);
|
$transitionForm->handleRequest($request);
|
||||||
|
@ -348,6 +348,23 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
return $this->transitionningStep;
|
return $this->transitionningStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User[]
|
||||||
|
*/
|
||||||
|
public function getUsersInvolved(): array
|
||||||
|
{
|
||||||
|
$usersInvolved = [];
|
||||||
|
$usersInvolved[spl_object_hash($this->getCreatedBy())] = $this->getCreatedBy();
|
||||||
|
|
||||||
|
foreach ($this->steps as $step) {
|
||||||
|
foreach ($step->getDestUser() as $u) {
|
||||||
|
$usersInvolved[spl_object_hash($u)] = $u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $usersInvolved;
|
||||||
|
}
|
||||||
|
|
||||||
public function getWorkflowName(): string
|
public function getWorkflowName(): string
|
||||||
{
|
{
|
||||||
return $this->workflowName;
|
return $this->workflowName;
|
||||||
|
@ -56,12 +56,7 @@ class CommentType extends AbstractType
|
|||||||
|
|
||||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
{
|
{
|
||||||
$view->vars = array_replace(
|
$view->vars['fullWidth'] = true;
|
||||||
$view->vars,
|
|
||||||
[
|
|
||||||
'fullWidth' => true,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
@ -19,6 +19,7 @@ use Symfony\Component\Form\FormInterface;
|
|||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,12 +29,15 @@ class PickUserDynamicType extends AbstractType
|
|||||||
{
|
{
|
||||||
private DenormalizerInterface $denormalizer;
|
private DenormalizerInterface $denormalizer;
|
||||||
|
|
||||||
|
private NormalizerInterface $normalizer;
|
||||||
|
|
||||||
private SerializerInterface $serializer;
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer)
|
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, NormalizerInterface $normalizer)
|
||||||
{
|
{
|
||||||
$this->denormalizer = $denormalizer;
|
$this->denormalizer = $denormalizer;
|
||||||
$this->serializer = $serializer;
|
$this->serializer = $serializer;
|
||||||
|
$this->normalizer = $normalizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
@ -46,6 +50,11 @@ class PickUserDynamicType extends AbstractType
|
|||||||
$view->vars['multiple'] = $options['multiple'];
|
$view->vars['multiple'] = $options['multiple'];
|
||||||
$view->vars['types'] = ['user'];
|
$view->vars['types'] = ['user'];
|
||||||
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
||||||
|
$view->vars['suggested'] = [];
|
||||||
|
|
||||||
|
foreach ($options['suggested'] as $user) {
|
||||||
|
$view->vars['suggested'][] = $this->normalizer->normalize($user, 'json', ['groups' => 'read']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
@ -53,7 +62,8 @@ class PickUserDynamicType extends AbstractType
|
|||||||
$resolver
|
$resolver
|
||||||
->setDefault('multiple', false)
|
->setDefault('multiple', false)
|
||||||
->setAllowedTypes('multiple', ['bool'])
|
->setAllowedTypes('multiple', ['bool'])
|
||||||
->setDefault('compound', false);
|
->setDefault('compound', false)
|
||||||
|
->setDefault('suggested', []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockPrefix()
|
public function getBlockPrefix()
|
||||||
|
@ -39,7 +39,7 @@ class PrivateCommentType extends AbstractType
|
|||||||
$builder
|
$builder
|
||||||
->add('comments', ChillTextareaType::class, [
|
->add('comments', ChillTextareaType::class, [
|
||||||
'disable_editor' => $options['disable_editor'],
|
'disable_editor' => $options['disable_editor'],
|
||||||
'label' => false,
|
'label' => $options['label'],
|
||||||
])
|
])
|
||||||
->setDataMapper($this->dataMapper);
|
->setDataMapper($this->dataMapper);
|
||||||
}
|
}
|
||||||
|
@ -95,12 +95,7 @@ class ScopePickerType extends AbstractType
|
|||||||
|
|
||||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
{
|
{
|
||||||
$view->vars = array_replace(
|
$view->vars['fullWidth'] = true;
|
||||||
$view->vars,
|
|
||||||
[
|
|
||||||
'fullWidth' => true,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
@ -154,6 +154,7 @@ class WorkflowStepType extends AbstractType
|
|||||||
'label' => 'workflow.dest for next steps',
|
'label' => 'workflow.dest for next steps',
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
'mapped' => false,
|
'mapped' => false,
|
||||||
|
'suggested' => $options['suggested_users'],
|
||||||
])
|
])
|
||||||
->add('future_dest_emails', ChillCollectionType::class, [
|
->add('future_dest_emails', ChillCollectionType::class, [
|
||||||
'label' => 'workflow.dest by email',
|
'label' => 'workflow.dest by email',
|
||||||
@ -200,6 +201,7 @@ class WorkflowStepType extends AbstractType
|
|||||||
->setAllowedTypes('transition', 'bool')
|
->setAllowedTypes('transition', 'bool')
|
||||||
->setRequired('entity_workflow')
|
->setRequired('entity_workflow')
|
||||||
->setAllowedTypes('entity_workflow', EntityWorkflow::class)
|
->setAllowedTypes('entity_workflow', EntityWorkflow::class)
|
||||||
|
->setDefault('suggested_users', [])
|
||||||
->setDefault('constraints', [
|
->setDefault('constraints', [
|
||||||
new Callback(
|
new Callback(
|
||||||
function ($step, ExecutionContextInterface $context, $payload) {
|
function ($step, ExecutionContextInterface $context, $payload) {
|
||||||
|
@ -23,7 +23,7 @@ function loadDynamicPicker(element) {
|
|||||||
(input.value === '[]' || input.value === '') ?
|
(input.value === '[]' || input.value === '') ?
|
||||||
null : [ JSON.parse(input.value) ]
|
null : [ JSON.parse(input.value) ]
|
||||||
)
|
)
|
||||||
;
|
suggested = JSON.parse(el.dataset.suggested)
|
||||||
|
|
||||||
if (!isMultiple) {
|
if (!isMultiple) {
|
||||||
if (input.value === '[]'){
|
if (input.value === '[]'){
|
||||||
@ -37,6 +37,7 @@ function loadDynamicPicker(element) {
|
|||||||
':types="types" ' +
|
':types="types" ' +
|
||||||
':picked="picked" ' +
|
':picked="picked" ' +
|
||||||
':uniqid="uniqid" ' +
|
':uniqid="uniqid" ' +
|
||||||
|
':suggested="notPickedSuggested" ' +
|
||||||
'@addNewEntity="addNewEntity" ' +
|
'@addNewEntity="addNewEntity" ' +
|
||||||
'@removeEntity="removeEntity"></pick-entity>',
|
'@removeEntity="removeEntity"></pick-entity>',
|
||||||
components: {
|
components: {
|
||||||
@ -48,16 +49,31 @@ function loadDynamicPicker(element) {
|
|||||||
types: JSON.parse(el.dataset.types),
|
types: JSON.parse(el.dataset.types),
|
||||||
picked: picked === null ? [] : picked,
|
picked: picked === null ? [] : picked,
|
||||||
uniqid: el.dataset.uniqid,
|
uniqid: el.dataset.uniqid,
|
||||||
|
suggested: suggested
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
notPickedSuggested() {
|
||||||
|
if (this.multiple) {
|
||||||
|
const pickedIds = new Set();
|
||||||
|
for (const p of this.picked) {
|
||||||
|
pickedIds.add(`${p.type}${p.id}`);
|
||||||
|
}
|
||||||
|
return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`))
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.suggested.filter(e => e.type !== this.picked.type && e.id !== e.picked.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addNewEntity(entity) {
|
addNewEntity({entity}) {
|
||||||
if (this.multiple) {
|
if (this.multiple) {
|
||||||
if (!this.picked.some(el => {
|
if (!this.picked.some(el => {
|
||||||
return el.type === entity.type && el.id === entity.id;
|
return el.type === entity.type && el.id === entity.id;
|
||||||
})) {
|
})) {
|
||||||
this.picked.push(entity);
|
this.picked.push(entity);
|
||||||
input.value = JSON.stringify(this.picked);
|
input.value = JSON.stringify(this.picked);
|
||||||
|
console.log(entity)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!this.picked.some(el => {
|
if (!this.picked.some(el => {
|
||||||
@ -69,7 +85,10 @@ function loadDynamicPicker(element) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeEntity(entity) {
|
removeEntity({entity}) {
|
||||||
|
if (-1 === this.suggested.findIndex(e => e.type === entity.type && e.id === entity.id)) {
|
||||||
|
this.suggested.push(entity);
|
||||||
|
}
|
||||||
this.picked = this.picked.filter(e => !(e.type === entity.type && e.id === entity.id));
|
this.picked = this.picked.filter(e => !(e.type === entity.type && e.id === entity.id));
|
||||||
input.value = JSON.stringify(this.picked);
|
input.value = JSON.stringify(this.picked);
|
||||||
},
|
},
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
</add-persons>
|
</add-persons>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<ul class="list-suggest add-items inline">
|
||||||
|
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)"><span>{{ s.text }}</span></li>
|
||||||
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -49,6 +52,10 @@ export default {
|
|||||||
// display picked entities.
|
// display picked entities.
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
|
},
|
||||||
|
suggested: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['addNewEntity', 'removeEntity'],
|
emits: ['addNewEntity', 'removeEntity'],
|
||||||
@ -61,55 +68,58 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
addPersonsOptions() {
|
addPersonsOptions() {
|
||||||
return {
|
return {
|
||||||
uniq: !this.multiple,
|
uniq: !this.multiple,
|
||||||
type: this.types,
|
type: this.types,
|
||||||
priority: null,
|
priority: null,
|
||||||
button: {
|
button: {
|
||||||
size: 'btn-sm',
|
size: 'btn-sm',
|
||||||
class: 'btn-submit',
|
class: 'btn-submit',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
translatedListOfTypes() {
|
translatedListOfTypes() {
|
||||||
let trans = [];
|
let trans = [];
|
||||||
this.types.forEach(t => {
|
this.types.forEach(t => {
|
||||||
if (this.$props.multiple) {
|
if (this.$props.multiple) {
|
||||||
trans.push(appMessages.fr.pick_entity[t].toLowerCase());
|
trans.push(appMessages.fr.pick_entity[t].toLowerCase());
|
||||||
} else {
|
} else {
|
||||||
trans.push(appMessages.fr.pick_entity[t + '_one'].toLowerCase());
|
trans.push(appMessages.fr.pick_entity[t + '_one'].toLowerCase());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.$props.multiple) {
|
if (this.$props.multiple) {
|
||||||
return appMessages.fr.pick_entity.modal_title + trans.join(', ');
|
return appMessages.fr.pick_entity.modal_title + trans.join(', ');
|
||||||
} else {
|
} else {
|
||||||
return appMessages.fr.pick_entity.modal_title_one + trans.join(', ');
|
return appMessages.fr.pick_entity.modal_title_one + trans.join(', ');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
listClasses() {
|
listClasses() {
|
||||||
return {
|
return {
|
||||||
'list-suggest': true,
|
'list-suggest': true,
|
||||||
'remove-items': this.$props.removableIfSet,
|
'remove-items': this.$props.removableIfSet,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addNewEntity({ selected, modal }) {
|
addNewSuggested(entity) {
|
||||||
selected.forEach((item) => {
|
this.$emit('addNewEntity', {entity: entity});
|
||||||
this.$emit('addNewEntity', item.result);
|
},
|
||||||
}, this
|
addNewEntity({ selected, modal }) {
|
||||||
);
|
selected.forEach((item) => {
|
||||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
this.$emit('addNewEntity', { entity: item.result});
|
||||||
modal.showModal = false;
|
}, this
|
||||||
},
|
);
|
||||||
removeEntity(entity) {
|
this.$refs.addPersons.resetSearch(); // to cast child method
|
||||||
if (!this.$props.removableIfSet) {
|
modal.showModal = false;
|
||||||
return;
|
},
|
||||||
}
|
removeEntity(entity) {
|
||||||
this.$emit('removeEntity', entity);
|
if (!this.$props.removableIfSet) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
this.$emit('removeEntity',{ entity: entity });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -68,7 +68,8 @@
|
|||||||
{{- form_errors(form) -}}
|
{{- form_errors(form) -}}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-sm">
|
<div class="col-12 clear">{{- form_label(form) -}}</div>
|
||||||
|
<div class="col-sm-12">
|
||||||
{{- form_widget(form, widget_attr) -}}
|
{{- form_widget(form, widget_attr) -}}
|
||||||
{{- form_help(form) -}}
|
{{- form_help(form) -}}
|
||||||
{{- form_errors(form) -}}
|
{{- form_errors(form) -}}
|
||||||
|
@ -18,43 +18,48 @@
|
|||||||
|
|
||||||
{% block form_row %}
|
{% block form_row %}
|
||||||
{% apply spaceless %}
|
{% apply spaceless %}
|
||||||
{% if form.vars.fullWidth is not defined or form.vars.fullWidth == false %}
|
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="{% apply spaceless %}
|
{% if form.vars.fullWidth is not defined or form.vars.fullWidth == false %}
|
||||||
{% if attr.class is defined and ('cf-title' in attr.class or 'cf-fields' in attr.class ) %}
|
<div class="{% apply spaceless %}
|
||||||
col-sm-12
|
{% if attr.class is defined and ('cf-title' in attr.class or 'cf-fields' in attr.class ) %}
|
||||||
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
col-sm-12
|
||||||
col-sm-2 col-md-4 clear
|
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
||||||
{% else %}
|
col-sm-2 col-md-4 clear
|
||||||
col-sm-4 clear
|
{% else %}
|
||||||
|
col-sm-4 clear
|
||||||
|
{% endif %}
|
||||||
|
{% endapply %}">
|
||||||
|
{% if attr.class is not defined or ('cf-title' not in attr.class and 'cf-fields' not in attr.class ) %}
|
||||||
|
{{ form_label(form) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endapply %}">
|
</div>
|
||||||
{% if attr.class is not defined or ('cf-title' not in attr.class and 'cf-fields' not in attr.class ) %}
|
<div class="{% apply spaceless %}
|
||||||
{{ form_label(form) }}
|
{% if attr.class is defined and 'cf-title' in attr.class %}
|
||||||
|
col-sm-12
|
||||||
|
{% elseif attr.class is defined and 'cf-fields' in attr.class %}
|
||||||
|
col-sm-12 parent
|
||||||
|
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
||||||
|
col-sm-2 col-md-8 multiple-cf-inline
|
||||||
|
{% else %}
|
||||||
|
col-sm-8
|
||||||
|
{% endif %}
|
||||||
|
{% endapply %}">
|
||||||
|
{{ form_widget(form) }}
|
||||||
|
{{ form_errors(form) }}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col-12 clear">{{ form_label(form) }}</div>
|
||||||
|
<div class="col-12">{{ form_widget(form) }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
<div class="{% apply spaceless %}
|
|
||||||
{% if attr.class is defined and 'cf-title' in attr.class %}
|
|
||||||
col-sm-12
|
|
||||||
{% elseif attr.class is defined and 'cf-fields' in attr.class %}
|
|
||||||
col-sm-12 parent
|
|
||||||
{% elseif attr.class is defined and 'multiple-cf-inline' in attr.class %}
|
|
||||||
col-sm-2 col-md-8 multiple-cf-inline
|
|
||||||
{% else %}
|
|
||||||
col-sm-8
|
|
||||||
{% endif %}
|
|
||||||
{% endapply %}">
|
|
||||||
{{ form_widget(form) }}
|
|
||||||
{{ form_errors(form) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
{{ form_widget(form) }}
|
|
||||||
{% endif %}
|
|
||||||
{% endapply %}
|
{% endapply %}
|
||||||
{% endblock form_row %}
|
{% endblock form_row %}
|
||||||
|
{#
|
||||||
|
The block 'form_row' above may be removed !
|
||||||
|
Read this note: https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/502#note_1311993084
|
||||||
|
#}
|
||||||
|
|
||||||
{% block choice_widget_expanded %}
|
{% block choice_widget_expanded %}
|
||||||
{% apply spaceless %}
|
{% apply spaceless %}
|
||||||
@ -200,7 +205,6 @@
|
|||||||
|
|
||||||
|
|
||||||
{% block private_comment_row %}
|
{% block private_comment_row %}
|
||||||
{{ form_label(form) }}
|
|
||||||
{{ form_row(form) }}
|
{{ form_row(form) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -211,7 +215,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block comment_row %}
|
{% block comment_row %}
|
||||||
{{ form_label(form) }}
|
|
||||||
{{ form_row(form) }}
|
{{ form_row(form) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -249,7 +252,11 @@
|
|||||||
|
|
||||||
{% block pick_entity_dynamic_widget %}
|
{% block pick_entity_dynamic_widget %}
|
||||||
<input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value|escape('html_attr') }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/>
|
<input type="hidden" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value|escape('html_attr') }}" {% endif %} data-input-uniqid="{{ form.vars['uniqid'] }}"/>
|
||||||
<div data-module="pick-dynamic" data-types="{{ form.vars['types']|json_encode }}" data-multiple="{{ form.vars['multiple'] }}" data-uniqid="{{ form.vars['uniqid'] }}"></div>
|
<div data-module="pick-dynamic"
|
||||||
|
data-types="{{ form.vars['types']|json_encode }}"
|
||||||
|
data-multiple="{{ form.vars['multiple'] }}"
|
||||||
|
data-uniqid="{{ form.vars['uniqid'] }}"
|
||||||
|
data-suggested="{{ form.vars['suggested']|json_encode|escape('html_attr') }}"></div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block pick_postal_code_widget %}
|
{% block pick_postal_code_widget %}
|
||||||
@ -269,4 +276,4 @@
|
|||||||
{{ form_errors(form.fixedDate) }}
|
{{ form_errors(form.fixedDate) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -36,6 +36,11 @@ interface EntityWorkflowHandlerInterface
|
|||||||
*/
|
*/
|
||||||
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string;
|
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User[]
|
||||||
|
*/
|
||||||
|
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array;
|
||||||
|
|
||||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string;
|
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string;
|
||||||
|
|
||||||
public function getTemplateData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
public function getTemplateData(EntityWorkflow $entityWorkflow, array $options = []): array;
|
||||||
|
@ -45,3 +45,12 @@ workflow:
|
|||||||
few {# workflows}
|
few {# workflows}
|
||||||
other {# workflows}
|
other {# workflows}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duration:
|
||||||
|
minute: >-
|
||||||
|
{m, plural,
|
||||||
|
=0 {Aucune durée}
|
||||||
|
one {# minute}
|
||||||
|
few {# minutes}
|
||||||
|
other {# minutes}
|
||||||
|
}
|
||||||
|
@ -160,6 +160,14 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
*/
|
*/
|
||||||
private ?DateInterval $warningInterval = null;
|
private ?DateInterval $warningInterval = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="integer", nullable=true)
|
||||||
|
* @Serializer\Groups({"read", "docgen:read"})
|
||||||
|
* @Serializer\Groups({"write"})
|
||||||
|
* @Serializer\Groups({"accompanying_period_work_evaluation:create"})
|
||||||
|
*/
|
||||||
|
private ?int $timeSpent = null;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->documents = new ArrayCollection();
|
$this->documents = new ArrayCollection();
|
||||||
@ -265,6 +273,11 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
return $this->warningInterval;
|
return $this->warningInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTimeSpent(): ?int
|
||||||
|
{
|
||||||
|
return $this->timeSpent;
|
||||||
|
}
|
||||||
|
|
||||||
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
|
public function removeDocument(AccompanyingPeriodWorkEvaluationDocument $document): self
|
||||||
{
|
{
|
||||||
$this->documents->removeElement($document);
|
$this->documents->removeElement($document);
|
||||||
@ -322,6 +335,13 @@ class AccompanyingPeriodWorkEvaluation implements TrackCreationInterface, TrackU
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setTimeSpent(?int $timeSpent): self
|
||||||
|
{
|
||||||
|
$this->timeSpent = $timeSpent;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setEvaluation(?Evaluation $evaluation): AccompanyingPeriodWorkEvaluation
|
public function setEvaluation(?Evaluation $evaluation): AccompanyingPeriodWorkEvaluation
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
@ -47,6 +47,7 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
|
|||||||
'endDate',
|
'endDate',
|
||||||
'maxDate',
|
'maxDate',
|
||||||
'warningInterval',
|
'warningInterval',
|
||||||
|
'timeSpent',
|
||||||
'acpw_id',
|
'acpw_id',
|
||||||
'acpw_startDate',
|
'acpw_startDate',
|
||||||
'acpw_endDate',
|
'acpw_endDate',
|
||||||
@ -295,6 +296,9 @@ class ListEvaluation implements ListInterface, GroupedExportInterface
|
|||||||
$qb->addSelect(sprintf('workeval.%s AS %s', $field, $field));
|
$qb->addSelect(sprintf('workeval.%s AS %s', $field, $field));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the time spent field
|
||||||
|
$qb->addSelect('(workeval.timeSpent / 60) AS timeSpent');
|
||||||
|
|
||||||
// those with identity
|
// those with identity
|
||||||
foreach (['createdBy', 'updatedBy'] as $field) {
|
foreach (['createdBy', 'updatedBy'] as $field) {
|
||||||
$qb->addSelect(sprintf('IDENTITY(workeval.%s) AS %s', $field, $field));
|
$qb->addSelect(sprintf('IDENTITY(workeval.%s) AS %s', $field, $field));
|
||||||
|
@ -19,7 +19,6 @@ use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
|||||||
use Chill\PersonBundle\Export\Declarations;
|
use Chill\PersonBundle\Export\Declarations;
|
||||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Query\Expr\Andx;
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Symfony\Component\Form\CallbackTransformer;
|
use Symfony\Component\Form\CallbackTransformer;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||||
@ -52,45 +51,39 @@ class SocialWorkTypeFilter implements FilterInterface
|
|||||||
|
|
||||||
public function alterQuery(QueryBuilder $qb, $data)
|
public function alterQuery(QueryBuilder $qb, $data)
|
||||||
{
|
{
|
||||||
$where = $qb->getDQLPart('where');
|
|
||||||
|
|
||||||
if (count($data['actionType']) > 0) {
|
if (count($data['actionType']) > 0) {
|
||||||
$clause = $qb->expr()->in('acpw.socialAction', ':actionType');
|
$qb
|
||||||
|
->andWhere($qb->expr()->in('acpw.socialAction', ':actionType'))
|
||||||
if ($where instanceof Andx) {
|
->setParameter('actionType', $data['actionType']);
|
||||||
$where->add($clause);
|
|
||||||
} else {
|
|
||||||
$where = $qb->expr()->andX($clause);
|
|
||||||
}
|
|
||||||
|
|
||||||
$qb->setParameter('actionType', $data['actionType']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($data['goal']) > 0) {
|
if (count($data['goal']) > 0) {
|
||||||
if (!in_array('goal', $qb->getAllAliases(), true)) {
|
if (!in_array('acpw_goal', $qb->getAllAliases(), true)) {
|
||||||
$qb->join('acpw.goals', 'goal');
|
$qb->join('acpw.goals', 'acpw_goal');
|
||||||
}
|
}
|
||||||
|
|
||||||
$where->add(
|
$orX = $qb->expr()->orX();
|
||||||
$qb->expr()->in('goal.id', ':goals')
|
foreach ($data['goal'] as $goal) {
|
||||||
);
|
|
||||||
|
|
||||||
$qb->setParameter('goals', $data['goal']);
|
/** @var Goal $goal */
|
||||||
}
|
$andX = $qb->expr()->andX();
|
||||||
|
$andX->add($qb->expr()->eq('acpw_goal.goal', $goalId = ':goal_'.uniqid()));
|
||||||
|
$qb->setParameter($goalId, $goal);
|
||||||
|
|
||||||
if (count($data['result']) > 0) {
|
if (count($data['result']) > 0) {
|
||||||
if (!in_array('result', $qb->getAllAliases(), true)) {
|
$orXResult = $qb->expr()->orX();
|
||||||
$qb->join('acpw.results', 'result');
|
foreach ($data['result'] as $result) {
|
||||||
|
|
||||||
|
/** @var Result $result */
|
||||||
|
$orXResult->add($qb->expr()->isMemberOf($resultId = ':result_'.uniqid(), 'acpw_goal.results'));
|
||||||
|
$qb->setParameter($resultId, $result);
|
||||||
|
}
|
||||||
|
$andX->add($orXResult);
|
||||||
|
}
|
||||||
|
$orX->add($andX);
|
||||||
}
|
}
|
||||||
|
$qb->andWhere($orX);
|
||||||
$where->add(
|
|
||||||
$qb->expr()->in('result.id', ':results')
|
|
||||||
);
|
|
||||||
|
|
||||||
$qb->setParameter('results', $data['result']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$qb->add('where', $where);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyOn(): string
|
public function applyOn(): string
|
||||||
|
@ -18,21 +18,25 @@ use Symfony\Component\Form\FormInterface;
|
|||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick user dymically, using vuejs module "AddPerson".
|
* m* Pick user dymically, using vuejs module "AddPerson".
|
||||||
*/
|
*/
|
||||||
class PickPersonDynamicType extends AbstractType
|
class PickPersonDynamicType extends AbstractType
|
||||||
{
|
{
|
||||||
private DenormalizerInterface $denormalizer;
|
private DenormalizerInterface $denormalizer;
|
||||||
|
|
||||||
|
private DenormalizerInterface $normalizer;
|
||||||
|
|
||||||
private SerializerInterface $serializer;
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer)
|
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, NormalizerInterface $normalizer)
|
||||||
{
|
{
|
||||||
$this->denormalizer = $denormalizer;
|
$this->denormalizer = $denormalizer;
|
||||||
$this->serializer = $serializer;
|
$this->serializer = $serializer;
|
||||||
|
$this->normalizer = $normalizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
@ -45,6 +49,11 @@ class PickPersonDynamicType extends AbstractType
|
|||||||
$view->vars['multiple'] = $options['multiple'];
|
$view->vars['multiple'] = $options['multiple'];
|
||||||
$view->vars['types'] = ['person'];
|
$view->vars['types'] = ['person'];
|
||||||
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
||||||
|
$view->vars['suggested'] = [];
|
||||||
|
|
||||||
|
foreach ($options['suggested'] as $person) {
|
||||||
|
$view->vars['suggested'][] = $this->normalizer->normalize($person, 'json', ['groups' => 'read']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
@ -52,7 +61,8 @@ class PickPersonDynamicType extends AbstractType
|
|||||||
$resolver
|
$resolver
|
||||||
->setDefault('multiple', false)
|
->setDefault('multiple', false)
|
||||||
->setAllowedTypes('multiple', ['bool'])
|
->setAllowedTypes('multiple', ['bool'])
|
||||||
->setDefault('compound', false);
|
->setDefault('compound', false)
|
||||||
|
->setDefault('suggested', []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockPrefix()
|
public function getBlockPrefix()
|
||||||
|
@ -49,6 +49,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
|
||||||
|
{{ $t('evaluation_time_spent') }}
|
||||||
|
</label>
|
||||||
|
<div class="col-8 col-sm-4 col-md-8 col-lg-4">
|
||||||
|
<select class="form-control form-control-sm" type="time" v-model="timeSpent">
|
||||||
|
<option disabled value="">{{ $t('select_time_spent') }}</option>
|
||||||
|
<option v-for="time in timeSpentChoices" :value="time.value">
|
||||||
|
{{ time.text }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-sm-4 col-form-label visually-hidden">{{ $t('evaluation_public_comment') }}</label>
|
<label class="col-sm-4 col-form-label visually-hidden">{{ $t('evaluation_public_comment') }}</label>
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
@ -191,6 +205,8 @@ const i18n = {
|
|||||||
evaluation_choose_a_template: "Choisir un modèle",
|
evaluation_choose_a_template: "Choisir un modèle",
|
||||||
evaluation_add_a_document: "Ajouter un document",
|
evaluation_add_a_document: "Ajouter un document",
|
||||||
evaluation_add: "Ajouter une évaluation",
|
evaluation_add: "Ajouter une évaluation",
|
||||||
|
evaluation_time_spent: "Temps de rédaction",
|
||||||
|
select_time_spent: "Indiquez le temps de rédaction",
|
||||||
Documents: "Documents",
|
Documents: "Documents",
|
||||||
document_add: "Générer ou téléverser un document",
|
document_add: "Générer ou téléverser un document",
|
||||||
document_upload: "Téléverser un document",
|
document_upload: "Téléverser un document",
|
||||||
@ -224,6 +240,22 @@ export default {
|
|||||||
maxPostSize: 15000000,
|
maxPostSize: 15000000,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
timeSpentChoices: [
|
||||||
|
{ text: '1 minute', value: 60 }, { text: '2 minutes', value: 120 },
|
||||||
|
{ text: '3 minutes', value: 180 }, { text: '4 minutes', value: 240 },
|
||||||
|
{ text: '5 minutes', value: 300 }, { text: '10 minutes', value: 600 },
|
||||||
|
{ text: '15 minutes', value: 900 },{ text: '20 minutes', value: 1200 },
|
||||||
|
{ text: '25 minutes', value: 1500 }, { text: '30 minutes', value: 1800 },
|
||||||
|
{ text: '45 minutes', value: 2700 },{ text: '1 hour', value: 3600 },
|
||||||
|
{ text: '1 hour 15 minutes', value: 4500 }, { text: '1 hour 30 minutes', value: 5400 },
|
||||||
|
{ text: '1 hour 45 minutes', value: 6300 }, { text: '2 hours', value: 7200 },
|
||||||
|
{ text: '2 hours 30 minutes', value: 9000 }, { text: '3 hours', value: 10800 },
|
||||||
|
{ text: '3 hours 30 minutes', value: 12600 },{ text: '4 hours', value: 14400 },
|
||||||
|
{ text: '4 hours 30 minutes', value: 16200 },{ text: '5 hours', value: 18000 },
|
||||||
|
{ text: '5 hours 30 minutes', value: 19800 },{ text: '6 hours', value: 21600 },
|
||||||
|
{ text: '6 hours 30 minutes', value: 23400 },{ text: '7 hours', value: 25200 },
|
||||||
|
{ text: '7 hours 30 minutes', value: 27000 },{ text: '8 hours', value: 28800 },
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -265,6 +297,10 @@ export default {
|
|||||||
get() { return this.evaluation.warningInterval; },
|
get() { return this.evaluation.warningInterval; },
|
||||||
set(v) { this.$store.commit('setEvaluationWarningInterval', { key: this.evaluation.key, days: v }); }
|
set(v) { this.$store.commit('setEvaluationWarningInterval', { key: this.evaluation.key, days: v }); }
|
||||||
},
|
},
|
||||||
|
timeSpent: {
|
||||||
|
get() { return this.evaluation.timeSpent },
|
||||||
|
set(v) { this.$store.commit('setEvaluationTimeSpent', { key: this.evaluation.key, time: v}) }
|
||||||
|
},
|
||||||
comment: {
|
comment: {
|
||||||
get() { return this.evaluation.comment; },
|
get() { return this.evaluation.comment; },
|
||||||
set(v) { this.$store.commit('setEvaluationComment', { key: this.evaluation.key, comment: v }); }
|
set(v) { this.$store.commit('setEvaluationComment', { key: this.evaluation.key, comment: v }); }
|
||||||
|
@ -116,6 +116,7 @@ const store = createStore({
|
|||||||
endDate: e.endDate === null || e.endDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.endDate)) },
|
endDate: e.endDate === null || e.endDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.endDate)) },
|
||||||
maxDate: e.maxDate === null || e.maxDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.maxDate)) },
|
maxDate: e.maxDate === null || e.maxDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.maxDate)) },
|
||||||
warningInterval: intervalDaysToISO(e.warningInterval),
|
warningInterval: intervalDaysToISO(e.warningInterval),
|
||||||
|
timeSpent: e.timeSpent,
|
||||||
comment: e.comment,
|
comment: e.comment,
|
||||||
documents: e.documents
|
documents: e.documents
|
||||||
};
|
};
|
||||||
@ -138,6 +139,7 @@ const store = createStore({
|
|||||||
endDate: e.endDate !== null ? dateToISO(new Date(e.endDate.datetime)) : null,
|
endDate: e.endDate !== null ? dateToISO(new Date(e.endDate.datetime)) : null,
|
||||||
maxDate: e.maxDate !== null ? dateToISO(new Date(e.maxDate.datetime)) : null,
|
maxDate: e.maxDate !== null ? dateToISO(new Date(e.maxDate.datetime)) : null,
|
||||||
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
|
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null,
|
||||||
|
timeSpent: e.timeSpent !== null ? e.timeSpent : null,
|
||||||
documents: e.documents.map((d, docIndex) => {
|
documents: e.documents.map((d, docIndex) => {
|
||||||
return Object.assign(d, {
|
return Object.assign(d, {
|
||||||
key: docIndex
|
key: docIndex
|
||||||
@ -258,6 +260,7 @@ const store = createStore({
|
|||||||
endDate: null,
|
endDate: null,
|
||||||
maxDate: null,
|
maxDate: null,
|
||||||
warningInterval: null,
|
warningInterval: null,
|
||||||
|
timeSpent: null,
|
||||||
comment: "",
|
comment: "",
|
||||||
editEvaluation: true,
|
editEvaluation: true,
|
||||||
workflows_availables: state.work.workflows_availables_evaluation,
|
workflows_availables: state.work.workflows_availables_evaluation,
|
||||||
@ -286,6 +289,10 @@ const store = createStore({
|
|||||||
state.evaluationsPicked.find(e => e.key === key)
|
state.evaluationsPicked.find(e => e.key === key)
|
||||||
.warningInterval = days;
|
.warningInterval = days;
|
||||||
},
|
},
|
||||||
|
setEvaluationTimeSpent(state, {key, time}) {
|
||||||
|
state.evaluationsPicked.find(e => e.key === key)
|
||||||
|
.timeSpent = time;
|
||||||
|
},
|
||||||
setEvaluationComment(state, {key, comment}) {
|
setEvaluationComment(state, {key, comment}) {
|
||||||
state.evaluationsPicked.find(e => e.key === key)
|
state.evaluationsPicked.find(e => e.key === key)
|
||||||
.comment = comment;
|
.comment = comment;
|
||||||
@ -482,7 +489,7 @@ const store = createStore({
|
|||||||
;
|
;
|
||||||
commit('setIsPosting', true);
|
commit('setIsPosting', true);
|
||||||
|
|
||||||
console.log('payload', payload);
|
console.log('the social action', payload);
|
||||||
|
|
||||||
return makeFetch('PUT', url, payload)
|
return makeFetch('PUT', url, payload)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
@ -118,6 +118,18 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if e.timeSpent is not null and e.timeSpent > 0 %}
|
||||||
|
<li>
|
||||||
|
{% set minutes = (e.timeSpent / 60) %}
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span> {{ 'duration.minute'|trans({ '{m}' : minutes }) }}
|
||||||
|
</li>
|
||||||
|
{% elseif displayContent is defined and displayContent == 'long' %}
|
||||||
|
<li>
|
||||||
|
<span class="item-key">{{ 'accompanying_course_work.timeSpent'|trans ~ ' : ' }}</span>
|
||||||
|
<span class="chill-no-data-statement">{{ 'Not given'|trans }}</span>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -143,7 +155,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<span class="chill-no-data-statement">{{ 'No document found'|trans }}</span>
|
<span class="chill-no-data-statement">{{ 'No document found'|trans }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
@ -97,6 +97,21 @@ class AccompanyingPeriodWorkEvaluationDocumentWorkflowHandler implements EntityW
|
|||||||
return AccompanyingPeriodWorkEvaluationDocumentVoter::SEE;
|
return AccompanyingPeriodWorkEvaluationDocumentVoter::SEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||||
|
{
|
||||||
|
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||||
|
|
||||||
|
$referrer = $this->getRelatedEntity($entityWorkflow)
|
||||||
|
->getAccompanyingPeriodWorkEvaluation()
|
||||||
|
->getAccompanyingPeriodWork()
|
||||||
|
->getAccompanyingPeriod()
|
||||||
|
->getUser();
|
||||||
|
|
||||||
|
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||||
|
|
||||||
|
return $suggestedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||||
{
|
{
|
||||||
return '@ChillPerson/Workflow/_evaluation_document.html.twig';
|
return '@ChillPerson/Workflow/_evaluation_document.html.twig';
|
||||||
|
@ -87,6 +87,20 @@ class AccompanyingPeriodWorkEvaluationWorkflowHandler implements EntityWorkflowH
|
|||||||
return AccompanyingPeriodWorkEvaluationVoter::SEE;
|
return AccompanyingPeriodWorkEvaluationVoter::SEE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||||
|
{
|
||||||
|
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||||
|
|
||||||
|
$referrer = $this->getRelatedEntity($entityWorkflow)
|
||||||
|
->getAccompanyingPeriodWork()
|
||||||
|
->getAccompanyingPeriod()
|
||||||
|
->getUser();
|
||||||
|
|
||||||
|
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||||
|
|
||||||
|
return $suggestedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||||
{
|
{
|
||||||
return '@ChillPerson/Workflow/_evaluation.html.twig';
|
return '@ChillPerson/Workflow/_evaluation.html.twig';
|
||||||
|
@ -94,6 +94,19 @@ class AccompanyingPeriodWorkWorkflowHandler implements EntityWorkflowHandlerInte
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
|
||||||
|
{
|
||||||
|
$suggestedUsers = $entityWorkflow->getUsersInvolved();
|
||||||
|
|
||||||
|
$referrer = $this->getRelatedEntity($entityWorkflow)
|
||||||
|
->getAccompanyingPeriod()
|
||||||
|
->getUser();
|
||||||
|
|
||||||
|
$suggestedUsers[spl_object_hash($referrer)] = $referrer;
|
||||||
|
|
||||||
|
return $suggestedUsers;
|
||||||
|
}
|
||||||
|
|
||||||
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
|
||||||
{
|
{
|
||||||
return '@ChillPerson/Workflow/_accompanying_period_work.html.twig';
|
return '@ChillPerson/Workflow/_accompanying_period_work.html.twig';
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Person;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20230210104424 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Add a duration field to accompanyingPeriodWorkEvaluation';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation ADD timeSpent INT DEFAULT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_person_accompanying_period_work_evaluation DROP timeSpent');
|
||||||
|
}
|
||||||
|
}
|
@ -908,6 +908,7 @@ accompanying_course_work:
|
|||||||
remove: Supprimer une action d'accompagnement
|
remove: Supprimer une action d'accompagnement
|
||||||
social_evaluation: Évaluation
|
social_evaluation: Évaluation
|
||||||
private_comment: Commentaire privé
|
private_comment: Commentaire privé
|
||||||
|
timeSpent: Temps de rédaction
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -1139,6 +1140,7 @@ export:
|
|||||||
updatedAt: Date de modification
|
updatedAt: Date de modification
|
||||||
createdBy: Créé par
|
createdBy: Créé par
|
||||||
updatedBy: Modifié par
|
updatedBy: Modifié par
|
||||||
|
timeSpent: Temps de rédaction (minutes)
|
||||||
acpw:
|
acpw:
|
||||||
List of accompanying period works: Liste des actions
|
List of accompanying period works: Liste des actions
|
||||||
List description: Génère une liste des actions d'accompagnement, filtrée sur différents paramètres.
|
List description: Génère une liste des actions d'accompagnement, filtrée sur différents paramètres.
|
||||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Form\FormInterface;
|
|||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,12 +28,15 @@ class PickThirdpartyDynamicType extends AbstractType
|
|||||||
{
|
{
|
||||||
private DenormalizerInterface $denormalizer;
|
private DenormalizerInterface $denormalizer;
|
||||||
|
|
||||||
|
private NormalizerInterface $normalizer;
|
||||||
|
|
||||||
private SerializerInterface $serializer;
|
private SerializerInterface $serializer;
|
||||||
|
|
||||||
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer)
|
public function __construct(DenormalizerInterface $denormalizer, SerializerInterface $serializer, NormalizerInterface $normalizer)
|
||||||
{
|
{
|
||||||
$this->denormalizer = $denormalizer;
|
$this->denormalizer = $denormalizer;
|
||||||
$this->serializer = $serializer;
|
$this->serializer = $serializer;
|
||||||
|
$this->normalizer = $normalizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
@ -45,6 +49,11 @@ class PickThirdpartyDynamicType extends AbstractType
|
|||||||
$view->vars['multiple'] = $options['multiple'];
|
$view->vars['multiple'] = $options['multiple'];
|
||||||
$view->vars['types'] = ['thirdparty'];
|
$view->vars['types'] = ['thirdparty'];
|
||||||
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
$view->vars['uniqid'] = uniqid('pick_user_dyn');
|
||||||
|
$view->vars['suggested'] = [];
|
||||||
|
|
||||||
|
foreach ($options['suggested'] as $tp) {
|
||||||
|
$view->vars['suggested'][] = $this->normalizer->normalize($tp, 'json', ['groups' => 'read']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function configureOptions(OptionsResolver $resolver)
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
@ -52,7 +61,8 @@ class PickThirdpartyDynamicType extends AbstractType
|
|||||||
$resolver
|
$resolver
|
||||||
->setDefault('multiple', false)
|
->setDefault('multiple', false)
|
||||||
->setAllowedTypes('multiple', ['bool'])
|
->setAllowedTypes('multiple', ['bool'])
|
||||||
->setDefault('compound', false);
|
->setDefault('compound', false)
|
||||||
|
->setDefault('suggested', []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBlockPrefix()
|
public function getBlockPrefix()
|
||||||
|
@ -20,6 +20,7 @@ use Chill\WopiBundle\Service\Controller\ResponderInterface;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
|
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
|
||||||
use loophp\psr17\Psr17Interface;
|
use loophp\psr17\Psr17Interface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
@ -81,7 +82,7 @@ final class Editor
|
|||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __invoke(string $fileId): Response
|
public function __invoke(string $fileId, Request $request): Response
|
||||||
{
|
{
|
||||||
if (null === $user = $this->security->getUser()) {
|
if (null === $user = $this->security->getUser()) {
|
||||||
throw new AccessDeniedHttpException('Please authenticate to access this feature');
|
throw new AccessDeniedHttpException('Please authenticate to access this feature');
|
||||||
@ -151,6 +152,7 @@ final class Editor
|
|||||||
UrlGeneratorInterface::ABSOLUTE_URL
|
UrlGeneratorInterface::ABSOLUTE_URL
|
||||||
),
|
),
|
||||||
'closebutton' => 1,
|
'closebutton' => 1,
|
||||||
|
'lang' => $request->getLocale(),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
<form id="office_form" name="office_form" target="office_frame" action="{{ server }}" method="post">
|
<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" value="{{ access_token }}" type="hidden" />
|
||||||
<input name="access_token_ttl" value="{{ access_token_ttl }}" type="hidden" />
|
<input name="access_token_ttl" value="{{ access_token_ttl }}" type="hidden" />
|
||||||
|
<input name="ui_defaults" value="TextRuler=fase;TextSidebar=false;TextStatusbar=true;PresentationSidebar=false;PresentationStatusbar=false;SpreadsheetSidebar=false;SpreadsheetStatusbar=false;UIMode=tabbed;SaveAsMode=group;" type="hidden" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<span id="frameholder"></span>
|
<span id="frameholder"></span>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user