1/** 2 * --------------------------------------------------------------------- 3 * 4 * GLPI - Gestionnaire Libre de Parc Informatique 5 * 6 * http://glpi-project.org 7 * 8 * @copyright 2015-2026 Teclib' and contributors. 9 * @copyright 2003-2014 by the INDEPNET Development Team. 10 * @licence https://www.gnu.org/licenses/gpl-3.0.html 11 * 12 * --------------------------------------------------------------------- 13 * 14 * LICENSE 15 * 16 * This file is part of GLPI. 17 * 18 * This program is free software: you can redistribute it and/or modify 19 * it under the terms of the GNU General Public License as published by 20 * the Free Software Foundation, either version 3 of the License, or 21 * (at your option) any later version. 22 * 23 * This program is distributed in the hope that it will be useful, 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 * GNU General Public License for more details. 27 * 28 * You should have received a copy of the GNU General Public License 29 * along with this program. If not, see <https://www.gnu.org/licenses/>. 30 * 31 * --------------------------------------------------------------------- 32 */ 33 34/* global glpi_confirm, glpi_alert, getAjaxCsrfToken */ 35/* global _ */ 36 37/** 38 * @todo Candidate for a websocket-based feature (or a mix of Ajax + Server-Sent Events) 39 */ 40class ObjectLock { 41 /** 42 * @param {{id: number, itemtype: string, itemtype_name: string, items_id: number}} lock 43 * @param {{name: string}} user_data 44 * @param {boolean} new_lock Was the item locked by the current user during this page request? 45 */ 46 constructor(lock, user_data, new_lock = false) { 47 this.lock = lock; 48 this.user_data = user_data; 49 this.new_lock = new_lock; 50 this.lockStatusTimer = undefined; 51 this.#registerListeners(); 52 } 53 54 #registerListeners() { 55 $('#alertMe').on('change', (e) => { 56 const checked = e.target.checked; 57 if (checked) { 58 this.lockStatusTimer = setInterval(() => { 59 $.get({ 60 url: `${CFG_GLPI.root_doc}/ajax/unlockobject.php`, 61 cache: false, 62 data: { 63 lockstatus: 1, 64 id: this.lock.id 65 }, 66 }).then((data) => { 67 if (data === 0) { 68 clearInterval(this.lockStatusTimer); 69 glpi_confirm({ 70 title: __('Item unlocked!'), 71 message: __('Reload page?'), 72 confirm_callback: () => { 73 window.location.reload(); 74 } 75 }); 76 } 77 }); 78 }, 15000); 79 } else { 80 clearInterval(this.lockStatusTimer); 81 } 82 }); 83 84 $('button.ask-unlock-item').on('click', () => { 85 glpi_confirm({ 86 title: `${_.escape(this.lock.itemtype_name)} #${_.escape(this.lock.items_id)}`, 87 message: __('Ask for unlock this item?'), 88 confirm_callback: () => { 89 $.post({ 90 url: `${CFG_GLPI.root_doc}/ajax/unlockobject.php`, 91 cache: false, 92 data: { 93 requestunlock: 1, 94 id: this.lock.id 95 }, 96 dataType: 'json' 97 }).then(() => { 98 glpi_alert({ 99 title: __('Unlock request sent!'), 100 message: __('Request sent to %s').replace('%s', _.escape(this.user_data['name'])), 101 }); 102 }, () => { 103 glpi_alert({ 104 title: _n('Error', 'Errors', 1), 105 message: __('An error occurred while sending the unlock request'), 106 }); 107 }); 108 } 109 }); 110 }); 111 112 $('button.force-unlock-item').on('click', () => { 113 glpi_confirm({ 114 title: `${this.lock.itemtype_name} #${this.lock.items_id}`, 115 message: __('Force unlock this item?'), 116 confirm_callback: () => { 117 $.post({
118 url: `${CFG_GLPI.root_doc}/ajax/unlockobject.php`, 119 cache: false, 120 data: { 121 unlock: 1, 122 force: 1, 123 id: this.lock.id, 124 }, 125 dataType: 'json' 126 }).then(() => { 127 glpi_confirm({ 128 title: __('Item unlocked!'), 129 message: __('Reload page?'), 130 confirm_callback: () => { 131 window.location.reload(); 132 } 133 }); 134 }, () => { 135 glpi_alert({ 136 title: __('Item NOT unlocked!'), 137 message: __('Contact your GLPI admin!'), 138 }); 139 }); 140 } 141 }); 142 }); 143 144 if (this.new_lock) { 145 $(window).on('beforeunload', () => { 146 const fallback_request = () => { 147 $.post({ 148 url: `${CFG_GLPI.root_doc}/ajax/unlockobject.php`, 149 async: false, 150 cache: false, 151 data: { 152 unlock: 1, 153 id: this.lock.id 154 }, 155 dataType: 'json' 156 }); 157 }; 158 159 if (typeof window.fetch !== 'undefined') { 160 fetch(`${CFG_GLPI.root_doc}/ajax/unlockobject.php`, { 161 method: 'POST', 162 cache: 'no-cache', 163 headers: { 164 'Accept': 'application/json', 165 'Content-Type': 'application/x-www-form-urlencoded;', 166 'X-Requested-With': 'XMLHttpRequest', 167 'X-Glpi-Csrf-Token': getAjaxCsrfToken(), 168 }, 169 body: `unlock=1&id=${this.lock.id}` 170 }).catch(() => { 171 //fallback if fetch fails 172 fallback_request(); 173 }); 174 } else { 175 //fallback for browsers with no fetch support 176 fallback_request(); 177 } 178 }); 179 } 180 } 181} 182 183export function initObjectLock(lock, user_data, new_lock = false) { 184 new ObjectLock(lock, user_data, new_lock); 185}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.