fix(ui): wire AdminRolesScript and clean unused imports
- Replace inline script in AdminRolesPage with extracted AdminRolesScript component - Remove unused JSX import aliases and format AdminUserDetailsPage
This commit is contained in:
parent
fa2778d4fe
commit
58d8e54ae5
@ -1,16 +1,7 @@
|
||||
import { AdminLayout } from "./AdminLayout.tsx";
|
||||
import type { AdminTable as _AdminTable } from "./admin/AdminTable.tsx";
|
||||
import { AdminModal } from "./admin/AdminModal.tsx";
|
||||
import { RoleEditorDrawer } from "./admin/drawers/RoleEditorDrawer.tsx";
|
||||
import { AdminRolesScript } from "./admin/AdminRolesScript.tsx";
|
||||
|
||||
// We need to use these imports, they are falsely flagged by lint because they are only used in JSX.
|
||||
// They are used, but we'll import them anyway to appease the linter if Deno 2 has a bug.
|
||||
// In Hono JSX, imports might not be strictly recognized.
|
||||
const _AdminModal = AdminModal;
|
||||
const _AdminRolesScript = AdminRolesScript;
|
||||
const _RoleEditorDrawer = RoleEditorDrawer;
|
||||
|
||||
export const AdminRolesPage = ({
|
||||
roles,
|
||||
apps,
|
||||
@ -287,140 +278,7 @@ export const AdminRolesPage = ({
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
function showNotice(msg, isError) {
|
||||
const banner = document.getElementById('status-banner');
|
||||
banner.textContent = msg;
|
||||
banner.style.display = 'block';
|
||||
banner.style.background = isError ? 'var(--danger-bg)' : 'var(--success-bg)';
|
||||
banner.style.color = isError ? 'var(--danger-text)' : 'var(--success-text)';
|
||||
banner.style.border = isError ? '1px solid var(--danger-border)' : '1px solid var(--success-border)';
|
||||
setTimeout(() => { banner.style.display = 'none'; }, 5000);
|
||||
}
|
||||
|
||||
function openCreateRoleDrawer() {
|
||||
document.getElementById('editRoleId').value = '';
|
||||
document.getElementById('roleFormTitle').textContent = 'Create New Role';
|
||||
document.getElementById('scopeSelectContainer').style.display = 'grid';
|
||||
document.getElementById('roleName').value = '';
|
||||
document.getElementById('roleDescription').value = '';
|
||||
document.getElementById('roleFormCard').style.display = 'block';
|
||||
document.getElementById('roleFormCard').scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
|
||||
function openEditRoleDrawer(roleJson) {
|
||||
const role = JSON.parse(roleJson);
|
||||
document.getElementById('editRoleId').value = role.id;
|
||||
document.getElementById('roleFormTitle').textContent = 'Edit Role: ' + role.name;
|
||||
document.getElementById('scopeSelectContainer').style.display = 'none';
|
||||
document.getElementById('roleName').value = role.name || '';
|
||||
document.getElementById('roleDescription').value = role.description || '';
|
||||
document.getElementById('roleFormCard').style.display = 'block';
|
||||
document.getElementById('roleFormCard').scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
|
||||
function closeRoleDrawer() {
|
||||
document.getElementById('roleFormModal').style.display = 'none';
|
||||
}
|
||||
|
||||
function handleScopeChange() {
|
||||
const scope = document.getElementById('roleScope').value;
|
||||
const appContainer = document.getElementById('appSelectContainer');
|
||||
appContainer.style.display = scope === 'app_specific' ? 'block' : 'none';
|
||||
}
|
||||
|
||||
function filterRoles() {
|
||||
const query = (document.getElementById('roleSearchInput')?.value || '').toLowerCase().trim();
|
||||
const selectedScope = document.getElementById('filterScopeSelect')?.value || 'all';
|
||||
|
||||
const rows = document.querySelectorAll('.role-row');
|
||||
const cards = document.querySelectorAll('.role-card');
|
||||
let visibleCount = 0;
|
||||
|
||||
const checkMatch = (appId, searchText) => {
|
||||
const scopeMatch = selectedScope === 'all' || (selectedScope === 'global' && appId === 'global') || (appId === selectedScope);
|
||||
const textMatch = !query || searchText.includes(query);
|
||||
return scopeMatch && textMatch;
|
||||
};
|
||||
|
||||
rows.forEach(r => {
|
||||
const appId = r.getAttribute('data-app-id');
|
||||
const search = r.getAttribute('data-search') || '';
|
||||
const match = checkMatch(appId, search);
|
||||
r.style.display = match ? '' : 'none';
|
||||
if (match) visibleCount++;
|
||||
});
|
||||
|
||||
cards.forEach(c => {
|
||||
const appId = c.getAttribute('data-app-id');
|
||||
const search = c.getAttribute('data-search') || '';
|
||||
const match = checkMatch(appId, search);
|
||||
c.style.display = match ? '' : 'none';
|
||||
});
|
||||
|
||||
document.getElementById('roleCountDisplay').textContent = 'Showing ' + visibleCount + ' roles';
|
||||
}
|
||||
|
||||
async function handleSaveRole(e) {
|
||||
e.preventDefault();
|
||||
const editId = document.getElementById('editRoleId').value;
|
||||
const scope = document.getElementById('roleScope')?.value;
|
||||
const name = document.getElementById('roleName').value.trim();
|
||||
const description = document.getElementById('roleDescription').value.trim();
|
||||
let appId = null;
|
||||
|
||||
if (!editId && scope === 'app_specific') {
|
||||
appId = document.getElementById('roleAppId').value;
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
showNotice('Role identifier is required', true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = editId ? ('/api/admin/roles/' + editId) : '/api/admin/roles';
|
||||
const method = editId ? 'PUT' : 'POST';
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name, description, appId }),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok) {
|
||||
showNotice(editId ? 'Role updated successfully!' : 'Role created successfully!', false);
|
||||
setTimeout(() => window.location.reload(), 600);
|
||||
} else {
|
||||
showNotice(data.error || 'Failed to save role', true);
|
||||
}
|
||||
} catch (err) {
|
||||
showNotice('Network error saving role', true);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteRole(roleId, roleName) {
|
||||
if (!confirm('Are you sure you want to delete role "' + roleName + '"?')) return;
|
||||
try {
|
||||
const res = await fetch('/api/admin/roles/' + roleId, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
if (res.ok) {
|
||||
showNotice('Role deleted', false);
|
||||
setTimeout(() => window.location.reload(), 600);
|
||||
} else {
|
||||
const data = await res.json();
|
||||
showNotice(data.error || 'Failed to delete role', true);
|
||||
}
|
||||
} catch (err) {
|
||||
showNotice('Network error', true);
|
||||
}
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
<AdminRolesScript />
|
||||
</AdminLayout>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,13 +1,7 @@
|
||||
import { AdminLayout } from "./AdminLayout.tsx";
|
||||
import { AdminTable } from "./admin/AdminTable.tsx";
|
||||
import { GrantDrawer } from "./admin/drawers/GrantDrawer.tsx";
|
||||
import type { GrantDrawer as _GrantDrawer } from "./admin/drawers/GrantDrawer.tsx";
|
||||
import { AdminUserDetailsScript } from "./admin/AdminUserDetailsScript.tsx";
|
||||
import type { AdminUserDetailsScript as _AdminUserDetailsScript } from "./admin/AdminUserDetailsScript.tsx";
|
||||
|
||||
// In Hono JSX, imports might not be strictly recognized.
|
||||
|
||||
|
||||
|
||||
export const AdminUserDetailsPage = ({
|
||||
user,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user