diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 055c13b567..731c7db7ac 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -2,12 +2,14 @@ import React, { useState } from 'react' import Modal from '@/app/components/base/modal' -import Button from '@/app/components/base/button' import type { Item } from '@/app/components/base/select' -import { PortalSelect } from '@/app/components/base/select' import type { GitHubRepoReleaseResponse } from '@/app/components/plugins/types' -import { InstallStep } from '../../types' +import { InstallStepFromGitHub } from '../../types' import Toast from '@/app/components/base/toast' +import SetURL from './steps/setURL' +import SetVersion from './steps/setVersion' +import SetPackage from './steps/setPackage' +import Installed from './steps/installed' type InstallFromGitHubProps = { onClose: () => void @@ -20,7 +22,7 @@ type GitHubUrlInfo = { } type InstallState = { - step: InstallStep + step: InstallStepFromGitHub repoUrl: string selectedVersion: string selectedPackage: string @@ -29,7 +31,7 @@ type InstallState = { const InstallFromGitHub: React.FC = ({ onClose }) => { const [state, setState] = useState({ - step: InstallStep.url, + step: InstallStepFromGitHub.setUrl, repoUrl: '', selectedVersion: '', selectedPackage: '', @@ -45,7 +47,7 @@ const InstallFromGitHub: React.FC = ({ onClose }) => { ? (state.releases .find(release => release.tag_name === state.selectedVersion) ?.assets -.map(asset => ({ + .map(asset => ({ value: asset.browser_download_url, name: asset.name, })) || []) @@ -80,12 +82,12 @@ const InstallFromGitHub: React.FC = ({ onClose }) => { // catch (error) { // console.error('Error installing package:') // } - setState(prevState => ({ ...prevState, step: InstallStep.installed })) + setState(prevState => ({ ...prevState, step: InstallStepFromGitHub.installed })) } const handleNext = async () => { switch (state.step) { - case InstallStep.url: { + case InstallStepFromGitHub.setUrl: { const { isValid, owner, repo } = parseGitHubUrl(state.repoUrl) if (!isValid || !owner || !repo) { Toast.notify({ @@ -107,7 +109,7 @@ const InstallFromGitHub: React.FC = ({ onClose }) => { name: asset.name, })), })) - setState(prevState => ({ ...prevState, releases: formattedReleases, step: InstallStep.version })) + setState(prevState => ({ ...prevState, releases: formattedReleases, step: InstallStepFromGitHub.setVersion })) } catch (error) { Toast.notify({ @@ -117,10 +119,10 @@ const InstallFromGitHub: React.FC = ({ onClose }) => { } break } - case InstallStep.version: - setState(prevState => ({ ...prevState, step: InstallStep.package })) + case InstallStepFromGitHub.setVersion: + setState(prevState => ({ ...prevState, step: InstallStepFromGitHub.setPackage })) break - case InstallStep.package: + case InstallStepFromGitHub.setPackage: handleInstall() break } @@ -129,44 +131,15 @@ const InstallFromGitHub: React.FC = ({ onClose }) => { const handleBack = () => { setState((prevState) => { switch (prevState.step) { - case InstallStep.version: - return { ...prevState, step: InstallStep.url } - case InstallStep.package: - return { ...prevState, step: InstallStep.version } + case InstallStepFromGitHub.setVersion: + return { ...prevState, step: InstallStepFromGitHub.setUrl } + case InstallStepFromGitHub.setPackage: + return { ...prevState, step: InstallStepFromGitHub.setVersion } default: return prevState } }) } - - const isInputValid = () => { - switch (state.step) { - case InstallStep.url: - return !!state.repoUrl.trim() - case InstallStep.version: - return !!state.selectedVersion - case InstallStep.package: - return !!state.selectedPackage - default: - return true - } - } - - const InfoRow = ({ label, value }: { label: string; value: string }) => ( -
-
-
- {label} -
-
-
-
- {value} -
-
-
- ) - return ( = ({ onClose }) => { Install plugin from GitHub
- {state.step !== InstallStep.installed && 'Please make sure that you only install plugins from a trusted source.'} + {state.step !== InstallStepFromGitHub.installed && 'Please make sure that you only install plugins from a trusted source.'}
-
- {state.step === InstallStep.url && ( - <> - - setState(prevState => ({ ...prevState, repoUrl: e.target.value }))} // TODO: needs to verify the url - className='flex items-center self-stretch rounded-lg border border-components-input-border-active - bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden - text-components-input-text-filled text-ellipsis system-sm-regular' - placeholder='Please enter GitHub repo URL' - /> - +
+ {state.step === InstallStepFromGitHub.setUrl && ( + setState(prevState => ({ ...prevState, repoUrl: value }))} + onNext={handleNext} + onCancel={onClose} + /> )} - {state.step === InstallStep.version && ( - <> - - setState(prevState => ({ ...prevState, selectedVersion: item.value as string }))} - items={versions} - placeholder="Please select a version" - popupClassName='w-[432px] z-[1001]' - /> - + {state.step === InstallStepFromGitHub.setVersion && ( + setState(prevState => ({ ...prevState, selectedVersion: item.value as string }))} + onNext={handleNext} + onBack={handleBack} + /> )} - {state.step === InstallStep.package && ( - <> - - setState(prevState => ({ ...prevState, selectedPackage: item.value as string }))} - items={packages} - placeholder="Please select a package" - popupClassName='w-[432px] z-[1001]' - /> - + {state.step === InstallStepFromGitHub.setPackage && ( + setState(prevState => ({ ...prevState, selectedPackage: item.value as string }))} + onInstall={handleInstall} + onBack={handleBack} + /> )} - {state.step === InstallStep.installed && ( - <> -
The plugin has been installed successfully.
-
- {[ - { label: 'Repository', value: state.repoUrl }, - { label: 'Version', value: state.selectedVersion }, - { label: 'Package', value: state.selectedPackage }, - ].map(({ label, value }) => ( - - ))} -
- + {state.step === InstallStepFromGitHub.installed && ( + )}
-
- {state.step === InstallStep.installed - ? ( - - ) - : ( - <> - - - - )} -
) } diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx new file mode 100644 index 0000000000..be6dc5b312 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import Button from '@/app/components/base/button' + +type InstalledProps = { + repoUrl: string + selectedVersion: string + selectedPackage: string + onClose: () => void +} + +const InfoRow = ({ label, value }: { label: string; value: string }) => ( +
+
+
+ {label} +
+
+
+
+ {value} +
+
+
+) + +const Installed: React.FC = ({ repoUrl, selectedVersion, selectedPackage, onClose }) => ( + <> +
The plugin has been installed successfully.
+
+ {[ + { label: 'Repository', value: repoUrl }, + { label: 'Version', value: selectedVersion }, + { label: 'Package', value: selectedPackage }, + ].map(({ label, value }) => ( + + ))} +
+
+ +
+ +) + +export default Installed diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx new file mode 100644 index 0000000000..2abadb8eb8 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import type { Item } from '@/app/components/base/select' +import { PortalSelect } from '@/app/components/base/select' +import Button from '@/app/components/base/button' + +type SetPackageProps = { + selectedPackage: string + packages: Item[] + onSelect: (item: Item) => void + onInstall: () => void + onBack: () => void +} + +const SetPackage: React.FC = ({ selectedPackage, packages, onSelect, onInstall, onBack }) => ( + <> + + +
+ + +
+ +) + +export default SetPackage diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx new file mode 100644 index 0000000000..a4bfd9f3f3 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import Button from '@/app/components/base/button' + +type SetURLProps = { + repoUrl: string + onChange: (value: string) => void + onNext: () => void + onCancel: () => void +} + +const SetURL: React.FC = ({ repoUrl, onChange, onNext, onCancel }) => ( + <> + + onChange(e.target.value)} + className='flex items-center self-stretch rounded-lg border border-components-input-border-active + bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden + text-components-input-text-filled text-ellipsis system-sm-regular' + placeholder='Please enter GitHub repo URL' + /> +
+ + +
+ +) + +export default SetURL diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx new file mode 100644 index 0000000000..a3f72f0f29 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import type { Item } from '@/app/components/base/select' +import { PortalSelect } from '@/app/components/base/select' +import Button from '@/app/components/base/button' + +type SetVersionProps = { + selectedVersion: string + versions: Item[] + onSelect: (item: Item) => void + onNext: () => void + onBack: () => void +} + +const SetVersion: React.FC = ({ selectedVersion, versions, onSelect, onNext, onBack }) => ( + <> + + +
+ + +
+ +) + +export default SetVersion diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index adf8c5a0f5..1ac4b44762 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -88,20 +88,20 @@ export type PluginDetail = { } export type Plugin = { - 'type': PluginType - 'org': string - 'name': string - 'version': string - 'latest_version': string - 'icon': string - 'label': Record - 'brief': Record + type: PluginType + org: string + name: string + version: string + latest_version: string + icon: string + label: Record + brief: Record // Repo readme.md content - 'introduction': string - 'repository': string - 'category': string - 'install_count': number - 'endpoint': { + introduction: string + repository: string + category: string + install_count: number + endpoint: { settings: CredentialFormSchemaBase[] } } @@ -117,11 +117,11 @@ export type Permissions = { canDebugger: PermissionType } -export enum InstallStep { - url = 'url', - version = 'version', - package = 'package', - installed = 'installed' +export enum InstallStepFromGitHub { + setUrl = 'url', + setVersion = 'version', + setPackage = 'package', + installed = 'installed', } // endpoint