amalia/25-nov-25 #36
@@ -16,112 +16,148 @@ export default function PermissionTree({
|
|||||||
selected: string[];
|
selected: string[];
|
||||||
onChange: (val: string[]) => void;
|
onChange: (val: string[]) => void;
|
||||||
}) {
|
}) {
|
||||||
const [open, setOpen] = useState<Record<string, boolean>>({});
|
// Ambil semua child dari node
|
||||||
|
const [openNodes, setOpenNodes] = useState<Record<string, boolean>>({});
|
||||||
|
|
||||||
const toggle = (key: string) => {
|
function toggleNode(label: string) {
|
||||||
setOpen((prev) => ({ ...prev, [key]: !prev[key] }));
|
setOpenNodes(prev => ({ ...prev, [label]: !prev[label] }));
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function getAllChildKeys(node: Node): string[] {
|
||||||
|
let result: string[] = [];
|
||||||
// Ambil semua key dari node termasuk semua keturunannya
|
if (node.children) {
|
||||||
const collectKeys = (n: Node): string[] => {
|
node.children.forEach((c) => {
|
||||||
if (!n.children) return [n.key];
|
result.push(c.key);
|
||||||
return [n.key, ...n.children.flatMap(collectKeys)];
|
result = [...result, ...getAllChildKeys(c)];
|
||||||
};
|
});
|
||||||
|
|
||||||
const checkState = (node: Node): { all: boolean; some: boolean } => {
|
|
||||||
const children = node.children || [];
|
|
||||||
// Jika tidak ada anak → nilai hanya berdasarkan dirinya sendiri
|
|
||||||
if (children.length === 0) {
|
|
||||||
const checked = selected.includes(node.key);
|
|
||||||
return { all: checked, some: checked };
|
|
||||||
}
|
}
|
||||||
// Rekursif ke anak
|
return result;
|
||||||
let all = selected.includes(node.key);
|
}
|
||||||
let some = selected.includes(node.key);
|
|
||||||
for (const c of children) {
|
// Dapatkan parentKey, jika ada
|
||||||
const childState = checkState(c);
|
function getParentKey(key: string) {
|
||||||
if (!childState.all) all = false;
|
const split = key.split(".");
|
||||||
if (childState.some) some = true;
|
if (split.length <= 1) return null;
|
||||||
|
split.pop();
|
||||||
|
return split.join(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update parent ke atas secara rekursif
|
||||||
|
function updateParent(next: string[], parentKey: string | null): string[] {
|
||||||
|
if (!parentKey) return next;
|
||||||
|
|
||||||
|
const allChildKeys = findAllChildKeysFromKey(parentKey);
|
||||||
|
|
||||||
|
const selectedChild = allChildKeys.filter((c) => next.includes(c));
|
||||||
|
|
||||||
|
if (selectedChild.length === 0) {
|
||||||
|
// Semua child uncheck → parent uncheck
|
||||||
|
next = next.filter((x) => x !== parentKey);
|
||||||
|
} else if (selectedChild.length === allChildKeys.length) {
|
||||||
|
// Semua child check → parent check
|
||||||
|
if (!next.includes(parentKey)) {
|
||||||
|
next.push(parentKey);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Sebagian child check → parent intermediate (checked = true, rendered sebagai indeterminate)
|
||||||
|
if (!next.includes(parentKey)) {
|
||||||
|
next.push(parentKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return { all, some };
|
|
||||||
};
|
|
||||||
|
|
||||||
// Untuk ordering sesuai urutan JSON
|
// Rekursif naik ke atas
|
||||||
const getOrderedKeys = (nodes: Node[]): string[] =>
|
return updateParent(next, getParentKey(parentKey));
|
||||||
nodes.flatMap((n) => [n.key, ...getOrderedKeys(n.children || [])]);
|
}
|
||||||
|
|
||||||
|
// dapatkan child dari string key
|
||||||
|
function findAllChildKeysFromKey(parentKey: string) {
|
||||||
|
const list: string[] = [];
|
||||||
|
|
||||||
const RenderNode = ({ node }: { node: Node }) => {
|
function traverse(nodes: Node[]) {
|
||||||
const children = node.children || [];
|
nodes.forEach((n) => {
|
||||||
|
if (n.key.startsWith(parentKey + ".") && n.key !== parentKey) {
|
||||||
|
list.push(n.key);
|
||||||
|
}
|
||||||
|
if (n.children) traverse(n.children);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const state = checkState(node); // ← gunakan recursive evaluator
|
traverse(permissionConfig.menus);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
const isChecked = state.all;
|
const RenderMenu = ({ menu }: { menu: Node }) => {
|
||||||
const isIndeterminate = !state.all && state.some;
|
const hasChild = menu.children && menu.children.length > 0;
|
||||||
|
const open = openNodes[menu.label] ?? false;
|
||||||
|
const childKeys = getAllChildKeys(menu);
|
||||||
|
const isChecked = selected.includes(menu.key);
|
||||||
|
const isIndeterminate =
|
||||||
|
!isChecked &&
|
||||||
|
selected.some(
|
||||||
|
(x) =>
|
||||||
|
typeof x === "string" &&
|
||||||
|
x.startsWith(menu.key + ".")
|
||||||
|
);
|
||||||
|
|
||||||
const showChildren = open[node.key] ?? false;
|
function handleCheck() {
|
||||||
|
let next = [...selected];
|
||||||
|
|
||||||
// Ambil semua key anak + parent
|
if (childKeys.length > 0) {
|
||||||
const collectKeys = (n: Node): string[] => {
|
// klik parent
|
||||||
if (!n.children) return [n.key];
|
if (!isChecked) {
|
||||||
return [n.key, ...n.children.flatMap(collectKeys)];
|
next = [...new Set([...next, menu.key, ...childKeys])];
|
||||||
};
|
} else {
|
||||||
|
next = next.filter((x) => x !== menu.key && !childKeys.includes(x));
|
||||||
|
}
|
||||||
|
|
||||||
const allKeys = collectKeys(node);
|
next = updateParent(next, getParentKey(menu.key));
|
||||||
|
onChange(next);
|
||||||
const toggleCheck = (checked: boolean) => {
|
return;
|
||||||
let updated = new Set(selected);
|
|
||||||
|
|
||||||
if (checked) {
|
|
||||||
// parent + semua child
|
|
||||||
allKeys.forEach((k) => updated.add(k));
|
|
||||||
} else {
|
|
||||||
// hilangkan parent + semua child
|
|
||||||
allKeys.forEach((k) => updated.delete(k));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⬇⬇⬇ PERBAIKAN PENTING ⬇⬇⬇
|
// klik child
|
||||||
//
|
|
||||||
// Jika node indeterminate → parent harus tetap ada di selected
|
|
||||||
//
|
|
||||||
if (isIndeterminate) {
|
|
||||||
updated.add(node.key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jika semua child tercentang → parent harus checked
|
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
updated.add(node.key);
|
next = next.filter((x) => x !== menu.key);
|
||||||
|
} else {
|
||||||
|
next.push(menu.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange([...updated]);
|
next = updateParent(next, getParentKey(menu.key));
|
||||||
};
|
onChange(next);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap={4} pl="xs">
|
<Stack gap={4}>
|
||||||
<Group wrap="nowrap">
|
<Group gap="xs">
|
||||||
{children.length > 0 ? (
|
{menu.children && menu.children.length > 0 ? (
|
||||||
<ActionIcon variant="subtle" onClick={() => toggle(node.key)}>
|
<ActionIcon
|
||||||
{showChildren ? <IconChevronDown size={16} /> : <IconChevronRight size={16} />}
|
variant="subtle"
|
||||||
|
onClick={() => toggleNode(menu.label)}
|
||||||
|
>
|
||||||
|
{openNodes[menu.label] ? (
|
||||||
|
<IconChevronDown size={16} />
|
||||||
|
) : (
|
||||||
|
<IconChevronRight size={16} />
|
||||||
|
)}
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ width: 24 }} />
|
<div style={{ width: 28 }} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={node.label}
|
label={menu.label}
|
||||||
checked={isChecked}
|
checked={isChecked}
|
||||||
indeterminate={isIndeterminate}
|
indeterminate={isIndeterminate}
|
||||||
onChange={(e) => toggleCheck(e.target.checked)}
|
onChange={handleCheck}
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
{children.length > 0 && (
|
{menu.children && (
|
||||||
<Collapse in={showChildren}>
|
<Collapse in={open}>
|
||||||
<Stack gap={4} pl="md">
|
<Stack gap={4} pl="md">
|
||||||
{children.map((c) => (
|
{menu.children.map((child) => (
|
||||||
<RenderNode key={c.key} node={c} />
|
<RenderMenu key={child.key} menu={child} />
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
@@ -130,14 +166,11 @@ export default function PermissionTree({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Text size="sm">Hak Akses</Text>
|
<Text size="sm">Hak Akses</Text>
|
||||||
|
|
||||||
{permissionConfig.menus.map((menu: Node) => (
|
{permissionConfig.menus.map((menu: Node) => (
|
||||||
<RenderNode key={menu.key} node={menu} />
|
<RenderMenu key={menu.key} menu={menu} />
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
});
|
});
|
||||||
notification({
|
notification({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
message: "Your user have been saved",
|
message: "Your role have been saved",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
notification({
|
notification({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
message: "Failed to create user ",
|
message: "Failed to create role",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
notification({
|
notification({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
message: "Failed to create user",
|
message: "Failed to create role",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
@@ -97,19 +97,19 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
async function handleEdit() {
|
async function handleEdit() {
|
||||||
try {
|
try {
|
||||||
setBtnLoading(true);
|
setBtnLoading(true);
|
||||||
const res = await apiFetch.api.pengaduan.category.update.post(dataEdit);
|
const res = await apiFetch.api.user["role-update"].post(dataEdit as any);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
mutate();
|
mutate();
|
||||||
close();
|
close();
|
||||||
notification({
|
notification({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
message: "Your category have been saved",
|
message: "Your role have been saved",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
notification({
|
notification({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
message: "Failed to edit category",
|
message: "Failed to edit role",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
notification({
|
notification({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
message: "Failed to edit category",
|
message: "Failed to edit role",
|
||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
@@ -156,16 +156,10 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function chooseEdit({
|
function chooseEdit({ data }: { data: { id: string; name: string; permissions: []; }; }) {
|
||||||
data,
|
setDataEdit({
|
||||||
}: {
|
id: data.id, name: data.name, permissions: data.permissions ? data.permissions : []
|
||||||
data: {
|
});
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
permissions: [];
|
|
||||||
};
|
|
||||||
}) {
|
|
||||||
setDataEdit(data);
|
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +179,6 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("dataTambah", dataTambah);
|
|
||||||
|
|
||||||
useShallowEffect(() => {
|
useShallowEffect(() => {
|
||||||
if (dataEdit.name.length > 0) {
|
if (dataEdit.name.length > 0) {
|
||||||
@@ -200,11 +193,11 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
opened={opened}
|
opened={opened}
|
||||||
onClose={close}
|
onClose={close}
|
||||||
title={"Edit"}
|
title={"Edit"}
|
||||||
centered
|
|
||||||
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
size={"lg"}
|
||||||
>
|
>
|
||||||
<Stack gap="ld">
|
<Stack gap="ld">
|
||||||
<Input.Wrapper label="Edit Kategori">
|
<Input.Wrapper label="Nama Role">
|
||||||
<Input
|
<Input
|
||||||
value={dataEdit.name}
|
value={dataEdit.name}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -216,6 +209,12 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Input.Wrapper>
|
</Input.Wrapper>
|
||||||
|
<PermissionTree
|
||||||
|
selected={dataEdit.permissions}
|
||||||
|
onChange={(permissions) => {
|
||||||
|
setDataEdit({ ...dataEdit, permissions: permissions as never[] });
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Group justify="center" grow>
|
<Group justify="center" grow>
|
||||||
<Button variant="light" onClick={close}>
|
<Button variant="light" onClick={close}>
|
||||||
Batal
|
Batal
|
||||||
@@ -223,7 +222,11 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
<Button
|
<Button
|
||||||
variant="filled"
|
variant="filled"
|
||||||
onClick={handleEdit}
|
onClick={handleEdit}
|
||||||
disabled={btnDisable}
|
disabled={
|
||||||
|
btnDisable ||
|
||||||
|
dataEdit.name.length < 1 ||
|
||||||
|
dataEdit.permissions?.length < 1
|
||||||
|
}
|
||||||
loading={btnLoading}
|
loading={btnLoading}
|
||||||
>
|
>
|
||||||
Simpan
|
Simpan
|
||||||
@@ -238,10 +241,11 @@ export default function UserRoleSetting({ permissions }: { permissions: JsonValu
|
|||||||
onClose={closeTambah}
|
onClose={closeTambah}
|
||||||
title={"Tambah"}
|
title={"Tambah"}
|
||||||
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
overlayProps={{ backgroundOpacity: 0.55, blur: 3 }}
|
||||||
|
size={"lg"}
|
||||||
>
|
>
|
||||||
<Stack gap="ld">
|
<Stack gap="ld">
|
||||||
<Input.Wrapper
|
<Input.Wrapper
|
||||||
label="Nama"
|
label="Nama Role"
|
||||||
description=""
|
description=""
|
||||||
error={error.name ? "Field is required" : ""}
|
error={error.name ? "Field is required" : ""}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -24,41 +24,41 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pengaduan.antrian",
|
"key": "pengaduan.antrian",
|
||||||
"label": "Antrian",
|
"label": "Detail pengaduan dengan status antrian",
|
||||||
"default": true,
|
"default": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"key": "pengaduan.antrian.tolak",
|
"key": "pengaduan.antrian.tolak",
|
||||||
"label": "Menolak",
|
"label": "Menolak pengaduan",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pengaduan.antrian.terima",
|
"key": "pengaduan.antrian.terima",
|
||||||
"label": "Menerima",
|
"label": "Menerima pengaduan",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pengaduan.diterima",
|
"key": "pengaduan.diterima",
|
||||||
"label": "Diterima",
|
"label": "Detail pengaduan dengan status diterima",
|
||||||
"default": true,
|
"default": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"key": "pengaduan.diterima.dikerjakan",
|
"key": "pengaduan.diterima.dikerjakan",
|
||||||
"label": "Dikerjakan",
|
"label": "Menegerjakan pengaduan",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pengaduan.dikerjakan",
|
"key": "pengaduan.dikerjakan",
|
||||||
"label": "Dikerjakan",
|
"label": "Detail pengaduan dengan status dikerjakan",
|
||||||
"default": true,
|
"default": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"key": "pengaduan.dikerjakan.selesai",
|
"key": "pengaduan.dikerjakan.selesai",
|
||||||
"label": "Diselesaikan",
|
"label": "Menyelesaikan pengaduan",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -77,34 +77,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pelayanan.antrian",
|
"key": "pelayanan.antrian",
|
||||||
"label": "Antrian",
|
"label": "Detail pelayanan dengan status antrian",
|
||||||
"default": true,
|
"default": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"key": "pelayanan.antrian.tolak",
|
"key": "pelayanan.antrian.tolak",
|
||||||
"label": "Menolak",
|
"label": "Menolak pelayanan",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pelayanan.antrian.terima",
|
"key": "pelayanan.antrian.terima",
|
||||||
"label": "Menerima",
|
"label": "Menerima pelayanan",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pelayanan.diterima",
|
"key": "pelayanan.diterima",
|
||||||
"label": "Diterima",
|
"label": "Detail pelayanan dengan status diterima",
|
||||||
"default": true,
|
"default": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"key": "pelayanan.diterima.tolak",
|
"key": "pelayanan.diterima.tolak",
|
||||||
"label": "Menolak",
|
"label": "Menolak pelayanan",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "pelayanan.diterima.setujui",
|
"key": "pelayanan.diterima.setujui",
|
||||||
"label": "Menyetujui",
|
"label": "Menyetujui pelayanan",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -300,7 +300,7 @@
|
|||||||
"default": true,
|
"default": true,
|
||||||
"children": [
|
"children": [
|
||||||
{
|
{
|
||||||
"key": "credential.viewØ",
|
"key": "credential.view",
|
||||||
"label": "View List",
|
"label": "View List",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ const UserRoute = new Elysia({
|
|||||||
const data = await prisma.role.findMany({
|
const data = await prisma.role.findMany({
|
||||||
where: {
|
where: {
|
||||||
isActive: true
|
isActive: true
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
name: "asc"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
@@ -193,11 +196,11 @@ const UserRoute = new Elysia({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.post("role-create", async ({ body }) => {
|
.post("role-create", async ({ body }) => {
|
||||||
const { name, permission } = body;
|
const { name, permissions } = body;
|
||||||
const create = await prisma.role.create({
|
const create = await prisma.role.create({
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
permissions: permission
|
permissions: permissions
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -208,7 +211,7 @@ const UserRoute = new Elysia({
|
|||||||
}, {
|
}, {
|
||||||
body: t.Object({
|
body: t.Object({
|
||||||
name: t.String({ minLength: 1, error: "name is required" }),
|
name: t.String({ minLength: 1, error: "name is required" }),
|
||||||
permission: t.Array(t.Any(), { minItems: 1, error: "permission is required" })
|
permissions: t.Any(),
|
||||||
}),
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "create-role",
|
summary: "create-role",
|
||||||
@@ -216,14 +219,14 @@ const UserRoute = new Elysia({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.post("/role-update", async ({ body }) => {
|
.post("/role-update", async ({ body }) => {
|
||||||
const { id, name, permission } = body;
|
const { id, name, permissions } = body;
|
||||||
const update = await prisma.role.update({
|
const update = await prisma.role.update({
|
||||||
where: {
|
where: {
|
||||||
id
|
id
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
permissions: permission
|
permissions
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -235,7 +238,7 @@ const UserRoute = new Elysia({
|
|||||||
body: t.Object({
|
body: t.Object({
|
||||||
id: t.String({ minLength: 1, error: "id is required" }),
|
id: t.String({ minLength: 1, error: "id is required" }),
|
||||||
name: t.String({ minLength: 1, error: "name is required" }),
|
name: t.String({ minLength: 1, error: "name is required" }),
|
||||||
permission: t.Array(t.String(), { minItems: 1, error: "permission is required" })
|
permissions: t.Any()
|
||||||
}),
|
}),
|
||||||
detail: {
|
detail: {
|
||||||
summary: "update-role",
|
summary: "update-role",
|
||||||
|
|||||||
Reference in New Issue
Block a user