mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
first impl for create form
This commit is contained in:
parent
07cc394abd
commit
3abfdbf6fd
@ -146,7 +146,7 @@ class CRUDRoutesLoader extends Loader
|
||||
|
||||
foreach ($crudConfig['actions'] as $name => $action) {
|
||||
// filter only on single actions
|
||||
$singleCollection = $action['single-collection'] ?? $name === '_entity' ? 'single' : NULL;
|
||||
$singleCollection = $action['single_collection'] ?? $name === '_entity' ? 'single' : NULL;
|
||||
if ('collection' === $singleCollection) {
|
||||
// continue;
|
||||
}
|
||||
@ -171,7 +171,7 @@ class CRUDRoutesLoader extends Loader
|
||||
// path are rewritten
|
||||
// if name === 'default', we rewrite it to nothing :-)
|
||||
$localName = \in_array($name, [ '_entity', '_index' ]) ? '' : '/'.$name;
|
||||
if ('collection' === $action['single-collection'] || '_index' === $name) {
|
||||
if ('collection' === $action['single_collection'] || '_index' === $name) {
|
||||
$localPath = $action['path'] ?? $localName.'.{_format}';
|
||||
} else {
|
||||
$localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
|
||||
|
@ -205,7 +205,7 @@ class Configuration implements ConfigurationInterface
|
||||
->ignoreExtraKeys(false)
|
||||
->info('the requirements for the route. Will be set to `[ \'id\' => \'\d+\' ]` if left empty.')
|
||||
->end()
|
||||
->enumNode('single-collection')
|
||||
->enumNode('single_collection')
|
||||
->values(['single', 'collection'])
|
||||
->defaultValue('single')
|
||||
->info('indicates if the returned object is a single element or a collection. '.
|
||||
|
@ -15,9 +15,9 @@
|
||||
*/
|
||||
const dateToISO = (date) => {
|
||||
return [
|
||||
this.$store.state.startDate.getFullYear(),
|
||||
(this.$store.state.startDate.getMonth() + 1).toString().padStart(2, '0'),
|
||||
this.$store.state.startDate.getDate().toString().padStart(2, '0')
|
||||
date.getFullYear(),
|
||||
(date.getMonth() + 1).toString().padStart(2, '0'),
|
||||
date.getDate().toString().padStart(2, '0')
|
||||
].join('-');
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,6 @@ class CollectionNormalizer implements NormalizerInterface, NormalizerAwareInterf
|
||||
public function normalize($collection, string $format = null, array $context = [])
|
||||
{
|
||||
/** @var $collection Collection */
|
||||
/** @var $collection Chill\MainBundle\Pagination\PaginatorInterface */
|
||||
$paginator = $collection->getPaginator();
|
||||
|
||||
$data['count'] = $paginator->getTotalItems();
|
||||
|
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
|
||||
class AccompanyingCourseWorkController extends AbstractController
|
||||
{
|
||||
private TranslatorInterface $trans;
|
||||
private SerializerInterface $serializer;
|
||||
|
||||
public function __construct(TranslatorInterface $trans, SerializerInterface $serializer)
|
||||
{
|
||||
$this->trans = $trans;
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route(
|
||||
* "{_locale}/person/accompanying-period/{id}/work/new",
|
||||
* methods={"GET", "POST"}
|
||||
* )
|
||||
*/
|
||||
public function createWork(AccompanyingPeriod $period)
|
||||
{
|
||||
// TODO ACL
|
||||
|
||||
if ($period->getSocialIssues()->count() === 0) {
|
||||
$this->addFlash('error', $this->trans->trans(
|
||||
"accompanying_work.You must add at least ".
|
||||
"one social issue on accompanying period")
|
||||
);
|
||||
|
||||
return $this->redirectToRoute('chill_person_accompanying_course_index', [
|
||||
'accompanying_period_id' => $period->getId()
|
||||
]);
|
||||
}
|
||||
|
||||
$json = $this->serializer->normalize($period, 'json', [ "groups" => [ "read" ]]);
|
||||
|
||||
return $this->render('@ChillPerson/AccompanyingCourseWork/create.html.twig', [
|
||||
'accompanyingCourse' => $period,
|
||||
'json' => $json
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\Serializer\Model\Collection;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactory;
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||
use Chill\MainBundle\CRUD\Controller\ApiController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
class SocialWorkSocialActionApiController extends ApiController
|
||||
{
|
||||
private SocialIssueRepository $socialIssueRepository;
|
||||
|
||||
private PaginatorFactory $paginator;
|
||||
|
||||
/**
|
||||
* @param SocialIssueRepository $socialIssueRepository
|
||||
*/
|
||||
public function __construct(SocialIssueRepository $socialIssueRepository, PaginatorFactory $paginator)
|
||||
{
|
||||
$this->socialIssueRepository = $socialIssueRepository;
|
||||
$this->paginator = $paginator;
|
||||
}
|
||||
|
||||
public function listBySocialIssueApi($id, Request $request)
|
||||
{
|
||||
$socialIssue = $this->socialIssueRepository
|
||||
->find($id);
|
||||
|
||||
if (NULL === $socialIssue) {
|
||||
throw $this->createNotFoundException("socialIssue not found");
|
||||
}
|
||||
|
||||
$socialActions = $socialIssue->getRecursiveSocialActions();
|
||||
$pagination = $this->paginator->create(count($socialActions));
|
||||
// max one page
|
||||
$pagination->setItemsPerPage(count($socialActions));
|
||||
|
||||
$collection = new Collection($socialActions, $pagination);
|
||||
|
||||
|
||||
return $this->json($collection, JsonResponse::HTTP_OK, [], [ "groups" => [ "read" ]]);
|
||||
}
|
||||
|
||||
}
|
@ -573,6 +573,49 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialAction::class,
|
||||
'name' => 'social_action',
|
||||
'base_path' => '/api/1.0/person/social/social-action',
|
||||
'controller' => \Chill\PersonBundle\Controller\SocialWorkSocialActionApiController::class,
|
||||
// TODO: acl
|
||||
'base_role' => 'ROLE_USER',
|
||||
'actions' => [
|
||||
'_entity' => [
|
||||
'methods' => [
|
||||
Request::METHOD_GET => true,
|
||||
Request::METHOD_HEAD => true,
|
||||
],
|
||||
'roles' => [
|
||||
Request::METHOD_GET => 'ROLE_USER',
|
||||
Request::METHOD_HEAD => 'ROLE_USER',
|
||||
]
|
||||
],
|
||||
'_index' => [
|
||||
'methods' => [
|
||||
Request::METHOD_GET => true,
|
||||
Request::METHOD_HEAD => true,
|
||||
],
|
||||
'roles' => [
|
||||
Request::METHOD_GET => 'ROLE_USER',
|
||||
Request::METHOD_HEAD => 'ROLE_USER',
|
||||
]
|
||||
],
|
||||
'listBySocialIssue' => [
|
||||
'single-collection' => 'collection',
|
||||
'path' => '/by-social-issue/{id}.{_format}',
|
||||
'methods' => [
|
||||
Request::METHOD_GET => true,
|
||||
Request::METHOD_HEAD => true,
|
||||
],
|
||||
'roles' => [
|
||||
Request::METHOD_GET => 'ROLE_USER',
|
||||
Request::METHOD_HEAD => 'ROLE_USER',
|
||||
]
|
||||
|
||||
]
|
||||
]
|
||||
],
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace Chill\PersonBundle\Entity\SocialWork;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
|
@ -6,8 +6,9 @@ use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class SocialIssueRepository
|
||||
final class SocialIssueRepository implements ObjectRepository
|
||||
{
|
||||
private EntityRepository $repository;
|
||||
|
||||
@ -15,4 +16,44 @@ final class SocialIssueRepository
|
||||
{
|
||||
$this->repository = $entityManager->getRepository(SocialIssue::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function find($id)
|
||||
{
|
||||
return $this->repository->find($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function findAll()
|
||||
{
|
||||
return $this->repository->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
|
||||
{
|
||||
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function findOneBy(array $criteria)
|
||||
{
|
||||
return $this->findOneBy($criteria);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getClassName()
|
||||
{
|
||||
return SocialIssue::class;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<h1>{{ $t('create_work') }}</h1>
|
||||
|
||||
<div v-for="si in socialIssues">
|
||||
<input type="radio" v-bind:value="si.id" name="socialIssue" v-model="socialIssuePicked"> {{ si.title.fr }}
|
||||
</div>
|
||||
|
||||
<div v-if="hasSocialIssuePicked">
|
||||
<vue-multiselect
|
||||
v-model="socialActionPicked"
|
||||
label="text"
|
||||
:options="socialActionsReachables"
|
||||
:searchable="true"
|
||||
:close-on-select="true"
|
||||
:show-labels="true"
|
||||
track-by="id"
|
||||
></vue-multiselect>
|
||||
</div>
|
||||
|
||||
<div v-if="hasSocialActionPicked">
|
||||
<p><label>{{ $t('start_date') }}</label> <input type="date" v-model="startDate" /></p>
|
||||
<p><label>{{ $t('end_date') }}</label> <input type="date" v-model="endDate" /></p>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { mapState, mapActions, mapGetters } from 'vuex';
|
||||
import VueMultiselect from 'vue-multiselect';
|
||||
import { dateToISO } from 'ChillMainAssets/js/date.js';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
VueMultiselect,
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'socialIssues',
|
||||
'socialActionsReachables',
|
||||
]),
|
||||
...mapGetters([
|
||||
'hasSocialIssuePicked',
|
||||
'hasSocialActionPicked',
|
||||
]),
|
||||
socialIssuePicked: {
|
||||
get() {
|
||||
let s = this.$store.state.socialIssuePicked;
|
||||
|
||||
if (s === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return s.id;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.dispatch('pickSocialIssue', value);
|
||||
}
|
||||
},
|
||||
socialActionPicked: {
|
||||
get() {
|
||||
return this.$store.state.socialActionPicked;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('setSocialAction', value);
|
||||
}
|
||||
},
|
||||
startDate: {
|
||||
get() {
|
||||
let d = this.$store.state.startDate;
|
||||
return dateToISO(d);
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('setStartDate', ISOToDate(value));
|
||||
}
|
||||
},
|
||||
endDate: {
|
||||
get() {
|
||||
return this.$store.state.endDate;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit('setEndDate', value);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
@ -0,0 +1,15 @@
|
||||
import { createApp } from 'vue';
|
||||
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n';
|
||||
import { store } from './store';
|
||||
import { personMessages } from 'ChillPersonAssets/vuejs/_js/i18n'
|
||||
import App from './App.vue';
|
||||
|
||||
const i18n = _createI18n(personMessages);
|
||||
|
||||
const app = createApp({
|
||||
template: `<app></app>`,
|
||||
})
|
||||
.use(store)
|
||||
.use(i18n)
|
||||
.component('app', App)
|
||||
.mount('#accompanying_course_work_create');
|
@ -0,0 +1,67 @@
|
||||
|
||||
import { createStore } from 'vuex';
|
||||
import { datetimeToISO } from 'ChillMainAssets/js/date.js';
|
||||
import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js';
|
||||
|
||||
const debug = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const socialIssues = window.accompanyingCourse.socialIssues;
|
||||
|
||||
const store = createStore({
|
||||
strict: debug,
|
||||
state: {
|
||||
socialIssues: socialIssues,
|
||||
socialIssuePicked: null,
|
||||
socialActionsReachables: [],
|
||||
socialActionPicked: null,
|
||||
startDate: new Date(),
|
||||
endDate: null,
|
||||
},
|
||||
getters: {
|
||||
hasSocialActionPicked(state) {
|
||||
console.log(state.socialActionPicked);
|
||||
return null !== state.socialActionPicked;
|
||||
},
|
||||
hasSocialIssuePicked(state) {
|
||||
console.log(state.socialIssuePicked);
|
||||
return null !== state.socialIssuePicked;
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setSocialActionsReachables(state, actions) {
|
||||
console.log('set social action reachables');
|
||||
console.log(actions);
|
||||
|
||||
state.socialActionsReachables = actions;
|
||||
},
|
||||
setSocialAction(state, socialAction) {
|
||||
console.log('socialAction', socialAction);
|
||||
state.socialActionPicked = socialAction;
|
||||
},
|
||||
setSocialIssue(state, socialIssueId) {
|
||||
console.log('socialAction', socialIssueId);
|
||||
state.socialIssuePicked = state.socialIssues
|
||||
.find(e => e.id === socialIssueId);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
pickSocialIssue({ commit }, payload) {
|
||||
console.log('pick social issue');
|
||||
console.log(payload);
|
||||
|
||||
|
||||
findSocialActionsBySocialIssue(payload).then(
|
||||
(response) => {
|
||||
console.log(response);
|
||||
console.log(response.results);
|
||||
commit('setSocialIssue', payload);
|
||||
commit('setSocialActionsReachables', response.results);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export { store };
|
@ -0,0 +1,21 @@
|
||||
|
||||
const findSocialActionsBySocialIssue = (id) => {
|
||||
const url = `/api/1.0/person/social/social-action/by-social-issue/${id}.json`;
|
||||
|
||||
return fetch(url)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Error while retrieving social actions " + response.status
|
||||
+ " " + response.statusText)
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
;
|
||||
};
|
||||
|
||||
export {
|
||||
findSocialActionsBySocialIssue
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
{% extends '@ChillPerson/AccompanyingCourse/layout.html.twig' %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<p>test</p>
|
||||
|
||||
<div id="accompanying_course_work_create"></div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script type="text/javascript">
|
||||
window.accompanyingCourse = {{ json|json_encode|raw }};
|
||||
</script>
|
||||
|
||||
{{ encore_entry_script_tags('accompanying_course_work_create') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block stylesheets %}
|
||||
{{ encore_entry_link_tags('accompanying_course_work_create') }}
|
||||
{% endblock %}
|
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\PersonBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||
|
||||
|
||||
class SocialActionNormalizer implements NormalizerInterface, NormalizerAwareInterface
|
||||
{
|
||||
use NormalizerAwareTrait;
|
||||
|
||||
private SocialActionRender $render;
|
||||
|
||||
public function __construct(SocialActionRender $render)
|
||||
{
|
||||
$this->render = $render;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function normalize($socialAction, string $format = null, array $context = [])
|
||||
{
|
||||
return [
|
||||
'text' => $this->render->renderString($socialAction, []),
|
||||
'parent' => $this->normalizer->normalize($socialAction->getParent()),
|
||||
'desactivationDate' => $this->normalizer->normalize($socialAction->getDesactivationDate()),
|
||||
'title' => $socialAction->getTitle()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function supportsNormalization($data, string $format = null)
|
||||
{
|
||||
return $data instanceof SocialAction;
|
||||
}
|
||||
}
|
@ -13,4 +13,5 @@ module.exports = function(encore, entries)
|
||||
encore.addEntry('household_members_editor', __dirname + '/Resources/public/vuejs/HouseholdMembersEditor/index.js');
|
||||
encore.addEntry('vue_accourse', __dirname + '/Resources/public/vuejs/AccompanyingCourse/index.js');
|
||||
encore.addEntry('household_edit_metadata', __dirname + '/Resources/public/modules/household_edit_metadata/index.js');
|
||||
encore.addEntry('accompanying_course_work_create', __dirname + '/Resources/public/vuejs/AccompanyingCourseWorkCreate/index.js');
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user