mirror of https://git.48k.eu/ogcp
js: add ogStorage to prevent localStorage key collission
Define ogStorage class to manage the localStorage operations. The new keys are constructed with the following structure: "group-context-id" Where group is either "show" for the collapsed items in the sidebar, or "check" for the selected checkboxes of the sidebar. Add sotrage versioning to delete obsolete localStorage when a new design for the storage is included in ogCP.master
parent
7296372e9c
commit
f03077edb7
|
@ -3,6 +3,61 @@ const macs = new Map();
|
|||
const Interval = 1000;
|
||||
let updateTimeoutId = null;
|
||||
|
||||
const StorageGroup = Object.freeze({
|
||||
SHOW: 'show',
|
||||
CHECK: 'check',
|
||||
});
|
||||
|
||||
class ogStorage {
|
||||
static STORAGE_VERSION = Object.freeze(1);
|
||||
|
||||
static store(group, context, elemId, value) {
|
||||
const key = `${group}-${context}-${elemId}`;
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
static remove(group, context, elemId) {
|
||||
const key = `${group}-${context}-${elemId}`;
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
static hasKey(group, context, elemId) {
|
||||
const key = `${group}-${context}-${elemId}`;
|
||||
return localStorage.getItem(key) !== null;
|
||||
}
|
||||
|
||||
static deleteInvalidStorage(items, group, context) {
|
||||
if (localStorage.getItem('storageVersion') < ogStorage.STORAGE_VERSION) {
|
||||
localStorage.clear();
|
||||
localStorage.setItem('storageVersion', ogStorage.STORAGE_VERSION);
|
||||
return
|
||||
}
|
||||
|
||||
const prefix = `${group}-${context}`;
|
||||
const existingKeys = items.map(function() {
|
||||
return `${group}-${context}-${this.id}`;
|
||||
}).get();
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
|
||||
if (!key.startsWith(prefix)) {
|
||||
continue;
|
||||
}
|
||||
if (!existingKeys.includes(key)) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static storeCheckboxStatus(checkbox, context) {
|
||||
if (checkbox.checked)
|
||||
ogStorage.store(StorageGroup.CHECK, context, checkbox.id, "");
|
||||
else
|
||||
ogStorage.remove(StorageGroup.CHECK, context, checkbox.id);
|
||||
}
|
||||
}
|
||||
|
||||
async function show_client_mac(pill_id) {
|
||||
const pill = $('#' +pill_id);
|
||||
|
||||
|
@ -54,13 +109,6 @@ function showSelectedClientsOnEvents() {
|
|||
});
|
||||
}
|
||||
|
||||
function storeCheckboxStatus(checkbox, context) {
|
||||
if (checkbox.checked)
|
||||
localStorage.setItem(context + checkbox.id, "check");
|
||||
else
|
||||
localStorage.removeItem(context + checkbox.id);
|
||||
}
|
||||
|
||||
function findParentCheckboxes(element) {
|
||||
const $element = $(element);
|
||||
const parents = $element.parentsUntil('#scopes').not('ul');
|
||||
|
@ -89,27 +137,10 @@ function setParentStatus(checkboxes) {
|
|||
});
|
||||
}
|
||||
|
||||
function deleteInvalidStorageItems(items, context) {
|
||||
const existingIds = items.map(function() {
|
||||
return context + this.id;
|
||||
}).get();
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
|
||||
if (!key.startsWith(context)) {
|
||||
continue;
|
||||
}
|
||||
if (!existingIds.includes(key)) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function configureCommandCheckboxes(context) {
|
||||
const checkboxes = $('input:checkbox[form="scopesForm"]');
|
||||
|
||||
deleteInvalidStorageItems(checkboxes, context);
|
||||
ogStorage.deleteInvalidStorage(checkboxes, StorageGroup.CHECK, context);
|
||||
|
||||
// Ensure the form fields are sent
|
||||
$('#scopesForm').on('submit', function() {
|
||||
|
@ -151,7 +182,7 @@ function configureCommandCheckboxes(context) {
|
|||
|
||||
checkboxes.each(function() {
|
||||
showSelectedClient(this);
|
||||
storeCheckboxStatus(this, context);
|
||||
ogStorage.storeCheckboxStatus(this, context);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -160,33 +191,35 @@ function keepSelectedClients(context) {
|
|||
const checkboxes = $('#sidebar input:checkbox')
|
||||
|
||||
checkboxes.on('change', function (event) {
|
||||
storeCheckboxStatus(this, context);
|
||||
ogStorage.storeCheckboxStatus(this, context);
|
||||
});
|
||||
|
||||
deleteInvalidStorageItems(checkboxes, context);
|
||||
ogStorage.deleteInvalidStorage(checkboxes, StorageGroup.CHECK, context);
|
||||
|
||||
checkboxes.each(function () {
|
||||
if (localStorage.getItem(context + this.id) == 'check') {
|
||||
if (ogStorage.hasKey(StorageGroup.CHECK, context, this.id)) {
|
||||
this.checked = true;
|
||||
$(this).trigger('show-client');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function keepTreeState(selector) {
|
||||
const tree = $(selector + ' .collapse');
|
||||
function keepTreeState(selector, context) {
|
||||
const tree_items = $(selector + ' .collapse');
|
||||
|
||||
tree.on('hidden.bs.collapse', function (event) {
|
||||
ogStorage.deleteInvalidStorage(tree_items, StorageGroup.SHOW, context);
|
||||
|
||||
tree_items.on('hidden.bs.collapse', function (event) {
|
||||
event.stopPropagation();
|
||||
localStorage.removeItem(this.id);
|
||||
ogStorage.remove(StorageGroup.SHOW, context, this.id)
|
||||
});
|
||||
tree.on('shown.bs.collapse', function (event) {
|
||||
tree_items.on('shown.bs.collapse', function (event) {
|
||||
event.stopPropagation();
|
||||
localStorage.setItem(this.id, 'show');
|
||||
ogStorage.store(StorageGroup.SHOW, context, this.id, "")
|
||||
});
|
||||
|
||||
tree.each(function () {
|
||||
if (localStorage.getItem(this.id) == 'show') {
|
||||
tree_items.each(function () {
|
||||
if (ogStorage.hasKey(StorageGroup.SHOW, context, this.id)) {
|
||||
$(this).collapse('show');
|
||||
} else {
|
||||
$(this).siblings('a').addClass('collapsed');
|
||||
|
@ -324,14 +357,14 @@ function checkFolderParent(context) {
|
|||
folder.on('change', function() {
|
||||
const folder_parent = $('#' + $.escapeSelector(this.dataset.parentInput));
|
||||
folder_parent.prop('checked', this.checked);
|
||||
storeCheckboxStatus(folder_parent.get(0), context);
|
||||
ogStorage.storeCheckboxStatus(folder_parent.get(0), context);
|
||||
});
|
||||
}
|
||||
|
||||
function limitCheckboxes(context) {
|
||||
const checkboxes = $('#sidebar input:checkbox');
|
||||
|
||||
deleteInvalidStorageItems(checkboxes, context);
|
||||
ogStorage.deleteInvalidStorage(checkboxes, StorageGroup.CHECK, context);
|
||||
|
||||
checkboxes.on('change', function () {
|
||||
const currentCheckbox = $(this);
|
||||
|
@ -353,7 +386,7 @@ function limitCheckboxes(context) {
|
|||
checkCheckbox('scope-server');
|
||||
|
||||
checkboxes.each(function() {
|
||||
storeCheckboxStatus(this, context);
|
||||
ogStorage.storeCheckboxStatus(this, context);
|
||||
showSelectedClient(this);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
<!-- ChartJS -->
|
||||
<script src="{{ url_for('static', filename='AdminLTE/plugins/chart.js/Chart.min.js') }}"></script>
|
||||
|
||||
<script src="{{ url_for('static', filename='js/ogcp.js') }}?v=22"></script>
|
||||
<script src="{{ url_for('static', filename='js/ogcp.js') }}?v=24"></script>
|
||||
|
||||
<script>
|
||||
// error messages
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// in the scope
|
||||
document.addEventListener('readystatechange', () => {
|
||||
if (document.readyState === 'complete') {
|
||||
keepTreeState('#servers');
|
||||
keepTreeState('#servers', 'images');
|
||||
keepSelectedClients('images');
|
||||
checkOnChange('image-server');
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
if (document.readyState === 'complete') {
|
||||
showSelectedClientsOnEvents();
|
||||
updateScopeState();
|
||||
keepTreeState('#scopes');
|
||||
keepTreeState('#scopes', 'scopes');
|
||||
let context = {{ selection_mode | tojson | safe }};
|
||||
{% if selection_mode == 'commands' %}
|
||||
configureCommandCheckboxes(context);
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
// in the scope
|
||||
document.addEventListener('readystatechange', () => {
|
||||
if (document.readyState === 'complete') {
|
||||
keepTreeState('#repos-list')
|
||||
keepTreeState('#repos-list', 'repos');
|
||||
keepSelectedClients('repos');
|
||||
checkOnChange('repos-server');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue