962 lines
31 KiB
HTML
962 lines
31 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Панель управления - Группы и идентификаторы</title>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||
}
|
||
|
||
:root {
|
||
--primary: #3b82f6;
|
||
--primary-dark: #2563eb;
|
||
--primary-light: #60a5fa;
|
||
--secondary: #6b7280;
|
||
--success: #10b981;
|
||
--danger: #ef4444;
|
||
--warning: #f59e0b;
|
||
--info: #06b6d4;
|
||
--light: #f9fafb;
|
||
--dark: #111827;
|
||
--border: #e5e7eb;
|
||
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||
--radius: 8px;
|
||
}
|
||
|
||
body {
|
||
background-color: #f3f4f6;
|
||
color: var(--dark);
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.container {
|
||
max-width: 1400px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
}
|
||
|
||
/* Header */
|
||
.header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 20px 0;
|
||
margin-bottom: 30px;
|
||
border-bottom: 2px solid var(--border);
|
||
}
|
||
|
||
.logo {
|
||
font-size: 24px;
|
||
font-weight: 700;
|
||
color: var(--primary);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.user-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20px;
|
||
}
|
||
|
||
.user-details {
|
||
text-align: right;
|
||
}
|
||
|
||
.user-name {
|
||
font-weight: 600;
|
||
color: var(--dark);
|
||
}
|
||
|
||
.user-role {
|
||
font-size: 14px;
|
||
color: var(--secondary);
|
||
}
|
||
|
||
.btn-logout {
|
||
background-color: var(--danger);
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 16px;
|
||
border-radius: var(--radius);
|
||
cursor: pointer;
|
||
font-weight: 500;
|
||
transition: background-color 0.3s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.btn-logout:hover {
|
||
background-color: #dc2626;
|
||
}
|
||
|
||
/* Tabs */
|
||
.tabs {
|
||
display: flex;
|
||
border-bottom: 2px solid var(--border);
|
||
margin-bottom: 30px;
|
||
gap: 5px;
|
||
}
|
||
|
||
.tab {
|
||
padding: 12px 24px;
|
||
background: none;
|
||
border: none;
|
||
border-bottom: 3px solid transparent;
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
color: var(--secondary);
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
border-radius: var(--radius var(--radius) 0 0);
|
||
}
|
||
|
||
.tab:hover {
|
||
color: var(--primary);
|
||
background-color: #f0f9ff;
|
||
}
|
||
|
||
.tab.active {
|
||
color: var(--primary);
|
||
border-bottom-color: var(--primary);
|
||
background-color: #f0f9ff;
|
||
}
|
||
|
||
/* Tab Content */
|
||
.tab-content {
|
||
display: none;
|
||
animation: fadeIn 0.5s;
|
||
}
|
||
|
||
.tab-content.active {
|
||
display: block;
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; transform: translateY(10px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
/* Toolbar */
|
||
.toolbar {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
flex-wrap: wrap;
|
||
gap: 15px;
|
||
}
|
||
|
||
.search-container {
|
||
flex: 1;
|
||
min-width: 300px;
|
||
max-width: 500px;
|
||
}
|
||
|
||
.search-input {
|
||
width: 100%;
|
||
padding: 10px 15px;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
font-size: 16px;
|
||
transition: border-color 0.3s;
|
||
}
|
||
|
||
.search-input:focus {
|
||
outline: none;
|
||
border-color: var(--primary);
|
||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||
}
|
||
|
||
.filters {
|
||
display: flex;
|
||
gap: 10px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.filter-select {
|
||
padding: 10px 15px;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
font-size: 14px;
|
||
background-color: white;
|
||
min-width: 150px;
|
||
}
|
||
|
||
.actions {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* Buttons */
|
||
.btn {
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: var(--radius);
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.btn-primary {
|
||
background-color: var(--primary);
|
||
color: white;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background-color: var(--primary-dark);
|
||
}
|
||
|
||
.btn-success {
|
||
background-color: var(--success);
|
||
color: white;
|
||
}
|
||
|
||
.btn-success:hover {
|
||
background-color: #0da271;
|
||
}
|
||
|
||
.btn-danger {
|
||
background-color: var(--danger);
|
||
color: white;
|
||
}
|
||
|
||
.btn-danger:hover {
|
||
background-color: #dc2626;
|
||
}
|
||
|
||
.btn-small {
|
||
padding: 6px 12px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
/* Tables */
|
||
.table-container {
|
||
background-color: white;
|
||
border-radius: var(--radius);
|
||
box-shadow: var(--shadow);
|
||
overflow: hidden;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
th {
|
||
background-color: #f8fafc;
|
||
padding: 15px;
|
||
text-align: left;
|
||
font-weight: 600;
|
||
color: var(--dark);
|
||
border-bottom: 2px solid var(--border);
|
||
}
|
||
|
||
td {
|
||
padding: 15px;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
|
||
tr:hover {
|
||
background-color: #f9fafb;
|
||
}
|
||
|
||
.loading, .error, .no-data {
|
||
text-align: center;
|
||
padding: 40px !important;
|
||
color: var(--secondary);
|
||
}
|
||
|
||
.loading i {
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.error {
|
||
color: var(--danger);
|
||
}
|
||
|
||
/* Badges */
|
||
.badge {
|
||
display: inline-block;
|
||
padding: 4px 10px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
|
||
.badge-sberbank {
|
||
background-color: #048b46;
|
||
color: white;
|
||
}
|
||
|
||
.badge-yandex {
|
||
background-color: #fc3f1d;
|
||
color: white;
|
||
}
|
||
|
||
.badge-ldap {
|
||
background-color: #3b82f6;
|
||
color: white;
|
||
}
|
||
|
||
.badge-other {
|
||
background-color: #6b7280;
|
||
color: white;
|
||
}
|
||
|
||
/* Status */
|
||
.status-active {
|
||
color: var(--success);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.status-inactive {
|
||
color: var(--danger);
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* Metadata Preview */
|
||
.metadata-preview {
|
||
background-color: #f0f9ff;
|
||
border: 1px solid var(--primary-light);
|
||
border-radius: var(--radius);
|
||
padding: 5px 10px;
|
||
font-size: 12px;
|
||
color: var(--primary);
|
||
cursor: pointer;
|
||
transition: background-color 0.3s;
|
||
text-align: center;
|
||
}
|
||
|
||
.metadata-preview:hover {
|
||
background-color: #dbeafe;
|
||
}
|
||
|
||
/* Pagination */
|
||
.pagination {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 20px;
|
||
gap: 5px;
|
||
}
|
||
|
||
.page-btn {
|
||
padding: 8px 14px;
|
||
border: 1px solid var(--border);
|
||
background-color: white;
|
||
border-radius: var(--radius);
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.page-btn:hover:not(:disabled) {
|
||
background-color: #f3f4f6;
|
||
border-color: var(--primary);
|
||
}
|
||
|
||
.page-btn.active {
|
||
background-color: var(--primary);
|
||
color: white;
|
||
border-color: var(--primary);
|
||
}
|
||
|
||
.page-btn:disabled {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
/* Modals */
|
||
.modal {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
z-index: 1000;
|
||
justify-content: center;
|
||
align-items: center;
|
||
animation: fadeIn 0.3s;
|
||
}
|
||
|
||
.modal.active {
|
||
display: flex;
|
||
}
|
||
|
||
.modal-content {
|
||
background-color: white;
|
||
border-radius: var(--radius);
|
||
box-shadow: var(--shadow-lg);
|
||
width: 90%;
|
||
max-width: 800px;
|
||
max-height: 90vh;
|
||
overflow-y: auto;
|
||
animation: slideIn 0.3s;
|
||
}
|
||
|
||
@keyframes slideIn {
|
||
from { opacity: 0; transform: translateY(-50px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.modal-header {
|
||
padding: 20px;
|
||
border-bottom: 1px solid var(--border);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
color: var(--dark);
|
||
}
|
||
|
||
.modal-close {
|
||
background: none;
|
||
border: none;
|
||
font-size: 24px;
|
||
color: var(--secondary);
|
||
cursor: pointer;
|
||
padding: 0;
|
||
width: 30px;
|
||
height: 30px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 50%;
|
||
transition: background-color 0.3s;
|
||
}
|
||
|
||
.modal-close:hover {
|
||
background-color: #f3f4f6;
|
||
}
|
||
|
||
.modal-body {
|
||
padding: 20px;
|
||
}
|
||
|
||
.modal-footer {
|
||
padding: 20px;
|
||
border-top: 1px solid var(--border);
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* Forms */
|
||
.form-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 20px;
|
||
}
|
||
|
||
.form-group {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.form-group label {
|
||
display: block;
|
||
margin-bottom: 8px;
|
||
font-weight: 500;
|
||
color: var(--dark);
|
||
}
|
||
|
||
.form-control {
|
||
width: 100%;
|
||
padding: 10px 15px;
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
font-size: 16px;
|
||
transition: border-color 0.3s;
|
||
}
|
||
|
||
.form-control:focus {
|
||
outline: none;
|
||
border-color: var(--primary);
|
||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||
}
|
||
|
||
textarea.form-control {
|
||
min-height: 100px;
|
||
resize: vertical;
|
||
}
|
||
|
||
.checkbox-group {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.checkbox-group input[type="checkbox"] {
|
||
width: 18px;
|
||
height: 18px;
|
||
}
|
||
|
||
.message {
|
||
padding: 15px;
|
||
border-radius: var(--radius);
|
||
margin-bottom: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.success {
|
||
background-color: #d1fae5;
|
||
color: #065f46;
|
||
border: 1px solid #a7f3d0;
|
||
}
|
||
|
||
.error {
|
||
background-color: #fee2e2;
|
||
color: #991b1b;
|
||
border: 1px solid #fecaca;
|
||
}
|
||
|
||
/* Stats */
|
||
.stats-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 20px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.stat-card {
|
||
background-color: white;
|
||
border-radius: var(--radius);
|
||
padding: 20px;
|
||
box-shadow: var(--shadow);
|
||
text-align: center;
|
||
}
|
||
|
||
.stat-label {
|
||
font-size: 14px;
|
||
color: var(--secondary);
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.stat-value {
|
||
font-size: 32px;
|
||
font-weight: 700;
|
||
color: var(--primary);
|
||
}
|
||
|
||
/* Responsive */
|
||
@media (max-width: 768px) {
|
||
.container {
|
||
padding: 10px;
|
||
}
|
||
|
||
.header {
|
||
flex-direction: column;
|
||
gap: 15px;
|
||
text-align: center;
|
||
}
|
||
|
||
.user-info {
|
||
flex-direction: column;
|
||
text-align: center;
|
||
}
|
||
|
||
.toolbar {
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
}
|
||
|
||
.search-container {
|
||
max-width: 100%;
|
||
}
|
||
|
||
.filters {
|
||
width: 100%;
|
||
}
|
||
|
||
.filter-select {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.actions {
|
||
width: 100%;
|
||
justify-content: center;
|
||
}
|
||
|
||
.table-container {
|
||
overflow-x: auto;
|
||
}
|
||
|
||
table {
|
||
min-width: 800px;
|
||
}
|
||
|
||
.modal-content {
|
||
width: 95%;
|
||
}
|
||
|
||
.form-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<!-- Header -->
|
||
<header class="header">
|
||
<div class="logo">
|
||
<i class="fas fa-users-cog"></i>
|
||
<span>Панель управления</span>
|
||
</div>
|
||
<div class="user-info">
|
||
<div class="user-details">
|
||
<div class="user-name" id="userName">Загрузка...</div>
|
||
<div class="user-role" id="userRole">Роль: загрузка...</div>
|
||
</div>
|
||
<button class="btn-logout" onclick="logout()">
|
||
<i class="fas fa-sign-out-alt"></i>
|
||
Выйти
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Tabs -->
|
||
<div class="tabs">
|
||
<button class="tab active" data-tab="groups">
|
||
<i class="fas fa-layer-group"></i>
|
||
Группы
|
||
</button>
|
||
<button class="tab" data-tab="idusers">
|
||
<i class="fas fa-id-card"></i>
|
||
Идентификаторы
|
||
</button>
|
||
<button class="tab" data-tab="stats">
|
||
<i class="fas fa-chart-bar"></i>
|
||
Статистика
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Tab: Groups -->
|
||
<div id="tab-groups" class="tab-content active">
|
||
<div class="toolbar">
|
||
<div class="search-container">
|
||
<input type="text" id="groupSearch" class="search-input" placeholder="Поиск по названию или описанию...">
|
||
</div>
|
||
<div class="filters">
|
||
<select id="groupServiceTypeFilter" class="filter-select">
|
||
<option value="">Все типы сервисов</option>
|
||
<option value="sberbank">Сбербанк</option>
|
||
<option value="yandex">Яндекс</option>
|
||
<option value="ldap">LDAP</option>
|
||
<option value="other">Прочие</option>
|
||
</select>
|
||
<select id="groupStatusFilter" class="filter-select">
|
||
<option value="">Все статусы</option>
|
||
<option value="true">Активные</option>
|
||
<option value="false">Неактивные</option>
|
||
</select>
|
||
</div>
|
||
<div class="actions">
|
||
<button class="btn btn-success" onclick="showAddGroupModal()">
|
||
<i class="fas fa-plus"></i>
|
||
Добавить группу
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Название</th>
|
||
<th>Тип сервиса</th>
|
||
<th>Описание</th>
|
||
<th>Статус</th>
|
||
<th>Дата создания</th>
|
||
<th>Дата обновления</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="groupsTableBody">
|
||
<tr>
|
||
<td colspan="8" class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
Загрузка групп...
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="pagination" id="groupsPagination"></div>
|
||
</div>
|
||
|
||
<!-- Tab: IdUsers -->
|
||
<div id="tab-idusers" class="tab-content">
|
||
<div class="toolbar">
|
||
<div class="search-container">
|
||
<input type="text" id="iduserSearch" class="search-input" placeholder="Поиск по ID, логину или имени...">
|
||
</div>
|
||
<div class="filters">
|
||
<select id="iduserServiceTypeFilter" class="filter-select">
|
||
<option value="">Все типы сервисов</option>
|
||
<option value="sberbank">Сбербанк</option>
|
||
<option value="yandex">Яндекс</option>
|
||
<option value="ldap">LDAP</option>
|
||
<option value="other">Прочие</option>
|
||
</select>
|
||
<select id="iduserGroupFilter" class="filter-select">
|
||
<option value="">Все группы</option>
|
||
<!-- Динамически заполняется -->
|
||
</select>
|
||
<select id="iduserStatusFilter" class="filter-select">
|
||
<option value="">Все статусы</option>
|
||
<option value="true">Активные</option>
|
||
<option value="false">Неактивные</option>
|
||
</select>
|
||
</div>
|
||
<div class="actions">
|
||
<button class="btn btn-success" onclick="showAddIdUserModal()">
|
||
<i class="fas fa-plus"></i>
|
||
Добавить идентификатор
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Пользователь</th>
|
||
<th>Тип сервиса</th>
|
||
<th>Внешний ID</th>
|
||
<th>Логин</th>
|
||
<th>Группа LDAP</th>
|
||
<th>Группа</th>
|
||
<th>Метаданные</th>
|
||
<th>Статус</th>
|
||
<th>Дата создания</th>
|
||
<th>Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="idusersTableBody">
|
||
<tr>
|
||
<td colspan="11" class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
Загрузка идентификаторов...
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="pagination" id="idusersPagination"></div>
|
||
</div>
|
||
|
||
<!-- Tab: Stats -->
|
||
<div id="tab-stats" class="tab-content">
|
||
<div class="stats-grid" id="statsGrid">
|
||
<div class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
Загрузка статистики...
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Тип сервиса</th>
|
||
<th>Всего идентификаторов</th>
|
||
<th>Активных</th>
|
||
<th>Уникальных пользователей</th>
|
||
<th>Доля</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="statsTableBody">
|
||
<tr>
|
||
<td colspan="5" class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
Загрузка данных...
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal: Add/Edit Group -->
|
||
<div id="groupModal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3 class="modal-title" id="groupModalTitle">Добавить группу</h3>
|
||
<button class="modal-close" onclick="closeGroupModal()">×</button>
|
||
</div>
|
||
<form id="groupForm" onsubmit="saveGroup(event)">
|
||
<div class="modal-body">
|
||
<div id="groupMessage"></div>
|
||
<input type="hidden" id="groupId" value="">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label for="groupName">Название группы *</label>
|
||
<input type="text" id="groupName" class="form-control" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="groupServiceType">Тип сервиса *</label>
|
||
<select id="groupServiceType" class="form-control" required>
|
||
<option value="sberbank">Сбербанк</option>
|
||
<option value="yandex">Яндекс</option>
|
||
<option value="ldap">LDAP</option>
|
||
<option value="other">Прочие</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="groupDescription">Описание</label>
|
||
<textarea id="groupDescription" class="form-control" rows="3"></textarea>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="groupIsActive" class="checkbox-group">
|
||
<input type="checkbox" id="groupIsActive" checked>
|
||
Активная группа
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn" onclick="closeGroupModal()">Отмена</button>
|
||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal: Add/Edit IdUser -->
|
||
<div id="iduserModal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3 class="modal-title" id="iduserModalTitle">Добавить идентификатор</h3>
|
||
<button class="modal-close" onclick="closeIdUserModal()">×</button>
|
||
</div>
|
||
<form id="iduserForm" onsubmit="saveIdUser(event)">
|
||
<div class="modal-body">
|
||
<div id="iduserMessage"></div>
|
||
<input type="hidden" id="iduserId" value="">
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label for="iduserUserId">Пользователь *</label>
|
||
<select id="iduserUserId" class="form-control" required>
|
||
<option value="">Выберите пользователя</option>
|
||
<!-- Динамически заполняется -->
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="iduserServiceType">Тип сервиса *</label>
|
||
<select id="iduserServiceType" class="form-control" required>
|
||
<option value="ldap" selected>LDAP</option>
|
||
<option value="sberbank">Сбербанк</option>
|
||
<option value="yandex">Яндекс</option>
|
||
<option value="other">Прочие</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="iduserExternalId">Внешний ID (необязательный)</label>
|
||
<input type="text" id="iduserExternalId" class="form-control" placeholder="Внешний идентификатор (необязательно)">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="iduserLogin">Логин</label>
|
||
<input type="text" id="iduserLogin" class="form-control" placeholder="Логин пользователя">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="iduserLdapGroup">Группа LDAP</label>
|
||
<input type="text" id="iduserLdapGroup" class="form-control" placeholder="Группа LDAP">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="iduserGroupId">Группа идентификаторов</label>
|
||
<select id="iduserGroupId" class="form-control">
|
||
<option value="">Без группы</option>
|
||
<!-- Динамически заполняется -->
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="iduserIsActive" class="checkbox-group">
|
||
<input type="checkbox" id="iduserIsActive" checked>
|
||
Активный идентификатор
|
||
</label>
|
||
</div>
|
||
<div class="form-group" style="grid-column: span 2;">
|
||
<label for="iduserMetadata">Метаданные (JSON)</label>
|
||
<textarea id="iduserMetadata" class="form-control" rows="6" placeholder='{"ключ": "значение"}'></textarea>
|
||
<small style="color: var(--secondary); margin-top: 5px; display: block;">
|
||
Дополнительные данные в формате JSON (необязательно)
|
||
</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn" onclick="closeIdUserModal()">Отмена</button>
|
||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal: Confirm Delete -->
|
||
<div id="confirmModal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3 class="modal-title" id="confirmModalTitle">Подтверждение удаления</h3>
|
||
<button class="modal-close" onclick="closeConfirmModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p id="confirmMessage">Вы уверены, что хотите удалить этот элемент?</p>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn" onclick="closeConfirmModal()">Отмена</button>
|
||
<button type="button" class="btn btn-danger" onclick="confirmDelete()">Удалить</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal: View Metadata -->
|
||
<div id="metadataModal" class="modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3 class="modal-title">Метаданные</h3>
|
||
<button class="modal-close" onclick="closeMetadataModal()">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<pre id="metadataContent" style="background: #f8fafc; padding: 15px; border-radius: var(--radius); overflow: auto; max-height: 500px; font-family: monospace;"></pre>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn" onclick="closeMetadataModal()">Закрыть</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="doc.js"></script>
|
||
<script src="doc-getUserGroups.js"></script>
|
||
</body>
|
||
</html> |