feat: fe mobile responsive next (#1609)

This commit is contained in:
Yuhao 2023-11-27 11:47:48 +08:00 • committed by GitHub
commit a9c1c7d239
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
89 changed files with 768 additions and 485 deletions

View file

@ -27,6 +27,7 @@ import Loading from '@/app/components/base/loading'
import ModelSelector from '@/app/components/header/account-setting/model-page/model-selector'
import { ModelType, ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
import { useProviderContext } from '@/context/provider-context'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import type { ModelModeType } from '@/types/app'
export type IConfigModelProps = {
isAdvancedMode: boolean
@ -54,6 +55,10 @@ const ConfigModel: FC<IConfigModelProps> = ({
const [maxTokenSettingTipVisible, setMaxTokenSettingTipVisible] = useState(false)
const configContentRef = React.useRef(null)
const currModel = textGenerationModelList.find(item => item.model_name === modelId)
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
// Cache loaded model param
const [allParams, setAllParams, getAllParams] = useGetState<Record<string, Record<string, any>>>({})
const currParams = allParams[provider]?.[modelId]
@ -288,7 +293,7 @@ const ConfigModel: FC<IConfigModelProps> = ({
</div>
{isShowConfig && (
<Panel
className='absolute z-20 top-8 right-0 !w-[496px] bg-white !overflow-visible shadow-md'
className='absolute z-20 top-8 left-0 sm:left-[unset] sm:right-0 !w-fit sm:!w-[496px] bg-white !overflow-visible shadow-md'
keepUnFold
headerIcon={
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -340,7 +345,7 @@ const ConfigModel: FC<IConfigModelProps> = ({
<div className='grow flex items-center' key={tone.id}>
<Radio
value={tone.id}
className={cn(tone.id === toneId && 'rounded-md border border-gray-200 shadow-md', '!mr-0 grow !px-2 !justify-center text-[13px] font-medium')}
className={cn(tone.id === toneId && 'rounded-md border border-gray-200 shadow-md', '!mr-0 grow !px-1 sm:!px-2 !justify-center text-[13px] font-medium')}
labelClassName={cn(tone.id === toneId
? ({
1: 'text-[#6938EF]',
@ -351,7 +356,7 @@ const ConfigModel: FC<IConfigModelProps> = ({
>
<>
{getToneIcon(tone.id)}
<div>{t(`common.model.tone.${tone.name}`) as string}</div>
{!isMobile && <div>{t(`common.model.tone.${tone.name}`) as string}</div>}
<div className=""></div>
</>
</Radio>
@ -361,12 +366,12 @@ const ConfigModel: FC<IConfigModelProps> = ({
</>
<Radio
value={TONE_LIST[3].id}
className={cn(toneId === 4 && 'rounded-md border border-gray-200 shadow-md', '!mr-0 grow !px-2 !justify-center text-[13px] font-medium')}
className={cn(toneId === 4 && 'rounded-md border border-gray-200 shadow-md', '!mr-0 grow !px-1 sm:!px-2 !justify-center text-[13px] font-medium')}
labelClassName={cn('flex items-center space-x-2 ', toneId === 4 ? 'text-[#155EEF]' : 'text-[#667085]')}
>
<>
{getToneIcon(TONE_LIST[3].id)}
<div>{t(`common.model.tone.${TONE_LIST[3].name}`) as string}</div>
{!isMobile && <div>{t(`common.model.tone.${TONE_LIST[3].name}`) as string}</div>}
</>
</Radio>
</Radio.Group>

View file

@ -20,7 +20,7 @@ const ModelModeTypeLabel: FC<Props> = ({
return (
<div
className={cn(className, isHighlight ? 'border-indigo-300 text-indigo-600' : 'border-gray-300 text-gray-500', 'flex items-center h-4 px-1 border rounded text-xs font-semibold uppercase')}
className={cn(className, isHighlight ? 'border-indigo-300 text-indigo-600' : 'border-gray-300 text-gray-500', 'flex items-center h-4 px-1 border rounded text-xs font-semibold uppercase text-ellipsis overflow-hidden whitespace-nowrap')}
>
{t(`appDebug.modelConfig.modeType.${type}`)}
</div>

View file

@ -18,7 +18,7 @@ const ModelName: FC<IModelNameProps> = ({
modelDisplayName,
}) => {
return (
<span title={modelDisplayName}>
<span className='text-ellipsis overflow-hidden whitespace-nowrap' title={modelDisplayName}>
{modelDisplayName}
</span>
)

View file

@ -49,7 +49,7 @@ const ParamItem: FC<IParamIteProps> = ({ id, name, tip, step = 0.1, min = 0, max
onChange(id, getFitPrecisionValue(value, precision))
}, [value, precision])
return (
<div className="flex items-center justify-between">
<div className="flex items-center justify-between flex-wrap gap-y-2">
<div className="flex flex-col flex-shrink-0">
<div className="flex items-center">
<span className="mr-[6px] text-gray-500 text-[13px] font-medium">{name}</span>

View file

@ -185,8 +185,8 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar
<div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.notSetVar')}</div>
)}
{hasVar && (
<div className='rounded-lg border border-gray-200 bg-white'>
<table className={`${s.table} w-full border-collapse border-0 rounded-lg text-sm`}>
<div className='rounded-lg border border-gray-200 bg-white overflow-x-auto'>
<table className={`${s.table} min-w-[440px] max-w-full border-collapse border-0 rounded-lg text-sm`}>
<thead className="border-b border-gray-200 text-gray-500 text-xs font-medium">
<tr className='uppercase'>
<td>{t('appDebug.variableTable.key')}</td>

View file

@ -31,7 +31,7 @@ const ParamsConfig: FC = () => {
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 50 }}>
<div className='w-[412px] p-4 bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg space-y-3'>
<div className='w-80 sm:w-[412px] p-4 bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg space-y-3'>
<ParamConfigContent />
</div>
</PortalToFollowElemContent>

View file

@ -16,6 +16,7 @@ import Loading from '@/app/components/base/loading'
import Confirm from '@/app/components/base/confirm'
// type
import type { AutomaticRes } from '@/service/debug'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
const noDataIcon = (
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -47,6 +48,9 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
}) => {
const { t } = useTranslation()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const [audiences, setAudiences] = React.useState<string>('')
const [hopingToSolve, setHopingToSolve] = React.useState<string>('')
const isValid = () => {
@ -103,15 +107,36 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
const [showConfirmOverwrite, setShowConfirmOverwrite] = React.useState(false)
const isShowAutoPromptInput = () => {
if (isMobile) {
// hide prompt panel on mobile if it is loading or has had result
if (isLoading || res)
return false
return true
}
// alway display prompt panel on desktop mode
return true
}
const isShowAutoPromptResPlaceholder = () => {
if (isMobile) {
// hide placeholder panel on mobile
return false
}
return !isLoading && !res
}
return (
<Modal
isShow={isShow}
onClose={onClose}
className='min-w-[1120px] !p-0'
className='!p-0 sm:min-w-[768px] xl:min-w-[1120px]'
closable
>
<div className='flex h-[680px]'>
<div className='w-[480px] shrink-0 px-8 py-6 h-full overflow-y-auto border-r border-gray-100'>
<div className='flex h-[680px] flex-wrap gap-y-4 overflow-y-auto'>
{isShowAutoPromptInput() && <div className='w-full sm:w-[360px] xl:w-[480px] shrink-0 px-8 py-6 h-full overflow-y-auto border-r border-gray-100'>
<div>
<div className='mb-1 text-xl font-semibold text-primary-600'>{t('appDebug.automatic.title')}</div>
<div className='text-[13px] font-normal text-gray-500'>{t('appDebug.automatic.description')}</div>
@ -139,7 +164,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
</Button>
</div>
</div>
</div>
</div>}
{(!isLoading && res) && (
<div className='grow px-8 pt-6 h-full overflow-y-auto'>
@ -180,7 +205,7 @@ const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
</div>
)}
{isLoading && renderLoading}
{(!isLoading && !res) && renderNoData}
{isShowAutoPromptResPlaceholder() && renderNoData}
{showConfirmOverwrite && (
<Confirm
title={t('appDebug.automatic.overwriteTitle')}

View file

@ -9,6 +9,8 @@ import { formatNumber } from '@/utils/format'
import FileIcon from '@/app/components/base/file-icon'
import { Settings01, Trash03 } from '@/app/components/base/icons/src/vender/line/general'
import { Folder } from '@/app/components/base/icons/src/vender/solid/files'
import Drawer from '@/app/components/base/drawer'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
type ItemProps = {
className?: string
@ -24,6 +26,10 @@ const Item: FC<ItemProps> = ({
onRemove,
}) => {
const { t } = useTranslation()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const [showSettingsModal, setShowSettingsModal] = useState(false)
const handleSave = (newDataset: DataSet) => {
@ -74,15 +80,13 @@ const Item: FC<ItemProps> = ({
<Trash03 className='w-4 h-4 text-gray-500 group-hover/action:text-[#D92D20]' />
</div>
</div>
{
showSettingsModal && (
<SettingsModal
currentDataset={config}
onCancel={() => setShowSettingsModal(false)}
onSave={handleSave}
/>
)
}
<Drawer isOpen={showSettingsModal} onClose={() => setShowSettingsModal(false)} footer={null} mask={isMobile} panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'>
<SettingsModal
currentDataset={config}
onCancel={() => setShowSettingsModal(false)}
onSave={handleSave}
/>
</Drawer>
</div>
)
}

View file

@ -137,7 +137,7 @@ const ParamsConfig: FC = () => {
onClose={() => {
setOpen(false)
}}
className='min-w-[528px]'
className='sm:min-w-[528px]'
wrapperClassName='z-50'
title={t('appDebug.datasetConfig.settingTitle')}
>

View file

@ -1,6 +1,5 @@
import type { FC } from 'react'
import { useRef, useState } from 'react'
import { useClickAway } from 'ahooks'
import { useTranslation } from 'react-i18next'
import { isEqual } from 'lodash-es'
import cn from 'classnames'
@ -30,7 +29,7 @@ type SettingsModalProps = {
}
const rowClass = `
flex justify-between py-4
flex justify-between py-4 flex-wrap gap-y-2
`
const labelClass = `
@ -45,10 +44,6 @@ const SettingsModal: FC<SettingsModalProps> = ({
const { t } = useTranslation()
const { notify } = useToastContext()
const ref = useRef(null)
useClickAway(() => {
if (ref)
onCancel()
}, ref)
const { setShowAccountSettingModal } = useModalContext()
const [loading, setLoading] = useState(false)
@ -122,10 +117,8 @@ const SettingsModal: FC<SettingsModalProps> = ({
return (
<div
className='fixed top-16 right-2 flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl z-10'
className='overflow-hidden w-full flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl'
style={{
zIndex: 11,
width: 700,
height: 'calc(100vh - 72px)',
}}
ref={ref}
@ -179,12 +172,12 @@ const SettingsModal: FC<SettingsModalProps> = ({
<div className={labelClass}>
<div>{t('datasetSettings.form.permissions')}</div>
</div>
<div className='w-[480px]'>
<div className='w-full sm:w-[480px]'>
<PermissionsRadio
disable={!localeCurrentDataset?.embedding_available}
value={localeCurrentDataset.permission}
onChange={v => handleValueChange('permission', v!)}
itemClassName='!w-[227px]'
itemClassName='sm:!w-[227px]'
/>
</div>
</div>
@ -198,7 +191,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
disable={!localeCurrentDataset?.embedding_available}
value={indexMethod}
onChange={v => setIndexMethod(v!)}
itemClassName='!w-[227px]'
itemClassName='sm:!w-[227px]'
/>
</div>
</div>
@ -272,7 +265,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
)}
<div
className='absolute z-[5] bottom-0 w-full flex justify-end py-4 px-6 border-t bg-white '
className='sticky z-[5] bottom-0 w-full flex justify-end py-4 px-6 border-t bg-white '
style={{
borderColor: 'rgba(0, 0, 0, 0.05)',
}}

View file

@ -8,6 +8,7 @@ import produce from 'immer'
import { useBoolean, useGetState } from 'ahooks'
import cn from 'classnames'
import { clone, isEqual } from 'lodash-es'
import { CodeBracketIcon } from '@heroicons/react/20/solid'
import Button from '../../base/button'
import Loading from '../../base/loading'
import s from './style.module.css'
@ -44,6 +45,8 @@ import { DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/
import SelectDataSet from '@/app/components/app/configuration/dataset-config/select-dataset'
import I18n from '@/context/i18n'
import { useModalContext } from '@/context/modal-context'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Drawer from '@/app/components/base/drawer'
type PublichConfig = {
modelConfig: ModelConfig
@ -64,6 +67,10 @@ const Configuration: FC = () => {
const [conversationId, setConversationId] = useState<string | null>('')
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const [isShowDebugPanel, { setTrue: showDebugPanel, setFalse: hideDebugPanel }] = useBoolean(false)
const [introduction, setIntroduction] = useState<string>('')
const [controlClearChatMessage, setControlClearChatMessage] = useState(0)
const [prevPromptConfig, setPrevPromptConfig] = useState<PromptConfig>({
@ -600,7 +607,7 @@ const Configuration: FC = () => {
>
<>
<div className="flex flex-col h-full">
<div className='flex items-center justify-between px-6 shrink-0 h-14'>
<div className='flex items-center justify-between px-6 shrink-0 py-3 flex-wrap gap-y-2'>
<div className='flex items-end'>
<div className={s.promptTitle}></div>
<div className='flex items-center h-[14px] space-x-1 text-xs'>
@ -630,7 +637,7 @@ const Configuration: FC = () => {
</div>
</div>
<div className='flex items-center'>
<div className='flex items-center flex-wrap gap-y-2 gap-x-2'>
{/* Model and Parameters */}
<ConfigModel
isAdvancedMode={isAdvancedMode}
@ -644,22 +651,28 @@ const Configuration: FC = () => {
}}
disabled={!hasSetAPIKEY}
/>
<div className='mx-3 w-[1px] h-[14px] bg-gray-200'></div>
<div className='w-[1px] h-[14px] bg-gray-200'></div>
<Button onClick={() => setShowConfirm(true)} className='shrink-0 mr-2 w-[70px] !h-8 !text-[13px] font-medium'>{t('appDebug.operation.resetConfig')}</Button>
{isMobile && (
<Button className='!h-8 !text-[13px] font-medium' onClick={showDebugPanel}>
<span className='mr-1'>{t('appDebug.operation.debugConfig')}</span>
<CodeBracketIcon className="h-4 w-4 text-gray-500" />
</Button>
)}
<Button type='primary' onClick={() => handlePublish(false)} className={cn(cannotPublish && '!bg-primary-200 !cursor-not-allowed', 'shrink-0 w-[70px] !h-8 !text-[13px] font-medium')}>{t('appDebug.operation.applyConfig')}</Button>
</div>
</div>
<div className='flex grow h-[200px]'>
<div className="w-1/2 min-w-[560px] shrink-0">
<div className="w-full sm:w-1/2 shrink-0">
<Config />
</div>
<div className="relative w-1/2 grow h-full overflow-y-auto py-4 px-6 bg-gray-50 flex flex-col rounded-tl-2xl border-t border-l" style={{ borderColor: 'rgba(0, 0, 0, 0.02)' }}>
{!isMobile && <div className="relative w-1/2 grow h-full overflow-y-auto py-4 px-6 bg-gray-50 flex flex-col rounded-tl-2xl border-t border-l" style={{ borderColor: 'rgba(0, 0, 0, 0.02)' }}>
<Debug
hasSetAPIKEY={hasSetAPIKEY}
onSetting={() => setShowAccountSettingModal({ payload: 'provider' })}
inputs={inputs}
/>
</div>
</div>}
</div>
</div>
{showConfirm && (
@ -707,6 +720,15 @@ const Configuration: FC = () => {
}}
/>
)}
{isMobile && (
<Drawer showClose isOpen={isShowDebugPanel} onClose={hideDebugPanel} mask footer={null} panelClassname='!bg-gray-50'>
<Debug
hasSetAPIKEY={hasSetAPIKEY}
onSetting={() => setShowAccountSettingModal({ payload: 'provider' })}
inputs={inputs}
/>
</Drawer>
)}
</>
</ConfigContext.Provider>
)

View file

@ -39,7 +39,7 @@ const Filter: FC<IFilterProps> = ({ appId, queryParams, setQueryParams }: IFilte
if (!data)
return null
return (
<div className='flex flex-row items-center mb-4 text-gray-900 text-base'>
<div className='flex flex-row flex-wrap gap-y-2 gap-x-4 items-center mb-4 text-gray-900 text-base'>
<SimpleSelect
items={TIME_PERIOD_LIST.map(item => ({ value: item.value, name: t(`appLog.filter.period.${item.name}`) }))}
className='mt-0 !w-40'
@ -47,7 +47,7 @@ const Filter: FC<IFilterProps> = ({ appId, queryParams, setQueryParams }: IFilte
setQueryParams({ ...queryParams, period: item.value })
}}
defaultValue={queryParams.period} />
<div className="relative ml-4 rounded-md mr-4">
<div className="relative rounded-md">
<SimpleSelect
defaultValue={'all'}
className='!w-[300px]'

View file

@ -33,6 +33,7 @@ import { TONE_LIST } from '@/config'
import ModelIcon from '@/app/components/app/configuration/config-model/model-icon'
import ModelName from '@/app/components/app/configuration/config-model/model-name'
import ModelModeTypeLabel from '@/app/components/app/configuration/config-model/model-mode-type-label'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
type IConversationList = {
logs?: ChatConversationsResponse | CompletionConversationsResponse
@ -200,7 +201,7 @@ function DetailPanel<T extends ChatConversationFullDetailResponse | CompletionCo
<div className='text-gray-500 text-[10px] leading-[14px]'>{isChatMode ? t('appLog.detail.conversationId') : t('appLog.detail.time')}</div>
<div className='text-gray-700 text-[13px] leading-[18px]'>{isChatMode ? detail.id?.split('-').slice(-1)[0] : dayjs.unix(detail.created_at).format(t('appLog.dateTimeFormat') as string)}</div>
</div>
<div className='flex items-center'>
<div className='flex items-center flex-wrap gap-y-1 justify-end'>
<div
className={cn('mr-2 flex items-center border h-8 px-2 space-x-2 rounded-lg bg-indigo-25 border-[#2A87F5]')}
>
@ -412,6 +413,10 @@ const ChatConversationDetailComp: FC<{ appId?: string; conversationId?: string }
*/
const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh }) => {
const { t } = useTranslation()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const [showDrawer, setShowDrawer] = useState<boolean>(false) // Whether to display the chat details drawer
const [currentConversation, setCurrentConversation] = useState<ChatConversationGeneralDetail | CompletionConversationGeneralDetail | undefined>() // Currently selected conversation
const isChatMode = appDetail?.mode === 'chat' // Whether the app is a chat app
@ -445,17 +450,17 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
return <Loading />
return (
<>
<table className={`w-full border-collapse border-0 text-sm mt-3 ${s.logTable}`}>
<thead className="h-8 leading-8 border-b border-gray-200 text-gray-500 font-bold">
<div className='overflow-x-auto'>
<table className={`w-full min-w-[440px] border-collapse border-0 text-sm mt-3 ${s.logTable}`}>
<thead className="h-8 leading-8 border-b border-gray-200 text-gray-500 font-bold">
<tr>
<td className='w-[1.375rem]'></td>
<td>{t('appLog.table.header.time')}</td>
<td>{t('appLog.table.header.endUser')}</td>
<td>{isChatMode ? t('appLog.table.header.summary') : t('appLog.table.header.input')}</td>
<td>{isChatMode ? t('appLog.table.header.messageCount') : t('appLog.table.header.output')}</td>
<td>{t('appLog.table.header.userRate')}</td>
<td>{t('appLog.table.header.adminRate')}</td>
<td className='w-[1.375rem] whitespace-nowrap'></td>
<td className='whitespace-nowrap'>{t('appLog.table.header.time')}</td>
<td className='whitespace-nowrap'>{t('appLog.table.header.endUser')}</td>
<td className='whitespace-nowrap'>{isChatMode ? t('appLog.table.header.summary') : t('appLog.table.header.input')}</td>
<td className='whitespace-nowrap'>{isChatMode ? t('appLog.table.header.messageCount') : t('appLog.table.header.output')}</td>
<td className='whitespace-nowrap'>{t('appLog.table.header.userRate')}</td>
<td className='whitespace-nowrap'>{t('appLog.table.header.adminRate')}</td>
</tr>
</thead>
<tbody className="text-gray-500">
@ -504,9 +509,9 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
<Drawer
isOpen={showDrawer}
onClose={onCloseDrawer}
mask={false}
mask={isMobile}
footer={null}
panelClassname='mt-16 mr-2 mb-3 !p-0 !max-w-[640px] rounded-b-xl'
panelClassname='mt-16 mx-2 sm:mr-2 mb-3 !p-0 !max-w-[640px] rounded-xl'
>
<DrawerContext.Provider value={{
onClose: onCloseDrawer,
@ -518,7 +523,7 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
}
</DrawerContext.Provider>
</Drawer>
</>
</div>
)
}

View file

@ -129,7 +129,7 @@ function AppCard({
return (
<div
className={`min-w-max shadow-xs border-[0.5px] rounded-lg border-gray-200 ${
className={`shadow-xs border-[0.5px] rounded-lg border-gray-200 ${
className ?? ''
}`}
>
@ -163,8 +163,8 @@ function AppCard({
: t('appOverview.overview.apiInfo.accessibleAddress')}
</div>
<div className="w-full h-9 pl-2 pr-0.5 py-0.5 bg-black bg-opacity-[0.02] rounded-lg border border-black border-opacity-5 justify-start items-center inline-flex">
<div className="h-4 px-2 justify-start items-start gap-2 flex flex-1">
<div className="text-gray-700 text-xs font-medium">
<div className="h-4 px-2 justify-start items-start gap-2 flex flex-1 min-w-0">
<div className="text-gray-700 text-xs font-medium text-ellipsis overflow-hidden whitespace-nowrap">
{isApp ? appUrl : apiUrl}
</div>
</div>
@ -196,7 +196,7 @@ function AppCard({
</div>
</div>
</div>
<div className={'pt-2 flex flex-row items-center'}>
<div className={'pt-2 flex flex-row items-center flex-wrap gap-y-2'}>
{!isApp && <SecretKeyButton className='flex-shrink-0 !h-8 bg-white mr-2' textCls='!text-gray-700 font-medium' iconCls='stroke-[1.2px]' appId={appInfo.id} />}
{OPERATIONS_MAP[cardType].map((op) => {
const disabled

View file

@ -81,10 +81,10 @@ const CustomizeModal: FC<IShareLinkProps> = ({
</div>
<div className='flex py-4'>
<StepNum>3</StepNum>
<div className='flex flex-col w-full'>
<div className='flex flex-col w-full overflow-hidden'>
<div className='text-gray-900'>{t(`${prefixCustomize}.way1.step3`)}</div>
<div className='text-gray-500 text-xs mt-1 mb-2'>{t(`${prefixCustomize}.way1.step3Tip`)}</div>
<pre className='box-border py-3 px-4 bg-gray-100 text-xs font-medium rounded-lg select-text'>
<pre className='overflow-x-scroll box-border py-3 px-4 bg-gray-100 text-xs font-medium rounded-lg select-text'>
NEXT_PUBLIC_APP_ID={`'${appId}'`} <br />
NEXT_PUBLIC_APP_KEY={'\'<Web API Key From Dify>\''} <br />
NEXT_PUBLIC_API_URL={`'${api_base_url}'`}

View file

@ -106,7 +106,7 @@ const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
<div className="mb-4 mt-8 text-gray-900 text-[14px] font-medium leading-tight">
{t(`${prefixEmbedded}.explanation`)}
</div>
<div className="flex items-center justify-between">
<div className="flex items-center justify-between flex-wrap gap-y-2">
{Object.keys(OPTION_MAP).map((v, index) => {
return (
<div
@ -150,7 +150,7 @@ const Embedded = ({ isShow, onClose, appBaseUrl, accessToken }: Props) => {
</Tooltip>
</div>
</div>
<div className="self-stretch p-3 justify-start items-start gap-2 inline-flex">
<div className="p-3 justify-start items-start gap-2 flex overflow-x-auto w-full">
<div className="grow shrink basis-0 text-slate-700 text-[13px] leading-tight font-mono">
<pre className='select-text'>{OPTION_MAP[option].getContent(appBaseUrl, accessToken, isTestEnv)}</pre>
</div>