Compare commits
12 Commits
main
...
chore/offl
| Author | SHA1 | Date |
|---|---|---|
|
|
7b88f09ee7 | 11 months ago |
|
|
81578f1705 | 11 months ago |
|
|
964ce48cbc | 11 months ago |
|
|
779daceeb2 | 11 months ago |
|
|
a294773dd5 | 11 months ago |
|
|
859b4cd6cc | 11 months ago |
|
|
d454214ddc | 11 months ago |
|
|
169ae55635 | 11 months ago |
|
|
015ce09593 | 11 months ago |
|
|
0337b857ff | 11 months ago |
|
|
d6fe22b19e | 11 months ago |
|
|
2c4239c593 | 11 months ago |
@ -0,0 +1,44 @@
|
|||||||
|
'use client'
|
||||||
|
import { RiArrowRightLine, RiImage2Fill } from '@remixicon/react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
const i18nPrefix = 'app.checkLegacy'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
appNum: number,
|
||||||
|
publishedNum: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
const AppTip: FC<Props> = ({
|
||||||
|
appNum,
|
||||||
|
publishedNum,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
return (
|
||||||
|
<div className='fixed bottom-0 left-0 right-0 z-10 border-t border-state-warning-hover px-12 py-4'>
|
||||||
|
<div className="absolute inset-0 bg-[linear-gradient(92deg,_rgba(247,144,9,0.25)_53.67%,_rgba(255,255,255,0)_100%)] opacity-40" />
|
||||||
|
<div className='relative flex items-center'>
|
||||||
|
<div className='relative rounded-lg bg-text-accent p-1.5'>
|
||||||
|
<RiImage2Fill className='size-5 text-text-primary-on-surface' />
|
||||||
|
<div className='absolute left-[-2px] top-[-2px] size-2 rounded-[3px] border border-white bg-components-badge-status-light-error-border-inner p-0.5'>
|
||||||
|
<div className='h-full w-full rounded-[3px] bg-components-badge-status-light-error-bg'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='ml-3'>
|
||||||
|
<div className='system-md-semibold text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||||
|
<div className='system-sm-regular mt-1 flex items-center space-x-0.5 text-text-secondary'>
|
||||||
|
{t(`${i18nPrefix}.description`, { num: appNum, publishedNum })}
|
||||||
|
<Link className='system-sm-semibold text-text-accent' href='/apps/check-legacy'>{t(`${i18nPrefix}.toSolve`)}</Link>
|
||||||
|
<RiArrowRightLine className='size-4 text-components-button-secondary-accent-text' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(AppTip)
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
|
||||||
|
const i18nPrefix = 'app.checkLegacy'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
className?: string,
|
||||||
|
appNum: number,
|
||||||
|
publishedNum: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
const Header: FC<Props> = ({
|
||||||
|
className,
|
||||||
|
appNum,
|
||||||
|
publishedNum,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
return (
|
||||||
|
<div className={cn(className)}>
|
||||||
|
<div className='title-2xl-semi-bold text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||||
|
<div className='system-md-regular mt-1 text-text-tertiary'>{t(`${i18nPrefix}.description`, { num: appNum, publishedNum })}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Header)
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
'use client'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import cn from '@/utils/classnames'
|
||||||
|
import AppIcon from '@/app/components/base/app-icon'
|
||||||
|
|
||||||
|
const i18nPrefix = 'app.checkLegacy.list'
|
||||||
|
type Props = {
|
||||||
|
list: any[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const List: FC<Props> = ({
|
||||||
|
list,
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
return (
|
||||||
|
<div className='h-0 grow overflow-y-auto'>
|
||||||
|
{list.length > 0 ? (
|
||||||
|
<table className={cn('mt-2 w-full min-w-[440px] border-collapse border-0')}>
|
||||||
|
<thead className='system-xs-medium-uppercase text-text-tertiary'>
|
||||||
|
<tr>
|
||||||
|
<td className='whitespace-nowrap rounded-l-lg bg-background-section-burn pl-3 pr-1'>{t(`${i18nPrefix}.appName`)}</td>
|
||||||
|
<td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.published`)}</td>
|
||||||
|
<td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.createBy`)}</td>
|
||||||
|
<td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.lastRequest`)}</td>
|
||||||
|
<td className='whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3'>{t(`${i18nPrefix}.createAt`)}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="system-sm-regular text-text-secondary">
|
||||||
|
{list.map((item, index) => (
|
||||||
|
<tr key={index} className='cursor-pointer border-b border-divider-subtle hover:bg-background-default-hover'>
|
||||||
|
<td className='whitespace-nowrap rounded-l-lg py-2 pl-3 pr-1'>
|
||||||
|
<div className='flex items-center space-x-2'>
|
||||||
|
<AppIcon size='tiny' />
|
||||||
|
<div>Python bug fixer</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className='whitespace-nowrap py-1.5 pl-3'>{t('app.checkLegacy.yes')}</td>
|
||||||
|
<td className='whitespace-nowrap py-1.5 pl-3'>Evan · evan@dify.ai</td>
|
||||||
|
<td className='whitespace-nowrap py-1.5 pl-3'>2023-03-21 10:25</td>
|
||||||
|
<td className='whitespace-nowrap rounded-r-lg py-1.5 pl-3'>2023-03-21 10:25</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
) : (
|
||||||
|
<div className='system-md-regular flex items-center justify-center text-text-secondary'>{t(`${i18nPrefix}.noData`)}</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default React.memo(List)
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
'use client'
|
||||||
|
import { RiBookOpenLine } from '@remixicon/react'
|
||||||
|
import type { FC } from 'react'
|
||||||
|
import React from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
const i18nPrefix = 'app.checkLegacy.tip'
|
||||||
|
|
||||||
|
const Tip: FC = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
return (
|
||||||
|
<div className='w-[316px] rounded-xl bg-background-section p-6'>
|
||||||
|
<div className='inline-flex rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-border p-2 shadow-lg backdrop-blur-[5px]'>
|
||||||
|
<RiBookOpenLine className='size-5 text-text-accent' />
|
||||||
|
</div>
|
||||||
|
<div className='system-xl-semibold mt-3 text-text-primary'>{t(`${i18nPrefix}.title`)}</div>
|
||||||
|
<div className='system-sm-regular mt-2 text-text-secondary'>{t(`${i18nPrefix}.description`)}</div>
|
||||||
|
<a className='system-sm-medium mt-2 text-text-accent' target='_blank' href='todo'>{t(`${i18nPrefix}.learnMore`)}</a>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(Tip)
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
'use client'
|
||||||
|
import Sort from '@/app/components/base/sort'
|
||||||
|
import Header from './components/header'
|
||||||
|
import List from './components/list'
|
||||||
|
import useLegacyList from './use-legacy-list'
|
||||||
|
import Chip from '@/app/components/base/chip'
|
||||||
|
import { RiFilter3Line, RiLoopLeftLine } from '@remixicon/react'
|
||||||
|
import { useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Button from '@/app/components/base/button'
|
||||||
|
import Pagination from '@/app/components/base/pagination'
|
||||||
|
import { APP_PAGE_LIMIT } from '@/config'
|
||||||
|
import { noop } from 'lodash'
|
||||||
|
import Tip from './components/tip'
|
||||||
|
|
||||||
|
const i18nPrefix = 'app.checkLegacy'
|
||||||
|
const Page = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const {
|
||||||
|
list,
|
||||||
|
total,
|
||||||
|
sort_by,
|
||||||
|
setOrderBy,
|
||||||
|
published,
|
||||||
|
setPublished,
|
||||||
|
clearPublished,
|
||||||
|
} = useLegacyList()
|
||||||
|
|
||||||
|
const handleSelectPublished = useCallback(({ value }: { value: number }) => {
|
||||||
|
setPublished(value)
|
||||||
|
}, [setPublished])
|
||||||
|
|
||||||
|
const renderTriggerContent = useCallback(() => {
|
||||||
|
if(published === undefined)
|
||||||
|
return t(`${i18nPrefix}.published`)
|
||||||
|
return (
|
||||||
|
<div className='flex space-x-1'>
|
||||||
|
<div>{t(`${i18nPrefix}.published`)}</div>
|
||||||
|
<span className='system-sm-medium text-text-secondary'>{published === 1 ? t(`${i18nPrefix}.yes`) : t(`${i18nPrefix}.no`)}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}, [published, t])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex grow rounded-t-2xl border-t border-effects-highlight bg-background-default-subtle px-6 pt-4'>
|
||||||
|
<div className='flex h-full grow flex-col pr-6'>
|
||||||
|
<Header className='shrink-0' appNum={5} publishedNum={3}/>
|
||||||
|
{/* Filter */}
|
||||||
|
<div className='mb-2 mt-4 flex shrink-0 items-center justify-between'>
|
||||||
|
<div className='flex items-center gap-2'>
|
||||||
|
<Chip
|
||||||
|
className='min-w-[150px]'
|
||||||
|
panelClassName='w-[270px]'
|
||||||
|
leftIcon={<RiFilter3Line className='h-4 w-4 text-text-secondary' />}
|
||||||
|
value={published}
|
||||||
|
renderTriggerContent={renderTriggerContent}
|
||||||
|
onSelect={handleSelectPublished}
|
||||||
|
onClear={clearPublished}
|
||||||
|
items={[
|
||||||
|
{ value: 1, name: t(`${i18nPrefix}.yes`) },
|
||||||
|
{ value: 0, name: t(`${i18nPrefix}.no`) },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<div className='h-3.5 w-px bg-divider-regular'></div>
|
||||||
|
<Sort
|
||||||
|
// '-' means descending order
|
||||||
|
order={sort_by?.startsWith('-') ? '-' : ''}
|
||||||
|
value={sort_by?.replace('-', '') || 'created_at'}
|
||||||
|
items={[
|
||||||
|
{ value: 'created_at', name: t(`${i18nPrefix}.createAt`) },
|
||||||
|
{ value: 'last_request', name: t(`${i18nPrefix}.lastRequest`) },
|
||||||
|
]}
|
||||||
|
onSelect={setOrderBy}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Button >
|
||||||
|
<RiLoopLeftLine className='mr-1 h-4 w-4' />
|
||||||
|
{t('common.operation.reset')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<List list={list} />
|
||||||
|
{(total && total > APP_PAGE_LIMIT)
|
||||||
|
? <div className='flex justify-end'><Pagination
|
||||||
|
className='shrink-0'
|
||||||
|
current={1}
|
||||||
|
onChange={noop}
|
||||||
|
total={total}
|
||||||
|
limit={10}
|
||||||
|
onLimitChange={noop}
|
||||||
|
/></div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
<div className='ml-3 shrink-0 pr-8 pt-[108px]'>
|
||||||
|
<Tip />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Page
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
import produce from 'immer'
|
||||||
|
import { useCallback, useState } from 'react'
|
||||||
|
|
||||||
|
const useLegacyList = () => {
|
||||||
|
const list: any[] = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}] // Placeholder for the list, replace with actual data fetching logic
|
||||||
|
const [queryParams, setQueryParams] = useState<Record<string, any>>({})
|
||||||
|
const {
|
||||||
|
sort_by,
|
||||||
|
published,
|
||||||
|
} = queryParams
|
||||||
|
const setOrderBy = useCallback((sortBy: string) => {
|
||||||
|
const nextValue = produce(queryParams, (draft) => {
|
||||||
|
draft.sort_by = sortBy
|
||||||
|
})
|
||||||
|
setQueryParams(nextValue)
|
||||||
|
}, [queryParams])
|
||||||
|
|
||||||
|
const setPublished = useCallback((value: number) => {
|
||||||
|
const nextValue = produce(queryParams, (draft) => {
|
||||||
|
draft.published = value
|
||||||
|
})
|
||||||
|
setQueryParams(nextValue)
|
||||||
|
}, [queryParams])
|
||||||
|
|
||||||
|
const clearPublished = useCallback(() => {
|
||||||
|
const nextValue = produce(queryParams, (draft) => {
|
||||||
|
draft.published = undefined
|
||||||
|
})
|
||||||
|
setQueryParams(nextValue)
|
||||||
|
}, [queryParams])
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: 5,
|
||||||
|
list,
|
||||||
|
sort_by,
|
||||||
|
setOrderBy,
|
||||||
|
published,
|
||||||
|
setPublished,
|
||||||
|
clearPublished,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useLegacyList
|
||||||
Loading…
Reference in New Issue