|
|
|
@ -1,20 +1,26 @@
|
|
|
|
'use client'
|
|
|
|
'use client'
|
|
|
|
import { RiCloseCircleFill, RiLockLine, RiOrganizationChart } from '@remixicon/react'
|
|
|
|
import { RiAlertFill, RiCloseCircleFill, RiLockLine, RiOrganizationChart } from '@remixicon/react'
|
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
import Avatar from '../../base/avatar'
|
|
|
|
import Avatar from '../../base/avatar'
|
|
|
|
import AddMemberOrGroupDialog from './add-member-or-group-dialog'
|
|
|
|
import Divider from '../../base/divider'
|
|
|
|
|
|
|
|
import Tooltip from '../../base/tooltip'
|
|
|
|
|
|
|
|
import AddMemberOrGroupDialog from './add-member-or-group-pop'
|
|
|
|
|
|
|
|
import useAccessControlStore, { AccessControlType } from './access-control-store'
|
|
|
|
|
|
|
|
import { useGlobalPublicStore } from '@/context/global-public-context'
|
|
|
|
|
|
|
|
|
|
|
|
type SpecificGroupsOrMembersProps = {
|
|
|
|
export default function SpecificGroupsOrMembers() {
|
|
|
|
active: boolean
|
|
|
|
const currentMenu = useAccessControlStore(s => s.currentMenu)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default function SpecificGroupsOrMembers(props: SpecificGroupsOrMembersProps) {
|
|
|
|
|
|
|
|
const { active } = props
|
|
|
|
|
|
|
|
const { t } = useTranslation()
|
|
|
|
const { t } = useTranslation()
|
|
|
|
if (!active) {
|
|
|
|
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
|
|
|
return <div className='h-[40px] p-3 flex items-center gap-x-2'>
|
|
|
|
const hideTip = systemFeatures.enable_web_sso_switch_component && systemFeatures.sso_enforced_for_web
|
|
|
|
<RiLockLine className='w-4 h-4 text-text-primary' />
|
|
|
|
|
|
|
|
<p className='system-sm-medium text-text-primary'>{t('app.accessControlDialog.accessItems.specific')}</p>
|
|
|
|
if (currentMenu !== AccessControlType.SPECIFIC_GROUPS_MEMBERS) {
|
|
|
|
|
|
|
|
return <div className='flex items-center p-3'>
|
|
|
|
|
|
|
|
<div className='grow flex items-center gap-x-2'>
|
|
|
|
|
|
|
|
<RiLockLine className='w-4 h-4 text-text-primary' />
|
|
|
|
|
|
|
|
<p className='system-sm-medium text-text-primary'>{t('app.accessControlDialog.accessItems.specific')}</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{!hideTip && <WebAppSSONotEnabledTip />}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -24,30 +30,54 @@ export default function SpecificGroupsOrMembers(props: SpecificGroupsOrMembersPr
|
|
|
|
<RiLockLine className='w-4 h-4 text-text-primary' />
|
|
|
|
<RiLockLine className='w-4 h-4 text-text-primary' />
|
|
|
|
<p className='system-sm-medium text-text-primary'>{t('app.accessControlDialog.accessItems.specific')}</p>
|
|
|
|
<p className='system-sm-medium text-text-primary'>{t('app.accessControlDialog.accessItems.specific')}</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<AddMemberOrGroupDialog />
|
|
|
|
<div className='flex items-center gap-x-1'>
|
|
|
|
|
|
|
|
{!hideTip && <>
|
|
|
|
|
|
|
|
<WebAppSSONotEnabledTip />
|
|
|
|
|
|
|
|
<Divider className='h-[14px] ml-2 mr-0' type="vertical" />
|
|
|
|
|
|
|
|
</>}
|
|
|
|
|
|
|
|
<AddMemberOrGroupDialog />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className='px-1 pb-1'>
|
|
|
|
<div className='px-1 pb-1'>
|
|
|
|
<div className='bg-background-section rounded-lg p-2 flex flex-col gap-y-2'>
|
|
|
|
<div className='bg-background-section rounded-lg p-2 flex flex-col gap-y-2'>
|
|
|
|
<p className='system-2xs-medium-uppercase text-text-tertiary'>{t('app.accessControlDialog.groups', { count: 1 })}</p>
|
|
|
|
<RenderGroupsAndMembers />
|
|
|
|
<div className='flex flex-row flex-wrap gap-1'>
|
|
|
|
|
|
|
|
<GroupItem />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<p className='system-2xs-medium-uppercase text-text-tertiary'>{t('app.accessControlDialog.members', { count: 4 })}</p>
|
|
|
|
|
|
|
|
<div className='flex flex-row flex-wrap gap-1'>
|
|
|
|
|
|
|
|
<MemberItem />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div >
|
|
|
|
</div >
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function GroupItem() {
|
|
|
|
|
|
|
|
|
|
|
|
function RenderGroupsAndMembers() {
|
|
|
|
|
|
|
|
const { t } = useTranslation()
|
|
|
|
|
|
|
|
const specificGroups = useAccessControlStore(s => s.specificGroups)
|
|
|
|
|
|
|
|
const specificMembers = useAccessControlStore(s => s.specificMembers)
|
|
|
|
|
|
|
|
if (specificGroups.length <= 0 && specificMembers.length <= 0)
|
|
|
|
|
|
|
|
return <div className='px-2 pt-5 pb-1.5'><p className='system-xs-regular text-text-tertiary text-center'>{t('app.accessControlDialog.noGroupsOrMembers')}</p></div>
|
|
|
|
|
|
|
|
return <>
|
|
|
|
|
|
|
|
<p className='system-2xs-medium-uppercase text-text-tertiary'>{t('app.accessControlDialog.groups', { count: specificGroups.length ?? 0 })}</p>
|
|
|
|
|
|
|
|
<div className='flex flex-row flex-wrap gap-1'>
|
|
|
|
|
|
|
|
{specificGroups.map((group, index) => <GroupItem key={index} group={group} />)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<p className='system-2xs-medium-uppercase text-text-tertiary'>{t('app.accessControlDialog.members', { count: specificMembers.length ?? 0 })}</p>
|
|
|
|
|
|
|
|
<div className='flex flex-row flex-wrap gap-1'>
|
|
|
|
|
|
|
|
{specificMembers.map((member, index) => <MemberItem key={index} member={member} />)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type GroupItemProps = {
|
|
|
|
|
|
|
|
group: string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function GroupItem({ group }: GroupItemProps) {
|
|
|
|
return <BaseItem icon={<RiOrganizationChart className='w-[14px] h-[14px] text-components-avatar-shape-fill-stop-0' />}>
|
|
|
|
return <BaseItem icon={<RiOrganizationChart className='w-[14px] h-[14px] text-components-avatar-shape-fill-stop-0' />}>
|
|
|
|
<p className='system-xs-regular text-text-primary'>Group Name</p>
|
|
|
|
<p className='system-xs-regular text-text-primary'>Group Name</p>
|
|
|
|
<p className='system-xs-regular text-text-tertiary'>7</p>
|
|
|
|
<p className='system-xs-regular text-text-tertiary'>7</p>
|
|
|
|
</BaseItem>
|
|
|
|
</BaseItem>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function MemberItem() {
|
|
|
|
type MemberItemProps = {
|
|
|
|
|
|
|
|
member: string
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function MemberItem({ member }: MemberItemProps) {
|
|
|
|
return <BaseItem icon={<Avatar className='w-[14px] h-[14px]' textClassName='text-[12px]' avatar={null} name='M' />}>
|
|
|
|
return <BaseItem icon={<Avatar className='w-[14px] h-[14px]' textClassName='text-[12px]' avatar={null} name='M' />}>
|
|
|
|
<p className='system-xs-regular text-text-primary'>Member Name</p>
|
|
|
|
<p className='system-xs-regular text-text-primary'>Member Name</p>
|
|
|
|
</BaseItem>
|
|
|
|
</BaseItem>
|
|
|
|
@ -70,3 +100,10 @@ function BaseItem({ icon, children }: BaseItemProps) {
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function WebAppSSONotEnabledTip() {
|
|
|
|
|
|
|
|
const { t } = useTranslation()
|
|
|
|
|
|
|
|
return <Tooltip asChild={false} popupContent={t('app.accessControlDialog.webAppSSONotEnabledTip')}>
|
|
|
|
|
|
|
|
<RiAlertFill className='w-4 h-4 text-text-warning-secondary shrink-0' />
|
|
|
|
|
|
|
|
</Tooltip>
|
|
|
|
|
|
|
|
}
|
|
|
|
|