Add German localization and styling for administration module
- Introduced new JavaScript file `fis.admin_txt_de.js` for German translations of administration-related terms and messages. - Created `fis.admin.css` for styling the administration interface, including layout, cards, and buttons. - Added `fis.admin.de.js` for the main functionality of the administration module, implementing features such as system status checks and email testing. - Minified version of the German JavaScript file created as `fis.admin.de.min.js`. - Minified CSS file created as `fis.admin.min.css` for optimized loading.
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
/* basics */
|
||||
/* Color SCHEME */
|
||||
/* #8396bd */
|
||||
/* #e3e6e6 */
|
||||
/* #ffffff */
|
||||
/* #262626 */
|
||||
/* #262626 */
|
||||
/* #e3e6e6 */
|
||||
/* #FFC801 */
|
||||
/* #ffff4a */
|
||||
/* media breaks */
|
||||
/* other */
|
||||
/* mixin */
|
||||
/* basics */
|
||||
/* Color SCHEME */
|
||||
/* #1b4379 #0033b3 */
|
||||
/*neu: #56a532 ; alt: rgb(32,144,119);*/
|
||||
/* 10% sw */
|
||||
.admfrm {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.admfrm .adm_sec {
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
color: rgb(27, 67, 121);
|
||||
margin: 1.5rem 0 0.75rem;
|
||||
border-bottom: 2px solid rgb(27, 67, 121);
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
.admfrm .adm_sec:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.admfrm .adm_err {
|
||||
padding: 1rem;
|
||||
color: #b00020;
|
||||
font-weight: bold;
|
||||
}
|
||||
.admfrm .adm_grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
|
||||
gap: 1rem;
|
||||
align-items: start;
|
||||
}
|
||||
.admfrm .adm_card {
|
||||
border: 1px solid #d5d5d5;
|
||||
border-radius: 0.4rem;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 3px rgba(50, 50, 50, 0.12);
|
||||
overflow: hidden;
|
||||
}
|
||||
.admfrm .adm_card.adm_card_wide {
|
||||
grid-column: 1/-1;
|
||||
}
|
||||
.admfrm .adm_card_hd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.6rem 0.85rem;
|
||||
background: rgb(27, 67, 121);
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
.admfrm .adm_card_hd > span:first-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.admfrm .adm_card_bd {
|
||||
padding: 0.6rem 0.85rem;
|
||||
}
|
||||
.admfrm .adm_card_ft {
|
||||
padding: 0.5rem 0.85rem 0.75rem;
|
||||
text-align: right;
|
||||
}
|
||||
.admfrm table.adm_kv {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
.admfrm table.adm_kv td {
|
||||
padding: 0.25rem 0.35rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
vertical-align: top;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.admfrm table.adm_kv td.k {
|
||||
color: #666;
|
||||
white-space: nowrap;
|
||||
width: 40%;
|
||||
}
|
||||
.admfrm table.adm_kv td.v {
|
||||
word-break: break-word;
|
||||
}
|
||||
.admfrm table.adm_kv tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.admfrm .adm_probe {
|
||||
margin-top: 0.6rem;
|
||||
padding-top: 0.5rem;
|
||||
border-top: 1px dashed #ddd;
|
||||
font-size: 0.88rem;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_msg {
|
||||
font-weight: 600;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_det {
|
||||
color: #555;
|
||||
word-break: break-word;
|
||||
margin-top: 0.15rem;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_dur {
|
||||
color: #999;
|
||||
margin-top: 0.15rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_metrics {
|
||||
margin-top: 0.35rem;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_metrics .adm_metric {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
padding: 0.1rem 0;
|
||||
border-bottom: 1px dotted #eee;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_metrics .adm_metric:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_metrics .adm_metric .adm_metric_k {
|
||||
color: #555;
|
||||
word-break: break-word;
|
||||
}
|
||||
.admfrm .adm_probe .adm_probe_metrics .adm_metric .adm_metric_v {
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.admfrm {
|
||||
/* startup checks list */
|
||||
}
|
||||
.admfrm .adm_checks {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.25rem 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check .adm_check_k {
|
||||
color: #333;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check .adm_check_v {
|
||||
font-weight: bold;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.05rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check .adm_check_ok {
|
||||
background: #e2f3da;
|
||||
color: #2f6d18;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check .adm_check_fail {
|
||||
background: #f3ded9;
|
||||
color: #c0341d;
|
||||
}
|
||||
.admfrm .adm_checks .adm_check .adm_check_skipped {
|
||||
background: #ececec;
|
||||
color: #777;
|
||||
}
|
||||
.admfrm {
|
||||
/* status pill */
|
||||
}
|
||||
.admfrm .adm_pill {
|
||||
display: inline-block;
|
||||
padding: 0.1rem 0.55rem;
|
||||
border-radius: 1rem;
|
||||
font-size: 0.78rem;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
background: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.admfrm .adm_pill_ok {
|
||||
background: rgb(86, 165, 50);
|
||||
}
|
||||
.admfrm .adm_pill_error {
|
||||
background: #c0341d;
|
||||
}
|
||||
.admfrm .adm_pill_disabled {
|
||||
background: #888;
|
||||
}
|
||||
.admfrm .adm_pill_unconfigured {
|
||||
background: #d69100;
|
||||
}
|
||||
.admfrm .adm_pill_checking {
|
||||
background: #2a72c4;
|
||||
}
|
||||
.admfrm {
|
||||
/* boolean chips */
|
||||
}
|
||||
.admfrm .adm_bool {
|
||||
display: inline-block;
|
||||
padding: 0 0.4rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.admfrm .adm_bool_y {
|
||||
background: #e2f3da;
|
||||
color: #2f6d18;
|
||||
}
|
||||
.admfrm .adm_bool_n {
|
||||
background: #f3e0dd;
|
||||
color: #9c2a17;
|
||||
}
|
||||
.admfrm .adm_env {
|
||||
font-size: 0.8rem;
|
||||
font-weight: normal;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
.admfrm .adm_env.adm_env_test {
|
||||
background: #13a143;
|
||||
}
|
||||
.admfrm .adm_btn {
|
||||
cursor: pointer;
|
||||
border-radius: 0.28rem;
|
||||
padding: 0.2rem 0.6rem;
|
||||
font-size: 0.85rem;
|
||||
border: 1px solid #ababab;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
}
|
||||
.admfrm .adm_btn.adm_btn_primary {
|
||||
background-color: rgb(86, 165, 50);
|
||||
border-color: rgb(69.68, 133.688372093, 40.511627907);
|
||||
color: #fff;
|
||||
}
|
||||
.admfrm .adm_card_hd .adm_btn {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
color: #fff;
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.adm_note {
|
||||
margin-top: 0.75rem;
|
||||
padding: 0.5rem 0.6rem;
|
||||
background: #f3f6fb;
|
||||
border-left: 3px solid rgb(27, 67, 121);
|
||||
font-size: 0.85rem;
|
||||
color: #444;
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
let $adt = {
|
||||
mdl: 'Administration'
|
||||
, sub_info: 'System'
|
||||
, sub_status: 'Status & Konnektivität'
|
||||
, sub_tests: 'Tests'
|
||||
// startup checks widget (non-refreshable)
|
||||
, startup: 'Startup-Prüfungen'
|
||||
, startup_notrun: 'Die Startup-Prüfungen sind deaktiviert oder wurden noch nicht ausgeführt (Fuchs:StartupChecks:Enabled).'
|
||||
, startup_on: 'Host'
|
||||
, startup_at: 'Ausgeführt (UTC)'
|
||||
, chk_ok: 'OK'
|
||||
, chk_fail: 'Fehler'
|
||||
, chk_skipped: 'übersprungen'
|
||||
, chk_KeyVault: 'Azure Key Vault'
|
||||
, chk_Database: 'SQL-Datenbank'
|
||||
, chk_MFR: 'MFR (ERP)'
|
||||
, chk_PdfLicense: 'Spire.PDF-Lizenz'
|
||||
, chk_Mailer: 'E-Mail (Startup-Probe)'
|
||||
// system info
|
||||
, host: 'Host / Server'
|
||||
, machine: 'Hostname'
|
||||
, os: 'Betriebssystem'
|
||||
, framework: 'Framework'
|
||||
, env: 'Umgebung'
|
||||
, testdep: 'Test-Deployment'
|
||||
, pid: 'Prozess-ID'
|
||||
, uptime: 'Laufzeit'
|
||||
, since: 'Start (UTC)'
|
||||
, hours: 'Std.'
|
||||
// status cards
|
||||
, db: 'SQL-Datenbank'
|
||||
, mail: 'E-Mail-Dienst'
|
||||
, blob: 'Azure Blob Storage'
|
||||
, mfr: 'MFR (ERP)'
|
||||
, kv: 'Azure Key Vault'
|
||||
// labels
|
||||
, server: 'Server'
|
||||
, catalog: 'Datenbank'
|
||||
, login: 'Login'
|
||||
, mailer: 'Mailer aktiv'
|
||||
, baseurl: 'Base-URL'
|
||||
, account: 'Account'
|
||||
, serverid: 'Server-ID'
|
||||
, token: 'Token hinterlegt'
|
||||
, override: 'OverrideRecipient'
|
||||
, overrideActive: 'Umleitung aktiv'
|
||||
, enabled: 'Aktiviert'
|
||||
, configured: 'Konfiguriert'
|
||||
, invContainer: 'Rechnungs-Container'
|
||||
, remContainer: 'Mahnungs-Container'
|
||||
, host_l: 'Host'
|
||||
, creds: 'Zugangsdaten hinterlegt'
|
||||
, sync: 'Sync aktiv'
|
||||
, vault: 'Vault-URI'
|
||||
, appname: 'App-Präfix'
|
||||
, seccount: 'Verwaltete Secrets'
|
||||
, clientreg: 'Client registriert'
|
||||
, duration: 'Dauer'
|
||||
, checked: 'Geprüft'
|
||||
, detail: 'Detail'
|
||||
// status values
|
||||
, st_ok: 'OK'
|
||||
, st_error: 'Fehler'
|
||||
, st_disabled: 'Deaktiviert'
|
||||
, st_unconfigured: 'Nicht konfiguriert'
|
||||
, st_checking: 'Prüfe…'
|
||||
// actions
|
||||
, refresh: 'Aktualisieren'
|
||||
, refreshAll: 'Alle prüfen'
|
||||
, yes: 'Ja'
|
||||
, no: 'Nein'
|
||||
// test email
|
||||
, testmail: 'Test-E-Mail'
|
||||
, testmail_btn: 'Test-E-Mail senden'
|
||||
, tm_to: 'Empfänger'
|
||||
, tm_subject: 'Betreff'
|
||||
, tm_body: 'Nachricht'
|
||||
, tm_hint: 'Der Versand nutzt die normale E-Mail-Pipeline; bei gesetztem OverrideRecipient wird die Nachricht dorthin umgeleitet.'
|
||||
, tm_sent: 'Test-E-Mail übergeben.'
|
||||
, tm_failed: 'Test-E-Mail konnte nicht gesendet werden.'
|
||||
, tm_default_subject: 'Fuchs Intranet – Test-E-Mail'
|
||||
, tm_default_body: 'Dies ist eine Test-E-Mail aus dem Administrationsbereich des Fuchs Intranet.'
|
||||
, loadfail: 'Der Systemstatus konnte nicht geladen werden.'
|
||||
};
|
||||
|
||||
let $adm = {
|
||||
init2: function () {
|
||||
// No external libraries needed — go straight to render.
|
||||
$ocms.getScript([], function () { $adm.init3(); });
|
||||
},
|
||||
init3: function () {
|
||||
$fis.cf(true);
|
||||
$fis.lf(true);
|
||||
$('#activemodule').text($adt.mdl);
|
||||
$adm.topbar();
|
||||
let frm = $$.dc('admfrm', $('#contentframe')).ldng(1);
|
||||
$adm.load(frm);
|
||||
},
|
||||
topbar: function () {
|
||||
return $('#topbar').ocmsmenu([
|
||||
{ lbl: $adt.refreshAll, id: 'adm_refresh_all', ico: 'glyphicon glyphicon-refresh', fnc: function () { $adm.init3(); } }
|
||||
]);
|
||||
},
|
||||
load: function (frm) {
|
||||
$ocms.postXT({
|
||||
url: $ocms.url('admin/status'), success: function (r) {
|
||||
frm.empty();
|
||||
$adm.render(frm, r.info || {}, r.probes || []);
|
||||
}, error: function () {
|
||||
frm.empty();
|
||||
$$.dc('adm_err', frm).text($adt.loadfail);
|
||||
}, complete: function () { frm.ldng(0); }
|
||||
});
|
||||
},
|
||||
render: function (frm, info, probes) {
|
||||
let pmap = {};
|
||||
$.each(probes, function (i, p) { pmap[p.component] = p; });
|
||||
|
||||
$$.dc('adm_sec', frm).text($adt.sub_info);
|
||||
$adm.sysCard(frm, info);
|
||||
$adm.startupCard(frm, info.startupChecks);
|
||||
|
||||
$$.dc('adm_sec', frm).text($adt.sub_status);
|
||||
let grid = $$.dc('adm_grid', frm);
|
||||
$adm.dbCard(grid, info.database || {}, pmap.database);
|
||||
$adm.mailCard(grid, info.email || {});
|
||||
$adm.blobCard(grid, info.blob || {}, pmap.blob);
|
||||
$adm.mfrCard(grid, info.mfr || {}, pmap.mfr);
|
||||
$adm.kvCard(grid, info.keyVault || {}, pmap.keyvault);
|
||||
},
|
||||
|
||||
/* ── generic building blocks ─────────────────────────────────────────── */
|
||||
kvTable: function (parent, rows) {
|
||||
let t = $$.tbl().addClass('adm_kv');
|
||||
$.each(rows || [], function (i, r) {
|
||||
if (!r) { return true; }
|
||||
let tr = $$.tr(t);
|
||||
$$.td(tr).addClass('k').text(r[0] == null ? '' : String(r[0]));
|
||||
let v = $$.td(tr).addClass('v');
|
||||
if (r[1] instanceof jQuery) { v.append(r[1]); } else { v.text(r[1] == null ? '' : String(r[1])); }
|
||||
});
|
||||
if (parent instanceof jQuery) { parent.append(t); }
|
||||
return t;
|
||||
},
|
||||
yesNo: function (b) {
|
||||
return $$.sc('adm_bool adm_bool_' + (b ? 'y' : 'n'), b ? $adt.yes : $adt.no);
|
||||
},
|
||||
setPill: function (pill, probe) {
|
||||
probe = probe || {};
|
||||
let st = probe.status || 'unconfigured';
|
||||
let lbl = {
|
||||
ok: $adt.st_ok, error: $adt.st_error, disabled: $adt.st_disabled,
|
||||
unconfigured: $adt.st_unconfigured, checking: $adt.st_checking
|
||||
}[st] || st;
|
||||
pill.attr('class', 'adm_pill adm_pill_' + st).text(lbl);
|
||||
return pill;
|
||||
},
|
||||
|
||||
/* Connectivity card with a live status pill + per-card refresh button. */
|
||||
probeCard: function (grid, title, component, cfgRows, probe) {
|
||||
let card = $$.dc('adm_card', grid);
|
||||
let hd = $$.dc('adm_card_hd', card);
|
||||
$$.s(title).appendTo(hd);
|
||||
let pill = $$.sc('adm_pill').appendTo(hd);
|
||||
let rbtn = $$.bbtn($adt.refresh, 'adm_btn').appendTo(hd);
|
||||
let bd = $$.dc('adm_card_bd', card);
|
||||
$adm.kvTable(bd, cfgRows);
|
||||
|
||||
let pf = $$.dc('adm_probe', bd);
|
||||
let msg = $$.dc('adm_probe_msg', pf);
|
||||
let met = $$.dc('adm_probe_metrics', pf);
|
||||
let det = $$.dc('adm_probe_det', pf);
|
||||
let dur = $$.dc('adm_probe_dur', pf);
|
||||
let apply = function (p) {
|
||||
p = p || {};
|
||||
$adm.setPill(pill, p);
|
||||
msg.text(p.message || '');
|
||||
met.empty();
|
||||
$.each(p.metrics || [], function (i, m) {
|
||||
let row = $$.dc('adm_metric', met);
|
||||
$$.sc('adm_metric_k').text(m.label || '').appendTo(row);
|
||||
$$.sc('adm_metric_v').text(m.value == null ? '' : String(m.value)).appendTo(row);
|
||||
});
|
||||
det.text(p.detail || '');
|
||||
dur.text(p.durationMs != null ? (p.durationMs + ' ms') : '');
|
||||
};
|
||||
apply(probe);
|
||||
|
||||
rbtn.click(function () {
|
||||
$adm.setPill(pill, { status: 'checking' });
|
||||
msg.text(''); met.empty(); det.text(''); dur.text('');
|
||||
$ocms.postXT({
|
||||
url: $ocms.url('admin/probe/' + component), success: function (r) {
|
||||
apply(r.probe);
|
||||
}, error: function () {
|
||||
$adm.setPill(pill, { status: 'error' });
|
||||
msg.text($adt.st_error);
|
||||
}
|
||||
});
|
||||
});
|
||||
return card;
|
||||
},
|
||||
|
||||
/* ── individual cards ────────────────────────────────────────────────── */
|
||||
sysCard: function (frm, info) {
|
||||
let card = $$.dc('adm_card adm_card_wide', frm);
|
||||
let hd = $$.dc('adm_card_hd', card);
|
||||
$$.s($adt.host).appendTo(hd);
|
||||
let env = $$.sc('adm_env').text(info.environment || '');
|
||||
if (info.isTestDeployment === true) { env.aC('adm_env_test'); }
|
||||
env.appendTo(hd);
|
||||
let bd = $$.dc('adm_card_bd', card);
|
||||
$adm.kvTable(bd, [
|
||||
[$adt.machine, info.machineName],
|
||||
[$adt.os, info.osDescription],
|
||||
[$adt.framework, info.frameworkDescription],
|
||||
[$adt.env, info.environment],
|
||||
[$adt.testdep, $adm.yesNo(info.isTestDeployment === true)],
|
||||
[$adt.pid, info.processId],
|
||||
[$adt.since, info.processStartUtc ? fdt(info.processStartUtc) : ''],
|
||||
[$adt.uptime, (info.uptimeHours != null ? (info.uptimeHours + ' ' + $adt.hours) : '')]
|
||||
]);
|
||||
},
|
||||
/* Non-refreshable widget: the one-shot startup self-test result captured at boot. */
|
||||
startupCard: function (frm, sc) {
|
||||
let card = $$.dc('adm_card adm_card_wide', frm);
|
||||
let hd = $$.dc('adm_card_hd', card);
|
||||
$$.s($adt.startup).appendTo(hd);
|
||||
let bd = $$.dc('adm_card_bd', card);
|
||||
|
||||
if (!sc || sc.ran !== true) {
|
||||
$adm.setPill($$.sc('adm_pill').appendTo(hd), { status: 'disabled' });
|
||||
$$.dc('adm_note', bd).text($adt.startup_notrun);
|
||||
return;
|
||||
}
|
||||
|
||||
let items = sc.items || [];
|
||||
let anyFail = false;
|
||||
$.each(items, function (i, it) { if (it.enabled === true && it.ok !== true) { anyFail = true; } });
|
||||
$adm.setPill($$.sc('adm_pill').appendTo(hd), { status: anyFail ? 'error' : 'ok' });
|
||||
|
||||
$adm.kvTable(bd, [
|
||||
[$adt.startup_on, sc.machineName],
|
||||
[$adt.startup_at, sc.completedUtc ? fdt(sc.completedUtc) : '']
|
||||
]);
|
||||
|
||||
let list = $$.dc('adm_checks', bd);
|
||||
$.each(items, function (i, it) {
|
||||
let row = $$.dc('adm_check', list);
|
||||
$$.sc('adm_check_k').text($adt['chk_' + it.name] || it.name).appendTo(row);
|
||||
let stt = it.enabled !== true ? 'skipped' : (it.ok === true ? 'ok' : 'fail');
|
||||
let lbl = { ok: $adt.chk_ok, fail: $adt.chk_fail, skipped: $adt.chk_skipped }[stt];
|
||||
$$.sc('adm_check_v adm_check_' + stt).text(lbl).appendTo(row);
|
||||
});
|
||||
},
|
||||
dbCard: function (grid, d, probe) {
|
||||
$adm.probeCard(grid, $adt.db, 'database', [
|
||||
[$adt.configured, $adm.yesNo(d.configured === true)],
|
||||
[$adt.server, d.server],
|
||||
[$adt.catalog, d.catalog],
|
||||
[$adt.login, d.userId]
|
||||
], probe);
|
||||
},
|
||||
mailCard: function (grid, e) {
|
||||
let card = $$.dc('adm_card', grid);
|
||||
let hd = $$.dc('adm_card_hd', card);
|
||||
$$.s($adt.mail).appendTo(hd);
|
||||
$adm.setPill($$.sc('adm_pill').appendTo(hd), { status: e.mailerEnabled === true ? 'ok' : 'disabled' });
|
||||
let bd = $$.dc('adm_card_bd', card);
|
||||
let rows = [
|
||||
[$adt.mailer, $adm.yesNo(e.mailerEnabled === true)],
|
||||
[$adt.baseurl, e.baseUrl],
|
||||
[$adt.account, e.accountId],
|
||||
[$adt.serverid, e.serverId],
|
||||
[$adt.token, $adm.yesNo(e.tokenConfigured === true)],
|
||||
[$adt.overrideActive, $adm.yesNo(e.overrideActive === true)]
|
||||
];
|
||||
if (e.overrideActive === true) { rows.push([$adt.override, e.overrideRecipient]); }
|
||||
$adm.kvTable(bd, rows);
|
||||
let ft = $$.dc('adm_card_ft', card);
|
||||
$$.bbtn($adt.testmail_btn, 'adm_btn adm_btn_primary').appendTo(ft).click($adm.testMailDlg);
|
||||
},
|
||||
blobCard: function (grid, b, probe) {
|
||||
$adm.probeCard(grid, $adt.blob, 'blob', [
|
||||
[$adt.enabled, $adm.yesNo(b.enabled === true)],
|
||||
[$adt.configured, $adm.yesNo(b.configured === true)],
|
||||
[$adt.invContainer, b.invoiceContainer],
|
||||
[$adt.remContainer, b.reminderContainer]
|
||||
], probe);
|
||||
},
|
||||
mfrCard: function (grid, m, probe) {
|
||||
$adm.probeCard(grid, $adt.mfr, 'mfr', [
|
||||
[$adt.host_l, m.host],
|
||||
[$adt.creds, $adm.yesNo(m.credentialsConfigured === true)],
|
||||
[$adt.sync, $adm.yesNo(m.syncEnabled === true)]
|
||||
], probe);
|
||||
},
|
||||
kvCard: function (grid, k, probe) {
|
||||
$adm.probeCard(grid, $adt.kv, 'keyvault', [
|
||||
[$adt.vault, k.vaultUri],
|
||||
[$adt.appname, k.appName],
|
||||
[$adt.seccount, k.managedSecretCount],
|
||||
[$adt.clientreg, $adm.yesNo(k.clientRegistered === true)]
|
||||
], probe);
|
||||
},
|
||||
|
||||
/* ── test email ──────────────────────────────────────────────────────── */
|
||||
testMailDlg: function () {
|
||||
$ocms.dlgform([
|
||||
{ name: 'to', label: $adt.tm_to, type: 'email', required: true, value: ($ocms.auth.email || '') },
|
||||
{ name: 'subject', label: $adt.tm_subject, type: 'string', required: true, value: $adt.tm_default_subject },
|
||||
{ name: 'body', label: $adt.tm_body, type: 'text', required: true, value: $adt.tm_default_body }
|
||||
], {
|
||||
title: $adt.testmail,
|
||||
button: $adt.testmail_btn,
|
||||
size: [420, 560],
|
||||
addcontent: $$.dc('adm_note').text($adt.tm_hint),
|
||||
submit: function (e) {
|
||||
let c = $(this).ldng(1);
|
||||
let qs = c.serializeObject(true, { typedvalues: true });
|
||||
$ocms.postXT({
|
||||
url: $ocms.url('admin/testmail'), data: qs, timeout: 60000, success: function (r) {
|
||||
let res = r.result || {};
|
||||
alert(res.message || (res.sent ? $adt.tm_sent : $adt.tm_failed));
|
||||
c.trigger('modal_close');
|
||||
}, error: function () {
|
||||
alert($adt.tm_failed);
|
||||
}, complete: function () { c.ldng(0); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
let $$adm = { init2: $adm.init2, auth: {} };
|
||||
export default $$adm;
|
||||
+1
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -0,0 +1 @@
|
||||
.admfrm{padding:1.5rem}.admfrm .adm_sec{font-size:1.2rem;font-weight:700;color:#1b4379;margin:1.5rem 0 .75rem;border-bottom:2px solid #1b4379;padding-bottom:.25rem}.admfrm .adm_sec:first-child{margin-top:0}.admfrm .adm_err{padding:1rem;color:#b00020;font-weight:700}.admfrm .adm_grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(22rem,1fr));gap:1rem;align-items:start}.admfrm .adm_card{border:1px solid #d5d5d5;border-radius:.4rem;background:#fff;box-shadow:0 1px 3px rgba(50,50,50,.12);overflow:hidden}.admfrm .adm_card.adm_card_wide{grid-column:1/-1}.admfrm .adm_card_hd{display:flex;align-items:center;gap:.5rem;padding:.6rem .85rem;background:#1b4379;color:#fff;font-weight:700}.admfrm .adm_card_hd>span:first-child{flex:1 1 auto}.admfrm .adm_card_bd{padding:.6rem .85rem}.admfrm .adm_card_ft{padding:.5rem .85rem .75rem;text-align:right}.admfrm table.adm_kv{border-collapse:collapse;width:100%}.admfrm table.adm_kv td{padding:.25rem .35rem;border-bottom:1px solid #eee;vertical-align:top;font-size:.92rem}.admfrm table.adm_kv td.k{color:#666;white-space:nowrap;width:40%}.admfrm table.adm_kv td.v{word-break:break-word}.admfrm table.adm_kv tr:last-child td{border-bottom:none}.admfrm .adm_probe{margin-top:.6rem;padding-top:.5rem;border-top:1px dashed #ddd;font-size:.88rem}.admfrm .adm_probe .adm_probe_msg{font-weight:600}.admfrm .adm_probe .adm_probe_det{color:#555;word-break:break-word;margin-top:.15rem}.admfrm .adm_probe .adm_probe_dur{color:#999;margin-top:.15rem;font-size:.8rem}.admfrm .adm_probe .adm_probe_metrics{margin-top:.35rem}.admfrm .adm_probe .adm_probe_metrics .adm_metric{display:flex;justify-content:space-between;gap:.5rem;padding:.1rem 0;border-bottom:1px dotted #eee}.admfrm .adm_probe .adm_probe_metrics .adm_metric:last-child{border-bottom:none}.admfrm .adm_probe .adm_probe_metrics .adm_metric .adm_metric_k{color:#555;word-break:break-word}.admfrm .adm_probe .adm_probe_metrics .adm_metric .adm_metric_v{font-weight:600;white-space:nowrap}.admfrm .adm_checks{margin-top:.5rem}.admfrm .adm_checks .adm_check{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.25rem 0;border-bottom:1px solid #eee}.admfrm .adm_checks .adm_check:last-child{border-bottom:none}.admfrm .adm_checks .adm_check .adm_check_k{color:#333}.admfrm .adm_checks .adm_check .adm_check_v{font-weight:700;font-size:.8rem;padding:.05rem .5rem;border-radius:.25rem;white-space:nowrap}.admfrm .adm_checks .adm_check .adm_check_ok{background:#e2f3da;color:#2f6d18}.admfrm .adm_checks .adm_check .adm_check_fail{background:#f3ded9;color:#c0341d}.admfrm .adm_checks .adm_check .adm_check_skipped{background:#ececec;color:#777}.admfrm .adm_pill{display:inline-block;padding:.1rem .55rem;border-radius:1rem;font-size:.78rem;font-weight:700;color:#fff;background:#999;white-space:nowrap}.admfrm .adm_pill_ok{background:#56a532}.admfrm .adm_pill_error{background:#c0341d}.admfrm .adm_pill_disabled{background:#888}.admfrm .adm_pill_unconfigured{background:#d69100}.admfrm .adm_pill_checking{background:#2a72c4}.admfrm .adm_bool{display:inline-block;padding:0 .4rem;border-radius:.25rem;font-size:.8rem;font-weight:700}.admfrm .adm_bool_y{background:#e2f3da;color:#2f6d18}.admfrm .adm_bool_n{background:#f3e0dd;color:#9c2a17}.admfrm .adm_env{font-size:.8rem;font-weight:400;padding:.1rem .5rem;border-radius:.25rem;background:rgba(255,255,255,.25)}.admfrm .adm_env.adm_env_test{background:#13a143}.admfrm .adm_btn{cursor:pointer;border-radius:.28rem;padding:.2rem .6rem;font-size:.85rem;border:1px solid #ababab;background-color:#fff;color:#333}.admfrm .adm_btn.adm_btn_primary{background-color:#56a532;border-color:rgb(69.68,133.688372093,40.511627907);color:#fff}.admfrm .adm_card_hd .adm_btn{background-color:rgba(255,255,255,.15);color:#fff;border-color:rgba(255,255,255,.4)}.adm_note{margin-top:.75rem;padding:.5rem .6rem;background:#f3f6fb;border-left:3px solid #1b4379;font-size:.85rem;color:#444}
|
||||
@@ -2842,6 +2842,7 @@ $.extend($t, {
|
||||
, m_rep: 'Berichte'
|
||||
, m_todo: 'ToDos'
|
||||
, m_bcd: 'BankBuchungen'
|
||||
, m_admin: 'Administration'
|
||||
, rsp: 'Passwort ändern'
|
||||
, pnm: 'Die Passwörter stimmen nicht überein'
|
||||
, cps: 'Das neue Passwort wurde gespeichert.'
|
||||
@@ -3221,8 +3222,26 @@ $fis.draft = {
|
||||
//, { lbl: $t.m_efa, id: 'm_efa', fnc: 'init:efa' }
|
||||
]);
|
||||
})();
|
||||
|
||||
/* The Administration module is restricted to users whose fds_sys authorization exceeds 4.
|
||||
The button is added — and only then does clicking it load the module script — after the
|
||||
asynchronous auth check resolves, so lower-privileged users never see it or fetch the code.
|
||||
Called from fis_main_go.js once the DOM (and the initial main menu) is ready. */
|
||||
$fis.addAdminMenuIfAuthorized = function () {
|
||||
if ($('#m_admin').length > 0) { return; } // idempotent
|
||||
$fis.getAuth('fds_sys').then(function (auth) {
|
||||
if ((auth || -1) > 4 && $('#m_admin').length === 0) {
|
||||
$ocms.ocmsmenu.push({ lbl: $t.m_admin, id: 'm_admin', fnc: 'init:admin', ico: 'glyphicon glyphicon-cog' });
|
||||
/* Re-render the main menu cleanly: drop the previously generated menu list
|
||||
(never the .nav-right settings dropdown) and rebuild it from the array. */
|
||||
$('#mainmenu').children('ul:not(.nav-right)').remove();
|
||||
$('#mainmenu').ocmsmenu($ocms.ocmsmenu);
|
||||
}
|
||||
}).catch(function () { /* auth lookup failed → leave the menu unchanged */ });
|
||||
};
|
||||
$(document).ready(function () {
|
||||
$fis.notifications.init();
|
||||
$fis.draft.init();
|
||||
$fis.ov();
|
||||
$fis.addAdminMenuIfAuthorized();
|
||||
});
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user