diff --git a/gradle/changelog/ssh_checkout.yaml b/gradle/changelog/ssh_checkout.yaml new file mode 100644 index 0000000000..d2149a0f4f --- /dev/null +++ b/gradle/changelog/ssh_checkout.yaml @@ -0,0 +1,2 @@ +- type: added + description: Protocol priority order by user preferences diff --git a/scm-core/src/main/java/sonia/scm/api/v2/resources/ConfigurationAdapterBase.java b/scm-core/src/main/java/sonia/scm/api/v2/resources/ConfigurationAdapterBase.java index 4fb84d14d2..4c5646dd6c 100644 --- a/scm-core/src/main/java/sonia/scm/api/v2/resources/ConfigurationAdapterBase.java +++ b/scm-core/src/main/java/sonia/scm/api/v2/resources/ConfigurationAdapterBase.java @@ -34,6 +34,7 @@ import sonia.scm.config.ConfigurationPermissions; import sonia.scm.store.ConfigurationStore; import sonia.scm.store.ConfigurationStoreFactory; +import javax.annotation.Nullable; import javax.inject.Provider; import javax.validation.Valid; import javax.validation.constraints.NotNull; @@ -143,7 +144,10 @@ public abstract class ConfigurationAdapterBase ({ - className: "is-small", -}))` +const SmallButton = styled(Button)` height: inherit; `; @@ -43,79 +42,59 @@ type Props = { repository: Repository; }; -type State = { - selected?: Link; +type Protocol = Link & { + profile: string; }; -function selectHttpOrFirst(repository: Repository) { - const protocols = (repository._links["protocol"] as Link[]) || []; +function selectPreferredProtocolFirst(repository: Repository) { + const protocols = (repository._links["protocol"] as Protocol[]) || []; - for (const protocol of protocols) { - if (protocol.name === "http") { - return protocol; - } + if (protocols.length === 0) { + return undefined; } - if (protocols.length > 0) { - return protocols[0]; - } - return undefined; + protocols.sort((a, b) => Number(b.profile) - Number(a.profile)); + return protocols[0]; } -export default class ProtocolInformation extends React.Component { - constructor(props: Props) { - super(props); - this.state = { - selected: selectHttpOrFirst(props.repository), - }; +const ProtocolInformation: FC = ({ repository }) => { + const [selected, setSelected] = useState(selectPreferredProtocolFirst(repository)); + + const protocols = repository._links["protocol"] as Protocol[]; + if (!protocols || protocols.length === 0) { + return null; } - selectProtocol = (protocol: Link) => { - this.setState({ - selected: protocol, - }); - }; - - renderProtocolButton = (protocol: Link) => { - const name = protocol.name || "unknown"; - - let color; - - const { selected } = this.state; - if (selected && protocol.name === selected.name) { - color = "link is-selected"; - } - - return ( - this.selectProtocol(protocol)}> - {name.toUpperCase()} - - ); - }; - - render() { - const { repository } = this.props; - - const protocols = repository._links["protocol"] as Link[]; - if (!protocols || protocols.length === 0) { - return null; - } - - if (protocols.length === 1) { - return ; - } - - const { selected } = this.state; - let cloneInformation = null; - if (selected) { - cloneInformation = ; - } - - return ( -
- {protocols.map(this.renderProtocolButton)} - {cloneInformation} -
- ); + if (protocols.length === 1) { + return ; } -} + + let cloneInformation = null; + if (selected) { + cloneInformation = ; + } + + return ( +
+ + {protocols.map((protocol, index) => { + return ( +
+ setSelected(protocol)} + > + {(protocol.name || "unknown").toUpperCase()} + +
+ ); + })} +
+ {cloneInformation} +
+ ); +}; + +export default ProtocolInformation; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java index 4eb3329fd6..b277083b39 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java @@ -215,6 +215,6 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper