From 01edc3bee1375bd3e687e1866d6d11a9ada74941 Mon Sep 17 00:00:00 2001 From: WASRUSGEN Date: Wed, 27 May 2026 13:08:55 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20MS=20Project-style=20Gantt=20at=20botto?= =?UTF-8?q?m=20of=20=D0=9C=D0=BE=D0=B8=20=D0=B4=D0=B5=D0=BB=D0=B0=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split view: left table (num/name/dur/start/end) + right timeline grid - 11 rows: 3 contracts as groups, 8 subtasks - Color-coded bars: done/active/urgent/pending/group - Today marker (red line), weekend columns shaded - Scrollable on mobile, renders on cabinet open --- mockup.html | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/mockup.html b/mockup.html index 35eab86..2f3035a 100644 --- a/mockup.html +++ b/mockup.html @@ -321,6 +321,54 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei .tk-status.active{background:rgba(96,165,250,.18);color:#93c5fd} .tk-dot{color:rgba(255,255,255,.2);padding:0 8px;font-size:16px} +/* ── MS-PROJECT GANTT ── */ +.msp-section{margin-top:28px;border-top:2px solid var(--line);padding-top:16px} +.msp-title{font-size:13px;font-weight:800;color:var(--mut);text-transform:uppercase;letter-spacing:.6px;margin-bottom:12px} +.msp-outer{border:1.5px solid #d1d5db;border-radius:10px;overflow:hidden;font-size:12px;font-family:var(--font-ui)} +.msp-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch} +.msp-table{display:grid;min-width:820px} +/* Шапка */ +.msp-head{display:flex;background:#e8e8f0;border-bottom:2px solid #b0b0c8;font-weight:700;font-size:11px;color:#444} +.msp-head .msp-left{display:flex;border-right:2px solid #b0b0c8;flex-shrink:0} +.msp-head .msp-right{flex:1;position:relative;overflow:hidden} +.msp-hcol{padding:6px 8px;border-right:1px solid #c8c8d8;white-space:nowrap;color:#333} +.msp-hcol.msp-c-num{width:32px;text-align:center} +.msp-hcol.msp-c-name{width:200px} +.msp-hcol.msp-c-dur{width:56px;text-align:center} +.msp-hcol.msp-c-start{width:72px;text-align:center} +.msp-hcol.msp-c-end{width:72px;text-align:center} +/* Строки */ +.msp-row{display:flex;border-bottom:1px solid #e5e7eb;cursor:pointer} +.msp-row:hover{background:#f0f0ff} +.msp-row.msp-group{background:#f3f4f8;font-weight:700} +.msp-row.msp-group:hover{background:#ebebf8} +.msp-row:last-child{border-bottom:none} +.msp-left{display:flex;border-right:2px solid #b0b0c8;flex-shrink:0} +.msp-right{flex:1;position:relative;height:28px;overflow:hidden} +.msp-cell{padding:6px 8px;border-right:1px solid #e5e7eb;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center} +.msp-cell.msp-c-num{width:32px;justify-content:center;color:#888;font-size:10px} +.msp-cell.msp-c-name{width:200px} +.msp-cell.msp-c-name.ind{padding-left:20px;font-weight:400;color:#333} +.msp-cell.msp-c-dur{width:56px;justify-content:center;color:#555} +.msp-cell.msp-c-start{width:72px;justify-content:center;color:#555;font-size:11px} +.msp-cell.msp-c-end{width:72px;justify-content:center;color:#555;font-size:11px} +/* Сетка и бары */ +.msp-grid-bg{position:absolute;inset:0;display:flex} +.msp-grid-col{flex:1;border-right:1px solid #e8e8f0;height:100%} +.msp-grid-col.weekend{background:#f5f5fb} +.msp-bar-wrap{position:absolute;inset:0;pointer-events:none} +.msp-bar{position:absolute;top:5px;height:18px;border-radius:3px;display:flex;align-items:center;padding:0 6px;font-size:10px;font-weight:700;color:#fff;white-space:nowrap;overflow:hidden} +.msp-bar.b-group{background:linear-gradient(180deg,#4a4a8a,#2d2d6a);height:8px;top:10px;border-radius:1px} +.msp-bar.b-done{background:linear-gradient(180deg,#2d7a2d,#1a5c1a)} +.msp-bar.b-active{background:linear-gradient(180deg,#1a56db,#1e40af)} +.msp-bar.b-urgent{background:linear-gradient(180deg,#c81e1e,#991b1b)} +.msp-bar.b-pending{background:linear-gradient(180deg,#6b7280,#4b5563)} +.msp-today{position:absolute;top:0;bottom:0;width:2px;background:#c81e1e;z-index:5;pointer-events:none} +.msp-today::before{content:'▼';position:absolute;top:-1px;left:50%;transform:translateX(-50%);color:#c81e1e;font-size:9px;line-height:1} +/* Дата-шапка на сетке */ +.msp-date-hdr{height:28px;position:relative;border-bottom:1px solid #c8c8d8;background:#e8e8f0} +.msp-date-tick{position:absolute;top:0;bottom:0;display:flex;align-items:center;font-size:10px;font-weight:700;color:#555;padding-left:4px;border-left:1px solid #c8c8d8;white-space:nowrap} + /* ── RETURNING CLIENT ── */ .ret-greet{font-size:30px;font-weight:800;line-height:1.2;margin-bottom:24px;letter-spacing:-.5px} .ret-sub{font-size:16px;color:rgba(255,255,255,.7);margin-bottom:22px} @@ -874,6 +922,15 @@ body{font-family:var(--font-ui);background:var(--surf);color:var(--ink);line-hei
🍽️
Кухня — агентский договор (ЗОВ)
23.05 · 12 рисков
⚠ Высокийсрок 3 дняпротокол готовится
Открыть →
💼
Трудовой договор
21.05 · 6 моментов
Среднийна проверке
Открыть →
🏠
Квартира — ДДУ (новая редакция)
19.05 · ждёт сверки
🔍 сверка версий
Открыть →
+ + +
+
⏱ Диаграмма сроков
+
+
+
+
+
@@ -1711,6 +1768,126 @@ window.addEventListener('DOMContentLoaded', checkReturning); }); })(); +/* ── MS-PROJECT GANTT ── */ +(function(){ + // Данные + var DATA = [ + { num:1, group:true, name:'🍽️ Кухня — агентский', dur:'18 дн', start:'23.05', end:'10.06', s:'2025-05-23', e:'2025-06-10', cls:'b-group', go:"tab('case')" }, + { num:2, group:false, name:' Анализ рисков', dur:'2 дн', start:'23.05', end:'24.05', s:'2025-05-23', e:'2025-05-24', cls:'b-done', go:"tab('case')" }, + { num:3, group:false, name:' Протокол разногласий', dur:'3 дн', start:'24.05', end:'27.05', s:'2025-05-24', e:'2025-05-27', cls:'b-urgent', go:"tab('case')" }, + { num:4, group:false, name:' Ответ контрагенту', dur:'2 дн', start:'27.05', end:'29.05', s:'2025-05-27', e:'2025-05-29', cls:'b-pending', go:"tab('case')" }, + { num:5, group:true, name:'💼 Трудовой договор', dur:'15 дн', start:'21.05', end:'05.06', s:'2025-05-21', e:'2025-06-05', cls:'b-group', go:"tab('case')" }, + { num:6, group:false, name:' Первичный анализ', dur:'1 дн', start:'21.05', end:'22.05', s:'2025-05-21', e:'2025-05-22', cls:'b-done', go:"tab('case')" }, + { num:7, group:false, name:' Допсоглашение', dur:'8 дн', start:'22.05', end:'30.05', s:'2025-05-22', e:'2025-05-30', cls:'b-active', go:"tab('case')" }, + { num:8, group:false, name:' Проверка финала', dur:'5 дн', start:'30.05', end:'05.06', s:'2025-05-30', e:'2025-06-05', cls:'b-pending', go:"tab('case')" }, + { num:9, group:true, name:'🏠 ДДУ (новая редакция)', dur:'17 дн', start:'19.05', end:'05.06', s:'2025-05-19', e:'2025-06-05', cls:'b-group', go:"tab('case')" }, + { num:10, group:false, name:' Сверка версий', dur:'8 дн', start:'19.05', end:'27.05', s:'2025-05-19', e:'2025-05-27', cls:'b-active', go:"tab('case')" }, + { num:11, group:false, name:' Финальное заключение', dur:'9 дн', start:'27.05', end:'05.06', s:'2025-05-27', e:'2025-06-05', cls:'b-pending', go:"tab('case')" }, + ]; + + var RS = new Date('2025-05-17T00:00:00'); + var RE = new Date('2025-06-15T00:00:00'); + var TOT = (RE - RS) / 86400000; + + function pct(str) { + var dt = new Date(str + 'T00:00:00'); + return Math.max(0, Math.min(100, (dt - RS) / 86400000 / TOT * 100)); + } + + // Построить тики дат + function buildDateTicks() { + var ticks = []; var cur = new Date(RS); + while(cur <= RE) { ticks.push(new Date(cur)); cur.setDate(cur.getDate()+7); } + return ticks; + } + + // Построить сетку (колонки = дни) + function buildGridCols() { + var cols = ''; var cur = new Date(RS); + while(cur < RE) { + var d = cur.getDay(); + cols += '
'; + cur.setDate(cur.getDate()+1); + } + return cols; + } + + function render() { + var root = document.getElementById('msp-root'); + if (!root) return; + + var today = new Date(); today.setHours(0,0,0,0); + var todayPct = pct(today.toISOString().slice(0,10)); + + var ticks = buildDateTicks(); + var gridCols = buildGridCols(); + var m = ['янв','фев','мар','апр','май','июн','июл','авг','сен','окт','ноя','дек']; + + // Шапка дат + var ticksHTML = ticks.map(function(dt){ + return '
'+ + dt.getDate()+' '+m[dt.getMonth()]+'
'; + }).join(''); + + // HEAD + var head = '
' + + '
' + + '
#
' + + '
Название задачи
' + + '
Длит.
' + + '
Начало
' + + '
Окончание
' + + '
' + + '
' + + '
' + ticksHTML + '
' + + '
' + + '
'; + + // ROWS + var rows = DATA.map(function(r){ + var left_pct = pct(r.s); + var right_pct = pct(r.e); + var w = Math.max(0.5, right_pct - left_pct); + var barLabel = r.group ? '' : r.end; + + return '
' + + '
' + + '
'+r.num+'
' + + '
'+r.name+'
' + + '
'+r.dur+'
' + + '
'+r.start+'
' + + '
'+r.end+'
' + + '
' + + '
' + + '
'+gridCols+'
' + + '
' + + '
' + + '
'+barLabel+'
' + + '
' + + '
' + + '
'; + }).join(''); + + root.innerHTML = head + rows; + } + + // Рендерим при открытии кабинета и при tab('cases') + var _origTab = window.tab; + window.tab = function(id) { + if (_origTab) _origTab(id); + if (id === 'cases') setTimeout(render, 50); + }; + var _origGo = window.go; + window.go = function(id) { + if (_origGo) _origGo(id); + if (id === 'cabinet') setTimeout(render, 80); + }; + window.addEventListener('DOMContentLoaded', function(){ + var el = document.getElementById('p-cases'); + if (el && el.classList.contains('on')) render(); + }); +})(); + /* ── СТАТУС ЗАКАЗА ── */ const OS_DEADLINES = { protocol: { 1:'до 12 часов', 2:'до 24 часов', 3:'до 48 часов', sub:'после получения файла договора' },