Commit 6fe4cdaf authored by Fabrice Gangler's avatar Fabrice Gangler 🎨
Browse files

FEAT(mapping): add form (add|edit)

Refs: #902 #874 #824 #882 #883
parent 9d528662
......@@ -2,6 +2,8 @@
namespace App\Controller\Api\V1;
use App\Controller\Api\V1\Taxonomy\CommonTaxonomySoftwareController;
use App\Model\Entity\Software;
use App\Model\Entity\User;
use App\Model\Table\TaxonomysSoftwaresTable;
use Cake\Datasource\Exception\RecordNotFoundException;
use Cake\Network\Exception\NotFoundException;
......@@ -61,10 +63,14 @@ class TaxonomysSoftwaresController extends CommonTaxonomySoftwareController
*/
public function mappingForm($softwareId = null)
{
// Get data
// Get taxonomy data
$mappingTaxons = $this->getMappingTaxons();
$mappingHead = $this->getmappingFirstLevels();
// Get user
$user = TableRegistry::get("Users")->get($this->Auth->user('id'));
$userId = (int) $user->id;
// $softwareId is not null only with /api/v1/ prefix
if (is_null($softwareId)) { // Get the ID from the URL
if (isset($this->request->params['softwareId'])) {
......@@ -85,17 +91,35 @@ class TaxonomysSoftwaresController extends CommonTaxonomySoftwareController
// Check that the current URL is correct
$lang = $this->selectedLanguage;
$currentUrl = $this->request->here(false);
$allowedUrl = "/$lang/mappingForm/$softwareId";
if ($allowedUrl !== $currentUrl) {
if ($allowedUrl !== $this->request->here(false)) {
return $this->redirect("$allowedUrl", 301);
}
// Get data
// Get already existing associations between the user, the software and the taxonomies
$existingEntries = $this->TaxonomysSoftwares->getObjsListByUserIdBySofwareId($userId, $softwareId);
// example: Array( <taxonId> => taxonomySoftware, ...)
// Form processing
if (isset($this->request->data['id'])) { // form sent
$processing = $this->processingMappingForm($software, $user, $existingEntries);
if ($processing === true) {
return $this->redirect("/$lang/softwares/" . $software->get('id'));
} else {
return $this->redirect("/$lang/mappingForm/" . $software->get('id'));
}
}
// Parameters for the view
$this->set(compact('user'));
$this->set(compact('software'));
$this->set(compact('existingEntries'));
$this->set(compact('mappingTaxons'));
$this->set(compact('mappingHead'));
$this->set('_serialize', ['existingEntries']);
$this->set('_serialize', ['software']);
$this->set('_serialize', ['mappingTaxons']);
$this->set('_serialize', ['mappingHead']);
// Breadcrumbs
$links = array();
......@@ -114,4 +138,111 @@ class TaxonomysSoftwaresController extends CommonTaxonomySoftwareController
];
$this->setBreadcrumbs($links);
}
/**
* Processing mapping form
*
* Two cases:
* - Add/Edit form sent empty ---> sub-processing by $this->processingMappingEmptyForm()
* - Add/Edit form sent with data --> sub-processing by $this->processingMappingFormWithData()
*
* @param Software $software
* @param User $user
* @param array $existingEntries example: [ <taxonId> => taxonomySoftware, ...]
* @return bool
*/
final private function processingMappingForm(Software $software, User $user, array $existingEntries): bool
{
$processing = true;
// Form sent empty
if (!isset($this->request->data['taxonCheckboxes']) || count($this->request->data['taxonCheckboxes']) === 0) {
$processing = $this->processingMappingEmptyForm($existingEntries); // calls flash messages directly
} else { // Form sent with data
$processing = $this->processingMappingFormWithData($software, $user, $existingEntries);
if ($processing === true) {
$this->Flash->success(__d("Taxonomy", "TaxonomySoftware.FormProcessing.sucessMsg"));
} else {
$this->Flash->error(__d("Taxonomy", "TaxonomySoftware.FormProcessing.errorMsg"));
}
}
return $processing;
}
/**
* Processing add/edit form sent with data
*
* @param Software $software
* @param User $user
* @param array $existingEntries example: [ <taxonId> => taxonomySoftware, ...]
* @return bool
*/
final private function processingMappingFormWithData(Software $software, User $user, array $existingEntries): bool
{
$processing = true;
$softwareId = $software->id;
$userId = $user->id;
$selectedTaxon = $this->request->data['taxonCheckboxes'];
foreach ($selectedTaxon as $idTaxon) {
$idTaxon = (int) $idTaxon;
// Preparing to delete old entries that have not been selected
if (isset($existingEntries[$idTaxon])) {
unset($existingEntries[$idTaxon]);
} else {
// Add new entries
$taxonomySoftware = $this->TaxonomysSoftwares->newEntity();
$taxonomySoftware->set('taxonomy_id', $idTaxon);
$taxonomySoftware->set('software_id', $softwareId);
$taxonomySoftware->set('user_id', $userId);
// Additional form ----> to be reviewed (refs. z881)
/////////////////////////////////////////////////////////
// if (isset($this->request->data['comment'])) {
// $comment = trim(strip_tags($this->request->data['comment']));
// if (!empty($comment)) {
// $taxonomySoftware->set('comment', "$comment");
// }
// }
if (false === $this->TaxonomysSoftwares->save($taxonomySoftware)) {
$processing = false;
}
}
}
// Delete old entries that have not been selected.
if (false === $this->TaxonomysSoftwares->deleteRecords($existingEntries)) {
$processing = false;
}
return $processing;
}
/**
* Processing empty mapping form
*
* Two cases:
* - Add form sent empty
* - Edit form sent empty --> delete all database entries
*
* @param array $existingEntries example: [ taxonomySoftware, ...]
* @return bool
*/
final private function processingMappingEmptyForm(array $existingEntries): bool
{
$processing = true;
if (count($existingEntries) === 0) { // Add form sent empty
$this->Flash->error(__d("Taxonomy", "TaxonomySoftware.FormProcessing.formEmptyErrorMsg"));
$processing = false;
} else { // Edit form sent empty --> delete all database entries
if (false === $this->TaxonomysSoftwares->deleteRecords($existingEntries)) {
$processing = false;
}
if ($processing === true) {
$this->Flash->success(__d("Taxonomy", "TaxonomySoftware.FormProcessing.formEmptySucessMsg"));
} else {
$this->Flash->error(__d("Taxonomy", "TaxonomySoftware.FormProcessing.errorMsg"));
}
}
return $processing;
}
}
......@@ -25,14 +25,33 @@ msgstr ""
msgid "Taxonomy.Index.H1"
msgstr ""
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:8
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.sucessMsg"
msgstr ""
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.errorMsg"
msgstr ""
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.formEmptyErrorMsg"
msgstr ""
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.formEmptySucessMsg"
msgstr ""
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:10
msgid "TaxonomySoftware.Form.Add.Title"
msgstr ""
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:8
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:11
msgid "TaxonomySoftware.Form.Add.H1"
msgstr ""
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:12
msgid "TaxonomySoftware.Form.Add.Help"
msgstr ""
#: Template/Api/V1/TaxonomysSoftwares/mapping_taxon_users_of.ctp:10
msgid "TaxonomySoftware.UserOf.Software_forOneTaxon.Title"
......
......@@ -26,14 +26,36 @@ msgstr "Mapping of business software for local governments"
msgid "Taxonomy.Index.H1"
msgstr "Mapping of business software for local governments"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:8
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.sucessMsg"
msgstr "Congratulations, everything went well. Thank you for your valuable input."
# msgstr "Your organization is now associated with this software on business mapping."
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.errorMsg"
msgstr "An error has occurred. Can you try again?"
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.formEmptyErrorMsg"
msgstr "Sorry, you must choose at least one area of use."
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.formEmptySucessMsg"
msgstr "Congratulations, everything went well. @@@TODO"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:10
msgid "TaxonomySoftware.Form.Add.Title"
msgstr "Mapping form"
msgstr "{0} software: declare your uses"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:8
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:11
msgid "TaxonomySoftware.Form.Add.H1"
msgstr "Mapping form"
msgstr "Uses of <strong>{0}</strong> software"
"<br><small>by your organisation (<strong>{1}</strong>)</small>"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:12
msgid "TaxonomySoftware.Form.Add.Help"
msgstr "Can you tell us what areas where the <strong>{0}</strong> "
"<br> software is used by your organization? "
#: Template/Api/V1/TaxonomysSoftwares/mapping_taxon_users_of.ctp:10
msgid "TaxonomySoftware.UserOf.Software_forOneTaxon.Title"
......
......@@ -26,14 +26,36 @@ msgstr "Cartographie des logiciels métiers pour les collectivités"
msgid "Taxonomy.Index.H1"
msgstr "Cartographie des logiciels métiers pour les collectivités"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:8
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.sucessMsg"
msgstr "Félicitations, tout s'est bien passé. Merci pour votre précieuse contribution."
# msgstr "Votre organisation est maintenant associée à ce logiciel sur la cartographie des métiers."
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.errorMsg"
msgstr "Une erreur s'est produite. Pouvez-vous réessayer ?"
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.formEmptyErrorMsg"
msgstr "Désolé, vous devez choisir au moins un domaine d'utilisation."
#: Controller/Api/V1/TTaxonomysSoftwaresController.php:
msgid "TaxonomySoftware.FormProcessing.formEmptySucessMsg"
msgstr "Félicitations, tout s'est bien passé. @@@TODO"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:10
msgid "TaxonomySoftware.Form.Add.Title"
msgstr "Formulaire cartographie"
msgstr "Logiciel {0} : déclarer vos usages"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:8
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:11
msgid "TaxonomySoftware.Form.Add.H1"
msgstr "Formulaire cartographie"
msgstr "Usages du logiciel <strong>{0}</strong>"
"<br><small>par votre structure (<strong>{1}</strong>)</small>"
#: Template/Api/V1/TaxonomysSoftwares/mapping_form.ctp:12
msgid "TaxonomySoftware.Form.Add.Help"
msgstr "Pouvez-vous nous préciser quels sont les domaines "
"<br> où le logiciel <strong>{0}</strong> est utilisé par votre organisation ?"
#: Template/Api/V1/TaxonomysSoftwares/mapping_taxon_users_of.ctp:10
msgid "TaxonomySoftware.UserOf.Software_forOneTaxon.Title"
......
......@@ -278,4 +278,39 @@ class TaxonomysSoftwaresTable extends Table
}
return $data;
}
/**
* Return a records list
*
* @param int $userId
* @param int $softwareId
* @return array example: [ <taxonId> => taxonomySoftware, ...]
*/
public function getObjsListByUserIdBySofwareId(int $userId, int $softwareId)
{
$existingEntries = $this->find()->where(['software_id' => $softwareId, 'user_id' => $userId])->toList();
$existingEntriesByTaxonId = [];
foreach ($existingEntries as $existingEntry) {
$existingEntriesByTaxonId[$existingEntry->taxonomy_id] = $existingEntry;
}
return $existingEntriesByTaxonId;
}
/**
* Delete a records list
*
* @param array $recordsList example: [ taxonomySoftware, ...]
* @return bool
*/
public function deleteRecords(array $recordsList)
{
$processing = true;
foreach ($recordsList as $obj) {
if (false === $this->delete($obj)) {
$processing = false;
}
}
return $processing;
}
}
......@@ -67,23 +67,25 @@ $this->assign('title', $headTitle);
<?php
if ($numberOfComments > 0) {
echo "<h2>".__d("Taxonomy", "TaxonomySoftware.UserOf.comments.title", $softwareName)."</h2>";
echo "<p>".__d("Taxonomy", "TaxonomySoftware.UserOf.comments.subtitle", $softwareName, $taxonName)."</p>";
foreach($userUpdateDates as $userId => $userUpdate) {
if (isset($comments[$userId])) {
$txt = $this->Text->autoParagraph(h($comments[$userId]));
$userName = $users[$userId]->username;
$userUrl = "/$selectedLanguage/users/$userId";
$userLink = $this->Html->link("$userName", $userUrl);
$commentDate = $this->Time->format($userUpdate, [IntlDateFormatter::LONG, -1], I18n::locale());
echo " <div id=\"$attId-comment-user$userId\" class=\"taxonomyComment\">
$commentDate, <strong>$userLink</strong>
<blockquote> $txt </blockquote>
</div>";
}
}
}
// Show TaxonomySoftwareComments ----> to be reviewed (refs. z881)
/////////////////////////////////////////////////////////////////
// if ($numberOfComments > 0) {
// echo "<h2>".__d("Taxonomy", "TaxonomySoftware.UserOf.comments.title", $softwareName)."</h2>";
// echo "<p>".__d("Taxonomy", "TaxonomySoftware.UserOf.comments.subtitle", $softwareName, $taxonName)."</p>";
// foreach($userUpdateDates as $userId => $userUpdate) {
// if (isset($comments[$userId])) {
// $txt = $this->Text->autoParagraph(h($comments[$userId]));
// $userName = $users[$userId]->username;
// $userUrl = "/$selectedLanguage/users/$userId";
// $userLink = $this->Html->link("$userName", $userUrl);
// $commentDate = $this->Time->format($userUpdate, [IntlDateFormatter::LONG, -1], I18n::locale());
// echo " <div id=\"$attId-comment-user$userId\" class=\"taxonomyComment\">
// $commentDate, <strong>$userLink</strong>
// <blockquote> $txt </blockquote>
// </div>";
// }
// }
// }
?>
<div class="pageUpdate">
......
<?php
/**
* URL: /api/v1/taxonomys-softwares/mappingForm/<softwareId> ---> redirect to '/<lang>/mappingForm/<softwareId> '
* /fr/mappingForm/<softwareId>
* /en/mappingForm/<softwareId>
*/
$this->layout = 'base';
$this->assign('title', __d("Taxonomy", "TaxonomySoftware.Form.Add.Title"));
/**
* URL: /api/v1/taxonomys-softwares/mappingForm/<softwareId> ---> redirect to '/<lang>/mappingForm/<softwareId> '
* /fr/mappingForm/<softwareId>
* /en/mappingForm/<softwareId>
*/
$this->layout = 'base';
$softwareName = $software->softwarename;
$userName = $user->username;
$headTitle = __d("Taxonomy", "TaxonomySoftware.Form.Add.Title", h($softwareName));
$htmlH1 = __d("Taxonomy", "TaxonomySoftware.Form.Add.H1", h($softwareName), h($userName));
$formHelpNew = __d("Taxonomy", "TaxonomySoftware.Form.Add.Help", h($softwareName));
$this->assign('title', $headTitle);
// Build the form
$list = [];
$htmlForm = '';
foreach ($mappingHead as $primaryId => $primaryLevel) {
$primaryName = $mappingTaxons[$primaryId]['title'];
$htmlSubLlist = "";
if(isset($mappingTaxons[$primaryId]['children'])){
foreach ($mappingTaxons[$primaryId]['children'] as $taxonId => $taxonName) {
$checkBoxData = [
'type' => 'checkbox',
'value' => $taxonId,
'id' => "checkbox_$taxonId",
'label' => $taxonName,
'hiddenField' => false,
];
if (isset($existingEntries[$taxonId])) { // existing entry for current user and this software
$checkBoxData['checked'] = 'checked';
}
$htmlSubLlist .= $this->Form->input('taxonCheckboxes[]', $checkBoxData);
}
$htmlForm .= "<fieldset id=\"\" class=\"form_fieldsetRadio\">
<legend>$primaryName</legend>
$htmlSubLlist
</fieldset>";
}
}
?>
<section id="mappingForm" class="row">
<h1>
<?= __d("Taxonomy", "TaxonomySoftware.Form.Add.H1")?>
- <?php echo $software->softwarename; ?>
</h1>
<section id="mappingForm" class="taxonomyPages clearfix">
<h1> <?php echo $htmlH1; ?> </h1>
<br>
<p> <?php echo $formHelpNew; ?> </p>
<?= $this->Form->create($software, [
'type' => 'file',
"enctype" => "multipart/form-data",
'id' => "taxonomyForm_step1"
]) ?>
<div class="taxonomyForm_step1_content">
<?php echo $htmlForm; ?>
</div>
<div class="taxonomyForm_step1_footer">
<?php
// Additional form ----> to be reviewed (refs. z881)
//////////////////////////////////////////////////////
// $commentLabel = "Informations complémentaires
// <br> <small style=\"font-weight: 100;\">Vous pouvez donner des précisions
// sur les utilisations
// <br> du logiciel <strong>$softwareName</strong> par votre organisation.</small>";
// echo $this->Form->input(
// 'comment', [
// "type"=>"textarea",
// "class" => "form-control",
// "label" => [
// "class"=>"control-label",
// "text"=> "$commentLabel" ,
// "escape"=>false,
// ],
// ]
// )
?>
<?= $this->Form->hidden('id') ?>
<?= $this->Form->button(
__d("Forms",'Submit'),
[
"class"=>"btn btn-default btn-mapping",
"id"=>"taxonomyFormButton",
]
) ?>
</div>
<?= $this->Form->end() ?>
</section>
......@@ -1483,3 +1483,108 @@ section.taxonomyPages strong {
border-color: silver;
font-size: 1em;
}
/* =====================================================================================================================
* ---------------------------------------------- Mapping Form --------------------------------------------------------------
* =====================================================================================================================
*/
.taxonomyForm_step1_content {
/* max-width: 120em; */
margin-bottom: 2em;
}
@media (min-width: 768px) {
.taxonomyForm_step1_content {
display: flex;
justify-content: space-between;
}
}
.taxonomyForm_step1_content fieldset {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
min-width: 10em;
margin-right: 2em;
}
.taxonomyForm_step1_content > fieldset > legend {
display: block;
padding: 0;
font-size: 30px;
border-bottom: 1px silver solid;
text-decoration: none;
}
.taxonomyForm_step1_content fieldset div.checkbox {
margin: 0;
padding: 0;
}
.taxonomyForm_step1_content label {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.taxonomyForm_step1_content input[type="checkbox"] {
/* outline: 1px solid red;*/
/*border: 1px solid green;*/
/*-moz-appearance:none;*/
/*-webkit-appearance:none;*/
/*-o-appearance:none;*/
-webkit-box-shadow: 0px 0px 0px 1px #c0c0c0;;
-moz-box-shadow: 0px 0px 0px 1px #c0c0c0;;
box-shadow: 0px 0px 0px 1px #c0c0c0;;
}
/*
Can I change the checkbox size using CSS?
https://stackoverflow.com/questions/306924/can-i-change-the-checkbox-size-using-css
*/
@media (max-width: 1200px) {
.taxonomyForm_step1_content input[type="checkbox"] {
/* Double-sized Checkboxes */
-ms-transform: scale(2); /* IE */
-moz-transform: scale(2); /* FF */
-webkit-transform: scale(2); /* Safari and Chrome */
-o-transform: scale(2); /* Opera */
transform: scale(2);
-ms-transform: scale(1.5); /* IE */
-moz-transform: scale(1.5); /* FF */
-webkit-transform: scale(1.5); /* Safari and Chrome */
-o-transform: scale(1.5); /* Opera */
transform: scale(1.5);
margin-top: 0.5em;
padding: 10px;
}
}
@media (min-width: 1201px) {
.taxonomyForm_step1_content input[type="checkbox"] {
/* Double-sized Checkboxes */
-ms-transform: scale(1.5); /* IE */
-moz-transform: scale(1.5); /* FF */
-webkit-transform: scale(1.5); /* Safari and Chrome */
-o-transform: scale(1.5); /* Opera */
transform: scale(1.5);
margin-top: 0.5em;
padding: 10px;
}
}
#taxonomyFormButton {
margin-top: 1em;
/*margin-left: 10em;*/
border: 2px solid #D9D9DE;
font-size: 15px;
color: #FFFFFF;
text-decoration: #fff;
background-color: #2A874B;
box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.18);
width: 20em;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment