admin appPermissions
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-07-09 09:06:55 +09:00
parent ecbf57d978
commit fd590540bc
4 changed files with 64 additions and 47 deletions
+26 -13
View File
@@ -4,16 +4,18 @@ import { DataTableCard, type DataTableColumn, type DataTableFilter } from '../..
import { useToast } from '../../components/toast';
import { Button, Modal } from '../../components/ui';
import { PageTitle } from '../../layout/AppLayout';
import { getAdminAppPermissions, isOwnerAdmin, setAdminAppPermissions } from '../../lib/admin-app-permissions';
import { isOwnerAdmin, setAdminAppPermissions } from '../../lib/admin-app-permissions';
import { listApps } from '../applications/application-api';
import type { AppWithComponents } from '../../types/application';
import {
createAdmin,
createAdminSshKey,
deleteAdminSshKey,
loadAdminAppPermissions,
loadAdminRoles,
loadAdmins,
resetAdminPassword,
updateAdminAppPermissions,
updateAdminRole,
updateAdminStatus,
type AdminAccount,
@@ -68,6 +70,7 @@ export function AdminManagementPage() {
});
const [permissionApps, setPermissionApps] = useState<AppWithComponents[]>([]);
const [permissionLoading, setPermissionLoading] = useState(false);
const [permissionSaving, setPermissionSaving] = useState(false);
const loadingVisible = useMinimumLoading(loading);
const refresh = () => {
@@ -123,14 +126,15 @@ export function AdminManagementPage() {
const openPermissionModal = (admin: AdminAccount) => {
setMenuAdmin(null);
setPermissionTarget({ admin, appIds: isOwnerAdmin(admin) ? [] : getAdminAppPermissions(admin) });
setPermissionTarget({ admin, appIds: [] });
setPermissionLoading(true);
listApps()
.then((apps) => {
Promise.all([
listApps(),
isOwnerAdmin(admin) ? Promise.resolve<string[]>([]) : loadAdminAppPermissions(admin.id)
])
.then(([apps, appIds]) => {
setPermissionApps(apps);
if (isOwnerAdmin(admin)) {
setPermissionTarget({ admin, appIds: apps.map((app) => app.id) });
}
setPermissionTarget({ admin, appIds: isOwnerAdmin(admin) ? apps.map((app) => app.id) : appIds });
})
.catch(() => {
setPermissionApps([]);
@@ -152,9 +156,18 @@ export function AdminManagementPage() {
return;
}
setAdminAppPermissions(permissionTarget.admin, permissionTarget.appIds);
setPermissionTarget({ admin: null, appIds: [] });
toast({ type: 'success', title: '앱 권한 저장', message: '관리자 앱 권한이 저장되었습니다.' });
setPermissionSaving(true);
updateAdminAppPermissions(permissionTarget.admin.id, permissionTarget.appIds)
.then((result) => {
setAdminAppPermissions(permissionTarget.admin as AdminAccount, result.appIds ?? permissionTarget.appIds);
setPermissionTarget({ admin: null, appIds: [] });
toast({ type: 'success', title: '앱 권한 저장', message: '관리자 앱 권한이 저장되었습니다.' });
refresh();
})
.catch((error) => {
toast({ type: 'error', title: '앱 권한 저장 실패', message: error instanceof Error ? error.message : '관리자 앱 권한 저장에 실패했습니다.' });
})
.finally(() => setPermissionSaving(false));
};
const submitAdmin = () => {
@@ -486,9 +499,9 @@ export function AdminManagementPage() {
className="max-w-2xl"
footer={
<>
<Button variant="outline" onClick={() => setPermissionTarget({ admin: null, appIds: [] })}>취소</Button>
<Button onClick={saveAppPermissions} disabled={permissionLoading || isOwnerAdmin(permissionTarget.admin)}>
저장
<Button variant="outline" onClick={() => setPermissionTarget({ admin: null, appIds: [] })} disabled={permissionSaving}>취소</Button>
<Button onClick={saveAppPermissions} disabled={permissionLoading || permissionSaving || isOwnerAdmin(permissionTarget.admin)}>
{permissionSaving ? '저장 중' : '저장'}
</Button>
</>
}