This is an automated email from the ASF dual-hosted git repository.

likyh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 4e799e36e feat(config-ui): improve the project detail page (#3918)
4e799e36e is described below

commit 4e799e36e2d92bed4b45a71521745c1f7639c102
Author: 青湛 <[email protected]>
AuthorDate: Tue Dec 13 17:04:08 2022 +0800

    feat(config-ui): improve the project detail page (#3918)
    
    * feat(config-ui): improve the project detail page
    
    * fix(config-ui): the interface return value to change
---
 config-ui/src/App.js                               |  11 +-
 config-ui/src/hooks/useDataScopesManager.jsx       |  16 +--
 .../pages/blueprint/{index.ts => detail/api.ts}    |   7 +-
 .../{index.ts => detail/blueprint-detail-page.tsx} |  29 +++-
 .../pages/blueprint/detail/blueprint-detail.tsx    |  53 +++++++
 .../src/pages/blueprint/{ => detail}/index.ts      |   3 +-
 .../pages/blueprint/{index.ts => detail/types.ts}  |   7 +-
 config-ui/src/pages/blueprint/detail/use-detail.ts |  75 ++++++++++
 config-ui/src/pages/blueprint/index.ts             |   1 +
 .../src/pages/blueprints/blueprint-detail.jsx      | 157 +++++++++------------
 .../src/pages/blueprints/blueprint-settings.jsx    | 139 +-----------------
 config-ui/src/pages/blueprints/index.jsx           |   4 +-
 .../src/pages/project/detail/panel/blueprint.tsx   |   3 +-
 13 files changed, 259 insertions(+), 246 deletions(-)

diff --git a/config-ui/src/App.js b/config-ui/src/App.js
index ac0b8c131..3357f47d9 100644
--- a/config-ui/src/App.js
+++ b/config-ui/src/App.js
@@ -42,6 +42,7 @@ import {
   ProjectHomePage,
   ProjectDetailPage,
   CreateBlueprintPage,
+  BlueprintDetailPage,
   WebHookConnectionPage
 } from '@/pages'
 import Integration from '@/pages/configure/integration/index'
@@ -124,16 +125,10 @@ function App(props) {
               path='/blueprints/create'
               component={() => <CreateBlueprintPage from='blueprint' />}
             />
-
-            <Route
-              exact
-              path='/blueprints/detail/:bId'
-              component={() => <BlueprintDetail />}
-            />
             <Route
               exact
-              path='/blueprints/settings/:bId'
-              component={() => <BlueprintSettings />}
+              path='/blueprints/:id'
+              component={() => <BlueprintDetailPage />}
             />
           </Switch>
           <MigrationAlertDialog
diff --git a/config-ui/src/hooks/useDataScopesManager.jsx 
b/config-ui/src/hooks/useDataScopesManager.jsx
index dc0ba3805..28f065e7f 100644
--- a/config-ui/src/hooks/useDataScopesManager.jsx
+++ b/config-ui/src/hooks/useDataScopesManager.jsx
@@ -224,7 +224,7 @@ function useDataScopesManager({
 
   const getGithubProjects = useCallback(
     (c) =>
-      c.scope.map(
+      c.scopes.map(
         (s) =>
           new GitHubProject({
             id: `${s.options?.owner}/${s.options?.repo}`,
@@ -240,7 +240,7 @@ function useDataScopesManager({
 
   const getGitlabProjects = useCallback(
     (c) =>
-      c.scope.map(
+      c.scopes.map(
         (s) =>
           new GitlabProject({
             id: s.options?.projectId,
@@ -255,7 +255,7 @@ function useDataScopesManager({
   const getJenkinsProjects = useCallback(
     (c) =>
       // when s.options?.jobName is empty, it's old jenkins config which 
collect all job data
-      c.scope
+      c.scopes
         .filter((s) => s.options?.jobName)
         .map(
           (s) =>
@@ -271,7 +271,7 @@ function useDataScopesManager({
 
   const getJiraBoard = useCallback(
     (c) =>
-      c.scope.map(
+      c.scopes.map(
         (s) =>
           new JiraBoard({
             id: s.options?.boardId,
@@ -423,12 +423,12 @@ function useDataScopesManager({
         `${ProviderLabels[c.plugin?.toUpperCase()]} #${c.connectionId || 
cIdx}`,
       // FIXME: entities in `c.scope[0]?.entities` means one of 
ALL_DATA_DOMAINS and is saved in db,
       // So it kept here.
-      dataDomains: c.scope[0]?.entities?.map((e) =>
+      dataDomains: c.scopes[0]?.entities?.map((e) =>
         ALL_DATA_DOMAINS.find((de) => de.value === e)
       ),
       scopeEntities: getProjects(c),
-      transformations: c.scope.map((s) => ({ ...s.transformation })),
-      transformationStates: c.scope.map((s) =>
+      transformations: c.scopes.map((s) => ({ ...s.transformation })),
+      transformationStates: c.scopes.map((s) =>
         Object.values(s.transformation ?? {}).some((v) =>
           Array.isArray(v)
             ? v.length > 0
@@ -439,7 +439,7 @@ function useDataScopesManager({
           ? 'Added'
           : '-'
       ),
-      scope: c.scope,
+      scope: c.scopes,
       // editable: ![Providers.JENKINS].includes(c.plugin),
       editable: true,
       advancedEditable: false,
diff --git a/config-ui/src/pages/blueprint/index.ts 
b/config-ui/src/pages/blueprint/detail/api.ts
similarity index 76%
copy from config-ui/src/pages/blueprint/index.ts
copy to config-ui/src/pages/blueprint/detail/api.ts
index 56e0942fb..85609f207 100644
--- a/config-ui/src/pages/blueprint/index.ts
+++ b/config-ui/src/pages/blueprint/detail/api.ts
@@ -16,4 +16,9 @@
  *
  */
 
-export * from './create'
+import request from '@/components/utils/request'
+
+export const getBlueprint = (id: ID) => request(`/blueprints/${id}`)
+
+export const updateBlueprint = (id: ID, payload: any) =>
+  request(`/blueprints/${id}`, { method: 'patch', data: payload })
diff --git a/config-ui/src/pages/blueprint/index.ts 
b/config-ui/src/pages/blueprint/detail/blueprint-detail-page.tsx
similarity index 54%
copy from config-ui/src/pages/blueprint/index.ts
copy to config-ui/src/pages/blueprint/detail/blueprint-detail-page.tsx
index 56e0942fb..5758b06d3 100644
--- a/config-ui/src/pages/blueprint/index.ts
+++ b/config-ui/src/pages/blueprint/detail/blueprint-detail-page.tsx
@@ -16,4 +16,31 @@
  *
  */
 
-export * from './create'
+import React from 'react'
+import { useParams } from 'react-router-dom'
+
+import { PageHeader, PageLoading } from '@/components'
+
+import { useDetail } from './use-detail'
+import { BlueprintDetail } from './blueprint-detail'
+
+export const BlueprintDetailPage = () => {
+  const { id } = useParams<{ id: string }>()
+
+  const { loading, blueprint } = useDetail({ id })
+
+  if (loading || !blueprint) {
+    return <PageLoading />
+  }
+
+  return (
+    <PageHeader
+      breadcrumbs={[
+        { name: 'Blueprints', path: '/blueprints' },
+        { name: blueprint.name, path: `/blueprints/${blueprint.id}` }
+      ]}
+    >
+      <BlueprintDetail id={blueprint.id} />
+    </PageHeader>
+  )
+}
diff --git a/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx 
b/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx
new file mode 100644
index 000000000..663bac67c
--- /dev/null
+++ b/config-ui/src/pages/blueprint/detail/blueprint-detail.tsx
@@ -0,0 +1,53 @@
+/*
+ * 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 } from 'react'
+import type { TabId } from '@blueprintjs/core'
+import { Tabs, Tab } from '@blueprintjs/core'
+
+// TO-DO: use new panel to replace it
+import Status from '@/pages/blueprints/blueprint-detail'
+import Configuration from '@/pages/blueprints/blueprint-settings'
+
+import { PageLoading } from '@/components'
+
+import type { UseDetailProps } from './use-detail'
+import { useDetail } from './use-detail'
+
+interface Props extends UseDetailProps {}
+
+export const BlueprintDetail = ({ id }: Props) => {
+  const [activeTab, setActiveTab] = useState<TabId>('configuration')
+
+  const { loading, blueprint, saving, onUpdate } = useDetail({ id })
+
+  if (loading || !blueprint) {
+    return <PageLoading />
+  }
+
+  return (
+    <Tabs selectedTabId={activeTab} onChange={(at) => setActiveTab(at)}>
+      <Tab id='status' title='Status' panel={<Status id={id} />} />
+      <Tab
+        id='configuration'
+        title='Configuration'
+        panel={<Configuration id={id} />}
+      />
+    </Tabs>
+  )
+}
diff --git a/config-ui/src/pages/blueprint/index.ts 
b/config-ui/src/pages/blueprint/detail/index.ts
similarity index 91%
copy from config-ui/src/pages/blueprint/index.ts
copy to config-ui/src/pages/blueprint/detail/index.ts
index 56e0942fb..688a1ab0f 100644
--- a/config-ui/src/pages/blueprint/index.ts
+++ b/config-ui/src/pages/blueprint/detail/index.ts
@@ -16,4 +16,5 @@
  *
  */
 
-export * from './create'
+export * from './blueprint-detail'
+export * from './blueprint-detail-page'
diff --git a/config-ui/src/pages/blueprint/index.ts 
b/config-ui/src/pages/blueprint/detail/types.ts
similarity index 89%
copy from config-ui/src/pages/blueprint/index.ts
copy to config-ui/src/pages/blueprint/detail/types.ts
index 56e0942fb..cc55cda89 100644
--- a/config-ui/src/pages/blueprint/index.ts
+++ b/config-ui/src/pages/blueprint/detail/types.ts
@@ -16,4 +16,9 @@
  *
  */
 
-export * from './create'
+export type BlueprintType = {
+  id: ID
+  name: string
+  isManual: boolean
+  cronConfig: string
+}
diff --git a/config-ui/src/pages/blueprint/detail/use-detail.ts 
b/config-ui/src/pages/blueprint/detail/use-detail.ts
new file mode 100644
index 000000000..8351d18f3
--- /dev/null
+++ b/config-ui/src/pages/blueprint/detail/use-detail.ts
@@ -0,0 +1,75 @@
+/*
+ * 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 { useState, useEffect, useMemo } from 'react'
+
+import { operator } from '@/utils'
+
+import type { BlueprintType } from './types'
+import * as API from './api'
+
+export interface UseDetailProps {
+  id: ID
+}
+
+export const useDetail = ({ id }: UseDetailProps) => {
+  const [loading, setLoading] = useState(false)
+  const [saving, setSaving] = useState(false)
+  const [blueprint, setBlueprint] = useState<BlueprintType>()
+
+  const getBlueprint = async () => {
+    setLoading(true)
+    try {
+      const res = await API.getBlueprint(id)
+      setBlueprint(res)
+    } finally {
+      setLoading(false)
+    }
+  }
+
+  useEffect(() => {
+    getBlueprint()
+  }, [])
+
+  const handleUpdate = async (payload: any) => {
+    const [success, res] = await operator(
+      () =>
+        API.updateBlueprint(id, {
+          ...blueprint,
+          ...payload
+        }),
+      {
+        setOperating: setSaving
+      }
+    )
+
+    if (success) {
+      setBlueprint(res)
+    }
+  }
+
+  return useMemo(
+    () => ({
+      loading,
+      saving,
+      blueprint,
+      onUpdate: handleUpdate
+    }),
+    [loading, saving, blueprint]
+  )
+}
diff --git a/config-ui/src/pages/blueprint/index.ts 
b/config-ui/src/pages/blueprint/index.ts
index 56e0942fb..b5d1e204d 100644
--- a/config-ui/src/pages/blueprint/index.ts
+++ b/config-ui/src/pages/blueprint/index.ts
@@ -17,3 +17,4 @@
  */
 
 export * from './create'
+export * from './detail'
diff --git a/config-ui/src/pages/blueprints/blueprint-detail.jsx 
b/config-ui/src/pages/blueprints/blueprint-detail.jsx
index e7ca7f000..4eabe1162 100644
--- a/config-ui/src/pages/blueprints/blueprint-detail.jsx
+++ b/config-ui/src/pages/blueprints/blueprint-detail.jsx
@@ -61,11 +61,9 @@ import useBlueprintManager from '@/hooks/useBlueprintManager'
 import usePipelineManager from '@/hooks/usePipelineManager'
 import usePaginator from '@/hooks/usePaginator'
 
-const BlueprintDetail = (props) => {
+const BlueprintDetail = ({ id }) => {
   const { integrations: Integrations, ProviderLabels } = useIntegrations()
 
-  const { bId } = useParams()
-
   const [blueprintId, setBlueprintId] = useState()
   const [activeBlueprint, setActiveBlueprint] = useState(NullBlueprint)
   // eslint-disable-next-line no-unused-vars
@@ -241,9 +239,9 @@ const BlueprintDetail = (props) => {
   )
 
   useEffect(() => {
-    setBlueprintId(bId)
-    console.log('>>> REQUESTED BLUEPRINT ID ===', bId)
-  }, [bId])
+    setBlueprintId(id)
+    console.log('>>> REQUESTED BLUEPRINT ID ===', id)
+  }, [id])
 
   useEffect(() => {
     if (blueprintId) {
@@ -268,7 +266,7 @@ const BlueprintDetail = (props) => {
           name: `${
             ProviderLabels[connection?.plugin.toUpperCase()]
           } Connection (ID #${connection?.connectionId})`,
-          dataScope: connection?.scope
+          dataScope: connection?.scopes
             .map((s) => [`${s.options?.owner}/${s?.options?.repo}`])
             .join(', '),
           dataDomains: []
@@ -381,93 +379,76 @@ const BlueprintDetail = (props) => {
     <>
       <main className='main'>
         <div
-          className='blueprint-header'
-          style={{
-            display: 'flex',
-            width: '100%',
-            justifyContent: 'space-between',
-            marginBottom: '10px'
-          }}
+          className='blueprint-info'
+          style={{ display: 'flex', alignItems: 'center' }}
         >
-          <div className='blueprint-name' style={{}}>
-            <h2 style={{ fontWeight: 'bold' }}>{activeBlueprint?.name}</h2>
+          <div className='blueprint-schedule'>
+            <span
+              className='blueprint-schedule-interval'
+              style={{ textTransform: 'capitalize', padding: '0 10px' }}
+            >
+              {activeBlueprint?.interval} (at{' '}
+              {dayjs(getNextRunDate(activeBlueprint?.cronConfig)).format(
+                'hh:mm A'
+              )}
+              )
+            </span>{' '}
+            &nbsp;{' '}
+            <span className='blueprint-schedule-nextrun'>
+              {activeBlueprint?.isManual ? (
+                <strong>Manual Mode</strong>
+              ) : (
+                <>
+                  Next Run{' '}
+                  
{dayjs(getNextRunDate(activeBlueprint?.cronConfig)).fromNow()}
+                </>
+              )}
+            </span>
           </div>
-          <div
-            className='blueprint-info'
-            style={{ display: 'flex', alignItems: 'center' }}
-          >
-            <div className='blueprint-schedule'>
-              <span
-                className='blueprint-schedule-interval'
-                style={{ textTransform: 'capitalize', padding: '0 10px' }}
-              >
-                {activeBlueprint?.interval} (at{' '}
-                {dayjs(getNextRunDate(activeBlueprint?.cronConfig)).format(
-                  'hh:mm A'
-                )}
+          <div className='blueprint-actions' style={{ padding: '0 10px' }}>
+            <Button
+              intent={Intent.PRIMARY}
+              small
+              text='Run Now'
+              onClick={runBlueprint}
+              disabled={
+                !activeBlueprint?.enable ||
+                [TaskStatus.CREATED, TaskStatus.RUNNING].includes(
+                  currentRun?.status
                 )
-              </span>{' '}
-              &nbsp;{' '}
-              <span className='blueprint-schedule-nextrun'>
-                {activeBlueprint?.isManual ? (
-                  <strong>Manual Mode</strong>
-                ) : (
-                  <>
-                    Next Run{' '}
-                    {dayjs(
-                      getNextRunDate(activeBlueprint?.cronConfig)
-                    ).fromNow()}
-                  </>
-                )}
-              </span>
-            </div>
-            <div className='blueprint-actions' style={{ padding: '0 10px' }}>
-              <Button
-                intent={Intent.PRIMARY}
-                small
-                text='Run Now'
-                onClick={runBlueprint}
-                disabled={
-                  !activeBlueprint?.enable ||
-                  [TaskStatus.CREATED, TaskStatus.RUNNING].includes(
-                    currentRun?.status
-                  )
-                }
-              />
-            </div>
-            <div className='blueprint-enabled'>
-              <Switch
-                id='blueprint-enable'
-                name='blueprint-enable'
-                checked={activeBlueprint?.enable}
-                label={
-                  activeBlueprint?.enable
-                    ? 'Blueprint Enabled'
-                    : 'Blueprint Disabled'
-                }
-                onChange={() => handleBlueprintActivation(activeBlueprint)}
-                style={{
-                  marginBottom: 0,
-                  marginTop: 0,
-                  color: !activeBlueprint?.enable ? Colors.GRAY3 : 'inherit'
-                }}
-                disabled={currentRun?.status === TaskStatus.RUNNING}
-              />
-            </div>
-            <div style={{ padding: '0 10px' }}>
-              <Button
-                intent={Intent.PRIMARY}
-                icon='trash'
-                small
-                minimal
-                disabled
-              />
-            </div>
+              }
+            />
+          </div>
+          <div className='blueprint-enabled'>
+            <Switch
+              id='blueprint-enable'
+              name='blueprint-enable'
+              checked={activeBlueprint?.enable}
+              label={
+                activeBlueprint?.enable
+                  ? 'Blueprint Enabled'
+                  : 'Blueprint Disabled'
+              }
+              onChange={() => handleBlueprintActivation(activeBlueprint)}
+              style={{
+                marginBottom: 0,
+                marginTop: 0,
+                color: !activeBlueprint?.enable ? Colors.GRAY3 : 'inherit'
+              }}
+              disabled={currentRun?.status === TaskStatus.RUNNING}
+            />
+          </div>
+          <div style={{ padding: '0 10px' }}>
+            <Button
+              intent={Intent.PRIMARY}
+              icon='trash'
+              small
+              minimal
+              disabled
+            />
           </div>
         </div>
 
-        <BlueprintNavigationLinks blueprint={activeBlueprint} />
-
         <div
           className='blueprint-run'
           style={{
diff --git a/config-ui/src/pages/blueprints/blueprint-settings.jsx 
b/config-ui/src/pages/blueprints/blueprint-settings.jsx
index da4ee703c..a69331d62 100644
--- a/config-ui/src/pages/blueprints/blueprint-settings.jsx
+++ b/config-ui/src/pages/blueprints/blueprint-settings.jsx
@@ -68,10 +68,9 @@ import {
 } from '@/config/jenkinsApiProxy'
 import { ALL_DATA_DOMAINS } from '@/data/DataDomains'
 
-const BlueprintSettings = (props) => {
+const BlueprintSettings = ({ id }) => {
   // eslint-disable-next-line no-unused-vars
   const history = useHistory()
-  const { bId } = useParams()
 
   const {
     registry,
@@ -545,9 +544,9 @@ const BlueprintSettings = (props) => {
   ])
 
   useEffect(() => {
-    setBlueprintId(bId)
-    console.log('>>> REQUESTED SETTINGS for BLUEPRINT ID ===', bId)
-  }, [bId])
+    setBlueprintId(id)
+    console.log('>>> REQUESTED SETTINGS for BLUEPRINT ID ===', id)
+  }, [id])
 
   useEffect(() => {
     if (!isNaN(blueprintId)) {
@@ -850,138 +849,8 @@ const BlueprintSettings = (props) => {
   return (
     <>
       <main className='main'>
-        {activeBlueprint?.id !== null && blueprintErrors.length === 0 && (
-          <div
-            className='blueprint-header'
-            style={{
-              display: 'flex',
-              width: '100%',
-              justifyContent: 'space-between',
-              marginBottom: '10px',
-              whiteSpace: 'nowrap'
-            }}
-          >
-            <div className='blueprint-name' style={{}}>
-              <h2
-                style={{
-                  fontWeight: 'bold',
-                  display: 'flex',
-                  alignItems: 'center',
-                  color: !activeBlueprint?.enable ? Colors.GRAY1 : 'inherit'
-                }}
-              >
-                {activeBlueprint?.name}
-                <Tag
-                  minimal
-                  intent={
-                    activeBlueprint.mode === BlueprintMode.ADVANCED
-                      ? Intent.DANGER
-                      : Intent.PRIMARY
-                  }
-                  style={{ marginLeft: '10px' }}
-                >
-                  {activeBlueprint?.mode?.toString().toUpperCase()}
-                </Tag>
-              </h2>
-            </div>
-            <div
-              className='blueprint-info'
-              style={{ display: 'flex', alignItems: 'center' }}
-            >
-              <div className='blueprint-schedule'>
-                {activeBlueprint?.isManual ? (
-                  <strong>Manual Mode</strong>
-                ) : (
-                  <span
-                    className='blueprint-schedule-interval'
-                    style={{
-                      textTransform: 'capitalize',
-                      padding: '0 10px'
-                    }}
-                  >
-                    {activeBlueprint?.interval} (at{' '}
-                    {dayjs(getNextRunDate(activeBlueprint?.cronConfig)).format(
-                      `hh:mm A ${
-                        activeBlueprint?.interval !== 'Hourly'
-                          ? ' MM/DD/YYYY'
-                          : ''
-                      }`
-                    )}
-                    )
-                  </span>
-                )}{' '}
-                <span className='blueprint-schedule-nextrun'>
-                  {!activeBlueprint?.isManual && (
-                    <>
-                      Next Run{' '}
-                      {dayjs(
-                        getNextRunDate(activeBlueprint?.cronConfig)
-                      ).fromNow()}
-                    </>
-                  )}
-                </span>
-              </div>
-              <div className='blueprint-actions' style={{ padding: '0 10px' }}>
-                {/* <Button
-                      intent={Intent.PRIMARY}
-                      small
-                      text='Run Now'
-                      onClick={runBlueprint}
-                      disabled={!activeBlueprint?.enable || currentRun?.status 
=== TaskStatus.RUNNING}
-                    /> */}
-              </div>
-              <div className='blueprint-enabled'>
-                <Switch
-                  id='blueprint-enable'
-                  name='blueprint-enable'
-                  checked={activeBlueprint?.enable}
-                  label={
-                    activeBlueprint?.enable
-                      ? 'Blueprint Enabled'
-                      : 'Blueprint Disabled'
-                  }
-                  onChange={() => handleBlueprintActivation(activeBlueprint)}
-                  style={{
-                    marginBottom: 0,
-                    marginTop: 0,
-                    color: !activeBlueprint?.enable ? Colors.GRAY3 : 'inherit'
-                  }}
-                  disabled={currentRun?.status === TaskStatus.RUNNING}
-                />
-              </div>
-              <div style={{ padding: '0 10px' }}>
-                <Button
-                  intent={Intent.PRIMARY}
-                  icon='trash'
-                  small
-                  minimal
-                  disabled
-                />
-              </div>
-            </div>
-          </div>
-        )}
-
-        {blueprintErrors?.length > 0 && (
-          <div className='bp3-non-ideal-state blueprint-non-ideal-state'>
-            <div className='bp3-non-ideal-state-visual'>
-              <Icon icon='warning-sign' size={32} color={Colors.RED5} />
-            </div>
-            <h4 className='bp3-heading'>Invalid Blueprint</h4>
-            <div>{blueprintErrors[0]}</div>
-            <button
-              className='bp3-button bp3-intent-primary'
-              onClick={viewBlueprints}
-            >
-              Continue
-            </button>
-          </div>
-        )}
-
         {activeBlueprint?.id !== null && blueprintErrors.length === 0 && (
           <>
-            <BlueprintNavigationLinks blueprint={activeBlueprint} />
-
             <div
               className='blueprint-main-settings'
               style={{
diff --git a/config-ui/src/pages/blueprints/index.jsx 
b/config-ui/src/pages/blueprints/index.jsx
index 9c9639f3c..9b3acf7ee 100644
--- a/config-ui/src/pages/blueprints/index.jsx
+++ b/config-ui/src/pages/blueprints/index.jsx
@@ -160,14 +160,14 @@ const Blueprints = (props) => {
 
   const configureBlueprint = useCallback(
     (blueprint) => {
-      history.push(`/blueprints/detail/${blueprint.id}`)
+      history.push(`/blueprints/${blueprint.id}`)
     },
     [history]
   )
 
   const configureBlueprintSettings = useCallback(
     (blueprint) => {
-      history.push(`/blueprints/settings/${blueprint.id}`)
+      history.push(`/blueprints/${blueprint.id}`)
     },
     [history]
   )
diff --git a/config-ui/src/pages/project/detail/panel/blueprint.tsx 
b/config-ui/src/pages/project/detail/panel/blueprint.tsx
index 79d47ea15..fae9e5235 100644
--- a/config-ui/src/pages/project/detail/panel/blueprint.tsx
+++ b/config-ui/src/pages/project/detail/panel/blueprint.tsx
@@ -21,6 +21,7 @@ import { useHistory } from 'react-router-dom'
 import { Button, Intent } from '@blueprintjs/core'
 
 import NoData from '@/images/no-data.svg'
+import { BlueprintDetail } from '@/pages'
 
 import type { ProjectType } from '../types'
 import * as S from '../styled'
@@ -56,6 +57,6 @@ export const BlueprintPanel = ({ name, project }: Props) => {
       </div>
     </S.Panel>
   ) : (
-    <div>blueprint detail</div>
+    <BlueprintDetail id={project.blueprint.id} />
   )
 }

Reply via email to