You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by e2...@apache.org on 2022/09/20 17:06:43 UTC
[incubator-devlake] branch main updated: feat: add deployment tag transformation setting (#3093)
This is an automated email from the ASF dual-hosted git repository.
e2corporation 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 4f748b7e feat: add deployment tag transformation setting (#3093)
4f748b7e is described below
commit 4f748b7e54c418686e23d6f9b0cf141d00439501
Author: Julien Chinapen <ju...@merico.dev>
AuthorDate: Tue Sep 20 13:06:38 2022 -0400
feat: add deployment tag transformation setting (#3093)
* feat: setup deployment tag transform property
* fix: update jenkins deploy tag transform
* fix: restore missing github transform settings
* fix: resolve missing github active transform
* fix: apply linting cleanups
* fix: use provider specific deploy tag hint
* fix: populate deploy tag by default
* fix: create active configuration key
* fix: restore jenkins transforms on modify scope
* fix: use change handler directly for deploy tag
* feat: add tooltip warning if deploy tag blank
* fix: resolve linter warnings
* fix: enable project selector for gitlab
* fix: add duplicate project obj validation check
* fix: add array check for all connections response
* fix: enable offline-mode when connections 404
* fix: remove spinner icon from go-back button
* fix: lift new connections state props to dsm hook
* fix: expand deployment to 3 separate properties
* fix: prevent next advance if connection offline
* fix: show no transforms message for tapd
* fix: resolve linter warnings with jira transforms
* fix: resolve lint warnings on integrations manager
* fix: deactivate staging and testing deploy tags
* fix: add handler for deployment option selection
* fix: resolve linter warnings
* chore: resolve linter warnings
* fix: disable trailing comma rule for prettier
* chore: resolve lint warnings
---
config-ui/.prettierrc.js | 2 +-
.../blueprints/BlueprintDataScopesDialog.jsx | 10 +-
.../src/components/blueprints/DataScopesGrid.jsx | 4 +-
.../blueprints/GitlabProjectsSelector.jsx | 3 +-
.../blueprints/ProviderTransformationSettings.jsx | 22 +-
.../blueprints/create-workflow/DataScopes.jsx | 3 +-
.../create-workflow/DataTransformations.jsx | 329 +++++++++------------
.../blueprints/transformations/CICD/Deployment.jsx | 251 ++++++++++++++++
.../{.prettierrc.js => src/data/DataScopes.js} | 13 +-
config-ui/src/hooks/useBlueprintValidation.jsx | 16 +-
config-ui/src/hooks/useConnectionManager.jsx | 19 +-
config-ui/src/hooks/useDataScopesManager.jsx | 133 +++++++--
config-ui/src/hooks/useNetworkOfflineMode.jsx | 2 +-
config-ui/src/models/Connection.js | 2 +
.../src/pages/blueprints/blueprint-settings.jsx | 12 +-
.../src/pages/blueprints/create-blueprint.jsx | 88 +++---
config-ui/src/pages/blueprints/index.jsx | 10 +-
.../pages/configure/connections/AddConnection.jsx | 2 +-
.../configure/connections/ConfigureConnection.jsx | 2 +-
.../src/pages/configure/integration/manage.jsx | 2 +-
config-ui/src/pages/configure/settings/github.jsx | 24 +-
config-ui/src/pages/configure/settings/gitlab.jsx | 50 ++--
config-ui/src/pages/configure/settings/jenkins.jsx | 54 +++-
config-ui/src/pages/configure/settings/jira.jsx | 10 +-
config-ui/src/pages/offline/index.jsx | 15 +-
config-ui/src/styles/offline.scss | 6 +-
26 files changed, 737 insertions(+), 347 deletions(-)
diff --git a/config-ui/.prettierrc.js b/config-ui/.prettierrc.js
index fb4c19b2..edcba14e 100644
--- a/config-ui/.prettierrc.js
+++ b/config-ui/.prettierrc.js
@@ -20,6 +20,6 @@ module.exports = {
printWidth: 140,
singleQuote: true,
jsxSingleQuote: true,
- trailingComma: 'es5',
+ trailingComma: 'none',
semi: false,
}
diff --git a/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx b/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx
index b27fcc79..59a11b0b 100644
--- a/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx
+++ b/config-ui/src/components/blueprints/BlueprintDataScopesDialog.jsx
@@ -66,6 +66,7 @@ const BlueprintDataScopesDialog = (props) => {
configuredConnection,
configuredProject,
configuredBoard,
+ configurationKey,
scopeConnection,
dataEntitiesList = [],
boardsList = [],
@@ -141,14 +142,6 @@ const BlueprintDataScopesDialog = (props) => {
}
} = props
- // useEffect(() => {
- // console.log('>>> MY BOARDS LIST!!!!', boardsList)
- // }, [boardsList])
-
- // useEffect(() => {
- // console.log('>>> MY SELECTED BOARDS!!!!', boards)
- // }, [boards])
-
return (
<>
<MultistepDialog
@@ -223,6 +216,7 @@ const BlueprintDataScopesDialog = (props) => {
configuredConnection={configuredConnection}
configuredProject={configuredProject}
configuredBoard={configuredBoard}
+ configurationKey={configurationKey}
addBoardTransformation={addBoardTransformation}
addProjectTransformation={addProjectTransformation}
isSaving={isSaving}
diff --git a/config-ui/src/components/blueprints/DataScopesGrid.jsx b/config-ui/src/components/blueprints/DataScopesGrid.jsx
index 52930371..4424624a 100644
--- a/config-ui/src/components/blueprints/DataScopesGrid.jsx
+++ b/config-ui/src/components/blueprints/DataScopesGrid.jsx
@@ -204,9 +204,9 @@ const DataScopesGrid = (props) => {
}}
>
<Button
- disabled={mode === BlueprintMode.NORMAL && [Providers.JENKINS, Providers.TAPD].includes(c.providerId)}
+ disabled={mode === BlueprintMode.NORMAL && [Providers.TAPD].includes(c.providerId)}
icon='annotation'
- intent={mode === BlueprintMode.NORMAL && c.providerId === Providers.JENKINS ? Intent.NONE : Intent.PRIMARY}
+ intent={mode === BlueprintMode.NORMAL && c.providerId === Providers.TAPD ? Intent.NONE : Intent.PRIMARY}
size={12}
small
minimal
diff --git a/config-ui/src/components/blueprints/GitlabProjectsSelector.jsx b/config-ui/src/components/blueprints/GitlabProjectsSelector.jsx
index d252335b..ab8d6e25 100644
--- a/config-ui/src/components/blueprints/GitlabProjectsSelector.jsx
+++ b/config-ui/src/components/blueprints/GitlabProjectsSelector.jsx
@@ -18,6 +18,7 @@
import React, { useEffect, useState } from 'react'
import { Checkbox, Intent, MenuItem, Position, Tooltip } from '@blueprintjs/core'
import { MultiSelect } from '@blueprintjs/select'
+import GitlabProject from '@/models/GitlabProject'
const GitlabProjectsSelector = (props) => {
const {
@@ -128,7 +129,7 @@ const GitlabProjectsSelector = (props) => {
...rT,
[configuredConnection.id]: [
...rT[configuredConnection.id],
- item,
+ new GitlabProject(item),
],
}
: { ...rT }
diff --git a/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx b/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx
index 1d4bfc09..c17e43e4 100644
--- a/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx
+++ b/config-ui/src/components/blueprints/ProviderTransformationSettings.jsx
@@ -15,15 +15,15 @@
* limitations under the License.
*
*/
-import React, { Fragment, useEffect, useState, useCallback } from 'react'
+import React, { useEffect } from 'react'
import {
Providers,
- ProviderTypes,
- ProviderIcons,
- ConnectionStatus,
- ConnectionStatusLabels,
+ // ProviderTypes,
+ // ProviderIcons,
+ // ConnectionStatus,
+ // ConnectionStatusLabels,
} from '@/data/Providers'
-import { DataEntities, DataEntityTypes } from '@/data/DataEntities'
+// import { DataEntities, DataEntityTypes } from '@/data/DataEntities'
import JiraSettings from '@/pages/configure/settings/jira'
import GitlabSettings from '@/pages/configure/settings/gitlab'
import JenkinsSettings from '@/pages/configure/settings/jenkins'
@@ -39,6 +39,7 @@ const ProviderTransformationSettings = (props) => {
configuredBoard,
transformations = {},
transformation = {},
+ entityIdKey,
newTransformation = {},
boards = {},
projects = {},
@@ -53,6 +54,10 @@ const ProviderTransformationSettings = (props) => {
isFetchingJIRA = false
} = props
+ useEffect(() => {
+ console.log('OVER HERE!!!', entityIdKey)
+ }, [entityIdKey])
+
return (
<div className='transformation-settings' data-provider={provider?.id}>
{provider?.id === Providers.GITHUB && (
@@ -62,6 +67,7 @@ const ProviderTransformationSettings = (props) => {
configuredProject={configuredProject}
projects={projects}
transformation={transformation}
+ entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
entities={entities[connection?.id]}
isSaving={isSaving}
@@ -76,6 +82,7 @@ const ProviderTransformationSettings = (props) => {
configuredProject={configuredProject}
projects={projects}
transformation={transformation}
+ entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
entities={entities[connection?.id]}
isSaving={isSaving}
@@ -93,6 +100,7 @@ const ProviderTransformationSettings = (props) => {
issueTypes={issueTypes}
fields={fields}
transformation={transformation}
+ entityIdKey={entityIdKey}
transformations={transformations}
onSettingsChange={onSettingsChange}
entities={entities[connection?.id]}
@@ -108,6 +116,7 @@ const ProviderTransformationSettings = (props) => {
provider={provider}
connection={connection}
transformation={transformation}
+ entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
entities={entities[connection?.id]}
isSaving={isSaving}
@@ -119,6 +128,7 @@ const ProviderTransformationSettings = (props) => {
provider={provider}
connection={connection}
transformation={transformation}
+ entityIdKey={entityIdKey}
onSettingsChange={onSettingsChange}
entities={entities[connection?.id]}
isSaving={isSaving}
diff --git a/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx b/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
index a550bc79..c2b65f4e 100644
--- a/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
+++ b/config-ui/src/components/blueprints/create-workflow/DataScopes.jsx
@@ -23,6 +23,7 @@ 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 {
@@ -128,7 +129,7 @@ const DataScopes = (props) => {
onChange={(values) =>
setProjects((p) => ({
...p,
- [configuredConnection.id]: [...values.map((v, vIdx) => ({
+ [configuredConnection.id]: [...values.map((v, vIdx) => new GitHubProject({
id: v,
key: v,
title: v,
diff --git a/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx b/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx
index ffb3b45d..ff3c9adf 100644
--- a/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx
+++ b/config-ui/src/components/blueprints/create-workflow/DataTransformations.jsx
@@ -16,33 +16,12 @@
*
*/
import React, { Fragment, useEffect, useState, useCallback, useMemo } from 'react'
-import {
- Button,
- Icon,
- Intent,
- InputGroup,
- MenuItem,
- Divider,
- Elevation,
- Card,
- Colors,
- Spinner,
- Tooltip,
- Position
-} from '@blueprintjs/core'
+import { Button, Icon, Intent, InputGroup, MenuItem, Divider, Elevation, Card, Colors, Spinner, Tooltip, Position } from '@blueprintjs/core'
import { Select } from '@blueprintjs/select'
import { integrationsData } from '@/data/integrations'
-import {
- Providers,
- ProviderTypes,
- ProviderIcons,
- ConnectionStatus,
- ConnectionStatusLabels,
-} from '@/data/Providers'
+import { Providers, ProviderTypes, ProviderIcons, ConnectionStatus, ConnectionStatusLabels } from '@/data/Providers'
import { DataEntities, DataEntityTypes } from '@/data/DataEntities'
-import {
- DEFAULT_DATA_ENTITIES
-} from '@/data/BlueprintWorkflow'
+import { DEFAULT_DATA_ENTITIES } from '@/data/BlueprintWorkflow'
import ConnectionTabs from '@/components/blueprints/ConnectionTabs'
import NoData from '@/components/NoData'
@@ -66,6 +45,7 @@ const DataTransformations = (props) => {
configuredConnection,
configuredProject,
configuredBoard,
+ configurationKey,
handleConnectionTabChange = () => {},
prevStep = () => {},
addBoardTransformation = () => {},
@@ -88,30 +68,38 @@ const DataTransformations = (props) => {
useDropdownSelector = false,
enableGoBack = true,
elevation = Elevation.TWO,
- cardStyle = {}
+ cardStyle = {},
} = props
- const boardsAndProjects = useMemo(() => [
- ...(Array.isArray(boards[configuredConnection?.id]) ? boards[configuredConnection?.id] : []),
- ...(Array.isArray(projects[configuredConnection?.id]) ? projects[configuredConnection?.id] : [])], [
- projects,
- boards,
- configuredConnection?.id
- ])
+ // lifted to dsm hook
+ // const entityIdKey = useMemo(() => provider?.id === Providers.JENKINS ? `C#${configuredConnection?.id}` : (configuredProject?.id || configuredBoard?.id), [provider?.id, configuredConnection?.id, configuredProject?.id, configuredBoard?.id])
- const [entityList, setEntityList] = useState(boardsAndProjects?.map((e, eIdx) => ({
- id: eIdx,
- value: e?.value,
- title: e?.title,
- entity: e,
- type: typeof e === 'object' ? 'board' : 'project'
- })))
+ const boardsAndProjects = useMemo(
+ () => [
+ ...(Array.isArray(boards[configuredConnection?.id]) ? boards[configuredConnection?.id] : []),
+ ...(Array.isArray(projects[configuredConnection?.id]) ? projects[configuredConnection?.id] : []),
+ ],
+ [projects, boards, configuredConnection?.id]
+ )
+
+ const [entityList, setEntityList] = useState(
+ boardsAndProjects?.map((e, eIdx) => ({
+ id: eIdx,
+ value: e?.value,
+ title: e?.title,
+ entity: e,
+ type: e.variant,
+ }))
+ )
const [activeEntity, setActiveEntity] = useState()
- const transformationHasProperties = useCallback((item) => {
- const storedTransform = transformations[item] || transformations[item?.id]
- return storedTransform && Object.values(storedTransform).some(v => v && v.length > 0)
- }, [transformations])
+ const transformationHasProperties = useCallback(
+ (item) => {
+ const storedTransform = transformations[item?.id]
+ return storedTransform && Object.values(storedTransform).some((v) => v && v.length > 0)
+ },
+ [transformations]
+ )
useEffect(() => {
console.log('>>> PROJECT/BOARD SELECT LIST DATA...', entityList)
@@ -132,14 +120,15 @@ const DataTransformations = (props) => {
}
}, [activeEntity, addBoardTransformation, addProjectTransformation, useDropdownSelector])
+ useEffect(() => {
+ console.log('>>> DATA TRANSFORMATIONS: DSM $configurationKey', configurationKey)
+ }, [configurationKey])
+
return (
<div className='workflow-step workflow-step-add-transformation' data-step={activeStep?.id}>
{enableNoticeAlert && (
- <p
- className='alert neutral'
- >
- Set transformation rules for your selected data to view more complex
- metrics in the dashboards.
+ <p className='alert neutral'>
+ Set transformation rules for your selected data to view more complex metrics in the dashboards.
<br />
<a
href='#'
@@ -158,15 +147,8 @@ const DataTransformations = (props) => {
{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' }}
- >
+ <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}
@@ -175,112 +157,91 @@ const DataTransformations = (props) => {
</Card>
</div>
)}
- <div
- className='connection-transformation'
- style={{ marginLeft: '10px', width: '100%' }}
- >
- <Card
- className='workflow-card workflow-panel-card'
- elevation={elevation}
- style={{ ...cardStyle }}
- >
+ <div className='connection-transformation' style={{ marginLeft: '10px', width: '100%' }}>
+ <Card className='workflow-card workflow-panel-card' elevation={elevation} style={{ ...cardStyle }}>
{configuredConnection && (
<>
<h3>
<span style={{ float: 'left', marginRight: '8px' }}>
- {ProviderIcons[configuredConnection.provider]
- ? (
- ProviderIcons[configuredConnection.provider](24, 24)
- )
- : (
- <></>
- )}
+ {ProviderIcons[configuredConnection.provider] ? ProviderIcons[configuredConnection.provider](24, 24) : <></>}
</span>{' '}
{configuredConnection.title}
</h3>
<Divider className='section-divider' />
- {useDropdownSelector && entityList && [Providers.JIRA, Providers.GITHUB].includes(configuredConnection.provider) && (
- <div className='project-or-board-select' style={{ marginBottom: '20px' }}>
- <h4>{configuredConnection.provider === Providers.JIRA ? 'Board' : 'Project'}</h4>
- <Select
- disabled={configuredConnection.provider === Providers.JENKINS}
- popoverProps={{ usePortal: false }}
- className='selector-entity'
- id='selector-entity'
- inline={false}
- fill={true}
- items={entityList}
- activeItem={activeEntity}
- itemPredicate={(query, item) =>
- item?.title?.toString().toLowerCase().indexOf(query.toLowerCase()) >=
- 0}
- itemRenderer={(item, { handleClick, modifiers }) => (
- <MenuItem
- active={modifiers.active}
- key={item.value}
- // label={item.value}
- onClick={handleClick}
- text={item.title}
- />
- )}
- noResults={
- <MenuItem disabled={true} text='No projects or boards.' />
- }
- onItemSelect={(item) => {
- setActiveEntity(item)
- }}
- >
- <Button
+ {useDropdownSelector &&
+ entityList &&
+ [Providers.JIRA, Providers.GITHUB, Providers.GITLAB].includes(configuredConnection.provider) && (
+ <div className='project-or-board-select' style={{ marginBottom: '20px' }}>
+ <h4>{configuredConnection.provider === Providers.JIRA ? 'Board' : 'Project'}</h4>
+ <Select
disabled={configuredConnection.provider === Providers.JENKINS}
- className='btn-select-entity'
- intent={Intent.PRIMARY}
- outlined
- text={
- activeEntity
- ? `${activeEntity?.title || '- None Available -'}`
- : '< Select Project / Board >'
- }
- rightIcon='caret-down'
- fill
- style={{
- maxWidth: '100%',
- display: 'flex',
- justifyContent: 'space-between',
+ popoverProps={{ usePortal: false }}
+ className='selector-entity'
+ id='selector-entity'
+ inline={false}
+ fill={true}
+ items={entityList}
+ activeItem={activeEntity}
+ itemPredicate={(query, item) => item?.title?.toString().toLowerCase().indexOf(query.toLowerCase()) >= 0}
+ itemRenderer={(item, { handleClick, modifiers }) => (
+ <MenuItem
+ active={modifiers.active}
+ key={item.value}
+ // label={item.value}
+ onClick={handleClick}
+ text={item.title}
+ />
+ )}
+ noResults={<MenuItem disabled={true} text='No projects or boards.' />}
+ onItemSelect={(item) => {
+ setActiveEntity(item)
}}
- />
- </Select>
- </div>
- )}
+ >
+ <Button
+ disabled={configuredConnection.provider === Providers.JENKINS}
+ className='btn-select-entity'
+ intent={Intent.PRIMARY}
+ outlined
+ text={activeEntity ? `${activeEntity?.title || '- None Available -'}` : '< Select Project / Board >'}
+ rightIcon='caret-down'
+ fill
+ style={{
+ maxWidth: '100%',
+ display: 'flex',
+ justifyContent: 'space-between',
+ }}
+ />
+ </Select>
+ </div>
+ )}
- {[Providers.GITLAB, Providers.GITHUB].includes(
- configuredConnection.provider
- ) && !useDropdownSelector && (!configuredProject) && (
- <>
- <StandardStackedList
- items={projects}
- transformations={transformations}
- className='selected-items-list selected-projects-list'
- connection={configuredConnection}
- activeItem={configuredProject}
- onAdd={addProjectTransformation}
- onChange={addProjectTransformation}
- isEditing={transformationHasProperties}
- />
- {projects[configuredConnection.id].length === 0 && (
- <NoData
- title='No Projects Selected'
- icon='git-branch'
- message='Please select specify at least one project.'
- onClick={prevStep}
+ {[Providers.GITLAB, Providers.GITHUB].includes(configuredConnection.provider) &&
+ !useDropdownSelector &&
+ !configuredProject && (
+ <>
+ <StandardStackedList
+ items={projects}
+ transformations={transformations}
+ className='selected-items-list selected-projects-list'
+ connection={configuredConnection}
+ activeItem={configuredProject}
+ onAdd={addProjectTransformation}
+ onChange={addProjectTransformation}
+ isEditing={transformationHasProperties}
/>
- )}
- </>
- )}
+ {projects[configuredConnection.id].length === 0 && (
+ <NoData
+ title='No Projects Selected'
+ icon='git-branch'
+ message='Please select specify at least one project.'
+ onClick={prevStep}
+ />
+ )}
+ </>
+ )}
- {[Providers.JIRA].includes(
- configuredConnection.provider
- ) && !useDropdownSelector && (!configuredBoard) && (
+ {[Providers.JIRA].includes(configuredConnection.provider) && !useDropdownSelector && !configuredBoard && (
<>
<StandardStackedList
items={boards}
@@ -303,18 +264,24 @@ const DataTransformations = (props) => {
</>
)}
- {(configuredProject || configuredBoard) && (
+ {(configuredProject ||
+ configuredBoard ||
+ (configuredConnection?.provider === Providers.JENKINS && configuredConnection)) && (
<div>
- {!useDropdownSelector && (
+ {!useDropdownSelector && (configuredProject || configuredBoard) && (
<>
<h4>Project</h4>
<p style={{ color: '#292B3F' }}>{configuredProject?.title || configuredBoard?.title || '< select a project >'}</p>
</>
)}
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
- <h4 style={{ margin: 0 }}>
- Data Transformation Rules
- </h4>
+ <div
+ style={{
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ }}
+ >
+ <h4 style={{ margin: 0 }}>Data Transformation Rules</h4>
<div>
{/* @todo: reactivate clear all functionality */}
{/* <Button
@@ -331,17 +298,16 @@ const DataTransformations = (props) => {
</div>
{!dataEntities[configuredConnection.id] ||
- (dataEntities[configuredConnection.id]?.length ===
- 0 && <p>(No Data Entities Selected)</p>)}
- {dataEntities[configuredConnection.id]?.find(
- (e) => DEFAULT_DATA_ENTITIES.some(dE => dE.value === e.value)
- ) && (
+ (dataEntities[configuredConnection.id]?.length === 0 && <p>(No Data Entities Selected)</p>)}
+
+ {dataEntities[configuredConnection.id]?.find((e) => DEFAULT_DATA_ENTITIES.some((dE) => dE.value === e.value)) && (
<ProviderTransformationSettings
- provider={integrationsData.find(i => i.id === configuredConnection?.provider)}
+ provider={integrationsData.find((i) => i.id === configuredConnection?.provider)}
blueprint={blueprint}
connection={configuredConnection}
configuredProject={configuredProject}
configuredBoard={configuredBoard}
+ entityIdKey={configurationKey}
issueTypes={issueTypes}
fields={fields}
boards={boards}
@@ -350,7 +316,6 @@ const DataTransformations = (props) => {
transformation={activeTransformation}
transformations={transformations}
onSettingsChange={setTransformationSettings}
- entity={DataEntityTypes.TICKET}
isSaving={isSaving}
isFetchingJIRA={isFetchingJIRA}
isSavingConnection={isSavingConnection}
@@ -374,25 +339,18 @@ const DataTransformations = (props) => {
disabled={[Providers.GITLAB].includes(configuredConnection?.provider)}
style={{ marginLeft: '5px' }}
/> */}
- {enableGoBack && (
- <Button
- text='Go Back'
- intent={Intent.PRIMARY}
- small
- outlined
- onClick={() => onSave()}
- // disabled={[Providers.GITLAB].includes(configuredConnection?.provider)}
- style={{ marginLeft: '5px' }}
- icon={(
- <Tooltip
- position={Position.TOP}
- intent={Intent.PRIMARY}
- content='Close Editor to Continue'
- >
- <Spinner size={12} />
- </Tooltip>
- )}
- />
+ {enableGoBack && (configuredProject || configuredBoard) && (
+ <Tooltip position={Position.TOP} intent={Intent.PRIMARY} content='Close Editor to Continue'>
+ <Button
+ text='Go Back'
+ intent={Intent.PRIMARY}
+ small
+ outlined
+ onClick={() => onSave()}
+ // disabled={[Providers.GITLAB].includes(configuredConnection?.provider)}
+ style={{ marginLeft: '5px' }}
+ />
+ </Tooltip>
)}
</div>
</div>
@@ -400,7 +358,9 @@ const DataTransformations = (props) => {
</>
)}
- {[Providers.JENKINS].includes(configuredConnection.provider) && (
+ {([Providers.TAPD].includes(configuredConnection.provider) ||
+ ([Providers.GITLAB].includes(configuredConnection.provider) &&
+ dataEntities[configuredConnection.id].every((e) => e.value !== DataEntityTypes.DEVOPS))) && (
<>
<div className='bp3-non-ideal-state'>
<div className='bp3-non-ideal-state-visual'>
@@ -431,10 +391,7 @@ const DataTransformations = (props) => {
</h4>
<div>Please select at least one connection source.</div>
</div>
- <button
- className='bp3-button bp4-intent-primary'
- onClick={prevStep}
- >
+ <button className='bp3-button bp4-intent-primary' onClick={prevStep}>
Go Back
</button>
</div>
diff --git a/config-ui/src/components/blueprints/transformations/CICD/Deployment.jsx b/config-ui/src/components/blueprints/transformations/CICD/Deployment.jsx
new file mode 100644
index 00000000..74ea0f98
--- /dev/null
+++ b/config-ui/src/components/blueprints/transformations/CICD/Deployment.jsx
@@ -0,0 +1,251 @@
+/*
+ * 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, { useState, useEffect, useMemo, useCallback } from 'react'
+import {
+ Intent,
+ FormGroup,
+ RadioGroup,
+ InputGroup,
+ Radio,
+ Tag,
+ Icon,
+ Colors,
+ Tooltip
+} from '@blueprintjs/core'
+import { Providers, ProviderLabels } from '@/data/Providers'
+const Deployment = (props) => {
+ const {
+ connection,
+ provider,
+ transformation,
+ configuredProject,
+ configuredBoard,
+ entityIdKey,
+ entities = [],
+ isSaving = false,
+ onSettingsChange = () => {},
+ } = props
+
+ const [deployTag, setDeployTag] = useState(transformation?.productionPattern || '')
+ const [enableDeployTag, setEnableDeployTag] = useState([
+ transformation?.productionPattern,
+ // transformation?.stagingPattern,
+ // transformation?.testingPattern
+ ].some(t => t && t !== '') ? 1 : 0)
+
+ const clearDeploymentTags = useCallback((deploymentOption) => {
+ if (entityIdKey && deploymentOption === 0) {
+ onSettingsChange({ productionPattern: '' }, entityIdKey)
+ // onSettingsChange({ stagingPattern: '' }, entityIdKey)
+ // onSettingsChange({ testingPattern: '' }, entityIdKey)
+ }
+ }, [entityIdKey, onSettingsChange])
+
+ const handleDeploymentPreference = useCallback((deployOptionState) => {
+ setEnableDeployTag(deployOptionState)
+ switch (deployOptionState) {
+ case 0:
+ clearDeploymentTags(deployOptionState)
+ break
+ case 1:
+ break
+ }
+ }, [clearDeploymentTags])
+
+ // @todo: check w/ product team about using standard message and avoid customized hints
+ const getDeployTagHint = (providerId, providerName = 'Plugin') => {
+ let tagHint = ''
+ switch (providerId) {
+ case Providers.JENKINS:
+ // eslint-disable-next-line max-len
+ tagHint = `The ${providerName} build with a name that matches the given regEx is considered as a deployment. You can define your Deployments for three environments: Production, Staging and Testing.`
+ break
+ case Providers.GITHUB:
+ case Providers.GITLAB:
+ case 'default':
+ // eslint-disable-next-line max-len
+ tagHint = 'A CI job/build with a name that matches the given regEx is considered as an deployment. You can define your Deployments for three environments: Production, Staging and Testing.'
+ break
+ }
+ return tagHint
+ }
+
+ const getDeployOptionLabel = (providerId, providerName) => {
+ let label = ''
+ switch (providerId) {
+ case Providers.JENKINS:
+ // eslint-disable-next-line max-len
+ label = `Detect Deployment from Builds in ${providerName}`
+ break
+ case Providers.GITHUB:
+ label = `Detect Deployment from Jobs in ${providerName} Action`
+ break
+ case Providers.GITLAB:
+ case 'default':
+ // eslint-disable-next-line max-len
+ label = `Detect Deployment from Jobs in ${providerName} CI`
+ break
+ }
+ return label
+ }
+
+ useEffect(() => {
+ console.log('>>> CI/CD Deployment: TRANSFORMATION OBJECT!', transformation)
+ setEnableDeployTag(
+ [transformation?.productionPattern,
+ // transformation?.stagingPattern,
+ // transformation?.testingPattern
+ ].some(t => t && t !== '') ? 1 : 0
+ )
+ }, [transformation, transformation?.productionPattern])
+
+ return (
+ <>
+ <h5>CI/CD <Tag className='bp3-form-helper-text' minimal>RegExp</Tag></h5>
+ <p>Define deployment using one of the followng options</p>
+ <p style={{ color: '#292B3F' }}>
+ <strong>What is a deployment?</strong>{' '}
+ <Tag intent={Intent.PRIMARY} style={{ fontSize: '10px' }} minimal>
+ DORA
+ </Tag>
+ </p>
+
+ <RadioGroup
+ inline={false}
+ label={false}
+ name='deploy-tag'
+ onChange={(e) => handleDeploymentPreference(Number(e.target.value))}
+ selectedValue={enableDeployTag}
+ required
+ >
+ <Radio
+ label={getDeployOptionLabel(provider?.id, ProviderLabels[provider?.id?.toUpperCase()])}
+ value={1}
+ />
+ {enableDeployTag === 1 && (
+ <>
+ <div
+ className='bp3-form-helper-text'
+ style={{ display: 'block', textAlign: 'left', color: '#94959F', marginBottom: '5px' }}
+ >
+ {getDeployTagHint(provider?.id, ProviderLabels[provider?.id?.toUpperCase()])}
+ </div>
+ <div className='formContainer'>
+ <FormGroup
+ disabled={isSaving}
+ inline={true}
+ label={<label className='bp3-label' style={{ minWidth: '150px', marginRight: '10px' }}>Deployment (Production)</label>}
+ labelFor='deploy-tag-production'
+ className='formGroup'
+ contentClassName='formGroupContent'
+ >
+ <InputGroup
+ id='deploy-tag-production'
+ placeholder='(?i)deploy'
+ value={transformation?.productionPattern}
+ onChange={(e) => onSettingsChange({ productionPattern: e.target.value }, entityIdKey)}
+ disabled={isSaving}
+ className='input'
+ maxLength={255}
+ rightElement={
+ enableDeployTag && (transformation?.productionPattern === '' || !transformation?.productionPattern)
+ ? (
+ <Tooltip intent={Intent.PRIMARY} content='Deployment Tag RegEx required'>
+ <Icon icon='warning-sign' color={Colors.GRAY3} size={12} style={{ margin: '8px' }} />
+ </Tooltip>
+ )
+ : null
+ }
+ required
+ />
+ </FormGroup>
+ </div>
+ {/* <div className='formContainer'>
+ <FormGroup
+ disabled={isSaving}
+ inline={true}
+ label={<label className='bp3-label' style={{ minWidth: '150px', marginRight: '10px' }}>Deployment (Staging)</label>}
+ labelFor='deploy-tag-staging'
+ className='formGroup'
+ contentClassName='formGroupContent'
+ >
+ <InputGroup
+ id='deploy-tag-staging'
+ placeholder='(?i)stag'
+ value={transformation?.stagingPattern}
+ onChange={(e) => onSettingsChange({ stagingPattern: e.target.value }, entityIdKey)}
+ disabled={isSaving}
+ className='input'
+ maxLength={255}
+ rightElement={
+ enableDeployTag && (transformation?.stagingPattern === '' || !transformation?.stagingPattern)
+ ? (
+ <Tooltip intent={Intent.PRIMARY} content='Deployment Tag RegEx required'>
+ <Icon icon='warning-sign' color={Colors.GRAY3} size={12} style={{ margin: '8px' }} />
+ </Tooltip>
+ )
+ : null
+ }
+ required
+ />
+ </FormGroup>
+ </div>
+ <div className='formContainer'>
+ <FormGroup
+ disabled={isSaving}
+ inline={true}
+ label={<label className='bp3-label' style={{ minWidth: '150px', marginRight: '10px' }}>Deployment (Testing)</label>}
+ labelFor='deploy-tag-testing'
+ className='formGroup'
+ contentClassName='formGroupContent'
+ >
+ <InputGroup
+ id='deploy-tag-testing'
+ placeholder='(?i)test'
+ value={transformation?.testingPattern}
+ onChange={(e) => onSettingsChange({ testingPattern: e.target.value }, entityIdKey)}
+ disabled={isSaving}
+ className='input'
+ maxLength={255}
+ rightElement={
+ enableDeployTag && (transformation?.testingPattern === '' || !transformation?.testingPattern)
+ ? (
+ <Tooltip intent={Intent.PRIMARY} content='Deployment Tag RegEx required'>
+ <Icon icon='warning-sign' color={Colors.GRAY3} size={12} style={{ margin: '8px' }} />
+ </Tooltip>
+ )
+ : null
+ }
+ required
+ />
+ </FormGroup>
+ </div> */}
+ </>
+ )}
+ <Radio
+ label={`Not using ${
+ ProviderLabels[provider?.id.toUpperCase()]
+ } Builds as Deployments`}
+ value={0}
+ />
+ </RadioGroup>
+ </>
+ )
+}
+
+export default Deployment
diff --git a/config-ui/.prettierrc.js b/config-ui/src/data/DataScopes.js
similarity index 86%
copy from config-ui/.prettierrc.js
copy to config-ui/src/data/DataScopes.js
index fb4c19b2..0aa84b66 100644
--- a/config-ui/.prettierrc.js
+++ b/config-ui/src/data/DataScopes.js
@@ -16,10 +16,11 @@
*
*/
-module.exports = {
- printWidth: 140,
- singleQuote: true,
- jsxSingleQuote: true,
- trailingComma: 'es5',
- semi: false,
+const DataScopeModes = {
+ CREATE: 'create',
+ EDIT: 'edit'
+}
+
+export {
+ DataScopeModes
}
diff --git a/config-ui/src/hooks/useBlueprintValidation.jsx b/config-ui/src/hooks/useBlueprintValidation.jsx
index ef66ff6b..b15c5de9 100644
--- a/config-ui/src/hooks/useBlueprintValidation.jsx
+++ b/config-ui/src/hooks/useBlueprintValidation.jsx
@@ -93,6 +93,10 @@ function useBlueprintValidation ({
return set.length > 0
}, [])
+ const validateUniqueObjectSet = useCallback((set = []) => {
+ return [...new Set(set.map(o => JSON.stringify(o)))].length === set.length
+ }, [])
+
const validateBlueprintName = useCallback((name = '') => {
return name && name.length >= 2
}, [])
@@ -145,12 +149,21 @@ function useBlueprintValidation ({
if (activeProvider?.id === Providers.GITHUB && !validateRepositoryName(projects[activeConnection?.id])) {
errs.push('Projects: Only Git Repository Names are supported (username/repo).')
}
+ if (activeProvider?.id === Providers.GITHUB && !validateRepositoryName(projects[activeConnection?.id])) {
+ errs.push('Projects: Only Git Repository Names are supported (username/repo).')
+ }
+ if (activeProvider?.id === Providers.GITHUB && !validateUniqueObjectSet(projects[activeConnection?.id])) {
+ errs.push('Projects: Duplicate project detected.')
+ }
if (entities[activeConnection?.id]?.length === 0) {
errs.push('Data Entities: No Data Entities selected.')
}
if (activeProvider?.id === Providers.GITLAB && projects[activeConnection?.id]?.length === 0) {
errs.push('Projects: No Project IDs entered.')
}
+ if (activeProvider?.id === Providers.GITLAB && !validateUniqueObjectSet(projects[activeConnection?.id])) {
+ errs.push('Projects: Duplicate project detected.')
+ }
connections.forEach(c => {
if (c.provider === Providers.JIRA && boards[c?.id]?.length === 0) {
@@ -191,7 +204,8 @@ function useBlueprintValidation ({
activeConnection,
isValidCronExpression,
validateNumericSet,
- validateRepositoryName
+ validateRepositoryName,
+ validateUniqueObjectSet
])
const fieldHasError = useCallback((fieldId) => {
diff --git a/config-ui/src/hooks/useConnectionManager.jsx b/config-ui/src/hooks/useConnectionManager.jsx
index 210087f2..b00cdd57 100644
--- a/config-ui/src/hooks/useConnectionManager.jsx
+++ b/config-ui/src/hooks/useConnectionManager.jsx
@@ -334,14 +334,16 @@ function useConnectionManager (
),
])
const builtConnections = aC
- .map((providerResponse) => [].concat(providerResponse.data || []).map(c => new Connection({
- ...c,
- connectionId: c.id,
- plugin: providerResponse.config?.url?.split('/')[3],
- provider: providerResponse.config?.url?.split('/')[3],
- // @note: realtime connection status will be later injected by hook callees (non-blocking)
- status: ConnectionStatus.ONLINE
- })))
+ .map((providerResponse) => []
+ .concat(Array.isArray(providerResponse.data) ? providerResponse.data : [])
+ .map(c => new Connection({
+ ...c,
+ connectionId: c.id,
+ plugin: providerResponse.config?.url?.split('/')[3],
+ provider: providerResponse.config?.url?.split('/')[3],
+ // @note: realtime connection status will be later injected by hook callees (non-blocking)
+ status: ConnectionStatus.ONLINE
+ })))
setAllProviderConnections(builtConnections.flat())
console.log(
'>> ALL SOURCE CONNECTIONS: FETCHING ALL CONNECTION FROM ALL DATA SOURCES'
@@ -352,6 +354,7 @@ function useConnectionManager (
`${DEVLAKE_ENDPOINT}/plugins/${provider?.id}/connections`
)
console.log('>> RAW ALL CONNECTIONS DATA FROM API...', c?.data)
+ handleOfflineMode(c?.status, c)
const providerConnections = []
.concat(Array.isArray(c?.data) ? c?.data : [])
.map((conn, idx) =>
diff --git a/config-ui/src/hooks/useDataScopesManager.jsx b/config-ui/src/hooks/useDataScopesManager.jsx
index 41f71520..6faa907b 100644
--- a/config-ui/src/hooks/useDataScopesManager.jsx
+++ b/config-ui/src/hooks/useDataScopesManager.jsx
@@ -27,12 +27,16 @@ import JiraBoard from '@/models/JiraBoard'
import GitHubProject from '@/models/GithubProject'
import GitlabProject from '@/models/GitlabProject'
import { Providers, ProviderLabels, ProviderIcons } from '@/data/Providers'
+import { DataScopeModes } from '@/data/DataScopes'
-function useDataScopesManager ({ provider, blueprint, /* connection, */ settings = {}, setSettings = () => {} }) {
+function useDataScopesManager ({ mode = DataScopeModes.CREATE, provider, blueprint, /* connection, */ settings = {}, setSettings = () => {} }) {
const [connections, setConnections] = useState([])
+ const [newConnections, setNewConnections] = useState([])
const [scopeConnection, setScopeConnection] = useState()
- const connection = useMemo(() => scopeConnection, [scopeConnection])
+ const [configuredConnection, setConfiguredConnection] = useState()
+ const connection = useMemo(() => mode === DataScopeModes.EDIT ? scopeConnection : configuredConnection, [scopeConnection, configuredConnection, mode])
+ // const connection = useMemo(() => scopeConnection, [scopeConnection])
// const [blueprint, setBlueprint] = useState(NullBlueprint)
const [boards, setBoards] = useState({})
@@ -43,21 +47,42 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
const [configuredProject, setConfiguredProject] = useState(null)
const [configuredBoard, setConfiguredBoard] = useState(null)
+ const configurationKey = useMemo(() => {
+ let key = `C#${connection?.id}`
+ switch (connection?.providerId) {
+ case Providers.GITHUB:
+ case Providers.GITLAB:
+ key = configuredProject?.id
+ break
+ case Providers.JIRA:
+ key = configuredBoard?.id
+ break
+ case Providers.JENKINS:
+ case 'default':
+ key = `C#${connection?.id}`
+ break
+ }
+ console.log('>>> DSM: Active Configuration Key ===', key)
+ return key
+ }, [connection?.providerId, connection?.id, configuredProject?.id, configuredBoard?.id])
const activeProject = useMemo(() => configuredProject, [configuredProject])
const activeBoard = useMemo(() => configuredBoard, [configuredBoard])
- const selectedProjects = useMemo(() => projects[connection?.id] || [], [projects, connection?.id])
+ const selectedProjects = useMemo(() => projects[connection?.id]?.map(
+ (p) => p && p?.id
+ ), [projects, connection?.id])
const selectedBoards = useMemo(() => boards[connection?.id]?.map(
(b) => b && b?.id
), [boards, connection?.id])
- const storedProjectTransformation = useMemo(() => connection?.transformations[connection?.projects?.findIndex(p => p === configuredProject)], [connection, configuredProject])
- const storedBoardTransformation = useMemo(() => connection?.transformations[connection?.boardIds?.findIndex(b => b === configuredBoard?.id)], [connection, configuredBoard?.id])
+ const storedProjectTransformation = useMemo(() => connection?.transformations && connection?.transformations[connection?.projects?.findIndex(p => p === configuredProject?.id)], [connection, configuredProject?.id])
+ const storedBoardTransformation = useMemo(() => connection?.transformations && connection?.transformations[connection?.boardIds?.findIndex(b => b === configuredBoard?.id)], [connection, configuredBoard?.id])
- const activeProjectTransformation = useMemo(() => transformations[activeProject], [transformations, activeProject])
+ const activeProjectTransformation = useMemo(() => transformations[activeProject?.id], [transformations, activeProject?.id])
const activeBoardTransformation = useMemo(() => transformations[activeBoard?.id], [transformations, activeBoard?.id])
- const activeTransformation = useMemo(() => transformations[connection?.providerId === Providers.JIRA ? configuredBoard?.id : configuredProject], [transformations, configuredProject, configuredBoard?.id, connection?.providerId])
+ const activeTransformation = useMemo(() => transformations[configurationKey], [configurationKey, transformations])
+ // const activeTransformation = useMemo(() => transformations[connection?.providerId === Providers.JIRA ? configuredBoard?.id : configuredProject?.id], [transformations, configuredProject?.id, configuredBoard?.id, connection?.providerId])
const getDefaultTransformations = useCallback((providerId) => {
let transforms = {}
@@ -74,6 +99,9 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
issueTypeBug: '',
issueTypeIncident: '',
refdiff: null,
+ productionPattern: '',
+ // stagingPattern: '',
+ // testingPattern: ''
}
break
case Providers.JIRA:
@@ -85,16 +113,36 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
bugTags: [],
incidentTags: [],
requirementTags: [],
+ // @todo: verify if jira utilizes deploy tag(s)?
+ productionPattern: '',
+ // stagingPattern: '',
+ // testingPattern: ''
}
break
case Providers.JENKINS:
- // No Transform Settings...
+ transforms = {
+ productionPattern: '',
+ // stagingPattern: '',
+ // testingPattern: ''
+ }
break
case Providers.GITLAB:
- // No Transform Settings...
+ transforms = {
+ productionPattern: '',
+ // stagingPattern: '',
+ // testingPattern: ''
+ }
break
case Providers.TAPD:
- // No Transform Settings...
+ // @todo: complete tapd transforms #2673
+ transforms = {
+ issueTypeRequirement: '',
+ issueTypeBug: '',
+ issueTypeIncident: '',
+ productionPattern: '',
+ // stagingPattern: '',
+ // testingPattern: ''
+ }
break
}
console.log('>>>>> DATA SCOPES MANAGER: Getting Default Transformation Values for PROVIDER Type ', providerId, transforms)
@@ -104,7 +152,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
const initializeTransformations = useCallback((pV, cV, iDx) => ({
...pV,
[cV]: new TransformationSettings(getDefaultTransformations(connection?.providerId, iDx)),
- }), [connection, getDefaultTransformations])
+ }), [connection?.providerId, getDefaultTransformations])
// @todo: generate scopes dynamically from $integrationsData (in future Integrations Hook [plugin registry])
const createProviderScopes = useCallback(
@@ -147,7 +195,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
projectId: Number(p.value),
title: p.title
},
- transformation: {},
+ transformation: { ...transformations[p?.id] },
}))
break
case Providers.JENKINS:
@@ -155,7 +203,8 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
...newScope,
// options: {
// },
- // transformation: {},
+ // NOTE: Jenkins has no concept of projects/boards. Transformations Key'ed by Conn *INDEX* ID!
+ transformation: { ...transformations[`C#${connection?.id}`] },
}
break
case Providers.GITHUB:
@@ -165,7 +214,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
owner: p.value.split('/')[0],
repo: p.value.split('/')[1],
},
- transformation: { ...transformations[p] },
+ transformation: { ...transformations[p?.id] },
}))
break
case Providers.TAPD:
@@ -230,23 +279,25 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
configuredEntity,
settings
)
- setTransformations((existingTransformations) => ({
+ setTransformations((existingTransformations) => configuredEntity ? ({
...existingTransformations,
[configuredEntity]: new TransformationSettings({
...existingTransformations[configuredEntity],
...settings,
- }),
- }))
+ })
+ }) : existingTransformations)
},
[setTransformations]
)
const getGithubProjects = useCallback((c) => [Providers.GITHUB].includes(c.plugin)
? c.scope.map((s) => new GitHubProject({
- id: `${s.options.owner}/${s.options?.repo}`,
- key: `${s.options.owner}/${s.options?.repo}`,
- value: `${s.options.owner}/${s.options?.repo}`,
- title: `${s.options.owner}/${s.options?.repo}`,
+ id: `${s.options?.owner}/${s.options?.repo}`,
+ key: `${s.options?.owner}/${s.options?.repo}`,
+ owner: s.options?.owner,
+ repo: s.options?.repo,
+ value: `${s.options?.owner}/${s.options?.repo}`,
+ title: `${s.options?.owner}/${s.options?.repo}`,
}))
: [], [])
@@ -318,7 +369,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
switch (providerId) {
case Providers.GITHUB:
case Providers.GITLAB:
- entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name !== 'ci-cd')
+ entities = DEFAULT_DATA_ENTITIES
break
case Providers.JIRA:
entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'issue-tracking' || d.name === 'cross-domain')
@@ -366,7 +417,8 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
: '-'
),
scope: c.scope,
- editable: ![Providers.JENKINS].includes(c.plugin),
+ // editable: ![Providers.JENKINS].includes(c.plugin),
+ editable: true,
advancedEditable: false,
isMultiStage: false,
isSingleStage: true,
@@ -431,7 +483,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
case Providers.GITLAB:
setProjects(p => ({ ...p, [connection?.id]: connection?.projects || [] }))
setEntities(e => ({ ...e, [connection?.id]: connection?.entityList || [] }))
- connection?.projects.forEach((p, pIdx) => setTransformationSettings(connection.transformations[pIdx], p))
+ connection?.projects.forEach((p, pIdx) => setTransformationSettings(connection.transformations[pIdx], p?.id))
break
case Providers.JIRA:
// fetchBoards()
@@ -443,6 +495,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
break
case Providers.JENKINS:
setEntities(e => ({ ...e, [connection?.id]: connection?.entityList || [] }))
+ setTransformationSettings(connection.transformations[0], `C#${connection?.id}`)
break
}
}, [
@@ -479,7 +532,22 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
}, [provider])
useEffect(() => {
- console.log('>>>>> DATA SCOPES MANAGER: BOARDS...', boards)
+ console.log('>>>>> DATA SCOPES MANAGER: INITIALIZE NEW CONNECTION TRANSFORMATIONS...', newConnections)
+ // @note: jenkins has no "project/board" entity associated!
+ // transformations are based on the main connection scope...
+ const jenkinsTransformations = newConnections.filter(c => c.plugin === Providers.JENKINS).map(c => `C#${c?.id}`)
+ console.log('>>>>> DATA SCOPES MANAGER: JENKINS TRANSFORMATIONS SCOPES...', jenkinsTransformations)
+ if (Array.isArray(jenkinsTransformations)) {
+ setTransformations((cT) => ({
+ ...jenkinsTransformations.reduce(initializeTransformations, {}),
+ // Spread Current/Existing Transformations Settings
+ ...cT,
+ }))
+ }
+ }, [newConnections, initializeTransformations])
+
+ useEffect(() => {
+ console.log('>>>>> DATA SCOPES MANAGER: INITIALIZE BOARDS...', boards)
const boardTransformations = boards[connection?.id]
if (Array.isArray(boardTransformations) && boardTransformations?.length > 0) {
setTransformations((cT) => ({
@@ -491,7 +559,7 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
}, [boards, connection?.id, initializeTransformations])
useEffect(() => {
- console.log('>>>>> DATA SCOPES MANAGER: PROJECTS...', projects)
+ console.log('>>>>> DATA SCOPES MANAGER: INITIALIZE PROJECTS...', projects)
const projectTransformations = projects[connection?.id]
if (Array.isArray(projectTransformations)) {
setTransformations((cT) => ({
@@ -506,6 +574,10 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
console.log('>>>>> DATA SCOPES MANAGER: DATA ENTITIES...', entities)
}, [entities])
+ useEffect(() => {
+ console.log('>>>>> DATA SCOPES MANAGER: DATA ENTITIES...', entities)
+ }, [entities])
+
useEffect(() => {
console.log('>>>>> DATA SCOPES MANAGER: TRANSFORMATIONS...', transformations)
}, [transformations])
@@ -526,15 +598,22 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
console.log('>>>>> DATA SCOPES MANAGER: ACTIVE BOARD TRANSFORMATION RULES...', activeBoardTransformation)
}, [activeBoardTransformation])
+ useEffect(() => {
+ console.log('>>>>> DATA SCOPES MANAGER: MEMOIZED ACTIVE CONNECTION...', connection)
+ }, [connection])
+
return {
connections,
+ newConnections,
// blueprint,
boards,
projects,
entities,
transformations,
+ configuredConnection,
configuredBoard,
configuredProject,
+ configurationKey,
storedProjectTransformation,
storedBoardTransformation,
activeBoardTransformation,
@@ -543,8 +622,10 @@ function useDataScopesManager ({ provider, blueprint, /* connection, */ settings
scopeConnection,
enabledProviders,
// setActiveTransformation,
+ setNewConnections,
setConnections,
setScopeConnection,
+ setConfiguredConnection,
setConfiguredBoard,
setConfiguredProject,
// setBlueprint,
diff --git a/config-ui/src/hooks/useNetworkOfflineMode.jsx b/config-ui/src/hooks/useNetworkOfflineMode.jsx
index 3cc96cbb..10cf14d9 100644
--- a/config-ui/src/hooks/useNetworkOfflineMode.jsx
+++ b/config-ui/src/hooks/useNetworkOfflineMode.jsx
@@ -18,7 +18,7 @@
import { useCallback, useState, useEffect } from 'react'
import { useHistory } from 'react-router-dom'
-function useNetworkOfflineMode (offlineStatuses = [502, 504], offlineRoute = '/offline') {
+function useNetworkOfflineMode (offlineStatuses = [502, 504, 404], offlineRoute = '/offline') {
const history = useHistory()
const [status, setStatus] = useState()
const [response, setResponse] = useState()
diff --git a/config-ui/src/models/Connection.js b/config-ui/src/models/Connection.js
index 08e7a126..2d787d37 100644
--- a/config-ui/src/models/Connection.js
+++ b/config-ui/src/models/Connection.js
@@ -34,6 +34,7 @@
* @property {plain|token?} authentication
* @property {string|object?} plugin
* @property {string|object?} provider
+ * @property {string?} providerId
* @property {<Array<DataEntity>>} entities
* @property {boolean} multiConnection
* @property {number|string?} status
@@ -61,6 +62,7 @@ class Connection {
this.plugin = data?.plugin || null
// @todo: will be replaced out by $this.plugin
this.provider = data?.provider || null
+ this.providerId = data?.providerId || null
this.entities = data?.entities || []
this.multiConnection = data?.multiConnection || true
this.status = data?.status || null
diff --git a/config-ui/src/pages/blueprints/blueprint-settings.jsx b/config-ui/src/pages/blueprints/blueprint-settings.jsx
index b946e06f..646061f6 100644
--- a/config-ui/src/pages/blueprints/blueprint-settings.jsx
+++ b/config-ui/src/pages/blueprints/blueprint-settings.jsx
@@ -60,6 +60,7 @@ import CodeInspector from '@/components/pipelines/CodeInspector'
// import { DataEntities, DataEntityTypes } from '@/data/DataEntities'
import { DEFAULT_DATA_ENTITIES } from '@/data/BlueprintWorkflow'
+import { DataScopeModes } from '@/data/DataScopes'
import useBlueprintManager from '@/hooks/useBlueprintManager'
import useConnectionManager from '@/hooks/useConnectionManager'
@@ -96,7 +97,7 @@ const BlueprintSettings = (props) => {
// @disabled Provided By Data Scopes Manager
// const [connections, setConnections] = useState([])
const [blueprintConnections, setBlueprintConnections] = useState([])
- const [configuredConnection, setConfiguredConnection] = useState()
+ // const [configuredConnection, setConfiguredConnection] = useState()
// @todo: relocate or discard
const [newConnectionScopes, setNewConnectionScopes] = useState({})
@@ -165,9 +166,12 @@ const BlueprintSettings = (props) => {
activeBoardTransformation,
activeProjectTransformation,
activeTransformation,
+ configuredConnection,
configuredBoard,
configuredProject,
+ configurationKey,
enabledProviders,
+ setConfiguredConnection,
setConfiguredBoard,
setConfiguredProject,
setBoards,
@@ -186,6 +190,7 @@ const BlueprintSettings = (props) => {
getJiraMappedBoards,
getDefaultEntities
} = useDataScopesManager({
+ mode: DataScopeModes.EDIT,
blueprint: activeBlueprint,
provider: activeProvider,
// connection: scopeConnection,
@@ -445,7 +450,8 @@ const BlueprintSettings = (props) => {
// activeProvider,
connectionsList,
connections,
- setScopeConnection
+ setScopeConnection,
+ setConfiguredConnection
])
const validateActiveSetting = useCallback(() => {
@@ -518,6 +524,7 @@ const BlueprintSettings = (props) => {
activeBlueprint?.mode
])
+ // @note: lifted higher to dsm hook
// const getDefaultEntities = useCallback((providerId) => {
// let entities = []
// switch (providerId) {
@@ -1288,6 +1295,7 @@ const BlueprintSettings = (props) => {
configuredConnection={configuredConnection}
configuredProject={configuredProject}
configuredBoard={configuredBoard}
+ configurationKey={configurationKey}
scopeConnection={scopeConnection}
activeTransformation={activeTransformation}
addProjectTransformation={addProjectTransformation}
diff --git a/config-ui/src/pages/blueprints/create-blueprint.jsx b/config-ui/src/pages/blueprints/create-blueprint.jsx
index 8d14e57f..965e1b17 100644
--- a/config-ui/src/pages/blueprints/create-blueprint.jsx
+++ b/config-ui/src/pages/blueprints/create-blueprint.jsx
@@ -111,8 +111,9 @@ const CreateBlueprint = (props) => {
])
const [boardsList, setBoardsList] = useState([])
- const [blueprintConnections, setBlueprintConnections] = useState([])
- const [configuredConnection, setConfiguredConnection] = useState()
+ // @note: lifted to dsm hook
+ // const [blueprintConnections, setBlueprintConnections] = useState([])
+ // const [configuredConnection, setConfiguredConnection] = useState()
const [activeConnectionTab, setActiveConnectionTab] = useState()
@@ -173,20 +174,31 @@ const CreateBlueprint = (props) => {
} = useBlueprintManager()
const {
+ newConnections: blueprintConnections,
boards,
projects,
entities: dataEntities,
transformations,
+ activeTransformation,
+ setNewConnections: setBlueprintConnections,
+ setConfiguredConnection,
+ setConfiguredBoard,
+ setConfiguredProject,
setBoards,
setProjects,
setEntities: setDataEntities,
setTransformations,
setTransformationSettings,
+ configuredConnection,
+ configuredProject,
+ configuredBoard,
+ configurationKey,
createProviderScopes,
createProviderConnections,
getDefaultTransformations,
+ getDefaultEntities,
initializeTransformations
- } = useDataScopesManager({ connection: configuredConnection, settings: blueprintSettings })
+ } = useDataScopesManager({ settings: blueprintSettings })
const {
pipelineName,
@@ -358,16 +370,16 @@ const CreateBlueprint = (props) => {
password,
})
- const [configuredProject, setConfiguredProject] = useState(
- // projects.length > 0 ? projects[0] : null
- null
- )
- const [configuredBoard, setConfiguredBoard] = useState(
- // boards.length > 0 ? boards[0] : null
- null
- )
+ // const [configuredProject, setConfiguredProject] = useState(
+ // // projects.length > 0 ? projects[0] : null
+ // null
+ // )
+ // const [configuredBoard, setConfiguredBoard] = useState(
+ // // boards.length > 0 ? boards[0] : null
+ // null
+ // )
- const activeTransformation = useMemo(() => transformations[configuredProject?.id || configuredBoard?.id], [transformations, configuredProject?.id, configuredBoard?.id])
+ // const activeTransformation = useMemo(() => transformations[configuredProject?.id || configuredBoard?.id], [transformations, configuredProject?.id, configuredBoard?.id])
// eslint-disable-next-line no-unused-vars
const isValidStep = useCallback((stepId) => { }, [])
@@ -386,7 +398,7 @@ const CreateBlueprint = (props) => {
)
setConfiguredProject(null)
setConfiguredBoard(null)
- }, [blueprintSteps])
+ }, [blueprintSteps, setConfiguredBoard, setConfiguredProject])
const testSelectedConnections = useCallback((connections, savedConnection = {}, callback = () => {}) => {
const runTest = async () => {
@@ -431,7 +443,7 @@ const CreateBlueprint = (props) => {
)
setConfiguredConnection(selectedConnection)
},
- [blueprintConnections, setProvider]
+ [blueprintConnections, setProvider, setConfiguredConnection]
)
const handleConnectionDialogOpen = useCallback(() => {
@@ -484,7 +496,7 @@ const CreateBlueprint = (props) => {
}))
setConfiguredProject(null)
setConfiguredBoard(null)
- }, [setTransformations, configuredProject, configuredBoard])
+ }, [setTransformations, setConfiguredBoard, setConfiguredProject, configuredProject, configuredBoard])
const handleBlueprintSave = useCallback(() => {
console.log('>>> SAVING BLUEPRINT!!')
@@ -570,7 +582,7 @@ const CreateBlueprint = (props) => {
setConfiguredBoard(null)
ToastNotification.clear()
ToastNotification.show({ message: 'Transformation Rules Added.', intent: Intent.SUCCESS, icon: 'small-tick' })
- }, [])
+ }, [setConfiguredProject, setConfiguredBoard])
const handleAdvancedMode = (enableAdvanced = true) => {
setAdvancedMode(enableAdvanced)
@@ -698,25 +710,25 @@ const CreateBlueprint = (props) => {
integrationsData.find((p) => p.id === someConnection.provider)
)
}
- const getDefaultEntities = (providerId) => {
- let entities = []
- switch (providerId) {
- case Providers.GITHUB:
- case Providers.GITLAB:
- entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name !== 'ci-cd')
- break
- case Providers.JIRA:
- entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'issue-tracking' || d.name === 'cross-domain')
- break
- case Providers.JENKINS:
- entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'ci-cd')
- break
- case Providers.TAPD:
- entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'ci-cd')
- break
- }
- return entities
- }
+ // const getDefaultEntities = (providerId) => {
+ // let entities = []
+ // switch (providerId) {
+ // case Providers.GITHUB:
+ // case Providers.GITLAB:
+ // entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name !== 'ci-cd')
+ // break
+ // case Providers.JIRA:
+ // entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'issue-tracking' || d.name === 'cross-domain')
+ // break
+ // case Providers.JENKINS:
+ // entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'ci-cd')
+ // break
+ // case Providers.TAPD:
+ // entities = DEFAULT_DATA_ENTITIES.filter((d) => d.name === 'ci-cd')
+ // break
+ // }
+ // return entities
+ // }
const initializeEntities = (pV, cV) => ({
...pV,
[cV.id]: !pV[cV.id] ? getDefaultEntities(cV?.provider) : [],
@@ -739,6 +751,8 @@ const CreateBlueprint = (props) => {
testSelectedConnections(blueprintConnections)
}, [
blueprintConnections,
+ getDefaultEntities,
+ setConfiguredConnection,
setProvider,
setBoards,
setDataEntities,
@@ -774,7 +788,7 @@ const CreateBlueprint = (props) => {
break
}
}
- }, [configuredConnection, setActiveConnectionTab])
+ }, [configuredConnection, setActiveConnectionTab, setConfiguredBoard, setConfiguredProject])
useEffect(() => {
console.log('>> DATA ENTITIES', dataEntities)
@@ -960,6 +974,7 @@ const CreateBlueprint = (props) => {
statusResponse: dataConnections.find(dC => dC.id === c.id && dC.provider === c.provider),
status: dataConnections.find(dC => dC.id === c.id && dC.provider === c.provider)?.status
})))
+ // @todo: re-enable next disable on offline connection! (disabled to allow GitHub Test)
setCanAdvanceNext(dataConnections.every(dC => dC.status === 200))
}, [dataConnections, setConnectionsList])
@@ -1085,6 +1100,7 @@ const CreateBlueprint = (props) => {
configuredConnection={configuredConnection}
configuredProject={configuredProject}
configuredBoard={configuredBoard}
+ configurationKey={configurationKey}
handleConnectionTabChange={handleConnectionTabChange}
prevStep={prevStep}
addBoardTransformation={addBoardTransformation}
diff --git a/config-ui/src/pages/blueprints/index.jsx b/config-ui/src/pages/blueprints/index.jsx
index 288450ba..0035ace3 100644
--- a/config-ui/src/pages/blueprints/index.jsx
+++ b/config-ui/src/pages/blueprints/index.jsx
@@ -136,7 +136,7 @@ const Blueprints = (props) => {
setExpandDetails(opened => blueprint.id === activeBlueprint?.id && opened ? false : !opened)
fetchAllPipelines()
setActiveBlueprint(blueprint)
- }, [fetchAllPipelines, setExpandDetails, setActiveBlueprint])
+ }, [fetchAllPipelines, setExpandDetails, setActiveBlueprint, activeBlueprint?.id])
const configureBlueprint = useCallback((blueprint) => {
history.push(`/blueprints/detail/${blueprint.id}`)
@@ -152,7 +152,7 @@ const Blueprints = (props) => {
const isActiveBlueprint = useCallback((bId) => {
return activeBlueprint?.id === bId
- }, [])
+ }, [activeBlueprint?.id])
const isStandardCronPreset = useCallback((cronConfig) => {
return cronPresets.some(p => p.cronConfig === cronConfig)
@@ -204,7 +204,7 @@ const Blueprints = (props) => {
setBlueprintDialogIsOpen(false)
fetchAllBlueprints()
}
- }, [saveComplete])
+ }, [saveComplete, fetchAllBlueprints])
useEffect(() => {
if (deleteComplete.status === 200) {
@@ -267,7 +267,7 @@ const Blueprints = (props) => {
}
})
setFilterParams(activeFilterStatus)
- }, [activeFilterStatus, setFilterParams, getCronPreset])
+ }, [activeFilterStatus, setFilterParams, getCronPreset, setFilterFunc])
// useEffect(() => {
// if (Array.isArray(tasks)) {
@@ -282,7 +282,7 @@ const Blueprints = (props) => {
useEffect(() => {
setPaginatorData(blueprints)
- }, [blueprints])
+ }, [blueprints, setPaginatorData])
return (
<>
diff --git a/config-ui/src/pages/configure/connections/AddConnection.jsx b/config-ui/src/pages/configure/connections/AddConnection.jsx
index 09e5351e..40e38461 100644
--- a/config-ui/src/pages/configure/connections/AddConnection.jsx
+++ b/config-ui/src/pages/configure/connections/AddConnection.jsx
@@ -126,7 +126,7 @@ export default function AddConnection () {
useEffect(() => {
console.log('>>>> DETECTED PROVIDER = ', providerId)
setActiveProvider(integrationsData.find(p => p.id === providerId))
- }, [])
+ }, [providerId])
return (
<>
diff --git a/config-ui/src/pages/configure/connections/ConfigureConnection.jsx b/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
index 7bcab51b..278acc01 100644
--- a/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
+++ b/config-ui/src/pages/configure/connections/ConfigureConnection.jsx
@@ -144,7 +144,7 @@ export default function ConfigureConnection () {
} else {
console.log('NO PARAMS!')
}
- }, [connectionId, providerId, integrationsData])
+ }, [connectionId, providerId])
useEffect(() => {
diff --git a/config-ui/src/pages/configure/integration/manage.jsx b/config-ui/src/pages/configure/integration/manage.jsx
index e26a1a37..7c7c1a81 100644
--- a/config-ui/src/pages/configure/integration/manage.jsx
+++ b/config-ui/src/pages/configure/integration/manage.jsx
@@ -130,7 +130,7 @@ export default function ManageIntegration () {
console.log('>> ACTIVE PROVIDER = ', providerId)
setIntegrations(integrations)
setActiveProvider(integrations.find(p => p.id === providerId))
- }, [])
+ }, [integrations, providerId])
useEffect(() => {
let flushTimeout
diff --git a/config-ui/src/pages/configure/settings/github.jsx b/config-ui/src/pages/configure/settings/github.jsx
index 0f53a5b2..9c79827b 100644
--- a/config-ui/src/pages/configure/settings/github.jsx
+++ b/config-ui/src/pages/configure/settings/github.jsx
@@ -29,16 +29,18 @@ import {
Position
} from '@blueprintjs/core'
import { DataEntityTypes } from '@/data/DataEntities'
+import Deployment from '@/components/blueprints/transformations/CICD/Deployment'
import '@/styles/integration.scss'
import '@/styles/connections.scss'
export default function GithubSettings (props) {
const {
- // eslint-disable-next-line no-unused-vars
+ provider,
connection,
entities = [],
transformation = {},
+ entityIdKey,
isSaving,
isSavingConnection,
onSettingsChange = () => {},
@@ -60,12 +62,12 @@ export default function GithubSettings (props) {
}, [setEnableAdditionalCalculations, configuredProject, onSettingsChange])
useEffect(() => {
- console.log('>>>> TRANSFORMATION SETTINGS OBJECT....', transformation)
+ console.log('>>>> GITHUB: TRANSFORMATION SETTINGS OBJECT....', transformation)
setEnableAdditionalCalculations(!!transformation?.refdiff)
}, [transformation])
useEffect(() => {
- console.log('>>>> ENABLE GITHUB ADDITIONAL SETTINGS..?', enableAdditionalCalculations)
+ console.log('>>>> GITHUB: ENABLE GITHUB ADDITIONAL SETTINGS..?', enableAdditionalCalculations)
if (enableAdditionalCalculations === 'disabled') {
// onSettingsChange({gitextractorCalculation: ''}, configuredProject)
}
@@ -206,6 +208,18 @@ export default function GithubSettings (props) {
</>
)}
+ {entities.some(e => e.value === DataEntityTypes.DEVOPS) && configuredProject && (
+ <Deployment
+ provider={provider}
+ entities={entities}
+ entityIdKey={entityIdKey}
+ transformation={transformation}
+ connection={connection}
+ onSettingsChange={onSettingsChange}
+ isSaving={isSaving || isSavingConnection}
+ />
+ )}
+
{entities.some(e => e.value === DataEntityTypes.CODE_REVIEW) && (
<><h5>Code Review{' '} <Tag className='bp3-form-helper-text' minimal>RegExp</Tag></h5>
<p className=''>Map your pull requests labels with each category to view corresponding metrics in the dashboard.</p>
@@ -296,6 +310,7 @@ export default function GithubSettings (props) {
<TextArea
id='github-pr-body'
className='textarea'
+ value={transformation?.prBodyClosePattern}
placeholder='(?mi)(fix|close|resolve|fixes|closes|resolves|fixed|closed|resolved)[\s]*.*(((and )?(#|https:\/\/github.com\/%s\/%s\/issues\/)\d+[ ]*)+)'
onChange={(e) => onSettingsChange({ prBodyClosePattern: e.target.value }, configuredProject?.id)}
disabled={isSaving || isSavingConnection}
@@ -303,8 +318,7 @@ export default function GithubSettings (props) {
rows={2}
growVertically={false}
autoFocus
- >{transformation?.prBodyClosePattern}
- </TextArea>
+ />
</FormGroup>
</div>
diff --git a/config-ui/src/pages/configure/settings/gitlab.jsx b/config-ui/src/pages/configure/settings/gitlab.jsx
index 85119ae2..a8fa23d5 100644
--- a/config-ui/src/pages/configure/settings/gitlab.jsx
+++ b/config-ui/src/pages/configure/settings/gitlab.jsx
@@ -18,6 +18,7 @@
import React, { useEffect } from 'react'
import { useHistory } from 'react-router-dom'
import { DataEntityTypes } from '@/data/DataEntities'
+import Deployment from '@/components/blueprints/transformations/CICD/Deployment'
import '@/styles/integration.scss'
import '@/styles/connections.scss'
@@ -26,44 +27,35 @@ export default function GitlabSettings (props) {
const {
connection,
entities = [],
- // eslint-disable-next-line max-len
transformation = {},
+ entityIdKey,
provider,
+ projects,
+ configuredProject,
+ isSaving = false,
+ isSavingConnection = false,
onSettingsChange = () => {}
} = props
- const history = useHistory()
useEffect(() => {
- const settings = {
- // no additional settings
- }
- onSettingsChange(settings)
- console.log('>> GITLAB INSTANCE SETTINGS FIELDS CHANGED!', settings)
- }, [
- onSettingsChange
- ])
-
- // eslint-disable-next-line max-len
- const cancel = () => {
- history.push(`/integrations/${provider.id}`)
- }
-
- useEffect(() => {
- if (connection && connection.id) {
- console.log('>> GITLAB CONNECTION OBJECT RECEIVED...', connection)
- } else {
- console.log('>>>> WARNING!! NO CONNECTION OBJECT', connection)
- }
- }, [connection])
+ console.log('>>>> GITLAB: TRANSFORMATION SETTINGS OBJECT....', transformation)
+ }, [transformation])
return (
<>
- <div className='headlineContainer'>
- <h5>No Additional Settings</h5>
- <p className='description'>
- This project doesn’t require any configuration.
- </p>
- </div>
+ {entities.some(e => e.value === DataEntityTypes.DEVOPS) && configuredProject ? (
+ <Deployment
+ provider={provider}
+ entities={entities}
+ entityIdKey={entityIdKey}
+ transformation={transformation}
+ connection={connection}
+ onSettingsChange={onSettingsChange}
+ isSaving={isSaving || isSavingConnection}
+ />
+ ) : (
+ <></>
+ )}
</>
)
}
diff --git a/config-ui/src/pages/configure/settings/jenkins.jsx b/config-ui/src/pages/configure/settings/jenkins.jsx
index 287cf794..8d29b3e9 100644
--- a/config-ui/src/pages/configure/settings/jenkins.jsx
+++ b/config-ui/src/pages/configure/settings/jenkins.jsx
@@ -20,13 +20,37 @@ import {
useParams,
useHistory
} from 'react-router-dom'
+import {
+ Button,
+ ButtonGroup,
+ Classes,
+ Intent,
+ FormGroup,
+ InputGroup,
+ Radio,
+ RadioGroup,
+ Switch,
+ Tag,
+ Tooltip,
+} from '@blueprintjs/core'
+
import { DataEntityTypes } from '@/data/DataEntities'
+import Deployment from '@/components/blueprints/transformations/CICD/Deployment'
import '@/styles/integration.scss'
import '@/styles/connections.scss'
export default function JenkinsSettings (props) {
- const { provider, connection, entities = [], onSettingsChange = () => {} } = props
+ const {
+ provider,
+ transformation,
+ entityIdKey,
+ connection,
+ entities = [],
+ onSettingsChange = () => {},
+ isSaving = false,
+ isSavingConnection = false
+ } = props
const history = useHistory()
const { providerId, connectionId } = useParams()
@@ -49,14 +73,30 @@ export default function JenkinsSettings (props) {
})
}, [errors, onSettingsChange, connectionId, providerId])
+ useEffect(() => {
+ console.log('>>> JENKINS: DATA ENTITIES...', entities)
+ }, [entities])
+
return (
<>
- <div className='headlineContainer'>
- <h3 className='headline'>No Additional Settings</h3>
- <p className='description'>
- This integration doesn’t require any configuration.
- </p>
- </div>
+ {entities.some(e => e.value === DataEntityTypes.DEVOPS) ? (
+ <Deployment
+ provider={provider}
+ entities={entities}
+ entityIdKey={entityIdKey}
+ transformation={transformation}
+ connection={connection}
+ onSettingsChange={onSettingsChange}
+ isSaving={isSaving || isSavingConnection}
+ />
+ ) : (
+ <div className='headlineContainer'>
+ <h3 className='headline'>No Additional Settings</h3>
+ <p className='description'>
+ This integration doesn’t require any configuration.
+ </p>
+ </div>
+ )}
</>
)
}
diff --git a/config-ui/src/pages/configure/settings/jira.jsx b/config-ui/src/pages/configure/settings/jira.jsx
index 07be90f4..482b33c8 100644
--- a/config-ui/src/pages/configure/settings/jira.jsx
+++ b/config-ui/src/pages/configure/settings/jira.jsx
@@ -53,11 +53,13 @@ const createTypeMapObject = (customType, standardType) => {
export default function JiraSettings (props) {
const {
+ provider,
connection,
blueprint,
entities = [],
configuredBoard,
transformation = {},
+ entityIdKey,
transformations = {},
isSaving,
onSettingsChange = () => {},
@@ -86,13 +88,13 @@ export default function JiraSettings (props) {
// @todo: lift higher to dsm hook
const savedRequirementTags = useMemo(() => boards[connection?.id]
? boards[connection?.id].reduce((pV, cV, iDx) => ({ ...pV, [cV?.id]: connection?.transformations ? connection?.transformations[iDx]?.requirementTags : transformation?.requirementTags, }), {})
- : {}, [connection?.id, configuredBoard?.id, boards, transformations])
+ : {}, [connection?.id, boards, connection?.transformations, transformation?.requirementTags])
const savedBugTags = useMemo(() => boards[connection?.id]
? boards[connection?.id].reduce((pV, cV, iDx) => ({ ...pV, [cV?.id]: connection?.transformations ? connection?.transformations[iDx]?.bugTags : transformation?.bugTags, }), {})
- : {}, [connection?.id, configuredBoard?.id, boards, transformations])
+ : {}, [connection?.id, boards, connection?.transformations, transformation?.bugTags])
const savedIncidentTags = useMemo(() => boards[connection?.id]
? boards[connection?.id].reduce((pV, cV, iDx) => ({ ...pV, [cV?.id]: connection?.transformations ? connection?.transformations[iDx]?.incidentTags : transformation?.incidentTags, }), {})
- : {}, [connection?.id, configuredBoard?.id, boards, transformations])
+ : {}, [connection?.id, boards, connection?.transformations, transformation?.incidentTags])
const [requirementTags, setRequirementTags] = useState(savedRequirementTags)
const [bugTags, setBugTags] = useState(savedBugTags)
@@ -363,7 +365,7 @@ export default function JiraSettings (props) {
<div className='issue-type-multiselect' style={{ display: 'flex', marginBottom: '10px' }}>
<div className='issue-type-label' style={{ minWidth: '120px', paddingRight: '10px', paddingTop: '3px' }}>
- <label>Incident</label>
+ <label>Incident <Tag intent={Intent.PRIMARY} style={{ fontSize: '10px' }} minimal>DORA</Tag></label>
</div>
<div className='issue-type-multiselect-selector' style={{ minWidth: '200px', width: '100%' }}>
<MultiSelect
diff --git a/config-ui/src/pages/offline/index.jsx b/config-ui/src/pages/offline/index.jsx
index 30ff9ab1..30977417 100644
--- a/config-ui/src/pages/offline/index.jsx
+++ b/config-ui/src/pages/offline/index.jsx
@@ -29,6 +29,8 @@ import {
Spinner,
Colors
} from '@blueprintjs/core'
+import { ReactComponent as Logo } from '@/images/devlake-logo.svg'
+import { ReactComponent as LogoText } from '@/images/devlake-textmark.svg'
import '@/styles/offline.scss'
const Offline = (props) => {
@@ -134,6 +136,10 @@ const Offline = (props) => {
style={{ maxWidth: '500px', margin: '0 auto', display: 'flex', height: '100%', flexDirection: 'column' }}
>
<div style={{ margin: 'auto auto', padding: '16px' }}>
+ <div className='devlake-logo' style={{ margin: 0 }}>
+ <Logo width={48} height={48} className='logo' />
+ <LogoText width={100} height={13} className='logo-textmark' />
+ </div>
<CSSTransition in={cardReady} timeout={900} classNames='offline-card'>
<Card
elevation={Elevation.THREE}
@@ -207,10 +213,10 @@ const Offline = (props) => {
style={{ cursor: 'pointer' }}
>
<Button
- intent={Intent.DANGER} icon='warning-sign'
+ intent={Intent.PRIMARY}
+ icon='warning-sign'
style={{ fontWeight: 700 }}
onClick={() => history.replace('/')}
- large
>Continue
</Button>
</Tooltip>
@@ -220,7 +226,6 @@ const Offline = (props) => {
style={{ marginLeft: '5px' }}
disabled={!cardReady}
onClick={() => testEndpoint()}
- large
/>
</>
)
@@ -232,7 +237,6 @@ const Offline = (props) => {
<Button
icon='cog' intent={Intent.PRIMARY}
onClick={() => history.replace('/')}
- large
>
Open Dashboard
</Button>
@@ -240,7 +244,7 @@ const Offline = (props) => {
href='https://github.com/apache/incubator-devlake/blob/main/README.md'
target='_blank'
rel='noreferrer'
- style={{ marginLeft: '5px' }} className='bp3-button bp3-large bp3-minimal'
+ style={{ marginLeft: '5px' }} className='bp3-button bp3-minimal'
>
<Icon icon='help' size={16} style={{ marginRight: '5px' }} />
Read Documentation
@@ -250,7 +254,6 @@ const Offline = (props) => {
</Card>
</CSSTransition>
<div style={{ margin: '10px 5px 10px 5px', display: 'flex', justifyContnt: 'flex-start' }}>
- <img src='/logo.svg' width={20} style={{ width: '20px', marginTop: '3px', marginRight: '5px', alignSelf: 'flex-start' }} />
<div style={{ color: 'rgba(33, 33, 33, 0.6)' }}>
{isOffline
? (
diff --git a/config-ui/src/styles/offline.scss b/config-ui/src/styles/offline.scss
index 85e31c5a..72cdbdd0 100644
--- a/config-ui/src/styles/offline.scss
+++ b/config-ui/src/styles/offline.scss
@@ -38,9 +38,9 @@
}
&.is-online::before {
- background: #DE6262;
- background: -webkit-linear-gradient(to right, #FFB88C, #DE6262);
- background: linear-gradient(to right, #FFB88C, #DE6262);
+ background: #606c88;
+ background: -webkit-linear-gradient(to left, #3f4c6b, #606c88);
+ background: linear-gradient(to left, #3f4c6b, #606c88);
}
.bp3-card {