diff --git a/web/app/(shareLayout)/webapp-signin/page.tsx b/web/app/(shareLayout)/webapp-signin/page.tsx index 6c00b46e90..d8a1267c6f 100644 --- a/web/app/(shareLayout)/webapp-signin/page.tsx +++ b/web/app/(shareLayout)/webapp-signin/page.tsx @@ -11,6 +11,7 @@ import { setAccessToken } from '@/app/components/share/utils' import Button from '@/app/components/base/button' import { useGlobalPublicStore } from '@/context/global-public-context' import { SSOProtocol } from '@/types/feature' +import Loading from '@/app/components/base/loading' const WebSSOForm: FC = () => { const { t } = useTranslation() @@ -91,6 +92,9 @@ const WebSSOForm: FC = () => { init() }, [message, processTokenAndRedirect, tokenFromUrl]) + if (tokenFromUrl) + return
+ if (systemFeatures.webapp_auth.enabled) { if (systemFeatures.webapp_auth.allow_sso) { return ( diff --git a/web/app/components/app-sidebar/app-info.tsx b/web/app/components/app-sidebar/app-info.tsx index f3621d3018..b14a6b5e47 100644 --- a/web/app/components/app-sidebar/app-info.tsx +++ b/web/app/components/app-sidebar/app-info.tsx @@ -177,7 +177,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => { }) } setShowConfirmDelete(false) - }, [appDetail, mutateApps, notify, onPlanInfoChanged, replace, t]) + }, [appDetail, mutateApps, notify, onPlanInfoChanged, replace, setAppDetail, t]) const handleClickAccessControl = useCallback(() => { if (!appDetail) @@ -480,7 +480,9 @@ const AppInfo = ({ expand }: IAppInfoProps) => { /> )} { - showAccessControl && { setShowAccessControl(false) }} /> + showAccessControl && { setShowAccessControl(false) }} + onClose={() => { setShowAccessControl(false) }} /> } diff --git a/web/app/components/app/app-access-control/specific-groups-or-members.tsx b/web/app/components/app/app-access-control/specific-groups-or-members.tsx index 272fb3b9cb..0fb3173d6e 100644 --- a/web/app/components/app/app-access-control/specific-groups-or-members.tsx +++ b/web/app/components/app/app-access-control/specific-groups-or-members.tsx @@ -1,7 +1,7 @@ 'use client' import { RiAlertFill, RiCloseCircleFill, RiLockLine, RiOrganizationChart } from '@remixicon/react' import { useTranslation } from 'react-i18next' -import { useEffect } from 'react' +import { useCallback, useEffect } from 'react' import Avatar from '../../base/avatar' import Divider from '../../base/divider' import Tooltip from '../../base/tooltip' @@ -85,7 +85,13 @@ type GroupItemProps = { group: AccessControlGroup } function GroupItem({ group }: GroupItemProps) { - return }> + const specificGroups = useAccessControlStore(s => s.specificGroups) + const setSpecificGroups = useAccessControlStore(s => s.setSpecificGroups) + const handleRemoveGroup = useCallback(() => { + setSpecificGroups(specificGroups.filter(g => g.id !== group.id)) + }, [group, setSpecificGroups, specificGroups]) + return } + onRemove={handleRemoveGroup}>

{group.name}

{group.groupSize}

@@ -95,7 +101,13 @@ type MemberItemProps = { member: AccessControlAccount } function MemberItem({ member }: MemberItemProps) { - return }> + const specificMembers = useAccessControlStore(s => s.specificMembers) + const setSpecificMembers = useAccessControlStore(s => s.setSpecificMembers) + const handleRemoveMember = useCallback(() => { + setSpecificMembers(specificMembers.filter(m => m.id !== member.id)) + }, [member, setSpecificMembers, specificMembers]) + return } + onRemove={handleRemoveMember}>

{member.name}

} @@ -103,8 +115,9 @@ function MemberItem({ member }: MemberItemProps) { type BaseItemProps = { icon: React.ReactNode children: React.ReactNode + onRemove?: () => void } -function BaseItem({ icon, children }: BaseItemProps) { +function BaseItem({ icon, onRemove, children }: BaseItemProps) { return
@@ -112,7 +125,7 @@ function BaseItem({ icon, children }: BaseItemProps) {
{children} -
+
diff --git a/web/service/base.ts b/web/service/base.ts index 5798af1bbf..b6c006842b 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -512,7 +512,16 @@ export const ssePost = ( }).catch(() => { res.json().then((data: any) => { if (isPublicAPI) { - if (data.code === 'web_sso_auth_required' || data.code === 'web_app_access_denied') + if (data.code === 'web_app_access_denied') { + Toast.notify({ + type: 'error', + message: data.message, + }) + setTimeout(() => { + requiredWebSSOLogin() + }, 1500) + } + if (data.code === 'web_sso_auth_required') requiredWebSSOLogin() if (data.code === 'unauthorized') { @@ -566,7 +575,17 @@ export const request = async(url: string, options = {}, otherOptions?: IOther // special code const { code, message } = errRespData // webapp sso - if (code === 'web_sso_auth_required' || code === 'web_app_access_denied') { + if (code === 'web_app_access_denied') { + Toast.notify({ + type: 'error', + message, + }) + setTimeout(() => { + requiredWebSSOLogin() + }, 1500) + return Promise.reject(err) + } + if (code === 'web_sso_auth_required') { requiredWebSSOLogin() return Promise.reject(err) }