iobroker.alias-workbench 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +269 -224
- package/admin/alias-workbench.png +0 -0
- package/admin/alias-workbench.svg +13 -0
- package/admin/css/werkbank.css +69 -0
- package/admin/i18n/de.json +15 -1
- package/admin/i18n/en.json +15 -1
- package/admin/js/baum.js +12 -2
- package/admin/js/detail.js +119 -7
- package/admin/js/entwurf.js +93 -5
- package/admin/js/ergebnis.js +15 -2
- package/admin/js/erkennung.js +87 -0
- package/admin/js/quellentausch.js +16 -0
- package/admin/js/schreiben.js +30 -5
- package/admin/js/vorlagen.js +13 -4
- package/admin/js/zielleiste.js +70 -2
- package/admin/js/zuordnung.js +15 -0
- package/admin/js/zustandsliste.js +71 -16
- package/admin/tab.html +11 -0
- package/io-package.json +27 -14
- package/package.json +2 -3
package/admin/js/erkennung.js
CHANGED
|
@@ -22,6 +22,89 @@ export function rolleAusAusdruck(r) {
|
|
|
22
22
|
|
|
23
23
|
export function rolleVonPlatz(st) { return st.defaultRole || rolleAusAusdruck(st.role); }
|
|
24
24
|
|
|
25
|
+
/* Alle Schreibweisen, die ein Platz annimmt — nicht nur seine Vorgabe.
|
|
26
|
+
|
|
27
|
+
Der LOWBAT-Platz nennt als Vorgabe `indicator.maintenance.lowbat`,
|
|
28
|
+
sein Ausdruck erlaubt aber vier Formen:
|
|
29
|
+
|
|
30
|
+
/^indicator(\.maintenance)?\.(lowbat|battery)$/
|
|
31
|
+
|
|
32
|
+
Nur die Vorgabe in die Auswahlliste zu stellen hiess: Wer die Rolle
|
|
33
|
+
sucht, die sein eigenes Geraet traegt, findet sie nicht. hm-rpc
|
|
34
|
+
schreibt `indicator.lowbat`, alle elf Homematic-Vorlagen benutzen sie,
|
|
35
|
+
und die ioBroker-Rollenliste fuehrt beide nebeneinander — nur die
|
|
36
|
+
Werkbank kannte eine davon nicht (Ricardo, 06.09.2026).
|
|
37
|
+
|
|
38
|
+
Ausmultipliziert werden genau zwei Formen, weil nur die im Detector
|
|
39
|
+
vorkommen: Alternativen `(a|b)` und optionale Gruppen `(…)?`. Alles
|
|
40
|
+
andere — Zeichenklassen, `.*`, Verschachtelung — gibt leer zurueck;
|
|
41
|
+
dann bleibt es bei der Vorgaberolle. Lieber eine Schreibweise zu wenig
|
|
42
|
+
als eine erfundene in der Liste. */
|
|
43
|
+
export function schreibweisenAus(r) {
|
|
44
|
+
if (!r) { return []; }
|
|
45
|
+
var q = (r.source !== undefined) ? r.source : String(r);
|
|
46
|
+
if (q.charAt(0) !== '^' || q.slice(-1) !== '$') { return []; }
|
|
47
|
+
q = q.slice(1, -1);
|
|
48
|
+
|
|
49
|
+
var teile = [''];
|
|
50
|
+
var rest = q;
|
|
51
|
+
var sicher = 0;
|
|
52
|
+
while (rest && sicher++ < 40) {
|
|
53
|
+
var g = /^\(([^()]*)\)(\?)?/.exec(rest);
|
|
54
|
+
if (g) {
|
|
55
|
+
var wahl = g[1].split('|');
|
|
56
|
+
if (g[2]) { wahl = wahl.concat(['']); } /* optional: auch weglassen */
|
|
57
|
+
var neu = [];
|
|
58
|
+
teile.forEach(function (v) {
|
|
59
|
+
wahl.forEach(function (w) { neu.push(v + w.split('\\').join('')); });
|
|
60
|
+
});
|
|
61
|
+
teile = neu;
|
|
62
|
+
rest = rest.slice(g[0].length);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
var lit = /^(\\.|[A-Za-z0-9_.])+/.exec(rest);
|
|
66
|
+
if (!lit) { return []; } /* etwas Unbekanntes */
|
|
67
|
+
var text = lit[0].split('\\').join('');
|
|
68
|
+
teile = teile.map(function (v) { return v + text; });
|
|
69
|
+
rest = rest.slice(lit[0].length);
|
|
70
|
+
}
|
|
71
|
+
if (rest) { return []; }
|
|
72
|
+
|
|
73
|
+
var gut = [];
|
|
74
|
+
teile.forEach(function (t) {
|
|
75
|
+
if (/^[A-Za-z0-9_]+([.][A-Za-z0-9_]+)*$/.test(t) && gut.indexOf(t) === -1) { gut.push(t); }
|
|
76
|
+
});
|
|
77
|
+
return gut;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Rollen, die der Detector aus Ruecksicht auf alte Adapter noch annimmt,
|
|
81
|
+
die aber nicht mehr benutzt werden sollen. Aus der Tabelle „Deprecated
|
|
82
|
+
role aliases" in ioBroker.docs (docs/en/dev/stateroles.md, gelesen am
|
|
83
|
+
06.09.2026) — dort steht zu jeder auch, was stattdessen gilt.
|
|
84
|
+
|
|
85
|
+
Sie stehen hier, weil die Zerlegung oben sonst gerade sie in die
|
|
86
|
+
Auswahlliste holt: `indicator(\.maintenance)?\.(lowbat|battery)`
|
|
87
|
+
erlaubt eben auch `indicator.battery`. Eine laengere Liste ist kein
|
|
88
|
+
Gewinn, wenn die Haelfte davon veraltet ist.
|
|
89
|
+
|
|
90
|
+
Vorgaberollen des Detectors werden NICHT gefiltert: was er selbst als
|
|
91
|
+
Vorgabe fuehrt, gilt, auch wenn die Doku es anders saehe. Gefiltert
|
|
92
|
+
wird nur, was diese Zerlegung zusaetzlich vorschlaegt. */
|
|
93
|
+
var VERALTET = {};
|
|
94
|
+
('action.close action.close.blind action.close.tilt action.home action.next ' +
|
|
95
|
+
'action.open action.open.blind action.open.tilt action.pause action.play ' +
|
|
96
|
+
'action.prev action.stop action.stop.blind action.stop.tilt ' +
|
|
97
|
+
'indicator.battery indicator.fire indicator.flood ' +
|
|
98
|
+
'indicator.maintenance.battery indicator.unreach ' +
|
|
99
|
+
'level.thermostat sensor.co sensor.fire sensor.flood ' +
|
|
100
|
+
'state.active state.alarm.co state.alarm.fire state.alarm.flood state.co ' +
|
|
101
|
+
'state.door state.fire state.flood state.light state.motion state.window ' +
|
|
102
|
+
'switch.active switch.autofocus switch.autowhitebalance switch.boost ' +
|
|
103
|
+
'switch.brightness switch.nightmode switch.party ' +
|
|
104
|
+
'value.accuracy value.brush value.brush.side value.elevation ' +
|
|
105
|
+
'value.latitude value.longitude value.radius value.sensors'
|
|
106
|
+
).split(' ').forEach(function (r) { VERALTET[r] = 1; });
|
|
107
|
+
|
|
25
108
|
export var ROLLEN = (function () {
|
|
26
109
|
if (!D) { return []; }
|
|
27
110
|
var m = {};
|
|
@@ -29,6 +112,10 @@ export var ROLLEN = (function () {
|
|
|
29
112
|
D.patterns[t].states.forEach(function (st) {
|
|
30
113
|
var r = rolleVonPlatz(st);
|
|
31
114
|
if (r) { m[r] = 1; }
|
|
115
|
+
/* Dazu, was der Platz sonst noch annimmt — ohne das Veraltete. */
|
|
116
|
+
schreibweisenAus(st.role).forEach(function (x) {
|
|
117
|
+
if (!VERALTET[x]) { m[x] = 1; }
|
|
118
|
+
});
|
|
32
119
|
});
|
|
33
120
|
});
|
|
34
121
|
['state', 'text', 'json', 'value'].forEach(function (r) { m[r] = 1; });
|
|
@@ -355,6 +355,22 @@ function zeichneTausch() {
|
|
|
355
355
|
var z1 = el('div');
|
|
356
356
|
z1.appendChild(el('b', null, tr('swap.from') + ' '));
|
|
357
357
|
z1.appendChild(el('span', 'sn', alt || tr('swap.unknown')));
|
|
358
|
+
/* Den Namen dahinter, wo er mehr sagt als die Kennung.
|
|
359
|
+
|
|
360
|
+
`hm-rpc.0.0000DBE9A2B8AF` sagt einem nichts; woran man das Geraet
|
|
361
|
+
erkennt, steht allein im Namen (Ricardo, 06.09.2026). Dieselbe Regel
|
|
362
|
+
wie im Baum: gleicht der Name dem letzten Stueck der Kennung, bringt
|
|
363
|
+
er nichts und bleibt weg.
|
|
364
|
+
|
|
365
|
+
Ist das Geraet weg — der Normalfall bei „Geraet kaputt" —, gibt es
|
|
366
|
+
kein Objekt und damit keinen Namen mehr. Dann steht dort wie bisher
|
|
367
|
+
nur die Kennung, und die Zeile darunter sagt, dass es sie nicht mehr
|
|
368
|
+
gibt. */
|
|
369
|
+
var altObj = alt && S.objects[alt];
|
|
370
|
+
var altName = altObj ? txt(altObj.common && altObj.common.name).trim() : '';
|
|
371
|
+
if (altName && altName !== String(alt).split('.').pop()) {
|
|
372
|
+
z1.appendChild(el('span', 'leise', ' ' + altName));
|
|
373
|
+
}
|
|
358
374
|
kopf.appendChild(z1);
|
|
359
375
|
if (alt && !S.objects[alt] && !kindZustaende(alt).length) {
|
|
360
376
|
kopf.appendChild(el('div', 'hint', tr('swap.gone')));
|
package/admin/js/schreiben.js
CHANGED
|
@@ -18,7 +18,8 @@ import {
|
|
|
18
18
|
ordnerUnterAlias,
|
|
19
19
|
gemeinsameKanaele,
|
|
20
20
|
kennungtauglich,
|
|
21
|
-
entwurfFuer
|
|
21
|
+
entwurfFuer,
|
|
22
|
+
aliasFuer
|
|
22
23
|
} from './entwurf.js';
|
|
23
24
|
import { zeichneErgebnis } from './ergebnis.js';
|
|
24
25
|
|
|
@@ -488,6 +489,20 @@ export function zeigeTrockenlauf(alleAusgaenge) {
|
|
|
488
489
|
}
|
|
489
490
|
body.appendChild(kopf);
|
|
490
491
|
|
|
492
|
+
/* Dieselbe Auskunft wie in der Zielleiste, noch einmal hier - der
|
|
493
|
+
Trockenlauf ist die letzte Stelle vor dem Schreiben, und wer den
|
|
494
|
+
Balken oben ueberliest, soll es spaetestens jetzt sehen: es gibt
|
|
495
|
+
schon einen Alias auf diese Quelle, und der bleibt stehen. */
|
|
496
|
+
var zwQuelle = S.entwurf && S.entwurf.kanal;
|
|
497
|
+
var zwZiel = S.entwurf && (S.entwurf.ziel || S.entwurf.kanal);
|
|
498
|
+
var zwAlt = zwQuelle ? aliasFuer(zwQuelle) : null;
|
|
499
|
+
if (zwAlt && S.objects[zwAlt] && zwAlt !== zwZiel) {
|
|
500
|
+
var zwK = el('div', 'aside w');
|
|
501
|
+
zwK.style.marginBottom = '11px';
|
|
502
|
+
zwK.appendChild(el('b', null, tr('target.twinExists', zwAlt)));
|
|
503
|
+
body.appendChild(zwK);
|
|
504
|
+
}
|
|
505
|
+
|
|
491
506
|
if (weg.length) {
|
|
492
507
|
var wk = el('div', 'card');
|
|
493
508
|
wk.style.marginBottom = '11px';
|
|
@@ -986,17 +1001,27 @@ export function sucheInSkripten(kennung, fertig) {
|
|
|
986
1001
|
} catch { fertigMit(); }
|
|
987
1002
|
}
|
|
988
1003
|
|
|
989
|
-
export function zeigeVerlegen() {
|
|
1004
|
+
export function zeigeVerlegen(altVorgabe, zielVorgabe) {
|
|
990
1005
|
/* Der Knopf steht auch an der Quelle, sobald es den Alias gibt (T1).
|
|
991
1006
|
Dort ist S.current die Quelle, nicht der Alias - gemeint ist immer
|
|
992
1007
|
das Ziel des Entwurfs. Genauso haelt es zeigeLoeschen; zeigeTausch
|
|
993
1008
|
tat es bis 05.09.2026 nicht, und beide Knoepfe waren an der Quelle
|
|
994
|
-
sichtbar, aber wirkungslos: kein Dialog, keine Meldung.
|
|
995
|
-
|
|
1009
|
+
sichtbar, aber wirkungslos: kein Dialog, keine Meldung.
|
|
1010
|
+
|
|
1011
|
+
Die zwei Vorgaben kommen vom Knopf „stattdessen verlegen" in der
|
|
1012
|
+
Zielleiste: dort ist das Ziel des Entwurfs der NEUE Pfad, den es
|
|
1013
|
+
noch gar nicht gibt - ohne Vorgabe stiege der Dialog gleich in der
|
|
1014
|
+
ersten Zeile wieder aus. Verlegt wird der vorhandene Alias
|
|
1015
|
+
(`altVorgabe`), und die Felder stehen schon auf dem, was in der
|
|
1016
|
+
Zielleiste getippt wurde (`zielVorgabe`). */
|
|
1017
|
+
var alt = (typeof altVorgabe === 'string' && altVorgabe) ||
|
|
1018
|
+
(S.entwurf && (S.entwurf.ziel || S.entwurf.kanal)) || S.current;
|
|
996
1019
|
if (!alt || alt.indexOf('alias.') !== 0 || !S.objects[alt]) { return; }
|
|
997
1020
|
S.verlegeZiel = alt;
|
|
998
1021
|
|
|
999
|
-
var
|
|
1022
|
+
var vorbelegt = (typeof zielVorgabe === 'string' && zielVorgabe &&
|
|
1023
|
+
zielVorgabe.indexOf('alias.') === 0) ? zielVorgabe : alt;
|
|
1024
|
+
var teile = vorbelegt.split('.');
|
|
1000
1025
|
var name0 = teile.pop();
|
|
1001
1026
|
var ordner0 = teile.join('.');
|
|
1002
1027
|
|
package/admin/js/vorlagen.js
CHANGED
|
@@ -370,8 +370,17 @@ export function schreibZiel(z, kanal, auf) {
|
|
|
370
370
|
return befehlMoeglich(kanal, pfad) ? (kanal + '.' + pfad) : '';
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
/* Vorlage auf einen Kanal anwenden → Entwurf.
|
|
374
|
-
|
|
373
|
+
/* Vorlage auf einen Kanal anwenden → Entwurf.
|
|
374
|
+
|
|
375
|
+
`auchOhneTreffer` laesst einen Entwurf auch dann entstehen, wenn keine
|
|
376
|
+
einzige Zeile der Vorlage eine Quelle am Geraet findet. Das gilt nur fuer
|
|
377
|
+
die Wahl von Hand: Genau dafuer ist das Auswahlfeld gedacht — „sonst steht
|
|
378
|
+
man bei einem Geraet, das noch nichts gesendet hat, ohne jede Moeglichkeit
|
|
379
|
+
da". Bis 06.09.2026 fiel gerade dieser Fall durch das Sieb unten, und der
|
|
380
|
+
Wechsel scheiterte still (Ricardo). Die automatische Erkennung ruft ohne
|
|
381
|
+
die Fahne auf und bleibt unveraendert — dort waere ein Entwurf ohne eine
|
|
382
|
+
einzige Zeile ein Fehlgriff. */
|
|
383
|
+
export function wendeAn(v, kanal, gruende, instanz, auchOhneTreffer) {
|
|
375
384
|
var auf = function (t) { return setzeInstanz(t, v, instanz); };
|
|
376
385
|
var e = { kanal: kanal, states: [], want: v.geraetetyp, wantAuto: v.geraetetyp,
|
|
377
386
|
alleMuster: false, vorschlag: true, roh: false,
|
|
@@ -499,7 +508,7 @@ export function wendeAn(v, kanal, gruende, instanz) {
|
|
|
499
508
|
});
|
|
500
509
|
});
|
|
501
510
|
|
|
502
|
-
return e.states.length ? e : null;
|
|
511
|
+
return (e.states.length || auchOhneTreffer) ? e : null;
|
|
503
512
|
}
|
|
504
513
|
|
|
505
514
|
/* Beste Vorlage suchen und anwenden. */
|
|
@@ -521,7 +530,7 @@ export function vorschlag(kanal, vorlagenId, instanz) {
|
|
|
521
530
|
gewaehlt = treffer[0];
|
|
522
531
|
}
|
|
523
532
|
|
|
524
|
-
var e = wendeAn(gewaehlt.vorlage, kanal, gewaehlt.gruende, gewaehlt.instanz);
|
|
533
|
+
var e = wendeAn(gewaehlt.vorlage, kanal, gewaehlt.gruende, gewaehlt.instanz, !!vorlagenId);
|
|
525
534
|
if (!e) { return null; }
|
|
526
535
|
if (!vorlagenId && gewaehlt.passt) {
|
|
527
536
|
var gleichAuf = treffer.filter(function (t) { return t.punkte === gewaehlt.punkte; });
|
package/admin/js/zielleiste.js
CHANGED
|
@@ -13,6 +13,7 @@ import { enumListe } from './aufzaehlungen.js';
|
|
|
13
13
|
import { enumZeile, setzeZiel } from './zuordnung.js';
|
|
14
14
|
import { aliasFuer, ordnerUnterAlias, kennungtauglich } from './entwurf.js';
|
|
15
15
|
import { zeichneErgebnis, entwurfAngefasst, angebotFrisch } from './ergebnis.js';
|
|
16
|
+
import { zeigeVerlegen } from './schreiben.js';
|
|
16
17
|
|
|
17
18
|
export function baueZielleiste(host, e) {
|
|
18
19
|
var istQuelle = S.current.indexOf('alias.') !== 0;
|
|
@@ -224,7 +225,23 @@ export function baueZielleiste(host, e) {
|
|
|
224
225
|
});
|
|
225
226
|
iO.addEventListener('change', uebernehmen);
|
|
226
227
|
iO.addEventListener('keydown', function (ev) {
|
|
227
|
-
|
|
228
|
+
/* Escape heisst „doch nicht" — die Liste zu machen reicht dafuer
|
|
229
|
+
nicht, der getippte Text muss auch weg. Sonst steht er weiter im
|
|
230
|
+
Feld und wird beim Verlassen uebernommen: Wer Escape drueckt und
|
|
231
|
+
danebenklickt, legt den Alias unter einem Ordner an, den er
|
|
232
|
+
gerade verworfen zu haben glaubte.
|
|
233
|
+
|
|
234
|
+
Musterfeld (`musterwahl.js`, ruft mBeschriften) und
|
|
235
|
+
Aufzaehlungsfeld (`zuordnung.js`, setzt ei.value zurueck) machen
|
|
236
|
+
das laengst; hier und im Namensfeld daneben fehlte es
|
|
237
|
+
(Ricardo, 06.09.2026). */
|
|
238
|
+
if (ev.key === 'Escape') {
|
|
239
|
+
iO.value = (e.zielOrdner === 'alias.0') ? '' : e.zielOrdner.slice('alias.0.'.length);
|
|
240
|
+
xBtn.hidden = !iO.value;
|
|
241
|
+
schliessen();
|
|
242
|
+
iO.blur();
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
228
245
|
if (ev.key === 'ArrowDown' || ev.key === 'ArrowUp') {
|
|
229
246
|
if (vlist.hidden) { malen(true); return; }
|
|
230
247
|
ev.preventDefault();
|
|
@@ -263,6 +280,14 @@ export function baueZielleiste(host, e) {
|
|
|
263
280
|
var iN2 = el('input', 'tx');
|
|
264
281
|
iN2.type = 'text';
|
|
265
282
|
iN2.value = e.zielName;
|
|
283
|
+
/* Dasselbe fuer den Namen. Hier gab es bisher gar keinen
|
|
284
|
+
Tastenhandler — Escape tat nichts, der getippte Name blieb stehen
|
|
285
|
+
und wurde beim Verlassen uebernommen (Ricardo, 06.09.2026). */
|
|
286
|
+
iN2.addEventListener('keydown', function (ev) {
|
|
287
|
+
if (ev.key !== 'Escape') { return; }
|
|
288
|
+
iN2.value = e.zielName;
|
|
289
|
+
iN2.blur();
|
|
290
|
+
});
|
|
266
291
|
iN2.addEventListener('change', function () {
|
|
267
292
|
/* Dieselbe Regel wie im Vorschlag und im Verlege-Dialog. Die eigene
|
|
268
293
|
Fassung hier liess Punkte und doppelte Unterstriche stehen - ein
|
|
@@ -291,7 +316,13 @@ export function baueZielleiste(host, e) {
|
|
|
291
316
|
Aenderung folgen, und der Blick ist beim angefassten Feld, nicht
|
|
292
317
|
beim anderen. Der Text nennt deshalb die Wirkung woanders. */
|
|
293
318
|
var angebot = null;
|
|
294
|
-
|
|
319
|
+
/* Frueher hing hier zusaetzlich `!aliasFuer(e.kanal)` - an einem
|
|
320
|
+
Geraet, das schon einen Alias hat, kam die Frage also nie. Gedacht
|
|
321
|
+
war das als „am fertigen Alias wird nicht mehr geraten"; in
|
|
322
|
+
Wahrheit ist gerade das der Fall, in dem sie gebraucht wird: wer
|
|
323
|
+
den Ordner eines vorhandenen Alias umschreibt, zieht um, und der
|
|
324
|
+
Raum soll mit (Ricardo, 06.09.2026). */
|
|
325
|
+
if (e.zuletzt === 'ordner') {
|
|
295
326
|
var otx = String(e.zielOrdner || '').slice('alias.0.'.length);
|
|
296
327
|
if (otx && otx.indexOf('.') === -1) {
|
|
297
328
|
var vorhandenerRaum = enumListe('rooms', true).filter(function (r) {
|
|
@@ -322,6 +353,42 @@ export function baueZielleiste(host, e) {
|
|
|
322
353
|
setTimeout(function () { iO.focus(); }, 0);
|
|
323
354
|
}
|
|
324
355
|
|
|
356
|
+
/* Der Zwilling: es gibt schon einen Alias auf diese Quelle, und das
|
|
357
|
+
Ziel zeigt woandershin.
|
|
358
|
+
|
|
359
|
+
Die Werkbank weiss das in diesem Moment - `aliasFuer` liefert den
|
|
360
|
+
alten Pfad -, sagte es aber nirgends. Am Chip stand nur „wird neu
|
|
361
|
+
angelegt", was stimmt und die Haelfte verschweigt: der alte bleibt
|
|
362
|
+
stehen, und aus einem Umbenennen des Ordners wird lautlos ein
|
|
363
|
+
zweiter Alias auf dieselbe Quelle (Ricardo, 06.09.2026, am
|
|
364
|
+
Bastelzimmer_Decklenlicht_RGB).
|
|
365
|
+
|
|
366
|
+
Verboten wird nichts. Zwei Aliase auf eine Quelle sind ein
|
|
367
|
+
ordentlicher Fall - einer fuers Licht, einer fuer den Verbrauch;
|
|
368
|
+
„alle anlegen" tut bei mehreren Ausgaengen nichts anderes. Es
|
|
369
|
+
fehlte die Auskunft, nicht die Sperre. Wer wirklich einen zweiten
|
|
370
|
+
will, drueckt denselben Knopf wie bisher und weiss jetzt, was er
|
|
371
|
+
tut; wer umziehen wollte, hat den Weg dafuer daneben.
|
|
372
|
+
|
|
373
|
+
Ohne Rueckprobe ueber `quelleVon`: an einem Homematic-Kanal
|
|
374
|
+
(…B8AF.0) zeigt die Quelle des Alias auf das Geraet (…B8AF), die
|
|
375
|
+
Probe schluege fehl und der Hinweis bliebe genau dort aus, wo er
|
|
376
|
+
gebraucht wird. `aliasFuer` ist dieselbe Funktion, mit der die
|
|
377
|
+
Werkbank auch „zum Alias →" und ihre Zielvorschlaege bestimmt -
|
|
378
|
+
irrt sie hier, irrt sie dort ebenso. Und der Hinweis haelt
|
|
379
|
+
niemanden auf. */
|
|
380
|
+
var zwilling = null;
|
|
381
|
+
var vorhAlias = aliasFuer(e.kanal);
|
|
382
|
+
if (vorhAlias && S.objects[vorhAlias] && vorhAlias !== e.ziel) {
|
|
383
|
+
var zw = el('div', 'uebernahme zwilling');
|
|
384
|
+
zw.appendChild(el('span', 'zq', tr('target.twinExists', vorhAlias)));
|
|
385
|
+
var vb = el('button', 'btn mini', tr('target.moveInstead'));
|
|
386
|
+
vb.title = tr('target.moveInsteadHint');
|
|
387
|
+
vb.addEventListener('click', function () { zeigeVerlegen(vorhAlias, e.ziel); });
|
|
388
|
+
zw.appendChild(vb);
|
|
389
|
+
zwilling = zw;
|
|
390
|
+
}
|
|
391
|
+
|
|
325
392
|
/* Das Angebot ganz ans Ende der Leiste.
|
|
326
393
|
|
|
327
394
|
Zuerst hing es direkt hinter dem Ordnerfeld - und weil es eine
|
|
@@ -329,6 +396,7 @@ export function baueZielleiste(host, e) {
|
|
|
329
396
|
Namensfeld stand ploetzlich darunter statt daneben. Eine Zeile,
|
|
330
397
|
die umbricht, gehoert hinter das, was in der Zeile bleiben soll. */
|
|
331
398
|
if (angebot) { zb.appendChild(angebot); }
|
|
399
|
+
if (zwilling) { zb.appendChild(zwilling); }
|
|
332
400
|
|
|
333
401
|
zb.appendChild(ergebnis);
|
|
334
402
|
|
package/admin/js/zuordnung.js
CHANGED
|
@@ -577,6 +577,21 @@ export function uebernehmeBestand(e) {
|
|
|
577
577
|
stehen; neue Punkte bekommen den neuen Namen. */
|
|
578
578
|
if (q.read && kenntQuelle[q.read] && !S.objects[e.ziel + '.' + kenntQuelle[q.read].n]) {
|
|
579
579
|
var vorhanden = kenntQuelle[q.read];
|
|
580
|
+
/* Die Zeile bekommt den Namen aus dem Alias — und damit einen
|
|
581
|
+
anderen, als die Erkennung eben gesehen hat. `platzVon` kennt
|
|
582
|
+
noch den Vorlagennamen, die Zeile heisst jetzt anders, und die
|
|
583
|
+
Platzpruefung findet nichts: Am `Bastelzimmer_Licht` stand nach
|
|
584
|
+
einem Wechsel auf die Steckdosen-Vorlage „kein Platz im
|
|
585
|
+
Steckdose-Muster" an ON_ACTUAL, obwohl der Platz ACTUAL frei
|
|
586
|
+
besetzt war. Nach jedem beliebigen Neuzeichnen war es weg
|
|
587
|
+
(Ricardo, 06.09.2026).
|
|
588
|
+
|
|
589
|
+
`bestandZog` loest genau dafuer das einmalige Nachzeichnen aus.
|
|
590
|
+
Gesetzt wurde es bisher nur in `vomAliasUebernehmen` — und das
|
|
591
|
+
steigt bei gesetzter Vorlage sofort aus, damit der Vorlagenstand
|
|
592
|
+
gilt. Die Umbenennung findet aber trotzdem statt, also gehoert
|
|
593
|
+
die Fahne hierher. */
|
|
594
|
+
if (vorhanden.n !== n) { e.bestandZog = true; }
|
|
580
595
|
vorhanden.n = n;
|
|
581
596
|
vorhanden.on = true;
|
|
582
597
|
vorhanden.ausBestand = true;
|
|
@@ -11,7 +11,7 @@ import { el } from './basis.js';
|
|
|
11
11
|
import { tr } from './sprache.js';
|
|
12
12
|
import { erkenneEntwurf, musterVon, rolleVonPlatz } from './erkennung.js';
|
|
13
13
|
import { kindZustaende, wertVon, fmt } from './werte.js';
|
|
14
|
-
import { steuerKanaele, vorlagenAbweichung, waehle } from './entwurf.js';
|
|
14
|
+
import { steuerKanaele, vorlagenAbweichung, bestandsAbweichung, waehle } from './entwurf.js';
|
|
15
15
|
import { musterName } from './musternamen.js';
|
|
16
16
|
import { detailZeile } from './detail.js';
|
|
17
17
|
import { rateAnzahl, rateZurueck, rateZurueckEine, rateBehalten } from './vorschlagen.js';
|
|
@@ -206,6 +206,10 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
var bar = el('div', 'listbar');
|
|
209
|
+
/* Wird beim Zeichnen der Zeilen weiter unten hochgezaehlt; die Legende
|
|
210
|
+
dazu haengt sich erst danach in die Leiste, weil vorher niemand
|
|
211
|
+
weiss, ob es ueberhaupt eine braucht. */
|
|
212
|
+
var ohnePlatzZahl = 0;
|
|
209
213
|
var an = e.states.filter(function (s) { return s.on; }).length;
|
|
210
214
|
bar.appendChild(document.createTextNode(tr('list.willBeCreated')));
|
|
211
215
|
bar.appendChild(el('span', 'cnt', tr('list.countOf', an, e.states.length)));
|
|
@@ -325,8 +329,19 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
|
|
|
325
329
|
e.states.forEach(function (s, i) {
|
|
326
330
|
var pl = platzVon[s.n];
|
|
327
331
|
var unfertig = (!s.n || !s.srcR);
|
|
328
|
-
|
|
332
|
+
/* Angehakt, vollstaendig, aber ohne Platz im Muster. Frueher stand
|
|
333
|
+
dazu in JEDER betroffenen Zeile derselbe Satz — bei einem
|
|
334
|
+
Thermostat mit 42 Punkten zwanzigmal dasselbe, und die Spalte
|
|
335
|
+
wurde so breit, dass Rolle und Wert wegrutschten (Ricardo,
|
|
336
|
+
06.09.2026). Jetzt traegt die Zeile eine Marke, der Satz steht
|
|
337
|
+
einmal als Legende ueber der Liste, und der lange Text haengt als
|
|
338
|
+
Hinweis an der Zeile. */
|
|
339
|
+
var ohnePlatz = (s.on && !unfertig && !pl);
|
|
340
|
+
if (ohnePlatz) { ohnePlatzZahl++; }
|
|
341
|
+
var row = el('div', 'erow' + (s.on ? '' : ' skip') + (S.openRow === i ? ' open' : '') +
|
|
342
|
+
(ohnePlatz ? ' ohneplatz' : ''));
|
|
329
343
|
row.tabIndex = 0;
|
|
344
|
+
if (ohnePlatz) { row.title = tr('pattern.noPlaceLong', musterName(e.want) || e.want || '?'); }
|
|
330
345
|
|
|
331
346
|
var cbw = el('span');
|
|
332
347
|
var cb = document.createElement('input');
|
|
@@ -359,20 +374,49 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
|
|
|
359
374
|
if (s.manuell) { n3.appendChild(el('span', 'hand', tr('list.byHand'))); }
|
|
360
375
|
if (s.geaendert) { n3.appendChild(el('span', 'geae', tr('list.changed'))); }
|
|
361
376
|
/* Was die Vorlage anders will, steht an der Zeile - sonst sieht man
|
|
362
|
-
es erst im Trockenlauf (Ricardo, 25.08.2026).
|
|
363
|
-
|
|
377
|
+
es erst im Trockenlauf (Ricardo, 25.08.2026).
|
|
378
|
+
|
|
379
|
+
Nicht mehr an `!s.geaendert` gebunden: Seit man ein einzelnes Feld
|
|
380
|
+
aus der Vorlage uebernehmen kann, ist die Zeile danach „geaendert"
|
|
381
|
+
— und haette die Marke daran gehangen, waeren die uebrigen
|
|
382
|
+
Abweichungen in dem Moment unsichtbar geworden. Massgeblich ist,
|
|
383
|
+
ob wirklich noch etwas abweicht. Eine Zeile kann beides tragen:
|
|
384
|
+
„geaendert" und „weicht von der Vorlage ab" (06.09.2026). */
|
|
385
|
+
if (s.on) {
|
|
364
386
|
var abw = vorlagenAbweichung(s);
|
|
365
387
|
if (abw.length) {
|
|
366
|
-
/*
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
388
|
+
/* Nur, DASS etwas abweicht — nicht was.
|
|
389
|
+
|
|
390
|
+
Die Marke nannte frueher den Wert der ersten Abweichung
|
|
391
|
+
(„Vorlage: indicator.lowbat"). Bei mehreren Feldern log sie
|
|
392
|
+
damit: sie zeigte eines und verschwieg die anderen, und lang
|
|
393
|
+
war sie obendrein. Welches Feld es betrifft, sieht man
|
|
394
|
+
aufgeklappt an der Markierung; der Tooltip hier zaehlt alle
|
|
395
|
+
auf (Ricardo, 06.09.2026). */
|
|
396
|
+
var av = el('span', 'geae tplabw', tr('list.tplDiffers'));
|
|
371
397
|
av.title = abw.map(function (x) {
|
|
372
398
|
return x.feld + ': ' + (x.jetzt || '—') + ' → ' + (x.vorlage || '—');
|
|
373
399
|
}).join(String.fromCharCode(10));
|
|
374
400
|
n3.appendChild(av);
|
|
375
401
|
}
|
|
402
|
+
/* Und dieselbe Auskunft gegen den gespeicherten Alias.
|
|
403
|
+
|
|
404
|
+
Wer das Muster oder die Vorlage wechselt, bekommt die Rollen
|
|
405
|
+
angepasst — das ist gewollt (`switch.light` passt auf kein
|
|
406
|
+
socket-SET). Nur sah man an der Zeile nicht, dass damit etwas
|
|
407
|
+
anderes geschrieben wuerde als bisher dasteht; sichtbar war es
|
|
408
|
+
allein an den Chips oben und im Trockenlauf. Drei Aussagen, drei
|
|
409
|
+
Marken, jede mit eigener Bedeutung: „geaendert" heisst, der
|
|
410
|
+
Nutzer war es; „weicht von der Vorlage ab" vergleicht mit der
|
|
411
|
+
Vorlage; diese hier mit der Datenbank (Ricardo, 06.09.2026). */
|
|
412
|
+
var bAbw = bestandsAbweichung(s, e.ziel);
|
|
413
|
+
if (bAbw.length) {
|
|
414
|
+
var bv = el('span', 'geae bstabw', tr('list.aliasDiffers'));
|
|
415
|
+
bv.title = bAbw.map(function (x) {
|
|
416
|
+
return x.feld + ': ' + (x.bestand || '—') + ' → ' + (x.jetzt || '—');
|
|
417
|
+
}).join(String.fromCharCode(10));
|
|
418
|
+
n3.appendChild(bv);
|
|
419
|
+
}
|
|
376
420
|
}
|
|
377
421
|
/* Die Marke ist zugleich der Griff: solange sie steht, ist die Zeile
|
|
378
422
|
unbestaetigt und faellt beim Zuruecknehmen. Ein Haken laesst sie
|
|
@@ -418,14 +462,12 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
|
|
|
418
462
|
var pe = el('em', null, pl);
|
|
419
463
|
pe.title = tr('pattern.slotName', pl, musterName(e.want) || e.want || '?');
|
|
420
464
|
n3.appendChild(pe);
|
|
421
|
-
} else if (!pl) {
|
|
422
|
-
/* Frueher stand der Vermerk nur an Zeilen, die das info-Muster
|
|
423
|
-
aufnaehme (imInfo). SABOTAGE mit indicator.alarm nimmt aber
|
|
424
|
-
nicht mal das - solche Zeilen blieben stumm, und oben stand
|
|
425
|
-
„3/7 belegt“ bei vier Haken ohne jede Erklaerung (Ricardo,
|
|
426
|
-
25.08.2026). Angehakt ohne Platz heisst immer: sagen. */
|
|
427
|
-
n3.appendChild(el('em', null, tr('pattern.noPlaceIn', musterName(e.want) || e.want || '?')));
|
|
428
465
|
}
|
|
466
|
+
/* Kein Vermerk mehr je Zeile: die Marke an der Zeile und die
|
|
467
|
+
Legende ueber der Liste sagen dasselbe, einmal statt zwanzigmal.
|
|
468
|
+
Dass es ueberhaupt gesagt wird, bleibt wichtig — frueher blieben
|
|
469
|
+
solche Zeilen stumm, und oben stand „3/7 belegt“ bei vier Haken
|
|
470
|
+
ohne jede Erklaerung (Ricardo, 25.08.2026). */
|
|
429
471
|
}
|
|
430
472
|
row.appendChild(n3);
|
|
431
473
|
|
|
@@ -511,5 +553,18 @@ export function baueListe(host, e, pl, rateKnopf, musterBlock) {
|
|
|
511
553
|
zeichneErgebnis();
|
|
512
554
|
});
|
|
513
555
|
card.appendChild(add);
|
|
556
|
+
|
|
557
|
+
/* Die Legende zum Streifen — einmal, und nur wenn es etwas zu erklaeren
|
|
558
|
+
gibt. Sie steht in der Leiste ueber der Liste, gleich neben der Zahl:
|
|
559
|
+
dort sucht man die Erklaerung fuer „11 von 42", nicht am Fuss. */
|
|
560
|
+
if (ohnePlatzZahl) {
|
|
561
|
+
var lg = el('span', 'legende');
|
|
562
|
+
lg.appendChild(el('span', 'lgmarke'));
|
|
563
|
+
lg.appendChild(document.createTextNode(
|
|
564
|
+
tr('pattern.noPlaceIn', musterName(e.want) || e.want || '?')));
|
|
565
|
+
lg.title = tr('pattern.noPlaceLong', musterName(e.want) || e.want || '?');
|
|
566
|
+
bar.insertBefore(lg, bar.querySelector('.sp2'));
|
|
567
|
+
}
|
|
568
|
+
|
|
514
569
|
host.appendChild(card);
|
|
515
570
|
}
|
package/admin/tab.html
CHANGED
|
@@ -144,5 +144,16 @@
|
|
|
144
144
|
<div class="dfoot"><button class="btn" data-close>Schließen</button></div>
|
|
145
145
|
</dialog>
|
|
146
146
|
|
|
147
|
+
<!-- Wer im Baum weiterklickt, verlor bis zum 06.09.2026 seine Aenderungen
|
|
148
|
+
ohne ein Wort (Ricardo). Der Text wird zur Laufzeit gesetzt. -->
|
|
149
|
+
<dialog id="dlg-leave">
|
|
150
|
+
<h3 id="leave-titel">Ungespeicherte Änderungen</h3>
|
|
151
|
+
<div class="dbody"><p id="leave-body"></p></div>
|
|
152
|
+
<div class="dfoot">
|
|
153
|
+
<button class="btn" id="btn-leave-stay">Hierbleiben</button>
|
|
154
|
+
<button class="btn primary" id="btn-leave-go">Verwerfen und wechseln</button>
|
|
155
|
+
</div>
|
|
156
|
+
</dialog>
|
|
157
|
+
|
|
147
158
|
</body>
|
|
148
159
|
</html>
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "alias-workbench",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.2",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.8.2": {
|
|
7
|
+
"en": "A second alias on the same source is now announced instead of created silently — with a button to move the existing one instead. Switching to a template that finds nothing now works. Roles the workbench adapted are marked and can be taken back. Escape discards in every field of the target bar. New adapter icon.",
|
|
8
|
+
"de": "Ein zweiter Alias auf dieselbe Quelle wird jetzt angesagt statt stillschweigend angelegt — daneben ein Knopf, der stattdessen den vorhandenen verlegt. Der Wechsel auf eine Vorlage, die nichts findet, greift jetzt. Angepasste Rollen sind markiert und lassen sich zurückholen. Escape verwirft in jedem Feld des Zielbalkens. Neues Adaptersymbol.",
|
|
9
|
+
"ru": "Второй алиас на тот же источник теперь объявляется, а не создаётся молча — рядом кнопка, чтобы вместо этого перенести существующий. Переключение на шаблон, который ничего не находит, теперь работает. Изменённые роли помечаются и могут быть возвращены. Escape отменяет ввод в каждом поле целевой строки. Новый значок адаптера.",
|
|
10
|
+
"pt": "Um segundo alias sobre a mesma fonte passa a ser anunciado em vez de criado em silêncio — com um botão para mover o existente. A mudança para um modelo que não encontra nada passa a funcionar. Os papéis adaptados são assinalados e podem ser revertidos. Escape descarta em todos os campos da barra de destino. Novo ícone do adaptador.",
|
|
11
|
+
"nl": "Een tweede alias op dezelfde bron wordt nu gemeld in plaats van stil aangemaakt — met een knop om de bestaande te verplaatsen. Overschakelen naar een sjabloon dat niets vindt werkt nu. Aangepaste rollen worden gemarkeerd en kunnen worden teruggehaald. Escape verwerpt in elk veld van de doelbalk. Nieuw adapterpictogram.",
|
|
12
|
+
"fr": "Un deuxième alias sur la même source est désormais signalé au lieu d’être créé en silence — avec un bouton pour déplacer celui qui existe. Le passage à un modèle qui ne trouve rien fonctionne maintenant. Les rôles adaptés sont marqués et peuvent être repris. Échap annule dans chaque champ de la barre de destination. Nouvelle icône d’adaptateur.",
|
|
13
|
+
"it": "Un secondo alias sulla stessa sorgente viene ora annunciato invece che creato in silenzio — con un pulsante per spostare quello esistente. Il passaggio a un modello che non trova nulla ora funziona. I ruoli adattati sono contrassegnati e si possono ripristinare. Esc annulla in ogni campo della barra di destinazione. Nuova icona dell’adattatore.",
|
|
14
|
+
"es": "Un segundo alias sobre la misma fuente ahora se anuncia en lugar de crearse en silencio — con un botón para mover el existente. Cambiar a una plantilla que no encuentra nada ya funciona. Los roles adaptados se marcan y se pueden recuperar. Escape descarta en cada campo de la barra de destino. Nuevo icono del adaptador.",
|
|
15
|
+
"pl": "Drugi alias na to samo źródło jest teraz zapowiadany, a nie tworzony po cichu — obok przycisk, który zamiast tego przenosi istniejący. Przełączenie na szablon, który nic nie znajduje, teraz działa. Zmienione role są oznaczone i można je cofnąć. Escape odrzuca w każdym polu paska celu. Nowa ikona adaptera.",
|
|
16
|
+
"uk": "Другий аліас на те саме джерело тепер оголошується, а не створюється мовчки — поруч кнопка, щоб натомість перенести наявний. Перемикання на шаблон, який нічого не знаходить, тепер працює. Змінені ролі позначені й їх можна повернути. Escape скасовує в кожному полі цільового рядка. Нова піктограма адаптера.",
|
|
17
|
+
"zh-cn": "同一数据源上的第二个别名现在会有提示,而不是被静默创建——旁边有按钮可改为移动已有的别名。切换到没有匹配项的模板现在也能生效。被调整过的角色会被标记,并可撤回。Escape 在目标栏的每个字段中都会放弃输入。新的适配器图标。"
|
|
18
|
+
},
|
|
19
|
+
"0.8.1": {
|
|
20
|
+
"en": "Published through npm trusted publishing (OIDC) — releases are signed with provenance from now on. No functional changes.",
|
|
21
|
+
"de": "Veröffentlichung über npm Trusted Publishing (OIDC) — Ausgaben sind ab jetzt mit Herkunftsnachweis signiert. Keine funktionalen Änderungen.",
|
|
22
|
+
"ru": "Публикация через npm trusted publishing (OIDC) — выпуски теперь подписаны с подтверждением происхождения. Функциональных изменений нет.",
|
|
23
|
+
"pt": "Publicação através de npm trusted publishing (OIDC) — as versões passam a ser assinadas com proveniência. Sem alterações funcionais.",
|
|
24
|
+
"nl": "Publicatie via npm trusted publishing (OIDC) — releases worden voortaan ondertekend met herkomst. Geen functionele wijzigingen.",
|
|
25
|
+
"fr": "Publication via npm trusted publishing (OIDC) — les versions sont désormais signées avec provenance. Aucun changement fonctionnel.",
|
|
26
|
+
"it": "Pubblicazione tramite npm trusted publishing (OIDC) — le versioni sono ora firmate con provenienza. Nessuna modifica funzionale.",
|
|
27
|
+
"es": "Publicación mediante npm trusted publishing (OIDC): las versiones se firman con procedencia a partir de ahora. Sin cambios funcionales.",
|
|
28
|
+
"pl": "Publikacja przez npm trusted publishing (OIDC) — wydania są od teraz podpisywane z poświadczeniem pochodzenia. Bez zmian funkcjonalnych.",
|
|
29
|
+
"uk": "Публікація через npm trusted publishing (OIDC) — випуски тепер підписані з підтвердженням походження. Функціональних змін немає.",
|
|
30
|
+
"zh-cn": "通过 npm 可信发布(OIDC)发布——此后的版本均带有来源签名。无功能变更。"
|
|
31
|
+
},
|
|
6
32
|
"0.8.0": {
|
|
7
33
|
"en": "Ready for the repository: settings page in eleven languages, ESLint and a CI workshop, checks that run before every commit. The buttons at the bottom now follow the mode. New description.",
|
|
8
34
|
"de": "Bereit fürs Repository: Einstellungsseite in elf Sprachen, ESLint und eine CI-Werkstatt, Prüfungen vor jedem Commit. Die Knöpfe unten richten sich jetzt nach dem Modus. Neue Beschreibung.",
|
|
@@ -15,19 +41,6 @@
|
|
|
15
41
|
"pl": "Gotowe do repozytorium: strona ustawień w jedenastu językach, ESLint i warsztat CI, sprawdzenia przed każdym commitem. Przyciski na dole podążają teraz za trybem. Nowy opis.",
|
|
16
42
|
"uk": "Готово до репозиторію: сторінка налаштувань одинадцятьма мовами, ESLint і CI-майстерня, перевірки перед кожним комітом. Кнопки внизу тепер залежать від режиму. Новий опис.",
|
|
17
43
|
"zh-cn": "已为仓库做好准备:十一种语言的设置页面、ESLint 与 CI 工作流、每次提交前的检查。底部按钮现在会随模式变化。全新的说明文字。"
|
|
18
|
-
},
|
|
19
|
-
"0.7.12": {
|
|
20
|
-
"en": "Tab rebuilt as ES modules; eleven Homematic templates; settings page; swap the source of an alias; picture preview beside room and function.",
|
|
21
|
-
"de": "Reiter in ES-Modulen; elf Homematic-Vorlagen; Einstellungsseite; Quelle eines Alias tauschen; Bildvorschau neben Raum und Funktion.",
|
|
22
|
-
"ru": "Вкладка перестроена на ES-модули; одиннадцать шаблонов Homematic; страница настроек; замена источника алиаса; предпросмотр значка рядом с комнатой и функцией.",
|
|
23
|
-
"pt": "Separador reconstruído como módulos ES; onze modelos Homematic; página de definições; trocar a fonte de um alias; pré-visualização da imagem junto a divisão e função.",
|
|
24
|
-
"nl": "Tabblad herbouwd als ES-modules; elf Homematic-sjablonen; instellingenpagina; de bron van een alias wisselen; afbeeldingsvoorbeeld naast ruimte en functie.",
|
|
25
|
-
"fr": "Onglet reconstruit en modules ES ; onze modèles Homematic ; page de réglages ; changer la source d'un alias ; aperçu de l'image à côté de la pièce et de la fonction.",
|
|
26
|
-
"it": "Scheda ricostruita come moduli ES; undici modelli Homematic; pagina delle impostazioni; sostituzione della sorgente di un alias; anteprima dell’immagine accanto a stanza e funzione.",
|
|
27
|
-
"es": "Pestaña reconstruida como módulos ES; once plantillas Homematic; página de ajustes; cambiar la fuente de un alias; vista previa de la imagen junto a la habitación y la función.",
|
|
28
|
-
"pl": "Zakładka przebudowana na moduły ES; jedenaście szablonów Homematic; strona ustawień; zamiana źródła aliasu; podgląd obrazka obok pomieszczenia i funkcji.",
|
|
29
|
-
"uk": "Вкладку перебудовано на ES-модулі; одинадцять шаблонів Homematic; сторінка налаштувань; заміна джерела аліаса; попередній перегляд зображення поруч із кімнатою та функцією.",
|
|
30
|
-
"zh-cn": "选项卡重构为 ES 模块;十一个 Homematic 模板;设置页面;更换别名的来源;房间和功能旁的图片预览。"
|
|
31
44
|
}
|
|
32
45
|
},
|
|
33
46
|
"titleLang": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.alias-workbench",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Creates aliases the comfortable way — devices that vis, Alexa and the device adapter understand. Templates do the work: shipped ones for HomeMatic and Tasmota, your own for everything else. Live values while you build, dry run before anything is written.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ricardo Hipp",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"@iobroker/eslint-config": "^2.3.4",
|
|
20
20
|
"@iobroker/testing": "^5.3.0",
|
|
21
21
|
"@iobroker/type-detector": "^6.0.0",
|
|
22
|
-
"esbuild": "^0.28.2"
|
|
23
|
-
"mocha": "^12.0.0"
|
|
22
|
+
"esbuild": "^0.28.2"
|
|
24
23
|
},
|
|
25
24
|
"scripts": {
|
|
26
25
|
"build": "esbuild src/detector-bundle.js --bundle --minify --format=iife --target=es2019 --outfile=admin/detector.js",
|