소스 검색

feat: new components for menus

hi-cactus! 3 년 전
부모
커밋
46b08ba5fd
51개의 변경된 파일1158개의 추가작업 그리고 634개의 파일을 삭제
  1. 22 0
      app/assets/images/dictionary.svg
  2. 15 0
      app/assets/images/dsrw.svg
  3. 22 0
      app/assets/images/gzzd.svg
  4. 22 0
      app/assets/images/jhfx.svg
  5. 22 0
      app/assets/images/kshzj.svg
  6. 4 29
      app/assets/images/logo_white.svg
  7. 22 0
      app/assets/images/sjkb.svg
  8. 22 0
      app/assets/images/sjy.svg
  9. 24 0
      app/assets/images/sjzc.svg
  10. 24 0
      app/assets/images/sjzl.svg
  11. 15 0
      app/assets/images/zljh.svg
  12. 1 1
      app/components/Navigator/Navigator.less
  13. 3 0
      app/components/Sidebar/Sidebar.less
  14. 3 3
      app/containers/App/index.tsx
  15. 3 1
      app/containers/Dashboard/Grid.tsx
  16. 3 1
      app/containers/Dashboard/index.tsx
  17. 35 35
      app/containers/DataGovernance/Sidebar.tsx
  18. 23 1
      app/containers/DataGovernance/index.tsx
  19. 7 0
      app/containers/DataGovernanceAuaitAnalysis/Loadable.tsx
  20. 13 0
      app/containers/DataGovernanceAuaitAnalysis/index.tsx
  21. 7 0
      app/containers/DataGovernanceMarkRule/Loadable.tsx
  22. 13 0
      app/containers/DataGovernanceMarkRule/index.tsx
  23. 7 0
      app/containers/DataGovernanceQualityAudit/Loadable.tsx
  24. 13 0
      app/containers/DataGovernanceQualityAudit/index.tsx
  25. 42 26
      app/containers/DataManager/Sidebar.tsx
  26. 20 43
      app/containers/DataManager/index.tsx
  27. 7 0
      app/containers/DataManagerDictionary/Loadable.tsx
  28. 91 0
      app/containers/DataManagerDictionary/index.tsx
  29. 7 0
      app/containers/DataManagerOverview/Loadable.tsx
  30. 56 0
      app/containers/DataManagerOverview/index.less
  31. 53 0
      app/containers/DataManagerOverview/index.tsx
  32. 3 15
      app/containers/DataShareService/Sidebar.tsx
  33. 26 20
      app/containers/DataShareService/index.tsx
  34. 5 0
      app/containers/Main/constants.ts
  35. 0 2
      app/containers/Main/index.tsx
  36. 208 199
      app/containers/Projects/List.tsx
  37. 11 1
      app/containers/Projects/hooks/projectPermission.tsx
  38. 5 0
      app/containers/Projects/types.ts
  39. 3 1
      app/containers/Schedule/Editor.tsx
  40. 43 41
      app/containers/Schedule/index.tsx
  41. 49 48
      app/containers/Source/index.tsx
  42. 82 57
      app/containers/View/Editor.tsx
  43. 43 37
      app/containers/View/index.tsx
  44. 7 7
      app/containers/Viz/DataVizList.tsx
  45. 3 1
      app/containers/Viz/Display/Editor.tsx
  46. 0 19
      app/containers/Viz/Loadable.tsx
  47. 3 1
      app/containers/Viz/Portal.tsx
  48. 3 3
      app/containers/Viz/dataShareServiceViz.tsx
  49. 42 41
      app/containers/Widget/List.tsx
  50. BIN
      app/favicon.ico
  51. 1 1
      app/index.html

+ 22 - 0
app/assets/images/dictionary.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>dictionary</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#BA8EEC" offset="0%"></stop>
+            <stop stop-color="#8B3CC4" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据管理" transform="translate(-44.000000, -392.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="dictionary" transform="translate(44.000000, 324.000000)">
+                    <circle id="椭圆形备份-3" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="数据字典-(1)" transform="translate(10.000000, 8.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M3,24 C1.344,24 0,22.656 0,21 L0,3 C0,1.344 1.344,0 3,0 L18,0 L18,3 L21,3 L21,24 L3,24 Z M7.5,12 L6,12 L6,15 L7.5,15 L7.5,12 Z M10.5,6 L9,6 L9,15 L10.5,15 L10.5,6 Z M13.5,9 L12,9 L12,15 L13.5,15 L13.5,9 Z M15,16.5 L4.5,16.5 L4.5,6 L3,6 L3,18 L15,18 L15,16.5 Z M19.5,4.5 L18,4.5 L18,21 L3.414,21 C3.936,21.894 4.89,22.5 6,22.5 L19.5,22.5 L19.5,4.5 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 15 - 0
app/assets/images/dsrw.svg


+ 22 - 0
app/assets/images/gzzd.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>gzzd</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#568ECF" offset="0%"></stop>
+            <stop stop-color="#2B55A2" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据治理" transform="translate(-44.000000, -92.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="gzzd" transform="translate(44.000000, 24.000000)">
+                    <circle id="椭圆形" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="调度规则制定" transform="translate(9.000000, 8.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M12.2122177,0.385037766 L20.1145938,4.94998804 C21.004474,5.4632073 21.5522085,6.41011184 21.5522085,7.43655037 L21.5522085,16.5634496 C21.5528329,17.5899331 21.0044837,18.5383826 20.1145938,19.050012 L12.2122177,23.6149622 C11.3236305,24.1283459 10.2285777,24.1283459 9.33999057,23.6149622 L1.43461317,19.050012 C0.546559869,18.5369368 -0.00031182821,17.589064 1.33396973e-07,16.5634496 L1.33396973e-07,7.43655037 C1.33396973e-07,6.41011184 0.546233633,5.4632073 1.43611381,4.94998804 L9.33999057,0.385037766 C10.2285777,-0.128345922 11.3236305,-0.128345922 12.2122177,0.385037766 Z M10.7746035,18.2216581 C14.2107303,18.2216581 16.9962615,15.4361269 16.9962615,12 C16.9962615,8.56387313 14.2107303,5.77834194 10.7746035,5.77834194 C7.33847661,5.77834194 4.55294541,8.56387313 4.55294541,12 C4.55294541,15.4361269 7.33847661,18.2216581 10.7746035,18.2216581 L10.7746035,18.2216581 Z M12.2122177,10.1332025 L12.2122177,8.26490426 L15.3215461,11.3772339 L9.7241547,11.3772339 L9.7241547,10.1317018 L12.2122177,10.1317018 L12.2122177,10.1332025 L12.2122177,10.1332025 Z M6.2276609,12.6212654 L11.8250523,12.6212654 L11.8250523,13.8667975 L9.34149121,13.8667975 L9.34149121,15.7335951 L6.2276609,12.6197648 L6.2276609,12.6212654 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 22 - 0
app/assets/images/jhfx.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>jhfx</title>
+    <defs>
+        <linearGradient x1="50%" y1="5.77972336%" x2="50%" y2="99.8185612%" id="linearGradient-1">
+            <stop stop-color="#FFD786" offset="0%"></stop>
+            <stop stop-color="#E98B3E" offset="99.9371722%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据治理" transform="translate(-44.000000, -292.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="jhfx" transform="translate(44.000000, 224.000000)">
+                    <circle id="椭圆形备份-2" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="市场分析" transform="translate(8.000000, 10.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M3.28028754,17.6608432 L5.64705287,17.6608432 C6.05987316,17.6608432 6.39445243,17.3251622 6.39445243,16.9111472 L6.39445243,6.3312649 C6.39445243,5.91714803 6.05982241,5.5815179 5.64705287,5.5815179 L3.28028754,5.5815179 C2.86746725,5.5815179 2.53288795,5.91719892 2.53288795,6.3312649 L2.53288795,16.9110963 C2.53283721,17.3251622 2.86746725,17.6608432 3.28028754,17.6608432 L3.28028754,17.6608432 Z M10.8836195,17.6608432 L13.2503847,17.6608432 C13.6632051,17.6608432 13.9977844,17.1701229 13.9977844,16.5647264 L13.9977844,1.0962187 C13.9977844,0.490771271 13.6631543,0 13.2503847,0 L10.8836195,0 C10.4708499,0 10.1362199,0.490771271 10.1362199,1.0962187 L10.1362199,16.5647264 C10.1362199,17.1701229 10.4707992,17.6608432 10.8836195,17.6608432 L10.8836195,17.6608432 Z M18.4869514,17.6608432 L20.8537167,17.6608432 C21.266537,17.6608432 21.6011163,17.2048871 21.6011163,16.6421951 L21.6011163,2.2682265 C21.6011163,1.70563629 21.2664863,1.24962927 20.8537167,1.24962927 L18.4869514,1.24962927 C18.0741311,1.24962927 17.7395518,1.70563629 17.7395518,2.2682265 L17.7395518,16.6421951 C17.739501,17.2048362 18.0741311,17.6608432 18.4869514,17.6608432 L18.4869514,17.6608432 Z M-4.43378667e-16,18.9104217 L24,18.9104217 L24,20.16 L-4.43378667e-16,20.16 L-4.43378667e-16,18.9104217 L-4.43378667e-16,18.9104217 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 22 - 0
app/assets/images/kshzj.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>kshzj</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#568ECF" offset="0%"></stop>
+            <stop stop-color="#2B55A2" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据开放服务" transform="translate(-44.000000, -92.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="kshzj" transform="translate(44.000000, 24.000000)">
+                    <circle id="椭圆形" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="可视化-组件" transform="translate(9.000000, 8.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M9.53906364,11.64 L0.539063642,6.84 C0.210597518,6.68947791 0,6.36131274 0,6 C0,5.63868726 0.210597518,5.31052209 0.539063642,5.16 L9.53906364,0.36 C10.3790636,-0.12 11.3390636,-0.12 12.1790636,0.36 L21.1790636,5.16 C21.8990636,5.52 21.8990636,6.48 21.1790636,6.84 L12.1790636,11.64 C11.3390636,12.12 10.3790636,12.12 9.53906364,11.64 L9.53906364,11.64 Z M18.2990636,15.6 L21.1790636,17.16 C21.8990636,17.52 21.8990636,18.48 21.1790636,18.84 L12.1790636,23.64 C11.3390636,24.12 10.3790636,24.12 9.53906364,23.64 L0.539063642,18.84 C0.210597518,18.6894779 0,18.3613127 0,18 C0,17.6386873 0.210597518,17.3105221 0.539063642,17.16 L3.41906364,15.6 L9.53906364,18.84 C10.2590636,19.2 11.2190636,19.32 11.9390636,18.96 L12.1790636,18.84 L18.2990636,15.6 L18.2990636,15.6 Z M18.2990636,9.6 L21.1790636,11.16 C21.8990636,11.52 21.8990636,12.48 21.1790636,12.84 L12.1790636,17.64 C11.3390636,18.12 10.3790636,18.12 9.53906364,17.64 L0.539063642,12.84 C0.210597518,12.6894779 0,12.3613127 0,12 C0,11.6386873 0.210597518,11.3105221 0.539063642,11.16 L3.41906364,9.6 L9.53906364,12.84 C10.2590636,13.2 11.2190636,13.32 11.9390636,12.96 L12.1790636,12.84 L18.2990636,9.6 L18.2990636,9.6 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 4 - 29
app/assets/images/logo_white.svg


+ 22 - 0
app/assets/images/sjkb.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>sjkb</title>
+    <defs>
+        <linearGradient x1="50%" y1="5.77972336%" x2="50%" y2="99.8185612%" id="linearGradient-1">
+            <stop stop-color="#FFD786" offset="0%"></stop>
+            <stop stop-color="#E98B3E" offset="99.9371722%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据开放服务" transform="translate(-44.000000, -192.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="sjkb" transform="translate(44.000000, 124.000000)">
+                    <circle id="椭圆形备份-2" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="数据看板" transform="translate(8.000000, 9.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M19,20 C19.5522275,20.0000809 19.9998534,20.4477725 19.9998534,21 C19.9998534,21.5522275 19.5522275,21.9999191 19,22 L5.00000001,22 C4.4477725,21.9999191 4.00014657,21.5522275 4.00014657,21 C4.00014657,20.4477725 4.4477725,20.0000809 5.00000001,20 L19,20 L19,20 Z M22,0 C23.1045695,0 24,0.8954305 24,2 L24,16 C24,17.1045695 23.1045695,18 22,18 L2,18 C0.8954305,18 0,17.1045695 0,16 L0,2 C0,0.8954305 0.8954305,0 2,0 L22,0 Z M20.495,3.005 L16,3.005 C15.4477725,3.005 15.0001466,3.45277249 15.0001466,4.005 C15.0001466,4.55722752 15.4477725,5.00491906 16,5.005 L18.58,5.00400001 L13,10.586 L9.06,6.646 C8.4743649,6.06109326 7.5256351,6.06109326 6.94000001,6.646 L2.29299999,11.293 C1.914028,11.6853789 1.91944793,12.3090846 2.30518164,12.6948184 C2.69091536,13.0805521 3.31462108,13.085972 3.707,12.707 L7.99999999,8.41400001 L11.94,12.354 C12.5256351,12.9389068 13.4743649,12.9389068 14.06,12.354 L19.995,6.41900001 L19.995,9 C19.9949476,9.3573005 20.1855351,9.68748219 20.4949577,9.86614756 C20.8043803,10.0448129 21.1856197,10.0448129 21.4950423,9.86614756 C21.8044649,9.68748219 21.995,9.3573005 21.995,9 L21.995,4.505 C21.995,3.67657288 21.3234271,3.005 20.495,3.005 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 22 - 0
app/assets/images/sjy.svg

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>sjy</title>
+    <defs>
+        <linearGradient x1="50%" y1="2.4085549%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#74BE80" offset="0%"></stop>
+            <stop stop-color="#21854B" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据管理" transform="translate(-44.000000, -192.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="sjy" transform="translate(44.000000, 124.000000)">
+                    <circle id="椭圆形备份-2" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="数据源" transform="translate(9.000000, 10.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M1.08,0 L22.92,0 C23.5165714,0 24,0.483428571 24,1.08 L24,4.79742856 C24,5.39389609 23.5164675,5.87742856 22.92,5.87742856 L1.08,5.87742856 C0.48353247,5.87742856 0,5.39389609 0,4.79742856 L0,1.08 C0,0.483428571 0.483428571,0 1.08,0 Z M1.08,7.34657143 L22.92,7.34657143 C23.5165714,7.34657143 24,7.83085715 24,8.42657143 L24,12.1448571 C24,12.7413247 23.5164675,13.2248571 22.92,13.2248571 L1.08,13.2248571 C0.48353247,13.2248571 0,12.7413247 0,12.1448571 L0,8.42571428 C0,7.83 0.483428571,7.34571428 1.08,7.34571428 L1.08,7.34657143 Z M1.08,14.694 L22.92,14.694 C23.5165714,14.694 24,15.1774286 24,15.774 L24,19.4914286 C24,20.0878961 23.5164675,20.5714286 22.92,20.5714286 L1.08,20.5714286 C0.48353247,20.5714286 0,20.0878961 0,19.4914286 L0,15.774 C0,15.1774286 0.483428571,14.694 1.08,14.694 Z M2.99999999,1.46914286 L2.99999999,4.40828572 L7.49999999,4.40828572 L7.49999999,1.46914286 L2.99999999,1.46914286 Z M2.99999999,8.81657142 L2.99999999,11.7548571 L7.49999999,11.7548571 L7.49999999,8.81657142 L2.99999999,8.81657142 L2.99999999,8.81657142 Z M2.99999999,16.1631428 L2.99999999,19.1022857 L7.49999999,19.1022857 L7.49999999,16.1631428 L2.99999999,16.1631428 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 24 - 0
app/assets/images/sjzc.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>sjzc</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#568ECF" offset="0%"></stop>
+            <stop stop-color="#2B55A2" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据管理" transform="translate(-44.000000, -292.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="sjzc" transform="translate(44.000000, 224.000000)">
+                    <circle id="椭圆形备份-3" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="敏感数据资产管理-02" transform="translate(9.000000, 8.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M0,3.77068966 C0,5.11782733 2.14522367,6.36263389 5.62758616,7.03620273 C9.10994865,7.70977158 13.4003962,7.70977158 16.8827587,7.03620273 C20.3651212,6.36263389 22.5103448,5.11782733 22.5103448,3.77068966 C22.5103448,1.68819526 17.4712325,0 11.2551724,0 C5.03911233,0 0,1.68819526 0,3.77068966 L0,3.77068966 Z M11.2551724,19.8853448 C5.03793103,19.8853448 1.77635684e-15,18.1965517 1.77635684e-15,16.1146552 L1.77635684e-15,20.2293103 C1.77635684e-15,22.3112069 5.03793103,24 11.2551724,24 C17.4724138,24 22.5103448,22.3112069 22.5103448,20.2293103 L22.5103448,16.1146552 C22.5103448,18.1965517 17.4724138,19.8853448 11.2551724,19.8853448 L11.2551724,19.8853448 Z M16.0112069,22.262069 C15.4862069,22.262069 15.0594828,21.8172414 15.0594828,21.2689655 C15.0594828,20.7206897 15.4862069,20.2758621 16.0112069,20.2758621 C16.5362069,20.2758621 16.962931,20.7206897 16.962931,21.2689655 C16.962931,21.8172414 16.5362069,22.262069 16.0112069,22.262069 Z" id="形状"></path>
+                        <path d="M11.2551724,14.4 C5.03793103,14.4 3.76342635e-15,12.7112069 3.76342635e-15,10.6293103 L3.76342635e-15,14.7439655 C3.76342635e-15,16.8258621 5.03793103,18.5146552 11.2551724,18.5146552 C17.4724138,18.5146552 22.5103448,16.8258621 22.5103448,14.7439655 L22.5103448,10.6293103 C22.5103448,12.7112069 17.4724138,14.4 11.2551724,14.4 Z M16.0112069,16.9655172 C15.4862069,16.9655172 15.0594828,16.5206897 15.0594828,15.9724138 C15.0594828,15.4241379 15.4862069,14.9793103 16.0112069,14.9793103 C16.5362069,14.9793103 16.962931,15.4241379 16.962931,15.9724138 C16.962931,16.5206897 16.5362069,16.9655172 16.0112069,16.9655172 Z" id="形状"></path>
+                        <path d="M11.2551724,8.91465517 C5.03793103,8.91465517 3.76342635e-15,7.22586207 3.76342635e-15,5.14396552 L3.76342635e-15,9.25862069 C3.76342635e-15,11.3405172 5.03793103,13.0293103 11.2551724,13.0293103 C17.4724138,13.0293103 22.5103448,11.3405172 22.5103448,9.25862069 L22.5103448,5.14396552 C22.5103448,7.22586207 17.4724138,8.91465517 11.2551724,8.91465517 L11.2551724,8.91465517 Z M16.0112069,11.6689655 C15.4862069,11.6689655 15.0594828,11.2241379 15.0594828,10.6758621 C15.0594828,10.1275862 15.4862069,9.68275862 16.0112069,9.68275862 C16.5362069,9.68275862 16.962931,10.1275862 16.962931,10.6758621 C16.962931,11.2241379 16.5362069,11.6689655 16.0112069,11.6689655 Z" id="形状"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 24 - 0
app/assets/images/sjzl.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>sjzl</title>
+    <defs>
+        <linearGradient x1="50%" y1="5.77972336%" x2="50%" y2="99.8185612%" id="linearGradient-1">
+            <stop stop-color="#FFD786" offset="0%"></stop>
+            <stop stop-color="#E98B3E" offset="99.9371722%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面展示" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="数据管理" transform="translate(-44.000000, -92.000000)">
+            <g id="左侧" transform="translate(0.000000, 68.000000)">
+                <g id="sjzl" transform="translate(44.000000, 24.000000)">
+                    <circle id="椭圆形" fill="url(#linearGradient-1)" cx="20" cy="20" r="20"></circle>
+                    <g id="总览" transform="translate(8.000000, 8.000000)" fill="#FFFFFF" fill-rule="nonzero">
+                        <path d="M19.95,3 C17.85,1.2 15,0 12,0 C9.45,0 7.2,0.75 5.25,2.1 L12,10.8 L19.95,3 L19.95,3 Z" id="路径"></path>
+                        <path d="M11.7,12.75 L4.05,3 C1.65,5.25 0,8.4 0,12 C0,18.6 5.4,24 12,24 C18.6,24 24,18.6 24,12 C24,11.85 24,11.55 24,11.4 L11.7,12.75 L11.7,12.75 Z" id="路径"></path>
+                        <path d="M23.85,9.9 C23.4,7.65 22.5,5.7 21,4.05 L14.1,10.95 L23.85,9.9 L23.85,9.9 Z" id="路径"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 15 - 0
app/assets/images/zljh.svg


+ 1 - 1
app/components/Navigator/Navigator.less

@@ -17,7 +17,7 @@
 }
 
 .logo {
-  width: 359px;
+  //width: 359px;
   height: 68px;
   padding-left: 15px;
   display: flex;

+ 3 - 0
app/components/Sidebar/Sidebar.less

@@ -58,5 +58,8 @@
     i {
       font-size: 30px;
     }
+    img {
+      height: 30px;
+    }
   }
 }

+ 3 - 3
app/containers/App/index.tsx

@@ -131,12 +131,12 @@ export class App extends React.PureComponent<AppProps> {
     return (
       <div>
         <Helmet
-          titleTemplate='%s - Davinci'
-          defaultTitle='Davinci Web Application'
+          titleTemplate='%s - 聚合平台'
+          defaultTitle='聚合平台'
           meta={[
             {
               name: 'description',
-              content: 'Davinci web application built for data visualization'
+              content: '聚合平台'
             }
           ]}
         />

+ 3 - 1
app/containers/Dashboard/Grid.tsx

@@ -826,7 +826,9 @@ export class Grid extends React.Component<IGridProps & RouteComponentWithParams,
     const { projectId, portalId, dashboardId } = this.props.match.params
     const editSign = [projectId, portalId, dashboardId, itemId].join(DEFAULT_SPLITER)
     sessionStorage.setItem('editWidgetFromDashboard', editSign)
-    this.props.history.push(`/project/${projectId}/widget/${widgetId}`)
+    const prefix = window.localStorage.getItem('inDataService') ?? ''
+    const prefixPath = prefix ? '/' + prefix : prefix
+    this.props.history.push(`/project/${projectId}${prefixPath}/widget/${widgetId}`)
   }
 
   private dataDrill = (drillDetail) => {

+ 3 - 1
app/containers/Dashboard/index.tsx

@@ -653,7 +653,9 @@ export class Dashboard extends React.Component<IDashboardProps, IDashboardStates
 
   private cancel = () => {
     const { history, match } = this.props
-    history.replace(`/project/${match.params.projectId}/vizs`)
+    const prefix = window.localStorage.getItem('inDataService') ?? ''
+    const prefixPath = prefix ? '/' + prefix : prefix
+    history.replace(`/project/${match.params.projectId}${prefixPath}/vizs`)
   }
 
   private initCheckNodes = (checkedKeys) => {

+ 35 - 35
app/containers/DataGovernance/Sidebar.tsx

@@ -34,6 +34,7 @@ import { IRouteParams } from 'utils/types'
 import useProjectPermission from '../Projects/hooks/projectPermission'
 
 import styles from '../Main/Main.less'
+import { IProjectPermission } from 'containers/Projects/types'
 
 const sidebarSource: Array<{
   icon: React.ReactNode
@@ -42,34 +43,22 @@ const sidebarSource: Array<{
   permissionName: typeof SidebarPermissions[number]
 }> = [
   {
-    icon: <i className='iconfont icon-dashboard' />,
-    name: '数据看板',
-    routes: ['vizs'],
-    permissionName: 'vizPermission'
+    icon: <img src={require('assets/images/gzzd.svg')} />,
+    name: '规则制定',
+    routes: ['makeRules'],
+    permissionName: 'makeRulePermission'
   },
   {
-    icon: <i className='iconfont icon-widget-gallery' />,
-    name: '可视化组件',
-    routes: ['widgets'],
-    permissionName: 'widgetPermission'
+    icon: <img src={require('assets/images/zljh.svg')} />,
+    name: '质量稽核',
+    routes: ['qualityAudits'],
+    permissionName: 'qualityAuditPermission'
   },
-  // {
-  //   icon: <i className='iconfont icon-custom-business' />,
-  //   name: '数据资产',
-  //   routes: ['views'],
-  //   permissionName: 'viewPermission'
-  // },
-  // {
-  //   icon: <i className='iconfont icon-datasource24' />,
-  //   name: '数据源',
-  //   routes: ['sources'],
-  //   permissionName: 'sourcePermission'
-  // },
   {
-    icon: <Icon type='clock-circle' />,
-    name: '定时任务',
-    routes: ['schedules'],
-    permissionName: 'schedulePermission'
+    icon: <img src={require('assets/images/jhfx.svg')} />,
+    name: '稽核分析',
+    routes: ['auditAnalysiss'],
+    permissionName: 'auditAnalysisPermission'
   }
 ]
 
@@ -86,27 +75,38 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
 
   const currentProject = useSelector(makeSelectCurrentProject())
 
+  // @ts-ignore
+  const nextPermission = useMemo<IProjectPermission>(() => ({
+      ...(currentProject?.permission ?? {}),
+      ...{
+        makeRulePermission: 3,
+        qualityAuditPermission: 3,
+        auditAnalysisPermission: 3
+      }
+    })
+    , [currentProject?.permission])
+
   useEffect(() => {
     if (!currentProject) {
       return
     }
-    const { id: projectId, permission } = currentProject
+    const { id: projectId } = currentProject
     const match = matchPath<IRouteParams>(pathname, {
-      path: `/project/:projectId/dataShareService`,
+      path: `/project/:projectId/dataGovernance`,
       exact: true,
       strict: false
     })
     if (match) {
       const hasPermission = SidebarPermissions.some((sidebarPermission) => {
-        if (permission[sidebarPermission] > 0) {
+        if (nextPermission[sidebarPermission] > 0) {
           const path = sidebarPermission.slice(0, -10)
-          history.replace(`/project/${projectId}/dataShareService/${path}s`)
+          history.replace(`/project/${projectId}/dataGovernance/${path}s`)
           return true
         }
       })
       !hasPermission && history.replace('/noAuthorization')
     }
-  }, [pathname, currentProject])
+  }, [pathname, currentProject?.id, nextPermission])
 
   const AuthorizedSidebarOptions = useProjectPermission(
     SidebarOption,
@@ -117,18 +117,18 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
     if (!currentProject) {
       return null
     }
-    const { id: projectId, permission } = currentProject
+    const { id: projectId } = currentProject
     const vizOnly = SidebarPermissions.every((permissionName) =>
       permissionName === 'vizPermission'
-        ? permission[permissionName]
-        : !permission[permissionName]
+        ? nextPermission[permissionName]
+        : !nextPermission[permissionName]
     )
     if (vizOnly) {
       return null
     }
     const sidebarOptions = sidebarSource.map(
       ({ permissionName, routes, icon, name }, idx) => {
-        if (!permission[permissionName]) {
+        if (!nextPermission[permissionName]) {
           return null
         }
 
@@ -142,13 +142,13 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
             projectId={projectId}
             icon={icon}
             name={name}
-            link={`/project/${projectId}/dataShareService/${routes[0]}`}
+            link={`/project/${projectId}/dataGovernance/${routes[0]}`}
           />
         )
       }
     )
     return <Sidebar>{sidebarOptions}</Sidebar>
-  }, [currentProject, pathname])
+  }, [currentProject?.id, nextPermission, pathname])
 
   return (
     <div className={styles.sidebar}>

+ 23 - 1
app/containers/DataGovernance/index.tsx

@@ -1,10 +1,32 @@
 import { Project } from 'containers/Projects/Loadable'
 import React from 'react'
+import { Route, Switch } from 'react-router-dom'
+import { DataGovernanceQualityAudit } from 'containers/DataGovernanceQualityAudit/Loadable'
+import { DataGovernanceMarkRule } from 'containers/DataGovernanceMarkRule/Loadable'
+import { DataGovernanceAuaitAnalysis } from 'containers/DataGovernanceAuaitAnalysis/Loadable'
+import { Sidebar } from 'containers/DataGovernance/Loadable'
 
 export default function DataGovernance() {
   return (
     <Project>
-
+      <Switch>
+        <Sidebar>
+          <Switch>
+            <Route
+              path="/project/:projectId/dataGovernance/makeRules"
+              component={DataGovernanceMarkRule}
+            />
+            <Route
+              path="/project/:projectId/dataGovernance/qualityAudits"
+              component={DataGovernanceQualityAudit}
+            />
+            <Route
+              path="/project/:projectId/dataGovernance/auditAnalysiss"
+              component={DataGovernanceAuaitAnalysis}
+            />
+          </Switch>
+        </Sidebar>
+      </Switch>
     </Project>
   )
 }

+ 7 - 0
app/containers/DataGovernanceAuaitAnalysis/Loadable.tsx

@@ -0,0 +1,7 @@
+import React from 'react'
+import loadable from 'utils/loadable'
+import { Skeleton } from 'antd'
+
+export const DataGovernanceAuaitAnalysis = loadable(() => import('./'), {
+  fallback: <Skeleton active paragraph={{ rows: 15 }} />
+})

+ 13 - 0
app/containers/DataGovernanceAuaitAnalysis/index.tsx

@@ -0,0 +1,13 @@
+import React from 'react'
+import Helmet from 'react-helmet'
+import Container, { ContainerBody } from 'components/Container'
+
+export default function DataGovernanceAuaitAnalysis() {
+  return (
+    <Container>
+      <Helmet title="稽核分析" />
+
+      <ContainerBody>稽核分析</ContainerBody>
+    </Container>
+  )
+}

+ 7 - 0
app/containers/DataGovernanceMarkRule/Loadable.tsx

@@ -0,0 +1,7 @@
+import React from 'react'
+import loadable from 'utils/loadable'
+import { Skeleton } from 'antd'
+
+export const DataGovernanceMarkRule = loadable(() => import('./'), {
+  fallback: <Skeleton active paragraph={{ rows: 15 }} />
+})

+ 13 - 0
app/containers/DataGovernanceMarkRule/index.tsx

@@ -0,0 +1,13 @@
+import React from 'react'
+import Container, { ContainerBody } from 'components/Container'
+import Helmet from 'react-helmet'
+
+export default function DataGovernance() {
+  return (
+    <Container>
+      <Helmet title="规则制定" />
+
+      <ContainerBody>规则制定</ContainerBody>
+    </Container>
+  )
+}

+ 7 - 0
app/containers/DataGovernanceQualityAudit/Loadable.tsx

@@ -0,0 +1,7 @@
+import React from 'react'
+import loadable from 'utils/loadable'
+import { Skeleton } from 'antd'
+
+export const DataGovernanceQualityAudit = loadable(() => import('./'), {
+  fallback: <Skeleton active paragraph={{ rows: 15 }} />
+})

+ 13 - 0
app/containers/DataGovernanceQualityAudit/index.tsx

@@ -0,0 +1,13 @@
+import React from 'react'
+import Container, { ContainerBody } from 'components/Container'
+import Helmet from 'react-helmet'
+
+export default function DataGovernanceQualityAudit() {
+  return (
+    <Container>
+      <Helmet title="质量稽核" />
+
+      <ContainerBody>质量稽核</ContainerBody>
+    </Container>
+  )
+}

+ 42 - 26
app/containers/DataManager/Sidebar.tsx

@@ -25,7 +25,6 @@ import { useLocation, matchPath, useHistory } from 'react-router-dom'
 import { showNavigator } from 'containers/App/actions'
 import { makeSelectCurrentProject } from 'containers/Projects/selectors'
 
-import { Icon } from 'antd'
 import SidebarOption from 'components/SidebarOption'
 import Sidebar from 'components/Sidebar'
 
@@ -34,6 +33,8 @@ import { IRouteParams } from 'utils/types'
 import useProjectPermission from '../Projects/hooks/projectPermission'
 
 import styles from '../Main/Main.less'
+import { IProjectPermission } from 'containers/Projects/types'
+import isEmpty from 'lodash/isEmpty'
 
 const sidebarSource: Array<{
   icon: React.ReactNode
@@ -42,35 +43,30 @@ const sidebarSource: Array<{
   permissionName: typeof SidebarPermissions[number]
 }> = [
   {
-    icon: <i className="iconfont icon-dashboard" />,
-    name: '数据看板',
-    routes: ['vizs'],
-    permissionName: 'vizPermission'
+    icon: <img src={require('assets/images/sjzl.svg')} />,
+    name: '数据总览',
+    routes: ['dataOverviiews'],
+    permissionName: 'dataOverviiewPermission'
   },
   {
-    icon: <i className="iconfont icon-widget-gallery" />,
-    name: '可视化组件',
-    routes: ['widgets'],
-    permissionName: 'widgetPermission'
-  },
-  {
-    icon: <i className="iconfont icon-custom-business" />,
+    icon: <img src={require('assets/images/sjzc.svg')} />,
     name: '数据资产',
     routes: ['views'],
     permissionName: 'viewPermission'
   },
   {
-    icon: <i className="iconfont icon-datasource24" />,
+    icon: <img src={require('assets/images/sjy.svg')} />,
     name: '数据源',
     routes: ['sources'],
     permissionName: 'sourcePermission'
   },
   {
-    icon: <Icon type="clock-circle" />,
-    name: '定时任务',
-    routes: ['schedules'],
-    permissionName: 'schedulePermission'
+    icon: <img src={require('assets/images/dictionary.svg')} />,
+    name: '数据字典',
+    routes: ['dataDictionarys'],
+    permissionName: 'dataDictionaryPermission'
   }
+
 ]
 
 const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
@@ -86,19 +82,35 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
 
   const currentProject = useSelector(makeSelectCurrentProject())
 
+  // @ts-ignore
+  const nextPermission = useMemo<IProjectPermission>(() => ({
+      ...(currentProject?.permission ?? {}),
+      ...{
+        dataOverviiewPermission: 3,
+        dataDictionaryPermission: 3,
+        makeRulePermission: 3,
+        qualityAuditPermission: 3,
+        auditAnalysisPermission: 3
+      }
+    })
+    , [currentProject?.permission])
+
   useEffect(() => {
     if (!currentProject) {
       return
     }
-    const { id: projectId, permission } = currentProject
+    const { id: projectId } = currentProject
     const match = matchPath<IRouteParams>(pathname, {
       path: `/project/:projectId/dataManager`,
       exact: true,
       strict: false
     })
+
     if (match) {
+
       const hasPermission = SidebarPermissions.some((sidebarPermission) => {
-        if (permission[sidebarPermission] > 0) {
+
+        if (nextPermission[sidebarPermission] > 0) {
           const path = sidebarPermission.slice(0, -10)
           history.replace(`/project/${projectId}/dataManager/${path}s`)
           return true
@@ -106,7 +118,7 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
       })
       !hasPermission && history.replace('/noAuthorization')
     }
-  }, [pathname, currentProject])
+  }, [pathname, currentProject?.id, nextPermission])
 
   const AuthorizedSidebarOptions = useProjectPermission(
     SidebarOption,
@@ -117,18 +129,21 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
     if (!currentProject) {
       return null
     }
-    const { id: projectId, permission } = currentProject
+    if (isEmpty(nextPermission)) {
+      return null
+    }
+    const { id: projectId } = currentProject
     const vizOnly = SidebarPermissions.every((permissionName) =>
       permissionName === 'vizPermission'
-        ? permission[permissionName]
-        : !permission[permissionName]
+        ? nextPermission[permissionName]
+        : !nextPermission[permissionName]
     )
     if (vizOnly) {
       return null
     }
     const sidebarOptions = sidebarSource.map(
-      ({ permissionName, routes, icon ,name}, idx) => {
-        if (!permission[permissionName]) {
+      ({ permissionName, routes, icon, name }, idx) => {
+        if (!nextPermission[permissionName]) {
           return null
         }
 
@@ -147,8 +162,9 @@ const MainSidebar: React.FC<PropsWithChildren<{}>> = (props) => {
         )
       }
     )
+    console.log(sidebarOptions)
     return <Sidebar>{sidebarOptions}</Sidebar>
-  }, [currentProject, pathname])
+  }, [currentProject?.id, nextPermission, pathname])
 
   return (
     <div className={styles.sidebar}>

+ 20 - 43
app/containers/DataManager/index.tsx

@@ -1,69 +1,46 @@
 import { Route, Switch } from 'react-router-dom'
-import { DataManagerViz as Viz } from 'containers/Viz/Loadable'
-import { DataManagerWidget as Widget, Workbench } from 'containers/Widget/Loadable'
+import { DataManagerWidget as Widget } from 'containers/Widget/Loadable'
 import { Sidebar } from './Loadable'
 import AuthorizedRoute from 'containers/Main/AuthorizedRoute'
-import { View, ViewEditor } from 'containers/View/Loadable'
+import { View } from 'containers/View/Loadable'
 import { Source } from 'containers/Source/Loadable'
-import { Schedule, ScheduleEditor } from 'containers/Schedule/Loadable'
 import { Project } from 'containers/Projects/Loadable'
-import React from 'react'
-import { Dashboard } from '../Dashboard/Loadable'
+import React, { useEffect } from 'react'
+import { DataOverview } from 'containers/DataManagerOverview/Loadable'
+import { DataDictionary } from '../DataManagerDictionary/Loadable'
 
 export default function DataManager() {
+  useEffect(() => {
+    window.localStorage.setItem('inDataService', 'dataManager')
+  }, [])
   return (
     <Project>
       <Switch>
-        <Route
-          path='/project/:projectId/dataManager/portal/:portalId'
-          component={Dashboard}
-        />
-        <Route
-          path='/project/:projectId/dataManager/display/:displayId'
-          component={Viz}
-        />
-        <Route
-          exact
-          path='/project/:projectId/dataManager/widget/:widgetId?'
-          component={Workbench}
-        />
-        <Route
-          exact
-          path='/project/:projectId/dataManager/view/:viewId?'
-          component={ViewEditor}
-        />
-        <Route
-          exact
-          path='/project/:projectId/dataManager/schedule/:scheduleId?'
-          component={ScheduleEditor}
-        />
         <Sidebar>
           <Switch>
-            <AuthorizedRoute
-              permission='vizPermission'
-              path='/project/:projectId/dataManager/vizs'
-              component={Viz}
+            <Route
+              path="/project/:projectId/dataManager/dataOverviiews"
+              component={DataOverview}
             />
             <AuthorizedRoute
-              permission='widgetPermission'
-              path='/project/:projectId/dataManager/widgets'
+              permission="widgetPermission"
+              path="/project/:projectId/dataManager/widgets"
               component={Widget}
             />
             <AuthorizedRoute
               exact
-              permission='viewPermission'
-              path='/project/:projectId/dataManager/views'
+              permission="viewPermission"
+              path="/project/:projectId/dataManager/views"
               component={View}
             />
             <AuthorizedRoute
-              permission='sourcePermission'
-              path='/project/:projectId/dataManager/sources'
+              permission="sourcePermission"
+              path="/project/:projectId/dataManager/sources"
               component={Source}
             />
-            <AuthorizedRoute
-              permission='schedulePermission'
-              path='/project/:projectId/dataManager/schedules'
-              component={Schedule}
+            <Route
+              path="/project/:projectId/dataManager/dataDictionarys"
+              component={DataDictionary}
             />
           </Switch>
         </Sidebar>

+ 7 - 0
app/containers/DataManagerDictionary/Loadable.tsx

@@ -0,0 +1,7 @@
+import React from 'react'
+import loadable from 'utils/loadable'
+import { Skeleton } from 'antd'
+
+export const DataDictionary = loadable(() => import('./'), {
+  fallback: <Skeleton active paragraph={{ rows: 15 }} />
+})

+ 91 - 0
app/containers/DataManagerDictionary/index.tsx

@@ -0,0 +1,91 @@
+import React, { useEffect, useState } from 'react'
+import Helmet from 'react-helmet'
+import Container, { ContainerBody } from 'components/Container'
+import Box from 'components/Box'
+import { Col, Icon, Row, Table, Tooltip } from 'antd'
+import { PaginationConfig } from 'antd/lib/table'
+import { compose } from 'redux'
+
+function DataDictionary() {
+  const [screenWidth, setScreenWidth] = useState(
+    document.documentElement.clientWidth
+  )
+
+  const handleSetScreenWidth = () => {
+    setScreenWidth(document.documentElement.clientWidth)
+  }
+  const basePagination: PaginationConfig = {
+    defaultPageSize: 20,
+    showSizeChanger: true
+  }
+  const tablePagination: PaginationConfig = {
+    ...basePagination,
+    simple: screenWidth <= 768
+  }
+  useEffect(() => {
+    window.addEventListener('resize', handleSetScreenWidth, false)
+    return () =>
+      window.removeEventListener('resize', handleSetScreenWidth, false)
+  }, [])
+  return (
+    <Container>
+      <Helmet title="数据字典" />
+
+      <ContainerBody>
+        <Box>
+          <Box.Header>
+            <Box.Title>
+              <Icon type="bars" />
+              数据字典列表
+            </Box.Title>
+            <Box.Tools>
+              <Tooltip placement="bottom" title="新增">
+                {/* <AdminButton */}
+                {/*  type="primary" */}
+                {/*  icon="plus" */}
+                {/*  onClick={this.addView} */}
+                {/* /> */}
+              </Tooltip>
+            </Box.Tools>
+          </Box.Header>
+          <Box.Body>
+            <Row>
+              <Col span={24}>
+                <Table
+                  bordered
+                  rowKey="id"
+                  // loading={loading.view}
+                  // dataSource={filterViews}
+                  // columns={tableColumns}
+                  pagination={tablePagination}
+                  // onChange={this.tableChange}
+                />
+              </Col>
+            </Row>
+          </Box.Body>
+        </Box>
+      </ContainerBody>
+    </Container>
+  )
+}
+
+// const mapDispatchToProps = (dispatch: Dispatch<ViewActionType>) => ({
+//   onLoadViews: (projectId) => dispatch(ViewActions.loadViews(projectId)),
+//   onDeleteView: (viewId, resolve) => dispatch(ViewActions.deleteView(viewId, resolve)),
+//   onCopyView: (view, resolve) => dispatch(ViewActions.copyView(view, resolve)),
+//   onCheckName: (data, resolve, reject) => dispatch(checkNameUniqueAction('view', data, resolve, reject))
+// })
+//
+// const mapStateToProps = createStructuredSelector({
+//   views: makeSelectViews(),
+//   currentProject: makeSelectCurrentProject(),
+//   loading: makeSelectLoading()
+// })
+// const withConnect = connect<IViewListStateProps, IViewListDispatchProps, RouteComponentWithParams>(mapStateToProps, mapDispatchToProps)
+// const withReducer = injectReducer({ key: 'view', reducer })
+// const withSaga = injectSaga({ key: 'view', saga: sagas })
+
+export default compose()(DataDictionary)
+// withReducer,
+// withSaga,
+// withConnect

+ 7 - 0
app/containers/DataManagerOverview/Loadable.tsx

@@ -0,0 +1,7 @@
+import React from 'react'
+import loadable from 'utils/loadable'
+import { Skeleton } from 'antd'
+
+export const DataOverview = loadable(() => import('./'), {
+  fallback: <Skeleton active paragraph={{ rows: 15 }} />
+})

+ 56 - 0
app/containers/DataManagerOverview/index.less

@@ -0,0 +1,56 @@
+@import "~assets/less/variable";
+
+.overview-container {
+  padding: 20px;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+
+
+  .charts {
+    margin-top: 20px;
+    flex: 1;
+    display: flex;
+    > div {
+      flex: 1;
+      background-color: #fff;
+      margin-right: 20px;
+      padding: 20px;
+      &:last-child {
+        margin-right: 0;
+      }
+      .chart-title {
+        font-size: 16px;
+      }
+      .chart-desc {
+        font-size: 12px;
+        opacity: .8;
+      }
+    }
+  }
+
+  .card-list {
+    display: flex;
+    width: 100%;
+    justify-content: space-between;
+    .item {
+      background-color: #fff;
+      height: 120px;
+      padding: 10px 20px;
+      flex: 1;
+      margin-right: 20px;
+      &:last-child {
+        margin-right: 0;
+      }
+      .title {
+        font-size: 16px;
+        padding-bottom: 10px;
+      }
+      .num {
+        font-size: 24px  ;
+        font-weight: bold;
+        color: @blue;
+      }
+    }
+  }
+}

+ 53 - 0
app/containers/DataManagerOverview/index.tsx

@@ -0,0 +1,53 @@
+import React from 'react'
+import Helmet from 'react-helmet'
+import Container from 'components/Container'
+import styles from './index.less'
+// const styles = require('./index.less')
+
+export default function DataOverview() {
+  return (
+    <Container>
+      <Helmet title="数据总览" />
+
+      <div className={styles['overview-container']}>
+        <div className={styles['card-list']}>
+          {[
+            {
+              title: '数据资源数量',
+              num: 131
+            },
+            {
+              title: '来源部门数量',
+              num: 9
+            },
+            {
+              title: '来源系统数量',
+              num: 10
+            },
+            {
+              title: '近一月目录新增数量',
+              num: 3
+            }
+          ].map((item) => (
+            <div className={styles.item} key={item.title}>
+              <div className={styles.title}>{item.title}</div>
+              <div>
+                <span className={styles.num}>{item.num}</span> 个
+              </div>
+            </div>
+          ))}
+        </div>
+        <div className={styles.charts}>
+          <div>
+            <div className={styles['chart-title']}>行业分类</div>
+            <div className={styles['chart-desc']}>资源目录各行业资源数量</div>
+          </div>
+          <div>
+            <div className={styles['chart-title']}>数据资源来源部门</div>
+            <div className={styles['chart-desc']}>数据资源来源部门TOP10</div>
+          </div>
+        </div>
+      </div>
+    </Container>
+  )
+}

+ 3 - 15
app/containers/DataShareService/Sidebar.tsx

@@ -42,31 +42,19 @@ const sidebarSource: Array<{
   permissionName: typeof SidebarPermissions[number]
 }> = [
   {
-    icon: <i className='iconfont icon-dashboard' />,
+    icon: <img src={require('assets/images/sjkb.svg')} />,
     name: '数据看板',
     routes: ['vizs'],
     permissionName: 'vizPermission'
   },
   {
-    icon: <i className='iconfont icon-widget-gallery' />,
+    icon: <img src={require('assets/images/kshzj.svg')} />,
     name: '可视化组件',
     routes: ['widgets'],
     permissionName: 'widgetPermission'
   },
-  // {
-  //   icon: <i className='iconfont icon-custom-business' />,
-  //   name: '数据资产',
-  //   routes: ['views'],
-  //   permissionName: 'viewPermission'
-  // },
-  // {
-  //   icon: <i className='iconfont icon-datasource24' />,
-  //   name: '数据源',
-  //   routes: ['sources'],
-  //   permissionName: 'sourcePermission'
-  // },
   {
-    icon: <Icon type='clock-circle' />,
+    icon: <img src={require('assets/images/dsrw.svg')} />,
     name: '定时任务',
     routes: ['schedules'],
     permissionName: 'schedulePermission'

+ 26 - 20
app/containers/DataShareService/index.tsx

@@ -1,68 +1,74 @@
 import { Route, Switch } from 'react-router-dom'
-import { DataShareServiceViz as Viz } from 'containers/Viz/Loadable'
-import { DataShareServiceWidget as Widget, Workbench } from 'containers/Widget/Loadable'
+import { DataShareServiceViz } from 'containers/Viz/Loadable'
+import {
+  DataShareServiceWidget as Widget,
+  Workbench
+} from 'containers/Widget/Loadable'
 import { Sidebar } from './Loadable'
 import AuthorizedRoute from 'containers/Main/AuthorizedRoute'
 import { View, ViewEditor } from 'containers/View/Loadable'
 import { Source } from 'containers/Source/Loadable'
 import { Schedule, ScheduleEditor } from 'containers/Schedule/Loadable'
 import { Project } from 'containers/Projects/Loadable'
-import React from 'react'
+import React, { useEffect } from 'react'
 import { Dashboard } from '../Dashboard/Loadable'
 
 export default function DataShareService() {
+  useEffect(() => {
+    window.localStorage.setItem('inDataService', 'dataShareService')
+  }, [])
   return (
     <Project>
       <Switch>
         <Route
-          path='/project/:projectId/dataShareService/portal/:portalId'
+          path="/project/:projectId/dataShareService/portal/:portalId"
           component={Dashboard}
         />
         <Route
-          path='/project/:projectId/dataShareService/display/:displayId'
-          component={Viz}
+          path="/project/:projectId/dataShareService/display/:displayId"
+          component={DataShareServiceViz}
         />
         <Route
           exact
-          path='/project/:projectId/dataShareService/widget/:widgetId?'
+          path="/project/:projectId/dataShareService/widget/:widgetId?"
           component={Workbench}
         />
         <Route
           exact
-          path='/project/:projectId/dataShareService/view/:viewId?'
+          path="/project/:projectId/dataShareService/view/:viewId?"
           component={ViewEditor}
         />
         <Route
           exact
-          path='/project/:projectId/dataShareService/schedule/:scheduleId?'
+          path="/project/:projectId/dataShareService/schedule/:scheduleId?"
           component={ScheduleEditor}
         />
         <Sidebar>
           <Switch>
             <AuthorizedRoute
-              permission='vizPermission'
-              path='/project/:projectId/dataShareService/vizs'
-              component={Viz}
+              permission="vizPermission"
+              path="/project/:projectId/dataShareService/vizs"
+              component={DataShareServiceViz}
             />
             <AuthorizedRoute
-              permission='widgetPermission'
-              path='/project/:projectId/dataShareService/widgets'
+              permission="widgetPermission"
+              path="/project/:projectId/dataShareService/widgets"
               component={Widget}
             />
             <AuthorizedRoute
               exact
-              permission='viewPermission'
-              path='/project/:projectId/dataShareService/views'
+              permission="viewPermission"
+              path="/project/:projectId/dataShareService/views"
               component={View}
             />
             <AuthorizedRoute
-              permission='sourcePermission'
-              path='/project/:projectId/dataShareService/sources'
+              permission="sourcePermission"
+              path="/project/:projectId/dataShareService/sources"
               component={Source}
             />
             <AuthorizedRoute
-              permission='schedulePermission'
-              path='/project/:projectId/dataShareService/schedules'
+              permission="schedulePermission"
+              path="/project/:projectId/dataShareService/schedules"
               component={Schedule}
             />
           </Switch>

+ 5 - 0
app/containers/Main/constants.ts

@@ -21,6 +21,11 @@
 import { IProjectPermission } from 'containers/Projects/types'
 
 export const SidebarPermissions: Array<keyof IProjectPermission> = [
+  'dataOverviiewPermission',
+  'dataDictionaryPermission',
+  'makeRulePermission',
+  'qualityAuditPermission',
+  'auditAnalysisPermission',
   'vizPermission',
   'widgetPermission',
   'viewPermission',

+ 0 - 2
app/containers/Main/index.tsx

@@ -192,11 +192,9 @@ export class Main extends React.Component<IMainProps, {}> {
                   component={DataShareService}
                 />
                 <Route
-                  exact
                   path='/project/:projectId/dataGovernance'
                   component={DataGovernance}
                 />
-
                 {/* </Switch> */}
               </Route>
             </Switch>

+ 208 - 199
app/containers/Projects/List.tsx

@@ -30,7 +30,7 @@ import React, {
 import classnames from 'classnames'
 import { connect } from 'react-redux'
 import { Row, Col, Tooltip, Popconfirm, Icon, Modal, Button } from 'antd'
-const styles = require('../Organizations/Project.less')
+
 
 import saga from './sagas'
 import reducer from './reducer'
@@ -56,9 +56,9 @@ import { makeSelectOrganizations } from '../Organizations/selectors'
 import { checkNameUniqueAction } from '../App/actions'
 import ComponentPermission from '../Account/components/checkMemberPermission'
 import Star from 'components/StarPanel/Star'
-const StarUserModal = Star.StarUser
+
 import HistoryStack from '../Organizations/component/historyStack'
-const historyStack = new HistoryStack()
+
 import { RouteComponentWithParams } from 'utils/types'
 import {
   IProject,
@@ -74,6 +74,10 @@ import { uuid } from 'app/utils/util'
 import { useResize } from './hooks/useResize'
 import ProjectItem from './component/ProjectItem'
 
+const StarUserModal = Star.StarUser
+const historyStack = new HistoryStack()
+const styles = require('../Organizations/Project.less')
+
 function enhanceInput(props, ref) {
   const inputRef = useRef(null)
   useImperativeHandle(ref, () => ({}))
@@ -135,18 +139,18 @@ const Toolbar: React.FC<IToolbarProps> = React.memo(
         <div className={styles.menu}>{menus}</div>
         <div className={styles.searchs}>
           <EnhanceInput
-            type="text"
+            type='text'
             ref={searchRef}
             val={searchKeywords}
             onChange={getKeywords}
-            placeholder="查找您的项目"
+            placeholder='查找您的项目'
           />
           <span className={styles.searchButton}>
-            <i className="iconfont icon-search" />
+            <i className='iconfont icon-search' />
           </span>
         </div>
         <div className={styles.create}>
-          <Button icon="plus" type="primary" shape="round" onClick={addPro}>
+          <Button icon='plus' type='primary' shape='round' onClick={addPro}>
             {documentWidth < 860 ? '' : '创建'}
           </Button>
         </div>
@@ -162,28 +166,26 @@ function stopPPG(e: React.MouseEvent<HTMLElement>) {
   return
 }
 
-const Projects: React.FC<
-  IProjectsProps & RouteComponentWithParams
-> = React.memo(
+const Projects: React.FC<IProjectsProps & RouteComponentWithParams> = React.memo(
   ({
-    projects,
-    onLoadProjects,
-    onLoadOrganizations,
-    organizations,
-    loginUser,
-    onLoadCollectProjects,
-    collectProjects,
-    history,
-    onAddProject,
-    onCheckUniqueName,
-    onTransferProject,
-    onDeleteProject,
-    onClickCollectProjects,
-    starUserList,
-    onStarProject,
-    onGetProjectStarUser,
-    onEditProject
-  }) => {
+     projects,
+     onLoadProjects,
+     onLoadOrganizations,
+     organizations,
+     loginUser,
+     onLoadCollectProjects,
+     collectProjects,
+     history,
+     onAddProject,
+     onCheckUniqueName,
+     onTransferProject,
+     onDeleteProject,
+     onClickCollectProjects,
+     starUserList,
+     onStarProject,
+     onGetProjectStarUser,
+     onEditProject
+   }) => {
     const [formKey, setFormKey] = useState(() => uuid(8, 16))
     const [projectType, setProjectType] = useState('all')
 
@@ -216,6 +218,10 @@ const Projects: React.FC<
     let proForm: FormComponentProps<IProjectFormFieldProps> = null
 
     useEffect(() => {
+      window.localStorage.setItem('inDataService', '')
+    }, [])
+
+    useEffect(() => {
       if (onLoadProjects) {
         onLoadProjects()
       }
@@ -363,6 +369,7 @@ const Projects: React.FC<
 
     const getProjectsBySearch = useMemo(() => {
       const { proIdList } = historyStack.getAll()
+
       function filterByKeyword(arr: IProject[]) {
         return (
           Array.isArray(arr) &&
@@ -373,7 +380,7 @@ const Projects: React.FC<
         )
       }
 
-      function filterByProjectType (arr: IProject[]) {
+      function filterByProjectType(arr: IProject[]) {
         if (Array.isArray(arr)) {
           switch (projectType) {
             case 'create':
@@ -389,7 +396,9 @@ const Projects: React.FC<
             case 'history':
               return proIdList.reduce((iteratee, pid) => {
                 const pl = arr.find((pro) => pro.id === pid)
-                if (pl) {iteratee.push(pl) }
+                if (pl) {
+                  iteratee.push(pl)
+                }
                 return iteratee
               }, [])
             case 'all':
@@ -407,11 +416,11 @@ const Projects: React.FC<
           collectProjects.map((col) => col.id)
         return Array.isArray(arr)
           ? arr.map((pro) => {
-              return favoriteProjectsId.includes &&
-                favoriteProjectsId.includes(pro.id)
-                ? { ...pro, isFavorites: true }
-                : pro
-            })
+            return favoriteProjectsId.includes &&
+            favoriteProjectsId.includes(pro.id)
+              ? { ...pro, isFavorites: true }
+              : pro
+          })
           : []
       }
 
@@ -426,196 +435,196 @@ const Projects: React.FC<
     const ProjectItems: ReactElement[] = useMemo(() => {
       const items = Array.isArray(projects)
         ? getProjectsBySearch.map((pro: IProject, index) => {
-            const {
-              pic,
-              name,
-              description,
-              createBy,
-              isStar,
-              isFavorites,
-              id,
-              starNum,
-              orgId
-            } = pro
-
-            const isMimePro = !!(createBy && createBy.id === loginUserId)
-
-            const getTagType = (function (mime, favorite) {
-              const tagType = []
-
-              if (mime) {
-                tagType.push({
-                  text: '创建',
-                  color: '#108EE9'
-                })
-              } else {
-                tagType.push({
-                  text: '参与',
-                  color: '#FA8C15'
-                })
-              }
-              return tagType
-            })(isMimePro, isFavorites)
-
-            const starProject = (id) => () => {
-              onStarProject(id, () => {
-                if (onLoadProjects) {
-                  onLoadProjects()
-                }
+          const {
+            pic,
+            name,
+            description,
+            createBy,
+            isStar,
+            isFavorites,
+            id,
+            starNum,
+            orgId
+          } = pro
+
+          const isMimePro = !!(createBy && createBy.id === loginUserId)
+
+          const getTagType = (function(mime, favorite) {
+            const tagType = []
+
+            if (mime) {
+              tagType.push({
+                text: '创建',
+                color: '#108EE9'
+              })
+            } else {
+              tagType.push({
+                text: '参与',
+                color: '#FA8C15'
               })
             }
+            return tagType
+          })(isMimePro, isFavorites)
 
-            const toProject = () => {
-              history.push(`/project/${id}`)
-              saveHistory(pro)
-            }
+          const starProject = (id) => () => {
+            onStarProject(id, () => {
+              if (onLoadProjects) {
+                onLoadProjects()
+              }
+            })
+          }
+
+          const toProject = () => {
+            history.push(`/project/${id}`)
+            saveHistory(pro)
+          }
 
-            const saveHistory = (pro) => historyStack.pushNode(pro)
+          const saveHistory = (pro) => historyStack.pushNode(pro)
 
-            const currentOrganization: IOrganization = organizations.find(
-              (org) => org.id === orgId
-            )
+          const currentOrganization: IOrganization = organizations.find(
+            (org) => org.id === orgId
+          )
 
-            const CreateButton = ComponentPermission(
-              currentOrganization,
-              ''
-            )(Icon)
+          const CreateButton = ComponentPermission(
+            currentOrganization,
+            ''
+          )(Icon)
 
-            const isHistoryType = !!(projectType && projectType === 'history')
+          const isHistoryType = !!(projectType && projectType === 'history')
 
-            const favoriteProject = (e: React.MouseEvent<HTMLElement>) => {
-              const { id, isFavorites } = pro
-              stopPPG(e)
-              if (favoritePro) {
-                favoritePro(id, isFavorites)
-              }
+          const favoriteProject = (e: React.MouseEvent<HTMLElement>) => {
+            const { id, isFavorites } = pro
+            stopPPG(e)
+            if (favoritePro) {
+              favoritePro(id, isFavorites)
             }
+          }
 
-            const transferPro = (e: React.MouseEvent<HTMLElement>) => {
-              stopPPG(e)
-              if (showProForm) {
-                showProForm('transfer', pro, e)
-              }
+          const transferPro = (e: React.MouseEvent<HTMLElement>) => {
+            stopPPG(e)
+            if (showProForm) {
+              showProForm('transfer', pro, e)
             }
+          }
 
-            const editPro = (e: React.MouseEvent<HTMLElement>) => {
-              stopPPG(e)
-              if (showProForm) {
-                showProForm('edit', pro, e)
-              }
+          const editPro = (e: React.MouseEvent<HTMLElement>) => {
+            stopPPG(e)
+            if (showProForm) {
+              showProForm('edit', pro, e)
             }
+          }
 
-            const deleteProject = (e: React.MouseEvent<HTMLElement>) => {
-              const { id, isFavorites } = pro
-              if (deletePro) {
-                deletePro(id, isFavorites)
-              }
-              stopPPG(e)
+          const deleteProject = (e: React.MouseEvent<HTMLElement>) => {
+            const { id, isFavorites } = pro
+            if (deletePro) {
+              deletePro(id, isFavorites)
             }
+            stopPPG(e)
+          }
 
-            const { Favorite, Transfer, Edit, Delete } = (function () {
-              const favoriteClassName = classnames({
-                [styles.ft16]: true,
-                [styles.mainColor]: isFavorites
-              })
+          const { Favorite, Transfer, Edit, Delete } = (function() {
+            const favoriteClassName = classnames({
+              [styles.ft16]: true,
+              [styles.mainColor]: isFavorites
+            })
 
-              const themeFavorite = isFavorites ? 'filled' : 'outlined'
+            const themeFavorite = isFavorites ? 'filled' : 'outlined'
+
+            const Favorite = !isMimePro ? (
+              <Tooltip title='收藏'>
+                <Icon
+                  type='heart'
+                  theme={themeFavorite}
+                  className={favoriteClassName}
+                  onClick={favoriteProject}
+                />
+              </Tooltip>
+            ) : (
+              []
+            )
 
-              const Favorite = !isMimePro ? (
-                <Tooltip title="收藏">
-                  <Icon
-                    type="heart"
-                    theme={themeFavorite}
-                    className={favoriteClassName}
-                    onClick={favoriteProject}
-                  />
-                </Tooltip>
-              ) : (
-                []
-              )
+            const Transfer = (
+              <Tooltip title='移交'>
+                <CreateButton
+                  type='swap'
+                  className={styles.ft16}
+                  onClick={transferPro}
+                />
+              </Tooltip>
+            )
 
-              const Transfer = (
-                <Tooltip title="移交">
-                  <CreateButton
-                    type="swap"
-                    className={styles.ft16}
-                    onClick={transferPro}
-                  />
-                </Tooltip>
-              )
+            const Edit = (
+              <Tooltip title='编辑'>
+                <CreateButton
+                  type='form'
+                  className={styles.ft16}
+                  onClick={editPro}
+                />
+              </Tooltip>
+            )
 
-              const Edit = (
-                <Tooltip title="编辑">
+            const Delete = (
+              <Popconfirm
+                title='确定删除?'
+                placement='bottom'
+                onCancel={stopPPG}
+                onConfirm={deleteProject}
+              >
+                <Tooltip title='删除'>
                   <CreateButton
-                    type="form"
+                    type='delete'
                     className={styles.ft16}
-                    onClick={editPro}
+                    onClick={stopPPG}
                   />
                 </Tooltip>
-              )
-
-              const Delete = (
-                <Popconfirm
-                  title="确定删除?"
-                  placement="bottom"
-                  onCancel={stopPPG}
-                  onConfirm={deleteProject}
-                >
-                  <Tooltip title="删除">
-                    <CreateButton
-                      type="delete"
-                      className={styles.ft16}
-                      onClick={stopPPG}
-                    />
-                  </Tooltip>
-                </Popconfirm>
-              )
+              </Popconfirm>
+            )
 
-              return {
-                Edit,
-                Favorite,
-                Transfer,
-                Delete
-              }
-            })()
-
-            return (
-              <Col
-                key={`pro${name}${uuid(8, 16)}orp${description}`}
-                xxl={4}
-                xl={6}
-                lg={6}
-                md={8}
-                sm={12}
-                xs={24}
+            return {
+              Edit,
+              Favorite,
+              Transfer,
+              Delete
+            }
+          })()
+
+          return (
+            <Col
+              key={`pro${name}${uuid(8, 16)}orp${description}`}
+              xxl={4}
+              xl={6}
+              lg={6}
+              md={8}
+              sm={12}
+              xs={24}
+            >
+              <ProjectItem
+                title={name}
+                tags={getTagType}
+                onClick={toProject}
+                description={description}
+                key={`projectItem${uuid}`}
+                backgroundImg={`url(${require(`assets/images/bg${pic}.png`)})`}
               >
-                <ProjectItem
-                  title={name}
-                  tags={getTagType}
-                  onClick={toProject}
-                  description={description}
-                  key={`projectItem${uuid}`}
-                  backgroundImg={`url(${require(`assets/images/bg${pic}.png`)})`}
-                >
-                  <div className={styles.others}>
-                    {!isHistoryType ? Edit : ''}
-                    {Favorite}
-                    {!isHistoryType ? Transfer : ''}
-                    {!isHistoryType ? Delete : ''}
-                  </div>
-                  <div className={styles.stars}>
-                    <Star
-                      proId={id}
-                      starNum={starNum}
-                      isStar={isStar}
-                      unStar={starProject}
-                      userList={getStarProjectUserList}
-                    />
-                  </div>
-                </ProjectItem>
-              </Col>
-            )
-          })
+                <div className={styles.others}>
+                  {!isHistoryType ? Edit : ''}
+                  {Favorite}
+                  {!isHistoryType ? Transfer : ''}
+                  {!isHistoryType ? Delete : ''}
+                </div>
+                <div className={styles.stars}>
+                  <Star
+                    proId={id}
+                    starNum={starNum}
+                    isStar={isStar}
+                    unStar={starProject}
+                    userList={getStarProjectUserList}
+                  />
+                </div>
+              </ProjectItem>
+            </Col>
+          )
+        })
         : []
 
       return items

+ 11 - 1
app/containers/Projects/hooks/projectPermission.tsx

@@ -45,7 +45,17 @@ function useProjectPermission<T>(
       return () => null
     }
     const { permission } = currentProject
-    const typePermission = permission[permissionName]
+    const nextPermission = ({
+      ...(currentProject?.permission ?? {}),
+      ...{
+        dataOverviiewPermission: 3,
+        dataDictionaryPermission: 3,
+        makeRulePermission: 3,
+        qualityAuditPermission: 3,
+        auditAnalysisPermission: 3
+      }
+    })
+    const typePermission = nextPermission[permissionName]
     if (!typePermission) {
       return () => null
     }

+ 5 - 0
app/containers/Projects/types.ts

@@ -27,6 +27,11 @@ export interface IProjectPermission {
   viewPermission: number
   vizPermission: number
   widgetPermission: number
+  dataOverviiewPermission: number
+  dataDictionaryPermission: number
+  makeRulePermission: number
+  qualityAuditPermission: number
+  auditAnalysisPermission: number
 }
 
 export interface IProject {

+ 3 - 1
app/containers/Schedule/Editor.tsx

@@ -164,7 +164,9 @@ const ScheduleEditor: React.FC<ScheduleEditorProps> = (props) => {
     }
   }, [])
   const goBack = useCallback(() => {
-    history.push(`/project/${projectId}/schedules`)
+    const prefix = window.localStorage.getItem('inDataService') ?? ''
+    const prefixPath = prefix ? '/' + prefix : prefix
+    history.push(`/project/${projectId}${prefixPath}/schedules`)
   }, [])
 
   const {

+ 43 - 41
app/containers/Schedule/index.tsx

@@ -128,9 +128,9 @@ const ScheduleList: React.FC<ScheduleListProps> = (props) => {
           return (
             <p className={Styles.info}>
               {name}
-              <Tooltip title="点击查看错误日志">
+              <Tooltip title='点击查看错误日志'>
                 <Icon
-                  type="info-circle"
+                  type='info-circle'
                   onClick={openExecLogModal(record.execLog)}
                 />
               </Tooltip>
@@ -241,44 +241,44 @@ const ScheduleList: React.FC<ScheduleListProps> = (props) => {
       align: 'center',
       width: 185,
       render: (_, record) => (
-        <span className="ant-table-action-column">
+        <span className='ant-table-action-column'>
           <Tooltip title={JobStatusNextOperations[record.jobStatus]}>
             <Button
               icon={JobStatusIcons[record.jobStatus]}
-              shape="circle"
-              type="ghost"
+              shape='circle'
+              type='ghost'
               onClick={changeJobStatus(record)}
             />
           </Tooltip>
           <Popconfirm
-            title="确定立即执行?"
-            placement="bottom"
+            title='确定立即执行?'
+            placement='bottom'
             onConfirm={executeScheduleImmediately(record.id)}
           >
-            <Tooltip title="立即执行">
+            <Tooltip title='立即执行'>
               <Button
-                shape="circle"
-                type="ghost"
+                shape='circle'
+                type='ghost'
               >
-                <i className="iconfont icon-lijitoudi" />
+                <i className='iconfont icon-lijitoudi' />
               </Button>
             </Tooltip>
           </Popconfirm>
-          <Tooltip title="修改" trigger="hover">
+          <Tooltip title='修改' trigger='hover'>
             <EditButton
-              icon="edit"
-              shape="circle"
-              type="ghost"
+              icon='edit'
+              shape='circle'
+              type='ghost'
               onClick={editSchedule(record.id)}
             />
           </Tooltip>
           <Popconfirm
-            title="确定删除?"
-            placement="bottom"
+            title='确定删除?'
+            placement='bottom'
             onConfirm={deleteSchedule(record.id)}
           >
-            <Tooltip title="删除">
-              <AdminButton icon="delete" shape="circle" type="ghost" />
+            <Tooltip title='删除'>
+              <AdminButton icon='delete' shape='circle' type='ghost' />
             </Tooltip>
           </Popconfirm>
         </span>
@@ -288,31 +288,33 @@ const ScheduleList: React.FC<ScheduleListProps> = (props) => {
 
   return (
     <Container>
-      <Helmet title="Schedule" />
-      <ContainerTitle>
-        <Row>
-          <Col span={24} className={utilStyles.shortcut}>
-            <Breadcrumb className={utilStyles.breadcrumb}>
-              <Breadcrumb.Item>
-                <Link to="">Schedule</Link>
-              </Breadcrumb.Item>
-            </Breadcrumb>
-            <Link to={`/account/organization/${currentProject.orgId}`}>
-              <i className='iconfont icon-organization' />
-            </Link>
-          </Col>
-        </Row>
-      </ContainerTitle>
+      <Helmet title='定时任务' />
+      {
+        !history.location.pathname.includes('dataShareService') && <ContainerTitle>
+          <Row>
+            <Col span={24} className={utilStyles.shortcut}>
+              <Breadcrumb className={utilStyles.breadcrumb}>
+                <Breadcrumb.Item>
+                  <Link to=''>Schedule</Link>
+                </Breadcrumb.Item>
+              </Breadcrumb>
+              <Link to={`/account/organization/${currentProject.orgId}`}>
+                <i className='iconfont icon-organization' />
+              </Link>
+            </Col>
+          </Row>
+        </ContainerTitle>
+      }
       <ContainerBody>
         <Box>
           <Box.Header>
             <Box.Title>
-              <Icon type="bars" />
-              Schedule List
+              <Icon type='bars' />
+              定时任务列表
             </Box.Title>
             <Box.Tools>
-              <Tooltip placement="bottom" title="新增">
-                <AdminButton type="primary" icon="plus" onClick={addSchedule} />
+              <Tooltip placement='bottom' title='新增'>
+                <AdminButton type='primary' icon='plus' onClick={addSchedule} />
               </Tooltip>
             </Box.Tools>
           </Box.Header>
@@ -320,7 +322,7 @@ const ScheduleList: React.FC<ScheduleListProps> = (props) => {
             <Row>
               <Col span={24}>
                 <Table
-                  rowKey="id"
+                  rowKey='id'
                   bordered
                   dataSource={schedules}
                   columns={tableColumns}
@@ -333,8 +335,8 @@ const ScheduleList: React.FC<ScheduleListProps> = (props) => {
         </Box>
       </ContainerBody>
       <Modal
-        title="错误日志"
-        wrapClassName="ant-modal-large"
+        title='错误日志'
+        wrapClassName='ant-modal-large'
         visible={execLogModalVisible}
         onCancel={closeExecLogModal}
         footer={false}

+ 49 - 48
app/containers/Source/index.tsx

@@ -111,10 +111,8 @@ const emptySource: ISourceFormValues = {
   }
 }
 
-export class SourceList extends React.PureComponent<
-  ISourceListProps,
-  ISourceListStates
-> {
+export class SourceList extends React.PureComponent<ISourceListProps,
+  ISourceListStates> {
   public state: Readonly<ISourceListStates> = {
     screenWidth: document.documentElement.clientWidth,
     tempFilterSourceName: '',
@@ -175,10 +173,10 @@ export class SourceList extends React.PureComponent<
   }))
 
   private getTableColumns = ({
-    sourcePermission,
-    AdminButton,
-    EditButton
-  }: ReturnType<typeof SourceList.getSourcePermission>) => {
+                               sourcePermission,
+                               AdminButton,
+                               EditButton
+                             }: ReturnType<typeof SourceList.getSourcePermission>) => {
     const {
       tempFilterSourceName,
       filterSourceName,
@@ -193,7 +191,7 @@ export class SourceList extends React.PureComponent<
         dataIndex: 'name',
         filterDropdown: (
           <SearchFilterDropdown
-            placeholder="名称"
+            placeholder='名称'
             value={tempFilterSourceName}
             onChange={this.filterSourceNameChange}
             onSearch={this.searchSource}
@@ -243,7 +241,7 @@ export class SourceList extends React.PureComponent<
           dangerouslySetInnerHTML={{
             __html: text.replace(
               regex,
-              `<span class="${utilStyles.highlight}">$1</span>`
+              `<span class='${utilStyles.highlight}'>$1</span>`
             )
           }}
         />
@@ -256,39 +254,39 @@ export class SourceList extends React.PureComponent<
         key: 'action',
         width: 180,
         render: (_, record) => (
-          <span className="ant-table-action-column">
-            <Tooltip title="重置连接">
+          <span className='ant-table-action-column'>
+            <Tooltip title='重置连接'>
               <EditButton
-                icon="reload"
-                shape="circle"
-                type="ghost"
+                icon='reload'
+                shape='circle'
+                type='ghost'
                 disabled={resetLoading}
                 onClick={this.openResetSource(record)}
               />
             </Tooltip>
-            <Tooltip title="修改">
+            <Tooltip title='修改'>
               <EditButton
-                icon="edit"
-                shape="circle"
-                type="ghost"
+                icon='edit'
+                shape='circle'
+                type='ghost'
                 onClick={this.editSource(record.id)}
               />
             </Tooltip>
             <Popconfirm
-              title="确定删除?"
-              placement="bottom"
+              title='确定删除?'
+              placement='bottom'
               onConfirm={this.deleteSource(record.id)}
             >
-              <Tooltip title="删除">
-                <AdminButton icon="delete" shape="circle" type="ghost" />
+              <Tooltip title='删除'>
+                <AdminButton icon='delete' shape='circle' type='ghost' />
               </Tooltip>
             </Popconfirm>
             {record && record.type === 'csv' ? (
-              <Tooltip title="上传">
+              <Tooltip title='上传'>
                 <EditButton
-                  icon="upload"
-                  shape="circle"
-                  type="ghost"
+                  icon='upload'
+                  shape='circle'
+                  type='ghost'
                   onClick={this.showUploadModal(record.id)}
                 />
               </Tooltip>
@@ -506,36 +504,39 @@ export class SourceList extends React.PureComponent<
       simple: screenWidth <= 768
     }
     const filterSources = this.getFilterSources(filterSourceName, sources)
+    const pathname = this.props.history.location.pathname
 
     return (
       <Container>
-        <Helmet title="Source" />
-        <ContainerTitle>
-          <Row>
-            <Col span={24} className={utilStyles.shortcut}>
-              <Breadcrumb className={utilStyles.breadcrumb}>
-                <Breadcrumb.Item>
-                  <Link to="">Source</Link>
-                </Breadcrumb.Item>
-              </Breadcrumb>
-              <Link to={`/account/organization/${currentProject.orgId}`}>
-                <i className='iconfont icon-organization' />
-              </Link>
-            </Col>
-          </Row>
-        </ContainerTitle>
+        <Helmet title='数据源' />
+        {
+          !pathname.includes('dataManager') &&
+          <ContainerTitle>
+            <Row>
+              <Col span={24} className={utilStyles.shortcut}>
+                <Breadcrumb className={utilStyles.breadcrumb}>
+                  <Breadcrumb.Item>
+                    <Link to=''>Source</Link>
+                  </Breadcrumb.Item>
+                </Breadcrumb>
+                <Link to={`/account/organization/${currentProject.orgId}`}>
+                  <i className='iconfont icon-organization' />
+                </Link>
+              </Col>
+            </Row>
+          </ContainerTitle>}
         <ContainerBody>
           <Box>
             <Box.Header>
               <Box.Title>
-                <Icon type="bars" />
-                Source List
+                <Icon type='bars' />
+                数据源列表
               </Box.Title>
               <Box.Tools>
-                <Tooltip placement="bottom" title="新增">
+                <Tooltip placement='bottom' title='新增'>
                   <AdminButton
-                    type="primary"
-                    icon="plus"
+                    type='primary'
+                    icon='plus'
                     onClick={this.addSource}
                   />
                 </Tooltip>
@@ -546,7 +547,7 @@ export class SourceList extends React.PureComponent<
                 <Col span={24}>
                   <Table
                     bordered
-                    rowKey="id"
+                    rowKey='id'
                     loading={listLoading}
                     dataSource={filterSources}
                     columns={tableColumns}

+ 82 - 57
app/containers/View/Editor.tsx

@@ -96,10 +96,12 @@ interface IViewEditorStateProps {
 
   isLastExecuteWholeSql: boolean
 }
+
 export enum EExecuteType {
   whole,
   single
 }
+
 interface IViewEditorDispatchProps {
   onHideNavigator: () => void
   onLoadViewDetail: (viewId: number) => void
@@ -146,9 +148,16 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
     sqlFragment: ''
   }
 
-  public constructor (props: IViewEditorProps) {
+  public constructor(props: IViewEditorProps) {
     super(props)
-    const { onHideNavigator, onLoadSources, onLoadViewDetail, onLoadProjectRoles, onLoadDacChannels, match } = this.props
+    const {
+      onHideNavigator,
+      onLoadSources,
+      onLoadViewDetail,
+      onLoadProjectRoles,
+      onLoadDacChannels,
+      match
+    } = this.props
     onHideNavigator()
     const { viewId, projectId } = match.params
     if (projectId) {
@@ -164,50 +173,50 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
   public static getDerivedStateFromProps:
     React.GetDerivedStateFromProps<IViewEditorProps, IViewEditorStates>
     = (props, state) => {
-      const { match, editingView, sqlValidation } = props
-      const { viewId } = match.params
-      const { init, sqlValidationCode } = state
-      let { lastSuccessExecutedSql } = state
-      if (sqlValidationCode !== sqlValidation.code && sqlValidation.code) {
-        notification.destroy()
-        sqlValidation.code === 200
-          ? notification.success({
-            message: '执行成功',
-            duration: 3
-          })
-          : notification.error({
-            message: '执行失败',
-            description: (
-              <Tooltip
-                placement="bottom"
-                trigger="click"
-                title={sqlValidation.message}
-                overlayClassName={Styles.errorMessage}
-              >
-                <a>点击查看错误信息</a>
-              </Tooltip>
-            ),
-            duration: null
-          })
-        if (sqlValidation.code === 200) {
-          lastSuccessExecutedSql = editingView.sql
-        }
+    const { match, editingView, sqlValidation } = props
+    const { viewId } = match.params
+    const { init, sqlValidationCode } = state
+    let { lastSuccessExecutedSql } = state
+    if (sqlValidationCode !== sqlValidation.code && sqlValidation.code) {
+      notification.destroy()
+      sqlValidation.code === 200
+        ? notification.success({
+          message: '执行成功',
+          duration: 3
+        })
+        : notification.error({
+          message: '执行失败',
+          description: (
+            <Tooltip
+              placement='bottom'
+              trigger='click'
+              title={sqlValidation.message}
+              overlayClassName={Styles.errorMessage}
+            >
+              <a>点击查看错误信息</a>
+            </Tooltip>
+          ),
+          duration: null
+        })
+      if (sqlValidation.code === 200) {
+        lastSuccessExecutedSql = editingView.sql
       }
-      if (editingView && editingView.id === +viewId) {
-        if (init) {
-          props.onLoadSourceDatabases(editingView.sourceId)
-          lastSuccessExecutedSql = editingView.sql
-          return {
-            init: false,
-            sqlValidationCode: sqlValidation.code,
-            lastSuccessExecutedSql
-          }
+    }
+    if (editingView && editingView.id === +viewId) {
+      if (init) {
+        props.onLoadSourceDatabases(editingView.sourceId)
+        lastSuccessExecutedSql = editingView.sql
+        return {
+          init: false,
+          sqlValidationCode: sqlValidation.code,
+          lastSuccessExecutedSql
         }
       }
-      return { sqlValidationCode: sqlValidation.code, lastSuccessExecutedSql }
     }
+    return { sqlValidationCode: sqlValidation.code, lastSuccessExecutedSql }
+  }
 
-  public componentWillUnmount () {
+  public componentWillUnmount() {
     this.props.onResetState()
     notification.destroy()
   }
@@ -251,7 +260,9 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
         return true
       }
     })
-    if (hasError) { return }
+    if (hasError) {
+      return
+    }
     this.setState({ currentStep: currentStep + step }, () => {
       if (this.state.currentStep > 1) {
         this.saveView()
@@ -274,7 +285,9 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
         const validColumnAuth = columnAuth.filter((c) => !!model[c])
         const validRowAuth = rowAuth.filter((r) => {
           const v = variable.find((v) => v.name === r.name)
-          if (!v) { return false }
+          if (!v) {
+            return false
+          }
           return (v.type === ViewVariableTypes.Authorization && !v.fromService)
         })
         return {
@@ -290,7 +303,9 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
   private goToViewList = () => {
     const { history, match } = this.props
     const { projectId } = match.params
-    history.push(`/project/${projectId}/views`)
+    const prefix = window.localStorage.getItem('inDataService') ?? ''
+    const prefixPath = prefix ? '/' + prefix : prefix
+    history.push(`/project/${projectId}${prefixPath}/views`)
   }
 
   private viewChange = (propName: keyof IView, value: string | number) => {
@@ -354,17 +369,23 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
   }
 
   private getSqlHints = memoizeOne((sourceId: number, schema: ISchema, variables: IViewVariable[]) => {
-    if (!sourceId) { return {} }
+    if (!sourceId) {
+      return {}
+    }
 
     const variableHints = variables.reduce((acc, v) => {
       acc[`$${v.name}$`] = []
       return acc
     }, {})
     const { mapDatabases, mapTables, mapColumns } = schema
-    if (!mapDatabases[sourceId]) { return {} }
+    if (!mapDatabases[sourceId]) {
+      return {}
+    }
 
     const tableHints: { [tableName: string]: string[] } = Object.values(mapTables).reduce((acc, tablesInfo) => {
-      if (tablesInfo.sourceId !== sourceId) { return acc }
+      if (tablesInfo.sourceId !== sourceId) {
+        return acc
+      }
 
       tablesInfo.tables.forEach(({ name: tableName }) => {
         acc[tableName] = []
@@ -373,7 +394,9 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
     }, {})
 
     Object.values(mapColumns).forEach((columnsInfo) => {
-      if (columnsInfo.sourceId !== sourceId) { return }
+      if (columnsInfo.sourceId !== sourceId) {
+        return
+      }
       const { tableName, columns } = columnsInfo
       if (tableHints[tableName]) {
         tableHints[tableName] = tableHints[tableName].concat(columns.map((col) => col.name))
@@ -387,7 +410,7 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
     return hints
   })
 
-  public render () {
+  public render() {
     const {
       sources, schema,
       sqlDataSource, sqlLimit, loading, projectRoles,
@@ -395,7 +418,8 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
       editingView, editingViewInfo,
       isLastExecuteWholeSql,
       onLoadSourceDatabases, onLoadDatabaseTables, onLoadTableColumns, onSetSqlLimit,
-      onLoadDacTenants, onLoadDacBizs } = this.props
+      onLoadDacTenants, onLoadDacBizs
+    } = this.props
     const { currentStep, lastSuccessExecutedSql, sqlFragment } = this.state
     const { model, variable, roles: viewRoles } = editingViewInfo
     const sqlHints = this.getSqlHints(editingView.sourceId, schema, variable)
@@ -405,7 +429,7 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
 
     return (
       <>
-        <Helmet title="View" />
+        <Helmet title='数据资产' />
         <div className={Styles.viewEditor}>
           <div className={Styles.header}>
             <div className={Styles.steps}>
@@ -418,7 +442,7 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
             onVariableChange={this.variableChange}
           >
             <SourceTable
-              key="SourceTable"
+              key='SourceTable'
               view={editingView}
               sources={sources}
               schema={schema}
@@ -427,10 +451,11 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
               onDatabaseSelect={onLoadDatabaseTables}
               onTableSelect={onLoadTableColumns}
             />
-            <SqlEditor key="SqlEditor" value={editingView.sql} hints={sqlHints} onSqlChange={this.sqlChange} onSelect={this.sqlSelect} onCmdEnter={this.executeSql} />
-            <SqlPreview key="SqlPreview" size="small" loading={loading.execute} response={sqlDataSource} />
+            <SqlEditor key='SqlEditor' value={editingView.sql} hints={sqlHints} onSqlChange={this.sqlChange}
+                       onSelect={this.sqlSelect} onCmdEnter={this.executeSql} />
+            <SqlPreview key='SqlPreview' size='small' loading={loading.execute} response={sqlDataSource} />
             <EditorBottom
-              key="EditorBottom"
+              key='EditorBottom'
               sqlLimit={sqlLimit}
               loading={loading.execute}
               nextDisabled={nextDisabled}
@@ -440,9 +465,9 @@ export class ViewEditor extends React.Component<IViewEditorProps, IViewEditorSta
               onExecuteSql={this.executeSql}
               onStepChange={this.stepChange}
             />
-            <ViewVariableList key="ViewVariableList" variables={variable} />
+            <ViewVariableList key='ViewVariableList' variables={variable} />
             <VariableModal
-              key="VariableModal"
+              key='VariableModal'
               channels={channels}
               tenants={tenants}
               bizs={bizs}

+ 43 - 37
app/containers/View/index.tsx

@@ -1,4 +1,3 @@
-
 /*
  * <<
  * Davinci
@@ -93,7 +92,7 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
     copyFromView: null
   }
 
-  public componentWillMount () {
+  public componentWillMount() {
     this.loadViews()
     window.addEventListener('resize', this.setScreenWidth, false)
   }
@@ -106,7 +105,7 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
     }
   }
 
-  public componentWillUnmount () {
+  public componentWillUnmount() {
     window.removeEventListener('resize', this.setScreenWidth, false)
   }
 
@@ -115,7 +114,9 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
   }
 
   private getFilterViews = memoizeOne((viewName: string, views: IViewBase[]) => {
-    if (!Array.isArray(views) || !views.length) { return [] }
+    if (!Array.isArray(views) || !views.length) {
+      return []
+    }
     const regex = new RegExp(viewName, 'gi')
     const filterViews = views.filter((v) => v.name.match(regex) || v.description.match(regex))
     return filterViews
@@ -139,7 +140,7 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
       dataIndex: 'name',
       filterDropdown: (
         <SearchFilterDropdown
-          placeholder="名称"
+          placeholder='名称'
           value={tempFilterViewName}
           onChange={this.filterViewNameChange}
           onSearch={this.searchView}
@@ -153,7 +154,8 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
       title: '描述',
       dataIndex: 'description'
     }, {
-      title: 'Source',
+      title: '数据源',
+      // title: 'Source',
       dataIndex: 'sourceName',
       filterMultiple: false,
       onFilter: (val, record) => record.sourceName === val,
@@ -167,7 +169,7 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
       columns[0].render = (text: string) => (
         <span
           dangerouslySetInnerHTML={{
-            __html: text.replace(regex, `<span class="${utilStyles.highlight}">$1</span>`)
+            __html: text.replace(regex, `<span class='${utilStyles.highlight}'>$1</span>`)
           }}
         />
       )
@@ -179,20 +181,20 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
         width: 150,
         className: utilStyles.textAlignCenter,
         render: (_, record) => (
-          <span className="ant-table-action-column">
-            <Tooltip title="复制">
-              <EditButton icon="copy" shape="circle" type="ghost" onClick={this.copyView(record)} />
+          <span className='ant-table-action-column'>
+            <Tooltip title='复制'>
+              <EditButton icon='copy' shape='circle' type='ghost' onClick={this.copyView(record)} />
             </Tooltip>
-            <Tooltip title="修改">
-              <EditButton icon="edit" shape="circle" type="ghost" onClick={this.editView(record.id)} />
+            <Tooltip title='修改'>
+              <EditButton icon='edit' shape='circle' type='ghost' onClick={this.editView(record.id)} />
             </Tooltip>
             <Popconfirm
-              title="确定删除?"
-              placement="bottom"
+              title='确定删除?'
+              placement='bottom'
               onConfirm={this.deleteView(record.id)}
             >
-              <Tooltip title="删除">
-                <AdminButton icon="delete" shape="circle" type="ghost" />
+              <Tooltip title='删除'>
+                <AdminButton icon='delete' shape='circle' type='ghost' />
               </Tooltip>
             </Popconfirm>
           </span>
@@ -270,7 +272,7 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
     onCheckName({ name: viewName, projectId: currentProject.id }, resolve, reject)
   }
 
-  public render () {
+  public render() {
     const { currentProject, views, loading } = this.props
     const { screenWidth, filterViewName } = this.state
     const { viewPermission, AdminButton, EditButton } = ViewList.getViewPermission(currentProject)
@@ -283,34 +285,38 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
 
     const { copyModalVisible, copyFromView } = this.state
 
+    const pathname = this.props.history.location.pathname
+
     return (
       <>
         <Container>
-          <Helmet title="View" />
-          <ContainerTitle>
-            <Row>
-              <Col span={24} className={utilStyles.shortcut}>
-                <Breadcrumb className={utilStyles.breadcrumb}>
-                  <Breadcrumb.Item>
-                    <Link to="">View</Link>
-                  </Breadcrumb.Item>
-                </Breadcrumb>
-                <Link to={`/account/organization/${currentProject.orgId}`}>
-                  <i className='iconfont icon-organization' />
-                </Link>
-              </Col>
-            </Row>
-          </ContainerTitle>
+          <Helmet title='数据资产' />
+          {
+            !pathname.includes('dataManager') && <ContainerTitle>
+              <Row>
+                <Col span={24} className={utilStyles.shortcut}>
+                  <Breadcrumb className={utilStyles.breadcrumb}>
+                    <Breadcrumb.Item>
+                      <Link to=''>View</Link>
+                    </Breadcrumb.Item>
+                  </Breadcrumb>
+                  <Link to={`/account/organization/${currentProject.orgId}`}>
+                    <i className='iconfont icon-organization' />
+                  </Link>
+                </Col>
+              </Row>
+            </ContainerTitle>
+          }
           <ContainerBody>
             <Box>
               <Box.Header>
                 <Box.Title>
-                  <Icon type="bars" />
-                  View List
+                  <Icon type='bars' />
+                  数据资产列表
                 </Box.Title>
                 <Box.Tools>
-                  <Tooltip placement="bottom" title="新增">
-                    <AdminButton type="primary" icon="plus" onClick={this.addView} />
+                  <Tooltip placement='bottom' title='新增'>
+                    <AdminButton type='primary' icon='plus' onClick={this.addView} />
                   </Tooltip>
                 </Box.Tools>
               </Box.Header>
@@ -319,7 +325,7 @@ export class ViewList extends React.PureComponent<IViewListProps, IViewListState
                   <Col span={24}>
                     <Table
                       bordered
-                      rowKey="id"
+                      rowKey='id'
                       loading={loading.view}
                       dataSource={filterViews}
                       columns={tableColumns}

+ 7 - 7
app/containers/Viz/DataVizList.tsx

@@ -79,9 +79,9 @@ export class VizList extends React.Component<IVizProps & RouteComponentWithParam
 
   private goToPortal = (portalId: number) => () => {
     const { history, match } = this.props
-    const next = this.props.location.pathname.replace('/vizs', '')
-    // history.push(`/project/${match.params.projectId}/portal/${portalId}`)
-    history.push(`${next}/portal/${portalId}`)
+    // const next = this.props.location.pathname.replace('/vizs', '')
+    history.push(`/project/${match.params.projectId}/portal/${portalId}`)
+    // history.push(`${next}/portal/${portalId}`)
   }
 
   private goToDisplay = (displayId: number) => () => {
@@ -93,9 +93,9 @@ export class VizList extends React.Component<IVizProps & RouteComponentWithParam
     } = this.props
     const projectId = match.params.projectId
     const isToPreview = vizPermission === 1
-    // const path = `/project/${projectId}/display/${displayId}${isToPreview ? '/preview' : ''}`
-    const next = this.props.location.pathname.replace('/vizs', '')
-    const path = `${next}/display/${displayId}${isToPreview ? '/preview' : ''}`
+    const path = `/project/${projectId}/display/${displayId}${isToPreview ? '/preview' : ''}`
+    // const next = this.props.location.pathname.replace('/vizs', '')
+    // const path = `${next}/display/${displayId}${isToPreview ? '/preview' : ''}`
     this.props.history.push(path)
   }
 
@@ -135,7 +135,7 @@ export class VizList extends React.Component<IVizProps & RouteComponentWithParam
     })
     return (
       <Container>
-        <Helmet title='Viz' />
+        <Helmet title='数据看板' />
         <ContainerBody>
           <Box>
             <Box.Header>

+ 3 - 1
app/containers/Viz/Display/Editor.tsx

@@ -66,7 +66,9 @@ const VizDisplayEditor: React.FC<RouteComponentWithParams> = (props) => {
   }, [])
 
   const goToViz = useCallback(() => {
-    history.replace(`/project/${projectId}/vizs`)
+    const prefix = window.localStorage.getItem('inDataService') ?? ''
+    const prefixPath = prefix ? '/' + prefix : prefix
+    history.replace(`/project/${projectId}${prefixPath}/vizs`)
   }, [projectId])
 
   const selectSlide = useCallback(

+ 0 - 19
app/containers/Viz/Loadable.tsx

@@ -6,9 +6,6 @@ export const Viz = loadable(() => import('./'), {
   fallback: <Skeleton active paragraph={{ rows: 15 }} />
 })
 
-export const DataManagerViz = loadable(() => import('./dataManagerViz'), {
-  fallback: <Skeleton active paragraph={{ rows: 15 }} />
-})
 export const DataShareServiceViz = loadable(() => import('./dataShareServiceViz'), {
   fallback: <Skeleton active paragraph={{ rows: 15 }} />
 })
@@ -26,24 +23,8 @@ export const PortalIndex = loadable(() => import('./Portal'), {
   fallback: <Skeleton active paragraph={{ rows: 15 }} />
 })
 
-export const DataManagerPortalIndex = loadable(() => import('./DataManagerPortal'), {
-  fallback: <Skeleton active paragraph={{ rows: 15 }} />
-})
-
-export const DataShareServicePortalIndex = loadable(() => import('./DataShareServicePortal'), {
-  fallback: <Skeleton active paragraph={{ rows: 15 }} />
-})
-
 export const VizDisplay = loadable(() => import('./Display'), {
   fallback: <Skeleton active paragraph={{ rows: 15 }} />
 })
 
-export const DataManagerVizDisplay = loadable(() => import('./DataManagerDisplay'), {
-  fallback: <Skeleton active paragraph={{ rows: 15 }} />
-})
-
-export const DataShareServiceVizDisplay = loadable(() => import('./DataShareServiceDisplay'), {
-  fallback: <Skeleton active paragraph={{ rows: 15 }} />
-})
-
 export default Viz

+ 3 - 1
app/containers/Viz/Portal.tsx

@@ -95,7 +95,9 @@ const VizPortal: React.FC<IVizPortalProps> = (props) => {
   }, [portalId])
 
   const goToViz = useCallback(() => {
-    history.replace(`/project/${projectId}/vizs`)
+    const prefix = window.localStorage.getItem('inDataService') ?? ''
+    const prefixPath = prefix ? '/' + prefix : prefix
+    history.replace(`/project/${projectId}${prefixPath}/vizs`)
   }, [])
 
   const onLoadDownloadList = useCallback(() => dispatch(loadDownloadList()), [])

+ 3 - 3
app/containers/Viz/dataShareServiceViz.tsx

@@ -26,7 +26,7 @@ import { useInjectSaga } from 'utils/injectSaga'
 import reducer from './reducer'
 import saga from './sagas'
 
-import { DataShareServicePortalIndex, DataShareServiceVizDisplay, DataVizList } from './Loadable'
+import { PortalIndex, VizDisplay, DataVizList } from './Loadable'
 
 export default () => {
   useInjectReducer({ key: 'viz', reducer })
@@ -35,8 +35,8 @@ export default () => {
   return (
     <Switch>
       <Route path='/project/:projectId/dataShareService/vizs' component={DataVizList} />
-      <Route path='/project/:projectId/dataShareService/portal/:portalId' component={DataShareServicePortalIndex} />
-      <Route path='/project/:projectId/dataShareService/display/:displayId' component={DataShareServiceVizDisplay} />
+      <Route path='/project/:projectId/portal/:portalId' component={PortalIndex} />
+      <Route path='/project/:projectId/display/:displayId' component={VizDisplay} />
     </Switch>
   )
 }

+ 42 - 41
app/containers/Widget/List.tsx

@@ -63,8 +63,8 @@ const mapStateToProps = createStructuredSelector({
 })
 
 const columnTitle = {
-  name: 'Widget名称',
-  viewName: 'View名称'
+  name: '组件名称',
+  viewName: '数据资产名称'
 }
 
 const WidgetList: React.FC<RouteComponentWithParams> = (props) => {
@@ -189,15 +189,15 @@ const WidgetList: React.FC<RouteComponentWithParams> = (props) => {
           dangerouslySetInnerHTML={{
             __html: text.replace(
               regex,
-              `<span class="${utilStyles.highlight}">$1</span>`
+              `<span class='${utilStyles.highlight}'>$1</span>`
             )
           }}
         />
       ) : (
-          text
-        ))
+        text
+      ))
     }
-  });
+  })
 
   const mappingIcon = (widgetConfig: IWidgetConfigBase) => {
     const selectedChart = widgetConfig.selectedChart
@@ -214,7 +214,7 @@ const WidgetList: React.FC<RouteComponentWithParams> = (props) => {
       render: (_, record) => (
         <div>
           <i className={`iconfont ${mappingIcon(record.config)}`}></i>
-          <span style={{marginLeft: 8}}>{record.name}</span>
+          <span style={{ marginLeft: 8 }}>{record.name}</span>
         </div>
       )
     },
@@ -237,30 +237,30 @@ const WidgetList: React.FC<RouteComponentWithParams> = (props) => {
       align: 'center',
       width: 145,
       render: (_, record) => (
-        <span className="ant-table-action-column">
-          <Tooltip title="复制">
+        <span className='ant-table-action-column'>
+          <Tooltip title='复制'>
             <EditButton
-              icon="copy"
-              shape="circle"
-              type="ghost"
+              icon='copy'
+              shape='circle'
+              type='ghost'
               onClick={openCopyModal(record)}
             />
           </Tooltip>
-          <Tooltip title="修改" trigger="hover">
+          <Tooltip title='修改' trigger='hover'>
             <EditButton
-              icon="edit"
-              shape="circle"
-              type="ghost"
+              icon='edit'
+              shape='circle'
+              type='ghost'
               onClick={toWorkbench(record.id)}
             />
           </Tooltip>
           <Popconfirm
-            title="确定删除?"
-            placement="bottom"
+            title='确定删除?'
+            placement='bottom'
             onConfirm={onDeleteWidget(record.id)}
           >
-            <Tooltip title="删除">
-              <AdminButton icon="delete" shape="circle" type="ghost" />
+            <Tooltip title='删除'>
+              <AdminButton icon='delete' shape='circle' type='ghost' />
             </Tooltip>
           </Popconfirm>
         </span>
@@ -278,33 +278,34 @@ const WidgetList: React.FC<RouteComponentWithParams> = (props) => {
   return (
     <>
       <Container>
-        <Helmet title="Widget" />
-        <ContainerTitle>
-          <Row>
-            <Col span={24} className={utilStyles.shortcut}>
-              <Breadcrumb className={utilStyles.breadcrumb}>
-                <Breadcrumb.Item>
-                  <Link to="">Widget</Link>
-                </Breadcrumb.Item>
-              </Breadcrumb>
-              <Link to={`/account/organization/${currentProject.orgId}`}>
-                <i className='iconfont icon-organization' />
-              </Link>
-            </Col>
-          </Row>
-        </ContainerTitle>
+        <Helmet title='可视化组件' />
+        {
+          !history?.location?.pathname?.includes('dataShareService') && <ContainerTitle>
+            <Row>
+              <Col span={24} className={utilStyles.shortcut}>
+                <Breadcrumb className={utilStyles.breadcrumb}>
+                  <Breadcrumb.Item>
+                    <Link to=''>Widget</Link>
+                  </Breadcrumb.Item>
+                </Breadcrumb>
+                <Link to={`/account/organization/${currentProject.orgId}`}>
+                  <i className='iconfont icon-organization' />
+                </Link>
+              </Col>
+            </Row>
+          </ContainerTitle>}
         <ContainerBody>
           <Box>
             <Box.Header>
               <Box.Title>
-                <Icon type="bars" />
-                Widget List
+                <Icon type='bars' />
+                可视化组件列表
               </Box.Title>
               <Box.Tools>
-                <Tooltip placement="bottom" title="新增">
+                <Tooltip placement='bottom' title='新增'>
                   <AdminButton
-                    type="primary"
-                    icon="plus"
+                    type='primary'
+                    icon='plus'
                     onClick={toWorkbench()}
                   />
                 </Tooltip>
@@ -314,7 +315,7 @@ const WidgetList: React.FC<RouteComponentWithParams> = (props) => {
               <Row>
                 <Col span={24}>
                   <Table
-                    rowKey="id"
+                    rowKey='id'
                     bordered
                     dataSource={filterWidgets}
                     columns={columns}

BIN
app/favicon.ico


+ 1 - 1
app/index.html

@@ -30,7 +30,7 @@
     <!-- Allow installing the app to the homescreen -->
     <meta name="mobile-web-app-capable" content="yes">
     <meta name="format-detection" content="telephone=no" />
-    <title>Davinci</title>
+    <title>聚合平台</title>
     <style>
       .general-loading {
         width: 100%;

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.