@@ -108,6 +108,12 @@ export const LightLabel = styled.span` | |||
color: ${themeColor('pageContentLight')}; | |||
`; | |||
export const DarkLabel = styled.label` | |||
color: ${themeColor('pageContentDark')}; | |||
${tw`sw-body-sm-highlight`} | |||
`; | |||
export const LightPrimary = styled.span` | |||
color: ${themeContrast('primaryLight')}; | |||
`; |
@@ -31,8 +31,8 @@ import { getHostUrl } from '../../../../helpers/urls'; | |||
import { GithubOrganization, GithubRepository } from '../../../../types/alm-integration'; | |||
import { AlmKeys, AlmSettingsInstance } from '../../../../types/alm-settings'; | |||
import { Paging } from '../../../../types/types'; | |||
import GitHubProjectCreateRenderer from './GitHubProjectCreateRenderer'; | |||
import { CreateProjectApiCallback } from '../types'; | |||
import GitHubProjectCreateRenderer from './GitHubProjectCreateRenderer'; | |||
interface Props { | |||
canAdmin: boolean; | |||
@@ -52,7 +52,6 @@ interface State { | |||
repositories: GithubRepository[]; | |||
searchQuery: string; | |||
selectedOrganization?: GithubOrganization; | |||
selectedRepository?: GithubRepository; | |||
selectedAlmInstance?: AlmSettingsInstance; | |||
} | |||
@@ -231,7 +230,6 @@ export default class GitHubProjectCreate extends React.Component<Props, State> { | |||
triggerSearch = (query: string) => { | |||
const { selectedOrganization } = this.state; | |||
if (selectedOrganization) { | |||
this.setState({ selectedRepository: undefined }); | |||
this.fetchRepositories({ organizationKey: selectedOrganization.key, query }); | |||
} | |||
}; | |||
@@ -239,18 +237,11 @@ export default class GitHubProjectCreate extends React.Component<Props, State> { | |||
handleSelectOrganization = (key: string) => { | |||
this.setState(({ organizations }) => ({ | |||
searchQuery: '', | |||
selectedRepository: undefined, | |||
selectedOrganization: organizations.find((o) => o.key === key), | |||
})); | |||
this.fetchRepositories({ organizationKey: key }); | |||
}; | |||
handleSelectRepository = (key: string) => { | |||
this.setState(({ repositories }) => ({ | |||
selectedRepository: repositories?.find((r) => r.key === key), | |||
})); | |||
}; | |||
handleSearch = (searchQuery: string) => { | |||
this.setState({ searchQuery }); | |||
this.triggerSearch(searchQuery); | |||
@@ -268,15 +259,15 @@ export default class GitHubProjectCreate extends React.Component<Props, State> { | |||
} | |||
}; | |||
handleImportRepository = () => { | |||
const { selectedOrganization, selectedRepository, selectedAlmInstance } = this.state; | |||
handleImportRepository = (repoKey: string) => { | |||
const { selectedOrganization, selectedAlmInstance } = this.state; | |||
if (selectedAlmInstance && selectedOrganization && selectedRepository) { | |||
if (selectedAlmInstance && selectedOrganization && repoKey !== '') { | |||
this.props.onProjectSetupDone( | |||
setupGithubProjectCreation({ | |||
almSetting: selectedAlmInstance.key, | |||
organization: selectedOrganization.key, | |||
repositoryKey: selectedRepository.key, | |||
repositoryKey: repoKey, | |||
}) | |||
); | |||
} | |||
@@ -304,7 +295,6 @@ export default class GitHubProjectCreate extends React.Component<Props, State> { | |||
repositories, | |||
searchQuery, | |||
selectedOrganization, | |||
selectedRepository, | |||
selectedAlmInstance, | |||
} = this.state; | |||
@@ -319,13 +309,11 @@ export default class GitHubProjectCreate extends React.Component<Props, State> { | |||
onLoadMore={this.handleLoadMore} | |||
onSearch={this.handleSearch} | |||
onSelectOrganization={this.handleSelectOrganization} | |||
onSelectRepository={this.handleSelectRepository} | |||
organizations={organizations} | |||
repositoryPaging={repositoryPaging} | |||
searchQuery={searchQuery} | |||
repositories={repositories} | |||
selectedOrganization={selectedOrganization} | |||
selectedRepository={selectedRepository} | |||
almInstances={almInstances} | |||
selectedAlmInstance={selectedAlmInstance} | |||
onSelectedAlmInstanceChange={this.onSelectedAlmInstanceChange} |
@@ -19,28 +19,27 @@ | |||
*/ | |||
/* eslint-disable react/no-unused-prop-types */ | |||
import { | |||
DarkLabel, | |||
DeferredSpinner, | |||
FlagMessage, | |||
InputSearch, | |||
InputSelect, | |||
LightPrimary, | |||
Link, | |||
Title, | |||
} from 'design-system'; | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { colors } from '../../../../app/theme'; | |||
import Link from '../../../../components/common/Link'; | |||
import ListFooter from '../../../../components/controls/ListFooter'; | |||
import Radio from '../../../../components/controls/Radio'; | |||
import SearchBox from '../../../../components/controls/SearchBox'; | |||
import Select, { LabelValueSelectOption } from '../../../../components/controls/Select'; | |||
import { Button } from '../../../../components/controls/buttons'; | |||
import CheckIcon from '../../../../components/icons/CheckIcon'; | |||
import QualifierIcon from '../../../../components/icons/QualifierIcon'; | |||
import { Alert } from '../../../../components/ui/Alert'; | |||
import DeferredSpinner from '../../../../components/ui/DeferredSpinner'; | |||
import { LabelValueSelectOption } from '../../../../components/controls/Select'; | |||
import { translate } from '../../../../helpers/l10n'; | |||
import { getBaseUrl } from '../../../../helpers/system'; | |||
import { getProjectUrl } from '../../../../helpers/urls'; | |||
import { GithubOrganization, GithubRepository } from '../../../../types/alm-integration'; | |||
import { AlmKeys, AlmSettingsInstance } from '../../../../types/alm-settings'; | |||
import { ComponentQualifier } from '../../../../types/component'; | |||
import { Paging } from '../../../../types/types'; | |||
import AlmRepoItem from '../components/AlmRepoItem'; | |||
import AlmSettingsInstanceDropdown from '../components/AlmSettingsInstanceDropdown'; | |||
import CreateProjectPageHeader from '../components/CreateProjectPageHeader'; | |||
export interface GitHubProjectCreateRendererProps { | |||
canAdmin: boolean; | |||
@@ -48,17 +47,15 @@ export interface GitHubProjectCreateRendererProps { | |||
loadingBindings: boolean; | |||
loadingOrganizations: boolean; | |||
loadingRepositories: boolean; | |||
onImportRepository: () => void; | |||
onImportRepository: (key: string) => void; | |||
onLoadMore: () => void; | |||
onSearch: (q: string) => void; | |||
onSelectOrganization: (key: string) => void; | |||
onSelectRepository: (key: string) => void; | |||
organizations: GithubOrganization[]; | |||
repositories?: GithubRepository[]; | |||
repositoryPaging: Paging; | |||
searchQuery: string; | |||
selectedOrganization?: GithubOrganization; | |||
selectedRepository?: GithubRepository; | |||
almInstances: AlmSettingsInstance[]; | |||
selectedAlmInstance?: AlmSettingsInstance; | |||
onSelectedAlmInstanceChange: (instance: AlmSettingsInstance) => void; | |||
@@ -69,89 +66,40 @@ function orgToOption({ key, name }: GithubOrganization) { | |||
} | |||
function renderRepositoryList(props: GitHubProjectCreateRendererProps) { | |||
const { | |||
loadingRepositories, | |||
repositories, | |||
repositoryPaging, | |||
searchQuery, | |||
selectedOrganization, | |||
selectedRepository, | |||
} = props; | |||
const isChecked = (repository: GithubRepository) => | |||
!!repository.sqProjectKey || | |||
(!!selectedRepository && selectedRepository.key === repository.key); | |||
const isDisabled = (repository: GithubRepository) => | |||
!!repository.sqProjectKey || loadingRepositories; | |||
const { loadingRepositories, repositories, repositoryPaging, searchQuery, selectedOrganization } = | |||
props; | |||
return ( | |||
selectedOrganization && | |||
repositories && ( | |||
<div className="boxed-group padded display-flex-wrap"> | |||
<div className="width-100"> | |||
<SearchBox | |||
className="big-spacer-bottom" | |||
<div> | |||
<div className="sw-flex sw-items-center sw-mb-6"> | |||
<InputSearch | |||
size="large" | |||
onChange={props.onSearch} | |||
placeholder={translate('onboarding.create_project.search_repositories')} | |||
value={searchQuery} | |||
clearIconAriaLabel={translate('clear')} | |||
/> | |||
<DeferredSpinner loading={loadingRepositories} className="sw-ml-2" /> | |||
</div> | |||
{repositories.length === 0 ? ( | |||
<div className="padded"> | |||
<DeferredSpinner loading={loadingRepositories}> | |||
{translate('no_results')} | |||
</DeferredSpinner> | |||
<div className="sw-py-6 sw-px-2"> | |||
<LightPrimary className="sw-body-sm">{translate('no_results')}</LightPrimary> | |||
</div> | |||
) : ( | |||
repositories.map((r) => ( | |||
<Radio | |||
className="spacer-top spacer-bottom padded create-project-github-repository" | |||
<AlmRepoItem | |||
key={r.key} | |||
checked={isChecked(r)} | |||
disabled={isDisabled(r)} | |||
value={r.key} | |||
onCheck={props.onSelectRepository} | |||
> | |||
<div className="big overflow-hidden max-width-100" title={r.name}> | |||
<div className="text-ellipsis"> | |||
{r.sqProjectKey ? ( | |||
<div className="display-flex-center max-width-100"> | |||
<Link | |||
className="display-flex-center max-width-60" | |||
to={getProjectUrl(r.sqProjectKey)} | |||
> | |||
<QualifierIcon | |||
className="spacer-right" | |||
qualifier={ComponentQualifier.Project} | |||
/> | |||
<span className="text-ellipsis">{r.name}</span> | |||
</Link> | |||
<em className="display-flex-center small big-spacer-left flex-0"> | |||
<span className="text-muted-2"> | |||
{translate('onboarding.create_project.repository_imported')} | |||
</span> | |||
<CheckIcon className="little-spacer-left" size={12} fill={colors.green} /> | |||
</em> | |||
</div> | |||
) : ( | |||
r.name | |||
)} | |||
</div> | |||
{r.url && ( | |||
<a | |||
className="notice small display-flex-center little-spacer-top" | |||
onClick={(e) => e.stopPropagation()} | |||
target="_blank" | |||
href={r.url} | |||
rel="noopener noreferrer" | |||
> | |||
{translate('onboarding.create_project.see_on_github')} | |||
</a> | |||
)} | |||
</div> | |||
</Radio> | |||
almKey={r.key} | |||
almUrl={r.url} | |||
almUrlText={translate('onboarding.create_project.see_on_github')} | |||
almIconSrc={`${getBaseUrl()}/images/tutorials/github-actions.svg`} | |||
sqProjectKey={r.sqProjectKey} | |||
onImport={props.onImportRepository} | |||
primaryTextNode={<span title={r.name}>{r.name}</span>} | |||
/> | |||
)) | |||
)} | |||
@@ -161,6 +109,7 @@ function renderRepositoryList(props: GitHubProjectCreateRendererProps) { | |||
total={repositoryPaging.total} | |||
loadMore={props.onLoadMore} | |||
loading={loadingRepositories} | |||
useMIUIButtons | |||
/> | |||
</div> | |||
</div> | |||
@@ -176,7 +125,6 @@ export default function GitHubProjectCreateRenderer(props: GitHubProjectCreateRe | |||
loadingOrganizations, | |||
organizations, | |||
selectedOrganization, | |||
selectedRepository, | |||
almInstances, | |||
selectedAlmInstance, | |||
} = props; | |||
@@ -186,33 +134,13 @@ export default function GitHubProjectCreateRenderer(props: GitHubProjectCreateRe | |||
} | |||
return ( | |||
<div> | |||
<CreateProjectPageHeader | |||
additionalActions={ | |||
selectedOrganization && ( | |||
<div className="display-flex-center pull-right"> | |||
<Button | |||
className="button-large button-primary" | |||
disabled={!selectedRepository} | |||
onClick={props.onImportRepository} | |||
> | |||
{translate('onboarding.create_project.import_selected_repo')} | |||
</Button> | |||
</div> | |||
) | |||
} | |||
title={ | |||
<span className="text-middle display-flex-center"> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
className="spacer-right" | |||
height={24} | |||
src={`${getBaseUrl()}/images/alm/github.svg`} | |||
/> | |||
{translate('onboarding.create_project.github.title')} | |||
</span> | |||
} | |||
/> | |||
<> | |||
<header className="sw-mb-10"> | |||
<Title className="sw-mb-4">{translate('onboarding.create_project.github.title')}</Title> | |||
<LightPrimary className="sw-body-sm"> | |||
{translate('onboarding.create_project.github.subtitle')} | |||
</LightPrimary> | |||
</header> | |||
<AlmSettingsInstanceDropdown | |||
almKey={AlmKeys.GitHub} | |||
@@ -222,76 +150,73 @@ export default function GitHubProjectCreateRenderer(props: GitHubProjectCreateRe | |||
/> | |||
{error && selectedAlmInstance && ( | |||
<div className="display-flex-justify-center"> | |||
<div className="boxed-group padded width-50 huge-spacer-top"> | |||
<h2 className="big-spacer-bottom"> | |||
{translate('onboarding.create_project.github.warning.title')} | |||
</h2> | |||
<Alert variant="warning"> | |||
{canAdmin ? ( | |||
<FormattedMessage | |||
id="onboarding.create_project.github.warning.message_admin" | |||
defaultMessage={translate( | |||
'onboarding.create_project.github.warning.message_admin' | |||
)} | |||
values={{ | |||
link: ( | |||
<Link to="/admin/settings?category=almintegration"> | |||
{translate('onboarding.create_project.github.warning.message_admin.link')} | |||
</Link> | |||
), | |||
}} | |||
/> | |||
) : ( | |||
translate('onboarding.create_project.github.warning.message') | |||
)} | |||
</Alert> | |||
</div> | |||
</div> | |||
<FlagMessage variant="warning" className="sw-my-2"> | |||
<span> | |||
{canAdmin ? ( | |||
<FormattedMessage | |||
id="onboarding.create_project.github.warning.message_admin" | |||
defaultMessage={translate('onboarding.create_project.github.warning.message_admin')} | |||
values={{ | |||
link: ( | |||
<Link to="/admin/settings?category=almintegration"> | |||
{translate('onboarding.create_project.github.warning.message_admin.link')} | |||
</Link> | |||
), | |||
}} | |||
/> | |||
) : ( | |||
translate('onboarding.create_project.github.warning.message') | |||
)} | |||
</span> | |||
</FlagMessage> | |||
)} | |||
{!error && ( | |||
<DeferredSpinner loading={loadingOrganizations}> | |||
<div className="form-field"> | |||
<label htmlFor="github-choose-organization"> | |||
<DeferredSpinner loading={loadingOrganizations && !error}> | |||
{!error && ( | |||
<div className="sw-flex sw-flex-col"> | |||
<DarkLabel htmlFor="github-choose-organization" className="sw-mb-2"> | |||
{translate('onboarding.create_project.github.choose_organization')} | |||
</label> | |||
</DarkLabel> | |||
{organizations.length > 0 ? ( | |||
<Select | |||
<InputSelect | |||
className="sw-w-abs-300 sw-mb-9" | |||
size="full" | |||
isSearchable | |||
inputId="github-choose-organization" | |||
className="input-super-large" | |||
options={organizations.map(orgToOption)} | |||
onChange={({ value }: LabelValueSelectOption) => props.onSelectOrganization(value)} | |||
value={selectedOrganization ? orgToOption(selectedOrganization) : null} | |||
/> | |||
) : ( | |||
!loadingOrganizations && ( | |||
<Alert className="spacer-top" variant="error"> | |||
{canAdmin ? ( | |||
<FormattedMessage | |||
id="onboarding.create_project.github.no_orgs_admin" | |||
defaultMessage={translate('onboarding.create_project.github.no_orgs_admin')} | |||
values={{ | |||
link: ( | |||
<Link to="/admin/settings?category=almintegration"> | |||
{translate( | |||
'onboarding.create_project.github.warning.message_admin.link' | |||
)} | |||
</Link> | |||
), | |||
}} | |||
/> | |||
) : ( | |||
translate('onboarding.create_project.github.no_orgs') | |||
)} | |||
</Alert> | |||
<FlagMessage variant="error" className="sw-mb-2"> | |||
<span> | |||
{canAdmin ? ( | |||
<FormattedMessage | |||
id="onboarding.create_project.github.no_orgs_admin" | |||
defaultMessage={translate('onboarding.create_project.github.no_orgs_admin')} | |||
values={{ | |||
link: ( | |||
<Link to="/admin/settings?category=almintegration"> | |||
{translate( | |||
'onboarding.create_project.github.warning.message_admin.link' | |||
)} | |||
</Link> | |||
), | |||
}} | |||
/> | |||
) : ( | |||
translate('onboarding.create_project.github.no_orgs') | |||
)} | |||
</span> | |||
</FlagMessage> | |||
) | |||
)} | |||
</div> | |||
</DeferredSpinner> | |||
)} | |||
)} | |||
</DeferredSpinner> | |||
{renderRepositoryList(props)} | |||
</div> | |||
</> | |||
); | |||
} |
@@ -106,8 +106,8 @@ it('should show import project feature when the authentication is successfull', | |||
expect(screen.getByText('Github repo 1')).toBeInTheDocument(); | |||
expect(screen.getByText('Github repo 2')).toBeInTheDocument(); | |||
repoItem = screen.getByRole('radio', { | |||
name: 'Github repo 1', | |||
repoItem = screen.getByRole('row', { | |||
name: 'Github repo 1 onboarding.create_project.see_on_github onboarding.create_project.repository_imported', | |||
}); | |||
expect( | |||
@@ -120,16 +120,11 @@ it('should show import project feature when the authentication is successfull', | |||
'/dashboard?id=key123' | |||
); | |||
repoItem = screen.getByRole('radio', { | |||
name: 'Github repo 2', | |||
repoItem = screen.getByRole('row', { | |||
name: 'Github repo 2 onboarding.create_project.see_on_github onboarding.create_project.import', | |||
}); | |||
const importButton = screen.getByText('onboarding.create_project.import_selected_repo'); | |||
expect(repoItem).toBeInTheDocument(); | |||
expect(importButton).toBeDisabled(); | |||
await user.click(repoItem); | |||
expect(importButton).toBeEnabled(); | |||
const importButton = screen.getByText('onboarding.create_project.import'); | |||
await user.click(importButton); | |||
expect( | |||
@@ -154,9 +149,7 @@ it('should show search filter when the authentication is successful', async () = | |||
await selectEvent.select(ui.organizationSelector.get(), [/org-1/]); | |||
const inputSearch = screen.getByRole('searchbox', { | |||
name: 'onboarding.create_project.search_repositories', | |||
}); | |||
const inputSearch = screen.getByRole('searchbox'); | |||
await user.click(inputSearch); | |||
await user.keyboard('search'); | |||
@@ -58,9 +58,10 @@ export default function AlmRepoItem({ | |||
return ( | |||
<StyledCard | |||
key={almKey} | |||
role="row" | |||
className={classNames('sw-flex sw-mb-2 sw-px-4', { | |||
'sw-py-4': sqProjectKey, | |||
'sw-py-2': !sqProjectKey, | |||
'sw-py-4': sqProjectKey !== undefined, | |||
'sw-py-2': sqProjectKey === undefined, | |||
})} | |||
> | |||
<div className="sw-w-[70%] sw-flex sw-mr-1"> | |||
@@ -87,7 +88,7 @@ export default function AlmRepoItem({ | |||
</div> | |||
</div> | |||
<div className="sw-flex sw-justify-between sw-items-center sw-flex-1"> | |||
{almUrl && ( | |||
{almUrl !== undefined && ( | |||
<div className="sw-flex sw-items-center"> | |||
<Link | |||
className="sw-body-sm-highlight" |
@@ -17,6 +17,8 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { DarkLabel } from 'design-system'; | |||
import * as React from 'react'; | |||
import AlmSettingsInstanceSelector from '../../../../components/devops-platform/AlmSettingsInstanceSelector'; | |||
import { hasMessage, translate, translateWithParameters } from '../../../../helpers/l10n'; | |||
@@ -42,15 +44,15 @@ export default function AlmSettingsInstanceDropdown(props: AlmSettingsInstanceDr | |||
: `alm.${almKey}`; | |||
return ( | |||
<div className="display-flex-column huge-spacer-bottom"> | |||
<label htmlFor="alm-config-selector" className="spacer-bottom"> | |||
<div className="sw-flex sw-flex-col"> | |||
<DarkLabel htmlFor="alm-config-selector" className="sw-mb-2"> | |||
{translateWithParameters('alm.configuration.selector.label', translate(almKeyTranslation))} | |||
</label> | |||
</DarkLabel> | |||
<AlmSettingsInstanceSelector | |||
instances={almInstances} | |||
onChange={props.onChangeConfig} | |||
initialValue={selectedAlmInstance ? selectedAlmInstance.key : undefined} | |||
classNames="abs-width-400" | |||
className="sw-w-abs-400 sw-mb-9" | |||
inputId="alm-config-selector" | |||
/> | |||
</div> |
@@ -31,8 +31,8 @@ import { translate } from '../../../../helpers/l10n'; | |||
import { getGlobalSettingsUrl } from '../../../../helpers/urls'; | |||
import { | |||
AlmSettingsInstance, | |||
ProjectAlmBindingConfigurationErrors, | |||
ProjectAlmBindingConfigurationErrorScope, | |||
ProjectAlmBindingConfigurationErrors, | |||
ProjectAlmBindingResponse, | |||
} from '../../../../types/alm-settings'; | |||
import { ALM_INTEGRATION_CATEGORY } from '../../constants'; | |||
@@ -135,7 +135,7 @@ export default function PRDecorationBindingRenderer(props: PRDecorationBindingRe | |||
instances={instances} | |||
onChange={(instance: AlmSettingsInstance) => props.onFieldChange('key', instance.key)} | |||
initialValue={formData.key} | |||
classNames="abs-width-400 big-spacer-top it__configuration-name-select" | |||
className="sw-w-abs-400 sw-mt-4 it__configuration-name-select" | |||
inputId="name" | |||
/> | |||
</div> |
@@ -17,18 +17,23 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { InputSelect, LabelValueSelectOption } from 'design-system'; | |||
import * as React from 'react'; | |||
import { components, OptionProps, SingleValueProps } from 'react-select'; | |||
import { OptionProps, SingleValueProps, components } from 'react-select'; | |||
import { translate } from '../../helpers/l10n'; | |||
import { AlmSettingsInstance } from '../../types/alm-settings'; | |||
import Select from '../controls/Select'; | |||
function optionRenderer(props: OptionProps<AlmSettingsInstance, false>) { | |||
return <components.Option {...props}>{customOptions(props.data)}</components.Option>; | |||
function optionRenderer(props: OptionProps<LabelValueSelectOption<AlmSettingsInstance>, false>) { | |||
return <components.Option {...props}>{customOptions(props.data.value)}</components.Option>; | |||
} | |||
function singleValueRenderer(props: SingleValueProps<AlmSettingsInstance, false>) { | |||
return <components.SingleValue {...props}>{customOptions(props.data)}</components.SingleValue>; | |||
function singleValueRenderer( | |||
props: SingleValueProps<LabelValueSelectOption<AlmSettingsInstance>, false> | |||
) { | |||
return ( | |||
<components.SingleValue {...props}>{customOptions(props.data.value)}</components.SingleValue> | |||
); | |||
} | |||
function customOptions(instance: AlmSettingsInstance) { | |||
@@ -42,36 +47,39 @@ function customOptions(instance: AlmSettingsInstance) { | |||
); | |||
} | |||
function orgToOption(alm: AlmSettingsInstance) { | |||
return { value: alm, label: alm.key }; | |||
} | |||
interface Props { | |||
instances: AlmSettingsInstance[]; | |||
initialValue?: string; | |||
onChange: (instance: AlmSettingsInstance) => void; | |||
classNames: string; | |||
className: string; | |||
inputId: string; | |||
} | |||
export default function AlmSettingsInstanceSelector(props: Props) { | |||
const { instances, initialValue, classNames, inputId } = props; | |||
const { instances, initialValue, className, inputId } = props; | |||
return ( | |||
<Select | |||
<InputSelect | |||
inputId={inputId} | |||
className={classNames} | |||
className={className} | |||
isClearable={false} | |||
isSearchable={false} | |||
options={instances} | |||
onChange={(inst) => { | |||
if (inst) { | |||
props.onChange(inst); | |||
} | |||
options={instances.map(orgToOption)} | |||
onChange={(data: LabelValueSelectOption<AlmSettingsInstance>) => { | |||
props.onChange(data.value); | |||
}} | |||
components={{ | |||
Option: optionRenderer, | |||
SingleValue: singleValueRenderer, | |||
}} | |||
placeholder={translate('alm.configuration.selector.placeholder')} | |||
getOptionValue={(opt) => opt.key} | |||
value={instances.find((inst) => inst.key === initialValue) ?? null} | |||
getOptionValue={(opt: LabelValueSelectOption<AlmSettingsInstance>) => opt.value.key} | |||
value={instances.map(orgToOption).find((opt) => opt.value.key === initialValue) ?? null} | |||
size="full" | |||
/> | |||
); | |||
} |
@@ -3965,10 +3965,10 @@ onboarding.create_project.bitbucketcloud.title=Bitbucket Cloud project onboardin | |||
onboarding.create_project.bitbucketcloud.no_projects=No projects could be fetched from Bitbucket. Contact your system administrator, or {link}. | |||
onboarding.create_project.bitbucketcloud.link=See on Bitbucket | |||
onboarding.create_project.github.title=GitHub project onboarding | |||
onboarding.create_project.github.subtitle=Import repositories from one of your GitHub organizations | |||
onboarding.create_project.github.choose_organization=Choose organization | |||
onboarding.create_project.github.warning.title=Could not connect to GitHub | |||
onboarding.create_project.github.warning.message=Please contact an administrator to configure GitHub integration. | |||
onboarding.create_project.github.warning.message_admin=Please make sure the GitHub instance is correctly configured in the {link} to create a new project from a repository. | |||
onboarding.create_project.github.warning.message=Could not connect to GitHub. Please contact an administrator to configure GitHub integration. | |||
onboarding.create_project.github.warning.message_admin=Could not connect to GitHub. Please make sure the GitHub instance is correctly configured in the {link} to create a new project from a repository. | |||
onboarding.create_project.github.warning.message_admin.link=DevOps Platform integration settings | |||
onboarding.create_project.github.no_orgs=We couldn't load any organizations with your key. Contact an administrator. | |||
onboarding.create_project.github.no_orgs_admin=We couldn't load any organizations. Make sure the GitHub App is installed in at least one organization and check the GitHub instance configuration in the {link}. |