fix .json overwriting
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
createJsonTree({
|
createJsonTree({
|
||||||
container: domElement,
|
container: domElement,
|
||||||
data: jsonData,
|
data: jsonData,
|
||||||
expandInitially = true // optional: expand all nodes
|
|
||||||
onChange: (data) => { }, // optional: callback on change
|
onChange: (data) => { }, // optional: callback on change
|
||||||
onSave: (data) => { } // optional: if set, a save button will be added
|
onSave: (data) => { } // optional: if set, a save button will be added
|
||||||
});
|
});
|
||||||
@@ -12,7 +11,7 @@ function createJsonTree({
|
|||||||
data,
|
data,
|
||||||
onChange = () => {},
|
onChange = () => {},
|
||||||
onSave = null,
|
onSave = null,
|
||||||
expandInitially = true
|
readonly = false
|
||||||
}) {
|
}) {
|
||||||
container.innerHTML = "";
|
container.innerHTML = "";
|
||||||
container.classList.add("json-tree-root");
|
container.classList.add("json-tree-root");
|
||||||
@@ -22,8 +21,6 @@ function createJsonTree({
|
|||||||
|
|
||||||
let lastSnapshot = clone(data);
|
let lastSnapshot = clone(data);
|
||||||
|
|
||||||
const expandedPaths = new Set();
|
|
||||||
|
|
||||||
function clone(obj) {
|
function clone(obj) {
|
||||||
return JSON.parse(JSON.stringify(obj));
|
return JSON.parse(JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
@@ -70,6 +67,7 @@ function createJsonTree({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function undo() {
|
function undo() {
|
||||||
|
if (readonly) return;
|
||||||
if (!history.length) return;
|
if (!history.length) return;
|
||||||
redoStack.push(clone(data));
|
redoStack.push(clone(data));
|
||||||
data = history.pop();
|
data = history.pop();
|
||||||
@@ -77,6 +75,7 @@ function createJsonTree({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function redo() {
|
function redo() {
|
||||||
|
if (readonly) return;
|
||||||
if (!redoStack.length) return;
|
if (!redoStack.length) return;
|
||||||
history.push(clone(data));
|
history.push(clone(data));
|
||||||
data = redoStack.pop();
|
data = redoStack.pop();
|
||||||
@@ -84,6 +83,7 @@ function createJsonTree({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
|
if (readonly) return;
|
||||||
if (onSave) onSave(data);
|
if (onSave) onSave(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +93,7 @@ function createJsonTree({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function remove(key, parent) {
|
function remove(key, parent) {
|
||||||
|
if (readonly) return;
|
||||||
if (key === null || parent == null) return;
|
if (key === null || parent == null) return;
|
||||||
|
|
||||||
if (!confirm("Wirklich löschen?")) return;
|
if (!confirm("Wirklich löschen?")) return;
|
||||||
@@ -109,28 +110,10 @@ function createJsonTree({
|
|||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
function collectPaths(obj, path = "root") {
|
|
||||||
if (typeof obj !== "object" || obj === null) return;
|
|
||||||
|
|
||||||
expandedPaths.add(path);
|
|
||||||
|
|
||||||
const entries = Array.isArray(obj)
|
|
||||||
? obj.map((v, i) => [i, v])
|
|
||||||
: Object.entries(obj);
|
|
||||||
|
|
||||||
for (const [k, v] of entries) {
|
|
||||||
collectPaths(v, `${path}.${k}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expandInitially) {
|
|
||||||
collectPaths(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
container.innerHTML = "";
|
container.innerHTML = "";
|
||||||
|
|
||||||
if (onSave) {
|
if (onSave && !readonly) {
|
||||||
const controls = document.createElement("div");
|
const controls = document.createElement("div");
|
||||||
controls.className = "json-controls";
|
controls.className = "json-controls";
|
||||||
|
|
||||||
@@ -174,10 +157,13 @@ function createJsonTree({
|
|||||||
const removeBtn = document.createElement("span");
|
const removeBtn = document.createElement("span");
|
||||||
removeBtn.className = "json-remove";
|
removeBtn.className = "json-remove";
|
||||||
removeBtn.textContent = " [x]";
|
removeBtn.textContent = " [x]";
|
||||||
|
|
||||||
|
if (!readonly) {
|
||||||
removeBtn.onclick = (evt) => {
|
removeBtn.onclick = (evt) => {
|
||||||
evt.stopPropagation();
|
evt.stopPropagation();
|
||||||
remove(key, parent);
|
remove(key, parent);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// OBJECT / ARRAY
|
// OBJECT / ARRAY
|
||||||
if (typeof value === "object" && value !== null) {
|
if (typeof value === "object" && value !== null) {
|
||||||
@@ -201,24 +187,12 @@ function createJsonTree({
|
|||||||
const children = document.createElement("div");
|
const children = document.createElement("div");
|
||||||
children.className = "json-children";
|
children.className = "json-children";
|
||||||
|
|
||||||
const toggleState = () => {
|
keyLabel.onclick = toggle.onclick = () => {
|
||||||
if (expandedPaths.has(path)) {
|
if (readonly) return;
|
||||||
expandedPaths.delete(path);
|
children.classList.toggle("collapsed");
|
||||||
children.classList.add("collapsed");
|
|
||||||
} else {
|
|
||||||
expandedPaths.add(path);
|
|
||||||
children.classList.remove("collapsed");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
keyLabel.onclick = toggle.onclick = toggleState;
|
if (!readonly) {
|
||||||
|
|
||||||
if (expandedPaths.has(path)) {
|
|
||||||
children.classList.remove("collapsed");
|
|
||||||
} else {
|
|
||||||
children.classList.add("collapsed");
|
|
||||||
}
|
|
||||||
|
|
||||||
addBtn.onclick = () => {
|
addBtn.onclick = () => {
|
||||||
let newKey = "";
|
let newKey = "";
|
||||||
let newValue;
|
let newValue;
|
||||||
@@ -261,20 +235,18 @@ function createJsonTree({
|
|||||||
default: newValue = "";
|
default: newValue = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isArray) {
|
if (isArray) value.push(newValue);
|
||||||
value.push(newValue);
|
else value[newKey] = newValue;
|
||||||
} else {
|
|
||||||
value[newKey] = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange(data);
|
onChange(data);
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
no: { text: 'Abbrechen' }
|
no: { text: "Abbrechen" }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const inner = document.createElement("div");
|
const inner = document.createElement("div");
|
||||||
|
|
||||||
@@ -292,9 +264,8 @@ function createJsonTree({
|
|||||||
|
|
||||||
header.appendChild(keyLabel);
|
header.appendChild(keyLabel);
|
||||||
header.appendChild(toggle);
|
header.appendChild(toggle);
|
||||||
header.appendChild(addBtn);
|
if (!readonly) header.appendChild(addBtn);
|
||||||
|
if (key !== null && !readonly) header.appendChild(removeBtn);
|
||||||
if (key !== null) header.appendChild(removeBtn);
|
|
||||||
|
|
||||||
wrapper.appendChild(header);
|
wrapper.appendChild(header);
|
||||||
wrapper.appendChild(children);
|
wrapper.appendChild(children);
|
||||||
@@ -308,18 +279,22 @@ function createJsonTree({
|
|||||||
input.className = "json-input string";
|
input.className = "json-input string";
|
||||||
input.value = value;
|
input.value = value;
|
||||||
|
|
||||||
|
if (readonly) {
|
||||||
|
input.disabled = true;
|
||||||
|
} else {
|
||||||
input.oninput = () => {
|
input.oninput = () => {
|
||||||
pushHistory();
|
pushHistory();
|
||||||
parent[key] = input.value;
|
parent[key] = input.value;
|
||||||
autoResize(input);
|
autoResize(input);
|
||||||
onChange(data);
|
onChange(data);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => autoResize(input), 0);
|
setTimeout(() => autoResize(input), 0);
|
||||||
|
|
||||||
wrapper.appendChild(keySpan);
|
wrapper.appendChild(keySpan);
|
||||||
wrapper.appendChild(input);
|
wrapper.appendChild(input);
|
||||||
if (key !== null) wrapper.appendChild(removeBtn);
|
if (key !== null && !readonly) wrapper.appendChild(removeBtn);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,18 +305,22 @@ function createJsonTree({
|
|||||||
input.className = "json-input number";
|
input.className = "json-input number";
|
||||||
input.value = value;
|
input.value = value;
|
||||||
|
|
||||||
|
if (readonly) {
|
||||||
|
input.disabled = true;
|
||||||
|
} else {
|
||||||
input.oninput = () => {
|
input.oninput = () => {
|
||||||
pushHistory();
|
pushHistory();
|
||||||
parent[key] = Number(input.value);
|
parent[key] = Number(input.value);
|
||||||
autoResize(input);
|
autoResize(input);
|
||||||
onChange(data);
|
onChange(data);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(() => autoResize(input), 0);
|
setTimeout(() => autoResize(input), 0);
|
||||||
|
|
||||||
wrapper.appendChild(keySpan);
|
wrapper.appendChild(keySpan);
|
||||||
wrapper.appendChild(input);
|
wrapper.appendChild(input);
|
||||||
if (key !== null) wrapper.appendChild(removeBtn);
|
if (key !== null && !readonly) wrapper.appendChild(removeBtn);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,15 +330,19 @@ function createJsonTree({
|
|||||||
input.type = "checkbox";
|
input.type = "checkbox";
|
||||||
input.checked = value;
|
input.checked = value;
|
||||||
|
|
||||||
|
if (readonly) {
|
||||||
|
input.disabled = true;
|
||||||
|
} else {
|
||||||
input.onchange = () => {
|
input.onchange = () => {
|
||||||
pushHistory();
|
pushHistory();
|
||||||
parent[key] = input.checked;
|
parent[key] = input.checked;
|
||||||
onChange(data);
|
onChange(data);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
wrapper.appendChild(keySpan);
|
wrapper.appendChild(keySpan);
|
||||||
wrapper.appendChild(input);
|
wrapper.appendChild(input);
|
||||||
if (key !== null) wrapper.appendChild(removeBtn);
|
if (key !== null && !readonly) wrapper.appendChild(removeBtn);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,8 +351,7 @@ function createJsonTree({
|
|||||||
|
|
||||||
wrapper.appendChild(keySpan);
|
wrapper.appendChild(keySpan);
|
||||||
wrapper.appendChild(span);
|
wrapper.appendChild(span);
|
||||||
|
if (key !== null && !readonly) wrapper.appendChild(removeBtn);
|
||||||
if (key !== null) wrapper.appendChild(removeBtn);
|
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
<span class="copy-icon" onclick="copyToClipboard(`${document.getElementById('pid').textContent}`)">⧉</span>
|
<span class="copy-icon" onclick="copyToClipboard(`${document.getElementById('pid').textContent}`)">⧉</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card" styles="max-height:350px;">
|
<div class="card">
|
||||||
<div class="table-wrapper">
|
<div class="table-wrapper" style="max-height:250px;height:100%">
|
||||||
<table id="releaseNotes">
|
<table id="releaseNotes">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -58,21 +58,6 @@
|
|||||||
data: [],
|
data: [],
|
||||||
buffer: 5,
|
buffer: 5,
|
||||||
rowHeight: 30,
|
rowHeight: 30,
|
||||||
filterConfig:{
|
|
||||||
exceptedColumns: [ 'Erledigt' ],
|
|
||||||
columnModes: {
|
|
||||||
'datetime': 'text',
|
|
||||||
'sAMAccountName': 'text',
|
|
||||||
'Note': 'text'
|
|
||||||
},
|
|
||||||
checkboxFilter: {
|
|
||||||
column: 'finish',
|
|
||||||
rules: [
|
|
||||||
{ label: 'Nur erledigte', test: v => v === true },
|
|
||||||
{ label: 'Nur unerledigte', test: v => v === false },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
customRender: (row, tr) => {
|
customRender: (row, tr) => {
|
||||||
createTd(tr,
|
createTd(tr,
|
||||||
`
|
`
|
||||||
@@ -87,13 +72,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
vt.addData(json.releaseNotes)
|
vt.addData(json.releaseNotes.sort((a, b) => new Date(b.datetime) - new Date(a.datetime)));
|
||||||
//document.querySelector('#package').innerHTML = JSON.stringify(json.package).split(',').join('<br>');
|
|
||||||
|
|
||||||
createJsonTree({
|
createJsonTree({
|
||||||
container: document.getElementById("package"),
|
container: document.getElementById("package"),
|
||||||
data: json.package,
|
data: json.package,
|
||||||
expandInitially: true
|
expandInitially: true,
|
||||||
|
readonly: true
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
pluginsTabWrapper.innerHTML = '';
|
pluginsTabWrapper.innerHTML = '';
|
||||||
|
|
||||||
const objectsContainer = document.createElement('div');
|
const objectsContainer = document.createElement('div');
|
||||||
objectsContainer.className = 'card static';
|
objectsContainer.className = 'card static row';
|
||||||
objectsContainer.style = ``;
|
objectsContainer.style = ``;
|
||||||
const card = document.createElement('div');
|
const card = document.createElement('div');
|
||||||
card.className = 'card static row';
|
card.className = 'card static row';
|
||||||
@@ -167,14 +167,14 @@
|
|||||||
if(typeof value === 'object') {
|
if(typeof value === 'object') {
|
||||||
const objectCard = document.createElement('div');
|
const objectCard = document.createElement('div');
|
||||||
objectCard.className = 'card static';
|
objectCard.className = 'card static';
|
||||||
objectCard.style = `min-height:400px;`;
|
objectCard.style = `flex:1;height:100%`;
|
||||||
objectCard.innerHTML = `
|
objectCard.innerHTML = `
|
||||||
<label style="font-weight:bold">${key}</label>
|
<label style="font-weight:bold">${key}</label>
|
||||||
<div style="overflow:auto" id="${metaData.name}-${key}"></div>
|
<div style="overflow:auto" id="${metaData.name}-${key}"></div>
|
||||||
`;
|
`;
|
||||||
objectsContainer.appendChild(objectCard);
|
objectsContainer.appendChild(objectCard);
|
||||||
pluginsTabWrapper.appendChild(objectsContainer);
|
pluginsTabWrapper.appendChild(objectsContainer);
|
||||||
const menu = createJsonTree({
|
createJsonTree({
|
||||||
container: document.getElementById(`${metaData.name}-${key}`),
|
container: document.getElementById(`${metaData.name}-${key}`),
|
||||||
data: metaData[key],
|
data: metaData[key],
|
||||||
onChange: (data) => { },
|
onChange: (data) => { },
|
||||||
|
|||||||
@@ -18,15 +18,15 @@
|
|||||||
"label": "Configs",
|
"label": "Configs",
|
||||||
"view": "serverconfig",
|
"view": "serverconfig",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
"defaultSize": {
|
||||||
|
"width": "900px",
|
||||||
|
"height": "900px"
|
||||||
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"Administration"
|
"Administration"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"defaultSize": {
|
|
||||||
"width": 800,
|
|
||||||
"height": 600
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -49,10 +49,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"defaultSize": {
|
|
||||||
"width": "1200px",
|
|
||||||
"height": "1200px"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -75,10 +71,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"defaultSize": {
|
|
||||||
"width": "900px",
|
|
||||||
"height": "800px"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -101,10 +93,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"defaultSize": {
|
|
||||||
"width": "900px",
|
|
||||||
"height": "500px"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -127,10 +115,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"defaultSize": {
|
|
||||||
"width": "460px",
|
|
||||||
"height": "515px"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,5 +54,12 @@
|
|||||||
"datetime": "2026-04-21",
|
"datetime": "2026-04-21",
|
||||||
"value": "Plugin-System + JSONtree bugfixes",
|
"value": "Plugin-System + JSONtree bugfixes",
|
||||||
"finish": true
|
"finish": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sAMAccountName": "manuel.sowada",
|
||||||
|
"plugin": "System",
|
||||||
|
"datetime": "2026-04-23",
|
||||||
|
"value": "Neues Stylesheet, integratedStartMenuItems JS > JSON, JSONtree Updates, OS-Styles (Mauszeiger, Scrollbalken, Responsive Design, Window-Resize)",
|
||||||
|
"finish": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ module.exports = {
|
|||||||
|
|
||||||
let context = fs.existsSync(pluginPath)
|
let context = fs.existsSync(pluginPath)
|
||||||
? service.get('fileSystemManager').loadJSON(pluginPath)
|
? service.get('fileSystemManager').loadJSON(pluginPath)
|
||||||
: (global.json.startMenuItems.live).find(item => item.name == name);
|
: (JSON.parse(JSON.stringify(global.json.startMenuItems.live))).find(item => item.name == name);
|
||||||
|
|
||||||
context.defaultSize =
|
context.defaultSize =
|
||||||
context.menu.items.find(item => item.label == viewLabel)?.defaultSize ||
|
context.menu.items.find(item => item.label == viewLabel)?.defaultSize ||
|
||||||
|
|||||||
2
utils.js
2
utils.js
@@ -30,7 +30,7 @@ module.exports = startMenuItems = async function (app, sAMAccountName) {
|
|||||||
return JSON.parse(JSON.stringify(obj));
|
return JSON.parse(JSON.stringify(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
const integratedStartmenuItems = safeClone(global.json.startMenuItems.live);
|
const integratedStartmenuItems = safeClone(service.get('fileSystemManager').loadJSON(global.json.startMenuItems.filePath));
|
||||||
|
|
||||||
const plugins = service
|
const plugins = service
|
||||||
.get('pluginManager')
|
.get('pluginManager')
|
||||||
|
|||||||
Reference in New Issue
Block a user