mirror of
http://112.124.100.131/huang.ze/ebiz-dify-ai.git
synced 2025-12-10 03:16:51 +08:00
Feat/dataset notion import (#392)
Co-authored-by: StyleZhang <jasonapring2015@outlook.com> Co-authored-by: JzoNg <jzongcode@gmail.com>
This commit is contained in:
@@ -9,9 +9,9 @@ import { Menu, Transition } from '@headlessui/react'
|
||||
import Indicator from '../indicator'
|
||||
import AccountSetting from '../account-setting'
|
||||
import AccountAbout from '../account-about'
|
||||
import WorkplaceSelector from './workplace-selector'
|
||||
import type { LangGeniusVersionResponse, UserProfileResponse } from '@/models/common'
|
||||
import I18n from '@/context/i18n'
|
||||
import WorkplaceSelector from './workplace-selector'
|
||||
import Avatar from '@/app/components/base/avatar'
|
||||
|
||||
type IAppSelectorProps = {
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Link from 'next/link'
|
||||
import { PlusIcon } from '@heroicons/react/24/solid'
|
||||
import cn from 'classnames'
|
||||
import Indicator from '../../../indicator'
|
||||
import Operate from './operate'
|
||||
import s from './style.module.css'
|
||||
import NotionIcon from '@/app/components/base/notion-icon'
|
||||
import { apiPrefix } from '@/config'
|
||||
import type { DataSourceNotion as TDataSourceNotion } from '@/models/common'
|
||||
|
||||
type DataSourceNotionProps = {
|
||||
workspaces: TDataSourceNotion[]
|
||||
}
|
||||
const DataSourceNotion = ({
|
||||
workspaces,
|
||||
}: DataSourceNotionProps) => {
|
||||
const { t } = useTranslation()
|
||||
const connected = !!workspaces.length
|
||||
|
||||
return (
|
||||
<div className='mb-2 border-[0.5px] border-gray-200 bg-gray-50 rounded-xl'>
|
||||
<div className='flex items-center px-3 py-[9px]'>
|
||||
<div className={cn(s['notion-icon'], 'w-8 h-8 mr-3 border border-gray-100 rounded-lg')} />
|
||||
<div className='grow'>
|
||||
<div className='leading-5 text-sm font-medium text-gray-800'>
|
||||
{t('common.dataSource.notion.title')}
|
||||
</div>
|
||||
{
|
||||
!connected && (
|
||||
<div className='leading-5 text-xs text-gray-500'>
|
||||
{t('common.dataSource.notion.description')}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{
|
||||
!connected
|
||||
? (
|
||||
<Link
|
||||
className='flex items-center ml-3 px-3 h-7 bg-white border border-gray-200 rounded-md text-xs font-medium text-gray-700 cursor-pointer'
|
||||
href={`${apiPrefix}/oauth/data-source/notion`}>
|
||||
{t('common.dataSource.connect')}
|
||||
</Link>
|
||||
)
|
||||
: (
|
||||
<Link
|
||||
href={`${apiPrefix}/oauth/data-source/notion`}
|
||||
className='flex items-center px-3 h-7 bg-white border-[0.5px] border-gray-200 text-xs font-medium text-primary-600 rounded-md cursor-pointer'>
|
||||
<PlusIcon className='w-[14px] h-[14px] mr-[5px]' />
|
||||
{t('common.dataSource.notion.addWorkspace')}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{
|
||||
connected && (
|
||||
<div className='flex items-center px-3 h-[18px]'>
|
||||
<div className='text-xs font-medium text-gray-500'>
|
||||
{t('common.dataSource.notion.connectedWorkspace')}
|
||||
</div>
|
||||
<div className='grow ml-3 border-t border-t-gray-100' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
connected && (
|
||||
<div className='px-3 pt-2 pb-3'>
|
||||
{
|
||||
workspaces.map(workspace => (
|
||||
<div className={cn(s['workspace-item'], 'flex items-center mb-1 py-1 pr-1 bg-white rounded-lg')} key={workspace.id}>
|
||||
<NotionIcon
|
||||
className='ml-3 mr-[6px]'
|
||||
src={workspace.source_info.workspace_icon}
|
||||
name={workspace.source_info.workspace_name}
|
||||
/>
|
||||
<div className='grow py-[7px] leading-[18px] text-[13px] font-medium text-gray-700 truncate' title={workspace.source_info.workspace_name}>{workspace.source_info.workspace_name}</div>
|
||||
{
|
||||
workspace.is_bound
|
||||
? <Indicator className='shrink-0 mr-[6px]' />
|
||||
: <Indicator className='shrink-0 mr-[6px]' color='yellow' />
|
||||
}
|
||||
<div className='shrink-0 mr-3 text-xs font-medium'>
|
||||
{
|
||||
workspace.is_bound
|
||||
? t('common.dataSource.notion.connected')
|
||||
: t('common.dataSource.notion.disconnected')
|
||||
}
|
||||
</div>
|
||||
<div className='mr-2 w-[1px] h-3 bg-gray-100' />
|
||||
<Operate workspace={workspace} />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DataSourceNotion
|
||||
@@ -0,0 +1,14 @@
|
||||
.file-icon {
|
||||
background: url(../../../../assets/file.svg) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.sync-icon {
|
||||
background: url(../../../../assets/sync.svg) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.trash-icon {
|
||||
background: url(../../../../assets/trash.svg) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
'use client'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Fragment } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useSWRConfig } from 'swr'
|
||||
import { EllipsisHorizontalIcon } from '@heroicons/react/24/solid'
|
||||
import { Menu, Transition } from '@headlessui/react'
|
||||
import cn from 'classnames'
|
||||
import s from './index.module.css'
|
||||
import { apiPrefix } from '@/config'
|
||||
import { syncDataSourceNotion, updateDataSourceNotionAction } from '@/service/common'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import type { DataSourceNotion } from '@/models/common'
|
||||
|
||||
type OperateProps = {
|
||||
workspace: DataSourceNotion
|
||||
}
|
||||
export default function Operate({
|
||||
workspace,
|
||||
}: OperateProps) {
|
||||
const itemClassName = `
|
||||
flex px-3 py-2 hover:bg-gray-50 text-sm text-gray-700
|
||||
cursor-pointer
|
||||
`
|
||||
const itemIconClassName = `
|
||||
mr-2 mt-[2px] w-4 h-4
|
||||
`
|
||||
const { t } = useTranslation()
|
||||
const { mutate } = useSWRConfig()
|
||||
|
||||
const updateIntegrates = () => {
|
||||
Toast.notify({
|
||||
type: 'success',
|
||||
message: t('common.api.success'),
|
||||
})
|
||||
mutate({ url: 'data-source/integrates' })
|
||||
}
|
||||
const handleSync = async () => {
|
||||
await syncDataSourceNotion({ url: `/oauth/data-source/notion/${workspace.id}/sync` })
|
||||
updateIntegrates()
|
||||
}
|
||||
const handleRemove = async () => {
|
||||
await updateDataSourceNotionAction({ url: `/data-source/integrates/${workspace.id}/disable` })
|
||||
updateIntegrates()
|
||||
}
|
||||
|
||||
return (
|
||||
<Menu as="div" className="relative inline-block text-left">
|
||||
{
|
||||
({ open }) => (
|
||||
<>
|
||||
<Menu.Button className={`flex items-center justify-center w-8 h-8 rounded-lg hover:bg-gray-100 ${open && 'bg-gray-100'}`}>
|
||||
<EllipsisHorizontalIcon className='w-4 h-4' />
|
||||
</Menu.Button>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-100"
|
||||
enterFrom="transform opacity-0 scale-95"
|
||||
enterTo="transform opacity-100 scale-100"
|
||||
leave="transition ease-in duration-75"
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items
|
||||
className="
|
||||
absolute right-0 top-9 w-60 max-w-80
|
||||
divide-y divide-gray-100 origin-top-right rounded-lg bg-white
|
||||
shadow-[0_10px_15px_-3px_rgba(0,0,0,0.1),0_4px_6px_rgba(0,0,0,0.05)]
|
||||
"
|
||||
>
|
||||
<div className="px-1 py-1">
|
||||
<Menu.Item>
|
||||
<Link
|
||||
className={itemClassName}
|
||||
href={`${apiPrefix}/oauth/data-source/notion`}>
|
||||
<div className={cn(s['file-icon'], itemIconClassName)}></div>
|
||||
<div>
|
||||
<div className='leading-5'>{t('common.dataSource.notion.changeAuthorizedPages')}</div>
|
||||
<div className='leading-5 text-xs text-gray-500'>
|
||||
{workspace.source_info.total} {t('common.dataSource.notion.pagesAuthorized')}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<div className={itemClassName} onClick={handleSync}>
|
||||
<div className={cn(s['sync-icon'], itemIconClassName)} />
|
||||
<div className='leading-5'>{t('common.dataSource.notion.sync')}</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</div>
|
||||
<Menu.Item>
|
||||
<div className='p-1'>
|
||||
<div className={itemClassName} onClick={handleRemove}>
|
||||
<div className={cn(s['trash-icon'], itemIconClassName)} />
|
||||
<div className='leading-5'>{t('common.dataSource.notion.remove')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Menu.Item>
|
||||
</Menu.Items>
|
||||
</Transition>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
.notion-icon {
|
||||
background: #ffffff url(../../../assets/notion.svg) center center no-repeat;
|
||||
background-size: 20px 20px;
|
||||
}
|
||||
|
||||
.workspace-item {
|
||||
box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05);
|
||||
}
|
||||
|
||||
.workspace-item:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import useSWR from 'swr'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import DataSourceNotion from './data-source-notion'
|
||||
import { fetchDataSource } from '@/service/common'
|
||||
|
||||
export default function DataSourcePage() {
|
||||
const { t } = useTranslation()
|
||||
const { data } = useSWR({ url: 'data-source/integrates' }, fetchDataSource)
|
||||
const notionWorkspaces = data?.data.filter(item => item.provider === 'notion') || []
|
||||
|
||||
return (
|
||||
<div className='mb-8'>
|
||||
<div className='mb-2 text-sm font-medium text-gray-900'>{t('common.dataSource.add')}</div>
|
||||
<DataSourceNotion workspaces={notionWorkspaces} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -2,4 +2,14 @@
|
||||
max-width: 720px !important;
|
||||
padding: 0 !important;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.data-source-icon {
|
||||
background: url(../assets/data-source.svg) center center no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.data-source-solid-icon {
|
||||
background: url(../assets/data-source-blue.svg) center center no-repeat;
|
||||
background-size: cover;
|
||||
}
|
||||
@@ -1,20 +1,32 @@
|
||||
'use client'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useState } from 'react'
|
||||
import { AtSymbolIcon, GlobeAltIcon, UserIcon, XMarkIcon, CubeTransparentIcon, UsersIcon } from '@heroicons/react/24/outline'
|
||||
import { AtSymbolIcon, CubeTransparentIcon, GlobeAltIcon, UserIcon, UsersIcon, XMarkIcon } from '@heroicons/react/24/outline'
|
||||
import { GlobeAltIcon as GlobalAltIconSolid, UserIcon as UserIconSolid, UsersIcon as UsersIconSolid } from '@heroicons/react/24/solid'
|
||||
import cn from 'classnames'
|
||||
import AccountPage from './account-page'
|
||||
import MembersPage from './members-page'
|
||||
import IntegrationsPage from './Integrations-page'
|
||||
import LanguagePage from './language-page'
|
||||
import ProviderPage from './provider-page'
|
||||
import DataSourcePage from './data-source-page'
|
||||
import s from './index.module.css'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
|
||||
const iconClassName = `
|
||||
w-[18px] h-[18px] ml-3 mr-2
|
||||
w-4 h-4 ml-3 mr-2
|
||||
`
|
||||
|
||||
type IconProps = {
|
||||
className?: string
|
||||
}
|
||||
const DataSourceIcon = ({ className }: IconProps) => (
|
||||
<div className={cn(s['data-source-icon'], className)} />
|
||||
)
|
||||
const DataSourceSolidIcon = ({ className }: IconProps) => (
|
||||
<div className={cn(s['data-source-solid-icon'], className)} />
|
||||
)
|
||||
|
||||
type IAccountSettingProps = {
|
||||
onCancel: () => void
|
||||
activeTab?: string
|
||||
@@ -48,7 +60,7 @@ export default function AccountSetting({
|
||||
icon: <GlobeAltIcon className={iconClassName} />,
|
||||
activeIcon: <GlobalAltIconSolid className={iconClassName} />,
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'workspace-group',
|
||||
@@ -66,8 +78,14 @@ export default function AccountSetting({
|
||||
icon: <CubeTransparentIcon className={iconClassName} />,
|
||||
activeIcon: <CubeTransparentIcon className={iconClassName} />,
|
||||
},
|
||||
]
|
||||
}
|
||||
{
|
||||
key: 'data-source',
|
||||
name: t('common.settings.dataSource'),
|
||||
icon: <DataSourceIcon className={iconClassName} />,
|
||||
activeIcon: <DataSourceSolidIcon className={iconClassName} />,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
@@ -126,6 +144,9 @@ export default function AccountSetting({
|
||||
{
|
||||
activeMenu === 'provider' && <ProviderPage />
|
||||
}
|
||||
{
|
||||
activeMenu === 'data-source' && <DataSourcePage />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
'use client'
|
||||
import { useState } from 'react'
|
||||
import s from './index.module.css'
|
||||
import cn from 'classnames'
|
||||
import useSWR from 'swr'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import I18n from '@/context/i18n'
|
||||
import { useContext } from 'use-context-selector'
|
||||
import { fetchMembers } from '@/service/common'
|
||||
import { UserPlusIcon } from '@heroicons/react/24/outline'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import s from './index.module.css'
|
||||
import InviteModal from './invite-modal'
|
||||
import InvitedModal from './invited-modal'
|
||||
import Operation from './operation'
|
||||
import { fetchMembers } from '@/service/common'
|
||||
import I18n from '@/context/i18n'
|
||||
import { useAppContext } from '@/context/app-context'
|
||||
import Avatar from '@/app/components/base/avatar'
|
||||
import { useWorkspacesContext } from '@/context/workspace-context'
|
||||
@@ -35,18 +35,18 @@ const MembersPage = () => {
|
||||
const owner = accounts.filter(account => account.role === 'owner')?.[0]?.email === userProfile.email
|
||||
const { workspaces } = useWorkspacesContext()
|
||||
const currentWrokspace = workspaces.filter(item => item.current)?.[0]
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<div className='flex items-center mb-4 p-3 bg-gray-50 rounded-2xl'>
|
||||
<div className={cn(s['logo-icon'], 'shrink-0')}></div>
|
||||
<div className='grow mx-2'>
|
||||
<div className='text-sm font-medium text-gray-900'>{currentWrokspace.name}</div>
|
||||
<div className='text-sm font-medium text-gray-900'>{currentWrokspace?.name}</div>
|
||||
<div className='text-xs text-gray-500'>{t('common.userProfile.workspace')}</div>
|
||||
</div>
|
||||
<div className='
|
||||
shrink-0 flex items-center py-[7px] px-3 border-[0.5px] border-gray-200
|
||||
shrink-0 flex items-center py-[7px] px-3 border-[0.5px] border-gray-200
|
||||
text-[13px] font-medium text-primary-600 bg-white
|
||||
shadow-[0_1px_2px_rgba(16,24,40,0.05)] rounded-lg cursor-pointer
|
||||
' onClick={() => setInviteModalVisible(true)}>
|
||||
@@ -78,10 +78,10 @@ const MembersPage = () => {
|
||||
<div className='shrink-0 flex items-center w-[104px] py-2 text-[13px] text-gray-700'>{dayjs(Number((account.last_login_at || account.created_at)) * 1000).locale(locale === 'zh-Hans' ? 'zh-cn' : 'en').fromNow()}</div>
|
||||
<div className='shrink-0 w-[96px] flex items-center'>
|
||||
{
|
||||
owner && account.role !== 'owner'
|
||||
(owner && account.role !== 'owner')
|
||||
? <Operation member={account} onOperate={() => mutate()} />
|
||||
: <div className='px-3 text-[13px] text-gray-700'>{RoleMap[account.role] || RoleMap.normal}</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
@@ -111,4 +111,4 @@ const MembersPage = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export default MembersPage
|
||||
export default MembersPage
|
||||
|
||||
3
web/app/components/header/assets/data-source-blue.svg
Normal file
3
web/app/components/header/assets/data-source-blue.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.66659 9.98845C10.1231 9.93732 11.4455 9.71981 12.461 9.38077C13.0418 9.18687 13.5593 8.94109 13.9452 8.6353C14.3245 8.33478 14.6666 7.89967 14.6666 7.33341V3.33341C14.6666 2.76545 14.3207 2.33047 13.9411 2.03132C13.5539 1.72624 13.0351 1.48065 12.4534 1.28675C11.283 0.896612 9.70849 0.666748 7.99992 0.666748C6.29135 0.666748 4.71686 0.896612 3.54646 1.28675C2.96474 1.48065 2.44589 1.72624 2.05878 2.03132C1.67918 2.33047 1.33325 2.76545 1.33325 3.33341V7.33341C1.33325 7.89967 1.67538 8.33478 2.05463 8.6353C2.44053 8.94109 2.958 9.18687 3.53881 9.38077C4.55435 9.71981 5.87675 9.93732 7.33325 9.98845V11.4472C6.76498 11.6481 6.31458 12.0985 6.11372 12.6667H1.99992C1.63173 12.6667 1.33325 12.9652 1.33325 13.3334C1.33325 13.7016 1.63173 14.0001 1.99992 14.0001H6.11372C6.38828 14.7769 7.12911 15.3334 7.99992 15.3334C8.87073 15.3334 9.61156 14.7769 9.88612 14.0001H13.9999C14.3681 14.0001 14.6666 13.7016 14.6666 13.3334C14.6666 12.9652 14.3681 12.6667 13.9999 12.6667H9.88612C9.68526 12.0985 9.23486 11.6481 8.66659 11.4472V9.98845ZM2.66659 3.33337C2.66659 3.33337 2.66657 3.32994 2.66862 3.32322C2.67089 3.31579 2.67647 3.30111 2.68997 3.27913C2.71827 3.23303 2.77597 3.16373 2.88408 3.07853C3.1042 2.90506 3.46403 2.71968 3.9681 2.55166C4.96927 2.21793 6.39478 2.00008 7.99992 2.00008C9.60506 2.00008 11.0306 2.21793 12.0317 2.55166C12.5358 2.71968 12.8956 2.90506 13.1158 3.07853C13.2239 3.16373 13.2816 3.23303 13.3099 3.27913C13.3234 3.30111 13.329 3.31579 13.3312 3.32322C13.3333 3.32994 13.3333 3.33337 13.3333 3.33337C13.3333 3.33337 13.3332 3.33722 13.3312 3.34361C13.329 3.35104 13.3234 3.36572 13.3099 3.3877C13.2816 3.4338 13.2239 3.5031 13.1158 3.5883C12.8956 3.76177 12.5358 3.94715 12.0317 4.11517C11.0306 4.4489 9.60506 4.66675 7.99992 4.66675C6.39478 4.66675 4.96927 4.4489 3.9681 4.11517C3.46403 3.94715 3.1042 3.76177 2.88408 3.5883C2.77597 3.5031 2.71827 3.4338 2.68997 3.3877C2.67647 3.36572 2.67089 3.35104 2.66862 3.34361C2.6667 3.33731 2.66659 3.33337 2.66659 3.33337Z" fill="#155EEF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
3
web/app/components/header/assets/data-source.svg
Normal file
3
web/app/components/header/assets/data-source.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.33333 13.3333C9.33333 14.0696 8.73638 14.6666 8 14.6666C7.26362 14.6666 6.66667 14.0696 6.66667 13.3333M9.33333 13.3333C9.33333 12.5969 8.73638 11.9999 8 11.9999M9.33333 13.3333H14M6.66667 13.3333C6.66667 12.5969 7.26362 11.9999 8 11.9999M6.66667 13.3333H2M8 11.9999V9.33325M14 3.33325C14 4.43782 11.3137 5.33325 8 5.33325C4.68629 5.33325 2 4.43782 2 3.33325M14 3.33325C14 2.22868 11.3137 1.33325 8 1.33325C4.68629 1.33325 2 2.22868 2 3.33325M14 3.33325V7.33325C14 8.43992 11.3333 9.33325 8 9.33325M2 3.33325V7.33325C2 8.43992 4.66667 9.33325 8 9.33325" stroke="#344054" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 755 B |
3
web/app/components/header/assets/file.svg
Normal file
3
web/app/components/header/assets/file.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.3333 6.99992V4.53325C13.3333 3.41315 13.3333 2.85309 13.1153 2.42527C12.9236 2.04895 12.6176 1.74299 12.2413 1.55124C11.8135 1.33325 11.2534 1.33325 10.1333 1.33325H5.86666C4.74655 1.33325 4.1865 1.33325 3.75868 1.55124C3.38235 1.74299 3.07639 2.04895 2.88464 2.42527C2.66666 2.85309 2.66666 3.41315 2.66666 4.53325V11.4666C2.66666 12.5867 2.66666 13.1467 2.88464 13.5746C3.07639 13.9509 3.38235 14.2569 3.75868 14.4486C4.1865 14.6666 4.74655 14.6666 5.86666 14.6666H7.99999M9.33332 7.33325H5.33332M6.66666 9.99992H5.33332M10.6667 4.66659H5.33332M12 13.9999V9.99992M9.99999 11.9999H14" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 787 B |
12
web/app/components/header/assets/notion.svg
Normal file
12
web/app/components/header/assets/notion.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_5364_42310)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.5725 18.2611L1.4229 15.5832C0.905706 14.9389 0.625 14.1466 0.625 13.3312V3.63437C0.625 2.4129 1.60224 1.39936 2.86295 1.31328L12.8326 0.632614C13.5569 0.583164 14.2768 0.775682 14.8717 1.17794L18.3745 3.5462C19.0015 3.97012 19.375 4.66312 19.375 5.40266V16.427C19.375 17.6223 18.4141 18.6121 17.1798 18.688L6.11458 19.3692C5.12958 19.4298 4.17749 19.0148 3.5725 18.2611Z" fill="white"/>
|
||||
<path d="M7.03006 8.48663V8.35968C7.03006 8.03787 7.28779 7.77098 7.61997 7.7488L10.0396 7.58726L13.3857 12.5146V8.19003L12.5244 8.07522V8.01492C12.5244 7.68933 12.788 7.42068 13.1244 7.40344L15.326 7.29066V7.60749C15.326 7.75622 15.2154 7.88343 15.0638 7.90907L14.534 7.99868V15.0022L13.8691 15.2309C13.3136 15.4219 12.6952 15.2174 12.3772 14.7376L9.12879 9.83568V14.5143L10.1287 14.7056L10.1147 14.7984C10.0711 15.0889 9.82028 15.3086 9.51687 15.3221L7.03006 15.4328C6.99718 15.1204 7.23132 14.8409 7.55431 14.807L7.88143 14.7726V8.53447L7.03006 8.48663Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9218 1.85418L2.95217 2.53485C2.35499 2.57562 1.89209 3.05572 1.89209 3.63431V13.3311C1.89209 13.8748 2.07923 14.4029 2.42402 14.8325L4.57362 17.5104C4.92117 17.9433 5.46812 18.1817 6.03397 18.1469L17.0991 17.4658C17.6663 17.4309 18.1078 16.9761 18.1078 16.4269V5.4026C18.1078 5.06281 17.9362 4.74441 17.6481 4.54963L14.1453 2.18137C13.7883 1.94002 13.3564 1.82451 12.9218 1.85418ZM3.44654 3.78556C3.30788 3.6829 3.37387 3.46903 3.54806 3.45654L12.9889 2.77938C13.2897 2.75781 13.5886 2.84064 13.8318 3.01299L15.7261 4.35502C15.798 4.40597 15.7642 4.51596 15.6752 4.5208L5.67742 5.06454C5.37485 5.081 5.0762 4.99211 4.83563 4.814L3.44654 3.78556ZM5.20848 6.76913C5.20848 6.44433 5.47088 6.17604 5.80642 6.15777L16.3769 5.5821C16.7039 5.56429 16.9792 5.81577 16.9792 6.13232V15.6782C16.9792 16.0024 16.7177 16.2705 16.3829 16.2895L5.8793 16.8871C5.51537 16.9079 5.20848 16.6282 5.20848 16.2759V6.76913Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_5364_42310">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
3
web/app/components/header/assets/sync.svg
Normal file
3
web/app/components/header/assets/sync.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.69773 13.1783C7.29715 13.8879 9.20212 13.8494 10.8334 12.9075C13.5438 11.3427 14.4724 7.87704 12.9076 5.16672L12.7409 4.87804M3.09233 10.8335C1.52752 8.12314 2.45615 4.65746 5.16647 3.09265C6.7978 2.15081 8.70277 2.11227 10.3022 2.82185M1.66226 10.8892L3.48363 11.3773L3.97166 9.5559M12.0284 6.44393L12.5164 4.62256L14.3378 5.1106" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 532 B |
3
web/app/components/header/assets/trash.svg
Normal file
3
web/app/components/header/assets/trash.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 2H10M2 4H14M12.6667 4L12.1991 11.0129C12.129 12.065 12.0939 12.5911 11.8667 12.99C11.6666 13.3412 11.3648 13.6235 11.0011 13.7998C10.588 14 10.0607 14 9.00623 14H6.99377C5.93927 14 5.41202 14 4.99889 13.7998C4.63517 13.6235 4.33339 13.3412 4.13332 12.99C3.90607 12.5911 3.871 12.065 3.80086 11.0129L3.33333 4M6.66667 7V10.3333M9.33333 7V10.3333" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 546 B |
@@ -24,7 +24,7 @@ export type INavSelectorProps = {
|
||||
|
||||
const itemClassName = `
|
||||
flex items-center w-full h-10 px-3 text-gray-700 text-[14px]
|
||||
rounded-lg font-normal hover:bg-gray-100 cursor-pointer
|
||||
rounded-lg font-normal hover:bg-gray-100 cursor-pointer truncate
|
||||
`
|
||||
|
||||
const NavSelector = ({ curNav, navs, createText, onCreate, onLoadmore }: INavSelectorProps) => {
|
||||
@@ -50,9 +50,9 @@ const NavSelector = ({ curNav, navs, createText, onCreate, onLoadmore }: INavSel
|
||||
text-[#1C64F2] hover:bg-[#EBF5FF]
|
||||
"
|
||||
>
|
||||
{curNav?.name}
|
||||
<div className='max-w-[180px] truncate' title={curNav?.name}>{curNav?.name}</div>
|
||||
<ChevronDownIcon
|
||||
className="w-3 h-3 ml-1"
|
||||
className="shrink-0 w-3 h-3 ml-1"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Menu.Button>
|
||||
@@ -68,7 +68,7 @@ const NavSelector = ({ curNav, navs, createText, onCreate, onLoadmore }: INavSel
|
||||
{
|
||||
navs.map(nav => (
|
||||
<Menu.Item key={nav.id}>
|
||||
<div className={itemClassName} onClick={() => router.push(nav.link)}>
|
||||
<div className={itemClassName} onClick={() => router.push(nav.link)} title={nav.name}>
|
||||
<div className='relative w-6 h-6 mr-2 bg-[#D5F5F6] rounded-[6px]'>
|
||||
<AppIcon size='tiny' icon={nav.icon} background={nav.icon_background}/>
|
||||
<div className='flex justify-center items-center absolute -right-0.5 -bottom-0.5 w-2.5 h-2.5 bg-white rounded'>
|
||||
|
||||
Reference in New Issue
Block a user