v1.8.4: единая стилистика — замена confirm/alert/prompt на кастомные модалки, SERVICE_STYLE_GUIDE.md, обновлен AGENTS.md
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
# Сервисный портал AegisOne — Единый стиль
|
||||
|
||||
> Этот документ ОБЯЗАН прочитать каждый AI-агент перед изменением шаблонов/CSS сервисного портала.
|
||||
|
||||
---
|
||||
|
||||
## 1. Структура страницы
|
||||
|
||||
Каждая страница наследует `page.html` и реализует блок `page_content`.
|
||||
|
||||
### Порядок элементов в правой части (main):
|
||||
|
||||
```
|
||||
page.html main-header:
|
||||
left: h1 (заголовок) + breadcrumb
|
||||
right: page_actions block + дата {{ now }}
|
||||
|
||||
page_content:
|
||||
1. div.card — основной контент
|
||||
├── div.card-header — заголовок + кнопка действия
|
||||
├── div.filter-bar — фильтры (если нужны)
|
||||
└── div.table-wrap > table — таблица данных
|
||||
|
||||
2. div.modal-overlay#modal-xxx — модалка создания/редактирования
|
||||
3. div.modal-overlay#confirm-delete-xxx — модалка подтверждения удаления
|
||||
```
|
||||
|
||||
### Card Header:
|
||||
|
||||
```html
|
||||
<div class="card-header">
|
||||
<h2>Название секции</h2>
|
||||
<button class="btn btn-primary btn-sm" onclick="openModal()">+ Действие</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Модалки
|
||||
|
||||
### Единые CSS-классы
|
||||
|
||||
| Класс | Назначение |
|
||||
|-------|-----------|
|
||||
| `.modal-overlay` | Затемнённый фон (position: fixed, z-index: 200) |
|
||||
| `.modal-overlay.open` | Показать модалку (display: flex) |
|
||||
| `.modal` | Контейнер модалки (фон, рамка, скругление) |
|
||||
| `.modal-close` | Кнопка закрытия (✕) в правом верхнем углу |
|
||||
| `.form-actions` | Блок кнопок внизу модалки (display: flex, gap: 10px) |
|
||||
|
||||
### Открытие/закрытие
|
||||
|
||||
```javascript
|
||||
// Открыть
|
||||
document.getElementById('modal-xxx').classList.add('open');
|
||||
|
||||
// Закрыть
|
||||
document.getElementById('modal-xxx').classList.remove('open');
|
||||
|
||||
// Или изнутри кнопки
|
||||
this.closest('.modal-overlay').classList.remove('open');
|
||||
```
|
||||
|
||||
**ЗАПРЕЩЕНО:** использовать `style.display = 'flex'` / `style.display = 'none'`
|
||||
|
||||
### Модалка создания/редактирования (стандарт)
|
||||
|
||||
```html
|
||||
<div class="modal-overlay" id="modal-xxx">
|
||||
<div class="modal">
|
||||
<button type="button" class="modal-close"
|
||||
onclick="this.closest('.modal-overlay').classList.remove('open')">✕</button>
|
||||
<h2>Название</h2>
|
||||
<form method="post" action="/service/xxx/create">
|
||||
<div class="form-row">
|
||||
<div class="form-group"><label>Поле</label><input type="text" name="field"></div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
<button type="button" class="btn"
|
||||
onclick="this.closest('.modal-overlay').classList.remove('open')">Отмена</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Модалка подтверждения удаления (единый шаблон)
|
||||
|
||||
**ЗАПРЕЩЕНЫ:** `confirm()`, `alert()`, `prompt()` — только кастомные модалки!
|
||||
|
||||
```html
|
||||
<div class="modal-overlay" id="confirm-delete-xxx">
|
||||
<div class="modal" style="max-width:420px;">
|
||||
<h2 style="font-size:16px;margin-bottom:8px;">Удалить [объект]?</h2>
|
||||
<p style="color:var(--text-secondary);font-size:14px;margin-bottom:20px;">
|
||||
<strong id="delete-xxx-name"></strong> будет удалён навсегда.
|
||||
Это действие нельзя отменить.
|
||||
</p>
|
||||
<div class="form-actions" style="justify-content:flex-end;">
|
||||
<button type="button" class="btn btn-danger" onclick="confirmDeleteXxx()">Удалить</button>
|
||||
<button type="button" class="btn" onclick="closeConfirmDeleteXxx()">Отмена</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Порядок кнопок в модалках
|
||||
|
||||
```
|
||||
[ Действие (btn-danger / btn-primary) ] [ Отмена (btn) ]
|
||||
слева справа
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Кнопки
|
||||
|
||||
### Иконки
|
||||
|
||||
| Иконка | Назначение | CSS-класс |
|
||||
|--------|-----------|-----------|
|
||||
| `+` | Создание (перед текстом) | `btn btn-primary btn-sm` |
|
||||
| `✎` | Редактирование | `btn btn-secondary btn-sm` |
|
||||
| `✕` | Удаление | `btn btn-danger btn-sm` |
|
||||
| `✓` | Завершение/включение | `btn btn-success btn-sm` |
|
||||
| `🗑` | Удаление (только в карточках) | `btn btn-danger btn-sm` |
|
||||
|
||||
### CSS-классы кнопок
|
||||
|
||||
| Класс | Назначение |
|
||||
|-------|-----------|
|
||||
| `.btn` | Базовая кнопка |
|
||||
| `.btn-primary` | Основное действие (синий) |
|
||||
| `.btn-secondary` | Вторичное действие (серый) |
|
||||
| `.btn-danger` | Удаление/опасное действие (красный) |
|
||||
| `.btn-success` | Успех/завершение (зелёный) |
|
||||
| `.btn-warning` | Предупреждение (жёлтый) |
|
||||
| `.btn-sm` | Маленький размер |
|
||||
|
||||
### Таблицы — колонка действий
|
||||
|
||||
```html
|
||||
<th class="actions"></th>
|
||||
<td class="actions">
|
||||
<button class="btn btn-secondary btn-sm" onclick="editXxx(...)" title="Редактировать">✎</button>
|
||||
<button class="btn btn-danger btn-sm" onclick="openConfirmDeleteXxx(...)" title="Удалить">✕</button>
|
||||
</td>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Уведомления
|
||||
|
||||
### Показ уведомлений
|
||||
|
||||
```javascript
|
||||
showNotification('Текст уведомления', 'success'); // зелёное
|
||||
showNotification('Текст уведомления', 'error'); // красное
|
||||
showNotification('Текст уведомления', 'warning'); // жёлтое
|
||||
showNotification('Текст уведомления', 'info'); // синее
|
||||
```
|
||||
|
||||
**ЗАПРЕЩЕНЫ:** `alert()`, `prompt()`, `confirm()` — только `showNotification()` и кастомные модалки!
|
||||
|
||||
---
|
||||
|
||||
## 5. Фильтры
|
||||
|
||||
```html
|
||||
<div class="filter-bar">
|
||||
<input type="text" id="search-input" placeholder="Поиск..." oninput="filterItems()">
|
||||
<select id="status-filter" onchange="filterItems()" class="filter-select">
|
||||
<option value="">Все статусы</option>
|
||||
</select>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Таблицы
|
||||
|
||||
```html
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Колонка 1</th>
|
||||
<th>Колонка 2</th>
|
||||
<th class="actions"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td>{{ item.field }}</td>
|
||||
<td>{{ item.field2 }}</td>
|
||||
<td class="actions">
|
||||
<button class="btn btn-secondary btn-sm" onclick="editXxx(...)">✎</button>
|
||||
<button class="btn btn-danger btn-sm" onclick="openConfirmDeleteXxx(...)">✕</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Страницы с JS-рендерингом
|
||||
|
||||
Для страниц, где данные загружаются через `fetch()` (bot_consent, bot_dialogues, bot_kb, bot_tickets, bot_unknown, charts):
|
||||
|
||||
- Таблица рендерится через `renderXxx(data)` в JavaScript
|
||||
- Фильтрация через `filterXxx()` на клиенте
|
||||
- Модалки подтверждения удаления — те же HTML-шаблоны
|
||||
|
||||
---
|
||||
|
||||
## 8. Чек-лист перед коммитом
|
||||
|
||||
- [ ] Нет `confirm()`, `alert()`, `prompt()` в коде
|
||||
- [ ] Модалки открываются через `classList.add('open')`
|
||||
- [ ] Модалки закрываются через `classList.remove('open')`
|
||||
- [ ] Кнопки удаления: `✕` (btn-danger)
|
||||
- [ ] Кнопки редактирования: `✎` (btn-secondary)
|
||||
- [ ] Порядок кнопок в модалках: Действие → Отмена
|
||||
- [ ] Уведомления через `showNotification()`
|
||||
- [ ] CSS-классы модалок: `.modal-overlay` / `.modal`
|
||||
Reference in New Issue
Block a user