mirror of
https://github.com/roleypoly/roleypoly.git
synced 2025-06-15 17:19:10 +00:00
feat: add access control
This commit is contained in:
parent
9c07ff0e54
commit
3f45153b66
47 changed files with 1084 additions and 164 deletions
|
@ -0,0 +1,13 @@
|
|||
import { presentableGuild, roleypolyGuild } from '../../fixtures/storyData';
|
||||
import { EditorAccessControl } from './EditorAccessControl';
|
||||
|
||||
export default {
|
||||
title: 'Organisms/Editor/Access Control',
|
||||
component: EditorAccessControl,
|
||||
args: {
|
||||
guild: presentableGuild,
|
||||
guildSlug: roleypolyGuild,
|
||||
},
|
||||
};
|
||||
|
||||
export const accessControl = (args) => <EditorAccessControl {...args} />;
|
|
@ -0,0 +1,8 @@
|
|||
import { palette } from '@roleypoly/design-system/atoms/colors';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const RoleContainer = styled.div`
|
||||
border-radius: 4px;
|
||||
border: 1px solid ${palette.taupe400};
|
||||
padding: 10px;
|
||||
`;
|
|
@ -0,0 +1,185 @@
|
|||
import { IconHelper } from '@roleypoly/design-system/atoms/icon-helper';
|
||||
import { Space } from '@roleypoly/design-system/atoms/space';
|
||||
import { Toggle } from '@roleypoly/design-system/atoms/toggle';
|
||||
import {
|
||||
AmbientLarge,
|
||||
LargeText,
|
||||
Link,
|
||||
Text,
|
||||
} from '@roleypoly/design-system/atoms/typography';
|
||||
import { EditableRoleList } from '@roleypoly/design-system/molecules/editable-role-list';
|
||||
import {
|
||||
EditorUtilityProps,
|
||||
EditorUtilityShell,
|
||||
} from '@roleypoly/design-system/molecules/editor-utility-shell';
|
||||
import { GuildAccessControl, PresentableGuild } from '@roleypoly/types';
|
||||
import deepEqual from 'deep-equal';
|
||||
import * as React from 'react';
|
||||
import { GoAlert, GoInfo, GoShield, GoThumbsdown, GoThumbsup } from 'react-icons/go';
|
||||
import { RoleContainer } from './EditorAccessControl.styled';
|
||||
|
||||
export type EditorAccessControlProps = {
|
||||
guild: PresentableGuild;
|
||||
} & EditorUtilityProps;
|
||||
|
||||
export const EditorAccessControl = (props: EditorAccessControlProps) => {
|
||||
const [accessControl, setAccessControl] = React.useState(
|
||||
props.guild.data.accessControl
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
setAccessControl(props.guild.data.accessControl);
|
||||
}, [props.guild.data.accessControl]);
|
||||
|
||||
const onSubmit = () => {
|
||||
props.onSubmit(accessControl);
|
||||
};
|
||||
|
||||
const handleChange =
|
||||
(key: keyof GuildAccessControl) =>
|
||||
(value: GuildAccessControl[keyof GuildAccessControl]) => {
|
||||
setAccessControl((prev) => ({ ...prev, [key]: value }));
|
||||
};
|
||||
|
||||
const hasChanges = React.useMemo(() => {
|
||||
return !deepEqual(accessControl, props.guild.data.accessControl);
|
||||
}, [accessControl, props.guild.data.accessControl]);
|
||||
|
||||
const rolesNotInBlocked = React.useMemo(() => {
|
||||
return props.guild.roles.filter(
|
||||
(role) => role.id !== props.guild.id && !accessControl.blockList.includes(role.id)
|
||||
);
|
||||
}, [accessControl, props.guild.roles]);
|
||||
|
||||
const rolesNotInAllowed = React.useMemo(() => {
|
||||
return props.guild.roles.filter(
|
||||
(role) => role.id !== props.guild.id && !accessControl.allowList.includes(role.id)
|
||||
);
|
||||
}, [accessControl, props.guild.roles]);
|
||||
|
||||
return (
|
||||
<EditorUtilityShell
|
||||
guildSlug={props.guild.guild}
|
||||
title="Access Control"
|
||||
icon={<GoShield />}
|
||||
hasChanges={hasChanges}
|
||||
onSubmit={onSubmit}
|
||||
onExit={props.onExit}
|
||||
>
|
||||
<p>
|
||||
<IconHelper level="chrome">
|
||||
<GoInfo />
|
||||
</IconHelper>
|
||||
Admins and Role Managers are exempt from all of these limits. Please note,
|
||||
this settings page is in order of precedence.
|
||||
</p>
|
||||
<Space />
|
||||
<div>
|
||||
<LargeText>
|
||||
Block pending members from using Roleypoly
|
||||
<IconHelper level="error">
|
||||
<GoThumbsdown />
|
||||
</IconHelper>
|
||||
</LargeText>
|
||||
<br />
|
||||
<br />
|
||||
{/* <RoleContainer> */}
|
||||
<Toggle
|
||||
state={accessControl.blockPending}
|
||||
onChange={handleChange('blockPending')}
|
||||
>
|
||||
If a user is behind Discord's{' '}
|
||||
<Link href="https://support.discord.com/hc/en-us/articles/1500000466882-Rules-Screening-FAQ">
|
||||
Membership Screening
|
||||
</Link>{' '}
|
||||
feature, they can <b>not</b> use Roleypoly.
|
||||
</Toggle>
|
||||
{/* </RoleContainer> */}
|
||||
<p>
|
||||
<AmbientLarge>
|
||||
<IconHelper level="chrome">
|
||||
<GoInfo />
|
||||
</IconHelper>
|
||||
This only applies to Discord servers with Community features enabled.
|
||||
</AmbientLarge>
|
||||
</p>
|
||||
</div>
|
||||
<Space />
|
||||
<div>
|
||||
<p>
|
||||
<LargeText>
|
||||
Block roles from using Roleypoly
|
||||
<IconHelper level="error">
|
||||
<GoThumbsdown />
|
||||
</IconHelper>
|
||||
</LargeText>
|
||||
<br />
|
||||
<Text>
|
||||
If there are roles in this list, any server member <b>with</b> a role in the
|
||||
list can <b>not</b> use Roleypoly.
|
||||
<br />
|
||||
<IconHelper level="info">
|
||||
<GoInfo />
|
||||
</IconHelper>
|
||||
Blocked roles take precedence over the allowed roles.
|
||||
</Text>
|
||||
</p>
|
||||
<RoleContainer>
|
||||
<EditableRoleList
|
||||
roles={props.guild.roles}
|
||||
unselectedRoles={rolesNotInBlocked}
|
||||
selectedRoles={accessControl.blockList}
|
||||
onChange={handleChange('blockList')}
|
||||
/>
|
||||
</RoleContainer>
|
||||
<p>
|
||||
<AmbientLarge>
|
||||
<IconHelper level="chrome">
|
||||
<GoInfo />
|
||||
</IconHelper>
|
||||
If your Discord server has a "muted" or "visitor" role, this setting is
|
||||
meant to complement it.
|
||||
</AmbientLarge>
|
||||
</p>
|
||||
</div>
|
||||
<Space />
|
||||
<div>
|
||||
<p>
|
||||
<LargeText>
|
||||
Allow these roles to use Roleypoly
|
||||
<IconHelper level="success">
|
||||
<GoThumbsup />
|
||||
</IconHelper>
|
||||
</LargeText>
|
||||
<br />
|
||||
<Text>
|
||||
If there are roles in this list, any server member <b>without</b> a role in
|
||||
the list can <b>not</b> use Roleypoly.
|
||||
<br />
|
||||
<IconHelper level="warn">
|
||||
<GoAlert />
|
||||
</IconHelper>
|
||||
This can disrupt use of the bot, so be careful!
|
||||
</Text>
|
||||
</p>
|
||||
<RoleContainer>
|
||||
<EditableRoleList
|
||||
roles={props.guild.roles}
|
||||
unselectedRoles={rolesNotInAllowed}
|
||||
selectedRoles={accessControl.allowList}
|
||||
onChange={handleChange('allowList')}
|
||||
/>
|
||||
</RoleContainer>
|
||||
<p>
|
||||
<AmbientLarge>
|
||||
<IconHelper level="chrome">
|
||||
<GoInfo />
|
||||
</IconHelper>
|
||||
If your Discord server uses a "role gating" system, this setting is
|
||||
meant to complement it.
|
||||
</AmbientLarge>
|
||||
</p>
|
||||
</div>
|
||||
</EditorUtilityShell>
|
||||
);
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export * from './EditorAccessControl';
|
Loading…
Add table
Add a link
Reference in a new issue