E-300 (#19726)
Signed-off-by: -LAN- <laipz8200@outlook.com> Co-authored-by: Hash Brown <hi@xzd.me> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: GareArc <chen4851@purdue.edu> Co-authored-by: Byron.wang <byron@dify.ai> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: Garfield Dai <dai.hai@foxmail.com> Co-authored-by: KVOJJJin <jzongcode@gmail.com> Co-authored-by: Alexi.F <654973939@qq.com> Co-authored-by: Xiyuan Chen <52963600+GareArc@users.noreply.github.com> Co-authored-by: kautsar_masuara <61046989+izon-masuara@users.noreply.github.com> Co-authored-by: achmad-kautsar <achmad.kautsar@insignia.co.id> Co-authored-by: Xin Zhang <sjhpzx@gmail.com> Co-authored-by: kelvintsim <83445753+kelvintsim@users.noreply.github.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: Zixuan Cheng <61724187+Theysua@users.noreply.github.com>
This commit is contained in:
@@ -16,12 +16,15 @@ import type {
|
||||
ConversationItem,
|
||||
} from '@/models/share'
|
||||
import { noop } from 'lodash-es'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
|
||||
export type ChatWithHistoryContextValue = {
|
||||
appInfoError?: any
|
||||
appInfoLoading?: boolean
|
||||
appMeta?: AppMeta
|
||||
appData?: AppData
|
||||
accessMode?: AccessMode
|
||||
userCanAccess?: boolean
|
||||
appParams?: ChatConfig
|
||||
appChatListDataLoading?: boolean
|
||||
currentConversationId: string
|
||||
@@ -60,6 +63,8 @@ export type ChatWithHistoryContextValue = {
|
||||
}
|
||||
|
||||
export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>({
|
||||
accessMode: AccessMode.SPECIFIC_GROUPS_MEMBERS,
|
||||
userCanAccess: false,
|
||||
currentConversationId: '',
|
||||
appPrevChatTree: [],
|
||||
pinnedConversationList: [],
|
||||
|
@@ -43,6 +43,9 @@ import { useAppFavicon } from '@/hooks/use-app-favicon'
|
||||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
import { noop } from 'lodash-es'
|
||||
import { useGetAppAccessMode, useGetUserCanAccessApp } from '@/service/access-control'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
|
||||
function getFormattedChatList(messages: any[]) {
|
||||
const newChatList: ChatItem[] = []
|
||||
@@ -72,7 +75,18 @@ function getFormattedChatList(messages: any[]) {
|
||||
|
||||
export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
||||
const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo])
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR(installedAppInfo ? null : 'appInfo', fetchAppInfo)
|
||||
const { isPending: isGettingAccessMode, data: appAccessMode } = useGetAppAccessMode({
|
||||
appId: installedAppInfo?.app.id || appInfo?.app_id,
|
||||
isInstalledApp,
|
||||
enabled: systemFeatures.webapp_auth.enabled,
|
||||
})
|
||||
const { isPending: isCheckingPermission, data: userCanAccessResult } = useGetUserCanAccessApp({
|
||||
appId: installedAppInfo?.app.id || appInfo?.app_id,
|
||||
isInstalledApp,
|
||||
enabled: systemFeatures.webapp_auth.enabled,
|
||||
})
|
||||
|
||||
useAppFavicon({
|
||||
enable: !installedAppInfo,
|
||||
@@ -447,7 +461,9 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
||||
|
||||
return {
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appInfoLoading: appInfoLoading || (systemFeatures.webapp_auth.enabled && (isGettingAccessMode || isCheckingPermission)),
|
||||
accessMode: systemFeatures.webapp_auth.enabled ? appAccessMode?.accessMode : AccessMode.PUBLIC,
|
||||
userCanAccess: systemFeatures.webapp_auth.enabled ? userCanAccessResult?.result : true,
|
||||
isInstalledApp,
|
||||
appId,
|
||||
currentConversationId,
|
||||
|
@@ -20,6 +20,7 @@ import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import { checkOrSetAccessToken } from '@/app/components/share/utils'
|
||||
import AppUnavailable from '@/app/components/base/app-unavailable'
|
||||
import cn from '@/utils/classnames'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
type ChatWithHistoryProps = {
|
||||
className?: string
|
||||
@@ -28,6 +29,7 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
||||
className,
|
||||
}) => {
|
||||
const {
|
||||
userCanAccess,
|
||||
appInfoError,
|
||||
appData,
|
||||
appInfoLoading,
|
||||
@@ -45,19 +47,17 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted)
|
||||
if (site) {
|
||||
if (customConfig)
|
||||
document.title = `${site.title}`
|
||||
else
|
||||
document.title = `${site.title} - Powered by Dify`
|
||||
}
|
||||
}, [site, customConfig, themeBuilder])
|
||||
|
||||
useDocumentTitle(site?.title || 'Chat')
|
||||
|
||||
if (appInfoLoading) {
|
||||
return (
|
||||
<Loading type='app' />
|
||||
)
|
||||
}
|
||||
if (!userCanAccess)
|
||||
return <AppUnavailable code={403} unknownReason='no permission.' />
|
||||
|
||||
if (appInfoError) {
|
||||
return (
|
||||
@@ -124,6 +124,8 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
||||
const {
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
accessMode,
|
||||
userCanAccess,
|
||||
appData,
|
||||
appParams,
|
||||
appMeta,
|
||||
@@ -166,6 +168,8 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appData,
|
||||
accessMode,
|
||||
userCanAccess,
|
||||
appParams,
|
||||
appMeta,
|
||||
appChatListDataLoading,
|
||||
|
@@ -19,6 +19,8 @@ import RenameModal from '@/app/components/base/chat/chat-with-history/sidebar/re
|
||||
import DifyLogo from '@/app/components/base/logo/dify-logo'
|
||||
import type { ConversationItem } from '@/models/share'
|
||||
import cn from '@/utils/classnames'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
|
||||
type Props = {
|
||||
isPanel?: boolean
|
||||
@@ -27,6 +29,8 @@ type Props = {
|
||||
const Sidebar = ({ isPanel }: Props) => {
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
isInstalledApp,
|
||||
accessMode,
|
||||
appData,
|
||||
handleNewConversation,
|
||||
pinnedConversationList,
|
||||
@@ -44,7 +48,7 @@ const Sidebar = ({ isPanel }: Props) => {
|
||||
isResponding,
|
||||
} = useChatWithHistoryContext()
|
||||
const isSidebarCollapsed = sidebarCollapseState
|
||||
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const [showConfirm, setShowConfirm] = useState<ConversationItem | null>(null)
|
||||
const [showRename, setShowRename] = useState<ConversationItem | null>(null)
|
||||
|
||||
@@ -136,7 +140,7 @@ const Sidebar = ({ isPanel }: Props) => {
|
||||
)}
|
||||
</div>
|
||||
<div className='flex shrink-0 items-center justify-between p-3'>
|
||||
<MenuDropdown placement='top-start' data={appData?.site} />
|
||||
<MenuDropdown hideLogout={isInstalledApp || accessMode === AccessMode.PUBLIC} placement='top-start' data={appData?.site} />
|
||||
{/* powered by */}
|
||||
<div className='shrink-0'>
|
||||
{!appData?.custom_config?.remove_webapp_brand && (
|
||||
@@ -144,34 +148,33 @@ const Sidebar = ({ isPanel }: Props) => {
|
||||
'flex shrink-0 items-center gap-1.5 px-1',
|
||||
)}>
|
||||
<div className='system-2xs-medium-uppercase text-text-tertiary'>{t('share.chat.poweredBy')}</div>
|
||||
{appData?.custom_config?.replace_webapp_logo && (
|
||||
<img src={appData?.custom_config?.replace_webapp_logo} alt='logo' className='block h-5 w-auto' />
|
||||
)}
|
||||
{!appData?.custom_config?.replace_webapp_logo && (
|
||||
<DifyLogo size='small' />
|
||||
)}
|
||||
{systemFeatures.branding.enabled ? (
|
||||
<img src={systemFeatures.branding.login_page_logo} alt='logo' className='block h-5 w-auto' />
|
||||
) : (
|
||||
<DifyLogo size='small' />)
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{!!showConfirm && (
|
||||
<Confirm
|
||||
title={t('share.chat.deleteConversation.title')}
|
||||
content={t('share.chat.deleteConversation.content') || ''}
|
||||
isShow
|
||||
onCancel={handleCancelConfirm}
|
||||
onConfirm={handleDelete}
|
||||
/>
|
||||
)}
|
||||
{showRename && (
|
||||
<RenameModal
|
||||
isShow
|
||||
onClose={handleCancelRename}
|
||||
saveLoading={conversationRenaming}
|
||||
name={showRename?.name || ''}
|
||||
onSave={handleRename}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{!!showConfirm && (
|
||||
<Confirm
|
||||
title={t('share.chat.deleteConversation.title')}
|
||||
content={t('share.chat.deleteConversation.content') || ''}
|
||||
isShow
|
||||
onCancel={handleCancelConfirm}
|
||||
onConfirm={handleDelete}
|
||||
/>
|
||||
)}
|
||||
{showRename && (
|
||||
<RenameModal
|
||||
isShow
|
||||
onClose={handleCancelRename}
|
||||
saveLoading={conversationRenaming}
|
||||
name={showRename?.name || ''}
|
||||
onSave={handleRename}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@@ -15,8 +15,11 @@ import type {
|
||||
ConversationItem,
|
||||
} from '@/models/share'
|
||||
import { noop } from 'lodash-es'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
|
||||
export type EmbeddedChatbotContextValue = {
|
||||
accessMode?: AccessMode
|
||||
userCanAccess?: boolean
|
||||
appInfoError?: any
|
||||
appInfoLoading?: boolean
|
||||
appMeta?: AppMeta
|
||||
@@ -53,6 +56,8 @@ export type EmbeddedChatbotContextValue = {
|
||||
}
|
||||
|
||||
export const EmbeddedChatbotContext = createContext<EmbeddedChatbotContextValue>({
|
||||
userCanAccess: false,
|
||||
accessMode: AccessMode.SPECIFIC_GROUPS_MEMBERS,
|
||||
currentConversationId: '',
|
||||
appPrevChatList: [],
|
||||
pinnedConversationList: [],
|
||||
|
@@ -36,6 +36,9 @@ import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
import { addFileInfos, sortAgentSorts } from '@/app/components/tools/utils'
|
||||
import { noop } from 'lodash-es'
|
||||
import { useGetAppAccessMode, useGetUserCanAccessApp } from '@/service/access-control'
|
||||
import { useGlobalPublicStore } from '@/context/global-public-context'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
|
||||
function getFormattedChatList(messages: any[]) {
|
||||
const newChatList: ChatItem[] = []
|
||||
@@ -65,7 +68,18 @@ function getFormattedChatList(messages: any[]) {
|
||||
|
||||
export const useEmbeddedChatbot = () => {
|
||||
const isInstalledApp = false
|
||||
const systemFeatures = useGlobalPublicStore(s => s.systemFeatures)
|
||||
const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR('appInfo', fetchAppInfo)
|
||||
const { isPending: isGettingAccessMode, data: appAccessMode } = useGetAppAccessMode({
|
||||
appId: appInfo?.app_id,
|
||||
isInstalledApp,
|
||||
enabled: systemFeatures.webapp_auth.enabled,
|
||||
})
|
||||
const { isPending: isCheckingPermission, data: userCanAccessResult } = useGetUserCanAccessApp({
|
||||
appId: appInfo?.app_id,
|
||||
isInstalledApp,
|
||||
enabled: systemFeatures.webapp_auth.enabled,
|
||||
})
|
||||
|
||||
const appData = useMemo(() => {
|
||||
return appInfo
|
||||
@@ -364,7 +378,9 @@ export const useEmbeddedChatbot = () => {
|
||||
|
||||
return {
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appInfoLoading: appInfoLoading || (systemFeatures.webapp_auth.enabled && (isGettingAccessMode || isCheckingPermission)),
|
||||
accessMode: systemFeatures.webapp_auth.enabled ? appAccessMode?.accessMode : AccessMode.PUBLIC,
|
||||
userCanAccess: systemFeatures.webapp_auth.enabled ? userCanAccessResult?.result : true,
|
||||
isInstalledApp,
|
||||
allowResetChat,
|
||||
appId,
|
||||
|
@@ -21,9 +21,11 @@ import Header from '@/app/components/base/chat/embedded-chatbot/header'
|
||||
import ChatWrapper from '@/app/components/base/chat/embedded-chatbot/chat-wrapper'
|
||||
import DifyLogo from '@/app/components/base/logo/dify-logo'
|
||||
import cn from '@/utils/classnames'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
const Chatbot = () => {
|
||||
const {
|
||||
userCanAccess,
|
||||
isMobile,
|
||||
allowResetChat,
|
||||
appInfoError,
|
||||
@@ -43,14 +45,10 @@ const Chatbot = () => {
|
||||
|
||||
useEffect(() => {
|
||||
themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted)
|
||||
if (site) {
|
||||
if (customConfig)
|
||||
document.title = `${site.title}`
|
||||
else
|
||||
document.title = `${site.title} - Powered by Dify`
|
||||
}
|
||||
}, [site, customConfig, themeBuilder])
|
||||
|
||||
useDocumentTitle(site?.title || 'Chat')
|
||||
|
||||
if (appInfoLoading) {
|
||||
return (
|
||||
<>
|
||||
@@ -66,6 +64,9 @@ const Chatbot = () => {
|
||||
)
|
||||
}
|
||||
|
||||
if (!userCanAccess)
|
||||
return <AppUnavailable code={403} unknownReason='no permission.' />
|
||||
|
||||
if (appInfoError) {
|
||||
return (
|
||||
<>
|
||||
@@ -137,6 +138,8 @@ const EmbeddedChatbotWrapper = () => {
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appData,
|
||||
accessMode,
|
||||
userCanAccess,
|
||||
appParams,
|
||||
appMeta,
|
||||
appChatListDataLoading,
|
||||
@@ -168,6 +171,8 @@ const EmbeddedChatbotWrapper = () => {
|
||||
} = useEmbeddedChatbot()
|
||||
|
||||
return <EmbeddedChatbotContext.Provider value={{
|
||||
userCanAccess,
|
||||
accessMode,
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appData,
|
||||
|
Reference in New Issue
Block a user