lhart-intelycare commented on issue #4838: URL: https://github.com/apache/incubator-devlake/issues/4838#issuecomment-2176824136
I've started coding away on my end. Wanted to get some advice on which way to go... The big difference ID'd so far between sonarcloud and sonarqube is that: 1. Sonarcloud always has the same REST endpoint: https://sonarcloud.io/api/ 2. Sonarcloud APIs often needs an "organization" passed in when looking for things like projects: https://sonarcloud.io/api/projects/search?deprecated=false&organization=intelycare&ps=100&p=1 Given that, it seemed like I should probably start with enhancing: 1. config-ui's sonarqube pluginconfig to have a multiconfig concept, similar to the jira plugin and then add an optional concept of "organization" when multiconfig is selected: https://github.com/apache/incubator-devlake/blob/0e7bf408afcb707a419c843a4a9839b054b1c7d4/config-ui/src/plugins/register/sonarqube/config.tsx: ``` export const SonarQubeConfig: IPluginConfig = { plugin: 'sonarqube', name: 'SonarQube', icon: ({ color }) => <Icon fill={color} />, sort: 11, connection: { docLink: DOC_URL.PLUGIN.SONARQUBE.BASIS, fields: [ 'name', { key: 'endpoint', subLabel: 'Provide the SonarQube instance API endpoint. E.g. http://<host>:<port>/api/', multipleVersions: { cloud: 'http://sonarcloud.io/', server: ' ' }, organizationRequired: true, }, 'organization', 'token', 'proxy', { key: 'rateLimitPerHour', subLabel: 'By default, DevLake uses 10,000 requests/hour for data collection for SonarQube. But you can adjust the collection speed by setting up your desirable rate limit.', learnMore: DOC_URL.PLUGIN.SONARQUBE.RATE_LIMIT, externalInfo: 'SonarQube does not specify a maximum value of rate limit.', defaultValue: 10000, }, ], }, dataScope: { title: 'Repositories', }, }; ``` 2. The endpoint connection config component, allowing a user to select cloud vs server and then if cloud, specify an organization : https://github.com/apache/incubator-devlake/blob/f27c31f3954bb4d5df8c6a4e829acfdedf36174a/config-ui/src/plugins/components/connection-form/fields/endpoint.tsx ``` import { useState, useEffect } from 'react'; import type { RadioChangeEvent } from 'antd'; import { Radio, Input } from 'antd'; import { Block } from '@/components'; type VersionType = 'cloud' | 'server'; interface Props { subLabel?: string; disabled?: boolean; name: string; multipleVersions?: Record<VersionType, string>; organizationRequired?: boolean; initialValue: string; value: string; error: string; setValue: (value: string) => void; setError: (error: string) => void; } export const ConnectionEndpoint = ({ subLabel, disabled = false, name, multipleVersions, organizationRequired, initialValue, value, setValue, setError, }: Props) => { const [version, setVersion] = useState<VersionType>('cloud'); useEffect(() => { setValue(initialValue); setVersion(initialValue === multipleVersions?.cloud ? 'cloud' : 'server'); }, [initialValue]); useEffect(() => { setError(value ? '' : 'endpoint is required'); }, [value]); const handleChange = (e: RadioChangeEvent) => { const version = e.target.value; if (version === 'cloud') { setValue(multipleVersions?.cloud ?? ''); } if (version === 'server') { setValue(''); } setVersion(version); }; const handleChangeValue = (e: React.ChangeEvent<HTMLInputElement>) => { setValue(e.target.value); }; if (multipleVersions) { return ( <> <Block title={name} required> <Radio.Group value={version} onChange={handleChange}> <Radio value="cloud">{name} Cloud</Radio> <Radio value="server" disabled={!multipleVersions.server}> {name} Server {multipleVersions.server ? multipleVersions.server : '(to be supported)'} </Radio> </Radio.Group> </Block> {version === 'cloud' && ( <Block> <p> If you are using {name} Cloud, you do not need to enter the endpoint URL, which is{' '} {multipleVersions.cloud}. </p> </Block> )} {organizationRequired && ( <Block> <p> Place some input here for "organization" </p> </Block> )} {version === 'server' && ( <Block title="Endpoint URL" description={subLabel ?? `If you are using ${name} Server, please enter the endpoint URL.`} required > <Input style={{ width: 386 }} placeholder="Your Endpoint URL" value={value} onChange={handleChangeValue} /> </Block> )} </> ); } return ( <Block title="Endpoint URL" description={subLabel ?? `Provide the ${name} instance API endpoint.`} required> <Input style={{ width: 386 }} disabled={disabled} placeholder="Your Endpoint URL" value={value} onChange={handleChangeValue} /> </Block> ); }; ``` DevLake devs (@Startrekzky?): does this sound directionally correct from a front-end perspective? Alternatively, I could create an entirely new field concept here, but it feels like org is tightly coupled to endpoint vs being its own entity: https://github.com/apache/incubator-devlake/blob/ac540080b73f313eb58b6a9659a392e1022beced/config-ui/src/plugins/components/connection-form/fields Thanks! -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@devlake.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org