| /* |
| * 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, useMemo } from 'react' |
| import { |
| Button, |
| Card, |
| Divider, |
| Elevation, |
| Intent, |
| TagInput |
| } from '@blueprintjs/core' |
| import { ProviderIcons, Providers } from '@/data/Providers' |
| import ConnectionTabs from '@/components/blueprints/ConnectionTabs' |
| import BoardsSelector from '@/components/blueprints/BoardsSelector' |
| import DataEntitiesSelector from '@/components/blueprints/DataEntitiesSelector' |
| import NoData from '@/components/NoData' |
| import GitlabProjectsSelector from '@/components/blueprints/GitlabProjectsSelector' |
| import GitHubProject from '@/models/GithubProject' |
| |
| const DataScopes = (props) => { |
| const { |
| activeStep, |
| activeConnectionTab, |
| blueprintConnections = [], |
| dataEntitiesList = [], |
| boardsList = [], |
| fetchGitlabProjects = () => [], |
| isFetchingGitlab = false, |
| gitlabProjects = [], |
| dataEntities = [], |
| projects = [], |
| boards = [], |
| validationErrors = [], |
| configuredConnection, |
| handleConnectionTabChange = () => {}, |
| setDataEntities = () => {}, |
| setProjects = () => {}, |
| setBoards = () => {}, |
| setBoardSearch = () => {}, |
| prevStep = () => {}, |
| fieldHasError = () => {}, |
| getFieldError = () => {}, |
| isSaving = false, |
| isRunning = false, |
| isFetching = false, |
| enableConnectionTabs = true, |
| elevation = Elevation.TWO, |
| cardStyle = {} |
| } = props |
| |
| const selectedBoards = useMemo( |
| () => boards[configuredConnection.id], |
| [boards, configuredConnection?.id] |
| ) |
| const selectedProjects = useMemo( |
| () => projects[configuredConnection.id], |
| [projects, configuredConnection?.id] |
| ) |
| |
| useEffect(() => { |
| console.log('>> OVER HERE!!!', selectedBoards) |
| }, [selectedBoards]) |
| |
| useEffect(() => { |
| console.log('>> OVER HERE FOR Projects!!!', selectedProjects) |
| }, [selectedProjects]) |
| |
| return ( |
| <div |
| className='workflow-step workflow-step-data-scope' |
| data-step={activeStep?.id} |
| > |
| {blueprintConnections.length > 0 && ( |
| <div style={{ display: 'flex' }}> |
| {enableConnectionTabs && ( |
| <div |
| className='connection-tab-selector' |
| style={{ minWidth: '200px' }} |
| > |
| <Card |
| className='workflow-card connection-tabs-card' |
| elevation={Elevation.TWO} |
| style={{ padding: '10px' }} |
| > |
| <ConnectionTabs |
| connections={blueprintConnections} |
| onChange={handleConnectionTabChange} |
| selectedTabId={activeConnectionTab} |
| errors={validationErrors} |
| /> |
| </Card> |
| </div> |
| )} |
| <div |
| className='connection-scope' |
| style={{ marginLeft: '10px', width: '100%' }} |
| > |
| <Card |
| className='workflow-card worfklow-panel-card' |
| elevation={elevation} |
| style={{ ...cardStyle }} |
| > |
| {configuredConnection && ( |
| <> |
| <h3> |
| <span style={{ float: 'left', marginRight: '8px' }}> |
| {ProviderIcons[configuredConnection.provider] ? ( |
| ProviderIcons[configuredConnection.provider](24, 24) |
| ) : ( |
| <></> |
| )} |
| </span>{' '} |
| {configuredConnection.title} |
| </h3> |
| <Divider className='section-divider' /> |
| |
| {[Providers.GITHUB].includes( |
| configuredConnection.provider |
| ) && ( |
| <> |
| <h4>Projects *</h4> |
| <p>Enter the project names you would like to sync.</p> |
| <TagInput |
| id='project-id' |
| disabled={isRunning} |
| placeholder='username/repo, username/another-repo' |
| values={ |
| projects[configuredConnection.id]?.map( |
| (p) => p.value |
| ) || [] |
| } |
| fill={true} |
| onChange={(values) => |
| setProjects((p) => ({ |
| ...p, |
| [configuredConnection.id]: [ |
| ...values.map( |
| (v, vIdx) => |
| new GitHubProject({ |
| id: v, |
| key: v, |
| title: v, |
| value: v, |
| type: 'string' |
| }) |
| ) |
| ] |
| })) |
| } |
| addOnPaste={true} |
| addOnBlur={true} |
| rightElement={ |
| <Button |
| disabled={isRunning} |
| icon='eraser' |
| minimal |
| onClick={() => |
| setProjects((p) => ({ |
| ...p, |
| [configuredConnection.id]: [] |
| })) |
| } |
| /> |
| } |
| onKeyDown={(e) => |
| e.key === 'Enter' && e.preventDefault() |
| } |
| tagProps={{ |
| intent: validationErrors.some((e) => |
| e.startsWith('Projects:') |
| ) |
| ? Intent.WARNING |
| : Intent.PRIMARY, |
| minimal: true |
| }} |
| className='input-project-id tagInput' |
| /> |
| </> |
| )} |
| |
| {[Providers.JIRA].includes(configuredConnection.provider) && ( |
| <> |
| <h4>Boards *</h4> |
| <p>Select the boards you would like to sync.</p> |
| <BoardsSelector |
| items={boardsList} |
| selectedItems={selectedBoards} |
| onQueryChange={setBoardSearch} |
| onItemSelect={setBoards} |
| onClear={setBoards} |
| onRemove={setBoards} |
| disabled={isSaving} |
| configuredConnection={configuredConnection} |
| isLoading={isFetching} |
| /> |
| </> |
| )} |
| |
| {[Providers.GITLAB].includes( |
| configuredConnection.provider |
| ) && ( |
| <> |
| <h4>Projects *</h4> |
| <p>Select the project you would like to sync.</p> |
| <GitlabProjectsSelector |
| onFetch={fetchGitlabProjects} |
| isFetching={isFetchingGitlab} |
| items={gitlabProjects} |
| selectedItems={selectedProjects} |
| onItemSelect={setProjects} |
| onClear={setProjects} |
| onRemove={setProjects} |
| disabled={isSaving} |
| configuredConnection={configuredConnection} |
| isLoading={isFetching} |
| /> |
| </> |
| )} |
| |
| <h4>Data Entities</h4> |
| <p> |
| Select the data entities you wish to collect for the |
| projects.{' '} |
| <a |
| href='https://devlake.apache.org/docs/DataModels/DevLakeDomainLayerSchema' |
| target='_blank' |
| rel='noreferrer' |
| > |
| Learn about data entities |
| </a> |
| </p> |
| <DataEntitiesSelector |
| items={dataEntitiesList} |
| selectedItems={dataEntities[configuredConnection.id] || []} |
| // restrictedItems={getRestrictedDataEntities()} |
| onItemSelect={setDataEntities} |
| onClear={setDataEntities} |
| fieldHasError={fieldHasError} |
| getFieldError={getFieldError} |
| onRemove={setDataEntities} |
| disabled={isSaving} |
| configuredConnection={configuredConnection} |
| isSaving={isSaving} |
| /> |
| </> |
| )} |
| </Card> |
| </div> |
| </div> |
| )} |
| {blueprintConnections.length === 0 && ( |
| <NoData |
| title='No Data Connections' |
| message='Please select at least one connection source.' |
| onClick={prevStep} |
| /> |
| )} |
| </div> |
| ) |
| } |
| |
| export default DataScopes |