fix #557: guide permission-driven VPD flow
This commit is contained in:
@@ -357,6 +357,28 @@ function renderMaskableColumnOptions(option) {
|
||||
current.push(column);
|
||||
}
|
||||
input.value = current.join(', ');
|
||||
renderSelectedVisibleColumns();
|
||||
updatePermissionWizardPreview(document);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderSelectedVisibleColumns() {
|
||||
const input = document.querySelector('input[name="visibleColumns"]');
|
||||
const list = document.querySelector('[data-selected-visible-columns]');
|
||||
if (!input || !list) {
|
||||
return;
|
||||
}
|
||||
const columns = input.value.split(',').map((value) => value.trim().toUpperCase()).filter(Boolean);
|
||||
list.innerHTML = columns.map((column) => (
|
||||
`<button type="button" class="badge text-bg-secondary border-0 me-1 mb-1" data-remove-visible-column="${column}">`
|
||||
+ `${escapeHtml(column)} ×</button>`
|
||||
)).join('');
|
||||
list.querySelectorAll('[data-remove-visible-column]').forEach((button) => {
|
||||
button.addEventListener('click', () => {
|
||||
const remove = button.dataset.removeVisibleColumn;
|
||||
input.value = columns.filter((column) => column !== remove).join(', ');
|
||||
renderSelectedVisibleColumns();
|
||||
updatePermissionWizardPreview(document);
|
||||
});
|
||||
});
|
||||
@@ -372,14 +394,15 @@ function syncRuleTypeHints(root = document) {
|
||||
}
|
||||
|
||||
const type = typeSelect.value;
|
||||
const valueRequired = ['=', '!=', 'DEPT', 'EMP_NO'].includes(type);
|
||||
const columnOptional = ['ALL', 'MY_DEPT', 'SELF', 'DEPT', 'EMP_NO'].includes(type);
|
||||
const valueRequired = ['=', '!=', 'DEPT', 'EMP_NO', 'TAG'].includes(type);
|
||||
const columnOptional = ['ALL', 'MY_DEPT', 'SELF', 'DEPT', 'EMP_NO', 'TAG'].includes(type);
|
||||
const placeholderByType = {
|
||||
ALL: '값 불필요',
|
||||
MY_DEPT: '값 불필요',
|
||||
SELF: '값 불필요',
|
||||
DEPT: '예: HR',
|
||||
EMP_NO: '예: E2001',
|
||||
TAG: '예: SPRING_BOOT',
|
||||
'=': '비교 값',
|
||||
'!=': '비교 값'
|
||||
};
|
||||
@@ -441,7 +464,59 @@ async function syncObjectCatalogSelection() {
|
||||
const owner = (selected.dataset.owner || '').toLowerCase();
|
||||
const objectName = (selected.dataset.objectName || '').toLowerCase();
|
||||
ordsPathInput.value = owner && objectName ? `cb-ords/cb-object-query/${owner}/${objectName}` : '';
|
||||
ordsPathInput.readOnly = true;
|
||||
}
|
||||
const ordsPathEdit = document.querySelector('[data-ords-path-edit]');
|
||||
if (ordsPathEdit) {
|
||||
ordsPathEdit.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
function initOrdsPathEditToggle() {
|
||||
const toggle = document.querySelector('[data-ords-path-edit]');
|
||||
const input = document.querySelector('[data-ords-path-input]');
|
||||
if (!toggle || !input) {
|
||||
return;
|
||||
}
|
||||
toggle.addEventListener('change', () => {
|
||||
input.readOnly = !toggle.checked;
|
||||
if (toggle.checked) {
|
||||
input.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initProbeObjectDescription() {
|
||||
const select = document.querySelector('select[name="objectId"]');
|
||||
const target = document.querySelector('[data-probe-object-description]');
|
||||
if (!select || !target) {
|
||||
return;
|
||||
}
|
||||
const update = () => {
|
||||
const option = selectedOption(select);
|
||||
target.textContent = option?.dataset.description
|
||||
|| '선택한 대상의 설명이 등록되지 않았습니다. ORDS 조회 대상에서 설명을 추가하세요.';
|
||||
};
|
||||
select.addEventListener('change', update);
|
||||
update();
|
||||
}
|
||||
|
||||
function initProbeVectorInput() {
|
||||
const select = document.querySelector('select[name="objectId"]');
|
||||
const block = document.querySelector('[data-vector-probe-input]');
|
||||
const input = block?.querySelector('textarea[name="requestBody"]');
|
||||
if (!select || !block || !input) {
|
||||
return;
|
||||
}
|
||||
const update = () => {
|
||||
const option = selectedOption(select);
|
||||
const isVectorSearch = option?.dataset.vectorSearch === 'true';
|
||||
block.hidden = !isVectorSearch;
|
||||
input.disabled = !isVectorSearch;
|
||||
input.required = isVectorSearch;
|
||||
};
|
||||
select.addEventListener('change', update);
|
||||
update();
|
||||
}
|
||||
|
||||
function selectedText(select) {
|
||||
@@ -570,6 +645,7 @@ function collectWizardRules(root) {
|
||||
SELF: 'OWNER_EMP_NO',
|
||||
DEPT: 'DEPT_CODE',
|
||||
EMP_NO: 'OWNER_EMP_NO',
|
||||
TAG: 'TECH_TAG',
|
||||
ALL: ''
|
||||
}[type] || '';
|
||||
if (type === 'ALL') {
|
||||
@@ -578,6 +654,9 @@ function collectWizardRules(root) {
|
||||
if (['MY_DEPT', 'SELF'].includes(type)) {
|
||||
return `${displayColumn} ${type}`;
|
||||
}
|
||||
if (type === 'TAG') {
|
||||
return `${displayColumn} TAG ${value.toUpperCase()}`;
|
||||
}
|
||||
return [displayColumn, type, value].filter(Boolean).join(' ');
|
||||
}).filter(Boolean);
|
||||
}
|
||||
@@ -592,6 +671,7 @@ function collectWizardPredicates(root) {
|
||||
SELF: 'OWNER_EMP_NO',
|
||||
DEPT: 'DEPT_CODE',
|
||||
EMP_NO: 'OWNER_EMP_NO',
|
||||
TAG: 'TECH_TAG',
|
||||
ALL: ''
|
||||
}[type] || '';
|
||||
if (type === 'ALL') {
|
||||
@@ -606,6 +686,9 @@ function collectWizardPredicates(root) {
|
||||
if (type === 'DEPT' || type === 'EMP_NO') {
|
||||
return `${displayColumn} = ${sqlLiteral(value)}`;
|
||||
}
|
||||
if (type === 'TAG') {
|
||||
return `REGEXP_LIKE(UPPER(${displayColumn}), ${sqlLiteral(`(^|,)${value.toUpperCase()}(,|$)`)})`;
|
||||
}
|
||||
if (type === '=') {
|
||||
return `TO_CHAR(${displayColumn}) = ${sqlLiteral(value)}`;
|
||||
}
|
||||
@@ -880,10 +963,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
});
|
||||
syncRuleTypeHints();
|
||||
document.querySelector('input[name="visibleColumns"]')?.addEventListener('input', renderSelectedVisibleColumns);
|
||||
renderSelectedVisibleColumns();
|
||||
const catalog = document.getElementById('objectCatalogSelect');
|
||||
if (catalog) {
|
||||
catalog.addEventListener('change', syncObjectCatalogSelection);
|
||||
syncObjectCatalogSelection();
|
||||
}
|
||||
initOrdsPathEditToggle();
|
||||
initProbeObjectDescription();
|
||||
initProbeVectorInput();
|
||||
document.querySelectorAll('[data-policy-template-select]').forEach((select) => {
|
||||
select.addEventListener('change', () => syncPolicyTemplate(select));
|
||||
syncPolicyTemplate(select);
|
||||
|
||||
Reference in New Issue
Block a user