diff --git a/amd/build/cardnumber.min.js b/amd/build/cardnumber.min.js index 13a03265..9be1dcd4 100644 --- a/amd/build/cardnumber.min.js +++ b/amd/build/cardnumber.min.js @@ -1,3 +1,3 @@ -define("mod_kanban/cardnumber",["exports"],(function(_exports){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;_exports.init=element=>{document.querySelectorAll("#"+element+" .mod_kanban_card_number").forEach((el=>{el.addEventListener("click",(event=>{document.querySelector('.mod_kanban_card[data-number="'.concat(event.target.dataset.id,'"] .mod_kanban_detail_trigger')).click()}))}))}})); +define("mod_kanban/cardnumber",["exports","core/notification","core/str"],(function(_exports,_notification,_str){Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0;_exports.init=element=>{document.querySelectorAll("#"+element+" .mod_kanban_card_number").forEach((el=>{el.addEventListener("click",(event=>{let card=document.querySelector('.mod_kanban_card[data-number="'.concat(event.target.dataset.id,'"] .mod_kanban_detail_trigger'));card?card.click():(0,_notification.alert)((0,_str.get_string)("cardnotfound","mod_kanban"))}))}))}})); //# sourceMappingURL=cardnumber.min.js.map \ No newline at end of file diff --git a/amd/build/cardnumber.min.js.map b/amd/build/cardnumber.min.js.map index 1b29c549..69378c91 100644 --- a/amd/build/cardnumber.min.js.map +++ b/amd/build/cardnumber.min.js.map @@ -1 +1 @@ -{"version":3,"file":"cardnumber.min.js","sources":["../src/cardnumber.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Add event listener to card number to open card detail.\n *\n * @module mod_kanban/cardnumber\n * @copyright 2024 ISB Bayern\n * @author Stefan Hanauska \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nexport const init = (element) => {\n document.querySelectorAll('#' + element + ' .mod_kanban_card_number').forEach((el) => {\n el.addEventListener('click', (event) => {\n document.querySelector(\n `.mod_kanban_card[data-number=\"${event.target.dataset.id}\"] .mod_kanban_detail_trigger`\n ).click();\n });\n });\n};\n"],"names":["element","document","querySelectorAll","forEach","el","addEventListener","event","querySelector","target","dataset","id","click"],"mappings":"0JAwBqBA,UACjBC,SAASC,iBAAiB,IAAMF,QAAU,4BAA4BG,SAASC,KAC3EA,GAAGC,iBAAiB,SAAUC,QAC1BL,SAASM,sDAC4BD,MAAME,OAAOC,QAAQC,qCACxDC"} \ No newline at end of file +{"version":3,"file":"cardnumber.min.js","sources":["../src/cardnumber.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Add event listener to card number to open card detail.\n *\n * @module mod_kanban/cardnumber\n * @copyright 2024 ISB Bayern\n * @author Stefan Hanauska \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {alert as displayAlert} from 'core/notification';\nimport {get_string as getString} from 'core/str';\n\nexport const init = (element) => {\n document.querySelectorAll('#' + element + ' .mod_kanban_card_number').forEach((el) => {\n el.addEventListener('click', (event) => {\n let card = document.querySelector(\n `.mod_kanban_card[data-number=\"${event.target.dataset.id}\"] .mod_kanban_detail_trigger`\n );\n if (card) {\n card.click();\n } else {\n displayAlert(getString('cardnotfound', 'mod_kanban'));\n }\n });\n });\n};\n"],"names":["element","document","querySelectorAll","forEach","el","addEventListener","event","card","querySelector","target","dataset","id","click"],"mappings":"4MA0BqBA,UACjBC,SAASC,iBAAiB,IAAMF,QAAU,4BAA4BG,SAASC,KAC3EA,GAAGC,iBAAiB,SAAUC,YACtBC,KAAON,SAASO,sDACiBF,MAAMG,OAAOC,QAAQC,qCAEtDJ,KACAA,KAAKK,iCAEQ,mBAAU,eAAgB"} \ No newline at end of file diff --git a/amd/src/cardnumber.js b/amd/src/cardnumber.js index 07bdac0e..3414a7e2 100644 --- a/amd/src/cardnumber.js +++ b/amd/src/cardnumber.js @@ -21,13 +21,20 @@ * @author Stefan Hanauska * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +import {alert as displayAlert} from 'core/notification'; +import {get_string as getString} from 'core/str'; export const init = (element) => { document.querySelectorAll('#' + element + ' .mod_kanban_card_number').forEach((el) => { el.addEventListener('click', (event) => { - document.querySelector( + let card = document.querySelector( `.mod_kanban_card[data-number="${event.target.dataset.id}"] .mod_kanban_detail_trigger` - ).click(); + ); + if (card) { + card.click(); + } else { + displayAlert(getString('cardnotfound', 'mod_kanban')); + } }); }); }; diff --git a/classes/boardmanager.php b/classes/boardmanager.php index dfc16cef..2332ddbc 100644 --- a/classes/boardmanager.php +++ b/classes/boardmanager.php @@ -931,13 +931,13 @@ public function update_card(int $cardid, array $data): void { ); helper::update_cached_timestamp($this->board->id, constants::MOD_KANBAN_CARD, $cardupdate['timemodified']); - if (!empty($this->kanban->usenumbers)) { + if (!empty($this->kanban->usenumbers) && !empty($this->kanban->linknumbers)) { if (isset($cardupdate['description'])) { $cardupdate['description'] = numberfilter::filter($cardupdate['description']); } } - $this->formatter->put('cards', $cardupdate); + $this->formatter->put('cards', $cardupdate, false); } /** diff --git a/classes/external/get_kanban_content.php b/classes/external/get_kanban_content.php index 1986c5cd..124a587d 100644 --- a/classes/external/get_kanban_content.php +++ b/classes/external/get_kanban_content.php @@ -548,7 +548,7 @@ public static function execute(int $cmid, int $boardid, int $timestamp = 0, bool 'attachments', $card->id ); - if ($common->usenumbers) { + if ($common->usenumbers && $common->linknumbers) { $card->description = numberfilter::filter($card->description); } $card->attachments = helper::get_attachments($context->id, $card->id); @@ -642,7 +642,8 @@ public static function get_discussion_update(int $cmid, int $boardid, int $cardi self::validate_context($context); require_capability('mod/kanban:view', $context); - $kanbanboard = helper::get_cached_board($boardid); + $boardmanager = new boardmanager($cmid, $boardid); + $kanbanboard = $boardmanager->get_board(); helper::check_permissions_for_user_or_group($kanbanboard, $context, $cminfo, constants::MOD_KANBAN_VIEW); @@ -657,7 +658,10 @@ public static function get_discussion_update(int $cmid, int $boardid, int $cardi $discussion->content = format_text($discussion->content, FORMAT_HTML); $discussion->candelete = $discussion->userid == $USER->id || has_capability('mod/kanban:manageboard', $context); $discussion->username = fullname(\core_user::get_user($discussion->userid)); - $formatter->put('discussions', (array) $discussion); + if (!empty($boardmanager->kanban->usenumbers) && !empty($boardmanager->kanban->linknumbers)) { + $discussion->content = numberfilter::filter($discussion->content); + } + $formatter->put('discussions', (array) $discussion, false); } return [ 'update' => $formatter->get_formatted_updates(), diff --git a/classes/numberfilter.php b/classes/numberfilter.php index ac3a3d67..a27c8a94 100644 --- a/classes/numberfilter.php +++ b/classes/numberfilter.php @@ -40,7 +40,7 @@ public static function filter(string $text): string { $pattern = '/#(\d+)/'; $text = preg_replace_callback($pattern, function ($matches) { $number = (int)$matches[1]; - return '#' . $number . ''; + return '#' . $number . ''; }, $text); return $text; } diff --git a/classes/updateformatter.php b/classes/updateformatter.php index adbaeb5e..9b7b5597 100644 --- a/classes/updateformatter.php +++ b/classes/updateformatter.php @@ -49,10 +49,13 @@ class updateformatter { * * @param string $name Name of the value to update * @param array $data Fields to update, must contain 'id' field + * @param bool $sanitize Sanitize the output */ - public function put(string $name, array $data) { + public function put(string $name, array $data, bool $sanitize = true) { // Sanitize the output. - $data = json_decode(helper::sanitize_json_string(json_encode($data)), true); + if ($sanitize) { + $data = json_decode(helper::sanitize_json_string(json_encode($data)), true); + } // Find int values covered as string. foreach ($data as $key => $value) { if ($key == 'sequence') { diff --git a/db/install.xml b/db/install.xml index ee1d6ca4..21a163a2 100755 --- a/db/install.xml +++ b/db/install.xml @@ -1,5 +1,5 @@ - @@ -14,6 +14,7 @@ + diff --git a/db/upgrade.php b/db/upgrade.php index 255c487d..9cb1fd39 100755 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -32,8 +32,8 @@ function xmldb_kanban_upgrade($oldversion) { global $DB; $dbman = $DB->get_manager(); - if ($oldversion < 2024032701) { - // Define field usenumbers to be added to kanban. + if ($oldversion < 2024120501) { + // Define field usenumbers to be added to table kanban. $table = new xmldb_table('kanban'); $field = new xmldb_field('usenumbers', XMLDB_TYPE_INTEGER, '2', null, null, null, '0', 'history'); @@ -42,7 +42,15 @@ function xmldb_kanban_upgrade($oldversion) { $dbman->add_field($table, $field); } - // Define field number to be added to kanban_card. + // Define field linknumbers to be added to table kanban. + $field = new xmldb_field('linknumbers', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'usenumbers'); + + // Conditionally launch add field linknumbers. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Define field number to be added to table kanban_card. $table = new xmldb_table('kanban_card'); $field = new xmldb_field('number', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', 'timemodified'); @@ -64,9 +72,10 @@ function xmldb_kanban_upgrade($oldversion) { } $DB->set_field('kanban_card', 'number', $nextnumber, ['id' => $card->id]); } + $cards->close(); // Kanban savepoint reached. - upgrade_mod_savepoint(true, 2024032701, 'kanban'); + upgrade_mod_savepoint(true, 2024120501, 'kanban'); } return true; } diff --git a/lang/en/kanban.php b/lang/en/kanban.php index 570a8239..c3d2f8b6 100644 --- a/lang/en/kanban.php +++ b/lang/en/kanban.php @@ -35,6 +35,7 @@ $string['autohide'] = 'Auto hide closed cards'; $string['cachedef_board'] = 'Cache for a board instance'; $string['cachedef_timestamp'] = 'Timestamp of last modification of card, column or board instance'; +$string['cardnotfound'] = 'Card not found'; $string['cardtitle'] = 'Card title'; $string['changegroup'] = 'Change group board'; $string['changeuser'] = 'Change user board'; @@ -97,6 +98,8 @@ $string['kanban:view'] = 'View a Kanban board'; $string['kanban:viewallboards'] = 'View all boards'; $string['kanban:viewhistory'] = 'View the history of the board'; +$string['linknumbers'] = 'Link card numbers'; +$string['linknumbers_help'] = 'Card numbers in card descriptions and discussion comments will be linked.'; $string['liveupdatetime'] = 'Interval for live update in seconds'; $string['liveupdatetimedescription'] = 'Boards will look for updates after this interval. Set to 0 to disable live update.'; $string['loading'] = 'Loading kanban board'; diff --git a/mod_form.php b/mod_form.php index a53dd3e5..41090aa3 100644 --- a/mod_form.php +++ b/mod_form.php @@ -59,8 +59,13 @@ public function definition(): void { $mform->addHelpButton('history', 'enablehistory', 'mod_kanban'); } - $mform->addElement('advcheckbox', 'usenumbers', get_string('usenumbers', 'kanban')); - $mform->addHelpButton('usenumbers', 'usenumbers', 'kanban'); + $mform->addElement('advcheckbox', 'usenumbers', get_string('usenumbers', 'mod_kanban')); + $mform->addHelpButton('usenumbers', 'usenumbers', 'mod_kanban'); + + $mform->addElement('advcheckbox', 'linknumbers', get_string('linknumbers', 'mod_kanban')); + $mform->addHelpButton('linknumbers', 'linknumbers', 'mod_kanban'); + $mform->hideIf('linknumbers', 'usenumbers', 'notchecked'); + $mform->setDefault('linknumbers', 1); $this->standard_coursemodule_elements(); diff --git a/styles.css b/styles.css index 58f10994..1426215e 100644 --- a/styles.css +++ b/styles.css @@ -308,7 +308,7 @@ a.mod_kanban_attachment_item { .mod_kanban_board:not(.mod_kanban_manageallcards):not(.mod_kanban_manageassignedcards) .mod_kanban_card:not(.mod_kanban_canedit) .mod_kanban_uncomplete_card, .mod_kanban_board:not(.mod_kanban_manageallcards):not(.mod_kanban_manageassignedcards) .mod_kanban_card:not(.mod_kanban_canedit) .mod_kanban_move_card, .mod_kanban_board:not(.mod_kanban_history) .mod_kanban_card_view_history, -.mod_kanban_board:not(.mod_kanban_usenumbers) .mod_kanban_number, +.mod_kanban_board:not(.mod_kanban_usenumbers) .mod_kanban_card_number, .mod_kanban_board.mod_kanban_manageassignedcards:not(.mod_kanban_manageallcards) .mod_kanban_card:not(.mod_kanban_selfassigned) .mod_kanban_complete_card, .mod_kanban_board.mod_kanban_manageassignedcards:not(.mod_kanban_manageallcards) .mod_kanban_card:not(.mod_kanban_selfassigned) @@ -442,15 +442,7 @@ a.mod_kanban_attachment_item { display: none; } -.mod_kanban_number { - font-weight: bold; -} - .mod_kanban_card_number { cursor: pointer; font-weight: bold; } - -.mod_kanban_card_number::before { - background-image: url([[pix:i/show]]); -} diff --git a/templates/card.mustache b/templates/card.mustache index 4049b9db..69c8f8c1 100644 --- a/templates/card.mustache +++ b/templates/card.mustache @@ -33,7 +33,7 @@ }}