ваше сообщение коммита
This commit is contained in:
@@ -65,7 +65,7 @@
|
||||
</template>
|
||||
<template v-else-if="column.type === 'multiselect-relation'">
|
||||
<div v-if="!editing" @click="editing = true" class="tags-cell-view">
|
||||
<span v-if="selectedMultiRelationNames.length">{{ selectedMultiRelationNames.map(prettyDisplay).join(', ') }}</span>
|
||||
<span v-if="selectedMultiRelationNames.length">{{ selectedMultiRelationNames.join(', ') }}</span>
|
||||
<span v-else class="cell-plus-icon" title="Добавить">
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none">
|
||||
<circle cx="9" cy="9" r="8" fill="#f3f4f6" stroke="#b6c6e6"/>
|
||||
@@ -78,7 +78,7 @@
|
||||
<div class="tags-multiselect">
|
||||
<div v-for="option in multiRelationOptions" :key="option.id" class="tag-option">
|
||||
<input type="checkbox" :id="'cell-multirel-' + option.id + '-' + rowId" :value="String(option.id)" v-model="editMultiRelationValues" />
|
||||
<label :for="'cell-multirel-' + option.id + '-' + rowId">{{ prettyDisplay(option.display, multiRelationOptions.value) }}</label>
|
||||
<label :for="'cell-multirel-' + option.id + '-' + rowId">{{ option.display }}</label>
|
||||
<button class="delete-tag-btn" @click.prevent="deleteTag(option.id)" title="Удалить тег">×</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -500,44 +500,55 @@ async function loadMultiRelationOptions() {
|
||||
}
|
||||
|
||||
const rel = props.column.options || {};
|
||||
if (rel.relatedTableId && rel.relatedColumnId) {
|
||||
try {
|
||||
// Проверяем кэш для данных таблицы
|
||||
const cachedTableData = cacheService.getTableData(rel.relatedTableId, 'default');
|
||||
let tableData;
|
||||
|
||||
if (cachedTableData) {
|
||||
// console.log(`[loadMultiRelationOptions] ✅ Используем предварительно загруженные данные таблицы ${rel.relatedTableId}`);
|
||||
tableData = cachedTableData;
|
||||
} else {
|
||||
// console.log(`[loadMultiRelationOptions] ⚠️ Данные таблицы ${rel.relatedTableId} не найдены в кэше, загружаем заново`);
|
||||
const response = await fetch(`/api/tables/${rel.relatedTableId}`);
|
||||
tableData = await response.json();
|
||||
// Сохраняем в кэш
|
||||
cacheService.setTableData(rel.relatedTableId, 'default', tableData);
|
||||
}
|
||||
|
||||
// Формируем опции из данных таблицы
|
||||
const colId = rel.relatedColumnId || (tableData.columns[0] && tableData.columns[0].id);
|
||||
const opts = [];
|
||||
for (const row of tableData.rows) {
|
||||
const cell = tableData.cellValues.find(c => c.row_id === row.id && c.column_id === colId);
|
||||
opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
|
||||
}
|
||||
multiRelationOptions.value = opts;
|
||||
lastLoadedOptionsKey = cacheKey;
|
||||
|
||||
// Обновляем selectedMultiRelationNames на основе текущих значений
|
||||
if (editMultiRelationValues.value.length > 0) {
|
||||
selectedMultiRelationNames.value = opts
|
||||
.filter(opt => editMultiRelationValues.value.includes(String(opt.id)))
|
||||
.map(opt => opt.display);
|
||||
} else {
|
||||
selectedMultiRelationNames.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
// console.error('[loadMultiRelationOptions] Error:', e);
|
||||
|
||||
// Проверяем, что options содержат необходимые данные
|
||||
if (!rel.relatedTableId || !rel.relatedColumnId) {
|
||||
console.warn('[loadMultiRelationOptions] Отсутствуют relatedTableId или relatedColumnId в options:', rel);
|
||||
multiRelationOptions.value = [];
|
||||
selectedMultiRelationNames.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Проверяем кэш для данных таблицы
|
||||
const cachedTableData = cacheService.getTableData(rel.relatedTableId, 'default');
|
||||
let tableData;
|
||||
|
||||
if (cachedTableData) {
|
||||
console.log(`[loadMultiRelationOptions] ✅ Используем предварительно загруженные данные таблицы ${rel.relatedTableId}`);
|
||||
tableData = cachedTableData;
|
||||
} else {
|
||||
console.log(`[loadMultiRelationOptions] ⚠️ Данные таблицы ${rel.relatedTableId} не найдены в кэше, загружаем заново`);
|
||||
const response = await fetch(`/api/tables/${rel.relatedTableId}`);
|
||||
tableData = await response.json();
|
||||
// Сохраняем в кэш
|
||||
cacheService.setTableData(rel.relatedTableId, 'default', tableData);
|
||||
}
|
||||
|
||||
// Формируем опции из данных таблицы
|
||||
const colId = rel.relatedColumnId || (tableData.columns[0] && tableData.columns[0].id);
|
||||
const opts = [];
|
||||
for (const row of tableData.rows) {
|
||||
const cell = tableData.cellValues.find(c => c.row_id === row.id && c.column_id === colId);
|
||||
opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
|
||||
}
|
||||
multiRelationOptions.value = opts;
|
||||
lastLoadedOptionsKey = cacheKey;
|
||||
|
||||
console.log('[loadMultiRelationOptions] Загружено опций:', opts.length);
|
||||
|
||||
// Обновляем selectedMultiRelationNames на основе текущих значений
|
||||
if (editMultiRelationValues.value.length > 0) {
|
||||
selectedMultiRelationNames.value = opts
|
||||
.filter(opt => editMultiRelationValues.value.includes(String(opt.id)))
|
||||
.map(opt => opt.display);
|
||||
} else {
|
||||
selectedMultiRelationNames.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[loadMultiRelationOptions] Error:', e);
|
||||
multiRelationOptions.value = [];
|
||||
selectedMultiRelationNames.value = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
<input id="dbPort" v-model.number="form.dbPort" type="number" required />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dbName">Database</label>
|
||||
<input id="dbName" v-model="form.dbName" type="text" required />
|
||||
<label class="info-label">
|
||||
<i class="info-icon">ℹ️</i>
|
||||
Database name: <strong>{{ form.dbName }}</strong> (неизменяемо)
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="dbUser">User</label>
|
||||
@@ -43,7 +45,7 @@
|
||||
<div v-else class="settings-view">
|
||||
<div class="view-row"><span>Host:</span> <b>{{ form.dbHost }}</b></div>
|
||||
<div class="view-row"><span>Port:</span> <b>{{ form.dbPort }}</b></div>
|
||||
<div class="view-row"><span>Database:</span> <b>{{ form.dbName }}</b></div>
|
||||
<div class="view-row"><span>Database:</span> <b>{{ form.dbName }}</b> <span class="readonly-badge">(неизменяемо)</span></div>
|
||||
<div class="view-row"><span>User:</span> <b>{{ form.dbUser }}</b></div>
|
||||
<div class="view-row"><span>Password:</span> <b>••••••••••••••••••••••••••••••••</b></div>
|
||||
<button type="button" class="edit-btn" @click="editMode = true">Изменить</button>
|
||||
@@ -97,12 +99,13 @@ onMounted(async () => {
|
||||
|
||||
const saveDbSettings = async () => {
|
||||
try {
|
||||
// Отправляем только безопасные для изменения поля
|
||||
await api.put('/settings/db-settings', {
|
||||
db_host: form.dbHost,
|
||||
db_port: form.dbPort,
|
||||
db_name: form.dbName,
|
||||
db_user: form.dbUser,
|
||||
db_password: form.dbPassword || undefined
|
||||
// db_name не отправляем - он неизменяем
|
||||
});
|
||||
alert('Настройки базы данных сохранены');
|
||||
form.dbPassword = '';
|
||||
@@ -219,4 +222,32 @@ h2 {
|
||||
.edit-btn:hover {
|
||||
background: var(--color-primary-dark);
|
||||
}
|
||||
.empty-placeholder {
|
||||
color: #888;
|
||||
font-size: 1em;
|
||||
margin: 0.7em 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 6px;
|
||||
padding: 0.75rem;
|
||||
color: #495057;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.info-icon {
|
||||
margin-right: 0.5rem;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.readonly-badge {
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
font-size: 0.8em;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user