mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-06-30 07:55:09 +08:00
feat: add base path to resources (#17655)
Co-authored-by: fhliu4 <fhliu4@iflytek.com>
This commit is contained in:
parent
12de1d175c
commit
7161d7ad96
@ -16,6 +16,7 @@ import AppsContext, { useAppContext } from '@/context/app-context'
|
|||||||
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 { 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'
|
||||||
@ -216,7 +217,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
|
|||||||
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(`/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')
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import {
|
import {
|
||||||
RiAddLine,
|
RiAddLine,
|
||||||
RiArrowRightLine,
|
RiArrowRightLine,
|
||||||
@ -17,7 +18,7 @@ const CreateAppCard = (
|
|||||||
<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'
|
||||||
>
|
>
|
||||||
<a 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'
|
||||||
@ -28,7 +29,7 @@ const CreateAppCard = (
|
|||||||
</div>
|
</div>
|
||||||
</a>
|
</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>
|
||||||
<a 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' />
|
||||||
</a>
|
</a>
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
PortalToFollowElemContent,
|
PortalToFollowElemContent,
|
||||||
PortalToFollowElemTrigger,
|
PortalToFollowElemTrigger,
|
||||||
} from '@/app/components/base/portal-to-follow-elem'
|
} from '@/app/components/base/portal-to-follow-elem'
|
||||||
|
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'
|
||||||
@ -75,7 +76,7 @@ const AppPublisher = ({
|
|||||||
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()
|
||||||
@ -120,7 +121,7 @@ const AppPublisher = ({
|
|||||||
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(`/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')
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useContext } from 'use-context-selector'
|
import { useContext } from 'use-context-selector'
|
||||||
import { usePathname } from 'next/navigation'
|
import { usePathname } from 'next/navigation'
|
||||||
@ -503,6 +504,12 @@ const Configuration: FC = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const collectionList = await fetchCollectionList()
|
const collectionList = await fetchCollectionList()
|
||||||
|
if (basePath) {
|
||||||
|
collectionList.forEach((item) => {
|
||||||
|
if (typeof item.icon == 'string' && !item.icon.includes(basePath))
|
||||||
|
item.icon = `${basePath}${item.icon}`
|
||||||
|
})
|
||||||
|
}
|
||||||
setCollectionList(collectionList)
|
setCollectionList(collectionList)
|
||||||
fetchAppDetail({ url: '/apps', id: appId }).then(async (res: any) => {
|
fetchAppDetail({ url: '/apps', id: appId }).then(async (res: any) => {
|
||||||
setMode(res.mode)
|
setMode(res.mode)
|
||||||
|
@ -14,6 +14,7 @@ import type { AppIconSelection } from '../../base/app-icon-picker'
|
|||||||
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 { 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'
|
||||||
@ -352,11 +353,11 @@ function AppScreenShot({ mode, show }: { mode: AppMode; show: boolean }) {
|
|||||||
'workflow': 'Workflow',
|
'workflow': 'Workflow',
|
||||||
}
|
}
|
||||||
return <picture>
|
return <picture>
|
||||||
<source media="(resolution: 1x)" srcSet={`/screenshots/${theme}/${modeToImageMap[mode]}.png`} />
|
<source media="(resolution: 1x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}.png`} />
|
||||||
<source media="(resolution: 2x)" srcSet={`/screenshots/${theme}/${modeToImageMap[mode]}@2x.png`} />
|
<source media="(resolution: 2x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}@2x.png`} />
|
||||||
<source media="(resolution: 3x)" srcSet={`/screenshots/${theme}/${modeToImageMap[mode]}@3x.png`} />
|
<source media="(resolution: 3x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}@3x.png`} />
|
||||||
<Image className={show ? '' : 'hidden'}
|
<Image className={show ? '' : 'hidden'}
|
||||||
src={`/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>
|
||||||
|
@ -7,6 +7,7 @@ import { usePathname } from 'next/navigation'
|
|||||||
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'
|
||||||
@ -109,7 +110,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
|
|||||||
? <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)
|
||||||
|
@ -17,6 +17,7 @@ import type { ConfigParams } from './settings'
|
|||||||
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'
|
||||||
@ -88,7 +89,7 @@ function AppCard({
|
|||||||
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) => {
|
||||||
|
@ -13,6 +13,7 @@ import { IS_CE_EDITION } from '@/config'
|
|||||||
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 = {
|
||||||
@ -28,7 +29,7 @@ const OPTION_MAP = {
|
|||||||
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">
|
||||||
@ -41,17 +42,17 @@ const OPTION_MAP = {
|
|||||||
token: '${token}'${isTestEnv
|
token: '${token}'${isTestEnv
|
||||||
? `,
|
? `,
|
||||||
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>
|
||||||
@ -66,7 +67,7 @@ const OPTION_MAP = {
|
|||||||
</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'
|
||||||
|
@ -11,6 +11,7 @@ import timezone from 'dayjs/plugin/timezone'
|
|||||||
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'
|
||||||
@ -100,7 +101,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
|
|||||||
? <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)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import classNames from '@/utils/classnames'
|
import classNames from '@/utils/classnames'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
|
|
||||||
type LogoEmbeddedChatHeaderProps = {
|
type LogoEmbeddedChatHeaderProps = {
|
||||||
className?: string
|
className?: string
|
||||||
@ -13,7 +14,7 @@ const LogoEmbeddedChatHeader: FC<LogoEmbeddedChatHeaderProps> = ({
|
|||||||
<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='/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)}
|
||||||
/>
|
/>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import classNames from '@/utils/classnames'
|
import classNames from '@/utils/classnames'
|
||||||
|
|
||||||
type LogoSiteProps = {
|
type LogoSiteProps = {
|
||||||
@ -11,7 +12,7 @@ const LogoSite: FC<LogoSiteProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
src={'/logo/logo.png'}
|
src={`${basePath}/logo/logo.png`}
|
||||||
className={classNames('block w-[22.651px] h-[24.5px]', className)}
|
className={classNames('block w-[22.651px] h-[24.5px]', className)}
|
||||||
alt='logo'
|
alt='logo'
|
||||||
/>
|
/>
|
||||||
|
@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
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 { 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'
|
||||||
@ -22,7 +23,7 @@ const WorkplaceSelector = () => {
|
|||||||
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(`${location.origin}`)
|
location.assign(`${location.origin}${basePath}`)
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
notify({ type: 'error', message: t('common.provider.saveFailed') })
|
notify({ type: 'error', message: t('common.provider.saveFailed') })
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import copy from 'copy-to-clipboard'
|
import copy from 'copy-to-clipboard'
|
||||||
import s from './index.module.css'
|
import s from './index.module.css'
|
||||||
@ -18,7 +19,7 @@ const InvitationLink = ({
|
|||||||
const selector = useRef(`invite-link-${randomString(4)}`)
|
const selector = useRef(`invite-link-${randomString(4)}`)
|
||||||
|
|
||||||
const copyHandle = useCallback(() => {
|
const copyHandle = useCallback(() => {
|
||||||
copy(`${!value.url.startsWith('http') ? window.location.origin : ''}${value.url}`)
|
copy(`${!value.url.startsWith('http') ? window.location.origin : ''}${basePath}${value.url}`)
|
||||||
setIsCopied(true)
|
setIsCopied(true)
|
||||||
}, [value])
|
}, [value])
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ const InvitationLink = ({
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
|
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
|
||||||
>
|
>
|
||||||
<div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2' onClick={copyHandle}>{value.url}</div>
|
<div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2' onClick={copyHandle}>{basePath + value.url}</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-4 shrink-0 border bg-divider-regular" />
|
<div className="h-4 shrink-0 border bg-divider-regular" />
|
||||||
|
@ -3,6 +3,7 @@ import type {
|
|||||||
Model,
|
Model,
|
||||||
ModelProvider,
|
ModelProvider,
|
||||||
} from '../declarations'
|
} from '../declarations'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import { useLanguage } from '../hooks'
|
import { useLanguage } from '../hooks'
|
||||||
import { Group } from '@/app/components/base/icons/src/vender/other'
|
import { Group } from '@/app/components/base/icons/src/vender/other'
|
||||||
import { OpenaiBlue, OpenaiViolet } from '@/app/components/base/icons/src/public/llm'
|
import { OpenaiBlue, OpenaiViolet } from '@/app/components/base/icons/src/public/llm'
|
||||||
@ -30,7 +31,7 @@ const ModelIcon: FC<ModelIconProps> = ({
|
|||||||
if (provider?.icon_small) {
|
if (provider?.icon_small) {
|
||||||
return (
|
return (
|
||||||
<div className={cn('flex h-5 w-5 items-center justify-center', isDeprecated && 'opacity-50', className)}>
|
<div className={cn('flex h-5 w-5 items-center justify-center', isDeprecated && 'opacity-50', className)}>
|
||||||
<img alt='model-icon' src={renderI18nObject(provider.icon_small, language)}/>
|
<img alt='model-icon' src={basePath + renderI18nObject(provider.icon_small, language)}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
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'
|
||||||
@ -40,7 +41,7 @@ const ProviderIcon: FC<ProviderIconProps> = ({
|
|||||||
<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'>
|
||||||
|
@ -14,6 +14,7 @@ import Type from './type'
|
|||||||
import Category from './category'
|
import Category from './category'
|
||||||
import Tools from './tools'
|
import Tools from './tools'
|
||||||
import cn from '@/utils/classnames'
|
import cn from '@/utils/classnames'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import I18n from '@/context/i18n'
|
import I18n from '@/context/i18n'
|
||||||
import Drawer from '@/app/components/base/drawer'
|
import Drawer from '@/app/components/base/drawer'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
@ -57,6 +58,12 @@ const AddToolModal: FC<Props> = ({
|
|||||||
const getAllTools = async () => {
|
const getAllTools = async () => {
|
||||||
setListLoading(true)
|
setListLoading(true)
|
||||||
const buildInTools = await fetchAllBuiltInTools()
|
const buildInTools = await fetchAllBuiltInTools()
|
||||||
|
if (basePath) {
|
||||||
|
buildInTools.forEach((item) => {
|
||||||
|
if (typeof item.icon == 'string' && !item.icon.includes(basePath))
|
||||||
|
item.icon = `${basePath}${item.icon}`
|
||||||
|
})
|
||||||
|
}
|
||||||
const customTools = await fetchAllCustomTools()
|
const customTools = await fetchAllCustomTools()
|
||||||
const workflowTools = await fetchAllWorkflowTools()
|
const workflowTools = await fetchAllWorkflowTools()
|
||||||
const mergedToolList = [
|
const mergedToolList = [
|
||||||
|
@ -2,6 +2,7 @@ import {
|
|||||||
memo,
|
memo,
|
||||||
useCallback,
|
useCallback,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import {
|
import {
|
||||||
RiAddLine,
|
RiAddLine,
|
||||||
@ -53,7 +54,7 @@ const Blocks = ({
|
|||||||
>
|
>
|
||||||
<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]}
|
||||||
<a 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' /></a>
|
<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 = (() => {
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
RiCloseLine,
|
RiCloseLine,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import { AuthHeaderPrefix, AuthType, CollectionType } from '../types'
|
import { AuthHeaderPrefix, AuthType, CollectionType } from '../types'
|
||||||
|
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'
|
||||||
@ -276,7 +277,7 @@ const ProviderDetail = ({
|
|||||||
variant='primary'
|
variant='primary'
|
||||||
className={cn('my-3 w-[183px] shrink-0')}
|
className={cn('my-3 w-[183px] shrink-0')}
|
||||||
>
|
>
|
||||||
<a 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' />
|
||||||
</a>
|
</a>
|
||||||
|
@ -59,6 +59,7 @@ import { CollectionType } from '@/app/components/tools/types'
|
|||||||
import { CUSTOM_ITERATION_START_NODE } from '@/app/components/workflow/nodes/iteration-start/constants'
|
import { CUSTOM_ITERATION_START_NODE } from '@/app/components/workflow/nodes/iteration-start/constants'
|
||||||
import { CUSTOM_LOOP_START_NODE } from '@/app/components/workflow/nodes/loop-start/constants'
|
import { CUSTOM_LOOP_START_NODE } from '@/app/components/workflow/nodes/loop-start/constants'
|
||||||
import { useWorkflowConfig } from '@/service/use-workflow'
|
import { useWorkflowConfig } from '@/service/use-workflow'
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
import { canFindTool } from '@/utils'
|
import { canFindTool } from '@/utils'
|
||||||
|
|
||||||
export const useIsChatMode = () => {
|
export const useIsChatMode = () => {
|
||||||
@ -446,6 +447,12 @@ export const useFetchToolsData = () => {
|
|||||||
if (type === 'builtin') {
|
if (type === 'builtin') {
|
||||||
const buildInTools = await fetchAllBuiltInTools()
|
const buildInTools = await fetchAllBuiltInTools()
|
||||||
|
|
||||||
|
if (basePath) {
|
||||||
|
buildInTools.forEach((item) => {
|
||||||
|
if (typeof item.icon == 'string' && !item.icon.includes(basePath))
|
||||||
|
item.icon = `${basePath}${item.icon}`
|
||||||
|
})
|
||||||
|
}
|
||||||
workflowStore.setState({
|
workflowStore.setState({
|
||||||
buildInTools: buildInTools || [],
|
buildInTools: buildInTools || [],
|
||||||
})
|
})
|
||||||
|
@ -3,6 +3,7 @@ import { useCallback, useState } from 'react'
|
|||||||
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 { 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'
|
||||||
@ -163,7 +164,7 @@ const ChangePasswordForm = () => {
|
|||||||
</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'>
|
||||||
<a href="/signin">{t('login.passwordChanged')}</a>
|
<a href={`${basePath}/signin`}>{t('login.passwordChanged')}</a>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,6 +10,7 @@ import { zodResolver } from '@hookform/resolvers/zod'
|
|||||||
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 { basePath } from '@/utils/var'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
fetchInitValidateStatus,
|
fetchInitValidateStatus,
|
||||||
@ -70,7 +71,7 @@ const ForgotPasswordForm = () => {
|
|||||||
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 = '/init'
|
window.location.href = `${basePath}/init`
|
||||||
})
|
})
|
||||||
|
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation'
|
|||||||
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 { 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'
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ const InitPasswordPopup = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchInitValidateStatus().then((res: InitValidateStatusResponse) => {
|
fetchInitValidateStatus().then((res: InitValidateStatusResponse) => {
|
||||||
if (res.status === 'finished')
|
if (res.status === 'finished')
|
||||||
window.location.href = '/install'
|
window.location.href = `${basePath}/install`
|
||||||
else
|
else
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
})
|
})
|
||||||
|
@ -80,12 +80,12 @@ const InstallForm = () => {
|
|||||||
fetchSetupStatus().then((res: SetupStatusResponse) => {
|
fetchSetupStatus().then((res: SetupStatusResponse) => {
|
||||||
if (res.step === 'finished') {
|
if (res.step === 'finished') {
|
||||||
localStorage.setItem('setup_status', 'finished')
|
localStorage.setItem('setup_status', 'finished')
|
||||||
window.location.href = '/signin'
|
router.push('/signin')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fetchInitValidateStatus().then((res: InitValidateStatusResponse) => {
|
fetchInitValidateStatus().then((res: InitValidateStatusResponse) => {
|
||||||
if (res.status === 'not_started')
|
if (res.status === 'not_started')
|
||||||
window.location.href = '/init'
|
router.push('/init')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { Viewport } from 'next'
|
import type { Viewport } from 'next'
|
||||||
|
import RoutePrefixHandle from './routePrefixHandle'
|
||||||
import I18nServer from './components/i18n-server'
|
import I18nServer from './components/i18n-server'
|
||||||
import BrowserInitor from './components/browser-initor'
|
import BrowserInitor from './components/browser-initor'
|
||||||
import SentryInitor from './components/sentry-initor'
|
import SentryInitor from './components/sentry-initor'
|
||||||
@ -71,6 +72,7 @@ const LocaleLayout = async ({
|
|||||||
</TanstackQueryIniter>
|
</TanstackQueryIniter>
|
||||||
</SentryInitor>
|
</SentryInitor>
|
||||||
</BrowserInitor>
|
</BrowserInitor>
|
||||||
|
<RoutePrefixHandle />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
|
53
web/app/routePrefixHandle.tsx
Normal file
53
web/app/routePrefixHandle.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { basePath } from '@/utils/var'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { usePathname } from 'next/navigation'
|
||||||
|
|
||||||
|
export default function RoutePrefixHandle() {
|
||||||
|
const pathname = usePathname()
|
||||||
|
const handleRouteChange = () => {
|
||||||
|
const addPrefixToImg = (e: HTMLImageElement) => {
|
||||||
|
const url = new URL(e.src)
|
||||||
|
const prefix = url.pathname.substr(0, basePath.length)
|
||||||
|
if (prefix !== basePath) {
|
||||||
|
url.pathname = basePath + url.pathname
|
||||||
|
e.src = url.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create an observer instance
|
||||||
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
|
for (const mutation of mutationsList) {
|
||||||
|
if (mutation.type === 'childList') {
|
||||||
|
// listen for newly added img tags
|
||||||
|
mutation.addedNodes.forEach((node) => {
|
||||||
|
if (((node as HTMLElement).tagName) === 'IMG')
|
||||||
|
addPrefixToImg(node as HTMLImageElement)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if (mutation.type === 'attributes' && (mutation.target as HTMLElement).tagName === 'IMG') {
|
||||||
|
// if the src of an existing img tag changes, update the prefix
|
||||||
|
if (mutation.attributeName === 'src')
|
||||||
|
addPrefixToImg(mutation.target as HTMLImageElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// configure observation options
|
||||||
|
const config = {
|
||||||
|
childList: true,
|
||||||
|
attributes: true,
|
||||||
|
subtree: true,
|
||||||
|
attributeFilter: ['src'],
|
||||||
|
}
|
||||||
|
|
||||||
|
observer.observe(document.body, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (basePath)
|
||||||
|
handleRouteChange()
|
||||||
|
}, [pathname])
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
@ -24,7 +24,8 @@ export const useTabSearchParams = ({
|
|||||||
searchParamName = 'category',
|
searchParamName = 'category',
|
||||||
disableSearchParams = false,
|
disableSearchParams = false,
|
||||||
}: UseTabSearchParamsOptions) => {
|
}: UseTabSearchParamsOptions) => {
|
||||||
const pathName = usePathname()
|
const pathnameFromHook = usePathname()
|
||||||
|
const pathName = window?.location?.pathname || pathnameFromHook
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const [activeTab, setTab] = useState<string>(
|
const [activeTab, setTab] = useState<string>(
|
||||||
!disableSearchParams
|
!disableSearchParams
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
const { basePath } = require('./utils/var-basePath')
|
||||||
const { codeInspectorPlugin } = require('code-inspector-plugin')
|
const { codeInspectorPlugin } = require('code-inspector-plugin')
|
||||||
const withMDX = require('@next/mdx')({
|
const withMDX = require('@next/mdx')({
|
||||||
extension: /\.mdx?$/,
|
extension: /\.mdx?$/,
|
||||||
@ -14,6 +15,7 @@ const withMDX = require('@next/mdx')({
|
|||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
|
basePath,
|
||||||
webpack: (config, { dev, isServer }) => {
|
webpack: (config, { dev, isServer }) => {
|
||||||
config.plugins.push(codeInspectorPlugin({ bundler: 'webpack' }))
|
config.plugins.push(codeInspectorPlugin({ bundler: 'webpack' }))
|
||||||
return config
|
return config
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { API_PREFIX, IS_CE_EDITION, PUBLIC_API_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 {
|
||||||
@ -466,7 +467,7 @@ export const request = async<T>(url: string, options = {}, otherOptions?: IOther
|
|||||||
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 = `${globalThis.location.origin}/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)
|
||||||
@ -498,11 +499,11 @@ export const request = async<T>(url: string, options = {}, otherOptions?: IOther
|
|||||||
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 = `${globalThis.location.origin}/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 = `${globalThis.location.origin}/install`
|
globalThis.location.href = `${globalThis.location.origin}${basePath}/install`
|
||||||
return Promise.reject(err)
|
return Promise.reject(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +511,7 @@ export const request = async<T>(url: string, options = {}, otherOptions?: IOther
|
|||||||
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 !== '/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)
|
||||||
}
|
}
|
||||||
|
5
web/utils/var-basePath.js
Normal file
5
web/utils/var-basePath.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// export basePath to next.config.js
|
||||||
|
// same as the one exported from var.ts
|
||||||
|
module.exports = {
|
||||||
|
basePath: '',
|
||||||
|
}
|
@ -104,3 +104,7 @@ export const getVars = (value: string) => {
|
|||||||
})
|
})
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the value of basePath
|
||||||
|
// example: /dify
|
||||||
|
export const basePath = ''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user