You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by kl...@apache.org on 2023/10/10 05:18:21 UTC

[incubator-devlake] branch main updated: feat(config-ui): support full sync mode (#6200)

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

klesh 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 d5b52b743 feat(config-ui): support full sync mode (#6200)
d5b52b743 is described below

commit d5b52b74341f60ae915685b74c449021819eb440
Author: 青湛 <0x...@gmail.com>
AuthorDate: Tue Oct 10 18:18:13 2023 +1300

    feat(config-ui): support full sync mode (#6200)
---
 config-ui/src/pages/blueprint/detail/api.ts        |  4 +-
 .../pages/blueprint/detail/configuration-panel.tsx |  2 +-
 .../src/pages/blueprint/detail/status-panel.tsx    | 89 ++++++++++++++--------
 3 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/config-ui/src/pages/blueprint/detail/api.ts b/config-ui/src/pages/blueprint/detail/api.ts
index a919d2b52..d63293958 100644
--- a/config-ui/src/pages/blueprint/detail/api.ts
+++ b/config-ui/src/pages/blueprint/detail/api.ts
@@ -24,8 +24,8 @@ export const getBlueprint = (id: ID): Promise<BlueprintType> => request(`/bluepr
 
 export const getBlueprintPipelines = (id: ID) => request(`/blueprints/${id}/pipelines`);
 
-export const runBlueprint = (id: ID, skipCollectors: boolean) =>
-  request(`/blueprints/${id}/trigger`, { method: 'post', data: { skipCollectors } });
+export const runBlueprint = (id: ID, data: { skipCollectors: boolean; fullSync: boolean }) =>
+  request(`/blueprints/${id}/trigger`, { method: 'post', data });
 
 export const updateBlueprint = (id: ID, payload: BlueprintType) =>
   request(`/blueprints/${id}`, { method: 'patch', data: payload });
diff --git a/config-ui/src/pages/blueprint/detail/configuration-panel.tsx b/config-ui/src/pages/blueprint/detail/configuration-panel.tsx
index 5dd944917..58eb17694 100644
--- a/config-ui/src/pages/blueprint/detail/configuration-panel.tsx
+++ b/config-ui/src/pages/blueprint/detail/configuration-panel.tsx
@@ -109,7 +109,7 @@ export const ConfigurationPanel = ({ from, blueprint, onRefresh, onChangeTab }:
   };
 
   const handleRun = async () => {
-    const [success] = await operator(() => API.runBlueprint(blueprint.id, false), {
+    const [success] = await operator(() => API.runBlueprint(blueprint.id, { skipCollectors: false, fullSync: false }), {
       setOperating,
       formatMessage: () => 'Trigger blueprint successful.',
     });
diff --git a/config-ui/src/pages/blueprint/detail/status-panel.tsx b/config-ui/src/pages/blueprint/detail/status-panel.tsx
index 11320384f..b0fbaa42a 100644
--- a/config-ui/src/pages/blueprint/detail/status-panel.tsx
+++ b/config-ui/src/pages/blueprint/detail/status-panel.tsx
@@ -18,10 +18,10 @@
 
 import { useState, useMemo } from 'react';
 import { useNavigate } from 'react-router-dom';
-import { Button, Switch, Icon, Intent, Position } from '@blueprintjs/core';
+import { Button, Switch, Intent, Position, Popover, Menu, MenuItem } from '@blueprintjs/core';
 import { Tooltip2 } from '@blueprintjs/popover2';
 
-import { Card, IconButton, Dialog } from '@/components';
+import { Card, IconButton, Dialog, Message } from '@/components';
 import { getCron } from '@/config';
 import { useAutoRefresh } from '@/hooks';
 import * as PipelineT from '@/routes/pipeline/types';
@@ -41,7 +41,7 @@ interface Props {
 }
 
 export const StatusPanel = ({ from, blueprint, pipelineId, onRefresh }: Props) => {
-  const [isOpen, setIsOpen] = useState(false);
+  const [type, setType] = useState<'delete' | 'fullSync'>();
   const [operating, setOperating] = useState(false);
 
   const navigate = useNavigate();
@@ -70,16 +70,18 @@ export const StatusPanel = ({ from, blueprint, pipelineId, onRefresh }: Props) =
     },
   );
 
-  const handleShowDeleteDialog = () => {
-    setIsOpen(true);
+  const handleResetType = () => {
+    setType(undefined);
   };
 
-  const handleHideDeleteDialog = () => {
-    setIsOpen(false);
-  };
-
-  const handleRun = async (skipCollectors: boolean) => {
-    const [success] = await operator(() => API.runBlueprint(blueprint.id, skipCollectors), {
+  const handleRun = async ({
+    skipCollectors = false,
+    fullSync = false,
+  }: {
+    skipCollectors?: boolean;
+    fullSync?: boolean;
+  }) => {
+    const [success] = await operator(() => API.runBlueprint(blueprint.id, { skipCollectors, fullSync }), {
       setOperating,
       formatMessage: () => 'Trigger blueprint successful.',
     });
@@ -134,7 +136,7 @@ export const StatusPanel = ({ from, blueprint, pipelineId, onRefresh }: Props) =
               loading={operating}
               intent={Intent.PRIMARY}
               text="Re-transform Data"
-              onClick={() => handleRun(true)}
+              onClick={() => handleRun({ skipCollectors: true })}
             />
           </Tooltip2>
           <Button
@@ -142,14 +144,24 @@ export const StatusPanel = ({ from, blueprint, pipelineId, onRefresh }: Props) =
             loading={operating}
             intent={Intent.PRIMARY}
             text="Collect All Data"
-            onClick={() => handleRun(false)}
+            onClick={() => handleRun({})}
           />
+          <Popover
+            content={
+              <Menu>
+                <MenuItem text="Collect All Data in Full Sync Mode" onClick={() => setType('fullSync')} />
+              </Menu>
+            }
+            placement="bottom"
+          >
+            <IconButton icon="more" tooltip="" />
+          </Popover>
         </S.ProjectACtion>
       )}
 
       {from === FromEnum.blueprint && (
         <S.BlueprintAction>
-          <Button text="Run Now" onClick={() => handleRun(false)} />
+          <Button text="Run Now" onClick={() => handleRun({})} />
           <Switch
             style={{ marginBottom: 0 }}
             label="Blueprint Enabled"
@@ -162,7 +174,7 @@ export const StatusPanel = ({ from, blueprint, pipelineId, onRefresh }: Props) =
             disabled={!!blueprint.projectName}
             icon="trash"
             tooltip="Delete Blueprint"
-            onClick={handleShowDeleteDialog}
+            onClick={() => setType('delete')}
           />
         </S.BlueprintAction>
       )}
@@ -193,24 +205,35 @@ export const StatusPanel = ({ from, blueprint, pipelineId, onRefresh }: Props) =
       </div>
       {/* </PipelineContextProvider> */}
 
-      <Dialog
-        isOpen={isOpen}
-        style={{ width: 820 }}
-        title="Are you sure you want to delete this Blueprint?"
-        okText="Confirm"
-        okLoading={operating}
-        onCancel={handleHideDeleteDialog}
-        onOk={handleDelete}
-      >
-        <S.DialogBody>
-          <Icon icon="warning-sign" />
-          <span>
-            Please note: deleting the Blueprint will not delete the historical data of the Data Scopes in this
-            Blueprint. If you would like to delete the historical data of Data Scopes, please visit the Connection page
-            and do so.
-          </span>
-        </S.DialogBody>
-      </Dialog>
+      {type === 'delete' && (
+        <Dialog
+          isOpen
+          style={{ width: 820 }}
+          title="Are you sure you want to delete this Blueprint?"
+          okText="Confirm"
+          okLoading={operating}
+          onCancel={handleResetType}
+          onOk={handleDelete}
+        >
+          <Message
+            content="Please note: deleting the Blueprint will not delete the historical data of the Data Scopes in this
+              Blueprint. If you would like to delete the historical data of Data Scopes, please visit the Connection
+              page and do so."
+          />
+        </Dialog>
+      )}
+
+      {type === 'fullSync' && (
+        <Dialog
+          isOpen
+          okText="Run Now"
+          okLoading={operating}
+          onCancel={handleResetType}
+          onOk={() => handleRun({ fullSync: true })}
+        >
+          <Message content="This operation may take a long time as it will empty all of your existing data and re-collect it." />
+        </Dialog>
+      )}
     </S.StatusPanel>
   );
 };