Compare commits

..

1 Commits

Author SHA1 Message Date
003b9e7234 add api Method GET on person 2021-05-21 15:52:52 +02:00
25 changed files with 556 additions and 639 deletions

View File

@@ -590,7 +590,7 @@ class CRUDController extends AbstractController
if (NULL === $entity) { if (NULL === $entity) {
throw $this->createNotFoundException(sprintf("The %s with id %s " throw $this->createNotFoundException(sprintf("The %s with id %s "
. "is not found", $this->getCrudName(), $id)); . "is not found"), $this->getCrudName(), $id);
} }
$response = $this->checkACL($action, $entity); $response = $this->checkACL($action, $entity);

View File

@@ -183,48 +183,12 @@ class CRUDRoutesLoader extends Loader
$methods = \array_keys(\array_filter($action['methods'], function($value, $key) { return $value; }, $methods = \array_keys(\array_filter($action['methods'], function($value, $key) { return $value; },
ARRAY_FILTER_USE_BOTH)); ARRAY_FILTER_USE_BOTH));
$route = new Route($path, $defaults, $requirements); if (count($methods) === 0) {
$route->setMethods($methods); throw new \RuntimeException("The api configuration named \"{$crudConfig['name']}\", action \"{$name}\", ".
"does not have any allowed methods. You should remove this action from the config ".
$collection->add('chill_api_single_'.$crudConfig['name'].'_'.$name, $route); "or allow, at least, one method");
} }
return $collection;
}
/**
* Load routes for api multi
*
* @param $crudConfig
* @return RouteCollection
*/
protected function loadApiMultiConfig(array $crudConfig): RouteCollection
{
$collection = new RouteCollection();
$controller ='csapi_'.$crudConfig['name'].'_controller';
foreach ($crudConfig['actions'] as $name => $action) {
// filter only on single actions
$singleCollection = $action['single-collection'] ?? $name === '_index' ? 'collection' : NULL;
if ('single' === $singleCollection) {
continue;
}
$defaults = [
'_controller' => $controller.':'.($action['controller_action'] ?? '_entity' === $name ? 'entityApi' : $name.'Api')
];
// path are rewritten
// if name === 'default', we rewrite it to nothing :-)
$localName = '_entity' === $name ? '' : '/'.$name;
$localPath = $action['path'] ?? '/{id}'.$localName.'.{_format}';
$path = $crudConfig['base_path'].$localPath;
$requirements = $action['requirements'] ?? [ '{id}' => '\d+' ];
$methods = \array_keys(\array_filter($action['methods'], function($value, $key) { return $value; },
ARRAY_FILTER_USE_BOTH));
$route = new Route($path, $defaults, $requirements); $route = new Route($path, $defaults, $requirements);
$route->setMethods($methods); $route->setMethods($methods);

View File

@@ -13,9 +13,9 @@
div#header-accompanying_course-name { div#header-accompanying_course-name {
background: none repeat scroll 0 0 #718596; background: none repeat scroll 0 0 #718596;
color: #FFF; color: #FFF;
h1 { padding-top: 1em;
margin: 0.4em 0; padding-bottom: 1em;
}
span { span {
a { a {
color: white; color: white;
@@ -54,10 +54,3 @@ div.subheader {
color: grey; color: grey;
margin-right: 1em; margin-right: 1em;
} }
table {
ul.record_actions {
margin: 0;
padding: 0.5em;
}
}

View File

@@ -37,32 +37,32 @@ class LoadSocialActions extends AbstractFixture implements OrderedFixtureInterfa
return 10020; return 10020;
} }
public static $socialActions = [ public static $socialActions = array(
'social_action_info_conseil' => [ 'social_action_info_conseil' => array(
'title' => [ 'title' => array(
'fr' => 'Informer, conseiller' 'fr' => 'Informer, conseiller'
], ),
'issue' => 'social_issue_prev_prot' 'issue' => 'social_issue_prev_prot'
], ),
'social_action_instruire' => [ 'social_action_instruire' => array(
'title' => [ 'title' => array(
'fr' => 'Instruire l\'imprime unique pour des impayés' 'fr' => 'Instruire l\'imprime unique pour des impayés'
], ),
'issue' => 'social_issue_prev_prot' 'issue' => 'social_issue_prev_prot'
], ),
'social_action_MASP' => [ 'social_action_MASP' => array(
'title' => [ 'title' => array(
'fr' => 'MASP' 'fr' => 'MASP'
], ),
'issue' => 'social_issue_diff_fin' 'issue' => 'social_issue_diff_fin'
], ),
'social_action_protection_enfant' => [ 'social_action_protection_enfant' => array(
'title' => [ 'title' => array(
'fr' => 'Protection Enfant confié dans le cadre judiciaire' 'fr' => 'Protection Enfant confié dans le cadre judiciaire'
], ),
'issue' => 'social_issue_enfant_protection' 'issue' => 'social_issue_enfant_protection'
], ),
]; );
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {

View File

@@ -38,20 +38,20 @@ class LoadSocialGoals extends AbstractFixture implements OrderedFixtureInterface
return 10030; return 10030;
} }
public static $socialGoals = [ public static $socialGoals = array(
'social_goal_instuire_dossier' => [ 'social_goal_instuire_dossier' => array(
'title' => [ 'title' => array(
'fr' => 'Instruire le dossier de surendettement' 'fr' => 'Instruire le dossier de surendettement'
], ),
'action' => 'social_action_MASP' 'action' => 'social_action_MASP'
], ),
'social_goal_proteger' => [ 'social_goal_proteger' => array(
'title' => [ 'title' => array(
'fr' => 'Protéger via une assistance educative placement' 'fr' => 'Protéger via une assistance educative placement'
], ),
'action' => 'social_action_protection_enfant' 'action' => 'social_action_protection_enfant'
], ),
]; );
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {

View File

@@ -37,36 +37,36 @@ class LoadSocialIssues extends AbstractFixture implements OrderedFixtureInterfac
return 10010; return 10010;
} }
public static $socialIssues = [ public static $socialIssues = array(
'social_issue_diff_fin_or_admin' => [ 'social_issue_diff_fin_or_admin' => array(
'title' => [ 'title' => array(
'fr' => 'ADULTE - DIFFICULTES FINANCIERES ET/OU ADMINISTRATIVES' 'fr' => 'ADULTE - DIFFICULTES FINANCIERES ET/OU ADMINISTRATIVES'
] )
], ),
'social_issue_prev_prot' => [ 'social_issue_prev_prot' => array(
'title' => [ 'title' => array(
'fr' => 'ADULTE PREVENTION/PROTECTION' 'fr' => 'ADULTE PREVENTION/PROTECTION'
], ),
'parent' => 'social_issue_diff_fin_or_admin' 'parent' => 'social_issue_diff_fin_or_admin'
], ),
'social_issue_diff_fin' => [ 'social_issue_diff_fin' => array(
'title' => [ 'title' => array(
'fr' => 'Difficulté financière' 'fr' => 'Difficulté financière'
], ),
'parent' => 'social_issue_diff_fin_or_admin' 'parent' => 'social_issue_diff_fin_or_admin'
], ),
'social_issue_enfant_famille' => [ 'social_issue_enfant_famille' => array(
'title' => [ 'title' => array(
'fr' => 'Enfant / famille' 'fr' => 'Enfant / famille'
] )
], ),
'social_issue_enfant_protection' => [ 'social_issue_enfant_protection' => array(
'title' => [ 'title' => array(
'fr' => 'enfant - protection' 'fr' => 'enfant - protection'
], ),
'parent' => 'social_issue_enfant_famille' 'parent' => 'social_issue_enfant_famille'
], ),
]; );
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {

View File

@@ -38,34 +38,34 @@ class LoadSocialResults extends AbstractFixture implements OrderedFixtureInterfa
return 10040; return 10040;
} }
public static $socialResults = [ public static $socialResults = array(
'social_result_FSL_acces' => [ 'social_result_FSL_acces' => array(
'title' => [ 'title' => array(
'fr' => 'FSL - accès cautionnement' 'fr' => 'FSL - accès cautionnement'
], ),
'action' => 'social_action_instruire' 'action' => 'social_action_instruire'
], ),
'social_result_FSL_maintien' => [ 'social_result_FSL_maintien' => array(
'title' => [ 'title' => array(
'fr' => 'FSL maintien - impayés de loyer' 'fr' => 'FSL maintien - impayés de loyer'
], ),
'action' => 'social_action_MASP' 'action' => 'social_action_MASP'
], ),
'social_result_soutien_parental' => [ 'social_result_soutien_parental' => array(
'title' => [ 'title' => array(
'fr' => 'Soutien parental' 'fr' => 'Soutien parental'
], ),
// 'action' => 'social_action_protection_enfant', (via le goal) // 'action' => 'social_action_protection_enfant', (via le goal)
'goal' => 'social_goal_proteger' 'goal' => 'social_goal_proteger'
], ),
'social_result_accompagnement_mineur' => [ 'social_result_accompagnement_mineur' => array(
'title' => [ 'title' => array(
'fr' => 'Accompagnement du mineur' 'fr' => 'Accompagnement du mineur'
], ),
// 'action' => 'social_action_protection_enfant', (via le goal) // 'action' => 'social_action_protection_enfant', (via le goal)
'goal' => 'social_goal_proteger', 'goal' => 'social_goal_proteger',
], ),
]; );
public function load(ObjectManager $manager) public function load(ObjectManager $manager)
{ {

View File

@@ -476,7 +476,6 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class, 'class' => \Chill\PersonBundle\Entity\SocialWork\SocialIssue::class,
'name' => 'social_work_social_issue', 'name' => 'social_work_social_issue',
'base_path' => '/api/1.0/person/social-work/social-issue', 'base_path' => '/api/1.0/person/social-work/social-issue',
// 'controller' => \Chill\PersonBundle\Controller\OpeningApiController::class,
'base_role' => 'ROLE_USER', 'base_role' => 'ROLE_USER',
'actions' => [ 'actions' => [
'_index' => [ '_index' => [
@@ -493,6 +492,25 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
], ],
] ]
], ],
[
'class' => \Chill\PersonBundle\Entity\Person::class,
'name' => 'person',
'base_path' => '/api/1.0/person/person',
'base_role' => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
'actions' => [
'_entity' => [
'methods' => [
Request::METHOD_GET => true,
Request::METHOD_HEAD => true
],
'roles' => [
Request::METHOD_GET => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
Request::METHOD_HEAD => \Chill\PersonBundle\Security\Authorization\PersonVoter::SEE,
]
],
]
],
] ]
]); ]);
} }

View File

@@ -32,19 +32,18 @@ export default {
PersonsAssociated, PersonsAssociated,
Requestor, Requestor,
SocialIssue, SocialIssue,
//Referrer, //fait foirer socialissues Referrer,
Resources, Resources,
Comment, Comment,
Confirm, Confirm,
}, },
computed: mapState([ computed: mapState([
'accompanyingCourse', 'socialIssueOptions' 'accompanyingCourse'
]) ])
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
div#accompanying-course {
h1 { h1 {
margin: 1.5em 0; margin: 1.5em 0;
} }
@@ -54,16 +53,10 @@ export default {
position: relative; position: relative;
&:before { &:before {
position: absolute; position: absolute;
/* content: "\f192";
content: "\f192"; //circle-dot
content: "\f1dd"; //paragraph
content: "\f292"; //hashtag
content: "\f069"; //asterisk
*/
content: "\f142"; //ellipsis-v
font-family: "ForkAwesome"; font-family: "ForkAwesome";
color: #718596ab; color: #718596ab;
left: -22px; left: -28px;
top: 4px; top: 4px;
} }
a[name^="section"] { a[name^="section"] {
@@ -98,5 +91,4 @@ export default {
table { table {
} }
} }
}
</style> </style>

View File

@@ -146,25 +146,6 @@ const postResource = (id, payload, method) => {
}); });
}; };
/*
* Endpoint to Add/remove SocialIssue
*/
const postSocialIssue = (id, body, method) => {
//console.log('api body and method', body, method);
const url = `/api/1.0/person/accompanying-course/${id}/socialissue.json`;
return fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(body)
})
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
};
export { export {
getAccompanyingCourse, getAccompanyingCourse,
patchAccompanyingCourse, patchAccompanyingCourse,
@@ -173,5 +154,4 @@ export {
postParticipation, postParticipation,
postRequestor, postRequestor,
postResource, postResource,
postSocialIssue
}; };

View File

@@ -20,11 +20,9 @@
<teleport to="#header-accompanying_course-name #banner-status"> <teleport to="#header-accompanying_course-name #banner-status">
<div v-if="accompanyingCourse.step === 'DRAFT'"> <div v-if="accompanyingCourse.step === 'DRAFT'">
<a href="#bottom">
<span class="badge badge-secondary"> <span class="badge badge-secondary">
{{ $t('course.step.draft') }} {{ $t('course.step.draft') }}
</span> </span>
</a>
</div> </div>
<div v-else> <div v-else>
<div> <div>
@@ -45,26 +43,20 @@
</teleport> </teleport>
<teleport to="#header-accompanying_course-details #banner-social-issues"> <teleport to="#header-accompanying_course-details #banner-social-issues">
<div class="grid-12"> <div class="grid-4">{{ $t('social_issue.title') }}</div>
<social-issues <div class="grid-4">_</div>
v-for="issue in accompanyingCourse.socialIssues" <div class="grid-4">_</div>
v-bind:key="issue.id"
v-bind:issue="issue">
</social-issues>
</div>
</teleport> </teleport>
</template> </template>
<script> <script>
import ToggleFlags from './Banner/ToggleFlags'; import ToggleFlags from './ToggleFlags';
import SocialIssues from './Banner/SocialIssues.vue';
export default { export default {
name: 'Banner', name: 'Banner',
components: { components: {
ToggleFlags, ToggleFlags
SocialIssues
}, },
computed: { computed: {
accompanyingCourse() { accompanyingCourse() {

View File

@@ -1,16 +0,0 @@
<template>
<span class="badge badge-secondary">{{ issue.text }}</span>
</template>
<script>
export default {
name: "SocialIssues",
props: ['issue']
}
</script>
<style lang="scss" scoped>
span.badge {
margin-right: 1em;
}
</style>

View File

@@ -8,17 +8,17 @@
</div--> </div-->
<div> <div>
<form @submit.prevent="submitform">
<label for="content">{{ $t('comment.label') }}</label>
<div v-if="initialComment"> <div v-if="initialComment">
{{ $t('comment.created_by', [ créé par {{ initialComment.creator.text }}
initialComment.creator.text, le {{ $d(initialComment.createdAt.datetime, 'long') }}
$d(initialComment.createdAt.datetime, 'long') <div v-if="initialComment.updatedAt.datetime !== initialComment.createdAt.datetime">
]) }} modifié par {{ initialComment.updatedBy.text }}
le {{ $d(initialComment.updatedAt.datetime, 'long') }}
</div>
</div> </div>
<form @submit.prevent="submitform">
<label for="content">{{ $t('comment.label') }}</label>
<textarea <textarea
name="content" name="content"
v-bind:placeholder="$t('comment.content')" v-bind:placeholder="$t('comment.content')"
@@ -27,7 +27,6 @@
ckeditor="ckeditor" ckeditor="ckeditor"
v-model="content"> v-model="content">
</textarea> </textarea>
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<button type="submit" class="sc-button bt-save">{{ $t('action.save') }}</button> <button type="submit" class="sc-button bt-save">{{ $t('action.save') }}</button>
@@ -39,7 +38,6 @@
</a> </a>
</li> </li>
</ul> </ul>
</form> </form>
</div> </div>

View File

@@ -43,7 +43,7 @@
<script> <script>
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import PersonItem from "./PersonsAssociated/PersonItem.vue" import PersonItem from "./PersonItem.vue"
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue' import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue'
export default { export default {

View File

@@ -54,9 +54,6 @@
</li> </li>
</ul> </ul>
</div> </div>
<div v-else>
<label>{{ $t('requestor.counter') }}</label>
</div>
<div> <div>
<add-persons v-if="accompanyingCourse.requestor === null" <add-persons v-if="accompanyingCourse.requestor === null"

View File

@@ -42,7 +42,7 @@
<script> <script>
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue'; import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue';
import ResourceItem from './Resources/ResourceItem.vue'; import ResourceItem from './ResourceItem.vue';
export default { export default {
name: 'Resources', name: 'Resources',

View File

@@ -3,20 +3,18 @@
<h2><a name="section-30"></a>{{ $t('social_issue.title') }}</h2> <h2><a name="section-30"></a>{{ $t('social_issue.title') }}</h2>
<div class="my-4"> <div class="my-4">
<!--label for="field">{{ $t('social_issue.label') }}</label <!--label for="selectIssues">{{ $t('social_issue.label') }}</label-->
-->
<VueMultiselect <VueMultiselect
name="field" name="selectIssues"
v-model="selected"
track-by="id"
label="text"
:placeholder="$t('social_issue.label')"
:multiple="true"
:searchable="true"
:close-on-select="false" :close-on-select="false"
:allow-empty="true" :allow-empty="true"
:show-labels="false" :show-labels="false"
track-by="id"
label="text"
:multiple="true"
:searchable="false"
:placeholder="$t('social_issue.label')"
@update:model-value="updateSocialIssues"
:model-value="value"
:options="options"> :options="options">
</VueMultiselect> </VueMultiselect>
</div> </div>
@@ -25,56 +23,38 @@
</template> </template>
<script> <script>
import VueMultiselect from 'vue-multiselect'; import VueMultiselect from 'vue-multiselect'
import { getSocialIssues } from '../api'; import { getSocialIssues } from '../api'
import { mapState } from 'vuex';
export default { export default {
name: "SocialIssue", name: "SocialIssue",
components: { VueMultiselect }, components: { VueMultiselect },
data () { data () {
return { return {
selected: null,
options: [] options: []
} }
}, },
computed: { computed: {
...mapState({
value: state => state.accompanyingCourse.socialIssues,
}),
}, },
mounted() { mounted() {
this.getOptions(); this.getOptions();
}, },
methods: { methods: {
getOptions() { getOptions() {
getSocialIssues().then(elements => new Promise((resolve, reject) => { getSocialIssues().then(socialIssues => new Promise((resolve, reject) => {
console.log('get socialIssues', elements.results); console.log('socialIssues', socialIssues);
this.options = elements.results; this.options = socialIssues.results;
resolve(); resolve();
})).catch(error => this.$store.commit('catchError', error)); })).catch(error => this.$store.commit('catchError', error));
}, },
updateSocialIssues(value) {
this.$store.dispatch('updateSocialIssues', this.transformValue(value));
},
transformValue(updated) {
let stored = this.value;
let added = updated.filter(x => stored.indexOf(x) === -1).shift();
let removed = stored.filter(x => updated.indexOf(x) === -1).shift();
let method = (typeof removed === 'undefined') ? 'POST' : 'DELETE';
let changed = (typeof removed === 'undefined') ? added : removed;
let body = { type: "social_issue", id: changed.id };
//console.log('body', body);
console.log('@@@ CHANGED', method, changed.text);
let payload = updated;
return { payload, body, method };
}
} }
} }
</script> </script>
<style src="vue-multiselect/dist/vue-multiselect.css"></style> <style src="vue-multiselect/dist/vue-multiselect.css"></style>
<style lang="scss"> <style lang="scss" scoped>
span.multiselect__tag { div.vue-component > div {
background: #e2793d; //margin: 3em;
} }
</style> </style>

View File

@@ -39,7 +39,6 @@ const appMessages = {
title: "Demandeur", title: "Demandeur",
add_requestor: "Ajouter un demandeur", add_requestor: "Ajouter un demandeur",
is_anonymous: "Le demandeur est anonyme", is_anonymous: "Le demandeur est anonyme",
counter: "Il n'y a pas encore de demandeur",
type: "Type", type: "Type",
person_id: "id", person_id: "id",
text: "Dénomination", text: "Dénomination",
@@ -58,10 +57,7 @@ const appMessages = {
label: "Choisir les problématiques sociales", label: "Choisir les problématiques sociales",
}, },
referrer: { referrer: {
title: "Référent du parcours", title: "Référent",
label: "Vous pouvez choisir un TMS ou vous assigner directement comme référent",
assign_me: "M'assigner comme référent",
placeholder: "Choisir un TMS",
}, },
resources: { resources: {
title: "Interlocuteurs privilégiés", title: "Interlocuteurs privilégiés",
@@ -73,8 +69,7 @@ const appMessages = {
comment: { comment: {
title: "Observations", title: "Observations",
label: "Ajout d'une note", label: "Ajout d'une note",
content: "Rédigez une première note...", content: "Rédigez une première note..."
created_by: "créé par {0}, le {1}"
}, },
confirm: { confirm: {
title: "Confirmation", title: "Confirmation",

View File

@@ -5,8 +5,7 @@ import { getAccompanyingCourse,
confirmAccompanyingCourse, confirmAccompanyingCourse,
postParticipation, postParticipation,
postRequestor, postRequestor,
postResource, postResource } from '../api';
postSocialIssue } from '../api';
const debug = process.env.NODE_ENV !== 'production'; const debug = process.env.NODE_ENV !== 'production';
const id = window.accompanyingCourseId; const id = window.accompanyingCourseId;
@@ -75,12 +74,9 @@ let initPromise = getAccompanyingCourse(id)
state.accompanyingCourse.confidential = value; state.accompanyingCourse.confidential = value;
}, },
postFirstComment(state, comment) { postFirstComment(state, comment) {
//console.log('### mutation: postFirstComment', comment); console.log('### mutation: postFirstComment', comment);
state.accompanyingCourse.initialComment = comment; state.accompanyingCourse.initialComment = comment;
}, },
updateSocialIssues(state, value) {
state.accompanyingCourse.socialIssues = value;
},
confirmAccompanyingCourse(state, response) { confirmAccompanyingCourse(state, response) {
//console.log('### mutation: confirmAccompanyingCourse: response', response); //console.log('### mutation: confirmAccompanyingCourse: response', response);
state.accompanyingCourse.step = response.step; state.accompanyingCourse.step = response.step;
@@ -149,7 +145,7 @@ let initPromise = getAccompanyingCourse(id)
})).catch((error) => { commit('catchError', error) }); })).catch((error) => { commit('catchError', error) });
}, },
toggleIntensity({ commit }, payload) { toggleIntensity({ commit }, payload) {
//console.log(payload); console.log(payload);
patchAccompanyingCourse(id, { type: "accompanying_period", intensity: payload }) patchAccompanyingCourse(id, { type: "accompanying_period", intensity: payload })
.then(course => new Promise((resolve, reject) => { .then(course => new Promise((resolve, reject) => {
commit('toggleIntensity', course.intensity); commit('toggleIntensity', course.intensity);
@@ -171,24 +167,16 @@ let initPromise = getAccompanyingCourse(id)
})).catch((error) => { commit('catchError', error) }); })).catch((error) => { commit('catchError', error) });
}, },
postFirstComment({ commit }, payload) { postFirstComment({ commit }, payload) {
//console.log('## action: postFirstComment: payload', payload); console.log('## action: postFirstComment: payload', payload);
patchAccompanyingCourse(id, { type: "accompanying_period", initialComment: payload }) patchAccompanyingCourse(id, { type: "accompanying_period", initialComment: payload })
.then(course => new Promise((resolve, reject) => { .then(course => new Promise((resolve, reject) => {
commit('postFirstComment', course.initialComment); commit('postFirstComment', course.initialComment);
resolve(); resolve();
})).catch((error) => { commit('catchError', error) }); })).catch((error) => { commit('catchError', error) });
}, },
updateSocialIssues({ commit }, { payload, body, method }) {
//console.log('## action: payload', { payload, body, method });
postSocialIssue(id, body, method)
.then(response => new Promise((resolve, reject) => {
console.log('response', response);
commit('updateSocialIssues', payload);
resolve();
})).catch((error) => { commit('catchError', error) });
},
confirmAccompanyingCourse({ commit }) { confirmAccompanyingCourse({ commit }) {
//console.log('## action: confirmAccompanyingCourse'); console.log('## action: confirmAccompanyingCourse');
confirmAccompanyingCourse(id) confirmAccompanyingCourse(id)
.then(response => new Promise((resolve, reject) => { .then(response => new Promise((resolve, reject) => {
commit('confirmAccompanyingCourse', response); commit('confirmAccompanyingCourse', response);

View File

@@ -5,7 +5,6 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<h1>{{ 'Resume Accompanying Course' | trans }}</h1>
{% if 'DRAFT' == accompanyingCourse.step %} {% if 'DRAFT' == accompanyingCourse.step %}
<div class="grid-8 centered error flash_message"> <div class="grid-8 centered error flash_message">
@@ -18,82 +17,12 @@
</div> </div>
{% endif %} {% endif %}
<div class="vue-component"> <h1>{{ 'Associated peoples'|trans }}</h1>
<h2>{{ 'Associated peoples'|trans }}</h2>
{% if accompanyingCourse.participations.count > 0 %} <h1>{{ 'Resources'|trans }}</h1>
<table class="rounded">
<thead>
<tr>
<th class="chill-orange">{{ 'First name' | trans }}</th>
<th class="chill-orange">{{ 'Last name' | trans }}</th>
<th class="chill-orange">{{ 'Start date' | trans }}</th>
<th class="chill-orange">{{ 'End date' | trans }}</th>
</tr>
</thead>
<tbody>
{% for participation in accompanyingCourse.participations %}
<tr>
<td>{{ participation.person.firstName }}</td>
<td>{{ participation.person.lastName }}</td>
<td>{{ participation.startDate | format_date('short') }}</td>
<td>{{ participation.endDate | format_date('short') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="grid-8 centered error flash_message">
{{ "No Associated peoples recorded" | trans }}
</div>
{% endif %}
</div>
<div class="vue-component"> <h1>{{ 'Social actions'|trans }}</h1>
<h2>{{ 'Resources'|trans }}</h2>
{% if accompanyingCourse.resources.count > 0 %} <h1>{{ 'Last events on accompanying course'|trans }}</h1>
<table class="rounded">
<thead>
<tr>
<th class="chill-orange">{{ 'First name' | trans }}</th>
<th class="chill-orange">{{ 'Last name' | trans }}</th>
</tr>
</thead>
<tbody>
{% for resource in accompanyingCourse.resources %}
<tr>
<td>{{ resource.person.firstName }}</td>
<td>{{ resource.person.lastName }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="grid-8 centered alert flash_message">
{{ "No resources recorded" | trans }}
</div>
{% endif %}
</div>
<div class="vue-component">
<h2>{{ 'Social actions'|trans }}</h2>
<div class="grid-8 centered notice flash_message">
{{ "Not implemented" | trans }}
</div>
</div>
<div class="vue-component">
<h2>{{ 'Last events on accompanying course'|trans }}</h2>
<div class="grid-8 centered notice flash_message">
{{ "Not implemented" | trans }}
</div>
</div>
{% endblock %}
{% block css %}
{{ encore_entry_link_tags('accompanying_course') }}
{% endblock %} {% endblock %}

View File

@@ -0,0 +1,83 @@
<?php
namespace Chill\PersonBundle\Tests\Controller;
use Chill\MainBundle\Test\PrepareClientTrait;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PersonApiControllerTest extends WebTestCase
{
use PrepareClientTrait;
/**
* @dataProvider dataGetPersonFromCenterB
*/
public function testPersonGetUnauthorized($personId): void
{
$client = $this->getClientAuthenticated();
$client->request(Request::METHOD_GET, "/api/1.0/person/person/{$personId}.json");
$response = $client->getResponse();
$this->assertEquals(403, $response->getStatusCode());
}
/**
* @dataProvider dataGetPersonFromCenterA
*/
public function testPersonGet($personId): void
{
$client = $this->getClientAuthenticated();
$client->request(Request::METHOD_GET, "/api/1.0/person/person/{$personId}.json");
$response = $client->getResponse();
$this->assertResponseIsSuccessful();
$data = \json_decode($client->getResponse()->getContent(), true);
$this->assertArrayHasKey('type', $data);
$this->assertArrayHasKey('id', $data);
$this->assertEquals('person', $data['type']);
$this->assertEquals($personId, $data['id']);
}
public function dataGetPersonFromCenterA(): \Iterator
{
self::bootKernel();
$em = self::$container->get(EntityManagerInterface::class);
$personIds= $em->createQuery("SELECT p.id FROM ".Person::class." p ".
"JOIN p.center c ".
"WHERE c.name = :center")
->setParameter('center', 'Center A')
->setMaxResults(100)
->getScalarResult()
;
\shuffle($personIds);
yield \array_pop($personIds);
yield \array_pop($personIds);
}
public function dataGetPersonFromCenterB(): \Iterator
{
self::bootKernel();
$em = self::$container->get(EntityManagerInterface::class);
$personIds= $em->createQuery("SELECT p.id FROM ".Person::class." p ".
"JOIN p.center c ".
"WHERE c.name = :center")
->setParameter('center', 'Center B')
->setMaxResults(100)
->getScalarResult()
;
\shuffle($personIds);
yield \array_pop($personIds);
yield \array_pop($personIds);
}
}

View File

@@ -178,6 +178,30 @@ components:
readOnly: true readOnly: true
paths: paths:
/1.0/person/person/{id}.json:
get:
tags:
- person
summary: Get a single person
parameters:
- name: id
in: path
required: true
description: The person's id
schema:
type: integer
format: integer
minimum: 1
responses:
200:
description: "OK"
content:
application/json:
schema:
$ref: "#/components/schemas/Person"
403:
description: "Unauthorized"
/1.0/person/social-work/social-issue.json: /1.0/person/social-work/social-issue.json:
get: get:
tags: tags: