1/** 2 * tec-registro-azioni.js â IL REGISTRO OPERATIVO RISCHIO â AZIONE, E IL VERDETTO DEL TECNICO. 3 * 4 * ââ LA RICHIESTA, NELLE SUE PAROLE ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 5 * Beniamino Macchiarola: «averla per il tecnico dentro il TecDVR, la più pratica, efficace ed 6 * efficiente possibile. Deve cioè elencare, SENZA DUBBI E SENZA MANCANZE, i rischi, la norma 7 * corrispondente, la gravità , le azioni suggerite, offrire un piano di esecuzione e la possibilità 8 * che quelle azioni siano ACCETTATE, RIFIUTATE, INTEGRATE O MODIFICATE dal tecnico». 9 * 10 * ââ «SENZA DUBBI E SENZA MANCANZE» E' UN REQUISITO, NON UN AUSPICIO ââââââââââââââââââââââââââ 11 * Percio' il registro parte dai RISCHI, non dalle azioni: ogni rischio valutato compare, anche 12 * quello per cui il tool non sa proporre nulla â e in quel caso lo DICHIARA («nessuna azione 13 * proposta») invece di sparire dall'elenco. Un registro che mostra solo le righe che ha saputo 14 * riempire non e' senza mancanze: e' senza le mancanze VISIBILI. 15 * 16 * ââ I QUATTRO VERBI, E IL QUINTO STATO CHE NON E' UN VERBO âââââââââââââââââââââââââââââââââââ 17 * PROPOSTA â il tool l'ha suggerita, il tecnico non si e' pronunciato. NON entra nel DVR. 18 * ACCETTATA â diventa una misura del Programma, come e' scritta. 19 * RIFIUTATA â non entra, e il rifiuto porta la sua motivazione: e' un atto tecnico, non un 20 * cestino. In audit «perche' non l'avete fatta» ha una risposta. 21 * INTEGRATA â accettata e arricchita: resta il testo del tool, piu' quello del tecnico. 22 * MODIFICATA â sostituita dal testo del tecnico: il tool cede, e lo dichiara. 23 * 24 * Il silenzio non e' consenso: una proposta non pronunciata non finisce nel pacchetto. E' la 25 * stessa regola dei servizi esterni verosimili e della sorveglianza sanitaria. 26 * 27 * ââ NON SCRIVE âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 28 * Produce cio' che andrebbe scritto e lo restituisce; scrive il chiamante. Cosi' la schermata puo' 29 * mostrare l'anteprima esatta di cio' che sta per accadere â la regola che il committente ha 30 * chiesto per tutti i pulsanti. 31 * 32 * Espone window._tecRegistroAzioni. 33 */ 34(function (win) { 35 'use strict'; 36 if (typeof win === 'undefined') return; 37 38 var VERSION = '20.373.134'; 39 40 var VERDETTI = [ 41 { id: 'proposta', label: 'Da decidere', colore: '64748B', nelDvr: false, 42 spiega: 'Il tool lâha suggerita. Finché non ti pronunci non entra nel DVR.' }, 43 { id: 'accettata', label: 'Accettata', colore: '16A34A', nelDvr: true, 44 spiega: 'Entra nel Programma di Miglioramento con il testo del tool.' }, 45 { id: 'rifiutata', label: 'Rifiutata', colore: 'DC2626', nelDvr: false, motivoObbligatorio: true, 46 spiega: 'Non entra. La motivazione resta nel tool: in audit «perché non lâavete fatta» ha una risposta.' }, 47 { id: 'integrata', label: 'Integrata', colore: '2563EB', nelDvr: true, testoAggiuntivo: true, 48 spiega: 'Entra con il testo del tool più il tuo.' }, 49 { id: 'modificata', label: 'Modificata', colore: 'B45309', nelDvr: true, testoSostitutivo: true, 50 spiega: 'Entra con il tuo testo al posto di quello del tool.' } 51 ]; 52 function verdettoMeta(id) { 53 for (var i = 0; i < VERDETTI.length; i++) if (VERDETTI[i].id === id) return VERDETTI[i]; 54 return VERDETTI[0]; 55 } 56 57 function _s(v) { return String(v == null ? '' : v).trim(); } 58 function _n(v) { var x = Number(v); return isNaN(x) ? 0 : x; } 59 function _arr(v) { return Array.isArray(v) ? v : []; } 60 61 /** 62 * La chiave di un'azione proposta. Deve restare la stessa fra due aperture della schermata, 63 * altrimenti il verdetto del tecnico si stacca dalla propria azione e sembra sparito. 64 * Non si usa l'indice nell'elenco: basta che il motore riordini e i verdetti si mescolano. 65 */ 66 function chiaveAzione(p) { 67 return [_s(p && p.rischioCod), _s(p && p.mansioneId), _s(p && p.luogoId), _s(p && p.tipo), 68 _s(p && p.descrizione).slice(0, 60).toLowerCase().replace(/\s+/g, ' ')].join('|'); 69 } 70 71 function _fascia(r) { 72 var D = win._tecDashboardRischi; 73 if (D && typeof D.fasciaDi === 'function') return D.fasciaDi(r); 74 return { id: 'basso', label: 'Basso', colore: '16A34A' }; 75 } 76 77 /** 78 * IL REGISTRO. Una riga per RISCHIO VALUTATO â tutti, anche quelli senza proposte. 79 */ 80 function registro(d) { 81 d = d || {}; 82 var MOT = win._tecMotore, AZ = win._tecAzioniDaResiduo;
83 if (!MOT || typeof MOT.righeMatriceDvr !== 'function') { 84 return { disponibile: false, perche: 'il motore dei rischi non è caricato', righe: [] }; 85 } 86 var righeM = []; 87 try { righeM = _arr(MOT.righeMatriceDvr(d)); } catch (_e) { 88 return { disponibile: false, perche: 'la matrice dei rischi non è calcolabile', righe: [] }; 89 } 90 var proposte = []; 91 if (AZ && typeof AZ.proponi === 'function') { 92 try { proposte = _arr(AZ.proponi(d)); } catch (_e2) { proposte = []; } 93 } 94 var verdetti = (d && d.verdettiAzioni) || {}; 95 96 var perRischio = {}; 97 proposte.forEach(function (p) { 98 var k = _s(p.rischioCod) + '|' + _s(p.mansioneId); 99 (perRischio[k] = perRischio[k] || []).push(p); 100 }); 101 102 var righe = righeM.map(function (x) { 103 var cod = _s(x[1]), mans = _s(x[0]); 104 var ri = _n(x[6]), rr = _n(x[7]) || ri; 105 var f = _fascia(rr); 106 var mie = []; 107 Object.keys(perRischio).forEach(function (k) { 108 if (k.indexOf(cod + '|') === 0) mie = mie.concat(perRischio[k]); 109 }); 110 var az = mie.map(function (p) { 111 var ch = chiaveAzione(p); 112 var v = verdetti[ch] || {}; 113 var stato = _s(v.verdetto) || 'proposta'; 114 var meta = verdettoMeta(stato); 115 return { 116 chiave: ch, tipo: _s(p.tipo), descrizione: _s(p.descrizione), norma: _s(p.norma), 117 responsabile: _s(v.responsabile) || _s(p.responsabile), 118 scadenza: _s(v.scadenza) || _s(p.scadenza), 119 rResiduoPre: _n(p.rResiduoPre), rAtteso: _n(p.rAtteso), 120 riduzioneAttesa: _n(p.rResiduoPre) - _n(p.rAtteso), 121 verdetto: stato, verdettoLabel: meta.label, verdettoColore: meta.colore, 122 nelDvr: !!meta.nelDvr, motivo: _s(v.motivo), testoTecnico: _s(v.testo), 123 decisaIl: _s(v.il) 124 }; 125 }); 126 return { 127 cod: cod, nome: _s(x[2]), mansione: mans, fonte: _s(x[3]), 128 P: _n(x[4]), D: _n(x[5]), R: ri, residuo: rr, 129 fascia: f.label, fasciaColore: f.colore, norma: _s(x[9]), 130 misureEsistenti: _s(x[8]), 131 azioni: az, 132 nProposte: az.filter(function (a) { return a.verdetto === 'proposta'; }).length, 133 nAccolte: az.filter(function (a) { return a.nelDvr; }).length, 134 senzaProposte: az.length === 0, 135 // «senza dubbi e senza mancanze»: un rischio sopra soglia senza alcuna azione accolta 136 // e' una lacuna, e va detta anche quando il tool non sa proporre niente. 137 scoperto: rr >= 6 && az.filter(function (a) { return a.nelDvr; }).length === 0 138 }; 139 }); 140 righe.sort(function (a, b) { return b.residuo - a.residuo || b.R - a.R; }); 141 return { 142 disponibile: true, norma: 'art. 28 c.2 lett. b, c e d D.Lgs. 81/08', 143 righe: righe, 144 nRischi: righe.length, 145 nSenzaProposte: righe.filter(function (r) { return r.senzaProposte; }).length, 146 nScoperti: righe.filter(function (r) { return r.scoperto; }).length, 147 nDaDecidere: righe.reduce(function (s, r) { return s + r.nProposte; }, 0), 148 nAccolte: righe.reduce(function (s, r) { return s + r.nAccolte; }, 0) 149 }; 150 } 151 152 /** 153 * IL PIANO DI ESECUZIONE: solo cio' che il tecnico ha accolto, ordinato per urgenza. 154 * Chi non ha responsabile o data viene messo in testa: e' un impegno che non impegna nessuno. 155 */ 156 function piano(d) { 157 var reg = registro(d); 158 if (!reg.disponibile) return { disponibile: false, perche: reg.perche, voci: [] }; 159 var voci = []; 160 reg.righe.forEach(function (r) { 161 r.azioni.forEach(function (a) { 162 if (!a.nelDvr) return; 163 voci.push({ 164 rischio: r.cod + ' â ' + r.nome, mansione: r.mansione, fascia: r.fascia, 165 residuo: r.residuo, riduzioneAttesa: a.riduzioneAttesa, 166 azione: a.verdetto === 'modificata' ? a.testoTecnico 167 : (a.verdetto === 'integrata' ? a.descrizione + ' â ' + a.testoTecnico : a.descrizione), 168 tipo: a.tipo, norma: a.norma, 169 responsabile: a.responsabile, scadenza: a.scadenza, 170 incompleta: !a.responsabile || !a.scadenza, 171 verdetto: a.verdetto 172 }); 173 }); 174 }); 175 voci.sort(function (a, b) { 176 if (a.incompleta !== b.incompleta) return a.incompleta ? -1 : 1; 177 return b.residuo - a.residuo; 178 }); 179 return { 180 disponibile: true, norma: 'art. 28 c.2 lett. c D.Lgs. 81/08', 181 voci: voci, totale: voci.length, 182 incomplete: voci.filter(function (v) { return v.incompleta; }).length, 183 riduzioneAttesaTotale: voci.reduce(function (s, v) { return s + _n(v.riduzioneAttesa); }, 0) 184 }; 185 } 186 187 /** 188 * Il verdetto del tecnico, tradotto in cio' che andrebbe scritto. NON scrive. 189 * @param scelta {verdetto, motivo, testo, responsabile, scadenza, il} 190 */ 191 function verdettoDaScrivere(d, chiave, scelta) { 192 scelta = scelta || {}; 193 var meta = verdettoMeta(_s(scelta.verdetto)); 194 var errori = []; 195 if (meta.motivoObbligatorio && !_s(scelta.motivo)) { 196 errori.push('Un rifiuto senza motivazione non è un atto tecnico: in audit «perché non lâavete fatta» resterebbe senza risposta.'); 197 } 198 if ((meta.testoAggiuntivo || meta.testoSostitutivo) && !_s(scelta.testo)) { 199 errori.push('Hai scelto «' + meta.label + '» ma non hai scritto il testo: senza, la scelta non ha contenuto.'); 200 } 201 if (errori.length) return { ok: false, errori: errori, scrivi: null }; 202 var riga = {}; 203 riga[_s(chiave)] = { 204 verdetto: meta.id, motivo: _s(scelta.motivo), testo: _s(scelta.testo), 205 responsabile: _s(scelta.responsabile), scadenza: _s(scelta.scadenza), il: _s(scelta.il) 206 }; 207 return { ok: true, errori: [], chiave: 'verdettiAzioni', scrivi: riga, nelDvr: !!meta.nelDvr }; 208 } 209 210 function selfTest() { 211 var e = [];
212 if (VERDETTI.length !== 5) e.push('i verbi del tecnico non sono piu cinque'); 213 if (verdettoMeta('proposta').nelDvr) e.push('una proposta non pronunciata entrerebbe nel DVR: il silenzio non e consenso'); 214 if (!verdettoMeta('accettata').nelDvr) e.push('un azione accettata non entra nel DVR'); 215 if (verdettoMeta('rifiutata').nelDvr) e.push('un azione rifiutata entrerebbe comunque nel DVR'); 216 if (!verdettoMeta('integrata').nelDvr || !verdettoMeta('modificata').nelDvr) e.push('integrata o modificata non entrano nel DVR'); 217 218 var k1 = chiaveAzione({ rischioCod: 'B10', mansioneId: 'm1', tipo: 'tecnica', descrizione: 'Pavimenti antisdrucciolevoli' }); 219 var k2 = chiaveAzione({ rischioCod: 'B10', mansioneId: 'm1', tipo: 'tecnica', descrizione: 'Pavimenti antisdrucciolevoli' }); 220 if (k1 !== k2) e.push('la chiave cambia per uno spazio doppio: il verdetto si staccherebbe dalla propria azione'); 221 if (chiaveAzione({ rischioCod: 'B10', tipo: 'dpi', descrizione: 'X' }) === k1) e.push('due azioni diverse hanno la stessa chiave'); 222 223 var r = verdettoDaScrivere({}, 'k', { verdetto: 'rifiutata' }); 224 if (r.ok) e.push('un rifiuto senza motivazione viene accettato'); 225 var r2 = verdettoDaScrivere({}, 'k', { verdetto: 'rifiutata', motivo: 'gia attuata da anni' }); 226 if (!r2.ok) e.push('un rifiuto motivato viene respinto'); 227 if (r2.nelDvr) e.push('un rifiuto motivato finirebbe nel DVR'); 228 var r3 = verdettoDaScrivere({}, 'k', { verdetto: 'modificata' }); 229 if (r3.ok) e.push('una modifica senza testo viene accettata'); 230 var r4 = verdettoDaScrivere({}, 'k', { verdetto: 'accettata' }); 231 if (!r4.ok || !r4.nelDvr) e.push('un accettazione non produce nulla'); 232 if (r4.scrivi && r4.scrivi.k && r4.scrivi.k.verdetto !== 'accettata') e.push('il verdetto scritto non e quello scelto'); 233 234 // il caso «motore assente» si prova nel gate, che puo' costruire una finestra nuda: qui il 235 // motore c'e' quasi sempre, e pretendere il contrario darebbe un selfTest che mente. 236 var reg = registro({}); 237 if (reg.disponibile) { 238 if (!Array.isArray(reg.righe)) e.push('il registro non restituisce un elenco di righe'); 239 if (typeof reg.nScoperti !== 'number') e.push('il registro non conta i rischi scoperti'); 240 } else if (!_s(reg.perche)) { 241 e.push('il registro si dichiara non disponibile senza dire perche'); 242 } 243 return { ok: e.length === 0, errors: e }; 244 } 245 246 win._tecRegistroAzioni = { 247 VERSION: VERSION, VERDETTI: VERDETTI, verdettoMeta: verdettoMeta, 248 chiaveAzione: chiaveAzione, registro: registro, piano: piano, 249 verdettoDaScrivere: verdettoDaScrivere, selfTest: selfTest 250 }; 251})(typeof window !== 'undefined' ? window : this); 252 253/** 254 * IL DISEGNO DEL REGISTRO. Una riga per rischio, le azioni dentro, e i quattro verbi a portata di 255 * pollice. Nessun «vai»: tutto cio' che riguarda un rischio sta nella sua riga. 256 * Le righe scoperte e quelle senza proposte stanno in TESTA, perche' sono le mancanze â e un 257 * registro «senza mancanze» deve mostrarle per prime, non nasconderle in fondo. 258 */ 259(function (win) { 260 'use strict'; 261 var A = win._tecRegistroAzioni; 262 if (!A) return; 263 function _e(s) { 264 return String(s == null ? '' : s).replace(/[&<>"]/g, function (c) { 265 return ({ '&': '&', '<': '<', '>': '>', '"': '"' })[c]; 266 }); 267 } 268 var NAVY = '#1e3a5f', GRIGIO = '#64748b'; 269 270 function _bottoni(a, onclickPrefix) { 271 var h = '<div style="display:flex;gap:5px;flex-wrap:wrap;margin-top:7px">'; 272 A.VERDETTI.filter(function (v) { return v.id !== 'proposta'; }
272).forEach(function (v) { 273 var on = a.verdetto === v.id; 274 h += '<button type="button" title="' + _e(v.spiega) + '"' 275 + (onclickPrefix ? ' onclick="' + onclickPrefix + '(\'' + _e(a.chiave) + '\',\'' + v.id + '\')"' : '') 276 + ' style="cursor:pointer;border:1.5px solid ' + (on ? '#' + v.colore : '#e2e8f0') 277 + ';background:' + (on ? '#' + v.colore : '#fff') + ';color:' + (on ? '#fff' : '#475569') 278 + ';border-radius:7px;font-size:10.5px;font-weight:800;padding:5px 10px;font-family:inherit">' 279 + _e(v.label) + '</button>'; 280 }); 281 return h + '</div>'; 282 } 283 284 function html(d, opts) { 285 opts = opts || {}; 286 var reg = opts.registro || A.registro(d); 287 if (!reg.disponibile) { 288 return '<div style="font-size:11.5px;color:' + GRIGIO + ';font-style:italic">Registro non disponibile: ' 289 + _e(reg.perche) + '.</div>'; 290 } 291 var pre = opts.onclick || ''; 292 var h = '<div style="border:1px solid #e2e8f0;border-radius:14px;background:#fff;overflow:hidden">'; 293 h += '<div style="padding:13px 16px;border-top:3px solid ' + (reg.nScoperti ? '#dc2626' : '#4338ca') 294 + ';border-bottom:1px solid #e2e8f0">' 295 + '<div style="font-size:9.5px;font-weight:900;letter-spacing:.09em;text-transform:uppercase;color:' + GRIGIO + '">' 296 + _e(reg.norma) + '</div>' 297 + '<div style="font-size:14.5px;font-weight:800;color:' + NAVY + ';margin-top:3px">Registro rischio â azione</div>' 298 + '<div style="font-size:11px;color:' + GRIGIO + ';margin-top:2px">' 299 + reg.nRischi + ' rischi valutati · <b>' + reg.nDaDecidere + ' azioni da decidere</b> · ' 300 + reg.nAccolte + ' accolte' 301 + (reg.nScoperti ? ' · <b style="color:#dc2626">' + reg.nScoperti + ' sopra soglia senza alcuna azione</b>' : '') 302 + (reg.nSenzaProposte ? ' · ' + reg.nSenzaProposte + ' senza proposte del tool' : '') 303 + '</div></div>'; 304 305 var ordinate = reg.righe.slice().sort(function (a, b) { 306 var pa = a.scoperto ? 0 : (a.senzaProposte ? 1 : 2); 307 var pb = b.scoperto ? 0 : (b.senzaProposte ? 1 : 2); 308 return pa - pb || b.residuo - a.residuo; 309 }); 310 311 ordinate.forEach(function (r) { 312 h += '<div style="padding:12px 16px;border-top:1px solid #f1f5f9' 313 + (r.scoperto ? ';background:#fff7f7' : '') + '">'; 314 h += '<div style="display:flex;gap:10px;align-items:baseline;flex-wrap:wrap">' 315 + '<span style="font-size:9.5px;font-weight:900;color:#fff;background:#' + r.fasciaColore 316 + ';border-radius:4px;padding:2px 7px">' + _e(r.fascia) + '</span>' 317 + '<span style="font-size:10px;font-weight:900;color:' + GRIGIO + '">' + _e(r.cod) + '</span>' 318 + '<span style="font-size:13px;font-weight:800;color:' + NAVY + '">' + _e(r.nome) + '</span>' 319 + '<span style="font-size:10.5px;color:' + GRIGIO + '">P' + r.P + ' · D' + r.D 320 + ' · R ' + r.R + ' â residuo <b>' + r.residuo + '</b></span>' 321 + '<span style="margin-left:auto;font-size:10px;color:#94a3b8">' + _e(r.mansione) + '</span></div>'; 322 h += '<div style="font-size:10px;color:' + GRIGIO + ';margin-top:3px"><b>Norma:</b> ' + _e(r.norma) + '</div>'; 323 324 if (r.senzaProposte) { 325 h += '<div style="margin-top:8px;padding:9px 12px;background:#fffbeb;border:1px solid #fde68a;border-radius:9px;' 326 + 'font-size:11px;color:#92400e">Il tool non sa proporre alcuna azione per questo rischio. ' 327 + '<b>Non significa che non serva:</b> significa che la misura la devi scrivere tu.' 328 + (pre ? ' <button type="button" onclick="' + pre + '(\'' + _e(r.cod) + '\',\'nuova\')" style="cursor:pointer;border:1px solid #d97706;background:#fff;color:#b45309;border-radius:7px;font-size:10.5px;font-weight:800;padding:4px 10px;margin-left:6px;font-family:inherit">Scrivi una misura</button>' : '') 329 + '</div>'; 330 } 331 r.azioni.forEach(function (a) { 332 h += '<div style="margin-top:8px;padding:9px 12px;border:1px solid #e2e8f0;border-radius:9px;background:#fcfdff">' 333 + '<div style="display:flex;gap:8px;align-items:baseline;flex-wrap:wrap">' 334 + '<span style="font-size:9px;font-weight:900;text-transform:uppercase;letter-spacing:.05em;
334color:#fff;background:#' 335 + a.verdettoColore + ';border-radius:4px;padding:2px 6px">' + _e(a.verdettoLabel) + '</span>' 336 + '<span style="font-size:9.5px;font-weight:800;color:' + GRIGIO + ';text-transform:uppercase">' + _e(a.tipo) + '</span>' 337 + (a.riduzioneAttesa > 0 338 ? '<span style="font-size:10px;font-weight:800;color:#16a34a">riduce ' + a.rResiduoPre + ' â ' + a.rAtteso + '</span>' 339 : '<span style="font-size:10px;color:#94a3b8">nessuna riduzione attesa dichiarata</span>') 340 + '</div>' 341 + '<div style="font-size:12px;color:#1e293b;line-height:1.45;margin-top:4px">' + _e(a.descrizione) + '</div>' 342 + (a.norma ? '<div style="font-size:10px;color:' + GRIGIO + ';margin-top:2px">' + _e(a.norma) + '</div>' : '') 343 + (a.motivo ? '<div style="font-size:10.5px;color:#991b1b;margin-top:4px"><b>Rifiutata perché:</b> ' + _e(a.motivo) + '</div>' : '') 344 + (a.testoTecnico ? '<div style="font-size:10.5px;color:#1d4ed8;margin-top:4px"><b>Tuo testo:</b> ' + _e(a.testoTecnico) + '</div>' : '') 345 + _bottoni(a, pre) 346 + '</div>'; 347 }); 348 h += '</div>'; 349 }); 350 return h + '</div>'; 351 } 352 353 /** Il piano di esecuzione, disegnato. Le voci senza responsabile o data stanno in testa. */ 354 function htmlPiano(d, opts) { 355 opts = opts || {}; 356 var p = opts.piano || A.piano(d); 357 if (!p.disponibile) return ''; 358 if (!p.totale) { 359 return '<div style="border:1px solid #e2e8f0;border-radius:14px;background:#fff;padding:15px 17px">' 360 + '<div style="font-size:14px;font-weight:800;color:' + NAVY + '">Piano di esecuzione</div>' 361 + '<div style="font-size:11.5px;color:' + GRIGIO + ';margin-top:4px">Nessuna azione è ancora stata accolta: ' 362 + 'il piano si popola man mano che ti pronunci sulle proposte qui sopra.</div></div>'; 363 } 364 var h = '<div style="border:1px solid #e2e8f0;border-radius:14px;background:#fff;overflow:hidden">' 365 + '<div style="padding:13px 16px;border-top:3px solid #16a34a;border-bottom:1px solid #e2e8f0">' 366 + '<div style="font-size:9.5px;font-weight:900;letter-spacing:.09em;text-transform:uppercase;color:' + GRIGIO + '">' 367 + _e(p.norma) + '</div>' 368 + '<div style="font-size:14.5px;font-weight:800;color:' + NAVY + ';margin-top:3px">Piano di esecuzione</div>' 369 + '<div style="font-size:11px;color:' + GRIGIO + ';margin-top:2px">' + p.totale + ' azioni accolte' 370 + (p.incomplete ? ' · <b style="color:#d97706">' + p.incomplete + ' senza responsabile o data</b>' : '') 371 + ' · riduzione attesa complessiva <b>' + p.riduzioneAttesaTotale + ' punti</b></div></div>'; 372 p.voci.forEach(function (v) { 373 h += '<div style="padding:10px 16px;border-top:1px solid #f1f5f9' + (v.incompleta ? ';background:#fffbeb' : '') + '">' 374 + '<div style="font-size:12px;font-weight:700;color:#1e293b">' + _e(v.azione) + '</div>' 375 + '<div style="font-size:10px;color:' + GRIGIO + ';margin-top:3px">' 376 + _e(v.rischio) + ' · ' + _e(v.mansione) + ' · ' + _e(v.norma) + '</div>' 377 + '<div style="font-size:10.5px;margin-top:3px;color:' + (v.incompleta ? '#b45309' : GRIGIO) + '">' 378 + '<b>Chi:</b> ' + _e(v.responsabile || 'â da indicare') + ' · <b>Entro:</b> ' + _e(v.scadenza || 'â da indicare') 379 + (v.incompleta ? ' â un impegno senza nome e senza data non impegna nessuno' : '') 380 + '</div></div>'; 381 }); 382 return h + '</div>'; 383 } 384 385 A.html = html; 386 A.htmlPiano = htmlPiano; 387})(typeof window !== 'undefined' ? window : this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.