diff --git a/plugins/scaffolder-backend/sample-templates/test-template-v2/template.yaml b/plugins/scaffolder-backend/sample-templates/test-template-v2/template.yaml
index 08432e6502..6b9e2142d9 100644
--- a/plugins/scaffolder-backend/sample-templates/test-template-v2/template.yaml
+++ b/plugins/scaffolder-backend/sample-templates/test-template-v2/template.yaml
@@ -82,25 +82,29 @@ spec:
type: service
parameters:
- title: Fill in some BS params
- required:
- - name
- properties:
- name:
- title: Name
- type: string
- description: Unique name of the component
- ui:autofocus: true
- ui:options:
- rows: 5
- repoUrl:
- title: Repository Location
- type: string
- description: Copy https://github.com/aeothgiaetgh/aetkijhahte and hammer in some more letters
- ui:field: RepoUrlPicker
- ui:options:
- allowedHosts:
- - github.com
+ - title: Fill in some parameters for the template
+ required:
+ - name
+ properties:
+ name:
+ title: Name
+ type: string
+ description: Unique name of the component
+ ui:autofocus: true
+ ui:options:
+ rows: 5
+ - title: Choose destination
+ required:
+ - repoUrl
+ properties:
+ repoUrl:
+ title: Repository Location
+ type: string
+ ui:field: RepoUrlPicker
+ ui:options:
+ allowedHosts:
+ - github.com
+
steps:
- id: fetch-base
diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx
new file mode 100644
index 0000000000..49c4213251
--- /dev/null
+++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState, useCallback, useEffect } from 'react';
+import { Field } from '@rjsf/core';
+import { useApi, Progress } from '@backstage/core';
+import { scaffolderApiRef } from '../../../api';
+import { useAsync } from 'react-use';
+import Select from '@material-ui/core/Select';
+import InputLabel from '@material-ui/core/InputLabel';
+import Input from '@material-ui/core/Input';
+import FormControl from '@material-ui/core/FormControl';
+import FormHelperText from '@material-ui/core/FormHelperText';
+
+function splitFormData(url: string | undefined) {
+ let host = undefined;
+ let owner = undefined;
+ let repo = undefined;
+
+ try {
+ if (url) {
+ const parsed = new URL(`https://${url}`);
+ host = parsed.host;
+ owner = parsed.searchParams.get('owner') || undefined;
+ repo = parsed.searchParams.get('repo') || undefined;
+ }
+ } catch {
+ /* ok */
+ }
+
+ return { host, owner, repo };
+}
+
+function serializeFormData(data: {
+ host?: string;
+ owner?: string;
+ repo?: string;
+}) {
+ if (!data.host) {
+ return undefined;
+ }
+ const params = new URLSearchParams();
+ if (data.owner) {
+ params.set('owner', data.owner);
+ }
+ if (data.repo) {
+ params.set('repo', data.repo);
+ }
+
+ return `${data.host}?${params.toString()}`;
+}
+
+export const RepoUrlPicker: Field = ({
+ onChange,
+ uiSchema,
+ rawErrors,
+ formData,
+}) => {
+ const api = useApi(scaffolderApiRef);
+ // const allowedHosts = uiSchema['ui:options']?.allowedHosts as string[];
+ const allowedHosts = React.useMemo(
+ () => ['github.com', 'gitlab.com'] as string[],
+ [],
+ );
+
+ const { value: integrations, loading } = useAsync(async () => {
+ return await api.getIntegrationsList({ allowedHosts });
+ });
+
+ const { host, owner, repo } = splitFormData(formData);
+ const updateHost = useCallback(
+ (evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
+ onChange(
+ serializeFormData({ host: evt.target.value as string, owner, repo }),
+ ),
+ [onChange, owner, repo],
+ );
+
+ const updateOwner = useCallback(
+ (evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
+ onChange(
+ serializeFormData({ host, owner: evt.target.value as string, repo }),
+ ),
+ [onChange, host, repo],
+ );
+
+ const updateRepo = useCallback(
+ (evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
+ onChange(
+ serializeFormData({ host, owner, repo: evt.target.value as string }),
+ ),
+ [onChange, host, owner],
+ );
+
+ useEffect(() => {
+ if (host === undefined && integrations?.length) {
+ onChange(serializeFormData({ host: integrations[0].host, owner, repo }));
+ }
+ }, [integrations, host]);
+
+ if (loading) {
+ return ;
+ }
+
+ return (
+ <>
+ 0 && !host}
+ >
+ Host
+
+
+ The host where the repository will be created
+
+
+ 0 && !owner}
+ >
+ Owner
+
+
+ The organization, user or project that this repo will belong to
+
+
+ 0 && !repo}
+ >
+ Repository
+
+ The name of the repository
+
+ >
+ );
+};
diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts
new file mode 100644
index 0000000000..1f7f9e0327
--- /dev/null
+++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.ts
@@ -0,0 +1 @@
+export { RepoUrlPicker } from './RepoUrlPicker';
diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.tsx
deleted file mode 100644
index a20f748d3a..0000000000
--- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/index.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright 2021 Spotify AB
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import React, { useState, useCallback, useEffect } from 'react';
-import { Field } from '@rjsf/core';
-import { useApi, Progress } from '@backstage/core';
-import { scaffolderApiRef } from '../../../api';
-import { useAsync } from 'react-use';
-import Select from '@material-ui/core/Select';
-import InputLabel from '@material-ui/core/InputLabel';
-import Input from '@material-ui/core/Input';
-import FormControl from '@material-ui/core/FormControl';
-import { Typography } from '@material-ui/core';
-import { rest } from 'msw/lib/types';
-
-export const RepoUrlPicker: Field = ({ onChange, uiSchema, ...rest }) => {
- const api = useApi(scaffolderApiRef);
- const allowedHosts = uiSchema['ui:options']?.allowedHosts as string[];
-
- const { value: integrations, loading } = useAsync(async () => {
- return await api.getIntegrationsList({ allowedHosts });
- });
-
- console.log(rest);
-
- const [host, setHost] = useState('');
- const [owner, setOwner] = useState('');
- const [repo, setRepo] = useState('');
-
- const updateHost = useCallback(
- (evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
- setHost(evt.target.value as string),
- [setHost],
- );
-
- const updateOwner = useCallback(
- (evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
- setOwner(evt.target.value as string),
- [setOwner],
- );
-
- const updateRepo = useCallback(
- (evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
- setRepo(evt.target.value as string),
- [setRepo],
- );
-
- useEffect(() => {
- if (host === '' && integrations?.length) {
- setHost(integrations[0].host);
- }
- }, [integrations, host]);
-
- useEffect(() => {
- const params = new URLSearchParams();
- params.set('owner', owner);
- params.set('repo', repo);
-
- onChange(`${encodeURIComponent(host)}?${params.toString()}`);
- }, [host, owner, repo, onChange]);
-
- if (loading) {
- return ;
- }
-
- return (
- <>
- Repository Location
-
- Host
-
-
-
- Owner
-
-
-
- Repository
-
-
- >
- );
-};