feat: Finish crappy role ranking implementation that works but is full of sin
parent
20c8dde197
commit
e7d7420d5b
|
|
@ -93,122 +93,129 @@ export function useRolesForReorder(server: Server) {
|
||||||
/**
|
/**
|
||||||
* Role reordering component
|
* Role reordering component
|
||||||
*/
|
*/
|
||||||
const RoleReorderPanel = observer(({ server }: Props) => {
|
const RoleReorderPanel = observer(
|
||||||
const initialRoles = useRolesForReorder(server);
|
({
|
||||||
const [roles, setRoles] = useState(initialRoles);
|
server,
|
||||||
const [isReordering, setIsReordering] = useState(false);
|
onRolesReordered,
|
||||||
|
}: Props & { onRolesReordered: () => void }) => {
|
||||||
|
const initialRoles = useRolesForReorder(server);
|
||||||
|
const [roles, setRoles] = useState(initialRoles);
|
||||||
|
const [isReordering, setIsReordering] = useState(false);
|
||||||
|
|
||||||
// Update local state when server roles change
|
// Update local state when server roles change
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
setRoles(useRolesForReorder(server));
|
setRoles(useRolesForReorder(server));
|
||||||
}, [server.roles, server.default_permissions]);
|
}, [server.roles, server.default_permissions]);
|
||||||
|
|
||||||
const moveRoleUp = (index: number) => {
|
const moveRoleUp = (index: number) => {
|
||||||
if (index === 0 || roles[index].id === "default") return;
|
if (index === 0 || roles[index].id === "default") return;
|
||||||
|
|
||||||
const newRoles = [...roles];
|
const newRoles = [...roles];
|
||||||
[newRoles[index - 1], newRoles[index]] = [
|
[newRoles[index - 1], newRoles[index]] = [
|
||||||
newRoles[index],
|
newRoles[index],
|
||||||
newRoles[index - 1],
|
newRoles[index - 1],
|
||||||
];
|
];
|
||||||
setRoles(newRoles);
|
setRoles(newRoles);
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveRoleDown = (index: number) => {
|
const moveRoleDown = (index: number) => {
|
||||||
// Can't move down if it's the last non-default role or if it's default
|
// Can't move down if it's the last non-default role or if it's default
|
||||||
if (index >= roles.length - 2 || roles[index].id === "default") return;
|
if (index >= roles.length - 2 || roles[index].id === "default")
|
||||||
|
return;
|
||||||
|
|
||||||
const newRoles = [...roles];
|
const newRoles = [...roles];
|
||||||
[newRoles[index], newRoles[index + 1]] = [
|
[newRoles[index], newRoles[index + 1]] = [
|
||||||
newRoles[index + 1],
|
newRoles[index + 1],
|
||||||
newRoles[index],
|
newRoles[index],
|
||||||
];
|
];
|
||||||
setRoles(newRoles);
|
setRoles(newRoles);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveReorder = async () => {
|
const saveReorder = async () => {
|
||||||
setIsReordering(true);
|
setIsReordering(true);
|
||||||
try {
|
try {
|
||||||
const nonDefaultRoles = roles.filter(
|
const nonDefaultRoles = roles.filter(
|
||||||
(role) => role.id !== "default",
|
(role) => role.id !== "default",
|
||||||
);
|
);
|
||||||
const roleIds = nonDefaultRoles.map((role) => role.id);
|
const roleIds = nonDefaultRoles.map((role) => role.id);
|
||||||
|
|
||||||
const session = useSession()!;
|
const session = useSession()!;
|
||||||
const client = session.client!;
|
const client = session.client!;
|
||||||
|
|
||||||
// Make direct API request since it's not in r.js as of writing
|
// Make direct API request since it's not in r.js as of writing
|
||||||
await client.api.patch(`/servers/${server._id}/roles/ranks`, {
|
await client.api.patch(`/servers/${server._id}/roles/ranks`, {
|
||||||
ranks: roleIds,
|
ranks: roleIds,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Roles reordered successfully");
|
console.log("Roles reordered successfully");
|
||||||
} catch (error) {
|
onRolesReordered();
|
||||||
console.error("Failed to reorder roles:", error);
|
} catch (error) {
|
||||||
setRoles(initialRoles);
|
console.error("Failed to reorder roles:", error);
|
||||||
} finally {
|
setRoles(initialRoles);
|
||||||
setIsReordering(false);
|
} finally {
|
||||||
}
|
setIsReordering(false);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const hasChanges = !isEqual(
|
const hasChanges = !isEqual(
|
||||||
roles.filter((r) => r.id !== "default").map((r) => r.id),
|
roles.filter((r) => r.id !== "default").map((r) => r.id),
|
||||||
initialRoles.filter((r) => r.id !== "default").map((r) => r.id),
|
initialRoles.filter((r) => r.id !== "default").map((r) => r.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SpaceBetween>
|
<SpaceBetween>
|
||||||
<H1>
|
<H1>
|
||||||
<Text id="app.settings.permissions.role_ranking" />
|
<Text id="app.settings.permissions.role_ranking" />
|
||||||
</H1>
|
</H1>
|
||||||
<Button
|
<Button
|
||||||
palette="secondary"
|
palette="secondary"
|
||||||
disabled={!hasChanges || isReordering}
|
disabled={!hasChanges || isReordering}
|
||||||
onClick={saveReorder}>
|
onClick={saveReorder}>
|
||||||
<Text id="app.special.modals.actions.save" />
|
<Text id="app.special.modals.actions.save" />
|
||||||
</Button>
|
</Button>
|
||||||
</SpaceBetween>
|
</SpaceBetween>
|
||||||
|
|
||||||
<RoleReorderContainer>
|
<RoleReorderContainer>
|
||||||
{roles.map((role, index) => (
|
{roles.map((role, index) => (
|
||||||
<RoleItem key={role.id}>
|
<RoleItem key={role.id}>
|
||||||
<RoleInfo>
|
<RoleInfo>
|
||||||
<RoleName>{role.name}</RoleName>
|
<RoleName>{role.name}</RoleName>
|
||||||
<RoleRank>
|
<RoleRank>
|
||||||
{role.id === "default" ? (
|
{role.id === "default" ? (
|
||||||
<Text id="app.settings.permissions.default_desc" />
|
<Text id="app.settings.permissions.default_desc" />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Text id="app.settings.permissions.role_ranking" />{" "}
|
<Text id="app.settings.permissions.role_ranking" />{" "}
|
||||||
{index}
|
{index}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</RoleRank>
|
</RoleRank>
|
||||||
</RoleInfo>
|
</RoleInfo>
|
||||||
|
|
||||||
{role.id !== "default" && (
|
{role.id !== "default" && (
|
||||||
<RoleControls>
|
<RoleControls>
|
||||||
<MoveButton
|
<MoveButton
|
||||||
palette="secondary"
|
palette="secondary"
|
||||||
disabled={index === 0}
|
disabled={index === 0}
|
||||||
onClick={() => moveRoleUp(index)}>
|
onClick={() => moveRoleUp(index)}>
|
||||||
<ChevronUp size={16} />
|
<ChevronUp size={16} />
|
||||||
</MoveButton>
|
</MoveButton>
|
||||||
<MoveButton
|
<MoveButton
|
||||||
palette="secondary"
|
palette="secondary"
|
||||||
disabled={index >= roles.length - 2}
|
disabled={index >= roles.length - 2}
|
||||||
onClick={() => moveRoleDown(index)}>
|
onClick={() => moveRoleDown(index)}>
|
||||||
<ChevronDown size={16} />
|
<ChevronDown size={16} />
|
||||||
</MoveButton>
|
</MoveButton>
|
||||||
</RoleControls>
|
</RoleControls>
|
||||||
)}
|
)}
|
||||||
</RoleItem>
|
</RoleItem>
|
||||||
))}
|
))}
|
||||||
</RoleReorderContainer>
|
</RoleReorderContainer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to memo-ize role information.
|
* Hook to memo-ize role information.
|
||||||
|
|
@ -237,6 +244,7 @@ export function useRoles(server: Server) {
|
||||||
*/
|
*/
|
||||||
export const Roles = observer(({ server }: Props) => {
|
export const Roles = observer(({ server }: Props) => {
|
||||||
const [showReorderPanel, setShowReorderPanel] = useState(false);
|
const [showReorderPanel, setShowReorderPanel] = useState(false);
|
||||||
|
const [rolesWereReordered, setRolesWereReordered] = useState(false);
|
||||||
|
|
||||||
// Consolidate all permissions that we can change right now.
|
// Consolidate all permissions that we can change right now.
|
||||||
const currentRoles = useRoles(server);
|
const currentRoles = useRoles(server);
|
||||||
|
|
@ -260,16 +268,26 @@ export const Roles = observer(({ server }: Props) => {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ReorderButton = styled(Button)`
|
const ReorderButton = styled(Button)`
|
||||||
margin: 0 0 16px 0;
|
margin-inline: auto 8px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const handleBackFromReorder = () => {
|
||||||
|
setShowReorderPanel(false);
|
||||||
|
if (rolesWereReordered) {
|
||||||
|
window.location.reload(); // Refresh because I don't actually care anymore.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (showReorderPanel) {
|
if (showReorderPanel) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<RoleReorderPanel server={server} />
|
<RoleReorderPanel
|
||||||
|
server={server}
|
||||||
|
onRolesReordered={() => setRolesWereReordered(true)}
|
||||||
|
/>
|
||||||
<Button
|
<Button
|
||||||
palette="secondary"
|
palette="secondary"
|
||||||
onClick={() => setShowReorderPanel(false)}
|
onClick={handleBackFromReorder}
|
||||||
style={{ marginBottom: "16px" }}>
|
style={{ marginBottom: "16px" }}>
|
||||||
<Text id="app.special.modals.actions.back" />
|
<Text id="app.special.modals.actions.back" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -279,11 +297,6 @@ export const Roles = observer(({ server }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ReorderButton
|
|
||||||
palette="secondary"
|
|
||||||
onClick={() => setShowReorderPanel(true)}>
|
|
||||||
<Text id="app.settings.permissions.role_ranking" />
|
|
||||||
</ReorderButton>
|
|
||||||
<PermissionsLayout
|
<PermissionsLayout
|
||||||
server={server}
|
server={server}
|
||||||
rank={server.member?.ranking ?? Infinity}
|
rank={server.member?.ranking ?? Infinity}
|
||||||
|
|
@ -343,6 +356,11 @@ export const Roles = observer(({ server }: Props) => {
|
||||||
fields={{ name: currentRole.name }}
|
fields={{ name: currentRole.name }}
|
||||||
/>
|
/>
|
||||||
</H1>
|
</H1>
|
||||||
|
<ReorderButton
|
||||||
|
palette="secondary"
|
||||||
|
onClick={() => setShowReorderPanel(true)}>
|
||||||
|
<Text id="app.settings.permissions.role_ranking" />
|
||||||
|
</ReorderButton>
|
||||||
<Button
|
<Button
|
||||||
palette="secondary"
|
palette="secondary"
|
||||||
disabled={isEqual(
|
disabled={isEqual(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue