@@ -16,13 +16,14 @@ import {
1616import mitt from "mitt" ;
1717import { ChangeEvent , FormEvent , useRef , useState } from "react" ;
1818import { useTranslation } from "react-i18next" ;
19+ import { Combobox } from "react-widgets" ;
1920import validator from "validator" ;
2021import { SAMPLE_YAML_URL } from "../contents/constants" ;
2122import { hasYamlFileExtension , isYamlFile } from "../yaml-upload" ;
2223import { ResetFormConfirm } from "./ResetFormConfirm" ;
2324
2425type YamlLoadEvents = {
25- loadRemoteYaml : string ;
26+ loadRemoteYaml : { url : string ; source : "gitlab" | "other" } ;
2627 loadFileYaml : File ;
2728} ;
2829
@@ -36,10 +37,17 @@ export default function UploadPanel({ onBack }: { onBack: () => void }) {
3637 const [ isModalVisible , setModalVisibility ] = useState ( false ) ;
3738 const [ url , setUrl ] = useState ( "" ) ;
3839 const [ file , setFile ] = useState < File | null > ( null ) ;
40+ const [ comboboxOpen , setComboboxOpen ] = useState ( false ) ;
41+ const [ source , setSource ] = useState < "gitlab" | "other" > ( null ! ) ;
3942 const [ submitType , setSubmitType ] = useState < "file" | "url" | undefined > (
4043 undefined
4144 ) ;
4245
46+ const sourceOptions = [
47+ { value : "gitlab" , text : t ( "editor.gitlab" ) } ,
48+ { value : "other" , text : t ( "editor.other" ) } ,
49+ ] ;
50+
4351 const handleSubmit = ( event : FormEvent < HTMLFormElement > ) => {
4452 event . preventDefault ( ) ;
4553
@@ -53,18 +61,12 @@ export default function UploadPanel({ onBack }: { onBack: () => void }) {
5361 setSubmitType ( submitType ) ;
5462
5563 if ( submitType === "url" ) {
56- const {
57- [ 0 ] : { value } ,
58- } = event . target as typeof event . target & {
59- [ 0 ] : { value ?: string } ;
60- } ;
61-
62- if ( ! value || ! validator . isURL ( value ) ) {
64+ if ( ! url || ! validator . isURL ( url ) ) {
6365 notify ( t ( "editor.notvalidurl" ) , { state : "error" } ) ;
6466 return ;
6567 }
6668
67- const hasNotYamlFilenameExtension = ! hasYamlFileExtension ( value ) ;
69+ const hasNotYamlFilenameExtension = ! hasYamlFileExtension ( url ) ;
6870 if ( hasNotYamlFilenameExtension ) {
6971 notify ( t ( "editor.filenotsupported" ) , { state : "error" } ) ;
7072 return ;
@@ -98,6 +100,38 @@ export default function UploadPanel({ onBack }: { onBack: () => void }) {
98100 const handleUrlChange = ( event : ChangeEvent < HTMLInputElement > ) => {
99101 const { value } = event . target ;
100102 setUrl ( value ) ;
103+
104+ // Automatically select gitlab source if URL host is gitlab.com
105+ try {
106+ const parsedUrl = new URL ( value ) ;
107+
108+ if ( parsedUrl . host === "gitlab.com" ) {
109+ setSource ( "gitlab" ) ;
110+ }
111+
112+ if ( parsedUrl . host === "github.com" ) {
113+ setSource ( "other" ) ;
114+ }
115+
116+ if ( parsedUrl . host !== "gitlab.com" && parsedUrl . host !== "github.com" ) {
117+ setComboboxOpen ( true ) ;
118+ }
119+ } catch ( error ) {
120+ console . error ( "Invalid URL:" , error ) ;
121+ }
122+ } ;
123+
124+ const handleSourceChange = (
125+ selectedValue : string | { value : string ; text : string } | null
126+ ) => {
127+ if ( selectedValue && typeof selectedValue === "object" ) {
128+ setSource ( selectedValue . value as "gitlab" | "other" ) ;
129+ } else if ( typeof selectedValue === "string" ) {
130+ const option = sourceOptions . find ( ( opt ) => opt . value === selectedValue ) ;
131+ if ( option ) {
132+ setSource ( option . value as "gitlab" | "other" ) ;
133+ }
134+ }
101135 } ;
102136
103137 return (
@@ -175,6 +209,21 @@ export default function UploadPanel({ onBack }: { onBack: () => void }) {
175209 />
176210 </ InputGroup >
177211 </ Row >
212+ { comboboxOpen && (
213+ < Row className = "mt-4 mb-5 pb-4" >
214+ < p className = "text-dark mb-2" > { t ( "editor.source" ) } </ p >
215+ < Combobox
216+ data = { sourceOptions }
217+ value = { sourceOptions . find (
218+ ( opt ) => opt . value === source
219+ ) }
220+ onChange = { handleSourceChange }
221+ textField = "text"
222+ className = "w-100"
223+ placeholder = { t ( "editor.selectSource" ) }
224+ />
225+ </ Row >
226+ ) }
178227 </ Form >
179228 </ TabPane >
180229 </ TabContent >
@@ -187,7 +236,7 @@ export default function UploadPanel({ onBack }: { onBack: () => void }) {
187236 setModalVisibility ( false ) ;
188237 if ( submitType === "url" ) {
189238 onBack ( ) ;
190- yamlLoadEventBus . emit ( "loadRemoteYaml" , url ) ;
239+ yamlLoadEventBus . emit ( "loadRemoteYaml" , { url, source } ) ;
191240 }
192241
193242 if ( submitType === "file" && file ) {
0 commit comments