You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by li...@apache.org on 2023/03/28 03:11:31 UTC
[incubator-devlake] branch main updated: feat(config-ui): support teambition connection config (#4777)
This is an automated email from the ASF dual-hosted git repository.
likyh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 0b86170b5 feat(config-ui): support teambition connection config (#4777)
0b86170b5 is described below
commit 0b86170b5d1ff15727a64e4fbb1b9cc23400e085
Author: coldgust <11...@users.noreply.github.com>
AuthorDate: Tue Mar 28 11:11:25 2023 +0800
feat(config-ui): support teambition connection config (#4777)
* feat(config-ui): support teambition connection config
* feat(config-ui): support teambition connection config
---
.../components/connection-form/fields/app-id.tsx | 83 ++++++++++++++++++++
.../components/connection-form/fields/index.tsx | 6 ++
.../connection-form/fields/secret-key.tsx | 83 ++++++++++++++++++++
.../components/connection-form/operate/test.tsx | 3 +-
config-ui/src/plugins/config.ts | 2 +
.../plugins/register/teambition/assets/icon.svg | 5 ++
.../src/plugins/register/teambition/config.tsx | 90 ++++++++++++++++++++++
.../register/teambition/connection-fields/index.ts | 20 +++++
.../teambition/connection-fields/styled.ts | 32 ++++++++
.../teambition/connection-fields/tenant-id.tsx | 77 ++++++++++++++++++
.../teambition/connection-fields/tenant-type.tsx | 77 ++++++++++++++++++
config-ui/src/plugins/register/teambition/index.ts | 19 +++++
12 files changed, 496 insertions(+), 1 deletion(-)
diff --git a/config-ui/src/plugins/components/connection-form/fields/app-id.tsx b/config-ui/src/plugins/components/connection-form/fields/app-id.tsx
new file mode 100644
index 000000000..5041e509b
--- /dev/null
+++ b/config-ui/src/plugins/components/connection-form/fields/app-id.tsx
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { useEffect } from 'react';
+import { FormGroup, InputGroup } from '@blueprintjs/core';
+
+import * as S from './styled';
+
+interface Props {
+ label?: string;
+ subLabel?: string;
+ placeholder?: string;
+ name: string;
+ initialValue: string;
+ value: string;
+ error: string;
+ setValue: (value: string) => void;
+ setError: (error: string) => void;
+}
+
+export const ConnectionAppId = ({
+ label,
+ subLabel,
+ placeholder,
+ initialValue,
+ value,
+ setValue,
+ setError,
+ }: Props) => {
+ useEffect(() => {
+ setValue(initialValue);
+ }, [initialValue]);
+
+ useEffect(() => {
+ setError(value ? '' : 'appid is required');
+ }, [value]);
+
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ setValue(e.target.value);
+ };
+
+ return (
+ <FormGroup
+ label={<S.Label>{label ?? 'AppId'}</S.Label>}
+ labelInfo={<S.LabelInfo>*</S.LabelInfo>}
+ subLabel={subLabel ? <S.LabelDescription>{subLabel}</S.LabelDescription> : null}
+ >
+ <InputGroup placeholder={placeholder ?? 'Your AppId'} value={value} onChange={handleChange} />
+ </FormGroup>
+ );
+};
diff --git a/config-ui/src/plugins/components/connection-form/fields/index.tsx b/config-ui/src/plugins/components/connection-form/fields/index.tsx
index 74027e33f..0b079d41e 100644
--- a/config-ui/src/plugins/components/connection-form/fields/index.tsx
+++ b/config-ui/src/plugins/components/connection-form/fields/index.tsx
@@ -25,6 +25,8 @@ import { ConnectionPassword } from './password';
import { ConnectionToken } from './token';
import { ConnectionProxy } from './proxy';
import { ConnectionRateLimit } from './rate-limit';
+import { ConnectionAppId } from "./app-id";
+import { ConnectionSecretKey } from "./secret-key";
interface Props {
name: string;
@@ -76,6 +78,10 @@ export const Form = ({ name, fields, initialValues, values, errors, setValues, s
return <ConnectionPassword key={key} {...getProps('password')} {...field} />;
case 'token':
return <ConnectionToken key={key} {...getProps('token')} {...field} />;
+ case 'appId':
+ return <ConnectionAppId key={key} {...getProps('appId')} {...field} />;
+ case 'secretKey':
+ return <ConnectionSecretKey key={key} {...getProps('secretKey')} {...field} />;
case 'proxy':
return <ConnectionProxy key={key} {...getProps('proxy')} {...field} />;
case 'rateLimitPerHour':
diff --git a/config-ui/src/plugins/components/connection-form/fields/secret-key.tsx b/config-ui/src/plugins/components/connection-form/fields/secret-key.tsx
new file mode 100644
index 000000000..88cc42ba6
--- /dev/null
+++ b/config-ui/src/plugins/components/connection-form/fields/secret-key.tsx
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { useEffect } from 'react';
+import { FormGroup, InputGroup } from '@blueprintjs/core';
+
+import * as S from './styled';
+
+interface Props {
+ label?: string;
+ subLabel?: string;
+ placeholder?: string;
+ name: string;
+ initialValue: string;
+ value: string;
+ error: string;
+ setValue: (value: string) => void;
+ setError: (value: string) => void;
+}
+
+export const ConnectionSecretKey = ({
+ label,
+ subLabel,
+ placeholder,
+ initialValue,
+ value,
+ setValue,
+ setError,
+}: Props) => {
+ useEffect(() => {
+ setValue(initialValue);
+ }, [initialValue]);
+
+ useEffect(() => {
+ setError(value ? '' : 'SecretKey is required');
+ }, [value]);
+
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ setValue(e.target.value);
+ };
+
+ return (
+ <FormGroup
+ label={<S.Label>{label ?? 'SecretKey'}</S.Label>}
+ labelInfo={<S.LabelInfo>*</S.LabelInfo>}
+ subLabel={subLabel ? <S.LabelDescription>{subLabel}</S.LabelDescription> : null}
+ >
+ <InputGroup type="password" placeholder={placeholder ?? 'Your SecretKey'} value={value} onChange={handleChange} />
+ </FormGroup>
+ );
+};
diff --git a/config-ui/src/plugins/components/connection-form/operate/test.tsx b/config-ui/src/plugins/components/connection-form/operate/test.tsx
index 3e49831e0..a8446e160 100644
--- a/config-ui/src/plugins/components/connection-form/operate/test.tsx
+++ b/config-ui/src/plugins/components/connection-form/operate/test.tsx
@@ -39,7 +39,8 @@ export const Test = ({ plugin, values, errors }: Props) => {
const handleSubmit = () => {
onSubmit(
- pick(values, ['endpoint', 'token', 'username', 'password', 'app_id', 'secret_key', 'proxy', 'authMethod']),
+ pick(values, ['endpoint', 'token', 'username', 'password', 'proxy', 'authMethod',
+ 'appId', 'secretKey', 'tenantId', 'tenantType']),
);
};
diff --git a/config-ui/src/plugins/config.ts b/config-ui/src/plugins/config.ts
index b4d836e05..ccb270c08 100644
--- a/config-ui/src/plugins/config.ts
+++ b/config-ui/src/plugins/config.ts
@@ -37,6 +37,7 @@ import { StarRocksConfig } from './register/starrocks';
import { TAPDConfig } from './register/tapd';
import { WebhookConfig } from './register/webook';
import { ZenTaoConfig } from './register/zentao';
+import { TeambitionConfig } from "./register/teambition";
export const PluginConfig: PluginConfigType[] = [
AEConfig,
@@ -57,6 +58,7 @@ export const PluginConfig: PluginConfigType[] = [
SonarQubeConfig,
StarRocksConfig,
TAPDConfig,
+ TeambitionConfig,
ZenTaoConfig,
WebhookConfig,
].sort((a, b) => a.sort - b.sort);
diff --git a/config-ui/src/plugins/register/teambition/assets/icon.svg b/config-ui/src/plugins/register/teambition/assets/icon.svg
new file mode 100644
index 000000000..93d227f72
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/assets/icon.svg
@@ -0,0 +1,5 @@
+<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M24.8601 7.75227C24.8606 6.58118 25.3105 5.45494 26.1169 4.60578C26.9234 3.75663 28.025 3.24932 29.1945 3.18845C26.7937 3.06965 24.1226 3 21.345 3C10.6606 3 2 3.98733 2 5.20407C2 6.42082 10.6606 7.40814 21.345 7.40814V12.3243H28.9487C28.7076 12.3059 28.4704 12.2535 28.244 12.1686C27.2724 11.9079 26.414 11.3336 25.8021 10.5351C25.1902 9.73651 24.8591 8.7583 24.8601 7.75227Z" fill="#BDCEFB"/>
+<path d="M21.345 7.40329C10.6606 7.40329 2 6.41596 2 5.19922V13.1757C2 14.0892 6.86288 14.8717 13.7987 15.2241V30.9066L21.4024 32.3609L21.345 7.40329Z" fill="#7497F7"/>
+<path d="M29.428 12.3237C31.953 12.3237 34 10.2768 34 7.7517C34 5.22665 31.953 3.17969 29.428 3.17969C26.9029 3.17969 24.856 5.22665 24.856 7.7517C24.856 10.2768 26.9029 12.3237 29.428 12.3237Z" fill="#7497F7"/>
+</svg>
diff --git a/config-ui/src/plugins/register/teambition/config.tsx b/config-ui/src/plugins/register/teambition/config.tsx
new file mode 100644
index 000000000..757f6c9a0
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/config.tsx
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 from 'react';
+
+import type { PluginConfigType } from '@/plugins';
+import { PluginType } from '@/plugins';
+
+import Icon from './assets/icon.svg';
+import { ConnectionTenantId, ConnectionTenantType } from "./connection-fields";
+
+export const TeambitionConfig: PluginConfigType = {
+ type: PluginType.Connection,
+ plugin: 'teambition',
+ name: 'Teambition',
+ isBeta: true,
+ icon: Icon,
+ sort: 100,
+ connection: {
+ docLink: 'https://devlake.apache.org/docs/Configuration/Teambition',
+ initialValues: {
+ endpoint: 'https://open.teambition.com/api/',
+ tenantType: 'organization'
+ },
+ fields: [
+ 'name',
+ {
+ key: 'endpoint',
+ subLabel: 'You do not need to enter the endpoint URL, because all versions use the same URL.',
+ disabled: true,
+ },
+ {
+ key: 'appId',
+ label: 'Application App Id',
+ subLabel: 'Your teambition application App Id.',
+ },
+ {
+ key: 'secretKey',
+ label: 'Application Secret Key',
+ subLabel: 'Your teambition application App Secret.',
+ },
+ ({ initialValues, values, errors, setValues, setErrors }: any) => (
+ <ConnectionTenantId
+ key="tenantId"
+ name="tenantId"
+ value={values.tenantId ?? ''}
+ error={errors.tenantId ?? ''}
+ setValue={(value) => setValues({ tenantId: value })}
+ setError={(value) => setErrors({ tenantId: value })}
+ initialValue={initialValues.tenantId} />
+ ),
+ ({ initialValues, values, errors, setValues, setErrors }: any) => (
+ <ConnectionTenantType
+ key="tenantType"
+ name="tenantType"
+ value={values.tenantType ?? ''}
+ error={errors.tenantType ?? ''}
+ setValue={(value) => setValues({ tenantType: value })}
+ setError={(value) => setErrors({ tenantType: value })}
+ initialValue={initialValues.tenantType} />
+ ),
+ 'proxy',
+ {
+ key: 'rateLimitPerHour',
+ subLabel:
+ 'By default, DevLake uses 3,000 requests/hour for data collection for TAPD. But you can adjust the collection speed by setting up your desirable rate limit.',
+ learnMore: 'https://devlake.apache.org/docs/Configuration/Tapd#fixed-rate-limit-optional',
+ externalInfo: 'The maximum rate limit of TAPD is 3,600 requests/hour.',
+ defaultValue: 3000,
+ },
+ ],
+ },
+ entities: ['TICKET'],
+ transformation: {},
+};
diff --git a/config-ui/src/plugins/register/teambition/connection-fields/index.ts b/config-ui/src/plugins/register/teambition/connection-fields/index.ts
new file mode 100644
index 000000000..b2481eb94
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/connection-fields/index.ts
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 * from './tenant-id';
+export * from './tenant-type';
diff --git a/config-ui/src/plugins/register/teambition/connection-fields/styled.ts b/config-ui/src/plugins/register/teambition/connection-fields/styled.ts
new file mode 100644
index 000000000..82ec96a20
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/connection-fields/styled.ts
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 styled from 'styled-components';
+
+export const Label = styled.label`
+ font-size: 16px;
+ font-weight: 600;
+`;
+
+export const LabelInfo = styled.i`
+ color: #ff8b8b;
+`;
+
+export const LabelDescription = styled.p`
+ margin: 0;
+`;
\ No newline at end of file
diff --git a/config-ui/src/plugins/register/teambition/connection-fields/tenant-id.tsx b/config-ui/src/plugins/register/teambition/connection-fields/tenant-id.tsx
new file mode 100644
index 000000000..cea5c8e35
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/connection-fields/tenant-id.tsx
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { useEffect } from 'react';
+import { FormGroup, InputGroup } from '@blueprintjs/core';
+
+import * as S from './styled';
+
+interface Props {
+ name: string;
+ initialValue: string;
+ value: string;
+ error: string;
+ setValue: (value: string) => void;
+ setError: (error: string) => void;
+}
+
+export const ConnectionTenantId = ({
+ initialValue,
+ value,
+ setValue,
+ setError,
+ }: Props) => {
+ useEffect(() => {
+ setValue(initialValue);
+ }, [initialValue]);
+
+ useEffect(() => {
+ setError(value ? '' : 'TenantId is required');
+ }, [value]);
+
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ setValue(e.target.value);
+ };
+
+ return (
+ <FormGroup
+ label={<S.Label>Tenant Id</S.Label>}
+ labelInfo={<S.LabelInfo>*</S.LabelInfo>}
+ subLabel={<S.LabelDescription>Your teambition organization id.</S.LabelDescription>}
+ >
+ <InputGroup placeholder="Your TenantId" value={value} onChange={handleChange} />
+ </FormGroup>
+ );
+};
diff --git a/config-ui/src/plugins/register/teambition/connection-fields/tenant-type.tsx b/config-ui/src/plugins/register/teambition/connection-fields/tenant-type.tsx
new file mode 100644
index 000000000..c4ce96d8f
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/connection-fields/tenant-type.tsx
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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, { useEffect } from 'react';
+import { FormGroup, InputGroup } from '@blueprintjs/core';
+
+import * as S from './styled';
+
+interface Props {
+ name: string;
+ initialValue: string;
+ value: string;
+ error: string;
+ setValue: (value: string) => void;
+ setError: (error: string) => void;
+}
+
+export const ConnectionTenantType = ({
+ initialValue,
+ value,
+ setValue,
+ setError,
+ }: Props) => {
+ useEffect(() => {
+ setValue(initialValue);
+ }, [initialValue]);
+
+ useEffect(() => {
+ setError(value ? '' : 'TenantType is required');
+ }, [value]);
+
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ setValue(e.target.value);
+ };
+
+ return (
+ <FormGroup
+ label={<S.Label>Tenant Type</S.Label>}
+ labelInfo={<S.LabelInfo>*</S.LabelInfo>}
+ subLabel={<S.LabelDescription>You do not need to enter the tenant type, because teambition only supports 'organization' type currently.</S.LabelDescription>}
+ >
+ <InputGroup disabled={true} placeholder="Your API Tenant Type" value={value} onChange={handleChange} />
+ </FormGroup>
+ );
+};
diff --git a/config-ui/src/plugins/register/teambition/index.ts b/config-ui/src/plugins/register/teambition/index.ts
new file mode 100644
index 000000000..de415db39
--- /dev/null
+++ b/config-ui/src/plugins/register/teambition/index.ts
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 * from './config';