More icons work 🔨

This commit is contained in:
jokob-sk
2024-04-14 12:34:14 +10:00
parent d75f27c6db
commit 8e7e437b4c
11 changed files with 80 additions and 57 deletions

View File

@@ -29,11 +29,11 @@ Copying the HTML code from [Font Awesome](https://fontawesome.com/search?o=r&m=f
![preview](/docs/img/ICONS/device_add_icon.png) ![preview](/docs/img/ICONS/device_add_icon.png)
3. Paste in the copied HTML or SVG code. 3. Paste in the copied HTML or SVG code and click "OK":
4. Click "OK" ![Paste SVG](/docs/img/ICONS/paste-svg.png)
5. "Save" the device 6. "Save" the device
> [!NOTE] > [!NOTE]
> If you want to mass-apply an icon to all devices of the same device type (Field: Type), you can click the mass-copy button (next to the "+" button). A confirmation prompt is displayed. If you proceed, icons of all devices set to the same device type as the current device, will be overwritten with the current device's icon. > If you want to mass-apply an icon to all devices of the same device type (Field: Type), you can click the mass-copy button (next to the "+" button). A confirmation prompt is displayed. If you proceed, icons of all devices set to the same device type as the current device, will be overwritten with the current device's icon.

BIN
docs/img/ICONS/paste-svg.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -748,28 +748,13 @@ function main () {
// Show device icon as it changes // Show device icon as it changes
$('#txtIcon').on('change input', function() { $('#txtIcon').on('change input', function() {
updateIconPreview() updateIconPreview('#txtIcon')
}); });
} }
// -----------------------------------------------------------------------------
function updateIconPreview () {
// update icon
iconInput = $('#txtIcon')
value = iconInput.val()
iconInput.on('change input', function() {
$('#txtIconFA').html(atob(value))
});
$('#txtIconFA').html(atob(value))
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initializeTabs () { function initializeTabs () {
// Activate panel // Activate panel
@@ -839,12 +824,12 @@ function initializeCombos () {
// nameTransformer) // callback to transform name // nameTransformer) // callback to transform name
initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genDevDetailsList, 'txtIcon', atob ) initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', atob )
initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genDevDetailsList, 'txtDeviceType' ) initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genDevDetailsList, 'txtOwner' ) initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genDevDetailsList, 'txtGroup' ) initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genDevDetailsList, 'txtLocation' ) initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genDevDetailsList, 'txtNetworkNodeMac' ) initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
// Initialize static combos // Initialize static combos
initializeComboSkipRepeated (); initializeComboSkipRepeated ();
@@ -1155,7 +1140,7 @@ function initializeCalendar () {
showSpinner() showSpinner()
} else { } else {
setTimeout(() => { setTimeout(() => {
updateIconPreview() updateIconPreview('#txtIcon')
}, 100); }, 100);
hideSpinner() hideSpinner()
@@ -1673,7 +1658,7 @@ function addAsBase64 () {
$('#txtIcon').val(iconHtmlBase64); $('#txtIcon').val(iconHtmlBase64);
updateIconPreview() updateIconPreview('#txtIcon')
} }

View File

@@ -186,13 +186,25 @@ function hideUIelements(settingKey) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Processor to generate options for a dropdown menu // Processor to generate options for a dropdown menu
function generateDropdownOptions(data, valuesArray) { function generateDropdownOptions(data, valuesArray, targetField, nameTransformer) {
var optionsHtml = ""; var optionsHtml = "";
data.forEach(function(item) { data.forEach(function(item) {
labelName = item.name
// console.log(nameTransformer);
// console.log(labelName);
// if(nameTransformer && nameTransformer != '' && labelName != '❌None')
// {
// console.log(labelName);
// labelName = nameTransformer(labelName)
// console.log(labelName);
// }
let selected = valuesArray.includes(item.id) ? 'selected' : ''; let selected = valuesArray.includes(item.id) ? 'selected' : '';
optionsHtml += `<option value="${item.id}" ${selected}>${item.name}</option>`; optionsHtml += `<option value="${item.id}" ${selected}>${labelName}</option>`;
}); });
return `${optionsHtml}`; return `${optionsHtml}`;
} }
@@ -200,21 +212,28 @@ function generateDropdownOptions(data, valuesArray) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Processor to generate a list // Processor to generate a list
function generateList(data, valuesArray) { function generateList(data, valuesArray, targetField, nameTransformer) {
var listHtml = ""; var listHtml = "";
data.forEach(function(item) { data.forEach(function(item) {
labelName = item.name
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
{
labelName = nameTransformer(labelName)
}
let selected = valuesArray.includes(item.id) ? 'selected' : ''; let selected = valuesArray.includes(item.id) ? 'selected' : '';
listHtml += `<li ${selected}>${item.name}</li>`; listHtml += `<li ${selected}>${labelName}</li>`;
}); });
return listHtml; return listHtml;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Processor to generate a list in teh deviceDetails page // Processor to generate a list in the deviceDetails page
function genDevDetailsList(data, valuesArray, targetField, nameTransformer) { function genListWithInputSet(data, valuesArray, targetField, nameTransformer) {
var listHtml = ""; var listHtml = "";
@@ -227,7 +246,7 @@ function genDevDetailsList(data, valuesArray, targetField, nameTransformer) {
labelName = item.name labelName = item.name
if(nameTransformer && labelName != '❌None') if(nameTransformer && nameTransformer != '' && labelName != '❌None')
{ {
labelName = nameTransformer(labelName) labelName = nameTransformer(labelName)
} }
@@ -242,7 +261,21 @@ function genDevDetailsList(data, valuesArray, targetField, nameTransformer) {
} }
// -----------------------------------------------------------------------------
// Updates the icon preview
function updateIconPreview (inputId) {
// update icon
iconInput = $(inputId)
value = iconInput.val()
iconInput.on('change input', function() {
$('#txtIconFA').html(atob(value))
});
$('#txtIconFA').html(atob(value))
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// initialize // initialize

View File

@@ -107,19 +107,36 @@
break; break;
} }
if (inputType === 'text.select') { if (inputType === 'text.select') {
targetLocation = columns[j].Code_Name + "_initSettingDropdown" targetLocation = columns[j].Code_Name + "_initSettingDropdown"
initSettingDropdown(columns[j].Code_Name, [], targetLocation, generateDropdownOptions) initSettingDropdown(columns[j].Code_Name, [], targetLocation, generateDropdownOptions)
// Handle Icons as tehy need a preview
if(columns[j].Code_Name == 'NEWDEV_dev_Icon')
{
input = `
<span class="input-group-addon" id="txtIconFA"></span>
<select class="form-control"
onChange="updateIconPreview('#NEWDEV_dev_Icon')"
id="${columns[j].Code_Name}"
data-my-column="${columns[j].Code_Name}"
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" >
<option id="${targetLocation}"></option>
</select>`
} else{
input = `<select class="form-control" input = `<select class="form-control"
id="${columns[j].Code_Name}" id="${columns[j].Code_Name}"
data-my-column="${columns[j].Code_Name}" data-my-column="${columns[j].Code_Name}"
data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" > data-my-targetColumns="${columns[j].Code_Name.replace('NEWDEV_','')}" >
<option id="${targetLocation}"></option> <option id="${targetLocation}"></option>
</select>` </select>`
}
} else { } else {
// Add classes specifically for checkboxes // Add classes specifically for checkboxes

View File

@@ -18,7 +18,7 @@
<!-- &copy; 2022 jokob-sk --> <!-- &copy; 2022 jokob-sk -->
<span style="display:inline-block; transform: rotate(180deg)">&copy;</span> <span style="display:inline-block; transform: rotate(180deg)">&copy;</span>
2020 Puche (2022+ <a href="mailto:jokob@duck.com?subject=NetAlertX">jokob-sk</a>) | <b><?= lang('Maintenance_built_on');?>: </b> Author: <a href="mailto:jokob@duck.com?subject=NetAlertX">jokob-sk</a> (Based on <a href="https://github.com/pucherot/Pi.Alert">2020 PiAlert</a>) | <b><?= lang('Maintenance_built_on');?>: </b>
<?php include 'php/templates/build.php'; ?> | <b> Version: </b> <?php include 'php/templates/version.php'; ?> | <?php include 'php/templates/build.php'; ?> | <b> Version: </b> <?php include 'php/templates/version.php'; ?> |
<a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs" target="_blank"><span>Docs <i class="fa fa-circle-question"></i></a> <a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs" target="_blank"><span>Docs <i class="fa fa-circle-question"></i></a>
<span> <span>

View File

@@ -613,7 +613,9 @@
"TIMEZONE_name": "Time zone", "TIMEZONE_name": "Time zone",
"UI_DEV_SECTIONS_description": "Select which UI elements to hide in the Devices pages.", "UI_DEV_SECTIONS_description": "Select which UI elements to hide in the Devices pages.",
"UI_DEV_SECTIONS_name": "Hide Devices Sections", "UI_DEV_SECTIONS_name": "Hide Devices Sections",
"UI_LANG_description": "Select the preferred UI language. Help translating or suggest languages in the online portal of <a href=\"https://hosted.weblate.org/projects/pialert/core/\" target=\"_blank\">Weblate</a>.", "UI_ICONS_description": "Select which UI elements to hide in the Devices pages.",
"UI_ICONS_name": "Pre-defined icons",
"UI_LANG_description": "A list of pre-defined icons. Proceed with caution, the preferred way to add icons is described in the <a href=\"https://github.com/jokob-sk/NetAlertX/blob/main/docs/ICONS.md\" target=\"_blank\">Icons documentation</a>. You can add a base64-encoded SVG HTML or Font-awesome HTML tag.",
"UI_LANG_name": "UI Language", "UI_LANG_name": "UI Language",
"UI_MY_DEVICES_description": "Devices of which statuses should be shown in the default <b>My Devices</b> view. (<code>CTRL + Click</code> to select/deselect)", "UI_MY_DEVICES_description": "Devices of which statuses should be shown in the default <b>My Devices</b> view. (<code>CTRL + Click</code> to select/deselect)",
"UI_MY_DEVICES_name": "Show in My Devices view", "UI_MY_DEVICES_name": "Show in My Devices view",

View File

@@ -589,7 +589,7 @@
{ {
"name" : "value", "name" : "value",
"type" : "sql", "type" : "sql",
"value" : "SELECT DISTINCT '❌None' AS name, '' AS id UNION SELECT Dev_Icon AS name, Dev_Icon AS id FROM Devices WHERE Dev_Icon <> '';" "value" : "WITH RECURSIVE SettingsIcons AS (SELECT REPLACE(REPLACE(REPLACE(Value, '[', ''), ']', ''), '''', '') AS icon_list FROM Settings WHERE Code_Name = 'UI_ICONS'), SplitIcons AS (SELECT TRIM(SUBSTR(icon_list, 1, INSTR(icon_list || ',', ',') - 1)) AS icon, SUBSTR(icon_list, INSTR(icon_list || ',', ',') + 1) AS remaining_icons FROM SettingsIcons WHERE icon_list <> '' UNION ALL SELECT TRIM(SUBSTR(remaining_icons, 1, INSTR(remaining_icons || ',', ',') - 1)) AS icon, SUBSTR(remaining_icons, INSTR(remaining_icons || ',', ',') + 1) AS remaining_icons FROM SplitIcons WHERE remaining_icons <> '') SELECT DISTINCT * FROM (SELECT icon as name, icon as id FROM SplitIcons UNION SELECT '❌None' AS name, '' AS id UNION SELECT Dev_Icon AS name, Dev_Icon AS id FROM Devices WHERE Dev_Icon <> '') AS combined_results;"
} }
], ],
"localized": ["name", "description"], "localized": ["name", "description"],

View File

@@ -7,11 +7,9 @@ import base64
from const import fullDbPath, sql_devices_stats, sql_devices_all from const import fullDbPath, sql_devices_stats, sql_devices_all
from logger import mylog from logger import mylog
from helper import json_obj, initOrSetParam, row_to_json, timeNowTZ, split_string #, updateState from helper import json_obj, initOrSetParam, row_to_json, timeNowTZ#, split_string #, updateState
from appevent import AppEvent_obj from appevent import AppEvent_obj
class DB(): class DB():
""" """
DB Class to provide the basic database interactions. DB Class to provide the basic database interactions.
@@ -83,12 +81,6 @@ class DB():
Check the current tables in the DB and upgrade them if neccessary Check the current tables in the DB and upgrade them if neccessary
""" """
# Registering UDF (User Defined Functions)
#
resultUDF = self.sql_connection.create_function("split_string", 2, split_string) # Register the UDF
mylog('none',f'[upgradeDB] resultUDF: {resultUDF}')
# indicates, if Online_History table is available # indicates, if Online_History table is available
onlineHistoryAvailable = self.sql.execute(""" onlineHistoryAvailable = self.sql.execute("""
SELECT name FROM sqlite_master WHERE type='table' SELECT name FROM sqlite_master WHERE type='table'

View File

@@ -597,12 +597,6 @@ def cleanDeviceName(str, match_IP):
# String manipulation methods # String manipulation methods
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Define the split_string function
def split_string(input_str, delimiter):
# remove any wrapping brackets
input_str = input_str.replace('[','').replace(']','')
return input_str.split(delimiter)
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------

View File

@@ -110,7 +110,7 @@ def importConfigs (db):
conf.UI_DEV_SECTIONS = ccd('UI_DEV_SECTIONS', [] , c_d, 'Show sections', 'text.multiselect', "['Tile Cards', 'Device Presence']", 'General') conf.UI_DEV_SECTIONS = ccd('UI_DEV_SECTIONS', [] , c_d, 'Show sections', 'text.multiselect', "['Tile Cards', 'Device Presence']", 'General')
conf.UI_MY_DEVICES = ccd('UI_MY_DEVICES', ['online', 'offline', 'archived', 'new', 'down'] , c_d, 'Include in My Devices', 'text.multiselect', "['online', 'offline', 'archived', 'new', 'down']", 'General') conf.UI_MY_DEVICES = ccd('UI_MY_DEVICES', ['online', 'offline', 'archived', 'new', 'down'] , c_d, 'Include in My Devices', 'text.multiselect', "['online', 'offline', 'archived', 'new', 'down']", 'General')
conf.UI_NOT_RANDOM_MAC = ccd('UI_NOT_RANDOM_MAC', [] , c_d, 'Exlude from Random Prefix', 'list', "", 'General') conf.UI_NOT_RANDOM_MAC = ccd('UI_NOT_RANDOM_MAC', [] , c_d, 'Exlude from Random Prefix', 'list', "", 'General')
conf.UI_ICONS = ccd('UI_ICONS', ['PGkgY2xhc3M9ImZhIGZhLWNvbXB1dGVyIj48L2k', 'PGkgY2xhc3M9ImZhIGZhLWV0aGVybmV0Ij48L2k', 'PGkgY2xhc3M9ImZhIGZhLWdhbWVwYWQiPjwvaT4', 'PGkgY2xhc3M9ImZhIGZhLWdsb2JlIj48L2k', 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI', 'PGkgY2xhc3M9ImZhIGZhLWxpZ2h0YnVsYiI', 'PGkgY2xhc3M9ImZhIGZhLXNoaWVsZCI', 'PGkgY2xhc3M9ImZhIGZhLXdpZmkiPjwvaT4'] , c_d, 'Icons', 'list', "", 'General') conf.UI_ICONS = ccd('UI_ICONS', ['PGkgY2xhc3M9ImZhIGZhLWNvbXB1dGVyIj48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWV0aGVybmV0Ij48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWdhbWVwYWQiPjwvaT4', 'PGkgY2xhc3M9ImZhIGZhLWdsb2JlIj48L2k+', 'PGkgY2xhc3M9ImZhIGZhLWxhcHRvcCI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLWxpZ2h0YnVsYiI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLXNoaWVsZCI+PC9pPg==', 'PGkgY2xhc3M9ImZhIGZhLXdpZmkiPjwvaT4'] , c_d, 'Icons', 'list', "", 'General')
conf.UI_REFRESH = ccd('UI_REFRESH', 0 , c_d, 'Refresh interval', 'integer', "", 'General') conf.UI_REFRESH = ccd('UI_REFRESH', 0 , c_d, 'Refresh interval', 'integer', "", 'General')
conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', 'integer', '', 'General') conf.DAYS_TO_KEEP_EVENTS = ccd('DAYS_TO_KEEP_EVENTS', 90 , c_d, 'Delete events days', 'integer', '', 'General')
conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', 'integer', "0", 'General') conf.HRS_TO_KEEP_NEWDEV = ccd('HRS_TO_KEEP_NEWDEV', 0 , c_d, 'Keep new devices for', 'integer', "0", 'General')