Co-authored-by: qingguo <qingguo@lexin.com>tags/1.4.1
| # different from api or web app domain. | # different from api or web app domain. | ||||
| # example: http://cloud.dify.ai/console/api | # example: http://cloud.dify.ai/console/api | ||||
| NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api | NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api | ||||
| NEXT_PUBLIC_WEB_PREFIX=http://localhost:3000 | |||||
| # The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from | # The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from | ||||
| # console or api domain. | # console or api domain. | ||||
| # example: http://udify.app/api | # example: http://udify.app/api | ||||
| NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api | NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api | ||||
| NEXT_PUBLIC_PUBLIC_WEB_PREFIX=http://localhost:3000 | |||||
| # The API PREFIX for MARKETPLACE | # The API PREFIX for MARKETPLACE | ||||
| NEXT_PUBLIC_MARKETPLACE_API_PREFIX=https://marketplace.dify.ai/api/v1 | NEXT_PUBLIC_MARKETPLACE_API_PREFIX=https://marketplace.dify.ai/api/v1 | ||||
| # The URL for MARKETPLACE | # The URL for MARKETPLACE |
| # different from api or web app domain. | # different from api or web app domain. | ||||
| # example: http://cloud.dify.ai/console/api | # example: http://cloud.dify.ai/console/api | ||||
| NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api | NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api | ||||
| NEXT_PUBLIC_WEB_PREFIX=http://localhost:3000 | |||||
| # The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from | # The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from | ||||
| # console or api domain. | # console or api domain. | ||||
| # example: http://udify.app/api | # example: http://udify.app/api | ||||
| NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api | NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api | ||||
| NEXT_PUBLIC_PUBLIC_WEB_PREFIX=http://localhost:3000 | |||||
| # SENTRY | # SENTRY | ||||
| NEXT_PUBLIC_SENTRY_DSN= | NEXT_PUBLIC_SENTRY_DSN= |
| import type { HtmlContentProps } from '@/app/components/base/popover' | import type { HtmlContentProps } from '@/app/components/base/popover' | ||||
| import CustomPopover from '@/app/components/base/popover' | import CustomPopover from '@/app/components/base/popover' | ||||
| import Divider from '@/app/components/base/divider' | import Divider from '@/app/components/base/divider' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| import { getRedirection } from '@/utils/app-redirection' | import { getRedirection } from '@/utils/app-redirection' | ||||
| import { useProviderContext } from '@/context/provider-context' | import { useProviderContext } from '@/context/provider-context' | ||||
| import { NEED_REFRESH_APP_LIST_KEY } from '@/config' | import { NEED_REFRESH_APP_LIST_KEY } from '@/config' | ||||
| try { | try { | ||||
| const { installed_apps }: any = await fetchInstalledAppList(app.id) || {} | const { installed_apps }: any = await fetchInstalledAppList(app.id) || {} | ||||
| if (installed_apps?.length > 0) | if (installed_apps?.length > 0) | ||||
| window.open(`${WEB_PREFIX}/explore/installed/${installed_apps[0].id}`, '_blank') | |||||
| window.open(`${basePath}/explore/installed/${installed_apps[0].id}`, '_blank') | |||||
| else | else | ||||
| throw new Error('No app found in Explore') | throw new Error('No app found in Explore') | ||||
| } | } |
| 'use client' | 'use client' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import Link from 'next/link' | |||||
| import { basePath } from '@/utils/var' | |||||
| import { | import { | ||||
| RiAddLine, | RiAddLine, | ||||
| RiArrowRightLine, | RiArrowRightLine, | ||||
| <div className='bg-background-default-dimm flex min-h-[160px] flex-col rounded-xl border-[0.5px] | <div className='bg-background-default-dimm flex min-h-[160px] flex-col rounded-xl border-[0.5px] | ||||
| border-components-panel-border transition-all duration-200 ease-in-out' | border-components-panel-border transition-all duration-200 ease-in-out' | ||||
| > | > | ||||
| <Link ref={ref} className='group flex grow cursor-pointer items-start p-4' href={'/datasets/create'}> | |||||
| <a ref={ref} className='group flex grow cursor-pointer items-start p-4' href={`${basePath}/datasets/create`}> | |||||
| <div className='flex items-center gap-3'> | <div className='flex items-center gap-3'> | ||||
| <div className='flex h-10 w-10 items-center justify-center rounded-lg border border-dashed border-divider-regular bg-background-default-lighter | <div className='flex h-10 w-10 items-center justify-center rounded-lg border border-dashed border-divider-regular bg-background-default-lighter | ||||
| p-2 group-hover:border-solid group-hover:border-effects-highlight group-hover:bg-background-default-dodge' | p-2 group-hover:border-solid group-hover:border-effects-highlight group-hover:bg-background-default-dodge' | ||||
| </div> | </div> | ||||
| <div className='system-md-semibold text-text-secondary group-hover:text-text-accent'>{t('dataset.createDataset')}</div> | <div className='system-md-semibold text-text-secondary group-hover:text-text-accent'>{t('dataset.createDataset')}</div> | ||||
| </div> | </div> | ||||
| </Link> | |||||
| </a> | |||||
| <div className='system-xs-regular p-4 pt-0 text-text-tertiary'>{t('dataset.createDatasetIntro')}</div> | <div className='system-xs-regular p-4 pt-0 text-text-tertiary'>{t('dataset.createDatasetIntro')}</div> | ||||
| <Link className='group flex cursor-pointer items-center gap-1 rounded-b-xl border-t-[0.5px] border-divider-subtle p-4' href={'datasets/connect'}> | |||||
| <a className='group flex cursor-pointer items-center gap-1 rounded-b-xl border-t-[0.5px] border-divider-subtle p-4' href={`${basePath}/datasets/connect`}> | |||||
| <div className='system-xs-medium text-text-tertiary group-hover:text-text-accent'>{t('dataset.connectDataset')}</div> | <div className='system-xs-medium text-text-tertiary group-hover:text-text-accent'>{t('dataset.connectDataset')}</div> | ||||
| <RiArrowRightLine className='h-3.5 w-3.5 text-text-tertiary group-hover:text-text-accent' /> | <RiArrowRightLine className='h-3.5 w-3.5 text-text-tertiary group-hover:text-text-accent' /> | ||||
| </Link> | |||||
| </a> | |||||
| </div> | </div> | ||||
| ) | ) | ||||
| } | } |
| PortalToFollowElemContent, | PortalToFollowElemContent, | ||||
| PortalToFollowElemTrigger, | PortalToFollowElemTrigger, | ||||
| } from '@/app/components/base/portal-to-follow-elem' | } from '@/app/components/base/portal-to-follow-elem' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| import { fetchInstalledAppList } from '@/service/explore' | import { fetchInstalledAppList } from '@/service/explore' | ||||
| import EmbeddedModal from '@/app/components/app/overview/embedded' | import EmbeddedModal from '@/app/components/app/overview/embedded' | ||||
| import { useStore as useAppStore } from '@/app/components/app/store' | import { useStore as useAppStore } from '@/app/components/app/store' | ||||
| const appDetail = useAppStore(state => state.appDetail) | const appDetail = useAppStore(state => state.appDetail) | ||||
| const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {} | const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {} | ||||
| const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode | const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode | ||||
| const appURL = `${appBaseURL}/${appMode}/${accessToken}` | |||||
| const appURL = `${appBaseURL}${basePath}/${appMode}/${accessToken}` | |||||
| const isChatApp = ['chat', 'agent-chat', 'completion'].includes(appDetail?.mode || '') | const isChatApp = ['chat', 'agent-chat', 'completion'].includes(appDetail?.mode || '') | ||||
| const language = useGetLanguage() | const language = useGetLanguage() | ||||
| try { | try { | ||||
| const { installed_apps }: any = await fetchInstalledAppList(appDetail?.id) || {} | const { installed_apps }: any = await fetchInstalledAppList(appDetail?.id) || {} | ||||
| if (installed_apps?.length > 0) | if (installed_apps?.length > 0) | ||||
| window.open(`${WEB_PREFIX}/explore/installed/${installed_apps[0].id}`, '_blank') | |||||
| window.open(`${basePath}/explore/installed/${installed_apps[0].id}`, '_blank') | |||||
| else | else | ||||
| throw new Error('No app found in Explore') | throw new Error('No app found in Explore') | ||||
| } | } |
| import Badge from '@/app/components/base/badge' | import Badge from '@/app/components/base/badge' | ||||
| import { useKnowledge } from '@/hooks/use-knowledge' | import { useKnowledge } from '@/hooks/use-knowledge' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { basePath } from '@/utils/var' | |||||
| export type ISelectDataSetProps = { | export type ISelectDataSetProps = { | ||||
| isShow: boolean | isShow: boolean | ||||
| }} | }} | ||||
| > | > | ||||
| <span className='text-text-tertiary'>{t('appDebug.feature.dataSet.noDataSet')}</span> | <span className='text-text-tertiary'>{t('appDebug.feature.dataSet.noDataSet')}</span> | ||||
| <Link href={'/datasets/create'} className='font-normal text-text-accent'>{t('appDebug.feature.dataSet.toCreate')}</Link> | |||||
| <Link href={`${basePath}/datasets/create`} className='font-normal text-text-accent'>{t('appDebug.feature.dataSet.toCreate')}</Link> | |||||
| </div> | </div> | ||||
| )} | )} | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import Divider from '@/app/components/base/divider' | import Divider from '@/app/components/base/divider' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| import AppsContext, { useAppContext } from '@/context/app-context' | import AppsContext, { useAppContext } from '@/context/app-context' | ||||
| import { useProviderContext } from '@/context/provider-context' | import { useProviderContext } from '@/context/provider-context' | ||||
| import { ToastContext } from '@/app/components/base/toast' | import { ToastContext } from '@/app/components/base/toast' | ||||
| 'workflow': 'Workflow', | 'workflow': 'Workflow', | ||||
| } | } | ||||
| return <picture> | return <picture> | ||||
| <source media="(resolution: 1x)" srcSet={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}.png`} /> | |||||
| <source media="(resolution: 2x)" srcSet={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}@2x.png`} /> | |||||
| <source media="(resolution: 3x)" srcSet={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}@3x.png`} /> | |||||
| <source media="(resolution: 1x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}.png`} /> | |||||
| <source media="(resolution: 2x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}@2x.png`} /> | |||||
| <source media="(resolution: 3x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}@3x.png`} /> | |||||
| <Image className={show ? '' : 'hidden'} | <Image className={show ? '' : 'hidden'} | ||||
| src={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}.png`} | |||||
| src={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}.png`} | |||||
| alt='App Screen Shot' | alt='App Screen Shot' | ||||
| width={664} height={448} /> | width={664} height={448} /> | ||||
| </picture> | </picture> |
| import { useDebounce } from 'ahooks' | import { useDebounce } from 'ahooks' | ||||
| import { omit } from 'lodash-es' | import { omit } from 'lodash-es' | ||||
| import dayjs from 'dayjs' | import dayjs from 'dayjs' | ||||
| import { basePath } from '@/utils/var' | |||||
| import { Trans, useTranslation } from 'react-i18next' | import { Trans, useTranslation } from 'react-i18next' | ||||
| import List from './list' | import List from './list' | ||||
| import Filter, { TIME_PERIOD_MAPPING } from './filter' | import Filter, { TIME_PERIOD_MAPPING } from './filter' | ||||
| ? <Loading type='app' /> | ? <Loading type='app' /> | ||||
| : total > 0 | : total > 0 | ||||
| ? <List logs={isChatMode ? chatConversations : completionConversations} appDetail={appDetail} onRefresh={isChatMode ? mutateChatList : mutateCompletionList} /> | ? <List logs={isChatMode ? chatConversations : completionConversations} appDetail={appDetail} onRefresh={isChatMode ? mutateChatList : mutateCompletionList} /> | ||||
| : <EmptyElement appUrl={`${appDetail.site.app_base_url}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} /> | |||||
| : <EmptyElement appUrl={`${appDetail.site.app_base_url}${basePath}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} /> | |||||
| } | } | ||||
| {/* Show Pagination only if the total is more than the limit */} | {/* Show Pagination only if the total is more than the limit */} | ||||
| {(total && total > APP_PAGE_LIMIT) | {(total && total > APP_PAGE_LIMIT) |
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import AppBasic from '@/app/components/app-sidebar/basic' | import AppBasic from '@/app/components/app-sidebar/basic' | ||||
| import { asyncRunSafe, randomString } from '@/utils' | import { asyncRunSafe, randomString } from '@/utils' | ||||
| import { basePath } from '@/utils/var' | |||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import Switch from '@/app/components/base/switch' | import Switch from '@/app/components/base/switch' | ||||
| import Divider from '@/app/components/base/divider' | import Divider from '@/app/components/base/divider' | ||||
| const runningStatus = isApp ? appInfo.enable_site : appInfo.enable_api | const runningStatus = isApp ? appInfo.enable_site : appInfo.enable_api | ||||
| const { app_base_url, access_token } = appInfo.site ?? {} | const { app_base_url, access_token } = appInfo.site ?? {} | ||||
| const appMode = (appInfo.mode !== 'completion' && appInfo.mode !== 'workflow') ? 'chat' : appInfo.mode | const appMode = (appInfo.mode !== 'completion' && appInfo.mode !== 'workflow') ? 'chat' : appInfo.mode | ||||
| const appUrl = `${app_base_url}/${appMode}/${access_token}` | |||||
| const appUrl = `${app_base_url}${basePath}/${appMode}/${access_token}` | |||||
| const apiUrl = appInfo?.api_base_url | const apiUrl = appInfo?.api_base_url | ||||
| const genClickFuncByName = (opName: string) => { | const genClickFuncByName = (opName: string) => { |
| import type { SiteInfo } from '@/models/share' | import type { SiteInfo } from '@/models/share' | ||||
| import { useThemeContext } from '@/app/components/base/chat/embedded-chatbot/theme/theme-context' | import { useThemeContext } from '@/app/components/base/chat/embedded-chatbot/theme/theme-context' | ||||
| import ActionButton from '@/app/components/base/action-button' | import ActionButton from '@/app/components/base/action-button' | ||||
| import { basePath } from '@/utils/var' | |||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| type Props = { | type Props = { | ||||
| iframe: { | iframe: { | ||||
| getContent: (url: string, token: string) => | getContent: (url: string, token: string) => | ||||
| `<iframe | `<iframe | ||||
| src="${url}/chatbot/${token}" | |||||
| src="${url}${basePath}/chatbot/${token}" | |||||
| style="width: 100%; height: 100%; min-height: 700px" | style="width: 100%; height: 100%; min-height: 700px" | ||||
| frameborder="0" | frameborder="0" | ||||
| allow="microphone"> | allow="microphone"> | ||||
| isDev: true` | isDev: true` | ||||
| : ''}${IS_CE_EDITION | : ''}${IS_CE_EDITION | ||||
| ? `, | ? `, | ||||
| baseUrl: '${url}'` | |||||
| baseUrl: '${url}${basePath}'` | |||||
| : ''}, | : ''}, | ||||
| systemVariables: { | systemVariables: { | ||||
| // user_id: 'YOU CAN DEFINE USER ID HERE', | // user_id: 'YOU CAN DEFINE USER ID HERE', | ||||
| } | } | ||||
| </script> | </script> | ||||
| <script | <script | ||||
| src="${url}/embed.min.js" | |||||
| src="${url}${basePath}/embed.min.js" | |||||
| id="${token}" | id="${token}" | ||||
| defer> | defer> | ||||
| </script> | </script> | ||||
| </style>`, | </style>`, | ||||
| }, | }, | ||||
| chromePlugin: { | chromePlugin: { | ||||
| getContent: (url: string, token: string) => `ChatBot URL: ${url}/chatbot/${token}`, | |||||
| getContent: (url: string, token: string) => `ChatBot URL: ${url}${basePath}/chatbot/${token}`, | |||||
| }, | }, | ||||
| } | } | ||||
| const prefixEmbedded = 'appOverview.overview.appInfo.embedded' | const prefixEmbedded = 'appOverview.overview.appInfo.embedded' |
| import { Trans, useTranslation } from 'react-i18next' | import { Trans, useTranslation } from 'react-i18next' | ||||
| import Link from 'next/link' | import Link from 'next/link' | ||||
| import List from './list' | import List from './list' | ||||
| import { basePath } from '@/utils/var' | |||||
| import Filter, { TIME_PERIOD_MAPPING } from './filter' | import Filter, { TIME_PERIOD_MAPPING } from './filter' | ||||
| import Pagination from '@/app/components/base/pagination' | import Pagination from '@/app/components/base/pagination' | ||||
| import Loading from '@/app/components/base/loading' | import Loading from '@/app/components/base/loading' | ||||
| ? <Loading type='app' /> | ? <Loading type='app' /> | ||||
| : total > 0 | : total > 0 | ||||
| ? <List logs={workflowLogs} appDetail={appDetail} onRefresh={mutate} /> | ? <List logs={workflowLogs} appDetail={appDetail} onRefresh={mutate} /> | ||||
| : <EmptyElement appUrl={`${appDetail.site.app_base_url}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} /> | |||||
| : <EmptyElement appUrl={`${appDetail.site.app_base_url}${basePath}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} /> | |||||
| } | } | ||||
| {/* Show Pagination only if the total is more than the limit */} | {/* Show Pagination only if the total is more than the limit */} | ||||
| {(total && total > APP_PAGE_LIMIT) | {(total && total > APP_PAGE_LIMIT) |
| 'use client' | 'use client' | ||||
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import classNames from '@/utils/classnames' | import classNames from '@/utils/classnames' | ||||
| import useTheme from '@/hooks/use-theme' | import useTheme from '@/hooks/use-theme' | ||||
| import { basePath } from '@/utils/var' | |||||
| export type LogoStyle = 'default' | 'monochromeWhite' | export type LogoStyle = 'default' | 'monochromeWhite' | ||||
| return ( | return ( | ||||
| <img | <img | ||||
| src={`${WEB_PREFIX}${logoPathMap[themedStyle]}`} | |||||
| src={`${basePath}${logoPathMap[themedStyle]}`} | |||||
| className={classNames('block object-contain', logoSizeMap[size], className)} | className={classNames('block object-contain', logoSizeMap[size], className)} | ||||
| alt='Dify logo' | alt='Dify logo' | ||||
| /> | /> |
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| type LogoEmbeddedChatAvatarProps = { | type LogoEmbeddedChatAvatarProps = { | ||||
| className?: string | className?: string | ||||
| }) => { | }) => { | ||||
| return ( | return ( | ||||
| <img | <img | ||||
| src={`${WEB_PREFIX}/logo/logo-embedded-chat-avatar.png`} | |||||
| src={`${basePath}/logo/logo-embedded-chat-avatar.png`} | |||||
| className={`block h-10 w-10 ${className}`} | className={`block h-10 w-10 ${className}`} | ||||
| alt='logo' | alt='logo' | ||||
| /> | /> |
| import classNames from '@/utils/classnames' | import classNames from '@/utils/classnames' | ||||
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| type LogoEmbeddedChatHeaderProps = { | type LogoEmbeddedChatHeaderProps = { | ||||
| className?: string | className?: string | ||||
| <source media="(resolution: 2x)" srcSet='/logo/logo-embedded-chat-header@2x.png' /> | <source media="(resolution: 2x)" srcSet='/logo/logo-embedded-chat-header@2x.png' /> | ||||
| <source media="(resolution: 3x)" srcSet='/logo/logo-embedded-chat-header@3x.png' /> | <source media="(resolution: 3x)" srcSet='/logo/logo-embedded-chat-header@3x.png' /> | ||||
| <img | <img | ||||
| src={`${WEB_PREFIX}/logo/logo-embedded-chat-header.png`} | |||||
| src={`${basePath}/logo/logo-embedded-chat-header.png`} | |||||
| alt='logo' | alt='logo' | ||||
| className={classNames('block h-6 w-auto', className)} | className={classNames('block h-6 w-auto', className)} | ||||
| /> | /> |
| 'use client' | |||||
| import type { FC } from 'react' | |||||
| import { basePath } from '@/utils/var' | |||||
| import classNames from '@/utils/classnames' | |||||
| type LogoSiteProps = { | |||||
| className?: string | |||||
| } | |||||
| const LogoSite: FC<LogoSiteProps> = ({ | |||||
| className, | |||||
| }) => { | |||||
| return ( | |||||
| <img | |||||
| src={`${basePath}/logo/logo.png`} | |||||
| className={classNames('block w-[22.651px] h-[24.5px]', className)} | |||||
| alt='logo' | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default LogoSite |
| import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react' | import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react' | ||||
| import { RiArrowDownSLine } from '@remixicon/react' | import { RiArrowDownSLine } from '@remixicon/react' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| import PlanBadge from '@/app/components/header/plan-badge' | import PlanBadge from '@/app/components/header/plan-badge' | ||||
| import { switchWorkspace } from '@/service/common' | import { switchWorkspace } from '@/service/common' | ||||
| import { useWorkspacesContext } from '@/context/workspace-context' | import { useWorkspacesContext } from '@/context/workspace-context' | ||||
| return | return | ||||
| await switchWorkspace({ url: '/workspaces/switch', body: { tenant_id } }) | await switchWorkspace({ url: '/workspaces/switch', body: { tenant_id } }) | ||||
| notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) | notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) | ||||
| location.assign(WEB_PREFIX) | |||||
| location.assign(`${location.origin}${basePath}`) | |||||
| } | } | ||||
| catch { | catch { | ||||
| notify({ type: 'error', message: t('common.provider.saveFailed') }) | notify({ type: 'error', message: t('common.provider.saveFailed') }) |
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import Input from '@/app/components/base/input' | import Input from '@/app/components/base/input' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useState } from 'react' | import { useState } from 'react' | ||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| }, | }, | ||||
| }) | }) | ||||
| notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) | notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) | ||||
| location.assign(WEB_PREFIX) | |||||
| location.assign(`${location.origin}`) | |||||
| } | } | ||||
| catch { | catch { | ||||
| notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) | notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') }) |
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import type { ModelProvider } from '../declarations' | import type { ModelProvider } from '../declarations' | ||||
| import { basePath } from '@/utils/var' | |||||
| import { useLanguage } from '../hooks' | import { useLanguage } from '../hooks' | ||||
| import { Openai } from '@/app/components/base/icons/src/vender/other' | import { Openai } from '@/app/components/base/icons/src/vender/other' | ||||
| import { AnthropicDark, AnthropicLight } from '@/app/components/base/icons/src/public/llm' | import { AnthropicDark, AnthropicLight } from '@/app/components/base/icons/src/public/llm' | ||||
| <div className={cn('inline-flex items-center gap-2', className)}> | <div className={cn('inline-flex items-center gap-2', className)}> | ||||
| <img | <img | ||||
| alt='provider-icon' | alt='provider-icon' | ||||
| src={renderI18nObject(provider.icon_small, language)} | |||||
| src={basePath + renderI18nObject(provider.icon_small, language)} | |||||
| className='h-6 w-6' | className='h-6 w-6' | ||||
| /> | /> | ||||
| <div className='system-md-semibold text-text-primary'> | <div className='system-md-semibold text-text-primary'> |
| import type { NavItem } from '../nav/nav-selector' | import type { NavItem } from '../nav/nav-selector' | ||||
| import { fetchDatasetDetail, fetchDatasets } from '@/service/datasets' | import { fetchDatasetDetail, fetchDatasets } from '@/service/datasets' | ||||
| import type { DataSetListResponse } from '@/models/datasets' | import type { DataSetListResponse } from '@/models/datasets' | ||||
| import { basePath } from '@/utils/var' | |||||
| const getKey = (pageIndex: number, previousPageData: DataSetListResponse) => { | const getKey = (pageIndex: number, previousPageData: DataSetListResponse) => { | ||||
| if (!pageIndex || previousPageData.has_more) | if (!pageIndex || previousPageData.has_more) | ||||
| icon_background: dataset.icon_background, | icon_background: dataset.icon_background, | ||||
| })) as NavItem[]} | })) as NavItem[]} | ||||
| createText={t('common.menus.newDataset')} | createText={t('common.menus.newDataset')} | ||||
| onCreate={() => router.push('/datasets/create')} | |||||
| onCreate={() => router.push(`${basePath}/datasets/create`)} | |||||
| onLoadmore={handleLoadmore} | onLoadmore={handleLoadmore} | ||||
| /> | /> | ||||
| ) | ) |
| memo, | memo, | ||||
| useCallback, | useCallback, | ||||
| } from 'react' | } from 'react' | ||||
| import Link from 'next/link' | |||||
| import { basePath } from '@/utils/var' | |||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { | import { | ||||
| RiAddLine, | RiAddLine, | ||||
| > | > | ||||
| <div className='flex h-[22px] w-full items-center justify-between pl-3 pr-1 text-xs font-medium text-gray-500'> | <div className='flex h-[22px] w-full items-center justify-between pl-3 pr-1 text-xs font-medium text-gray-500'> | ||||
| {toolWithProvider.label[language]} | {toolWithProvider.label[language]} | ||||
| <Link className='hidden cursor-pointer items-center group-hover:flex' href={`/tools?category=${toolWithProvider.type}`} target='_blank'>{t('tools.addToolModal.manageInTools')}<ArrowUpRight className='ml-0.5 h-3 w-3' /></Link> | |||||
| <a className='hidden cursor-pointer items-center group-hover:flex' href={`${basePath}/tools?category=${toolWithProvider.type}`} target='_blank'>{t('tools.addToolModal.manageInTools')}<ArrowUpRight className='ml-0.5 h-3 w-3' /></a> | |||||
| </div> | </div> | ||||
| {list.map((tool) => { | {list.map((tool) => { | ||||
| const labelContent = (() => { | const labelContent = (() => { |
| RiCloseLine, | RiCloseLine, | ||||
| } from '@remixicon/react' | } from '@remixicon/react' | ||||
| import { AuthHeaderPrefix, AuthType, CollectionType } from '../types' | import { AuthHeaderPrefix, AuthType, CollectionType } from '../types' | ||||
| import Link from 'next/link' | |||||
| import { basePath } from '@/utils/var' | |||||
| import type { Collection, CustomCollectionBackend, Tool, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '../types' | import type { Collection, CustomCollectionBackend, Tool, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '../types' | ||||
| import ToolItem from './tool-item' | import ToolItem from './tool-item' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| variant='primary' | variant='primary' | ||||
| className={cn('my-3 w-[183px] shrink-0')} | className={cn('my-3 w-[183px] shrink-0')} | ||||
| > | > | ||||
| <Link className='flex items-center' href={`/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'> | |||||
| <a className='flex items-center' href={`${basePath}/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'> | |||||
| <div className='system-sm-medium'>{t('tools.openInStudio')}</div> | <div className='system-sm-medium'>{t('tools.openInStudio')}</div> | ||||
| <LinkExternal02 className='ml-1 h-4 w-4' /> | <LinkExternal02 className='ml-1 h-4 w-4' /> | ||||
| </Link> | |||||
| </a> | |||||
| </Button> | </Button> | ||||
| <Button | <Button | ||||
| className={cn('my-3 w-[183px] shrink-0')} | className={cn('my-3 w-[183px] shrink-0')} |
| import Editor, { loader } from '@monaco-editor/react' | import Editor, { loader } from '@monaco-editor/react' | ||||
| import React, { useEffect, useMemo, useRef, useState } from 'react' | import React, { useEffect, useMemo, useRef, useState } from 'react' | ||||
| import Base from '../base' | import Base from '../base' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' | import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' | ||||
| import { | import { | ||||
| import useTheme from '@/hooks/use-theme' | import useTheme from '@/hooks/use-theme' | ||||
| import './style.css' | import './style.css' | ||||
| import { noop } from 'lodash-es' | import { noop } from 'lodash-es' | ||||
| import { basePath } from '@/utils/var' | |||||
| // load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482 | // load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482 | ||||
| loader.config({ paths: { vs: `${WEB_PREFIX}/vs` } }) | |||||
| loader.config({ paths: { vs: `${basePath}/vs` } }) | |||||
| const CODE_EDITOR_LINE_HEIGHT = 18 | const CODE_EDITOR_LINE_HEIGHT = 18 | ||||
| 'transition-all duration-200', | 'transition-all duration-200', | ||||
| expandedIterations[index] | expandedIterations[index] | ||||
| ? 'opacity-100' | ? 'opacity-100' | ||||
| : 'max-h-0 overflow-hidden opacity-0', | |||||
| : 'max-h-0 opacity-0 overflow-hidden', | |||||
| )}> | )}> | ||||
| <TracingPanel | <TracingPanel | ||||
| list={iteration} | list={iteration} |
| 'transition-all duration-200', | 'transition-all duration-200', | ||||
| expandedLoops[index] | expandedLoops[index] | ||||
| ? 'opacity-100' | ? 'opacity-100' | ||||
| : 'max-h-0 overflow-hidden opacity-0', | |||||
| : 'max-h-0 opacity-0 overflow-hidden', | |||||
| )}> | )}> | ||||
| { | { | ||||
| loopVariableMap?.[index] && ( | loopVariableMap?.[index] && ( |
| 'transition-all duration-200', | 'transition-all duration-200', | ||||
| expandedLoops[index] | expandedLoops[index] | ||||
| ? 'opacity-100' | ? 'opacity-100' | ||||
| : 'max-h-0 overflow-hidden opacity-0', | |||||
| : 'max-h-0 opacity-0 overflow-hidden', | |||||
| )}> | )}> | ||||
| <TracingPanel | <TracingPanel | ||||
| list={loop} | list={loop} |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import useSWR from 'swr' | import useSWR from 'swr' | ||||
| import { useSearchParams } from 'next/navigation' | import { useSearchParams } from 'next/navigation' | ||||
| import Link from 'next/link' | |||||
| import { basePath } from '@/utils/var' | |||||
| import cn from 'classnames' | import cn from 'classnames' | ||||
| import { CheckCircleIcon } from '@heroicons/react/24/solid' | import { CheckCircleIcon } from '@heroicons/react/24/solid' | ||||
| import Input from '../components/base/input' | import Input from '../components/base/input' | ||||
| </div> | </div> | ||||
| <div className="mx-auto mt-6 w-full"> | <div className="mx-auto mt-6 w-full"> | ||||
| <Button variant='primary' className='w-full'> | <Button variant='primary' className='w-full'> | ||||
| <Link href={'/signin'}>{t('login.passwordChanged')}</Link> | |||||
| <a href={`${basePath}/signin`}>{t('login.passwordChanged')}</a> | |||||
| </Button> | </Button> | ||||
| </div> | </div> | ||||
| </div> | </div> |
| import Loading from '../components/base/loading' | import Loading from '../components/base/loading' | ||||
| import Input from '../components/base/input' | import Input from '../components/base/input' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| import { | import { | ||||
| fetchInitValidateStatus, | fetchInitValidateStatus, | ||||
| fetchSetupStatus().then(() => { | fetchSetupStatus().then(() => { | ||||
| fetchInitValidateStatus().then((res: InitValidateStatusResponse) => { | fetchInitValidateStatus().then((res: InitValidateStatusResponse) => { | ||||
| if (res.status === 'not_started') | if (res.status === 'not_started') | ||||
| window.location.href = `${WEB_PREFIX}/init` | |||||
| window.location.href = `${basePath}/init` | |||||
| }) | }) | ||||
| setLoading(false) | setLoading(false) |
| import Toast from '../components/base/toast' | import Toast from '../components/base/toast' | ||||
| import Loading from '../components/base/loading' | import Loading from '../components/base/loading' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import { WEB_PREFIX } from '@/config' | |||||
| import { basePath } from '@/utils/var' | |||||
| import { fetchInitValidateStatus, initValidate } from '@/service/common' | import { fetchInitValidateStatus, initValidate } from '@/service/common' | ||||
| import type { InitValidateStatusResponse } from '@/models/common' | import type { InitValidateStatusResponse } from '@/models/common' | ||||
| useEffect(() => { | useEffect(() => { | ||||
| fetchInitValidateStatus().then((res: InitValidateStatusResponse) => { | fetchInitValidateStatus().then((res: InitValidateStatusResponse) => { | ||||
| if (res.status === 'finished') | if (res.status === 'finished') | ||||
| window.location.href = `${WEB_PREFIX}/install` | |||||
| window.location.href = `${basePath}/install` | |||||
| else | else | ||||
| setLoading(false) | setLoading(false) | ||||
| }) | }) |
| <body | <body | ||||
| className="color-scheme h-full select-auto" | className="color-scheme h-full select-auto" | ||||
| data-api-prefix={process.env.NEXT_PUBLIC_API_PREFIX} | data-api-prefix={process.env.NEXT_PUBLIC_API_PREFIX} | ||||
| data-web-prefix={process.env.NEXT_PUBLIC_WEB_PREFIX} | |||||
| data-pubic-api-prefix={process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX} | data-pubic-api-prefix={process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX} | ||||
| data-pubic-web-prefix={process.env.NEXT_PUBLIC_PUBLIC_WEB_PREFIX} | |||||
| data-marketplace-api-prefix={process.env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX} | data-marketplace-api-prefix={process.env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX} | ||||
| data-marketplace-url-prefix={process.env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX} | data-marketplace-url-prefix={process.env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX} | ||||
| data-public-edition={process.env.NEXT_PUBLIC_EDITION} | data-public-edition={process.env.NEXT_PUBLIC_EDITION} |
| import { PromptRole } from '@/models/debug' | import { PromptRole } from '@/models/debug' | ||||
| export let apiPrefix = '' | export let apiPrefix = '' | ||||
| export let webPrefix = '' | |||||
| export let publicApiPrefix = '' | export let publicApiPrefix = '' | ||||
| export let publicWebPrefix = '' | |||||
| export let marketplaceApiPrefix = '' | export let marketplaceApiPrefix = '' | ||||
| export let marketplaceUrlPrefix = '' | export let marketplaceUrlPrefix = '' | ||||
| // NEXT_PUBLIC_API_PREFIX=/console/api NEXT_PUBLIC_PUBLIC_API_PREFIX=/api npm run start | // NEXT_PUBLIC_API_PREFIX=/console/api NEXT_PUBLIC_PUBLIC_API_PREFIX=/api npm run start | ||||
| if ( | |||||
| process.env.NEXT_PUBLIC_API_PREFIX | |||||
| && process.env.NEXT_PUBLIC_WEB_PREFIX | |||||
| && process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX | |||||
| && process.env.NEXT_PUBLIC_PUBLIC_WEB_PREFIX | |||||
| ) { | |||||
| if (process.env.NEXT_PUBLIC_API_PREFIX && process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX) { | |||||
| apiPrefix = process.env.NEXT_PUBLIC_API_PREFIX | apiPrefix = process.env.NEXT_PUBLIC_API_PREFIX | ||||
| webPrefix = process.env.NEXT_PUBLIC_WEB_PREFIX | |||||
| publicApiPrefix = process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX | publicApiPrefix = process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX | ||||
| publicWebPrefix = process.env.NEXT_PUBLIC_PUBLIC_WEB_PREFIX | |||||
| } | } | ||||
| else if ( | else if ( | ||||
| globalThis.document?.body?.getAttribute('data-api-prefix') | globalThis.document?.body?.getAttribute('data-api-prefix') | ||||
| ) { | ) { | ||||
| // Not build can not get env from process.env.NEXT_PUBLIC_ in browser https://nextjs.org/docs/basic-features/environment-variables#exposing-environment-variables-to-the-browser | // Not build can not get env from process.env.NEXT_PUBLIC_ in browser https://nextjs.org/docs/basic-features/environment-variables#exposing-environment-variables-to-the-browser | ||||
| apiPrefix = globalThis.document.body.getAttribute('data-api-prefix') as string | apiPrefix = globalThis.document.body.getAttribute('data-api-prefix') as string | ||||
| webPrefix = (globalThis.document.body.getAttribute('data-web-prefix') as string || globalThis.location.origin) | |||||
| publicApiPrefix = globalThis.document.body.getAttribute('data-pubic-api-prefix') as string | publicApiPrefix = globalThis.document.body.getAttribute('data-pubic-api-prefix') as string | ||||
| publicWebPrefix = (globalThis.document.body.getAttribute('data-pubic-web-prefix') as string || globalThis.location.origin) | |||||
| } | } | ||||
| else { | else { | ||||
| // const domainParts = globalThis.location?.host?.split('.'); | // const domainParts = globalThis.location?.host?.split('.'); | ||||
| // in production env, the host is dify.app . In other env, the host is [dev].dify.app | // in production env, the host is dify.app . In other env, the host is [dev].dify.app | ||||
| // const env = domainParts.length === 2 ? 'ai' : domainParts?.[0]; | // const env = domainParts.length === 2 ? 'ai' : domainParts?.[0]; | ||||
| apiPrefix = 'http://localhost:5001/console/api' | apiPrefix = 'http://localhost:5001/console/api' | ||||
| webPrefix = 'http://localhost:3000' | |||||
| publicApiPrefix = 'http://localhost:5001/api' // avoid browser private mode api cross origin | publicApiPrefix = 'http://localhost:5001/api' // avoid browser private mode api cross origin | ||||
| publicWebPrefix = 'http://localhost:3000' | |||||
| marketplaceApiPrefix = 'http://localhost:5002/api' | marketplaceApiPrefix = 'http://localhost:5002/api' | ||||
| } | } | ||||
| } | } | ||||
| export const API_PREFIX: string = apiPrefix | export const API_PREFIX: string = apiPrefix | ||||
| export const WEB_PREFIX: string = webPrefix | |||||
| export const PUBLIC_API_PREFIX: string = publicApiPrefix | export const PUBLIC_API_PREFIX: string = publicApiPrefix | ||||
| export const PUBLIC_WEB_PREFIX: string = publicWebPrefix | |||||
| export const MARKETPLACE_API_PREFIX: string = marketplaceApiPrefix | export const MARKETPLACE_API_PREFIX: string = marketplaceApiPrefix | ||||
| export const MARKETPLACE_URL_PREFIX: string = marketplaceUrlPrefix | export const MARKETPLACE_URL_PREFIX: string = marketplaceUrlPrefix | ||||
| export NEXT_PUBLIC_DEPLOY_ENV=${DEPLOY_ENV} | export NEXT_PUBLIC_DEPLOY_ENV=${DEPLOY_ENV} | ||||
| export NEXT_PUBLIC_EDITION=${EDITION} | export NEXT_PUBLIC_EDITION=${EDITION} | ||||
| export NEXT_PUBLIC_API_PREFIX=${CONSOLE_API_URL}/console/api | export NEXT_PUBLIC_API_PREFIX=${CONSOLE_API_URL}/console/api | ||||
| export NEXT_PUBLIC_WEB_PREFIX=${CONSOLE_WEB_URL} | |||||
| export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_API_URL}/api | export NEXT_PUBLIC_PUBLIC_API_PREFIX=${APP_API_URL}/api | ||||
| export NEXT_PUBLIC_PUBLIC_WEB_PREFIX=${APP_WEB_URL} | |||||
| export NEXT_PUBLIC_MARKETPLACE_API_PREFIX=${MARKETPLACE_API_URL}/api/v1 | export NEXT_PUBLIC_MARKETPLACE_API_PREFIX=${MARKETPLACE_API_URL}/api/v1 | ||||
| export NEXT_PUBLIC_MARKETPLACE_URL_PREFIX=${MARKETPLACE_URL} | export NEXT_PUBLIC_MARKETPLACE_URL_PREFIX=${MARKETPLACE_URL} | ||||
| import { API_PREFIX, IS_CE_EDITION, PUBLIC_API_PREFIX, PUBLIC_WEB_PREFIX, WEB_PREFIX } from '@/config' | |||||
| import { API_PREFIX, IS_CE_EDITION, PUBLIC_API_PREFIX } from '@/config' | |||||
| import { refreshAccessTokenOrRelogin } from './refresh-token' | import { refreshAccessTokenOrRelogin } from './refresh-token' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { basePath } from '@/utils/var' | |||||
| import type { AnnotationReply, MessageEnd, MessageReplace, ThoughtItem } from '@/app/components/base/chat/chat/type' | import type { AnnotationReply, MessageEnd, MessageReplace, ThoughtItem } from '@/app/components/base/chat/chat/type' | ||||
| import type { VisionFile } from '@/types/app' | import type { VisionFile } from '@/types/app' | ||||
| import type { | import type { | ||||
| } | } | ||||
| function requiredWebSSOLogin() { | function requiredWebSSOLogin() { | ||||
| globalThis.location.href = `${PUBLIC_WEB_PREFIX}/webapp-signin?redirect_url=${globalThis.location.pathname}` | |||||
| globalThis.location.href = `/webapp-signin?redirect_url=${globalThis.location.pathname}` | |||||
| } | } | ||||
| export function format(text: string) { | export function format(text: string) { | ||||
| const errResp: Response = err as any | const errResp: Response = err as any | ||||
| if (errResp.status === 401) { | if (errResp.status === 401) { | ||||
| const [parseErr, errRespData] = await asyncRunSafe<ResponseError>(errResp.json()) | const [parseErr, errRespData] = await asyncRunSafe<ResponseError>(errResp.json()) | ||||
| const loginUrl = `${WEB_PREFIX}/signin` | |||||
| const loginUrl = `${globalThis.location.origin}${basePath}/signin` | |||||
| if (parseErr) { | if (parseErr) { | ||||
| globalThis.location.href = loginUrl | globalThis.location.href = loginUrl | ||||
| return Promise.reject(err) | return Promise.reject(err) | ||||
| return Promise.reject(err) | return Promise.reject(err) | ||||
| } | } | ||||
| if (code === 'not_init_validated' && IS_CE_EDITION) { | if (code === 'not_init_validated' && IS_CE_EDITION) { | ||||
| globalThis.location.href = `${WEB_PREFIX}/init` | |||||
| globalThis.location.href = `${globalThis.location.origin}${basePath}/init` | |||||
| return Promise.reject(err) | return Promise.reject(err) | ||||
| } | } | ||||
| if (code === 'not_setup' && IS_CE_EDITION) { | if (code === 'not_setup' && IS_CE_EDITION) { | ||||
| globalThis.location.href = `${WEB_PREFIX}/install` | |||||
| globalThis.location.href = `${globalThis.location.origin}${basePath}/install` | |||||
| return Promise.reject(err) | return Promise.reject(err) | ||||
| } | } | ||||
| const [refreshErr] = await asyncRunSafe(refreshAccessTokenOrRelogin(TIME_OUT)) | const [refreshErr] = await asyncRunSafe(refreshAccessTokenOrRelogin(TIME_OUT)) | ||||
| if (refreshErr === null) | if (refreshErr === null) | ||||
| return baseFetch<T>(url, options, otherOptionsForBaseFetch) | return baseFetch<T>(url, options, otherOptionsForBaseFetch) | ||||
| if (!location.pathname.includes('/signin') || !IS_CE_EDITION) { | |||||
| if (location.pathname !== `${basePath}/signin` || !IS_CE_EDITION) { | |||||
| globalThis.location.href = loginUrl | globalThis.location.href = loginUrl | ||||
| return Promise.reject(err) | return Promise.reject(err) | ||||
| } | } |
| import ky from 'ky' | import ky from 'ky' | ||||
| import type { IOtherOptions } from './base' | import type { IOtherOptions } from './base' | ||||
| import Toast from '@/app/components/base/toast' | import Toast from '@/app/components/base/toast' | ||||
| import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX, WEB_PREFIX } from '@/config' | |||||
| import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config' | |||||
| import { getInitialTokenV2, isTokenV1 } from '@/app/components/share/utils' | import { getInitialTokenV2, isTokenV1 } from '@/app/components/share/utils' | ||||
| import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils' | import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils' | ||||
| if (!otherOptions.silent) | if (!otherOptions.silent) | ||||
| Toast.notify({ type: 'error', message: data.message }) | Toast.notify({ type: 'error', message: data.message }) | ||||
| if (data.code === 'already_setup') | if (data.code === 'already_setup') | ||||
| globalThis.location.href = `${WEB_PREFIX}/signin` | |||||
| globalThis.location.href = `${globalThis.location.origin}/signin` | |||||
| }) | }) | ||||
| break | break | ||||
| case 401: | case 401: |