Add row context menus, fix glyphicon copy corruption, combine CC email editing
- Fuchs/gulpfile.js: pass encoding:false to gulp.src() in the copy task — vinyl-fs otherwise UTF-8-decodes binary files by default, which was silently corrupting the glyphicons webfont (and any other binary asset copyconfig.json matches) on every `gulp copy`/`gulp all` run. - Invoice/reminder editor: replace the row's flat action icons (edit/ delete/insert/set-price) with a single context button opening a dropdown menu, reusing the existing $ocms.menu toolbar mechanism. - Fix "-1" leaking into the Pos. column for Text/Title rows: $inv.rrw's `dta.position || dta.SortOrder` fallback treated the numbering's intentional empty string as unset and fell back to SortOrder (-1 for such rows); now only a genuinely uncomputed position falls back. - Zusatzempfänger (CC) is now edited together with the main invoice email in one combined dialog ($inv.emailFrm/$inv.eEmail), wired into all three entry points (create, continue, storno) instead of a separate hover-revealed row with its own edit target. - Add tooltips to every row/header edit control, including several that had none before (header field pencils, the request/section title edit button), phrased as object+verb ($rct.frmTT). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -746,13 +746,13 @@ $inv.ccInv = function (ev) { //normale rechnung
|
||||
|
||||
let admin = response.admin || {}, fm = (cls, txt, nme, hd, dta) => {
|
||||
let fr = $$.dc('inpfrm', frm).aC(cls).append(typeof hd === 'string' ? $$.dc('ahd', hd) : (hd > 0 ? $$.dc('ahd', $rct.frm[nme]) : null)), fc = $$.dc('content', fr).rwText(txt);
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit').data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit', { title: $rct.frmTT[nme] || $rct.frm[nme] }).data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
rif.tbl.data('new')[nme] = txt;
|
||||
};
|
||||
fm('tfrm', admin.invoicetitle, 'invoicetitle', 0, null);
|
||||
fm('adrfrm', admin.invoiceaddress, 'invoiceaddress', 0, null);
|
||||
fm('locfrm', '', 'loc', 1, { list: deepCopy(response.locations), lbl: 'ref', property: 'address' });
|
||||
fm('emailfrm', admin.invoiceemail, 'invoiceemail', 0, null);
|
||||
$inv.emailFrm(frm, rif, admin.invoiceemail, admin.invoiceemailcc);
|
||||
$$.dc('sndfrm', frm).append($$.dc('content').text(admin.sender));
|
||||
|
||||
let admtxt, admlbl;
|
||||
@@ -821,13 +821,13 @@ $inv.ccStInv = function (ev) { // Stornorechnung
|
||||
|
||||
let admin = response.admin || {}, fm = (cls, txt, nme, hd, dta) => {
|
||||
let fr = $$.dc('inpfrm', frm).aC(cls).append(typeof hd === 'string' ? $$.dc('ahd', hd) : (hd > 0 ? $$.dc('ahd', $rct.frm[nme]) : null)), fc = $$.dc('content', fr).rwText(txt);
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit').data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit', { title: $rct.frmTT[nme] || $rct.frm[nme] }).data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
rif.tbl.data('new')[nme] = txt;
|
||||
};
|
||||
fm('tfrm', admin.invoicetitle, 'invoicetitle', 0, null);
|
||||
fm('adrfrm', admin.invoiceaddress, 'invoiceaddress', 0, null);
|
||||
fm('locfrm', admin.provisionlocation, 'loc', 1, { list: deepCopy(response.locations), lbl: 'ref', property: 'address' });
|
||||
fm('emailfrm', admin.invoiceemail, 'invoiceemail', 0, null);
|
||||
$inv.emailFrm(frm, rif, admin.invoiceemail, admin.invoiceemailcc);
|
||||
$$.dc('sndfrm', frm).append($$.dc('content').text(admin.sender));
|
||||
|
||||
let admtxt, admlbl;
|
||||
@@ -897,14 +897,13 @@ $inv.cntInv = function (data) { //invoice continuation
|
||||
|
||||
let fm = (cls, txt, nme, hd, dta) => {
|
||||
let fr = $$.dc('inpfrm', frm).aC(cls).append(typeof hd === 'string' ? $$.dc('ahd', hd) : (hd > 0 ? $$.dc('ahd', $rct.frm[nme]) : null)), fc = $$.dc('content', fr).rwText(txt);
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit').data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit', { title: $rct.frmTT[nme] || $rct.frm[nme] }).data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
rif.tbl.data('new')[nme] = txt;
|
||||
};
|
||||
fm('tfrm', inv.InvoiceTitle, 'invoicetitle', 0, null);
|
||||
fm('adrfrm', inv.SendToAddress, 'invoiceaddress', 0, null);
|
||||
fm('locfrm', inv.ProvisionLocation, 'loc', 1, null);
|
||||
fm('emailfrm', inv.SendToEmail, 'invoiceemail', 0, null);
|
||||
fm('emailccfrm', inv.SendToEmailCc, 'invoiceemailcc', 0, null);
|
||||
$inv.emailFrm(frm, rif, inv.SendToEmail, inv.SendToEmailCc);
|
||||
$$.dc('sndfrm', frm).append($$.dc('content').text(response.admin.sender));
|
||||
|
||||
fm('admfrm', inv.ProvisionPeriod, 'provisionperiod', ((inv.ProvisionPeriod || '').includes('-') === true ? $rct.provP : $rct.provD), 1, null);
|
||||
@@ -960,14 +959,13 @@ $inv.cSt = function (data) {
|
||||
|
||||
let fm = (cls, txt, nme, hd, dta) => {
|
||||
let fr = $$.dc('inpfrm', frm).aC(cls).append(typeof hd === 'string' ? $$.dc('ahd', hd) : (hd > 0 ? $$.dc('ahd', $rct.frm[nme]) : null)), fc = $$.dc('content', fr).rwText(txt);
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit').data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit', { title: $rct.frmTT[nme] || $rct.frm[nme] }).data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
rif.tbl.data('new')[nme] = txt;
|
||||
};
|
||||
fm('tfrm', inv.InvoiceTitle, 'invoicetitle', 0, null);
|
||||
fm('adrfrm', inv.SendToAddress, 'invoiceaddress', 0, null);
|
||||
fm('locfrm', inv.ProvisionLocation, 'loc', 1, null);
|
||||
fm('emailfrm', inv.SendToEmail, 'invoiceemail', 0, null);
|
||||
fm('emailccfrm', inv.SendToEmailCc, 'invoiceemailcc', 0, null);
|
||||
$inv.emailFrm(frm, rif, inv.SendToEmail, inv.SendToEmailCc);
|
||||
$$.dc('sndfrm', frm).append($$.dc('content').text(response.admin.sender));
|
||||
|
||||
fm('admfrm', inv.ProvisionPeriod, 'provisionperiod', ((inv.ProvisionPeriod || '').includes('-') === true ? $rct.provP : $rct.provD), 1, null);
|
||||
@@ -1095,6 +1093,45 @@ $inv.eProvisionPeriod = function (ev) {
|
||||
});
|
||||
};
|
||||
|
||||
/* Main recipient + CC ("Zusatzempfänger") edited together in one dialog — there is no separate
|
||||
pencil on the CC row, only on the email row (see $inv.emailFrm), which passes both content
|
||||
spans through ev.data.t / ev.data.ccT. */
|
||||
$inv.eEmail = function (ev) {
|
||||
let flds = [
|
||||
{ name: 'email', label: $rct.frm.invoiceemail, type: 'text', value: (ev.data.t || $$.s()).text() },
|
||||
{ name: 'emailcc', label: $rct.frm.invoiceemailcc, type: 'text', value: (ev.data.ccT || $$.s()).text() }
|
||||
];
|
||||
$ocms.dlgform(flds, {
|
||||
title: $rct.frm.invoiceemail,
|
||||
success: function (res) {
|
||||
let email = ('' + (res.email || '')).trim(), cc = ('' + (res.emailcc || '')).trim();
|
||||
if (ev.data && ev.data.t) { ev.data.t.text(email); }
|
||||
if (ev.data && ev.data.ccT) { ev.data.ccT.text(cc); }
|
||||
if (typeof (ev.data || {}).change === 'function') { ev.data.change(email); }
|
||||
if (typeof (ev.data || {}).changeCc === 'function') { ev.data.changeCc(cc); }
|
||||
/* backend-authoritative: mirror both fields to the server session (see $inv.eHtml's
|
||||
generic path, which this mirrors for a single field). */
|
||||
$inv.d.syncField('invoiceemail', email);
|
||||
$inv.rd.syncField('invoiceemail', email);
|
||||
$inv.d.syncField('invoiceemailcc', cc);
|
||||
$inv.rd.syncField('invoiceemailcc', cc);
|
||||
}
|
||||
});
|
||||
};
|
||||
/* Builds the email + CC ("Zusatzempfänger") header rows together: only the email row gets a
|
||||
pencil, opening the combined $inv.eEmail dialog for both fields (see there). */
|
||||
$inv.emailFrm = function (frm, rif, email, emailcc) {
|
||||
let ccfr = $$.dc('inpfrm emailccfrm', frm), ccfc = $$.dc('content', ccfr).rwText(emailcc);
|
||||
let efr = $$.dc('inpfrm emailfrm', frm), efc = $$.dc('content', efr).rwText(email);
|
||||
$$.dc('axf', efr).append($$.dc('ibtn edit', { title: $rct.frmTT.invoiceemail }).append(gi('pencil')).click({
|
||||
t: efc, ccT: ccfc, nme: 'invoiceemail',
|
||||
change: (nv) => { rif.tbl.data('new').invoiceemail = nv; },
|
||||
changeCc: (nv) => { rif.tbl.data('new').invoiceemailcc = nv; }
|
||||
}, $inv.eHtml));
|
||||
rif.tbl.data('new').invoiceemail = email;
|
||||
rif.tbl.data('new').invoiceemailcc = emailcc;
|
||||
};
|
||||
|
||||
$inv.eHtml = function (ev) {
|
||||
/* The recipient address and the service date/period are edited through structured dialogs
|
||||
whenever an invoice draft is active; reminders (no invoice draft token) keep the plain
|
||||
@@ -1103,6 +1140,9 @@ $inv.eHtml = function (ev) {
|
||||
if (ev.data.nme === 'invoiceaddress') { return $inv.eAddress.call(this, ev); }
|
||||
if (ev.data.nme === 'provisionperiod') { return $inv.eProvisionPeriod.call(this, ev); }
|
||||
}
|
||||
/* The CC/Zusatzempfänger recipient is edited together with the main email, in one dialog —
|
||||
there is no separate pencil on the CC row (see $inv.emailFrm). */
|
||||
if (ev.data && !(ev.data instanceof jQuery) && ev.data.nme === 'invoiceemail' && ev.data.ccT) { return $inv.eEmail.call(this, ev); }
|
||||
let t = $(this), frmct = ev.data instanceof jQuery ? ev.data : ev.data.t;
|
||||
/* Single-line fields must stay plain text — the TinyMCE/html editor wraps the value in <p>
|
||||
tags, which used to get posted and persisted verbatim (e.g. <p>18.06.2026</p> in the
|
||||
@@ -1216,15 +1256,29 @@ $inv.eRw = function(row, dta, flds) {
|
||||
changed block(s) to the backend session (t_fds_inv -> syncChanged). Committing on drop (rather
|
||||
than on every mid-drag hover-swap) avoids rebuilding the row that is currently being dragged. */
|
||||
$inv.bdysort = (i, e) => { $(e).Sortable({ dragItem: false, dragHandleClass: 'ico', parentident: 'tr', onend: () => { $inv.t_fds_inv(); } }) }
|
||||
/* Single "Kontext-Button" per row/field, opening a dropdown of the row's edit actions
|
||||
(reuses $ocms.menu, the same mechanism that already drives the toolbar menus — see
|
||||
$inv.eM/$inv.iMn). Calling .ocmsmenu() directly on a <nav> we built ourselves (rather than
|
||||
letting $ocms.menu create one inside a bar) keeps our own sizing class instead of being
|
||||
replaced. Every entry carries both its label and a matching `title` tooltip. */
|
||||
$inv.rowCtxMenu = function (items) {
|
||||
let nav = $$[0]('nav').aC('rowctx');
|
||||
nav.ocmsmenu([{ glyph: 'glyphicon-option-vertical', aclass: 'ctxbtn', attr: { title: $rct.ctxM }, itm: items }]);
|
||||
/* $ocms.menu puts `attr` (incl. our title tooltip) on the <li>, not the <a> a viewer actually
|
||||
hovers — mirror it onto the <a> too so the native tooltip is guaranteed to fire regardless
|
||||
of how the browser resolves title on a non-interactive ancestor. */
|
||||
nav.find('li[title]').each(function () { let li = $(this); li.children('a').attr('title', li.attr('title')); });
|
||||
return nav;
|
||||
};
|
||||
$inv.rrw = function () {
|
||||
let rw = $(this), dta = rw.data(), co = {}, ph = rw.is('.placeholder'), hn = rw.is('.hidenote');
|
||||
let oHtml = (e) => $$.d().append(e).html();
|
||||
let bc = [
|
||||
$$.dc('ibtn insb', { title: $rct.iRb }).append(gi('indent-left')).click(rw, $inv.inRow)
|
||||
let mi = [
|
||||
{ lbl: $rct.iRb, attr: { title: $rct.iRb }, data: rw, fnc: $inv.inRow }
|
||||
];
|
||||
if (ph === false) {
|
||||
bc.unshift($$.dc('ibtn edit', { title: $rct.cP }).append(gi('pencil')).click(rw, $inv.eRow));
|
||||
bc.push($$.dc('ibtn del', { title: $rct.dR }).append(gi('trash')).click(function (e) { if (confirm($rct.cD)) { rw.remove(); $inv.t_fds_inv(); } }));
|
||||
mi.unshift({ lbl: $rct.cP, attr: { title: $rct.cP }, data: rw, fnc: $inv.eRow });
|
||||
mi.push({ lbl: $rct.dR, attr: { title: $rct.dR }, fnc: function (e) { if (confirm($rct.cD)) { rw.remove(); $inv.t_fds_inv(); } } });
|
||||
/* "Auf Setpreis umstellen": offered on a Set header item that does not yet carry a
|
||||
price. fds__prepInvoice's [SetItmId] now anchors on the still-unconverted (price 0)
|
||||
header, so the header row's own SetItmId self-references its own id rather than being
|
||||
@@ -1233,10 +1287,10 @@ $inv.rrw = function () {
|
||||
Irreversible: the actual sum/clear mutation happens server-side (backend-authoritative,
|
||||
see InvoiceDraftEditService.ApplyItemSetPrice) via the "item.setprice" patch target. */
|
||||
if ((dta.Type || '').toLowerCase() === 'set' && (dta.net_val || 0) === 0) {
|
||||
bc.push($$.dc('ibtn tosetp', { title: $rct.toSetP }).append(gi('scale')).click(rw, $inv.toSetPrice));
|
||||
mi.push({ lbl: $rct.toSetP, attr: { title: $rct.toSetP }, data: rw, fnc: $inv.toSetPrice });
|
||||
}
|
||||
}
|
||||
let axf = $$.dc('axf').append(bc);
|
||||
let axf = $$.dc('axf').append($inv.rowCtxMenu(mi));
|
||||
if (ph === true) {
|
||||
co = { id: '', typ: 'placeholder' };
|
||||
} else if (rw.is('.itm.osum') === true) {
|
||||
@@ -1245,7 +1299,12 @@ $inv.rrw = function () {
|
||||
co = { invrqid: dta.InvRqId, id: dta.Id || '', typ: dta.Type || 'other', p: '', q: null, t: '', tt: null, v: null, vt: dta.net_val, vs: dta.svcnet_val, vat: dta.vat, vv: dta.vat_val, vsv: dta.svcvat_val, det: (dta.Note || '') !== '' && hn === false, SetItmId: dta.SetItmId || null, lvl: (dta.lvl || 0) };
|
||||
$$.dc('ibtn ico move', axf, { title: $rct.mR }); /* should be the last added */
|
||||
|
||||
co.p = dta.position || (dta.SortOrder || '');
|
||||
/* dta.position is '' (not unset) for a Text/Title row once invSumUpdate has numbered the
|
||||
invoice (ADR 0017) — an intentional "no number", not a missing value, so it must NOT
|
||||
fall through to SortOrder (which is -1 for such rows and would leak "-1" into Pos.).
|
||||
Only an as-yet-uncomputed row (freshly inserted, before the next invSumUpdate pass)
|
||||
has position === undefined and should still fall back to SortOrder as a placeholder. */
|
||||
co.p = dta.position != null ? dta.position : (dta.SortOrder || '');
|
||||
if (co.id === '') {
|
||||
co.t = '';
|
||||
} else if (['Text', 'Title'].includes(co.typ) && (dta.net_val || 0) === 0) {
|
||||
@@ -1259,7 +1318,7 @@ $inv.rrw = function () {
|
||||
}
|
||||
}
|
||||
if ((dta.Note || '') !== '') {
|
||||
$$.dc('ibtn add', axf).append(gi('object-align-left')).click(function (e) {
|
||||
$$.dc('ibtn add', axf, { title: $rct.noteToggle }).append(gi('object-align-left')).click(function (e) {
|
||||
$inv.rrw.call(rw.tC('hidenote'));
|
||||
});
|
||||
}
|
||||
@@ -1404,7 +1463,7 @@ $inv.rendersrq = function () {
|
||||
$$.dc('ibtn insb', aux, { title: $rct.iRb }).append(gi('indent-left')).click(rtr, $inv.inRow);
|
||||
let stxt = $$.sc('text', rx.text);
|
||||
let nme = $$.td(rtr, { colspan: onesum ? 4 : 5 }).append(stxt), oidta, numkeys = ['net_val', 'vat_val', 'svcnet_val', 'svcvat_val', 'net'];
|
||||
$$.dc('ibtn edit', aux).data('dialog', $rcol.req.lbl().Name).append(gi('pencil')).click({ t: stxt, change: (nv) => { rx.text = nv; $inv.t_fds_inv(); } }, $inv.eHtml)
|
||||
$$.dc('ibtn edit', aux, { title: $rct.sectionTitleEditTT }).data('dialog', $rcol.req.lbl().Name).append(gi('pencil')).click({ t: stxt, change: (nv) => { rx.text = nv; $inv.t_fds_inv(); } }, $inv.eHtml)
|
||||
if (onesum) {
|
||||
$$.tdc('currency isumval', rtr);
|
||||
oidta = { Id: rx.Id.toString() + '_osum', net_val: 0, vat_val: 0, svcnet_val: 0, svcvat_val: 0, net: 0 };
|
||||
@@ -1781,7 +1840,8 @@ $inv.ccRem = function (id, InvoiceId) { //reminder creation
|
||||
$inv.rRemRw = function (dta) {
|
||||
let tr = $(this), rem = dta.rm || {};
|
||||
tr.empty().data({ invoiceid: rem.invoiceid, invoicedate: rem.invoicedate, amount: rem.amount, amount_payed: rem.amount_payed });
|
||||
let axf = $$.dc('axf').append($$.dc('ibtn edit', { title: $rct.cP }).append(gi('pencil')).click(tr, $inv.eRowR));
|
||||
let mi = [{ lbl: $rct.cP, attr: { title: $rct.cP }, data: tr, fnc: $inv.eRowR }];
|
||||
let axf = $$.dc('axf').append($inv.rowCtxMenu(mi));
|
||||
tr.append([$$.tdc('aux').append(axf), $$.tdc('keep', rem.invoiceid), $$.tdc('keep', fdt(rem.invoicedate, 'dd.MM.yy')), $$.tdc('currency', fnum(rem.amount, $rct.cst)), $$.tdc('currency', fnum(rem.amount_payed, $rct.cst)), $$.tdc('currency', fnum(rem.amount - rem.amount_payed, $rct.cst))]);
|
||||
};
|
||||
$inv.eRowR = function (ev) {
|
||||
@@ -1822,9 +1882,12 @@ $inv.ccRem_s2 = function (id, sets) { //reminder creation
|
||||
$inv.rRemRw.call($$.tr(rif.bdy), rif.tbl.data());
|
||||
rif.ft.appendTo(rif.tbl);
|
||||
|
||||
/* Reminders have no CC/Zusatzempfänger field (see $inv.emailFrm, invoice-only), so the
|
||||
email pencil here keeps a plain tooltip instead of $rct.frmTT.invoiceemail. */
|
||||
let remTT = { invoiceemail: 'Email-Adresse ändern', subject: 'Betreff ändern' };
|
||||
let fm = (cls, txt, nme, hd, dta) => {
|
||||
let fr = $$.dc('inpfrm', frm).aC(cls).append(typeof hd === 'string' ? $$.dc('ahd', hd) : (hd > 0 ? $$.dc('ahd', $rct.frm[nme]) : null)), fc = $$.dc('content', fr).rwText(txt);
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit').data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
$$.dc('axf', fr).append($$.dc('ibtn edit', { title: remTT[nme] || $rct.frmTT[nme] || $rct.frm[nme] }).data('dialog', $rct.frm[nme]).append(gi('pencil')).click($.extend({ t: fc, nme: nme, change: (nv) => { rif.tbl.data('new')[nme] = nv; } }, dta), $inv.eHtml));
|
||||
rif.tbl.data('new')[nme] = txt;
|
||||
};
|
||||
fm('tfrm', rem.subject, 'subject', 0, null);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
top: 0;
|
||||
width: auto;
|
||||
max-height: 1.5rem;
|
||||
overflow: hidden;
|
||||
overflow: visible; /* the .rowctx dropdown popout must escape this pill-shaped bar */
|
||||
padding: 0.1rem;
|
||||
|
||||
> .ibtn {
|
||||
@@ -40,6 +40,51 @@
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Single row "Kontext-Button" opening a dropdown of edit actions (see $inv.rowCtxMenu).
|
||||
Resets the generic full-bar <nav> styling (meant for #topbar/#sidebar) down to a
|
||||
small inline trigger; the dropdown popout itself keeps the shared nav/dropdown-menu
|
||||
look (background, shadow, open/close via $nuf) so it matches every other menu in the app. */
|
||||
nav.rowctx {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 1.5rem;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
max-height: none;
|
||||
background: transparent;
|
||||
z-index: auto;
|
||||
vertical-align: top;
|
||||
|
||||
> ul {
|
||||
height: 100%;
|
||||
|
||||
> li {
|
||||
height: 100%;
|
||||
float: none;
|
||||
|
||||
> a.ctxbtn {
|
||||
padding: 0;
|
||||
width: 1.5rem;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
line-height: 1.3rem;
|
||||
|
||||
> .caret {
|
||||
display: none; /* single kebab trigger, no caret needed */
|
||||
}
|
||||
}
|
||||
|
||||
&.dropdown > ul.dropdown-menu {
|
||||
top: 100%;
|
||||
left: auto;
|
||||
right: 0;
|
||||
font-size: 0.85rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sndfrm {
|
||||
@@ -71,7 +116,6 @@
|
||||
min-width: 5rem;
|
||||
height: 1rem;
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -80,7 +124,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Read-only display: edited together with the email above, via that row's pencil
|
||||
(see $inv.emailFrm / $inv.eEmail) — no pencil/hover-reveal of its own. */
|
||||
.emailccfrm {
|
||||
position: absolute;
|
||||
font-size: 0.7rem;
|
||||
@@ -88,28 +134,10 @@
|
||||
left: 0.5rem;
|
||||
width: auto;
|
||||
height: auto;
|
||||
cursor: pointer;
|
||||
|
||||
.content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* Unlike the other optional fields (plain "-" placeholder), this one names the action —
|
||||
there is no default "Zusatzempfänger" from MFR, so an empty state must read as an
|
||||
offer to add one, not as missing data. */
|
||||
.content:empty::before {
|
||||
content: 'Zusatzempfänger hinzufügen';
|
||||
min-width: 5rem;
|
||||
height: 1rem;
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
div.axf {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admfrm {
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
sV: 'USt festlegen',
|
||||
cD: 'Löschen?',
|
||||
mR: 'Zeile verschieben',
|
||||
ctxM: 'Weitere Aktionen',
|
||||
noteToggle: 'Notiz ein-/ausblenden',
|
||||
sectionTitleEditTT: 'Auftragsbezeichnung ändern',
|
||||
svcPart: 'Service-Anteil',
|
||||
vat: 'Umsatzsteuer',
|
||||
combP: 'Positionen zusammenfassen',
|
||||
@@ -62,11 +65,21 @@
|
||||
, '-': '-'
|
||||
}, invHR: ['Pos.', 'Menge', 'Artikelbezeichnung', 'VK', 'Summe']
|
||||
, frm: {
|
||||
invoiceaddress: 'Adresse'
|
||||
invoicetitle: 'Titel'
|
||||
, invoiceaddress: 'Adresse'
|
||||
, loc: 'Leistungsort / Lieferadresse'
|
||||
, invoiceemail: 'Email'
|
||||
, invoiceemailcc: 'Zusatzempfänger (CC)'
|
||||
|
||||
, provisionperiod: 'Leistungsdatum / -zeitraum'
|
||||
}
|
||||
/* Tooltip text for each header-field pencil — object+verb phrasing ("<was> <tun>"),
|
||||
distinct from frm[] above (used for dialog titles / field labels, which stay short nouns). */
|
||||
, frmTT: {
|
||||
invoicetitle: 'Rechnungstitel ändern'
|
||||
, invoiceaddress: 'Rechnungsempfänger-Adresse ändern'
|
||||
, loc: 'Leistungsort oder Lieferadresse ändern'
|
||||
, invoiceemail: 'Email-Adresse ändern und zusätzliche Email-Empfänger festlegen'
|
||||
, provisionperiod: 'Leistungsdatum oder -zeitraum ändern'
|
||||
}
|
||||
}, $rcol = {
|
||||
req: new fields_definition('Auftrag', 'Aufträge', [
|
||||
|
||||
Reference in New Issue
Block a user