chore(web): new lint setup (#30020)

Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
Stephen Zhou
2025-12-23 16:58:55 +08:00
committed by GitHub
co-authored by yyh
parent 9701a2994b
commit f2842da397
3356 changed files with 85039 additions and 81271 deletions
+9 -8
View File
@@ -16,18 +16,19 @@ const ApiServer: FC<ApiServerProps> = ({
const { t } = useTranslation()
return (
<div className='flex flex-wrap items-center gap-y-2'>
<div className='mr-2 flex h-8 items-center rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal pl-1.5 pr-1 leading-5'>
<div className='mr-0.5 h-5 shrink-0 rounded-md border border-divider-subtle px-1.5 text-[11px] text-text-tertiary'>{t('appApi.apiServer')}</div>
<div className='w-fit truncate px-1 text-[13px] font-medium text-text-secondary sm:w-[248px]'>{apiBaseUrl}</div>
<div className='mx-1 h-[14px] w-[1px] bg-divider-regular'></div>
<CopyFeedback content={apiBaseUrl}/>
<div className="flex flex-wrap items-center gap-y-2">
<div className="mr-2 flex h-8 items-center rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal pl-1.5 pr-1 leading-5">
<div className="mr-0.5 h-5 shrink-0 rounded-md border border-divider-subtle px-1.5 text-[11px] text-text-tertiary">{t('appApi.apiServer')}</div>
<div className="w-fit truncate px-1 text-[13px] font-medium text-text-secondary sm:w-[248px]">{apiBaseUrl}</div>
<div className="mx-1 h-[14px] w-[1px] bg-divider-regular"></div>
<CopyFeedback content={apiBaseUrl} />
</div>
<div className='mr-2 flex h-8 items-center rounded-lg border-[0.5px] border-[#D1FADF] bg-[#ECFDF3] px-3 text-xs font-semibold text-[#039855]'>
<div className="mr-2 flex h-8 items-center rounded-lg border-[0.5px] border-[#D1FADF] bg-[#ECFDF3] px-3 text-xs font-semibold text-[#039855]">
{t('appApi.ok')}
</div>
<SecretKeyButton
className='!h-8 shrink-0' appId={appId}
className="!h-8 shrink-0"
appId={appId}
/>
</div>
)
+19 -21
View File
@@ -1,4 +1,6 @@
'use client'
import type { PropsWithChildren, ReactElement, ReactNode } from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import {
Children,
createContext,
@@ -7,11 +9,9 @@ import {
useRef,
useState,
} from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import { Tag } from './tag'
import { cn } from '@/utils/classnames'
import { writeTextToClipboard } from '@/utils/clipboard'
import type { PropsWithChildren, ReactElement, ReactNode } from 'react'
import { Tag } from './tag'
type IChildrenProps = {
children: React.ReactNode
@@ -50,10 +50,9 @@ function CopyButton({ code }: { code: string }) {
return (
<button
type="button"
className={cn('group/button absolute right-4 top-1.5 overflow-hidden rounded-full py-1 pl-2 pr-3 text-2xs font-medium opacity-0 backdrop-blur transition focus:opacity-100 group-hover:opacity-100',
copied
? 'bg-emerald-400/10 ring-1 ring-inset ring-emerald-400/20'
: 'hover:bg-white/7.5 dark:bg-white/2.5 bg-white/5 dark:hover:bg-white/5')}
className={cn('group/button absolute right-4 top-1.5 overflow-hidden rounded-full py-1 pl-2 pr-3 text-2xs font-medium opacity-0 backdrop-blur transition focus:opacity-100 group-hover:opacity-100', copied
? 'bg-emerald-400/10 ring-1 ring-inset ring-emerald-400/20'
: 'hover:bg-white/7.5 dark:bg-white/2.5 bg-white/5 dark:hover:bg-white/5')}
onClick={() => {
writeTextToClipboard(code).then(() => {
setCopyCount(count => count + 1)
@@ -62,16 +61,14 @@ function CopyButton({ code }: { code: string }) {
>
<span
aria-hidden={copied}
className={cn('pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300',
copied && '-translate-y-1.5 opacity-0')}
className={cn('pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300', copied && '-translate-y-1.5 opacity-0')}
>
<ClipboardIcon className="h-5 w-5 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" />
Copy
</span>
<span
aria-hidden={!copied}
className={cn('pointer-events-none absolute inset-0 flex items-center justify-center text-emerald-400 transition duration-300',
!copied && 'translate-y-1.5 opacity-0')}
className={cn('pointer-events-none absolute inset-0 flex items-center justify-center text-emerald-400 transition duration-300', !copied && 'translate-y-1.5 opacity-0')}
>
Copied!
</span>
@@ -79,7 +76,7 @@ function CopyButton({ code }: { code: string }) {
)
}
function CodePanelHeader({ tag, label }: { tag?: string; label?: string }) {
function CodePanelHeader({ tag, label }: { tag?: string, label?: string }) {
if (!tag && !label)
return null
@@ -129,11 +126,13 @@ function CodePanel({ tag, label, children, targetCode }: ICodePanelProps) {
{/* <CopyButton code={child.props.code ?? code} /> */}
{/* <CopyButton code={child.props.children.props.children} /> */}
<pre className="overflow-x-auto p-4 text-xs text-white">
{targetCode?.code ? (
<code>{targetCode?.code}</code>
) : (
child
)}
{targetCode?.code
? (
<code>{targetCode?.code}</code>
)
: (
child
)}
</pre>
<CopyButton code={targetCode?.code ?? child.props.children.props.children} />
</div>
@@ -162,10 +161,9 @@ function CodeGroupHeader({ title, tabTitles, selectedIndex }: CodeGroupHeaderPro
{tabTitles!.map((tabTitle, tabIndex) => (
<Tab
key={tabIndex}
className={cn('border-b py-3 transition focus:[&:not(:focus-visible)]:outline-none',
tabIndex === selectedIndex
? 'border-emerald-500 text-emerald-400'
: 'border-transparent text-zinc-400 hover:text-zinc-300')}
className={cn('border-b py-3 transition focus:[&:not(:focus-visible)]:outline-none', tabIndex === selectedIndex
? 'border-emerald-500 text-emerald-400'
: 'border-transparent text-zinc-400 hover:text-zinc-300')}
>
{tabTitle}
</Tab>
+87 -83
View File
@@ -1,25 +1,25 @@
'use client'
import { useEffect, useMemo, useState } from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { RiCloseLine, RiListUnordered } from '@remixicon/react'
import TemplateEn from './template/template.en.mdx'
import TemplateZh from './template/template.zh.mdx'
import TemplateJa from './template/template.ja.mdx'
import TemplateAdvancedChatEn from './template/template_advanced_chat.en.mdx'
import TemplateAdvancedChatZh from './template/template_advanced_chat.zh.mdx'
import TemplateAdvancedChatJa from './template/template_advanced_chat.ja.mdx'
import TemplateWorkflowEn from './template/template_workflow.en.mdx'
import TemplateWorkflowZh from './template/template_workflow.zh.mdx'
import TemplateWorkflowJa from './template/template_workflow.ja.mdx'
import TemplateChatEn from './template/template_chat.en.mdx'
import TemplateChatZh from './template/template_chat.zh.mdx'
import TemplateChatJa from './template/template_chat.ja.mdx'
import { useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n-config/language'
import useTheme from '@/hooks/use-theme'
import { LanguagesSupported } from '@/i18n-config/language'
import { AppModeEnum, Theme } from '@/types/app'
import { cn } from '@/utils/classnames'
import TemplateEn from './template/template.en.mdx'
import TemplateJa from './template/template.ja.mdx'
import TemplateZh from './template/template.zh.mdx'
import TemplateAdvancedChatEn from './template/template_advanced_chat.en.mdx'
import TemplateAdvancedChatJa from './template/template_advanced_chat.ja.mdx'
import TemplateAdvancedChatZh from './template/template_advanced_chat.zh.mdx'
import TemplateChatEn from './template/template_chat.en.mdx'
import TemplateChatJa from './template/template_chat.ja.mdx'
import TemplateChatZh from './template/template_chat.zh.mdx'
import TemplateWorkflowEn from './template/template_workflow.en.mdx'
import TemplateWorkflowJa from './template/template_workflow.ja.mdx'
import TemplateWorkflowZh from './template/template_workflow.zh.mdx'
type IDocProps = {
appDetail: any
@@ -28,7 +28,7 @@ type IDocProps = {
const Doc = ({ appDetail }: IDocProps) => {
const { locale } = useContext(I18n)
const { t } = useTranslation()
const [toc, setToc] = useState<Array<{ href: string; text: string }>>([])
const [toc, setToc] = useState<Array<{ href: string, text: string }>>([])
const [isTocExpanded, setIsTocExpanded] = useState(false)
const [activeSection, setActiveSection] = useState<string>('')
const { theme } = useTheme()
@@ -58,7 +58,7 @@ const Doc = ({ appDetail }: IDocProps) => {
}
}
return null
}).filter((item): item is { href: string; text: string } => item !== null)
}).filter((item): item is { href: string, text: string } => item !== null)
setToc(tocItems)
if (tocItems.length > 0)
setActiveSection(tocItems[0].href.replace('#', ''))
@@ -97,7 +97,7 @@ const Doc = ({ appDetail }: IDocProps) => {
}
}, [toc, activeSection])
const handleTocClick = (e: React.MouseEvent<HTMLAnchorElement>, item: { href: string; text: string }) => {
const handleTocClick = (e: React.MouseEvent<HTMLAnchorElement>, item: { href: string, text: string }) => {
e.preventDefault()
const targetId = item.href.replace('#', '')
const element = document.getElementById(targetId)
@@ -163,75 +163,79 @@ const Doc = ({ appDetail }: IDocProps) => {
<div className={`fixed right-20 top-32 z-10 transition-all duration-150 ease-out ${isTocExpanded ? 'w-[280px]' : 'w-11'}`}>
{isTocExpanded
? (
<nav className="toc flex max-h-[calc(100vh-150px)] w-full flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-background-default-hover shadow-xl">
<div className="relative z-10 flex items-center justify-between border-b border-components-panel-border-subtle bg-background-default-hover px-4 py-2.5">
<span className="text-xs font-medium uppercase tracking-wide text-text-tertiary">
{t('appApi.develop.toc')}
</span>
<button type="button"
onClick={() => setIsTocExpanded(false)}
className="group flex h-6 w-6 items-center justify-center rounded-md transition-colors hover:bg-state-base-hover"
aria-label="Close"
>
<RiCloseLine className="h-3 w-3 text-text-quaternary transition-colors group-hover:text-text-secondary" />
</button>
</div>
<nav className="toc flex max-h-[calc(100vh-150px)] w-full flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-background-default-hover shadow-xl">
<div className="relative z-10 flex items-center justify-between border-b border-components-panel-border-subtle bg-background-default-hover px-4 py-2.5">
<span className="text-xs font-medium uppercase tracking-wide text-text-tertiary">
{t('appApi.develop.toc')}
</span>
<button
type="button"
onClick={() => setIsTocExpanded(false)}
className="group flex h-6 w-6 items-center justify-center rounded-md transition-colors hover:bg-state-base-hover"
aria-label="Close"
>
<RiCloseLine className="h-3 w-3 text-text-quaternary transition-colors group-hover:text-text-secondary" />
</button>
</div>
<div className="from-components-panel-border-subtle/20 pointer-events-none absolute left-0 right-0 top-[41px] z-10 h-2 bg-gradient-to-b to-transparent"></div>
<div className="pointer-events-none absolute left-0 right-0 top-[43px] z-10 h-3 bg-gradient-to-b from-background-default-hover to-transparent"></div>
<div className="from-components-panel-border-subtle/20 pointer-events-none absolute left-0 right-0 top-[41px] z-10 h-2 bg-gradient-to-b to-transparent"></div>
<div className="pointer-events-none absolute left-0 right-0 top-[43px] z-10 h-3 bg-gradient-to-b from-background-default-hover to-transparent"></div>
<div className="relative flex-1 overflow-y-auto px-3 py-3 pt-1">
{toc.length === 0 ? (
<div className="px-2 py-8 text-center text-xs text-text-quaternary">
{t('appApi.develop.noContent')}
</div>
) : (
<ul className="space-y-0.5">
{toc.map((item, index) => {
const isActive = activeSection === item.href.replace('#', '')
return (
<li key={index}>
<a
href={item.href}
onClick={e => handleTocClick(e, item)}
className={cn(
'group relative flex items-center rounded-md px-3 py-2 text-[13px] transition-all duration-200',
isActive
? 'bg-state-base-hover font-medium text-text-primary'
: 'text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
)}
>
<span
className={cn(
'mr-2 h-1.5 w-1.5 rounded-full transition-all duration-200',
isActive
? 'scale-100 bg-text-accent'
: 'scale-75 bg-components-panel-border',
)}
/>
<span className="flex-1 truncate">
{item.text}
</span>
</a>
</li>
<div className="relative flex-1 overflow-y-auto px-3 py-3 pt-1">
{toc.length === 0
? (
<div className="px-2 py-8 text-center text-xs text-text-quaternary">
{t('appApi.develop.noContent')}
</div>
)
})}
</ul>
)}
</div>
: (
<ul className="space-y-0.5">
{toc.map((item, index) => {
const isActive = activeSection === item.href.replace('#', '')
return (
<li key={index}>
<a
href={item.href}
onClick={e => handleTocClick(e, item)}
className={cn(
'group relative flex items-center rounded-md px-3 py-2 text-[13px] transition-all duration-200',
isActive
? 'bg-state-base-hover font-medium text-text-primary'
: 'text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
)}
>
<span
className={cn(
'mr-2 h-1.5 w-1.5 rounded-full transition-all duration-200',
isActive
? 'scale-100 bg-text-accent'
: 'scale-75 bg-components-panel-border',
)}
/>
<span className="flex-1 truncate">
{item.text}
</span>
</a>
</li>
)
})}
</ul>
)}
</div>
<div className="pointer-events-none absolute bottom-0 left-0 right-0 z-10 h-4 rounded-b-xl bg-gradient-to-t from-background-default-hover to-transparent"></div>
</nav>
)
<div className="pointer-events-none absolute bottom-0 left-0 right-0 z-10 h-4 rounded-b-xl bg-gradient-to-t from-background-default-hover to-transparent"></div>
</nav>
)
: (
<button type="button"
onClick={() => setIsTocExpanded(true)}
className="group flex h-11 w-11 items-center justify-center rounded-full border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg transition-all duration-150 hover:bg-background-default-hover hover:shadow-xl"
aria-label="Open table of contents"
>
<RiListUnordered className="h-5 w-5 text-text-tertiary transition-colors group-hover:text-text-secondary" />
</button>
)}
<button
type="button"
onClick={() => setIsTocExpanded(true)}
className="group flex h-11 w-11 items-center justify-center rounded-full border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg transition-all duration-150 hover:bg-background-default-hover hover:shadow-xl"
aria-label="Open table of contents"
>
<RiListUnordered className="h-5 w-5 text-text-tertiary transition-colors group-hover:text-text-secondary" />
</button>
)}
</div>
<article className={cn('prose-xl prose', theme === Theme.dark && 'prose-invert')}>
{Template}
+7 -7
View File
@@ -1,8 +1,8 @@
'use client'
import Doc from '@/app/components/develop/doc'
import { useStore as useAppStore } from '@/app/components/app/store'
import Loading from '@/app/components/base/loading'
import ApiServer from '@/app/components/develop/ApiServer'
import { useStore as useAppStore } from '@/app/components/app/store'
import Doc from '@/app/components/develop/doc'
type IDevelopMainProps = {
appId: string
@@ -13,19 +13,19 @@ const DevelopMain = ({ appId }: IDevelopMainProps) => {
if (!appDetail) {
return (
<div className='flex h-full items-center justify-center bg-background-default'>
<div className="flex h-full items-center justify-center bg-background-default">
<Loading />
</div>
)
}
return (
<div className='relative flex h-full flex-col overflow-hidden'>
<div className='flex shrink-0 items-center justify-between border-b border-solid border-b-divider-regular px-6 py-2'>
<div className='text-lg font-medium text-text-primary'></div>
<div className="relative flex h-full flex-col overflow-hidden">
<div className="flex shrink-0 items-center justify-between border-b border-solid border-b-divider-regular px-6 py-2">
<div className="text-lg font-medium text-text-primary"></div>
<ApiServer apiBaseUrl={appDetail.api_base_url} appId={appId} />
</div>
<div className='grow overflow-auto px-4 py-4 sm:px-10'>
<div className="grow overflow-auto px-4 py-4 sm:px-10">
<Doc appDetail={appDetail} />
</div>
</div>
+5 -6
View File
@@ -43,14 +43,14 @@ export const Heading = function H2({
}
return (
<>
<span id={name?.replace(/^#/, '')} className='relative -top-28' />
<div className="flex items-center gap-x-3" >
<span id={name?.replace(/^#/, '')} className="relative -top-28" />
<div className="flex items-center gap-x-3">
<span className={`rounded-lg px-1.5 font-mono text-[0.625rem] font-semibold leading-6 ring-1 ring-inset ${style}`}>{method}</span>
{/* <span className="h-0.5 w-0.5 rounded-full bg-zinc-300 dark:bg-zinc-600"></span> */}
<span className="font-mono text-xs text-zinc-400">{url}</span>
</div>
<h2 className='mt-2 scroll-mt-32'>
<a href={name} className='group text-inherit no-underline hover:text-inherit'>{title}</a>
<h2 className="mt-2 scroll-mt-32">
<a href={name} className="group text-inherit no-underline hover:text-inherit">{title}</a>
</h2>
</>
@@ -71,8 +71,7 @@ type IColProps = IChildrenProps & {
export function Col({ children, sticky = false }: IColProps) {
return (
<div
className={cn('[&>:first-child]:mt-0 [&>:last-child]:mb-0',
sticky && 'xl:sticky xl:top-24')}
className={cn('[&>:first-child]:mt-0 [&>:last-child]:mb-0', sticky && 'xl:sticky xl:top-24')}
>
{children}
</div>
@@ -1,9 +1,9 @@
'use client'
import React, { useEffect, useState } from 'react'
import copy from 'copy-to-clipboard'
import { t } from 'i18next'
import Tooltip from '@/app/components/base/tooltip'
import React, { useEffect, useState } from 'react'
import CopyFeedback from '@/app/components/base/copy-feedback'
import Tooltip from '@/app/components/base/tooltip'
type IInputCopyProps = {
value?: string
@@ -34,21 +34,24 @@ const InputCopy = ({
<div className={`flex items-center rounded-lg bg-components-input-bg-normal py-2 hover:bg-state-base-hover ${className}`}>
<div className="flex h-5 grow items-center">
{children}
<div className='relative h-full grow text-[13px]'>
<div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2' onClick={() => {
copy(value)
setIsCopied(true)
}}>
<div className="relative h-full grow text-[13px]">
<div
className="r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2"
onClick={() => {
copy(value)
setIsCopied(true)
}}
>
<Tooltip
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
position='bottom'
position="bottom"
>
<span className='text-text-secondary'>{value}</span>
<span className="text-text-secondary">{value}</span>
</Tooltip>
</div>
</div>
<div className="h-4 w-px shrink-0 bg-divider-regular" />
<div className='mx-1'><CopyFeedback content={value} /></div>
<div className="mx-1"><CopyFeedback content={value} /></div>
</div>
</div>
)
@@ -1,7 +1,7 @@
'use client'
import { RiKey2Line } from '@remixicon/react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiKey2Line } from '@remixicon/react'
import Button from '@/app/components/base/button'
import SecretKeyModal from '@/app/components/develop/secret-key/secret-key-modal'
@@ -19,11 +19,11 @@ const SecretKeyButton = ({ className, appId, textCls }: ISecretKeyButtonProps) =
<Button
className={`px-3 ${className}`}
onClick={() => setVisible(true)}
size='small'
variant='ghost'
size="small"
variant="ghost"
>
<div className={'flex h-3.5 w-3.5 items-center justify-center'}>
<RiKey2Line className='h-3.5 w-3.5 text-text-tertiary' />
<div className="flex h-3.5 w-3.5 items-center justify-center">
<RiKey2Line className="h-3.5 w-3.5 text-text-tertiary" />
</div>
<div className={`system-xs-medium px-[3px] text-text-tertiary ${textCls}`}>{t('appApi.apiKey')}</div>
</Button>
@@ -1,11 +1,11 @@
'use client'
import { useTranslation } from 'react-i18next'
import type { CreateApiKeyResponse } from '@/models/app'
import { XMarkIcon } from '@heroicons/react/20/solid'
import InputCopy from './input-copy'
import s from './style.module.css'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import type { CreateApiKeyResponse } from '@/models/app'
import InputCopy from './input-copy'
import s from './style.module.css'
type ISecretKeyGenerateModalProps = {
isShow: boolean
@@ -26,17 +26,17 @@ const SecretKeyGenerateModal = ({
<div className="-mr-2 -mt-6 mb-4 flex justify-end">
<XMarkIcon className="h-6 w-6 cursor-pointer text-text-tertiary" onClick={onClose} />
</div>
<p className='mt-1 text-[13px] font-normal leading-5 text-text-tertiary'>{t('appApi.apiKeyModal.generateTips')}</p>
<div className='my-4'>
<InputCopy className='w-full' value={newKey?.token} />
<p className="mt-1 text-[13px] font-normal leading-5 text-text-tertiary">{t('appApi.apiKeyModal.generateTips')}</p>
<div className="my-4">
<InputCopy className="w-full" value={newKey?.token} />
</div>
<div className='my-4 flex justify-end'>
<div className="my-4 flex justify-end">
<Button className={`shrink-0 ${s.w64}`} onClick={onClose}>
<span className='text-xs font-medium text-text-secondary'>{t('appApi.actionMsg.ok')}</span>
<span className="text-xs font-medium text-text-secondary">{t('appApi.actionMsg.ok')}</span>
</Button>
</div>
</Modal >
</Modal>
)
}
@@ -1,16 +1,19 @@
'use client'
import type { CreateApiKeyResponse } from '@/models/app'
import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid'
import { RiDeleteBinLine } from '@remixicon/react'
import {
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { RiDeleteBinLine } from '@remixicon/react'
import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid'
import SecretKeyGenerateModal from './secret-key-generate'
import s from './style.module.css'
import ActionButton from '@/app/components/base/action-button'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Confirm from '@/app/components/base/confirm'
import CopyFeedback from '@/app/components/base/copy-feedback'
import Loading from '@/app/components/base/loading'
import Modal from '@/app/components/base/modal'
import { useAppContext } from '@/context/app-context'
import useTimestamp from '@/hooks/use-timestamp'
import {
createApikey as createAppApikey,
delApikey as delAppApikey,
@@ -19,13 +22,10 @@ import {
createApikey as createDatasetApikey,
delApikey as delDatasetApikey,
} from '@/service/datasets'
import type { CreateApiKeyResponse } from '@/models/app'
import Loading from '@/app/components/base/loading'
import Confirm from '@/app/components/base/confirm'
import useTimestamp from '@/hooks/use-timestamp'
import { useAppContext } from '@/context/app-context'
import { useAppApiKeys, useInvalidateAppApiKeys } from '@/service/use-apps'
import { useDatasetApiKeys, useInvalidateDatasetApiKeys } from '@/service/knowledge/use-dataset'
import { useAppApiKeys, useInvalidateAppApiKeys } from '@/service/use-apps'
import SecretKeyGenerateModal from './secret-key-generate'
import s from './style.module.css'
type ISecretKeyModalProps = {
isShow: boolean
@@ -92,24 +92,24 @@ const SecretKeyModal = ({
<div className="-mr-2 -mt-6 mb-4 flex justify-end">
<XMarkIcon className="h-6 w-6 cursor-pointer text-text-tertiary" onClick={onClose} />
</div>
<p className='mt-1 shrink-0 text-[13px] font-normal leading-5 text-text-tertiary'>{t('appApi.apiKeyModal.apiSecretKeyTips')}</p>
{isApiKeysLoading && <div className='mt-4'><Loading /></div>}
<p className="mt-1 shrink-0 text-[13px] font-normal leading-5 text-text-tertiary">{t('appApi.apiKeyModal.apiSecretKeyTips')}</p>
{isApiKeysLoading && <div className="mt-4"><Loading /></div>}
{
!!apiKeysList?.data?.length && (
<div className='mt-4 flex grow flex-col overflow-hidden'>
<div className='flex h-9 shrink-0 items-center border-b border-divider-regular text-xs font-semibold text-text-tertiary'>
<div className='w-64 shrink-0 px-3'>{t('appApi.apiKeyModal.secretKey')}</div>
<div className='w-[200px] shrink-0 px-3'>{t('appApi.apiKeyModal.created')}</div>
<div className='w-[200px] shrink-0 px-3'>{t('appApi.apiKeyModal.lastUsed')}</div>
<div className='grow px-3'></div>
<div className="mt-4 flex grow flex-col overflow-hidden">
<div className="flex h-9 shrink-0 items-center border-b border-divider-regular text-xs font-semibold text-text-tertiary">
<div className="w-64 shrink-0 px-3">{t('appApi.apiKeyModal.secretKey')}</div>
<div className="w-[200px] shrink-0 px-3">{t('appApi.apiKeyModal.created')}</div>
<div className="w-[200px] shrink-0 px-3">{t('appApi.apiKeyModal.lastUsed')}</div>
<div className="grow px-3"></div>
</div>
<div className='grow overflow-auto'>
<div className="grow overflow-auto">
{apiKeysList.data.map(api => (
<div className='flex h-9 items-center border-b border-divider-regular text-sm font-normal text-text-secondary' key={api.id}>
<div className='w-64 shrink-0 truncate px-3 font-mono'>{generateToken(api.token)}</div>
<div className='w-[200px] shrink-0 truncate px-3'>{formatTime(Number(api.created_at), t('appLog.dateTimeFormat') as string)}</div>
<div className='w-[200px] shrink-0 truncate px-3'>{api.last_used_at ? formatTime(Number(api.last_used_at), t('appLog.dateTimeFormat') as string) : t('appApi.never')}</div>
<div className='flex grow space-x-2 px-3'>
<div className="flex h-9 items-center border-b border-divider-regular text-sm font-normal text-text-secondary" key={api.id}>
<div className="w-64 shrink-0 truncate px-3 font-mono">{generateToken(api.token)}</div>
<div className="w-[200px] shrink-0 truncate px-3">{formatTime(Number(api.created_at), t('appLog.dateTimeFormat') as string)}</div>
<div className="w-[200px] shrink-0 truncate px-3">{api.last_used_at ? formatTime(Number(api.last_used_at), t('appLog.dateTimeFormat') as string) : t('appApi.never')}</div>
<div className="flex grow space-x-2 px-3">
<CopyFeedback content={api.token} />
{isCurrentWorkspaceManager && (
<ActionButton
@@ -118,7 +118,7 @@ const SecretKeyModal = ({
setShowConfirmDelete(true)
}}
>
<RiDeleteBinLine className='h-4 w-4' />
<RiDeleteBinLine className="h-4 w-4" />
</ActionButton>
)}
</div>
@@ -128,13 +128,13 @@ const SecretKeyModal = ({
</div>
)
}
<div className='flex'>
<div className="flex">
<Button className={`mt-4 flex shrink-0 ${s.autoWidth}`} onClick={onCreate} disabled={!currentWorkspace || !isCurrentWorkspaceEditor}>
<PlusIcon className='mr-1 flex h-4 w-4 shrink-0' />
<div className='text-xs font-medium text-text-secondary'>{t('appApi.apiKeyModal.createNewSecretKey')}</div>
<PlusIcon className="mr-1 flex h-4 w-4 shrink-0" />
<div className="text-xs font-medium text-text-secondary">{t('appApi.apiKeyModal.createNewSecretKey')}</div>
</Button>
</div>
<SecretKeyGenerateModal className='shrink-0' isShow={isVisible} onClose={() => setVisible(false)} newKey={newKey} />
<SecretKeyGenerateModal className="shrink-0" isShow={isVisible} onClose={() => setVisible(false)} newKey={newKey} />
{showConfirmDelete && (
<Confirm
title={`${t('appApi.actionMsg.deleteConfirmTitle')}`}
@@ -147,7 +147,7 @@ const SecretKeyModal = ({
}}
/>
)}
</Modal >
</Modal>
)
}
+1 -3
View File
@@ -53,9 +53,7 @@ export function Tag({
}: ITagProps) {
return (
<span
className={cn('font-mono text-[0.625rem] font-semibold leading-6',
variantStyles[variant],
colorStyles[color][variant])}
className={cn('font-mono text-[0.625rem] font-semibold leading-6', variantStyles[variant], colorStyles[color][variant])}
>
{children}
</span>