dify
This commit is contained in:
@@ -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="M10.6665 2.66683C11.2865 2.66683 11.5965 2.66683 11.8508 2.73498C12.541 2.91991 13.0801 3.45901 13.265 4.14919C13.3332 4.40352 13.3332 4.71352 13.3332 5.3335V11.4668C13.3332 12.5869 13.3332 13.147 13.1152 13.5748C12.9234 13.9511 12.6175 14.2571 12.2412 14.4488C11.8133 14.6668 11.2533 14.6668 10.1332 14.6668H5.8665C4.7464 14.6668 4.18635 14.6668 3.75852 14.4488C3.3822 14.2571 3.07624 13.9511 2.88449 13.5748C2.6665 13.147 2.6665 12.5869 2.6665 11.4668V5.3335C2.6665 4.71352 2.6665 4.40352 2.73465 4.14919C2.91959 3.45901 3.45868 2.91991 4.14887 2.73498C4.4032 2.66683 4.71319 2.66683 5.33317 2.66683M5.99984 10.0002L7.33317 11.3335L10.3332 8.3335M6.39984 4.00016H9.59984C9.9732 4.00016 10.1599 4.00016 10.3025 3.9275C10.4279 3.86359 10.5299 3.7616 10.5938 3.63616C10.6665 3.49355 10.6665 3.30686 10.6665 2.9335V2.40016C10.6665 2.02679 10.6665 1.84011 10.5938 1.6975C10.5299 1.57206 10.4279 1.47007 10.3025 1.40616C10.1599 1.3335 9.97321 1.3335 9.59984 1.3335H6.39984C6.02647 1.3335 5.83978 1.3335 5.69718 1.40616C5.57174 1.47007 5.46975 1.57206 5.40583 1.6975C5.33317 1.84011 5.33317 2.02679 5.33317 2.40016V2.9335C5.33317 3.30686 5.33317 3.49355 5.40583 3.63616C5.46975 3.7616 5.57174 3.86359 5.69718 3.9275C5.83978 4.00016 6.02647 4.00016 6.39984 4.00016Z" stroke="#1D2939" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -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="M10.6665 2.66634H11.9998C12.3535 2.66634 12.6926 2.80682 12.9426 3.05687C13.1927 3.30691 13.3332 3.64605 13.3332 3.99967V13.333C13.3332 13.6866 13.1927 14.0258 12.9426 14.2758C12.6926 14.5259 12.3535 14.6663 11.9998 14.6663H3.99984C3.64622 14.6663 3.30708 14.5259 3.05703 14.2758C2.80698 14.0258 2.6665 13.6866 2.6665 13.333V3.99967C2.6665 3.64605 2.80698 3.30691 3.05703 3.05687C3.30708 2.80682 3.64622 2.66634 3.99984 2.66634H5.33317M5.99984 1.33301H9.99984C10.368 1.33301 10.6665 1.63148 10.6665 1.99967V3.33301C10.6665 3.7012 10.368 3.99967 9.99984 3.99967H5.99984C5.63165 3.99967 5.33317 3.7012 5.33317 3.33301V1.99967C5.33317 1.63148 5.63165 1.33301 5.99984 1.33301Z" stroke="#1D2939" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 875 B |
@@ -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="M10.6665 2.66634H11.9998C12.3535 2.66634 12.6926 2.80682 12.9426 3.05687C13.1927 3.30691 13.3332 3.64605 13.3332 3.99967V13.333C13.3332 13.6866 13.1927 14.0258 12.9426 14.2758C12.6926 14.5259 12.3535 14.6663 11.9998 14.6663H3.99984C3.64622 14.6663 3.30708 14.5259 3.05703 14.2758C2.80698 14.0258 2.6665 13.6866 2.6665 13.333V3.99967C2.6665 3.64605 2.80698 3.30691 3.05703 3.05687C3.30708 2.80682 3.64622 2.66634 3.99984 2.66634H5.33317M5.99984 1.33301H9.99984C10.368 1.33301 10.6665 1.63148 10.6665 1.99967V3.33301C10.6665 3.7012 10.368 3.99967 9.99984 3.99967H5.99984C5.63165 3.99967 5.33317 3.7012 5.33317 3.33301V1.99967C5.33317 1.63148 5.63165 1.33301 5.99984 1.33301Z" stroke="#667085" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 875 B |
@@ -0,0 +1,21 @@
|
||||
.modal {
|
||||
padding: 32px !important;
|
||||
width: 480px !important;
|
||||
/* background: linear-gradient(180deg, rgba(3, 152, 85, 0.05) 0%, rgba(3, 152, 85, 0) 22.44%), #F9FAFB !important; */
|
||||
}
|
||||
|
||||
.copyIcon {
|
||||
background-image: url(./assets/copy.svg);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.copyIcon:hover {
|
||||
background-image: url(./assets/copy-hover.svg);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.copyIcon.copied {
|
||||
background-image: url(./assets/copied.svg);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
import { CheckCircleIcon } from '@heroicons/react/24/solid'
|
||||
import { XMarkIcon } from '@heroicons/react/24/outline'
|
||||
import { RiQuestionLine } from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useMemo } from 'react'
|
||||
import InvitationLink from './invitation-link'
|
||||
import s from './index.module.css'
|
||||
import Modal from '@/app/components/base/modal'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import type { InvitationResult } from '@/models/common'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { noop } from 'lodash-es'
|
||||
|
||||
export type SuccessInvitationResult = Extract<InvitationResult, { status: 'success' }>
|
||||
export type FailedInvitationResult = Extract<InvitationResult, { status: 'failed' }>
|
||||
|
||||
type IInvitedModalProps = {
|
||||
invitationResults: InvitationResult[]
|
||||
onCancel: () => void
|
||||
}
|
||||
const InvitedModal = ({
|
||||
invitationResults,
|
||||
onCancel,
|
||||
}: IInvitedModalProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const successInvitationResults = useMemo<SuccessInvitationResult[]>(() => invitationResults?.filter(item => item.status === 'success') as SuccessInvitationResult[], [invitationResults])
|
||||
const failedInvitationResults = useMemo<FailedInvitationResult[]>(() => invitationResults?.filter(item => item.status !== 'success') as FailedInvitationResult[], [invitationResults])
|
||||
|
||||
return (
|
||||
<div className={s.wrap}>
|
||||
<Modal isShow onClose={noop} className={s.modal}>
|
||||
<div className='mb-3 flex justify-between'>
|
||||
<div className='
|
||||
flex h-12 w-12 items-center justify-center rounded-xl
|
||||
border-[0.5px] border-components-panel-border bg-background-section-burn
|
||||
shadow-xl
|
||||
'>
|
||||
<CheckCircleIcon className='h-[22px] w-[22px] text-[#039855]' />
|
||||
</div>
|
||||
<XMarkIcon className='h-4 w-4 cursor-pointer' onClick={onCancel} />
|
||||
</div>
|
||||
<div className='mb-1 text-xl font-semibold text-text-primary'>{t('common.members.invitationSent')}</div>
|
||||
{!IS_CE_EDITION && (
|
||||
<div className='mb-10 text-sm text-text-tertiary'>{t('common.members.invitationSentTip')}</div>
|
||||
)}
|
||||
{IS_CE_EDITION && (
|
||||
<>
|
||||
<div className='mb-5 text-sm text-text-tertiary'>{t('common.members.invitationSentTip')}</div>
|
||||
<div className='mb-9 flex flex-col gap-2'>
|
||||
{
|
||||
!!successInvitationResults.length
|
||||
&& <>
|
||||
<div className='font-Medium py-2 text-sm text-text-primary'>{t('common.members.invitationLink')}</div>
|
||||
{successInvitationResults.map(item =>
|
||||
<InvitationLink key={item.email} value={item} />)}
|
||||
</>
|
||||
}
|
||||
{
|
||||
!!failedInvitationResults.length
|
||||
&& <>
|
||||
<div className='font-Medium py-2 text-sm text-text-primary'>{t('common.members.failedInvitationEmails')}</div>
|
||||
<div className='flex flex-wrap justify-between gap-y-1'>
|
||||
{
|
||||
failedInvitationResults.map(item =>
|
||||
<div key={item.email} className='flex justify-center rounded-md border border-red-300 bg-orange-50 px-1'>
|
||||
<Tooltip
|
||||
popupContent={item.message}
|
||||
>
|
||||
<div className='flex items-center justify-center gap-1 text-sm'>
|
||||
{item.email}
|
||||
<RiQuestionLine className='h-4 w-4 text-red-300' />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>,
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className='flex justify-end'>
|
||||
<Button
|
||||
className='w-[96px]'
|
||||
onClick={onCancel}
|
||||
variant='primary'
|
||||
>
|
||||
{t('common.members.ok')}
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvitedModal
|
||||
@@ -0,0 +1,60 @@
|
||||
'use client'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { t } from 'i18next'
|
||||
import copy from 'copy-to-clipboard'
|
||||
import s from './index.module.css'
|
||||
import type { SuccessInvitationResult } from '.'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
|
||||
type IInvitationLinkProps = {
|
||||
value: SuccessInvitationResult
|
||||
}
|
||||
|
||||
const InvitationLink = ({
|
||||
value,
|
||||
}: IInvitationLinkProps) => {
|
||||
const [isCopied, setIsCopied] = useState(false)
|
||||
|
||||
const copyHandle = useCallback(() => {
|
||||
// No prefix is needed here because the backend has already processed it
|
||||
copy(`${!value.url.startsWith('http') ? window.location.origin : ''}${value.url}`)
|
||||
setIsCopied(true)
|
||||
}, [value])
|
||||
|
||||
useEffect(() => {
|
||||
if (isCopied) {
|
||||
const timeout = setTimeout(() => {
|
||||
setIsCopied(false)
|
||||
}, 1000)
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
}
|
||||
}, [isCopied])
|
||||
|
||||
return (
|
||||
<div className='flex items-center rounded-lg border border-components-input-border-active bg-components-input-bg-normal py-2 hover:bg-state-base-hover'>
|
||||
<div className="flex h-5 grow items-center">
|
||||
<div className='relative h-full grow text-[13px]'>
|
||||
<Tooltip
|
||||
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
|
||||
>
|
||||
<div className='r-0 absolute left-0 top-0 w-full cursor-pointer truncate pl-2 pr-2 text-text-primary' onClick={copyHandle}>{value.url}</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="h-4 shrink-0 border bg-divider-regular" />
|
||||
<Tooltip
|
||||
popupContent={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`}
|
||||
>
|
||||
<div className="shrink-0 px-0.5">
|
||||
<div className={`box-border flex h-[30px] w-[30px] cursor-pointer items-center justify-center rounded-lg hover:bg-state-base-hover ${s.copyIcon} ${isCopied ? s.copied : ''}`} onClick={copyHandle}>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InvitationLink
|
||||
Reference in New Issue
Block a user