N°803 - Allow display & edition of attributes on n:n relations on Portal

- Remove input when object is in view mode
- Improve form errors handling
- Prevent row selection when clicking input 
- Attach date time picker to table instead of input to prevent popup truncating (popup will be visible but not aligned on the input)
This commit is contained in:
Benjamin Dalsass
2023-06-09 10:34:19 +02:00
parent 1b7529fcb9
commit c486aea299
21 changed files with 327 additions and 129 deletions

View File

@@ -75,6 +75,11 @@ p_object_get_information_json:
defaults:
_controller: 'Combodo\iTop\Portal\Controller\ObjectController::GetInformationAsJsonAction'
p_object_get_information_for_linked_set_json:
path: '/object/get-information-for-linked-set/json'
defaults:
_controller: 'Combodo\iTop\Portal\Controller\ObjectController::GetInformationForLinkedSetAsJsonAction'
p_object_document_display:
path: '/object/document/display/{sObjectClass}/{sObjectId}/{sObjectField}'
defaults:

View File

@@ -103,12 +103,6 @@ $(function()
oEvent.preventDefault();
var me = this;
// Prevent form submit if input in invalid state
// @see Bug N°803 - Allow display & edition of attributes on n:n relations on Portal
if($('input:invalid', this.element).length > 0){
return;
}
// EasterEgg : Vibrate on submit
if(window.navigator.vibrate)
{

View File

@@ -26,6 +26,7 @@ use AttributeFinalClass;
use AttributeFriendlyName;
use AttributeImage;
use BinaryExpression;
use Combodo\iTop\Form\Field\DateTimeField;
use Combodo\iTop\Portal\Brick\CreateBrick;
use Combodo\iTop\Portal\Helper\ApplicationHelper;
use Combodo\iTop\Portal\Helper\ContextManipulatorHelper;
@@ -1313,6 +1314,64 @@ class ObjectController extends BrickController
/** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator */
$oScopeValidator = $this->get('scope_validator');
$aData = array();
// Retrieving parameters
$sObjectClass = $oRequestManipulator->ReadParam('sObjectClass', '');
$aObjectIds = $oRequestManipulator->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW);
$aObjectAttCodes = $oRequestManipulator->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW);
if (empty($sObjectClass) || empty($aObjectIds) || empty($aObjectAttCodes)) {
IssueLog::Info(__METHOD__.' at line '.__LINE__.' : sObjectClass, aObjectIds and aObjectAttCodes expected, "'.$sObjectClass.'", "'.implode('/',
$aObjectIds).'" given.');
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Invalid request data, some information are missing');
}
// Building the search
$bIgnoreSilos = $oScopeValidator->IsAllDataAllowedForScope(UserRights::ListProfiles(), $sObjectClass);
$aParams = array('objects_id' => $aObjectIds);
$oSearch = DBObjectSearch::FromOQL("SELECT $sObjectClass WHERE id IN (:objects_id)");
if ($bIgnoreSilos === true) {
$oSearch->AllowAllData();
}
$oSet = new DBObjectSet($oSearch, array(), $aParams);
$oSet->OptimizeColumnLoad(array($oSearch->GetClassAlias() => $aObjectAttCodes));
// Checking that id is in the AttCodes
// Note: We do that AFTER the array is used in OptimizeColumnLoad() because the function doesn't support this anymore.
if (!in_array('id', $aObjectAttCodes)) {
$aObjectAttCodes = array_merge(array('id'), $aObjectAttCodes);
}
// Retrieving objects
while ($oObject = $oSet->Fetch()) {
$aData['items'][] = $this->PrepareObjectInformation($oObject, $aObjectAttCodes);
}
return new JsonResponse($aData);
}
/**
* GetInformationAsJsonAction for linked set usages.
*
* @param \Symfony\Component\HttpFoundation\Request $oRequest
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
*
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @throws \OQLException
* @throws \Exception
* @since 3.1
*
*/
public function GetInformationForLinkedSetAsJsonAction(Request $oRequest)
{
/** @var \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulator */
$oRequestManipulator = $this->get('request_manipulator');
/** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator */
$oScopeValidator = $this->get('scope_validator');
// Data array
$aData = array(
'js_inline' => '',
@@ -1325,6 +1384,7 @@ class ObjectController extends BrickController
$aObjectIds = $oRequestManipulator->ReadParam('aObjectIds', array(), FILTER_UNSAFE_RAW);
$aObjectAttCodes = $oRequestManipulator->ReadParam('aObjectAttCodes', array(), FILTER_UNSAFE_RAW);
$aLinkAttCodes = $oRequestManipulator->ReadParam('aLinkAttCodes', array(), FILTER_UNSAFE_RAW);
$sDateTimePickerWidgetParent = $oRequestManipulator->ReadParam('sDateTimePickerWidgetParent', array(), FILTER_SANITIZE_STRING);
if (empty($sObjectClass) || empty($aObjectIds) || empty($aObjectAttCodes)) {
IssueLog::Info(__METHOD__.' at line '.__LINE__.' : sObjectClass, aObjectIds and aObjectAttCodes expected, "'.$sObjectClass.'", "'.implode('/',
@@ -1358,6 +1418,10 @@ class ObjectController extends BrickController
foreach ($aLinkAttCodes as $sAttCode) {
$oAttDef = MetaModel::GetAttributeDef($sLinkClass, $sAttCode);
$oField = $oAttDef->MakeFormField($oNewLink);
// Prevent datetimepicker popup to be truncated
if ($oField instanceof DateTimeField) {
$oField->SetDateTimePickerWidgetParent($sDateTimePickerWidgetParent);
}
$sFieldRendererClass = BsLinkedSetFieldRenderer::GetFieldRendererClass($oField);
$sValue = $oAttDef->GetAsHTML($oNewLink->Get($sAttCode));
if ($sFieldRendererClass !== null) {

View File

@@ -751,7 +751,7 @@ class ObjectFormManager extends FormManager
if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\LinkedSetField'))) {
/** @var \Combodo\iTop\Form\Field\LinkedSetField $oField */
if ($this->oFormHandlerHelper !== null) {
$oField->SetInformationEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_get_information_json'));
$oField->SetInformationEndpoint($this->oFormHandlerHelper->GetUrlGenerator()->generate('p_object_get_information_for_linked_set_json'));
}
}
// - Field that require to apply scope on its DM OQL