From 3885218f487b1ee9cc03ab656220462302d446cd Mon Sep 17 00:00:00 2001 From: Lukas Eichenauer Date: Mon, 11 May 2026 12:21:51 +0200 Subject: [PATCH 1/2] ObjectGroup: Add New Object Action for Object Groups See: https://docu.ilias.de/go/wiki/wpage_8622_1357 Implement a new async command to the object group list gui to create and add a new object inside an object group. --- .../src/Creation/AddNewItemGUI.php | 37 +++++++++----- .../classes/class.ilObjItemGroupAccess.php | 12 ++--- .../classes/class.ilObjItemGroupGUI.php | 32 +++++++----- .../classes/class.ilObjItemGroupListGUI.php | 49 +++++++++++++++++-- lang/ilias_de.lang | 2 + lang/ilias_en.lang | 4 +- 6 files changed, 98 insertions(+), 38 deletions(-) diff --git a/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php b/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php index d5f26b53029a..7fdc2b4996c2 100755 --- a/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php +++ b/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php @@ -20,6 +20,10 @@ namespace ILIAS\ILIASObject\Creation; +use ILIAS\UI\Component\Clickable; +use ILIAS\UI\Component\Divider\Horizontal; +use ILIAS\UI\Component\Menu\Sub; +use ILIAS\UI\Component\Modal\RoundTrip; use ILIAS\UI\Factory as UIFactory; use ILIAS\UI\Renderer as UIRenderer; @@ -31,10 +35,6 @@ class AddNewItemGUI { private \ilLanguage $lng; - private \ilObjectDefinition $obj_definition; - private \ilSetting $settings; - private \ilAccessHandler $access; - private \ilCtrl $ctrl; private \ilToolbarGUI $toolbar; private \ilGlobalTemplateInterface $tpl; @@ -42,7 +42,7 @@ class AddNewItemGUI private UIRenderer $ui_renderer; /** - * @param array $elements + * @param array $elements * The Key MUST contain the object type or the */ public function __construct( @@ -58,21 +58,31 @@ public function __construct( $this->ui_renderer = $DIC['ui.renderer']; } - /** - * Add new item selection to current page incl. toolbar (trigger) and overlay - */ - public function render(): void + public function createModal(): ?RoundTrip { if ($this->elements === []) { - return; + return null; } - $modal = $this->ui_factory->modal()->roundtrip( + + return $this->ui_factory->modal()->roundtrip( $this->lng->txt('cntr_add_new_item'), $this->ui_factory->menu()->drilldown( $this->lng->txt('object_list'), $this->buildAddNewItemsMenu($this->elements) ) ); + } + + /** + * Add new item selection to current page incl. toolbar (trigger) and overlay + */ + public function render(): void + { + $modal = $this->createModal(); + + if ($modal === null) { + return; + } $this->toolbar->addComponent( $this->ui_factory->button()->primary( @@ -87,7 +97,8 @@ public function render(): void } /** - * @return array + * @param array $elements + * @return ?array */ private function buildAddNewItemsMenu(array $elements): ?array { @@ -99,6 +110,7 @@ private function buildAddNewItemsMenu(array $elements): ?array $element->getLabel(), $this->buildAddNewItemsMenu($element->getSubElements()) ); + continue; } if ($element->getType() === AddNewItemElementTypes::Object) { $sub_menu[] = $this->ui_factory->link()->bulky( @@ -106,7 +118,6 @@ private function buildAddNewItemsMenu(array $elements): ?array $element->getLabel(), $element->getCreationUri() ); - continue; } } diff --git a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupAccess.php b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupAccess.php index bf1dcd297b75..fd8ea4242117 100755 --- a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupAccess.php +++ b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupAccess.php @@ -42,13 +42,13 @@ public static function _getCommands(): array global $DIC; $DIC->language()->loadLanguageModule("itgr"); - $commands = array( - array("permission" => "read", "cmd" => "gotoParent", "lang_var" => "", "default" => true), - array("permission" => "write", "cmd" => "listMaterials", "lang_var" => "itgr_assign_materials", "default" => false), - array("permission" => "write", "cmd" => "edit", "lang_var" => "settings", "default" => false) - ); - return $commands; + return [ + ["permission" => "read", "cmd" => "gotoParent", "lang_var" => "", "default" => true], + ["permission" => "write", "cmd" => "addOrAssignObject", "lang_var" => "itgr_create_and_assign_object", "default" => false], + ["permission" => "write", "cmd" => "listMaterials", "lang_var" => "itgr_assign_materials", "default" => false], + ["permission" => "write", "cmd" => "edit", "lang_var" => "settings", "default" => false] + ]; } public function _checkAccess(string $cmd, string $permission, int $ref_id, int $obj_id, ?int $user_id = null): bool diff --git a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php index 96e79d84cd10..85baa1a94d2e 100755 --- a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php +++ b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php @@ -16,6 +16,7 @@ * *********************************************************************/ +use ILIAS\ILIASObject\Creation\AddNewItemGUI; use ILIAS\ItemGroup\StandardGUIRequest; use ILIAS\ILIASObject\Properties\Translations\TranslationGUI; @@ -225,30 +226,35 @@ protected function afterUpdate(): void public function listMaterials(): void { - $tree = $this->tree; - $ilTabs = $this->tabs; - $tpl = $this->tpl; - $this->checkPermission("write"); - $ilTabs->activateTab("materials"); + $this->tabs->activateTab("materials"); - $parent_ref_id = $tree->getParentId($this->object->getRefId()); + $parent_ref_id = $this->tree->getParentId($this->object->getRefId()); $parent_type = ilObject::_lookupType($parent_ref_id, true); - $parent_gui_class = 'ilObj' . $this->obj_definition->getClassName($parent_type) . 'GUI'; + $parent_gui_class = "ilObj{$this->obj_definition->getClassName($parent_type)}GUI"; $this->ctrl->setParameterByClass($parent_gui_class, 'ref_id', $parent_ref_id); - $gui = new ILIAS\ILIASObject\Creation\AddNewItemGUI( + $add_new_item_gui = $this->resolveAddNewItemGUI(); + $add_new_item_gui->render(); + $this->ctrl->clearParameterByClass($parent_gui_class, 'ref_id'); + + $tab = new ilItemGroupItemsTableGUI($this->gui, $this, "listMaterials"); + $this->tpl->setContent($tab->getHTML()); + } + + public function resolveAddNewItemGUI(): AddNewItemGUI + { + $parent_ref_id = $this->tree->getParentId($this->object->getRefId()); + $parent_type = ilObject::_lookupType($parent_ref_id, true); + $parent_gui_class = "ilObj{$this->obj_definition->getClassName($parent_type)}GUI"; + + return new AddNewItemGUI( $this->buildAddNewItemElements( $this->getCreatableObjectTypes(), $parent_gui_class, $this->object->getRefId() ) ); - $gui->render(); - $this->ctrl->clearParameterByClass($parent_gui_class, 'ref_id'); - - $tab = new ilItemGroupItemsTableGUI($this->gui, $this, "listMaterials"); - $tpl->setContent($tab->getHTML()); } public function getCreatableObjectTypes(): array diff --git a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupListGUI.php b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupListGUI.php index 30147facb891..e6efe8ad8629 100755 --- a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupListGUI.php +++ b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupListGUI.php @@ -16,6 +16,9 @@ * *********************************************************************/ +use ILIAS\ILIASObject\Creation\AddNewItemGUI; +use ILIAS\UI\Component\Modal\RoundTrip; + /** * Item group list gui class * @author Alexander Killing @@ -24,6 +27,8 @@ class ilObjItemGroupListGUI extends ilObjectListGUI { protected bool $subitems_enabled; + private ?RoundTrip $add_new_object_modal; + public function __construct() { global $DIC; @@ -52,6 +57,13 @@ public function init(): void $this->commands = ilObjItemGroupAccess::_getCommands(); } + public function initItem(int $ref_id, int $obj_id, string $type, string $title = '', string $description = ''): void + { + parent::initItem($ref_id, $obj_id, $type, $title, $description); // TODO: Change the autogenerated stub + + $this->add_new_object_modal = new ilObjItemGroupGUI($ref_id)->resolveAddNewItemGUI()->createModal(); + } + public function enableSubscribe(bool $status): void { $this->subscribe_enabled = false; @@ -66,14 +78,41 @@ public function enableInfoScreen(bool $info_screen): void $this->info_screen_enabled = false; } + public function getCommandsHTML(string $title = ''): string + { + if ($this->add_new_object_modal === null) { + return parent::getCommandsHTML($title); + } + + return parent::getCommandsHTML($title) . $this->ui->renderer()->render($this->add_new_object_modal); + } + + public function insertCommand( + string $href, + string $text, + string $frame = '', + string $img = '', + string $cmd = '', + string $onclick = '' + ): void { + if ($cmd === 'addOrAssignObject') { + $this->current_actions[] = $this->ui->factory()->button()->shy( + $this->lng->txt('itgr_create_and_assign_object'), + '#' + )->withOnClick($this->add_new_object_modal->getShowSignal()); + + return; + } + + parent::insertCommand($href, $text, $frame, $img, $cmd, $onclick); + } + public function getCommandLink(string $cmd): string { - $ilCtrl = $this->ctrl; + $this->ctrl->setParameterByClass(ilRepositoryGUI::class, "ref_id", $this->ref_id); + $cmd_link = $this->ctrl->getLinkTargetByClass(ilRepositoryGUI::class, $cmd); + $this->ctrl->setParameterByClass(ilRepositoryGUI::class, "ref_id", $this->requested_ref_id); - // separate method for this line - $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $this->ref_id); - $cmd_link = $ilCtrl->getLinkTargetByClass("ilrepositorygui", $cmd); - $ilCtrl->setParameterByClass("ilrepositorygui", "ref_id", $this->requested_ref_id); return $cmd_link; } diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index aa93b38588d9..966456c9e0d8 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -10770,6 +10770,7 @@ itgr#:#itgr_assigned_materials#:#Objekte im Objekteblock itgr#:#itgr_assignment#:#Eingebunden itgr#:#itgr_behaviour#:#Verhalten itgr#:#itgr_behaviour_info#:#Das System merkt sich den Zustand (geöffnet/geschlossen) je Benutzer bis zur Abmeldung (Logout). +itgr#:#itgr_create_and_assign_object#:#Objekt erstellen und zuweisen itgr#:#itgr_desc_info#:#Die Beschreibung wird bei der Anzeige des Objekteblocks nicht mit ausgegeben. itgr#:#itgr_edit#:#Einstellungen des Objekteblocks itgr#:#itgr_expandable_closed#:#Ausklappbar (zunächst geschlossen) @@ -10780,6 +10781,7 @@ itgr#:#itgr_list_default#:#Standard itgr#:#itgr_list_default_info#:#Übernimmt die Einstellung des übergeordneten Containers. itgr#:#itgr_list_presentation#:#Präsentationsansicht für Inhalte itgr#:#itgr_materials#:#Objekte +itgr#:#itgr_organise_objects#:#Objekte verwalten itgr#:#itgr_show_title#:#Titel anzeigen itgr#:#itgr_show_title_info#:#Der Titel des Objekteblocks wird angezeigt. itgr#:#itgr_tile#:#Kacheln diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index fec96911362f..59464acd8ea4 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -10739,11 +10739,12 @@ irss#:#type#:#File Type irss#:#upload_field_title#:#Selected Files irss#:#upload_modal_title#:#Add Files itgr#:#itgr_always_open#:#Always Open -itgr#:#itgr_assign_materials#:#Assign Materials +itgr#:#itgr_assign_materials#:#Organize Objects itgr#:#itgr_assigned_materials#:#Assigned Materials itgr#:#itgr_assignment#:#Assigned itgr#:#itgr_behaviour#:#Block Behaviour itgr#:#itgr_behaviour_info#:#The system will store the opened/closed state for the current user until logout. +itgr#:#itgr_create_and_assign_object#:#Create and Assign Object itgr#:#itgr_desc_info#:#The description will not be a part of the item group's presentation in its container. itgr#:#itgr_edit#:#Edit Item Groups itgr#:#itgr_expandable_closed#:#Expandable (initially closed) @@ -10754,6 +10755,7 @@ itgr#:#itgr_list_default#:#Default itgr#:#itgr_list_default_info#:#Inherits value from upper container. itgr#:#itgr_list_presentation#:#Item Presentation itgr#:#itgr_materials#:#Materials +itgr#:#itgr_organise_objects#:#Manage Objects itgr#:#itgr_show_title#:#Show Title itgr#:#itgr_show_title_info#:#Shows title of item group in presentation for learner. itgr#:#itgr_tile#:#Tiles From 5606efb05529027bdc85ee5310b330da10988666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Jou=C3=9Fen?= Date: Mon, 8 Jun 2026 14:50:26 +0200 Subject: [PATCH 2/2] ILIASObject: Rename AddNewItemGUI::render to AddNewItemGUI::renderToolbarAction This change is related to Feature-Request https://docu.ilias.de/go/wiki/wpage_8622_1357 and the discussion inside https://github.com/ILIAS-eLearning/ILIAS/pull/11549. To prevent context missmatch, a more descriptive name is chosen. --- components/ILIAS/Container/classes/class.ilContainerGUI.php | 2 +- components/ILIAS/Course/classes/class.ilObjCourseGUI.php | 2 +- .../classes/class.ilObjTalkTemplateAdministrationGUI.php | 2 +- components/ILIAS/Folder/classes/class.ilObjFolderGUI.php | 2 +- components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php | 2 +- components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php | 2 +- .../LearningSequence/classes/class.ilObjLearningSequenceGUI.php | 2 +- components/ILIAS/OrgUnit/classes/class.ilObjOrgUnitGUI.php | 2 +- components/ILIAS/Session/classes/class.ilObjSessionGUI.php | 2 +- .../WorkspaceFolder/classes/class.ilObjWorkspaceFolderGUI.php | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/ILIAS/Container/classes/class.ilContainerGUI.php b/components/ILIAS/Container/classes/class.ilContainerGUI.php index 0a7f7154ccc0..c62367e55a1c 100755 --- a/components/ILIAS/Container/classes/class.ilContainerGUI.php +++ b/components/ILIAS/Container/classes/class.ilContainerGUI.php @@ -347,7 +347,7 @@ protected function showPossibleSubObjects(): void $gui = new ILIAS\ILIASObject\Creation\AddNewItemGUI( $this->buildAddNewItemElements($this->getCreatableObjectTypes()) ); - $gui->render(); + $gui->renderToolbarAction(); } public function getContentGUI(): ilContainerContentGUI diff --git a/components/ILIAS/Course/classes/class.ilObjCourseGUI.php b/components/ILIAS/Course/classes/class.ilObjCourseGUI.php index 8ff7f3897435..a3d7118c4566 100755 --- a/components/ILIAS/Course/classes/class.ilObjCourseGUI.php +++ b/components/ILIAS/Course/classes/class.ilObjCourseGUI.php @@ -1533,7 +1533,7 @@ public function renderAddNewItem(string ...$disabled_object_types): void $gui = new ILIAS\ILIASObject\Creation\AddNewItemGUI( $this->buildAddNewItemElements($createble_object_types) ); - $gui->render(); + $gui->renderToolbarAction(); } /** diff --git a/components/ILIAS/EmployeeTalk/classes/class.ilObjTalkTemplateAdministrationGUI.php b/components/ILIAS/EmployeeTalk/classes/class.ilObjTalkTemplateAdministrationGUI.php index bb23d15496b5..47e93f713415 100755 --- a/components/ILIAS/EmployeeTalk/classes/class.ilObjTalkTemplateAdministrationGUI.php +++ b/components/ILIAS/EmployeeTalk/classes/class.ilObjTalkTemplateAdministrationGUI.php @@ -131,7 +131,7 @@ protected function showPossibleSubObjects(): void $subtypes )] ); - $gui->render(); + $gui->renderToolbarAction(); } protected function getCreatableObjectTypes(): array diff --git a/components/ILIAS/Folder/classes/class.ilObjFolderGUI.php b/components/ILIAS/Folder/classes/class.ilObjFolderGUI.php index f54467f4d02a..ccae1487dd52 100755 --- a/components/ILIAS/Folder/classes/class.ilObjFolderGUI.php +++ b/components/ILIAS/Folder/classes/class.ilObjFolderGUI.php @@ -539,7 +539,7 @@ protected function showPossibleSubObjects(): void $this->getCreatableObjectTypes() ) ); - $gui->render(); + $gui->renderToolbarAction(); } diff --git a/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php b/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php index 7fdc2b4996c2..06a1efb8146f 100755 --- a/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php +++ b/components/ILIAS/ILIASObject/src/Creation/AddNewItemGUI.php @@ -76,7 +76,7 @@ public function createModal(): ?RoundTrip /** * Add new item selection to current page incl. toolbar (trigger) and overlay */ - public function render(): void + public function renderToolbarAction(): void { $modal = $this->createModal(); diff --git a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php index 85baa1a94d2e..e93e012fd9be 100755 --- a/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php +++ b/components/ILIAS/ItemGroup/classes/class.ilObjItemGroupGUI.php @@ -235,7 +235,7 @@ public function listMaterials(): void $parent_gui_class = "ilObj{$this->obj_definition->getClassName($parent_type)}GUI"; $this->ctrl->setParameterByClass($parent_gui_class, 'ref_id', $parent_ref_id); $add_new_item_gui = $this->resolveAddNewItemGUI(); - $add_new_item_gui->render(); + $add_new_item_gui->renderToolbarAction(); $this->ctrl->clearParameterByClass($parent_gui_class, 'ref_id'); $tab = new ilItemGroupItemsTableGUI($this->gui, $this, "listMaterials"); diff --git a/components/ILIAS/LearningSequence/classes/class.ilObjLearningSequenceGUI.php b/components/ILIAS/LearningSequence/classes/class.ilObjLearningSequenceGUI.php index d2c237b77efe..4ebf180b4cb9 100755 --- a/components/ILIAS/LearningSequence/classes/class.ilObjLearningSequenceGUI.php +++ b/components/ILIAS/LearningSequence/classes/class.ilObjLearningSequenceGUI.php @@ -895,7 +895,7 @@ public function showPossibleSubObjects(): void $this->ref_id ) ); - $gui->render(); + $gui->renderToolbarAction(); $this->ctrl->clearParametersByClass(ilRepositoryGUI::class); } diff --git a/components/ILIAS/OrgUnit/classes/class.ilObjOrgUnitGUI.php b/components/ILIAS/OrgUnit/classes/class.ilObjOrgUnitGUI.php index f5e72dd7a084..9a512d1331cf 100755 --- a/components/ILIAS/OrgUnit/classes/class.ilObjOrgUnitGUI.php +++ b/components/ILIAS/OrgUnit/classes/class.ilObjOrgUnitGUI.php @@ -436,7 +436,7 @@ protected function showPossibleSubObjects(): void $subtypes )] ); - $gui->render(); + $gui->renderToolbarAction(); } public function getCreatableObjectTypes(): array diff --git a/components/ILIAS/Session/classes/class.ilObjSessionGUI.php b/components/ILIAS/Session/classes/class.ilObjSessionGUI.php index 8c8a59209080..29344f90f33e 100755 --- a/components/ILIAS/Session/classes/class.ilObjSessionGUI.php +++ b/components/ILIAS/Session/classes/class.ilObjSessionGUI.php @@ -1118,7 +1118,7 @@ public function materialsObject(): void $this->object->getRefId() ) ); - $gui->render(); + $gui->renderToolbarAction(); $this->ctrl->clearParameterByClass($parent_gui_class, 'ref_id'); $this->event_items = new ilEventItems($this->object->getId()); diff --git a/components/ILIAS/WorkspaceFolder/classes/class.ilObjWorkspaceFolderGUI.php b/components/ILIAS/WorkspaceFolder/classes/class.ilObjWorkspaceFolderGUI.php index 7eecd90df081..03f2c096987a 100755 --- a/components/ILIAS/WorkspaceFolder/classes/class.ilObjWorkspaceFolderGUI.php +++ b/components/ILIAS/WorkspaceFolder/classes/class.ilObjWorkspaceFolderGUI.php @@ -216,7 +216,7 @@ public function render(): void $gui = new ILIAS\ILIASObject\Creation\AddNewItemGUI( $this->buildAvailableObjectTypes() ); - $gui->render(); + $gui->renderToolbarAction(); ilObjectListGUI::prepareJsLinks( "",