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 @@
}}