dify
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
@keyframes realistic-blink {
|
||||
0% { fill: #37ff37; opacity: 0.4; }
|
||||
15% { fill: #37ff37; opacity: 0.9; }
|
||||
25% { fill: #37ff37; opacity: 0.3; }
|
||||
38% { fill: #ff4444; opacity: 0.8; }
|
||||
42% { fill: #ff4444; opacity: 0.3; }
|
||||
58% { fill: #37ff37; opacity: 0.9; }
|
||||
65% { fill: #37ff37; opacity: 0.4; }
|
||||
79% { fill: #ff4444; opacity: 0.8; }
|
||||
84% { fill: #ff4444; opacity: 0.3; }
|
||||
92% { fill: #37ff37; opacity: 0.8; }
|
||||
100% { fill: #37ff37; opacity: 0.4; }
|
||||
}
|
||||
|
||||
@keyframes drop {
|
||||
0% {
|
||||
transform: translateY(-4px);
|
||||
opacity: 0;
|
||||
}
|
||||
5% {
|
||||
transform: translateY(-4px);
|
||||
opacity: 1;
|
||||
}
|
||||
65% {
|
||||
transform: translateY(2px);
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
transform: translateY(2px);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(2px);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#downloadingIconLight {
|
||||
animation: realistic-blink 3s infinite ease-in-out;
|
||||
}
|
||||
|
||||
#downloadingIconArrow {
|
||||
animation: drop 1.2s cubic-bezier(0.4, 0, 1, 1) infinite;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import s from './downloading-icon.module.css'
|
||||
|
||||
const DownloadingIcon = () => {
|
||||
return (
|
||||
<div className="inline-flex text-components-button-secondary-text">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" className="install-icon">
|
||||
<g id="install-line">
|
||||
<path d="M8 2V4H5L4.999 14H18.999L19 4H16V2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V3C3 2.44772 3.44772 2 4 2H8ZM18.999 16H4.999L5 20H19L18.999 16Z" fill="currentColor"/>
|
||||
<path id={s.downloadingIconLight} d="M17 19V17H15V19H17Z"/>
|
||||
<path id={s.downloadingIconArrow} d="M13 2V7H16L12 11L8 7H11V2H13Z" fill="currentColor"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DownloadingIcon
|
||||
66
dify/web/app/components/header/plugins-nav/index.tsx
Normal file
66
dify/web/app/components/header/plugins-nav/index.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
'use client'
|
||||
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Link from 'next/link'
|
||||
import classNames from '@/utils/classnames'
|
||||
import { Group } from '@/app/components/base/icons/src/vender/other'
|
||||
import { useSelectedLayoutSegment } from 'next/navigation'
|
||||
import DownloadingIcon from './downloading-icon'
|
||||
import { usePluginTaskStatus } from '@/app/components/plugins/plugin-page/plugin-tasks/hooks'
|
||||
import Indicator from '@/app/components/header/indicator'
|
||||
|
||||
type PluginsNavProps = {
|
||||
className?: string
|
||||
}
|
||||
|
||||
const PluginsNav = ({
|
||||
className,
|
||||
}: PluginsNavProps) => {
|
||||
const { t } = useTranslation()
|
||||
const selectedSegment = useSelectedLayoutSegment()
|
||||
const activated = selectedSegment === 'plugins'
|
||||
const {
|
||||
isInstalling,
|
||||
isInstallingWithError,
|
||||
isFailed,
|
||||
} = usePluginTaskStatus()
|
||||
|
||||
return (
|
||||
<Link href="/plugins" className={classNames(
|
||||
className, 'group', 'plugins-nav-button', // used for use-fold-anim-into.ts
|
||||
)}>
|
||||
<div
|
||||
className={classNames(
|
||||
'system-sm-medium relative flex h-8 flex-row items-center justify-center gap-0.5 rounded-xl border border-transparent p-1.5',
|
||||
activated && 'border-components-main-nav-nav-button-border bg-components-main-nav-nav-button-bg-active text-components-main-nav-nav-button-text shadow-md',
|
||||
!activated && 'text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
|
||||
(isInstallingWithError || isFailed) && !activated && 'border-components-panel-border-subtle',
|
||||
)}
|
||||
>
|
||||
{
|
||||
(isFailed || isInstallingWithError) && !activated && (
|
||||
<Indicator
|
||||
color='red'
|
||||
className='absolute left-[-1px] top-[-1px]'
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div className='mr-0.5 flex h-5 w-5 items-center justify-center'>
|
||||
{
|
||||
(!(isInstalling || isInstallingWithError) || activated) && (
|
||||
<Group className='h-4 w-4' />
|
||||
)
|
||||
}
|
||||
{
|
||||
(isInstalling || isInstallingWithError) && !activated && (
|
||||
<DownloadingIcon />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<span className='px-0.5'>{t('common.menus.plugins')}</span>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
export default PluginsNav
|
||||
Reference in New Issue
Block a user