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)
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]
> 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
$('#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 () {
// Activate panel
@@ -839,12 +824,12 @@ function initializeCombos () {
// nameTransformer) // callback to transform name
initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genDevDetailsList, 'txtIcon', atob )
initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genDevDetailsList, 'txtDeviceType' )
initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genDevDetailsList, 'txtOwner' )
initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genDevDetailsList, 'txtGroup' )
initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genDevDetailsList, 'txtLocation' )
initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genDevDetailsList, 'txtNetworkNodeMac' )
initSettingDropdown("NEWDEV_dev_Icon", [], "dropdownIcon_tmp", genListWithInputSet, 'txtIcon', atob )
initSettingDropdown("NEWDEV_dev_DeviceType", [], "dropdownDeviceType_tmp", genListWithInputSet, 'txtDeviceType' )
initSettingDropdown("NEWDEV_dev_Owner", [], "dropdownOwner_tmp", genListWithInputSet, 'txtOwner' )
initSettingDropdown("NEWDEV_dev_Group", [], "dropdownGroup_tmp", genListWithInputSet, 'txtGroup' )
initSettingDropdown("NEWDEV_dev_Location", [], "dropdownLocation_tmp", genListWithInputSet, 'txtLocation' )
initSettingDropdown("NEWDEV_dev_Network_Node_MAC_ADDR", [], "dropdownNetworkNodeMac_tmp", genListWithInputSet, 'txtNetworkNodeMac' )
// Initialize static combos
initializeComboSkipRepeated ();
@@ -1155,7 +1140,7 @@ function initializeCalendar () {
showSpinner()
} else {
setTimeout(() => {
updateIconPreview()
updateIconPreview('#txtIcon')
}, 100);
hideSpinner()
@@ -1673,7 +1658,7 @@ function addAsBase64 () {
$('#txtIcon').val(iconHtmlBase64);
updateIconPreview()
updateIconPreview('#txtIcon')
}

View File

@@ -186,13 +186,25 @@ function hideUIelements(settingKey) {
// -----------------------------------------------------------------------------
// Processor to generate options for a dropdown menu
function generateDropdownOptions(data, valuesArray) {
function generateDropdownOptions(data, valuesArray, targetField, nameTransformer) {
var optionsHtml = "";
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' : '';
optionsHtml += `<option value="${item.id}" ${selected}>${item.name}</option>`;
optionsHtml += `<option value="${item.id}" ${selected}>${labelName}</option>`;
});
return `${optionsHtml}`;
}
@@ -200,21 +212,28 @@ function generateDropdownOptions(data, valuesArray) {
// -----------------------------------------------------------------------------
// Processor to generate a list
function generateList(data, valuesArray) {
function generateList(data, valuesArray, targetField, nameTransformer) {
var listHtml = "";
data.forEach(function(item) {
labelName = item.name
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
{
labelName = nameTransformer(labelName)
}
let selected = valuesArray.includes(item.id) ? 'selected' : '';
listHtml += `<li ${selected}>${item.name}</li>`;
listHtml += `<li ${selected}>${labelName}</li>`;
});
return listHtml;
}
// -----------------------------------------------------------------------------
// Processor to generate a list in teh deviceDetails page
function genDevDetailsList(data, valuesArray, targetField, nameTransformer) {
// Processor to generate a list in the deviceDetails page
function genListWithInputSet(data, valuesArray, targetField, nameTransformer) {
var listHtml = "";
@@ -227,7 +246,7 @@ function genDevDetailsList(data, valuesArray, targetField, nameTransformer) {
labelName = item.name
if(nameTransformer && labelName != '❌None')
if(nameTransformer && nameTransformer != '' && labelName != '❌None')
{
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

View File

@@ -107,19 +107,36 @@
break;
}
if (inputType === 'text.select') {
targetLocation = columns[j].Code_Name + "_initSettingDropdown"
initSettingDropdown(columns[j].Code_Name, [], targetLocation, generateDropdownOptions)
input = `<select class="form-control"
// 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"
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 {
// Add classes specifically for checkboxes

View File

@@ -18,7 +18,7 @@
<!-- &copy; 2022 jokob-sk -->
<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'; ?> |
<a href="https://github.com/jokob-sk/NetAlertX/tree/main/docs" target="_blank"><span>Docs <i class="fa fa-circle-question"></i></a>
<span>

View File

@@ -613,7 +613,9 @@
"TIMEZONE_name": "Time zone",
"UI_DEV_SECTIONS_description": "Select which UI elements to hide in the Devices pages.",
"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_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",

View File

@@ -589,7 +589,7 @@
{
"name" : "value",
"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"],

View File

@@ -7,11 +7,9 @@ import base64
from const import fullDbPath, sql_devices_stats, sql_devices_all
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
class DB():
"""
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
"""
# 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
onlineHistoryAvailable = self.sql.execute("""
SELECT name FROM sqlite_master WHERE type='table'

View File

@@ -597,12 +597,6 @@ def cleanDeviceName(str, match_IP):
# 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_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_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.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')