diff --git a/config-ui/src/api/connection/index.ts b/config-ui/src/api/connection/index.ts index a546c98558b..e376036c009 100644 --- a/config-ui/src/api/connection/index.ts +++ b/config-ui/src/api/connection/index.ts @@ -42,7 +42,16 @@ export const test = ( payload?: Partial< Pick< IConnectionAPI, - 'endpoint' | 'authMethod' | 'username' | 'password' | 'token' | 'appId' | 'secretKey' | 'proxy' | 'dbUrl' + | 'endpoint' + | 'authMethod' + | 'username' + | 'password' + | 'token' + | 'appId' + | 'secretKey' + | 'proxy' + | 'dbUrl' + | 'companyId' > >, ): Promise => diff --git a/config-ui/src/plugins/components/connection-form/fields/token.tsx b/config-ui/src/plugins/components/connection-form/fields/token.tsx index 1788ed3953d..344a100baa4 100644 --- a/config-ui/src/plugins/components/connection-form/fields/token.tsx +++ b/config-ui/src/plugins/components/connection-form/fields/token.tsx @@ -15,23 +15,6 @@ * 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 { useEffect } from 'react'; import { Input } from 'antd'; diff --git a/config-ui/src/plugins/components/connection-form/index.tsx b/config-ui/src/plugins/components/connection-form/index.tsx index 4f6582e055e..af285259989 100644 --- a/config-ui/src/plugins/components/connection-form/index.tsx +++ b/config-ui/src/plugins/components/connection-form/index.tsx @@ -72,6 +72,7 @@ export const ConnectionForm = ({ plugin, connectionId, onSuccess }: Props) => { secretKey: isEqual(connection?.secretKey, values.secretKey) ? undefined : values.secretKey, proxy: isEqual(connection?.proxy, values.proxy) ? undefined : values.proxy, dbUrl: isEqual(connection?.dbUrl, values.dbUrl) ? undefined : values.dbUrl, + companyId: isEqual(connection?.companyId, values.companyId) ? undefined : values.companyId, }) : API.connection.testOld( plugin, @@ -87,6 +88,7 @@ export const ConnectionForm = ({ plugin, connectionId, onSuccess }: Props) => { 'tenantId', 'tenantType', 'dbUrl', + 'companyId', ]), ), { diff --git a/config-ui/src/plugins/register/github/config.tsx b/config-ui/src/plugins/register/github/config.tsx index 295d9d1ad1b..1679cdfaea0 100644 --- a/config-ui/src/plugins/register/github/config.tsx +++ b/config-ui/src/plugins/register/github/config.tsx @@ -100,6 +100,7 @@ export const GitHubConfig: IPluginConfig = { ], }, dataScope: { + localSearch: true, title: 'Repositories', millerColumn: { columnCount: 2, diff --git a/config-ui/src/plugins/register/tapd/config.tsx b/config-ui/src/plugins/register/tapd/config.tsx index d0124db1766..cdce22db3d1 100644 --- a/config-ui/src/plugins/register/tapd/config.tsx +++ b/config-ui/src/plugins/register/tapd/config.tsx @@ -20,7 +20,7 @@ import { ExternalLink } from '@/components'; import { DOC_URL } from '@/release'; import { IPluginConfig } from '@/types'; -import { DataScope } from './data-scope'; +import { CompanyId } from './connection-fields'; import Icon from './assets/icon.svg?react'; export const TAPDConfig: IPluginConfig = { @@ -56,6 +56,16 @@ export const TAPDConfig: IPluginConfig = { label: 'API Token', placeholder: 'Your API Token', }, + ({ initialValues, values, errors, setValues, setErrors }: any) => ( + setValues({ companyId: value })} + setError={(error) => setErrors({ companyId: error })} + /> + ), 'proxy', { key: 'rateLimitPerHour', @@ -68,7 +78,10 @@ export const TAPDConfig: IPluginConfig = { ], }, dataScope: { - render: ({ ...props }: any) => , + title: 'Workspaces', + millerColumn: { + columnCount: 2.5, + }, }, scopeConfig: { entities: ['TICKET', 'CROSS'], diff --git a/config-ui/src/plugins/register/tapd/connection-fields/company-id.tsx b/config-ui/src/plugins/register/tapd/connection-fields/company-id.tsx new file mode 100644 index 00000000000..afb8f8b5da9 --- /dev/null +++ b/config-ui/src/plugins/register/tapd/connection-fields/company-id.tsx @@ -0,0 +1,62 @@ +/* + * 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 { ChangeEvent, useEffect } from 'react'; +import { Input } from 'antd'; + +import { Block } from '@/components'; + +interface Props { + initialValue: number; + value: number; + error: string; + setValue: (value: number) => void; + setError: (value: string) => void; +} + +export const CompanyId = ({ initialValue, value, setValue, setError }: Props) => { + useEffect(() => { + setValue(initialValue); + }, [initialValue]); + + useEffect(() => { + let error = ''; + + if (!value) { + error = 'company id is required'; + } else if (!/\d/.test(value.toString())) { + error = 'company id is a number'; + } + + setError(error); + }, [value]); + + const handleChange = (e: ChangeEvent) => { + const value = +e.target.value; + + if (typeof value === 'number' && !isNaN(value)) { + setValue(value); + } + }; + + return ( + + + + ); +}; diff --git a/config-ui/src/plugins/register/tapd/connection-fields/index.ts b/config-ui/src/plugins/register/tapd/connection-fields/index.ts new file mode 100644 index 00000000000..98afdfa28f7 --- /dev/null +++ b/config-ui/src/plugins/register/tapd/connection-fields/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 './company-id'; diff --git a/config-ui/src/plugins/register/tapd/data-scope.tsx b/config-ui/src/plugins/register/tapd/data-scope.tsx deleted file mode 100644 index 2aee59e152a..00000000000 --- a/config-ui/src/plugins/register/tapd/data-scope.tsx +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 { useEffect, useState } from 'react'; -import { Input, Button } from 'antd'; -import type { McsID, McsItem } from 'miller-columns-select'; -import MillerColumnsSelect from 'miller-columns-select'; - -import API from '@/api'; -import { ExternalLink, Loading } from '@/components'; -import * as T from '@/plugins/components/data-scope-remote/types'; -// import * as API from '@/plugins/components/data-scope-remote/api'; - -// import { prepareToken } from './api'; - -interface Props { - connectionId: ID; - disabledItems: T.ResItem[]; - selectedItems: T.ResItem[]; - onChangeSelectedItems: (items: T.ResItem[]) => void; -} - -export const DataScope = ({ connectionId, disabledItems, selectedItems, onChangeSelectedItems }: Props) => { - const [pageToken, setPageToken] = useState(undefined); - const [companyId, setCompanyId] = useState( - localStorage.getItem(`plugin/tapd/connections/${connectionId}/company_id`) || '', - ); - - const [miller, setMiller] = useState<{ - items: McsItem[]; - loadedIds: ID[]; - }>({ - items: [], - loadedIds: [], - }); - - useEffect(() => { - if (!pageToken) return; - getItems(null, pageToken); - }, [pageToken]); - - const getItems = async (groupId: ID | null, currentPageToken?: string) => { - const res = await API.scope.remote('tapd', connectionId, { - groupId, - pageToken: currentPageToken, - }); - - const newItems = (res.children ?? []).map((it) => ({ - ...it, - title: it.name, - })); - - setMiller((m) => ({ - ...m, - items: [...m.items, ...newItems], - loadedIds: [...m.loadedIds, groupId ? groupId : 'root'], - })); - }; - - const getPageToken = async (companyId: string | undefined) => { - if (!companyId) { - setPageToken(undefined); - return; - } - const res = await API.plugin.tapd.remoteScopePrepareToken(connectionId, { - companyId, - }); - setPageToken(res.pageToken); - }; - - return ( - <> -

Workspaces *

-

Type in the company ID to list all the workspaces you want to sync.

- - Learn about how to get your company ID - - -
- { - setCompanyId(e.target.value); - localStorage.setItem(`plugin/tapd/connections/${connectionId}/company_id`, e.target.value); - }} - /> - -
- - {pageToken && ( - it.type === 'group'} - getHasMore={(id) => !miller.loadedIds.includes(id ?? 'root')} - onExpand={(id: McsID) => getItems(id, pageToken)} - onScroll={(id: McsID | null) => getItems(id, pageToken)} - columnCount={2.5} - columnHeight={300} - renderLoading={() => } - disabledIds={(disabledItems ?? []).map((it) => it.id)} - selectedIds={selectedItems.map((it) => it.id)} - onSelectItemIds={(selectedIds: ID[]) => - onChangeSelectedItems(miller.items.filter((it) => selectedIds.includes(it.id))) - } - /> - )} - - ); -}; diff --git a/config-ui/src/plugins/register/tapd/index.ts b/config-ui/src/plugins/register/tapd/index.ts index 14fdb67cd87..5f16858cbe4 100644 --- a/config-ui/src/plugins/register/tapd/index.ts +++ b/config-ui/src/plugins/register/tapd/index.ts @@ -17,5 +17,4 @@ */ export * from './config'; -export * from './data-scope'; export * from './transformation'; diff --git a/config-ui/src/types/connection.ts b/config-ui/src/types/connection.ts index 806eb18d33f..b5b9573069e 100644 --- a/config-ui/src/types/connection.ts +++ b/config-ui/src/types/connection.ts @@ -28,6 +28,7 @@ export interface IConnectionAPI { secretKey?: string; dbUrl?: string; enableGraphql?: boolean; + companyId?: number; proxy: string; rateLimitPerHour?: number; } @@ -81,6 +82,7 @@ export interface IConnection { secretKey?: string; dbUrl?: string; enableGraphql?: boolean; + companyId?: number; proxy: string; rateLimitPerHour?: number; }