feat: add update to modal context

pull/12372/head
Joel 1 year ago
parent a3becde6d8
commit 474ea97fc7

@ -0,0 +1,60 @@
'use client'
import { PluginSource } from '@/app/components/plugins/types'
import { useModalContext } from '@/context/modal-context'
import React from 'react'
const UpdatePlugin = () => {
const { setShowUpdatePluginModal } = useModalContext()
const handleUpdateFromMarketPlace = () => {
setShowUpdatePluginModal({
payload: {
type: PluginSource.marketplace,
marketPlace: {
originalPackageInfo: {
id: 'original_xxx',
},
targetPackageInfo: {
id: 'target_xxx',
payload: {} as any,
},
},
},
onCancelCallback: () => {
console.log('canceled')
},
onSaveCallback: () => {
console.log('saved')
},
})
}
const handleUpdateFromGithub = () => {
setShowUpdatePluginModal({
payload: {
type: PluginSource.github,
github: {
repo: 'repo_xxx',
originalPluginId: 'original_xxx',
version: 'version_xxx',
},
},
onCancelCallback: () => {
console.log('canceled')
},
onSaveCallback: () => {
console.log('saved')
},
})
}
return (
<div>
<div></div>
<div className='flex space-x-1'>
<div className='underline cursor-pointer' onClick={handleUpdateFromMarketPlace}> Marketplace</div>
<div className='underline cursor-pointer' onClick={handleUpdateFromGithub}> GitHub</div>
</div>
</div>
)
}
export default React.memo(UpdatePlugin)

@ -140,6 +140,33 @@ export type Permissions = {
debug_permission: PermissionType debug_permission: PermissionType
} }
export type UpdateFromMarketPlacePayload = {
originalPackageInfo: {
id: string
},
targetPackageInfo: {
id: string
payload: PluginDeclaration
}
}
export type UpdateFromGitHubPayload = {
repo: string
originalPluginId: string
version: string
}
export type UpdatePluginPayload = {
type: PluginSource
marketPlace?: UpdateFromMarketPlacePayload
github?: UpdateFromGitHubPayload
}
export type UpdatePluginModalType = UpdatePluginPayload & {
onCancel: () => void
onSave: () => void
}
export enum InstallStepFromGitHub { export enum InstallStepFromGitHub {
setUrl = 'url', setUrl = 'url',
selectPackage = 'selecting', selectPackage = 'selecting',

@ -0,0 +1,21 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import type { UpdateFromGitHubPayload } from '../types'
type Props = {
payload: UpdateFromGitHubPayload
onSave: () => void
onCancel: () => void
}
const FromGitHub: FC<Props> = ({
payload,
}) => {
return (
<div>
{JSON.stringify(payload)}
</div>
)
}
export default React.memo(FromGitHub)

@ -0,0 +1,104 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useMemo, useState } from 'react'
import { RiInformation2Line } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import Card from '@/app/components/plugins/card'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Badge, { BadgeState } from '@/app/components/base/badge/index'
import { toolNotion } from '@/app/components/plugins/card/card-mock'
import type { UpdateFromMarketPlacePayload } from '../types'
const i18nPrefix = 'plugin.upgrade'
type Props = {
payload: UpdateFromMarketPlacePayload
onSave: () => void
onCancel: () => void
}
enum UploadStep {
notStarted = 'notStarted',
upgrading = 'upgrading',
installed = 'installed',
}
const UpdatePluginModal: FC<Props> = ({
onSave,
onCancel,
}) => {
const { t } = useTranslation()
const [uploadStep, setUploadStep] = useState<UploadStep>(UploadStep.notStarted)
const configBtnText = useMemo(() => {
return ({
[UploadStep.notStarted]: t(`${i18nPrefix}.upgrade`),
[UploadStep.upgrading]: t(`${i18nPrefix}.upgrading`),
[UploadStep.installed]: t(`${i18nPrefix}.close`),
})[uploadStep]
}, [t, uploadStep])
const handleConfirm = useCallback(() => {
if (uploadStep === UploadStep.notStarted) {
setUploadStep(UploadStep.upgrading)
setTimeout(() => {
setUploadStep(UploadStep.installed)
}, 1500)
return
}
if (uploadStep === UploadStep.installed) {
onSave()
onCancel()
}
}, [onCancel, onSave, uploadStep])
return (
<Modal
isShow={true}
onClose={onCancel}
className='min-w-[560px]'
closable
title={t(`${i18nPrefix}.${uploadStep === UploadStep.installed ? 'successfulTitle' : 'title'}`)}
>
<div className='mt-3 mb-2 text-text-secondary system-md-regular'>
{t(`${i18nPrefix}.description`)}
</div>
<div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'>
<Card
installed={uploadStep === UploadStep.installed}
payload={toolNotion as any}
className='w-full'
titleLeft={
<>
<Badge className='mx-1' size="s" state={BadgeState.Warning}>
{'1.2.0 -> 1.3.2'}
</Badge>
<div className='flex px-0.5 justify-center items-center gap-0.5'>
<div className='text-text-warning system-xs-medium'>{t(`${i18nPrefix}.usedInApps`, { num: 3 })}</div>
{/* show the used apps */}
<RiInformation2Line className='w-4 h-4 text-text-tertiary' />
</div>
</>
}
/>
</div>
<div className='flex pt-5 justify-end items-center gap-2 self-stretch'>
{uploadStep === UploadStep.notStarted && (
<Button
onClick={onCancel}
>
{t('common.operation.cancel')}
</Button>
)}
<Button
variant='primary'
loading={uploadStep === UploadStep.upgrading}
onClick={handleConfirm}
disabled={uploadStep === UploadStep.upgrading}
>
{configBtnText}
</Button>
</div>
</Modal>
)
}
export default React.memo(UpdatePluginModal)

@ -1,97 +1,33 @@
'use client' 'use client'
import type { FC } from 'react' import type { FC } from 'react'
import React, { useCallback, useMemo, useState } from 'react' import React from 'react'
import { RiInformation2Line } from '@remixicon/react' import type { UpdatePluginModalType } from '../types'
import { useTranslation } from 'react-i18next' import { PluginSource } from '../types'
import Card from '@/app/components/plugins/card' import UpdateFromGitHub from './from-github'
import Modal from '@/app/components/base/modal' import UpdateFromMarketplace from './from-market-place'
import Button from '@/app/components/base/button'
import Badge, { BadgeState } from '@/app/components/base/badge/index'
import { toolNotion } from '@/app/components/plugins/card/card-mock'
const i18nPrefix = 'plugin.upgrade' const UpdatePlugin: FC<UpdatePluginModalType> = ({
type,
type Props = { marketPlace,
onHide: () => void github,
} onCancel,
onSave,
enum UploadStep {
notStarted = 'notStarted',
upgrading = 'upgrading',
installed = 'installed',
}
const UpdatePluginModal: FC<Props> = ({
onHide,
}) => { }) => {
const { t } = useTranslation() if (type === PluginSource.github) {
const [uploadStep, setUploadStep] = useState<UploadStep>(UploadStep.notStarted) return (
const configBtnText = useMemo(() => { <UpdateFromGitHub
return ({ payload={github!}
[UploadStep.notStarted]: t(`${i18nPrefix}.upgrade`), onSave={onSave}
[UploadStep.upgrading]: t(`${i18nPrefix}.upgrading`), onCancel={onCancel}
[UploadStep.installed]: t(`${i18nPrefix}.close`), />
})[uploadStep] )
}, [uploadStep]) }
const handleConfirm = useCallback(() => {
if (uploadStep === UploadStep.notStarted) {
setUploadStep(UploadStep.upgrading)
setTimeout(() => {
setUploadStep(UploadStep.installed)
}, 1500)
return
}
if (uploadStep === UploadStep.installed)
onHide()
}, [uploadStep])
return ( return (
<Modal <UpdateFromMarketplace
isShow={true} payload={marketPlace!}
onClose={onHide} onSave={onSave}
className='min-w-[560px]' onCancel={onCancel}
closable />
title={t(`${i18nPrefix}.${uploadStep === UploadStep.installed ? 'successfulTitle' : 'title'}`)}
>
<div className='mt-3 mb-2 text-text-secondary system-md-regular'>
{t(`${i18nPrefix}.description`)}
</div>
<div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'>
<Card
installed={uploadStep === UploadStep.installed}
payload={toolNotion as any}
className='w-full'
titleLeft={
<>
<Badge className='mx-1' size="s" state={BadgeState.Warning}>
{'1.2.0 -> 1.3.2'}
</Badge>
<div className='flex px-0.5 justify-center items-center gap-0.5'>
<div className='text-text-warning system-xs-medium'>{t(`${i18nPrefix}.usedInApps`, { num: 3 })}</div>
{/* show the used apps */}
<RiInformation2Line className='w-4 h-4 text-text-tertiary' />
</div>
</>
}
/>
</div>
<div className='flex pt-5 justify-end items-center gap-2 self-stretch'>
{uploadStep === UploadStep.notStarted && (
<Button
onClick={onHide}
>
{t('common.operation.cancel')}
</Button>
)}
<Button
variant='primary'
loading={uploadStep === UploadStep.upgrading}
onClick={handleConfirm}
disabled={uploadStep === UploadStep.upgrading}
>
{configBtnText}
</Button>
</div>
</Modal>
) )
} }
export default React.memo(UpdatePluginModal) export default React.memo(UpdatePlugin)

@ -31,8 +31,10 @@ import ModelLoadBalancingModal from '@/app/components/header/account-setting/mod
import OpeningSettingModal from '@/app/components/base/features/new-feature-panel/conversation-opener/modal' import OpeningSettingModal from '@/app/components/base/features/new-feature-panel/conversation-opener/modal'
import type { OpeningStatement } from '@/app/components/base/features/types' import type { OpeningStatement } from '@/app/components/base/features/types'
import type { InputVar } from '@/app/components/workflow/types' import type { InputVar } from '@/app/components/workflow/types'
import type { UpdatePluginPayload } from '@/app/components/plugins/types'
import UpdatePlugin from '@/app/components/plugins/update-plugin'
export interface ModalState<T> { export type ModalState<T> = {
payload: T payload: T
onCancelCallback?: () => void onCancelCallback?: () => void
onSaveCallback?: (newPayload: T) => void onSaveCallback?: (newPayload: T) => void
@ -43,7 +45,7 @@ export interface ModalState<T> {
datasetBindings?: { id: string; name: string }[] datasetBindings?: { id: string; name: string }[]
} }
export interface ModelModalType { export type ModelModalType = {
currentProvider: ModelProvider currentProvider: ModelProvider
currentConfigurationMethod: ConfigurationMethodEnum currentConfigurationMethod: ConfigurationMethodEnum
currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields
@ -52,7 +54,8 @@ export type LoadBalancingEntryModalType = ModelModalType & {
entry?: ModelLoadBalancingConfigEntry entry?: ModelLoadBalancingConfigEntry
index?: number index?: number
} }
export interface ModalContextState {
export type ModalContextState = {
setShowAccountSettingModal: Dispatch<SetStateAction<ModalState<string> | null>> setShowAccountSettingModal: Dispatch<SetStateAction<ModalState<string> | null>>
setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>> setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>>
setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>> setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>>
@ -68,6 +71,7 @@ export interface ModalContextState {
workflowVariables?: InputVar[] workflowVariables?: InputVar[]
onAutoAddPromptVariable?: (variable: PromptVariable[]) => void onAutoAddPromptVariable?: (variable: PromptVariable[]) => void
}> | null>> }> | null>>
setShowUpdatePluginModal: Dispatch<SetStateAction<ModalState<UpdatePluginPayload> | null>>
} }
const ModalContext = createContext<ModalContextState>({ const ModalContext = createContext<ModalContextState>({
setShowAccountSettingModal: () => { }, setShowAccountSettingModal: () => { },
@ -81,6 +85,7 @@ const ModalContext = createContext<ModalContextState>({
setShowModelLoadBalancingModal: () => { }, setShowModelLoadBalancingModal: () => { },
setShowModelLoadBalancingEntryModal: () => { }, setShowModelLoadBalancingEntryModal: () => { },
setShowOpeningModal: () => { }, setShowOpeningModal: () => { },
setShowUpdatePluginModal: () => { },
}) })
export const useModalContext = () => useContext(ModalContext) export const useModalContext = () => useContext(ModalContext)
@ -90,7 +95,7 @@ export const useModalContext = () => useContext(ModalContext)
export const useModalContextSelector = <T,>(selector: (state: ModalContextState) => T): T => export const useModalContextSelector = <T,>(selector: (state: ModalContextState) => T): T =>
useContextSelector(ModalContext, selector) useContextSelector(ModalContext, selector)
interface ModalContextProviderProps { type ModalContextProviderProps = {
children: React.ReactNode children: React.ReactNode
} }
export const ModalContextProvider = ({ export const ModalContextProvider = ({
@ -109,6 +114,8 @@ export const ModalContextProvider = ({
workflowVariables?: InputVar[] workflowVariables?: InputVar[]
onAutoAddPromptVariable?: (variable: PromptVariable[]) => void onAutoAddPromptVariable?: (variable: PromptVariable[]) => void
}> | null>(null) }> | null>(null)
const [showUpdatePluginModal, setShowUpdatePluginModal] = useState<ModalState<UpdatePluginPayload> | null>(null)
const searchParams = useSearchParams() const searchParams = useSearchParams()
const router = useRouter() const router = useRouter()
const [showPricingModal, setShowPricingModal] = useState(searchParams.get('show-pricing') === '1') const [showPricingModal, setShowPricingModal] = useState(searchParams.get('show-pricing') === '1')
@ -228,6 +235,7 @@ export const ModalContextProvider = ({
setShowModelLoadBalancingModal, setShowModelLoadBalancingModal,
setShowModelLoadBalancingEntryModal, setShowModelLoadBalancingEntryModal,
setShowOpeningModal, setShowOpeningModal,
setShowUpdatePluginModal,
}}> }}>
<> <>
{children} {children}
@ -338,6 +346,22 @@ export const ModalContextProvider = ({
onAutoAddPromptVariable={showOpeningModal.payload.onAutoAddPromptVariable} onAutoAddPromptVariable={showOpeningModal.payload.onAutoAddPromptVariable}
/> />
)} )}
{
!!showUpdatePluginModal && (
<UpdatePlugin
{...showUpdatePluginModal.payload}
onCancel={() => {
setShowUpdatePluginModal(null)
showUpdatePluginModal.onCancelCallback?.()
}}
onSave={() => {
setShowUpdatePluginModal(null)
showUpdatePluginModal.onSaveCallback?.({} as any)
}}
/>
)
}
</> </>
</ModalContext.Provider> </ModalContext.Provider>
) )

Loading…
Cancel
Save