styles and startmenuItems

This commit is contained in:
2026-04-23 15:01:32 +02:00
parent 12d7de5065
commit 0876e754eb
11 changed files with 458 additions and 233 deletions

View File

@@ -48,7 +48,7 @@ module.exports = ([
{
label: 'Plugins',
view: 'plugindashboard',
defaultSize: { width: "1000px", height: "400px" },
defaultSize: { width: "900px", height: "800px" },
icon: "plugins.png",
permissions: [ 'Administration' ]
}

View File

@@ -0,0 +1,154 @@
[
{
"section": "System",
"name": "Server",
"active": true,
"menu": {
"label": "Server",
"items": [
{
"label": "Styles",
"view": "styleconfig",
"icon": "brush.png",
"permissions": [
"Administration"
]
},
{
"label": "Configs",
"view": "serverconfig",
"icon": "app.png",
"permissions": [
"Administration"
]
}
]
},
"defaultSize": {
"width": 800,
"height": 600
}
},
{
"section": "System",
"name": "EventLog",
"active": true,
"menu": {
"label": "EventLog",
"items": [
{
"label": "EventLog",
"view": "eventlog",
"defaultSize": {
"width": "1200px",
"height": "1200px"
},
"icon": "eventlog.ico",
"permissions": [
"Administration"
]
}
]
},
"defaultSize": {
"width": "1200px",
"height": "1200px"
}
},
{
"section": "System",
"name": "Plugins",
"active": true,
"menu": {
"label": "Plugins",
"items": [
{
"label": "Plugins",
"view": "plugindashboard",
"defaultSize": {
"width": "900px",
"height": "800px"
},
"icon": "plugins.png",
"permissions": [
"Administration"
]
}
]
},
"defaultSize": {
"width": "900px",
"height": "800px"
}
},
{
"section": "System",
"name": "Info",
"active": true,
"menu": {
"label": "Info",
"items": [
{
"label": "Info",
"view": "serverinfo",
"defaultSize": {
"width": "900px",
"height": "500px"
},
"icon": "serverinfo.png",
"permissions": [
"Administration"
]
}
]
},
"defaultSize": {
"width": "900px",
"height": "500px"
}
},
{
"section": "Benutzer",
"name": "Einstellungen",
"active": true,
"menu": {
"label": "Einstellungen",
"items": [
{
"label": "Einstellungen",
"view": "usersettings",
"defaultSize": {
"width": "460px",
"height": "515px"
},
"icon": "app.png",
"permissions": [
"*"
]
}
]
},
"defaultSize": {
"width": "460px",
"height": "515px"
}
},
{
"section": "Benutzer",
"name": "Hilfe",
"active": true,
"menu": {
"label": "Hilfe",
"items": [
{
"label": "Hilfe",
"view": "help",
"icon": "help.png",
"permissions": [
"*"
]
}
]
}
}
]

View File

@@ -122,6 +122,13 @@ module.exports = {
}
});
app.post('/api/plugins/integrated', async (req, res) => {
try {
res.status(200).json(global.json.startMenuItems.live);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.post('/api/plugins/:name/update', async (req, res) => {
const { name } = req.params;

View File

@@ -31,132 +31,131 @@ class FileSystemManager {
}
/**
* Liest rekursiv Dateien und gibt nur die gewünschten Attribute zurück.
*
* @param {string} dirPath - Startverzeichnis
* @param {string[]} attributes - gewünschte Attribute:
* ['name','fullPath','size','lastModified','isDirectory','extension', ...]
* @param {string|null} sortBy - Attribut zum Sortieren (z.B. 'lastModified' oder 'name')
* @param {string} order - 'asc' oder 'desc'
*/
readFiles(dirPath, attributes = ['name', 'fullPath'], sortBy = null, order = 'asc') {
let results = [];
/**
* Liest rekursiv Dateien und gibt nur die gewünschten Attribute zurück.
*
* @param {string} dirPath - Startverzeichnis
* @param {string[]} attributes - gewünschte Attribute:
* ['name','fullPath','size','lastModified','isDirectory','extension', ...]
* @param {string|null} sortBy - Attribut zum Sortieren (z.B. 'lastModified' oder 'name')
* @param {string} order - 'asc' oder 'desc'
*/
readFiles(dirPath, attributes = ['name', 'fullPath'], sortBy = null, order = 'asc') {
let results = [];
const items = fs.readdirSync(dirPath);
const items = fs.readdirSync(dirPath);
for (const item of items) {
const fullPath = path.join(dirPath, item);
const stats = fs.statSync(fullPath);
const isDir = stats.isDirectory();
for (const item of items) {
const fullPath = path.join(dirPath, item);
const stats = fs.statSync(fullPath);
const isDir = stats.isDirectory();
// Objekt mit ALLEN möglichen Infos
const allInfo = {
name: item,
nameWithoutExt: item.substring(0, item.indexOf('.')),
fullPath: fullPath,
size: stats.size,
lastModified: stats.mtime,
created: stats.birthtime,
isDirectory: isDir,
extension: isDir ? null : path.extname(item)
};
// Objekt mit ALLEN möglichen Infos
const allInfo = {
name: item,
nameWithoutExt: item.substring(0, item.indexOf('.')),
fullPath: fullPath,
size: stats.size,
lastModified: stats.mtime,
created: stats.birthtime,
isDirectory: isDir,
extension: isDir ? null : path.extname(item)
};
if (isDir) {
// rekursiv weitermachen
results = results.concat(this.readFiles(fullPath, attributes, null, order));
} else {
// nur gewünschte Attribute ausgeben
const filtered = {};
for (const attr of attributes) {
if (allInfo[attr] !== undefined) {
filtered[attr] = allInfo[attr];
if (isDir) {
// rekursiv weitermachen
results = results.concat(this.readFiles(fullPath, attributes, null, order));
} else {
// nur gewünschte Attribute ausgeben
const filtered = {};
for (const attr of attributes) {
if (allInfo[attr] !== undefined) {
filtered[attr] = allInfo[attr];
}
}
results.push(filtered);
}
results.push(filtered);
}
// Sortieren, falls gewünscht
if (sortBy) {
results.sort((a, b) => {
if (a[sortBy] < b[sortBy]) return order === 'asc' ? -1 : 1;
if (a[sortBy] > b[sortBy]) return order === 'asc' ? 1 : -1;
return 0;
});
}
return results;
}
// Sortieren, falls gewünscht
if (sortBy) {
results.sort((a, b) => {
if (a[sortBy] < b[sortBy]) return order === 'asc' ? -1 : 1;
if (a[sortBy] > b[sortBy]) return order === 'asc' ? 1 : -1;
return 0;
});
}
return results;
}
/**
* Sammelt verschiedene Pattern-Ergebnisse aus Dateien mehrerer Ordner.
*
* @param {Object} options
* @param {string|string[]} options.folderPaths - Pfad oder Array von Pfaden zu Ordnern
* @param {string} [options.extension='.js'] - Dateiendung
* @param {Array<{ name: string, pattern: RegExp, mapFn?: Function }>} options.patterns - Liste von Pattern-Definitionen
* @param {boolean} [options.recursive=true] - Unterordner durchsuchen?
* @returns {Array} - kombinierte Ergebnisse aller Pattern
*/
collectFromFiles({
folderPaths,
extension = '.js',
patterns,
recursive = true
}) {
const results = [];
// if only one path selected
const paths = Array.isArray(folderPaths) ? folderPaths : [folderPaths];
function readDir(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
/**
* Sammelt verschiedene Pattern-Ergebnisse aus Dateien mehrerer Ordner.
*
* @param {Object} options
* @param {string|string[]} options.folderPaths - Pfad oder Array von Pfaden zu Ordnern
* @param {string} [options.extension='.js'] - Dateiendung
* @param {Array<{ name: string, pattern: RegExp, mapFn?: Function }>} options.patterns - Liste von Pattern-Definitionen
* @param {boolean} [options.recursive=true] - Unterordner durchsuchen?
* @returns {Array} - kombinierte Ergebnisse aller Pattern
*/
collectFromFiles({
folderPaths,
extension = '.js',
patterns,
recursive = true
}) {
const results = [];
if (entry.isDirectory() && recursive) {
readDir(fullPath);
} else if (entry.isFile() && entry.name.endsWith(extension)) {
const content = fs.readFileSync(fullPath, 'utf8');
// if only one path selected
const paths = Array.isArray(folderPaths) ? folderPaths : [folderPaths];
// 👉 NEU: fallback wenn keine patterns
if (!patterns || patterns.length === 0) {
results.push({
file: entry.name,
fullPath
});
continue;
}
function readDir(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory() && recursive) {
readDir(fullPath);
} else if (entry.isFile() && entry.name.endsWith(extension)) {
const content = fs.readFileSync(fullPath, 'utf8');
// 👉 NEU: fallback wenn keine patterns
if (!patterns || patterns.length === 0) {
results.push({
file: entry.name,
fullPath
});
continue;
}
for (const { name, pattern, mapFn } of patterns) {
let match;
while ((match = pattern.exec(content)) !== null) {
const mapped = mapFn
? mapFn(match, entry.name, fullPath, name)
: { file: entry.name, type: name, match: match[0] };
results.push(mapped);
for (const { name, pattern, mapFn } of patterns) {
let match;
while ((match = pattern.exec(content)) !== null) {
const mapped = mapFn
? mapFn(match, entry.name, fullPath, name)
: { file: entry.name, type: name, match: match[0] };
results.push(mapped);
}
}
}
}
}
}
// Run through multiple paths
for (const dir of paths) {
if (fs.existsSync(dir)) {
readDir(path.resolve(dir));
} else {
console.warn(`Ordner nicht gefunden: ${dir}`);
// Run through multiple paths
for (const dir of paths) {
if (fs.existsSync(dir)) {
readDir(path.resolve(dir));
} else {
console.warn(`Ordner nicht gefunden: ${dir}`);
}
}
return results;
}
return results;
}
@@ -171,6 +170,16 @@ collectFromFiles({
}
}
loadFile(path) {
try {
const rawData = fs.readFileSync(path, 'utf8');
return rawData;
} catch (err) {
console.log(err)
return err
}
}
// Check file-/path
exists(path) {

View File

@@ -1,6 +1,6 @@
const path = require('path');
const fs = require('fs');
const startMenuItemContext = require('@models/integratedStartmenuItems.js')
module.exports = (app, socketManager, namespace, pluginManager, authenticationModel, fileSystemManager, eventManager, activeDirectory) => {
const mainSocket = socketManager.namespaces.get(namespace);