chore: think i've finished the refactor of this bloody component now
Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { useApi } from '@backstage/core-plugin-api';
|
||||
import { scmIntegrationsApiRef } from '@backstage/integration-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GithubRepoPicker } from './GithubRepoPicker';
|
||||
import { GitlabRepoPicker } from './GitlabRepoPicker';
|
||||
import { AzureRepoPicker } from './AzureRepoPicker';
|
||||
import { BitbucketRepoPicker } from './BitbucketRepoPicker';
|
||||
import { CustomFieldExtension } from '../../../extensions';
|
||||
import { RepoUrlPickerHost } from './RepoUrlPickerHost';
|
||||
|
||||
export interface RepoUrlPickerUiOptions {
|
||||
allowedHosts?: string[];
|
||||
allowedOwners?: string[];
|
||||
}
|
||||
|
||||
function serializeFormData(data: {
|
||||
host?: string;
|
||||
owner?: string;
|
||||
repo?: string;
|
||||
organization?: string;
|
||||
workspace?: string;
|
||||
project?: 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);
|
||||
}
|
||||
if (data.organization) {
|
||||
params.set('organization', data.organization);
|
||||
}
|
||||
if (data.workspace) {
|
||||
params.set('workspace', data.workspace);
|
||||
}
|
||||
if (data.project) {
|
||||
params.set('project', data.project);
|
||||
}
|
||||
|
||||
return `${data.host}?${params.toString()}`;
|
||||
}
|
||||
|
||||
export const RepoUrlPicker = ({
|
||||
uiSchema,
|
||||
onChange,
|
||||
rawErrors,
|
||||
formData,
|
||||
}: CustomFieldExtension<string, RepoUrlPickerUiOptions>) => {
|
||||
const [state, setState] = useState<{
|
||||
host?: string;
|
||||
owner?: string;
|
||||
repo?: string;
|
||||
organization?: string;
|
||||
workspace?: string;
|
||||
project?: string;
|
||||
}>({});
|
||||
const integrationApi = useApi(scmIntegrationsApiRef);
|
||||
|
||||
const allowedHosts = uiSchema?.['ui:options']?.allowedHosts ?? [];
|
||||
const allowedOwners = uiSchema?.['ui:options']?.allowedOwners ?? [];
|
||||
|
||||
useEffect(() => {
|
||||
onChange(serializeFormData(state));
|
||||
}, [state, onChange]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<RepoUrlPickerHost
|
||||
host={state.host}
|
||||
hosts={allowedHosts}
|
||||
onChange={host => setState({ host })}
|
||||
rawErrors={rawErrors}
|
||||
/>
|
||||
{state.host && integrationApi.byHost(state.host)?.type === 'github' && (
|
||||
<GithubRepoPicker
|
||||
allowedOwners={allowedOwners}
|
||||
rawErrors={rawErrors}
|
||||
owner={state.owner}
|
||||
repoName={state.repo}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onOwnerChange={owner =>
|
||||
setState(prevState => ({ ...prevState, owner }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{state.host && integrationApi.byHost(state.host)?.type === 'gitlab' && (
|
||||
<GitlabRepoPicker
|
||||
allowedOwners={allowedOwners}
|
||||
rawErrors={rawErrors}
|
||||
owner={state.owner}
|
||||
repoName={state.repo}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onOwnerChange={owner =>
|
||||
setState(prevState => ({ ...prevState, owner }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{state.host &&
|
||||
integrationApi.byHost(state.host)?.type === 'bitbucket' && (
|
||||
<BitbucketRepoPicker
|
||||
rawErrors={rawErrors}
|
||||
host={state.host}
|
||||
project={state.project}
|
||||
workspace={state.workspace}
|
||||
repoName={state.repo}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onProjectChange={project =>
|
||||
setState(prevState => ({ ...prevState, project }))
|
||||
}
|
||||
onWorkspaceChange={workspace =>
|
||||
setState(prevState => ({ ...prevState, workspace }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{state.host && integrationApi.byHost(state.host)?.type === 'azure' && (
|
||||
<AzureRepoPicker
|
||||
rawErrors={rawErrors}
|
||||
org={state.organization}
|
||||
repoName={state.repo}
|
||||
owner={state.owner}
|
||||
onOwnerChange={owner =>
|
||||
setState(prevState => ({ ...prevState, owner }))
|
||||
}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onOrgChange={org =>
|
||||
setState(prevState => ({ ...prevState, organization: org }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -13,371 +13,117 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
Progress,
|
||||
Select,
|
||||
SelectedItems,
|
||||
SelectItem,
|
||||
} from '@backstage/core-components';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { scmIntegrationsApiRef } from '@backstage/integration-react';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
import Input from '@material-ui/core/Input';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import { FieldProps } from '@rjsf/core';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { scaffolderApiRef } from '../../../api';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GithubRepoPicker } from './GithubRepoPicker';
|
||||
import { GitlabRepoPicker } from './GitlabRepoPicker';
|
||||
import { AzureRepoPicker } from './AzureRepoPicker';
|
||||
import { BitbucketRepoPicker } from './BitbucketRepoPicker';
|
||||
import { CustomFieldExtension } from '../../../extensions';
|
||||
import { RepoUrlPickerHost } from './RepoUrlPickerHost';
|
||||
import { splitFormData, serializeFormData } from './utils';
|
||||
|
||||
function splitFormData(url: string | undefined, allowedOwners?: string[]) {
|
||||
let host = undefined;
|
||||
let owner = undefined;
|
||||
let repo = undefined;
|
||||
let organization = undefined;
|
||||
let workspace = undefined;
|
||||
let project = undefined;
|
||||
|
||||
try {
|
||||
if (url) {
|
||||
const parsed = new URL(`https://${url}`);
|
||||
host = parsed.host;
|
||||
owner = parsed.searchParams.get('owner') || allowedOwners?.[0];
|
||||
repo = parsed.searchParams.get('repo') || undefined;
|
||||
// This is azure dev ops specific. not used for any other provider.
|
||||
organization = parsed.searchParams.get('organization') || undefined;
|
||||
// These are bitbucket specific, not used for any other provider.
|
||||
workspace = parsed.searchParams.get('workspace') || undefined;
|
||||
project = parsed.searchParams.get('project') || undefined;
|
||||
}
|
||||
} catch {
|
||||
/* ok */
|
||||
}
|
||||
|
||||
return { host, owner, repo, organization, workspace, project };
|
||||
}
|
||||
|
||||
function serializeFormData(data: {
|
||||
host?: string;
|
||||
owner?: string;
|
||||
repo?: string;
|
||||
organization?: string;
|
||||
workspace?: string;
|
||||
project?: 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);
|
||||
}
|
||||
if (data.organization) {
|
||||
params.set('organization', data.organization);
|
||||
}
|
||||
if (data.workspace) {
|
||||
params.set('workspace', data.workspace);
|
||||
}
|
||||
if (data.project) {
|
||||
params.set('project', data.project);
|
||||
}
|
||||
|
||||
return `${data.host}?${params.toString()}`;
|
||||
export interface RepoUrlPickerUiOptions {
|
||||
allowedHosts?: string[];
|
||||
allowedOwners?: string[];
|
||||
}
|
||||
|
||||
export const RepoUrlPicker = ({
|
||||
onChange,
|
||||
uiSchema,
|
||||
onChange,
|
||||
rawErrors,
|
||||
formData,
|
||||
}: FieldProps<string>) => {
|
||||
const scaffolderApi = useApi(scaffolderApiRef);
|
||||
}: CustomFieldExtension<string, RepoUrlPickerUiOptions>) => {
|
||||
const [state, setState] = useState<{
|
||||
host?: string;
|
||||
owner?: string;
|
||||
repo?: string;
|
||||
organization?: string;
|
||||
workspace?: string;
|
||||
project?: string;
|
||||
}>(splitFormData(formData));
|
||||
const integrationApi = useApi(scmIntegrationsApiRef);
|
||||
const allowedHosts = uiSchema['ui:options']?.allowedHosts as string[];
|
||||
const allowedOwners = uiSchema['ui:options']?.allowedOwners as string[];
|
||||
|
||||
const { value: integrations, loading } = useAsync(async () => {
|
||||
return await scaffolderApi.getIntegrationsList({ allowedHosts });
|
||||
});
|
||||
|
||||
const { host, owner, repo, organization, workspace, project } = splitFormData(
|
||||
formData,
|
||||
allowedOwners,
|
||||
);
|
||||
const updateHost = useCallback(
|
||||
(value: SelectedItems) => {
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host: value as string,
|
||||
owner,
|
||||
repo,
|
||||
organization,
|
||||
workspace,
|
||||
project,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[onChange, owner, repo, organization, workspace, project],
|
||||
);
|
||||
|
||||
const updateOwnerSelect = useCallback(
|
||||
(value: SelectedItems) =>
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host,
|
||||
owner: value as string,
|
||||
repo,
|
||||
organization,
|
||||
workspace,
|
||||
project,
|
||||
}),
|
||||
),
|
||||
[onChange, host, repo, organization, workspace, project],
|
||||
);
|
||||
|
||||
const updateOwner = useCallback(
|
||||
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host,
|
||||
owner: evt.target.value as string,
|
||||
repo,
|
||||
organization,
|
||||
workspace,
|
||||
project,
|
||||
}),
|
||||
),
|
||||
[onChange, host, repo, organization, workspace, project],
|
||||
);
|
||||
|
||||
const updateRepo = useCallback(
|
||||
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host,
|
||||
owner,
|
||||
repo: evt.target.value as string,
|
||||
organization,
|
||||
workspace,
|
||||
project,
|
||||
}),
|
||||
),
|
||||
[onChange, host, owner, organization, workspace, project],
|
||||
);
|
||||
|
||||
const updateOrganization = useCallback(
|
||||
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host,
|
||||
owner,
|
||||
repo,
|
||||
organization: evt.target.value as string,
|
||||
workspace,
|
||||
project,
|
||||
}),
|
||||
),
|
||||
[onChange, host, owner, repo, workspace, project],
|
||||
);
|
||||
|
||||
const updateWorkspace = useCallback(
|
||||
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host,
|
||||
owner,
|
||||
repo,
|
||||
organization,
|
||||
workspace: evt.target.value as string,
|
||||
project,
|
||||
}),
|
||||
),
|
||||
[onChange, host, owner, repo, organization, project],
|
||||
);
|
||||
|
||||
const updateProject = useCallback(
|
||||
(evt: React.ChangeEvent<{ name?: string; value: unknown }>) =>
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host,
|
||||
owner,
|
||||
repo,
|
||||
organization,
|
||||
workspace,
|
||||
project: evt.target.value as string,
|
||||
}),
|
||||
),
|
||||
[onChange, host, owner, repo, organization, workspace],
|
||||
);
|
||||
const allowedHosts = uiSchema?.['ui:options']?.allowedHosts ?? [];
|
||||
const allowedOwners = uiSchema?.['ui:options']?.allowedOwners ?? [];
|
||||
|
||||
useEffect(() => {
|
||||
if (host === undefined && integrations?.length) {
|
||||
onChange(
|
||||
serializeFormData({
|
||||
host: integrations[0].host,
|
||||
owner,
|
||||
repo,
|
||||
organization,
|
||||
workspace,
|
||||
project,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}, [
|
||||
onChange,
|
||||
integrations,
|
||||
host,
|
||||
owner,
|
||||
repo,
|
||||
organization,
|
||||
workspace,
|
||||
project,
|
||||
]);
|
||||
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
}
|
||||
|
||||
const hostsOptions: SelectItem[] = integrations
|
||||
? integrations
|
||||
.filter(i => allowedHosts?.includes(i.host))
|
||||
.map(i => ({ label: i.title, value: i.host }))
|
||||
: [{ label: 'Loading...', value: 'loading' }];
|
||||
|
||||
const ownersOptions: SelectItem[] = allowedOwners
|
||||
? allowedOwners.map(i => ({ label: i, value: i }))
|
||||
: [{ label: 'Loading...', value: 'loading' }];
|
||||
onChange(serializeFormData(state));
|
||||
}, [state, onChange]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !host}
|
||||
>
|
||||
<Select
|
||||
native
|
||||
disabled={hostsOptions.length === 1}
|
||||
label="Host"
|
||||
onChange={updateHost}
|
||||
selected={host}
|
||||
items={hostsOptions}
|
||||
<RepoUrlPickerHost
|
||||
host={state.host}
|
||||
hosts={allowedHosts}
|
||||
onChange={host => setState({ host })}
|
||||
rawErrors={rawErrors}
|
||||
/>
|
||||
{state.host && integrationApi.byHost(state.host)?.type === 'github' && (
|
||||
<GithubRepoPicker
|
||||
allowedOwners={allowedOwners}
|
||||
rawErrors={rawErrors}
|
||||
owner={state.owner}
|
||||
repoName={state.repo}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onOwnerChange={owner =>
|
||||
setState(prevState => ({ ...prevState, owner }))
|
||||
}
|
||||
/>
|
||||
|
||||
<FormHelperText>
|
||||
The host where the repository will be created
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
{/* Show this for dev.azure.com only */}
|
||||
{host === 'dev.azure.com' && (
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !organization}
|
||||
>
|
||||
<InputLabel htmlFor="repoInput">Organization</InputLabel>
|
||||
<Input
|
||||
id="repoInput"
|
||||
onChange={updateOrganization}
|
||||
value={organization}
|
||||
)}
|
||||
{state.host && integrationApi.byHost(state.host)?.type === 'gitlab' && (
|
||||
<GitlabRepoPicker
|
||||
allowedOwners={allowedOwners}
|
||||
rawErrors={rawErrors}
|
||||
owner={state.owner}
|
||||
repoName={state.repo}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onOwnerChange={owner =>
|
||||
setState(prevState => ({ ...prevState, owner }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{state.host &&
|
||||
integrationApi.byHost(state.host)?.type === 'bitbucket' && (
|
||||
<BitbucketRepoPicker
|
||||
rawErrors={rawErrors}
|
||||
host={state.host}
|
||||
project={state.project}
|
||||
workspace={state.workspace}
|
||||
repoName={state.repo}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onProjectChange={project =>
|
||||
setState(prevState => ({ ...prevState, project }))
|
||||
}
|
||||
onWorkspaceChange={workspace =>
|
||||
setState(prevState => ({ ...prevState, workspace }))
|
||||
}
|
||||
/>
|
||||
<FormHelperText>The name of the organization</FormHelperText>
|
||||
</FormControl>
|
||||
)}
|
||||
{host && integrationApi.byHost(host)?.type === 'bitbucket' && (
|
||||
<>
|
||||
{/* Show this for bitbucket.org only */}
|
||||
{host === 'bitbucket.org' && (
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !workspace}
|
||||
>
|
||||
<InputLabel htmlFor="wokrspaceInput">Workspace</InputLabel>
|
||||
<Input
|
||||
id="wokrspaceInput"
|
||||
onChange={updateWorkspace}
|
||||
value={workspace}
|
||||
/>
|
||||
<FormHelperText>
|
||||
The workspace where the repository will be created
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
)}
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !project}
|
||||
>
|
||||
<InputLabel htmlFor="wokrspaceInput">Project</InputLabel>
|
||||
<Input
|
||||
id="wokrspaceInput"
|
||||
onChange={updateProject}
|
||||
value={project}
|
||||
/>
|
||||
<FormHelperText>
|
||||
The project where the repository will be created
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
</>
|
||||
)}
|
||||
{/* Show this for all hosts except bitbucket */}
|
||||
{host &&
|
||||
integrationApi.byHost(host)?.type !== 'bitbucket' &&
|
||||
!allowedOwners && (
|
||||
<>
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !owner}
|
||||
>
|
||||
<InputLabel htmlFor="ownerInput">Owner</InputLabel>
|
||||
<Input id="ownerInput" onChange={updateOwner} value={owner} />
|
||||
<FormHelperText>
|
||||
The organization, user or project that this repo will belong to
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
</>
|
||||
)}
|
||||
{/* Show this for all hosts except bitbucket where allowed owner is set */}
|
||||
{host &&
|
||||
integrationApi.byHost(host)?.type !== 'bitbucket' &&
|
||||
allowedOwners && (
|
||||
<>
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !owner}
|
||||
>
|
||||
<Select
|
||||
native
|
||||
label="Owner Available"
|
||||
onChange={updateOwnerSelect}
|
||||
disabled={ownersOptions.length === 1}
|
||||
selected={owner}
|
||||
items={ownersOptions}
|
||||
/>
|
||||
|
||||
<FormHelperText>
|
||||
The organization, user or project that this repo will belong to
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
</>
|
||||
)}
|
||||
{/* Show this for all hosts */}
|
||||
<FormControl
|
||||
margin="normal"
|
||||
required
|
||||
error={rawErrors?.length > 0 && !repo}
|
||||
>
|
||||
<InputLabel htmlFor="repoInput">Repository</InputLabel>
|
||||
<Input id="repoInput" onChange={updateRepo} value={repo} />
|
||||
<FormHelperText>The name of the repository</FormHelperText>
|
||||
</FormControl>
|
||||
{state.host && integrationApi.byHost(state.host)?.type === 'azure' && (
|
||||
<AzureRepoPicker
|
||||
rawErrors={rawErrors}
|
||||
org={state.organization}
|
||||
repoName={state.repo}
|
||||
owner={state.owner}
|
||||
onOwnerChange={owner =>
|
||||
setState(prevState => ({ ...prevState, owner }))
|
||||
}
|
||||
onRepoNameChange={repo =>
|
||||
setState(prevState => ({ ...prevState, repo }))
|
||||
}
|
||||
onOrgChange={org =>
|
||||
setState(prevState => ({ ...prevState, organization: org }))
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { RepoUrlPicker } from './NewRepoUrlPicker';
|
||||
export { RepoUrlPicker } from './RepoUrlPicker';
|
||||
export { repoPickerValidation } from './validation';
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
export function serializeFormData(data: {
|
||||
host?: string;
|
||||
owner?: string;
|
||||
repo?: string;
|
||||
organization?: string;
|
||||
workspace?: string;
|
||||
project?: 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);
|
||||
}
|
||||
if (data.organization) {
|
||||
params.set('organization', data.organization);
|
||||
}
|
||||
if (data.workspace) {
|
||||
params.set('workspace', data.workspace);
|
||||
}
|
||||
if (data.project) {
|
||||
params.set('project', data.project);
|
||||
}
|
||||
|
||||
return `${data.host}?${params.toString()}`;
|
||||
}
|
||||
|
||||
export function splitFormData(url: string | undefined) {
|
||||
let host = undefined;
|
||||
let owner = undefined;
|
||||
let repo = undefined;
|
||||
let organization = undefined;
|
||||
let workspace = undefined;
|
||||
let project = 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;
|
||||
organization = parsed.searchParams.get('organization') || undefined;
|
||||
workspace = parsed.searchParams.get('workspace') || undefined;
|
||||
project = parsed.searchParams.get('project') || undefined;
|
||||
}
|
||||
} catch {
|
||||
/* ok */
|
||||
}
|
||||
|
||||
return { host, owner, repo, organization, workspace, project };
|
||||
}
|
||||
Reference in New Issue
Block a user