Files
Stend_mont/app/templates/bundles.html
T
ruslan 40de4d5a0f Bundles feature WIP + fix request-access products cap (20 -> 200)
- app/main.py: raise products_raw[:20] cap to [:200] in /api/request-access
  and /api/request-more-access - was silently truncating access requests
  with more than 20 selected products
- accumulated bundles/product-page WIP (config, models, runtime, templates)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 13:58:09 +00:00

208 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Готовые связки — MONT инфраструктурный полигон</title>
<link rel="stylesheet" href="/static/style.css?v=2" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon_32.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/static/favicon_192.png" />
<link rel="apple-touch-icon" sizes="192x192" href="/static/favicon_192.png" />
<link rel="manifest" href="/static/manifest.json" />
<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function(m,e,t,r,i,k,a){
m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
})(window, document,"script","https://mc.yandex.ru/metrika/tag.js?id=109119977", "ym");
ym(109119977, "init", {ssr:true, webvisor:true, clickmap:true, ecommerce:"dataLayer", referrer: document.referrer, url: location.href, accurateTrackBounce:true, trackLinks:true});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/109119977" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
<style>
#mobile-wall{display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:9999;background:linear-gradient(135deg,#0d1b2a 0%,#1a2e45 60%,#0f2137 100%);flex-direction:column;align-items:center;justify-content:center;padding:clamp(1rem,6vw,2.5rem);text-align:center;font-family:sans-serif;box-sizing:border-box;overflow:hidden}
@media(max-width:1023px){ #mobile-wall{display:flex} }
.mw-icon{font-size:clamp(2.2rem,12vw,3.5rem);margin-bottom:clamp(.5rem,2vw,1.2rem);filter:drop-shadow(0 0 18px rgba(42,140,214,.5))}
.mw-title{font-size:clamp(1rem,5.5vw,1.5rem);font-weight:800;color:#fff;margin-bottom:.6rem;letter-spacing:.01em;word-break:break-word;width:100%}
.mw-sub{font-size:clamp(.8rem,3.8vw,.95rem);color:#a0b8cc;width:100%;max-width:320px;line-height:1.6;margin-bottom:clamp(.8rem,4vw,2rem);word-break:break-word;overflow-wrap:break-word}
.mw-badge{display:inline-flex;align-items:center;gap:.45rem;background:rgba(42,140,214,.15);border:1px solid rgba(42,140,214,.4);border-radius:999px;padding:.45rem .9rem;color:#6bbfff;font-size:clamp(.7rem,3.2vw,.85rem);font-weight:600;max-width:88vw;flex-wrap:wrap;justify-content:center;word-break:break-word}
.mw-badge svg{width:16px;height:16px;flex-shrink:0}
.mw-footer{position:absolute;bottom:1.2rem;left:0;width:100%;text-align:center;font-size:clamp(.65rem,2.8vw,.78rem);color:rgba(160,184,204,.45);font-family:sans-serif}
:root{
--dv-bg:#eef1f5; --dv-panel:#fff; --dv-raised:#fff;
--dv-line:#d7dee6; --dv-line-soft:#e3e8ee;
--dv-fg:#16202c; --dv-fg-dim:#5c6b7c; --dv-fg-faint:#93a1b0;
--dv-accent:#c96c14; --dv-accent-dim:rgba(201,108,20,.10); --dv-accent-ink:#2a1400;
--dv-good:#1f9d63;
}
.dashboard-page{background:var(--dv-bg) !important;color:var(--dv-fg);
font-family:"Ubuntu","IBM Plex Sans",system-ui,sans-serif;min-height:100vh;overflow-x:hidden}
.dashboard-page *{box-sizing:border-box;min-width:0}
.dashboard-page a{color:inherit;text-decoration:none}
.dv-shell{display:grid;grid-template-columns:248px minmax(0,1fr);min-height:100vh}
@media (max-width:980px){ .dv-shell{grid-template-columns:minmax(0,1fr)} }
.dv-rail{border-right:1px solid var(--dv-line);padding:26px 16px 26px 24px;position:sticky;top:0;
align-self:start;height:100vh;overflow:auto;display:flex;flex-direction:column;gap:22px}
@media (max-width:980px){ .dv-rail{position:static;height:auto;border-right:none;border-bottom:1px solid var(--dv-line);padding:20px 18px} }
.dv-rail-brand{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.dv-rail-brand img{height:30px}
.dv-rail-kicker{font:700 11px/1 "Ubuntu Mono",monospace;letter-spacing:.16em;color:var(--dv-fg-faint);text-transform:uppercase;margin:0 0 8px 10px}
.dv-rail-nav{display:flex;flex-direction:column;gap:2px}
@media (max-width:980px){ .dv-rail-nav{flex-direction:row;flex-wrap:wrap;gap:6px} }
.dv-rail-link{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:6px;
font:500 14px/1.3 "Ubuntu",sans-serif;color:var(--dv-fg-dim);border:1px solid transparent}
.dv-rail-link:hover{background:var(--dv-panel);color:var(--dv-fg);border-color:var(--dv-line)}
.dv-rail-dot{width:6px;height:6px;border-radius:50%;background:var(--dv-fg-faint);flex-shrink:0}
.dv-rail-link:hover .dv-rail-dot{background:var(--dv-accent)}
.dv-rail-count{margin-left:auto;font:600 11px/1 "Ubuntu Mono",monospace;color:var(--dv-fg-faint)}
.dv-rail-link.active{background:var(--dv-accent-dim);border-color:var(--dv-accent);color:var(--dv-fg)}
.dv-rail-link.active .dv-rail-dot{background:var(--dv-accent)}
.dv-rail-link.active .dv-rail-count{color:var(--dv-accent)}
.dv-rail-foot{margin-top:auto;font:400 12px/1.6 "Ubuntu Mono",monospace;color:var(--dv-fg-faint)}
@media (max-width:980px){ .dv-rail-foot{display:none} }
.dv-main{padding:0 clamp(18px,3vw,48px) 70px;min-width:0}
.dv-topbar{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:20px 0;
border-bottom:1px solid var(--dv-line);flex-wrap:wrap}
.dv-who{display:flex;align-items:center;gap:10px}
.dv-who-avatar{width:32px;height:32px;border-radius:8px;background:var(--dv-raised);border:1px solid var(--dv-line);
display:flex;align-items:center;justify-content:center;font:700 13px/1 "Ubuntu Mono",monospace;color:var(--dv-accent)}
.dv-who-name{font:500 14.5px/1.2 "Ubuntu",sans-serif}
.dv-who-role{font:400 12px/1.2 "Ubuntu Mono",monospace;color:var(--dv-fg-faint)}
.dv-topbar-actions{display:flex;gap:8px}
.dv-btn{font:600 13px/1 "Ubuntu",sans-serif;padding:9px 16px;border-radius:7px;border:1px solid var(--dv-line);
background:var(--dv-panel);color:var(--dv-fg-dim);cursor:pointer}
.dv-btn:hover{color:var(--dv-fg);border-color:var(--dv-fg-faint)}
.dv-hero{padding:32px 0 30px;border-bottom:1px solid var(--dv-line)}
.dv-hero-eyebrow{font:700 12.5px/1 "Ubuntu Mono",monospace;letter-spacing:.16em;text-transform:uppercase;color:var(--dv-accent);margin:0 0 10px}
.dv-hero h1{font:800 clamp(28px,3.8vw,40px)/1.1 "Ubuntu",sans-serif;letter-spacing:-.01em;margin:0 0 14px;overflow-wrap:break-word}
.dv-hero-lede{font:400 15px/1.6 "Ubuntu",sans-serif;color:var(--dv-fg-dim);max-width:70ch;margin:0}
.dv-section{padding:36px 0 6px}
.dv-section-head{display:flex;align-items:baseline;gap:12px;margin-bottom:16px}
.dv-section-head h2{font:700 13.5px/1 "Ubuntu Mono",monospace;letter-spacing:.1em;text-transform:uppercase;margin:0}
.dv-section-head::after{content:"";flex:1;height:1px;background:var(--dv-line)}
.dv-scn-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}
.dv-scn-card{position:relative;background:var(--dv-panel);border:1px solid var(--dv-line);border-radius:12px;
padding:18px 18px 16px;opacity:.85}
.dv-scn-title{font:600 15px/1.35 "Ubuntu",sans-serif;margin:0 0 8px;padding-right:70px}
.dv-scn-desc{font:400 13.5px/1.55 "Ubuntu",sans-serif;color:var(--dv-fg-dim);margin:0}
.dv-scn-badge{position:absolute;top:16px;right:16px;font:700 10px/1 "Ubuntu Mono",monospace;letter-spacing:.06em;
text-transform:uppercase;color:var(--dv-accent);background:var(--dv-accent-dim);border:1px solid var(--dv-accent);
border-radius:999px;padding:4px 9px}
.dv-page-footer{margin-top:50px;padding-top:20px;border-top:1px solid var(--dv-line);display:flex;
justify-content:space-between;flex-wrap:wrap;gap:8px;font:400 12px/1 "Ubuntu Mono",monospace;color:var(--dv-fg-faint)}
</style>
</head>
<body class="dashboard-page">
<div id="mobile-wall">
<a href="https://4mont.ru"><img src="/static/logo.png?v=4" alt="MONT" style="position:absolute;top:1.2rem;left:50%;transform:translateX(-50%);height:clamp(4rem,16vw,6rem);opacity:.9"></a>
<div class="mw-icon">🖥️</div>
<div class="mw-title">Только для компьютера</div>
<div class="mw-sub">Инфраструктурный полигон MONT оптимизирован для работы на ПК.<br>Пожалуйста, откройте портал с настольного компьютера или ноутбука.</div>
<div class="mw-badge">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
Минимальная ширина экрана: 1024 px
</div>
<div class="mw-footer"><a href="mailto:ruslan@ipcom.su" style="color:inherit;text-decoration:none">Made by Galyaviev</a></div>
</div>
<div class="dv-shell">
<aside class="dv-rail">
<div class="dv-rail-brand"><a href="https://4mont.ru"><img src="/static/logo-color.png?v=1" alt="MONT" /></a></div>
<div>
<div class="dv-rail-kicker">Категории</div>
<nav class="dv-rail-nav">
<a class="dv-rail-link" href="/">
<span class="dv-rail-dot"></span>Все сервисы
</a>
</nav>
</div>
<div>
<div class="dv-rail-kicker">Скоро</div>
<nav class="dv-rail-nav">
<a class="dv-rail-link active" href="/bundles">
<span class="dv-rail-dot"></span>Готовые связки<span class="dv-rail-count">NEW</span>
</a>
</nav>
</div>
<div class="dv-rail-foot">SESSION LIMIT: {{ max_active_services }}<br/>IDLE TIMEOUT: {{ idle_timeout_min }} MIN<br/>RESET: 00:00 MSK</div>
</aside>
<main class="dv-main">
<div class="dv-topbar">
<div class="dv-who">
<div class="dv-who-avatar">{{ ((user.first_name[0] if user.first_name else user.username[0]) + (user.last_name[0] if user.last_name else ''))|upper }}</div>
<div>
<div class="dv-who-name">{{ (user.first_name + ' ' + user.last_name)|trim or user.username }}</div>
<div class="dv-who-role">оператор стенда</div>
</div>
</div>
<div class="dv-topbar-actions">
{% if user.is_admin %}
<a class="dv-btn" href="/admin">Администрирование</a>
{% endif %}
<form method="post" action="/logout" style="margin:0">
<button type="submit" class="dv-btn">Выход</button>
</form>
</div>
</div>
<div class="dv-hero">
<p class="dv-hero-eyebrow">MONT · Готовые связки</p>
<h1>Комплексные инфраструктуры</h1>
<p class="dv-hero-lede">Заказчику редко нужен один продукт в вакууме — обычно решение должно встроиться в существующую или новую инфраструктуру. Мы собираем на полигоне связку из нескольких продуктов, имитирующую реальный сценарий внедрения, чтобы показать не «продукт», а готовое решение задачи. Раздел готовится — ниже сценарии, которые уже прорабатываются.</p>
</div>
<section class="dv-section">
<div class="dv-section-head"><h2>В подготовке</h2></div>
<div class="dv-scn-grid">
<div class="dv-scn-card">
<span class="dv-scn-badge">Готовится</span>
<div class="dv-scn-title">Миграция домена</div>
<div class="dv-scn-desc">ALDpro в связке с рабочими станциями на Astra Linux, РЕД ОС и Альт Рабочая станция — вход, групповые политики и совместная работа каталога с разными ОС на местах.</div>
</div>
<div class="dv-scn-card">
<span class="dv-scn-badge">Готовится</span>
<div class="dv-scn-title">VDI-инфраструктура</div>
<div class="dv-scn-desc">Termidesk поверх Ред Виртуализация — типовой сценарий виртуальных рабочих столов, от сервера виртуализации до подключения пользователя.</div>
</div>
<div class="dv-scn-card">
<span class="dv-scn-badge">Готовится</span>
<div class="dv-scn-title">Резервное копирование виртуальной инфраструктуры</div>
<div class="dv-scn-desc">RuBackup или Vinchin в связке с Альт Виртуализация (PVE) — бэкап и восстановление виртуальных машин на живом кластере.</div>
</div>
<div class="dv-scn-card">
<span class="dv-scn-badge">Готовится</span>
<div class="dv-scn-title">Импортозамещение рабочего места целиком</div>
<div class="dv-scn-desc">ОС (Astra Linux / РЕД ОС / Альт Рабочая станция) + офисный пакет (АльтерОфис / P7-КС2024) + почта (CommuniGate Pro / RuPost) — полный стек рабочего места сотрудника.</div>
</div>
<div class="dv-scn-card">
<span class="dv-scn-badge">Готовится</span>
<div class="dv-scn-title">Контейнеризированное приложение с базой данных</div>
<div class="dv-scn-desc">Deckhouse Platform (Kubernetes) + Postgres Pro или Tantor — развёртывание приложения с реальной СУБД под капотом.</div>
</div>
<div class="dv-scn-card">
<span class="dv-scn-badge">Готовится</span>
<div class="dv-scn-title">Наблюдаемость виртуальной инфраструктуры</div>
<div class="dv-scn-desc">Astra Мониторинг поверх Ред Виртуализация или Альт Виртуализация (PVE) — контроль состояния кластера и виртуальных машин.</div>
</div>
</div>
</section>
<footer class="dv-page-footer"><span>MONT PROVING GROUND</span><a href="mailto:ruslan@ipcom.su">Made by Galyaviev</a></footer>
</main>
</div>
</body>
</html>