Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/web/i18n/en/account_team.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"forbid_hint": "After forbidden, this invitation link will become invalid. This action is irreversible. Are you sure you want to deactivate?",
"forbid_success": "Forbid success",
"forbidden": "Forbidden",
"link_forbidden": "Forbidden",
"group": "group",
"group_name": "Group name",
"handle_invitation": "Handle Invitation",
Expand Down Expand Up @@ -220,7 +221,8 @@
"recover_team_member": "Member Recovery",
"relocate_department": "Department Mobile",
"remark": "remark",
"remove_tip": "Confirm to remove {{username}} from the team?",
"remove_tip": "Confirm to remove {{username}} from the team? The member will be marked as 'leave'. Operation data will not be deleted, and resources under the account will be automatically transferred to the team owner.",
"forbidden_tip": "Confirm disabling {{username}}? The member will be marked as 'disabled' and will not be able to log in. Operation data will not be deleted, and resources under the account will be automatically transferred to the team owner.",
"restore_tip": "Confirm to join the team {{username}}? \nOnly the availability and related permissions of this member account are restored, and the resources under the account cannot be restored.",
"restore_tip_title": "Recovery confirmation",
"retain_admin_permissions": "Keep administrator rights",
Expand Down
2 changes: 2 additions & 0 deletions packages/web/i18n/zh-CN/account_team.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"forbid_hint": "停用后,该邀请链接将失效。 该操作不可撤销,是否确认停用?",
"forbid_success": "停用成功",
"forbidden": "停用",
"link_forbidden": "禁用",
"group": "群组",
"group_name": "群组名称",
"handle_invitation": "处理团队邀请",
Expand Down Expand Up @@ -225,6 +226,7 @@
"relocate_department": "部门移动",
"remark": "备注",
"remove_tip": "确认将 {{username}} 移出团队?成员将被标记为“离开”,不删除操作数据,账号下资源自动转让给团队所有者。",
"forbidden_tip": "确认将 {{username}} 禁用?成员将被标记为“禁用”并无法登录,不删除操作数据,账号下资源自动转让给团队所有者。",
"restore_tip": "确认将 {{username}} 加入团队吗?仅恢复该成员账号可用性及相关权限,无法恢复账号下资源。",
"restore_tip_title": "恢复确认",
"retain_admin_permissions": "保留管理员权限",
Expand Down
4 changes: 3 additions & 1 deletion packages/web/i18n/zh-Hant/account_team.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"forbid_hint": "停用後,該邀請連結將失效。該操作不可撤銷,是否確認停用?",
"forbid_success": "停用成功",
"forbidden": "停用",
"link_forbidden": "禁用",
"group": "群組",
"group_name": "群組名稱",
"handle_invitation": "處理團隊邀請",
Expand Down Expand Up @@ -220,7 +221,8 @@
"recover_team_member": "成員恢復",
"relocate_department": "部門移動",
"remark": "備註",
"remove_tip": "確認將 {{username}} 移出團隊?",
"remove_tip": "確認將 {{username}} 移出團隊?成員將被標記為“離開”,不刪除操作數據,賬號下資源自動轉讓給團隊所有者。",
"forbidden_tip": "確認將 {{username}} 禁用?成員將被標記為“禁用”並無法登錄,不刪除操作數據,賬號下資源自動轉讓給團隊所有者。",
"restore_tip": "確認將 {{username}} 加入團隊嗎?\n僅恢復該成員賬號可用性及相關權限,無法恢復賬號下資源。",
"restore_tip_title": "恢復確認",
"retain_admin_permissions": "保留管理員權限",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ const InviteModal = ({ onClose }: { onClose: () => void }) => {
Trigger={
<Button variant="outline" ml="10px" size="sm" color="myGray.900">
<Icon name="common/lineStop" w="16px" mr="1" />
{t('account_team:forbidden')}
{t('account_team:link_forbidden')}
</Button>
}
closeOnBlur={true}
Expand Down
73 changes: 43 additions & 30 deletions projects/app/src/pageComponents/account/team/MemberTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
postRestoreMember
} from '@/web/support/user/team/api';
import Tag from '@fastgpt/web/components/common/Tag';
import Icon from '@fastgpt/web/components/common/Icon';
import { useContextSelector } from 'use-context-selector';
import { TeamContext } from './context';
import { useSystemStore } from '@/web/common/system/useSystemStore';
Expand Down Expand Up @@ -60,7 +59,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
const { toast } = useToast();
const { userInfo } = useUserStore();
const { feConfigs } = useSystemStore();
const isSyncMember = feConfigs?.register_method?.includes('sync');
const isSyncMode = feConfigs?.register_method?.includes('sync');

const { myTeams, onSwitchTeam } = useContextSelector(TeamContext, (v) => v);

Expand All @@ -76,8 +75,16 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
},
{
label: t('account_team:leave'),
value: 'inactive'
}
value: 'leave'
},
...(isSyncMode
? [
{
label: t('account_team:forbidden'),
value: 'forbidden'
}
]
: [])
];
const [status, setStatus] = useState<string>();

Expand Down Expand Up @@ -192,7 +199,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
{t('account_team:label_sync')}
</Button>
)}
{userInfo?.team.permission.hasManagePer && isSyncMember && (
{userInfo?.team.permission.hasManagePer && isSyncMode && (
<Button
variant={'primary'}
size="md"
Expand All @@ -206,7 +213,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
{t('account_team:sync_immediately')}
</Button>
)}
{userInfo?.team.permission.hasManagePer && !isSyncMember && (
{userInfo?.team.permission.hasManagePer && !isSyncMode && (
<Button
variant={'primary'}
size="md"
Expand All @@ -218,7 +225,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
{t('account_team:user_team_invite_member')}
</Button>
)}
{userInfo?.team.permission.isOwner && isSyncMember && (
{userInfo?.team.permission.isOwner && isSyncMode && (
<Button
variant={'whitePrimary'}
size="md"
Expand All @@ -235,7 +242,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
{t('account_team:export_members')}
</Button>
)}
{!userInfo?.team.permission.isOwner && (
{!userInfo?.team.permission.isOwner && !isSyncMode && (
<PopoverConfirm
Trigger={
<Button
Expand Down Expand Up @@ -285,7 +292,9 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
{member.memberName}
{member.status !== 'active' && (
<Tag ml="2" colorSchema="gray" bg={'myGray.100'} color={'myGray.700'}>
{t('account_team:leave')}
{member.status === 'forbidden'
? t('account_team:forbidden')
: t('account_team:leave')}
</Tag>
)}
</Box>
Expand Down Expand Up @@ -331,31 +340,35 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
</Box>
}
type="delete"
content={t('account_team:remove_tip', {
username: member.memberName
})}
content={
isSyncMode
? t('account_team:forbidden_tip', {
username: member.memberName
})
: t('account_team:remove_tip', {
username: member.memberName
})
}
onConfirm={() => onRemoveMember(member.tmbId)}
/>
</HStack>
) : (
member.status === TeamMemberStatusEnum.forbidden && (
<PopoverConfirm
Trigger={
<Box display={'inline-block'}>
<MyIconButton
icon={'common/confirm/restoreTip'}
size={'1rem'}
hoverColor={'primary.500'}
/>
</Box>
}
type="info"
content={t('account_team:restore_tip', {
username: member.memberName
})}
onConfirm={() => onRestore(member.tmbId)}
/>
)
<PopoverConfirm
Trigger={
<Box display={'inline-block'}>
<MyIconButton
icon={'common/confirm/restoreTip'}
size={'1rem'}
hoverColor={'primary.500'}
/>
</Box>
}
type="info"
content={t('account_team:restore_tip', {
username: member.memberName
})}
onConfirm={() => onRestore(member.tmbId)}
/>
))}
</Td>
</Tr>
Expand Down
3 changes: 2 additions & 1 deletion projects/app/src/pageComponents/login/LoginModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { LoginContainer } from '@/pageComponents/login';
import I18nLngSelector from '@/components/Select/I18nLngSelector';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
import type { ResLogin } from '@/global/support/api/userRes';

type LoginModalProps = {
onSuccess?: () => void;
onSuccess?: (res: ResLogin) => void;
};

const LoginModal = ({ onSuccess }: LoginModalProps) => {
Expand Down
6 changes: 5 additions & 1 deletion projects/app/src/pageComponents/login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { useTranslation } from 'next-i18next';
import LoginForm from '@/pageComponents/login/LoginForm/LoginForm';
import { GET } from '@/web/common/api/request';
import { getDocPath } from '@/web/common/system/doc';
import { postAcceptInvitationLink } from '@/web/support/user/team/api';
import { useRouter } from 'next/router';

const RegisterForm = dynamic(() => import('@/pageComponents/login/RegisterForm'));
const ForgetPasswordForm = dynamic(() => import('@/pageComponents/login/ForgetPasswordForm'));
Expand Down Expand Up @@ -194,10 +196,12 @@ export const LoginContainer = ({

const [pageType, setPageType] = useState<`${LoginPageTypeEnum}` | null>(null);
const [showCommunityModal, setShowCommunityModal] = useState(false);
const router = useRouter();
const { lastRoute = '' } = router.query as { lastRoute: string };

// login success handler
const loginSuccess = useCallback(
(res: ResLogin) => {
async (res: ResLogin) => {
setUserInfo(res.user);
onSuccess?.(res);
},
Expand Down
34 changes: 24 additions & 10 deletions projects/app/src/pages/login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,35 @@ import { serviceSideProps } from '@/web/common/i18n/utils';
import { clearToken } from '@/web/support/user/auth';
import { useMount } from 'ahooks';
import LoginModal from '@/pageComponents/login/LoginModal';
import { postAcceptInvitationLink } from '@/web/support/user/team/api';
import type { ResLogin } from '@/global/support/api/userRes';

const Login = () => {
const router = useRouter();
const { lastRoute = '' } = router.query as { lastRoute: string };

const loginSuccess = useCallback(() => {
const decodeLastRoute = decodeURIComponent(lastRoute);

const navigateTo =
decodeLastRoute && !decodeLastRoute.includes('/login') && decodeLastRoute.startsWith('/')
? lastRoute
: '/dashboard/apps';

router.push(navigateTo);
}, [lastRoute, router]);
const loginSuccess = useCallback(
async (res: ResLogin) => {
const decodeLastRoute = decodeURIComponent(lastRoute);
const navigateTo = await (async () => {
if (res.user.team.status !== 'active') {
if (decodeLastRoute.includes('/account/team?invitelinkid=')) {
const id = decodeLastRoute.split('invitelinkid=')[1];
await postAcceptInvitationLink(id);
return '/dashboard/apps';
}
}
return decodeLastRoute &&
!decodeLastRoute.includes('/login') &&
decodeLastRoute.startsWith('/')
? lastRoute
: '/dashboard/apps';
})();

router.replace(navigateTo);
},
[lastRoute, router]
);

useMount(() => {
clearToken();
Expand Down
28 changes: 24 additions & 4 deletions projects/app/src/pages/login/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
getSourceDomain,
removeFastGPTSem
} from '@/web/support/marketing/utils';
import { postAcceptInvitationLink } from '@/web/support/user/team/api';

let isOauthLogging = false;

Expand All @@ -35,11 +36,31 @@ const provider = () => {
: '/dashboard/apps';
const errorRedirectPage = lastRoute.startsWith('/chat') ? lastRoute : '/login';

// const loginSuccess = useCallback(async () => {
// const decodeLastRoute = decodeURIComponent(lastRoute);

// router.push(navigateTo);
// }, [lastRoute, router]);

const loginSuccess = useCallback(
(res: ResLogin) => {
async (res: ResLogin) => {
const decodeLastRoute = decodeURIComponent(lastRoute);
setUserInfo(res.user);

router.replace(lastRoute);
const navigateTo = await (async () => {
if (res.user.team.status !== 'active') {
if (decodeLastRoute.includes('/account/team?invitelinkid=')) {
const id = decodeLastRoute.split('invitelinkid=')[1];
await postAcceptInvitationLink(id);
return '/dashboard/apps';
}
}
return decodeLastRoute &&
!decodeLastRoute.includes('/login') &&
decodeLastRoute.startsWith('/')
? lastRoute
: '/dashboard/apps';
})();
router.replace(navigateTo);
},
[setUserInfo, router, lastRoute]
);
Expand Down Expand Up @@ -94,7 +115,6 @@ const provider = () => {
return;
}

console.log('SSO', { initd, loginStore, props, state });
if (!props || !initd) return;

if (isOauthLogging) return;
Expand Down
Loading