Merge branch 'dev-3.6' of https://git.mesalab.cn/nezha/nezha-fronted into dev-3.5-webpack
This commit is contained in:
@@ -425,6 +425,7 @@ if (process.env.NODE_ENV == 'development') {
|
||||
{
|
||||
delete: [
|
||||
path.join(__dirname, '../dist', '/config.json'),
|
||||
path.join(__dirname, '../dist', '/*.js'),
|
||||
path.join(__dirname, '../.cache/')
|
||||
]
|
||||
},
|
||||
|
||||
86
nezha-fronted/package-lock.json
generated
86
nezha-fronted/package-lock.json
generated
@@ -1494,7 +1494,7 @@
|
||||
},
|
||||
"@mapbox/geojson-rewind": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz",
|
||||
"integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==",
|
||||
"requires": {
|
||||
"get-stream": "^6.0.1",
|
||||
@@ -1503,24 +1503,24 @@
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
||||
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@mapbox/jsonlint-lines-primitives": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
|
||||
"integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ=="
|
||||
},
|
||||
"@mapbox/mapbox-gl-supported": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.1.tgz",
|
||||
"integrity": "sha512-HP6XvfNIzfoMVfyGjBckjiAOQK9WfX0ywdLubuPMPv+Vqf5fj0uCbgBQYpiqcWZT6cbyyRnTSXDheT1ugvF6UQ=="
|
||||
},
|
||||
"@mapbox/node-pre-gyp": {
|
||||
@@ -1676,9 +1676,9 @@
|
||||
}
|
||||
},
|
||||
"tar": {
|
||||
"version": "6.1.11",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
||||
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
|
||||
"version": "6.1.12",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.12.tgz",
|
||||
"integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==",
|
||||
"requires": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
@@ -1697,22 +1697,22 @@
|
||||
},
|
||||
"@mapbox/point-geometry": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
|
||||
"integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="
|
||||
},
|
||||
"@mapbox/tiny-sdf": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz",
|
||||
"integrity": "sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw=="
|
||||
},
|
||||
"@mapbox/unitbezier": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz",
|
||||
"integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw=="
|
||||
},
|
||||
"@mapbox/vector-tile": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
|
||||
"integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==",
|
||||
"requires": {
|
||||
"@mapbox/point-geometry": "~0.1.0"
|
||||
@@ -1720,7 +1720,7 @@
|
||||
},
|
||||
"@mapbox/whoots-js": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
|
||||
"integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q=="
|
||||
},
|
||||
"@npmcli/fs": {
|
||||
@@ -1894,7 +1894,7 @@
|
||||
},
|
||||
"@types/geojson": {
|
||||
"version": "7946.0.10",
|
||||
"resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.10.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
|
||||
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
|
||||
},
|
||||
"@types/glob": {
|
||||
@@ -1950,12 +1950,12 @@
|
||||
},
|
||||
"@types/mapbox__point-geometry": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox__point-geometry/-/mapbox__point-geometry-0.1.2.tgz",
|
||||
"integrity": "sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA=="
|
||||
},
|
||||
"@types/mapbox__vector-tile": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/mapbox__vector-tile/-/mapbox__vector-tile-1.3.0.tgz",
|
||||
"integrity": "sha512-kDwVreQO5V4c8yAxzZVQLE5tyWF+IPToAanloQaSnwfXmIcJ7cyOrv8z4Ft4y7PsLYmhWXmON8MBV8RX0Rgr8g==",
|
||||
"requires": {
|
||||
"@types/geojson": "*",
|
||||
@@ -1982,7 +1982,7 @@
|
||||
},
|
||||
"@types/pbf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/pbf/-/pbf-3.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.2.tgz",
|
||||
"integrity": "sha512-EDrLIPaPXOZqDjrkzxxbX7UlJSeQVgah3i0aA4pOSzmK9zq3BIh7/MZIQxED7slJByvKM4Gc6Hypyu2lJzh3SQ=="
|
||||
},
|
||||
"@types/q": {
|
||||
@@ -4515,12 +4515,12 @@
|
||||
"integrity": "sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA=="
|
||||
},
|
||||
"canvas": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.10.1.tgz",
|
||||
"integrity": "sha512-29pIjn9uwTUsIgJUNd7GXxKk8sg4iyJwLm1wIilNIqX1mVzXSc2nUij9exW1LqNpis1d2ebMYfMqTWcokZ4pdA==",
|
||||
"version": "2.10.2",
|
||||
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.10.2.tgz",
|
||||
"integrity": "sha512-FSmlsip0nZ0U4Zcfht0qBJqDhlfGuevTZKE8h+dBOYrJjGvY3iqMGSzzbvkaFhvMXiVxfcMaPHS/kge++T5SKg==",
|
||||
"requires": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.0",
|
||||
"nan": "^2.15.0",
|
||||
"nan": "^2.17.0",
|
||||
"simple-get": "^3.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -4800,7 +4800,7 @@
|
||||
},
|
||||
"clipboard": {
|
||||
"version": "2.0.11",
|
||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
|
||||
"integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
|
||||
"requires": {
|
||||
"good-listener": "^1.2.2",
|
||||
@@ -5941,7 +5941,7 @@
|
||||
},
|
||||
"csscolorparser": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||
"integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w=="
|
||||
},
|
||||
"cssesc": {
|
||||
@@ -7125,7 +7125,7 @@
|
||||
},
|
||||
"delegate": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
|
||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
|
||||
},
|
||||
"delegates": {
|
||||
@@ -7399,7 +7399,7 @@
|
||||
},
|
||||
"earcut": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmmirror.com/earcut/-/earcut-2.2.4.tgz",
|
||||
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
|
||||
"integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
|
||||
},
|
||||
"easings-css": {
|
||||
@@ -9227,7 +9227,7 @@
|
||||
},
|
||||
"geojson-vt": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
|
||||
"integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg=="
|
||||
},
|
||||
"get-caller-file": {
|
||||
@@ -9281,7 +9281,7 @@
|
||||
},
|
||||
"gl-matrix": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/gl-matrix/-/gl-matrix-3.4.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
|
||||
"integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
|
||||
},
|
||||
"glob": {
|
||||
@@ -9468,7 +9468,7 @@
|
||||
},
|
||||
"good-listener": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
|
||||
"integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
|
||||
"requires": {
|
||||
"delegate": "^3.1.2"
|
||||
@@ -12059,7 +12059,7 @@
|
||||
},
|
||||
"kdbush": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/kdbush/-/kdbush-3.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
|
||||
"integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
|
||||
},
|
||||
"keyv": {
|
||||
@@ -12402,7 +12402,7 @@
|
||||
},
|
||||
"maplibre-gl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/maplibre-gl/-/maplibre-gl-2.2.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-2.2.0.tgz",
|
||||
"integrity": "sha512-5LB7ROIxvBADPa4PmU2j+mp0jG5IIbEidCOyZEXVbEriluMJn0hz28vszVb4Cr2IA4YQ9cnERqjHaf33MHIRBQ==",
|
||||
"requires": {
|
||||
"@mapbox/geojson-rewind": "^0.5.2",
|
||||
@@ -13020,7 +13020,7 @@
|
||||
},
|
||||
"murmurhash-js": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
|
||||
"integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw=="
|
||||
},
|
||||
"mv": {
|
||||
@@ -13995,7 +13995,7 @@
|
||||
},
|
||||
"pbf": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/pbf/-/pbf-3.2.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz",
|
||||
"integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
|
||||
"requires": {
|
||||
"ieee754": "^1.1.12",
|
||||
@@ -15359,7 +15359,7 @@
|
||||
},
|
||||
"potpack": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/potpack/-/potpack-1.0.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
|
||||
},
|
||||
"preload": {
|
||||
@@ -15500,7 +15500,7 @@
|
||||
},
|
||||
"protocol-buffers-schema": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
|
||||
"integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
@@ -15613,7 +15613,7 @@
|
||||
},
|
||||
"quickselect": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/quickselect/-/quickselect-2.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
|
||||
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
|
||||
},
|
||||
"quill": {
|
||||
@@ -16116,7 +16116,7 @@
|
||||
},
|
||||
"resolve-protobuf-schema": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
|
||||
"integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
|
||||
"requires": {
|
||||
"protocol-buffers-schema": "^3.3.1"
|
||||
@@ -16493,7 +16493,7 @@
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
|
||||
"integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
|
||||
},
|
||||
"select-hose": {
|
||||
@@ -17603,7 +17603,7 @@
|
||||
},
|
||||
"supercluster": {
|
||||
"version": "7.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/supercluster/-/supercluster-7.1.5.tgz",
|
||||
"resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
|
||||
"integrity": "sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==",
|
||||
"requires": {
|
||||
"kdbush": "^3.0.0"
|
||||
@@ -18405,7 +18405,7 @@
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
|
||||
},
|
||||
"tinycolor2": {
|
||||
@@ -18415,13 +18415,13 @@
|
||||
},
|
||||
"tinyqueue": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/tinyqueue/-/tinyqueue-2.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz",
|
||||
"integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA=="
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz",
|
||||
"integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=",
|
||||
"integrity": "sha512-89PTqMWGDva+GqClOqBV9s3SMh7MA3Mq0pJUdAoHuF65YoE7O0LermaZkVfT5/Ngfo18H4eYiyG7zKOtnEbxsw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"os-tmpdir": "~1.0.1"
|
||||
@@ -19073,7 +19073,7 @@
|
||||
},
|
||||
"vt-pbf": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/vt-pbf/-/vt-pbf-3.1.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz",
|
||||
"integrity": "sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==",
|
||||
"requires": {
|
||||
"@mapbox/point-geometry": "0.1.0",
|
||||
@@ -19088,7 +19088,7 @@
|
||||
},
|
||||
"vue-clipboard2": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-clipboard2/-/vue-clipboard2-0.3.3.tgz",
|
||||
"resolved": "https://registry.npmmirror.com/vue-clipboard2/-/vue-clipboard2-0.3.3.tgz",
|
||||
"integrity": "sha512-aNWXIL2DKgJyY/1OOeITwAQz1fHaCIGvUFHf9h8UcoQBG5a74MkdhS/xqoYe7DNZdQmZRL+TAdIbtUs9OyVjbw==",
|
||||
"requires": {
|
||||
"clipboard": "^2.0.0"
|
||||
|
||||
4066
nezha-fronted/src/assets/css/animate.css
vendored
Normal file
4066
nezha-fronted/src/assets/css/animate.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -565,7 +565,7 @@ textarea {
|
||||
.el-dialog__header{
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
#entranceHtml {
|
||||
#entrance {
|
||||
.el-icon-arrow-right {
|
||||
font-family: "nz-icon" !important;
|
||||
font-size: 16px;
|
||||
@@ -576,6 +576,12 @@ textarea {
|
||||
.el-icon-arrow-right:before {
|
||||
content: "\e6ad";
|
||||
}
|
||||
.el-icon-arrow-up{
|
||||
font-family: nz-icon!important;
|
||||
}
|
||||
.el-icon-arrow-up:before{
|
||||
content: "\e6af";
|
||||
}
|
||||
.el-icon-arrow-down{
|
||||
font-family: nz-icon!important;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
color: $--color-primary;
|
||||
}
|
||||
.nz-btn.nz-btn-style-normal:hover:not(.nz-btn-disabled) { /* 橙色按钮hover */
|
||||
background: $--button-primary-hover-background-color;
|
||||
background: $--button-primary-hover-background-color !important;
|
||||
color: $--button-primary-color;
|
||||
border: 1px solid $--button-primary-hover-background-color;
|
||||
}
|
||||
|
||||
@@ -449,7 +449,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.endpoint-query-metrics.chart-fullscreen.nz-dialog {
|
||||
.endpoint-query-metrics.chart-fullscreen.nz-dialog,.recordRules-query-metrics.chart-fullscreen.nz-dialog {
|
||||
.chart-screen-header .chart-header__tools #browser-go {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
211
nezha-fronted/src/assets/css/components/cli/fileDirectory.scss
Normal file
211
nezha-fronted/src/assets/css/components/cli/fileDirectory.scss
Normal file
@@ -0,0 +1,211 @@
|
||||
.fileDirectory {
|
||||
width: 45%;
|
||||
min-width: 700px;
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
height: calc(100% + 30px);
|
||||
right: -15px;
|
||||
background: $--background-color-empty;
|
||||
box-shadow: 5px 0 3px 0 $--explore-border-color-bottom;
|
||||
z-index: 10;
|
||||
font-size: 14px;
|
||||
.file-directory-header{
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
background: $--background-color-empty;
|
||||
border-bottom: 1px solid rgba(51,51,51,0.10);
|
||||
box-sizing: border-box;
|
||||
color:$--color-text-regular;
|
||||
.header-option{
|
||||
>i {
|
||||
margin-right: 22px;
|
||||
}
|
||||
.nz-icon-close {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.file-directory-path{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
background: $--background-color-empty;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
box-sizing: border-box;
|
||||
color:$--color-text-regular;
|
||||
.breadcrumb-box{
|
||||
.nz-icon-edit{
|
||||
margin-left: 15px;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.breadcrumb-box:hover {
|
||||
.nz-icon-edit{
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.nz-icon-edit:hover{
|
||||
color: $--color-primary;
|
||||
cursor: pointer;
|
||||
}
|
||||
.breadcrumb-item{
|
||||
color:$--color-text-regular
|
||||
}
|
||||
.breadcrumb-action{
|
||||
cursor: pointer;
|
||||
}
|
||||
.breadcrumb-action:hover{
|
||||
color: $--color-primary;
|
||||
}
|
||||
.path-option{
|
||||
display: inline-block;
|
||||
align-items: center;
|
||||
.nz-icon-a-newfolder{
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.el-input--suffix .el-input__inner{
|
||||
padding-right: 106px;
|
||||
}
|
||||
}
|
||||
.file-directory-content{
|
||||
height: calc(100% - 60px);
|
||||
width: calc(100% - 15px);
|
||||
overflow: auto;
|
||||
}
|
||||
//.file-state-panel-content::-webkit-scrollbar {
|
||||
// width: 6px;
|
||||
//}
|
||||
//.file-directory-content::-webkit-scrollbar-thumb {
|
||||
// width: 6px;
|
||||
//}
|
||||
//.file-directory-content::-webkit-scrollbar-thumb:hover {
|
||||
// width: 6px;
|
||||
//}
|
||||
.directory-content-header{
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background: $--background-color-2;
|
||||
width: calc(100% - 22px);
|
||||
color: $--color-text-regular;
|
||||
> div{text-transform:capitalize};
|
||||
}
|
||||
.file-name{
|
||||
width: 44%;
|
||||
box-sizing: border-box;
|
||||
padding-left: 10px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
.nz-icon-link{
|
||||
position: absolute;
|
||||
font-size: 10px;
|
||||
left: 7px;
|
||||
bottom: -5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
.file-size{
|
||||
width: 15%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.file-date{
|
||||
width: 25%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.file-opt{
|
||||
width: 14%;
|
||||
display: inline-block;
|
||||
.nz-icon-shuxing{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
.file-arrow-header{
|
||||
display: inline-flex;align-items: center;width: 100%
|
||||
}
|
||||
.nz-arrow-box{
|
||||
display: flex;flex-direction: column;align-items: center;margin-left: 7px
|
||||
}
|
||||
.nz-arrow-up{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.nz-arrow-up.is-select{
|
||||
border-bottom:5px solid $--color-primary; /* 定义底部颜色 */
|
||||
}
|
||||
.nz-arrow-down.is-select{
|
||||
border-top:5px solid $--color-primary; /* 定义底部颜色 */
|
||||
}
|
||||
.nz-icon-caret-up {
|
||||
position: absolute;
|
||||
}
|
||||
.nz-icon-caret-down {
|
||||
position: absolute;
|
||||
}
|
||||
.file-item{
|
||||
font-family: Roboto-Regular;
|
||||
font-size: 14px;
|
||||
color: $--color-text-regular;
|
||||
font-weight: 400;
|
||||
margin-top: 8px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.file-item:hover{
|
||||
background: rgba(255,134,0,0.50);
|
||||
font-family: Roboto-Regular;
|
||||
}
|
||||
.my-loading-box{
|
||||
background: #1a1a1a;
|
||||
}
|
||||
.nz-icon:hover{
|
||||
color: $--color-primary;
|
||||
}
|
||||
.file-info-item-header{
|
||||
padding-bottom: 20px; border-bottom: 1px solid $--border-color-light;
|
||||
}
|
||||
.file-info-item{
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
align-items: center;
|
||||
|
||||
.file-info-item-left{
|
||||
width: 180px;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.file-info-item-right{
|
||||
width: 200px;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
div.nz-arrow-up {
|
||||
width:0px;
|
||||
height:0px;
|
||||
border-left:5px solid transparent; /* 右透明 */
|
||||
border-right:5px solid transparent; /*右透明 */
|
||||
border-bottom:5px solid $--color-text-disabled; /* 定义底部颜色 */
|
||||
font-size:0px;
|
||||
line-height:0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* css3三角形(向下 ▼) */
|
||||
div.nz-arrow-down {
|
||||
width:0px;
|
||||
height:0px;
|
||||
border-left:5px solid transparent;
|
||||
border-right:5px solid transparent;
|
||||
border-top:5px solid $--color-text-disabled;
|
||||
font-size:0px;
|
||||
line-height:0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
129
nezha-fronted/src/assets/css/components/cli/fileListState.scss
Normal file
129
nezha-fronted/src/assets/css/components/cli/fileListState.scss
Normal file
@@ -0,0 +1,129 @@
|
||||
.file-state-panel{
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
right:0;
|
||||
top:-100px;
|
||||
max-height: 246px;
|
||||
min-width: 96px;
|
||||
width: 308px;
|
||||
background: $--background-color-empty;
|
||||
box-shadow: -2px 1px 4px 0 rgba(0,0,0,0.06), 1px 1px 4px -1px rgba(0,0,0,0.16);
|
||||
border-radius: 2px;
|
||||
.file-state-panel-content::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
.file-state-panel-content::-webkit-scrollbar-thumb {
|
||||
background: rgba(0,0,0,0.16);
|
||||
border-radius: 4px;
|
||||
border:none
|
||||
}
|
||||
.file-state-panel-content::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0,0,0,0.16);
|
||||
border-radius: 4px;
|
||||
border:none
|
||||
}
|
||||
.file-state-panel-header{
|
||||
height: 48px;
|
||||
background: $--background-color-empty;
|
||||
box-shadow: 0 1px 0 0 $--background-color-disabled;
|
||||
padding: 0 20px;
|
||||
line-height: 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
text-transform: capitalize;
|
||||
> i {
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
}
|
||||
.file-state-panel-title{
|
||||
font-size: 14px;
|
||||
letter-spacing: 0;
|
||||
font-weight: 500;
|
||||
text-transform: capitalize;
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
.file-state-panel-content {
|
||||
min-height: 50px;
|
||||
max-height: 180px;
|
||||
line-height: 48px;
|
||||
padding-bottom: 15px;
|
||||
border-radius: 0 0 2px 2px;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
.file-state-panel-item{
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 3px 14px 3px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
.item-icon{
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: $--background-color-base;
|
||||
border-radius: 2px;
|
||||
color: $--color-text-regular;
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-shrink:0;
|
||||
}
|
||||
.item-progress{
|
||||
width: calc(100% - 86px);
|
||||
flex: 1;
|
||||
margin: 0 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.item-progress-top{
|
||||
width: 100%;
|
||||
color: $--color-text-regular;
|
||||
height: 15px;
|
||||
line-height: 15px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.item-progress-middle{
|
||||
}
|
||||
.item-progress-bottom{
|
||||
margin-top: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 10px;
|
||||
color: $--color-text-secondary;
|
||||
line-height: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
.item-state{
|
||||
flex-shrink:0;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
color: $--color-text-regular;
|
||||
line-height: 28px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.file-nodata{
|
||||
text-align: center;
|
||||
color: #b7b7b7;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 15px;
|
||||
.table-no-data__title{
|
||||
text-align: center;
|
||||
color: #b7b7b7;
|
||||
}
|
||||
}
|
||||
.translationOriginUp{
|
||||
transform-origin: 70% 100%
|
||||
}
|
||||
.translationOriginDown{
|
||||
transform-origin: 70% 0%
|
||||
}
|
||||
.el-progress-bar__outer{
|
||||
background-color: $--el-progress-bar__outer;
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,21 @@
|
||||
background: #000 !important;
|
||||
left: -2px;
|
||||
}
|
||||
.right-tip {
|
||||
position: absolute;
|
||||
left: 9px;
|
||||
top: -8px;
|
||||
padding: 0 6px;
|
||||
line-height: 15px;
|
||||
height: 15px;
|
||||
background-color: #ba3939;
|
||||
opacity: .9;
|
||||
border-radius: 7px;
|
||||
color: white;
|
||||
font-size: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.shell-service-max {
|
||||
height: 100%;
|
||||
position: fixed !important;
|
||||
@@ -239,6 +253,38 @@
|
||||
.popper__arrow{
|
||||
display: none;
|
||||
}
|
||||
.webshell-box-top{
|
||||
border-bottom: 1px solid rgba(25,25,28,0.10);
|
||||
}
|
||||
.webshell-box-bottom{
|
||||
border-top: 1px solid rgba(25,25,28,0.10);
|
||||
}
|
||||
.webshell-box-item{
|
||||
height: 32px;
|
||||
font-size: 14px;
|
||||
color: $--color-text-primary;
|
||||
letter-spacing: 0;
|
||||
line-height: 32px;
|
||||
.nz-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.webshell-box-item:hover{
|
||||
background: $--background-color-base;
|
||||
color: $--color-primary;
|
||||
}
|
||||
|
||||
}
|
||||
.popover-webshell-new{
|
||||
padding: 0 !important;
|
||||
.webshell-box-top, .webshell-box-bottom{
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.webshell-box-top, .webshell-box-bottom,.webshell-box-item{
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
div.sp-header{
|
||||
display: none;
|
||||
@@ -275,4 +321,13 @@ div.sp-header{
|
||||
.custom-footer {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ternimal-header{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
background: #101010;
|
||||
box-shadow: 0 1px 0 0 #303030;
|
||||
}
|
||||
|
||||
147
nezha-fronted/src/assets/css/components/cli/webSSHNew.scss
Normal file
147
nezha-fronted/src/assets/css/components/cli/webSSHNew.scss
Normal file
@@ -0,0 +1,147 @@
|
||||
.web-terminal-new{
|
||||
height: calc(100vh - 68px);
|
||||
background: $--background-color-base;
|
||||
/*border-top: 1px solid #BEBEBE;*/
|
||||
box-shadow: 0 1px 0 0 $--border-color-light;
|
||||
/deep/ .el-tabs{
|
||||
border: none;
|
||||
height: 100%;
|
||||
width:100%;
|
||||
margin-left:0px;
|
||||
.el-tabs__nav-prev, .el-tabs__nav-next{
|
||||
display: inline-block;
|
||||
background: $--background-color-2 !important;
|
||||
width: 20px;
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
.el-tabs__nav-prev.is-disabled, .el-tabs__nav-next.is-disabled{
|
||||
cursor: pointer !important;
|
||||
display: inline-block;
|
||||
background: $--background-color-2 !important;
|
||||
width: 20px;
|
||||
height: 36px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
.el-tabs__header{
|
||||
height: 36px;
|
||||
width: 100%;
|
||||
.el-tabs__item{
|
||||
height: 36px;
|
||||
transform: translateY(-2px);
|
||||
padding: 0 10px 0 10px;
|
||||
margin-top: 0;
|
||||
border-top: 2px solid transparent;
|
||||
width: 126px;
|
||||
background: $--background-color-empty;
|
||||
line-height: 34px;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
.el-tabs__item-label{
|
||||
display: inline-flex;
|
||||
width: calc(100% - 20px);
|
||||
align-items: center;
|
||||
.active-icon{
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.el-tabs__item-label-name{
|
||||
flex: 1;
|
||||
width: calc(100% - 30px);
|
||||
}
|
||||
}
|
||||
.el-icon-close{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.el-tabs__item.is-active {
|
||||
width: 200px;
|
||||
border-top: 2px solid $--color-primary;
|
||||
font-size: 14px;
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
.icon-reference{
|
||||
display: none;
|
||||
}
|
||||
.el-tabs__item:hover{
|
||||
width: 200px;
|
||||
.icon-reference{
|
||||
display: inline-block;
|
||||
}
|
||||
.el-icon-close{
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.el-tabs__item:last-of-type {
|
||||
height: 36px;
|
||||
padding: 0 5px;
|
||||
border: none;
|
||||
border-top: 2px solid transparent;
|
||||
background: transparent;
|
||||
width: 40px;
|
||||
line-height: 34px;
|
||||
}
|
||||
}
|
||||
.el-tabs__content{
|
||||
height: calc(100% - 36px);
|
||||
background: #000;
|
||||
box-sizing: border-box;
|
||||
overflow: unset;
|
||||
padding: 5px 5px;
|
||||
.el-tab-pane{
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.webTerminal{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
.web-terminal-header{
|
||||
height: 36px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 15px;
|
||||
background: $--background-color-base;
|
||||
box-shadow: inset 0 -1px 0 0 $--dropdown-menu-box-shadow-color;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
color: $--color-text-primary;
|
||||
img {
|
||||
vertical-align: sub;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.right-tip {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 4px;
|
||||
padding: 0 6px;
|
||||
line-height: 15px;
|
||||
height: 15px;
|
||||
background-color: #ba3939;
|
||||
opacity: .9;
|
||||
border-radius: 7px;
|
||||
color: white;
|
||||
font-size: 6px;
|
||||
}
|
||||
.shell-input{
|
||||
input {
|
||||
background: #1E1E1E !important;
|
||||
border: none;
|
||||
}
|
||||
input::input-placeholder{
|
||||
color: #7C7C7C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,21 +97,23 @@
|
||||
}
|
||||
}
|
||||
.nz-btn-group {
|
||||
#endpoint-query-changetime:hover {
|
||||
#endpoint-query-changetime,
|
||||
#recordRules-query-changetime:hover {
|
||||
border: 1px solid $--asset-label-btn-border-color;
|
||||
}
|
||||
.nz-btn.nz-btn-size-normal.nz-btn-style-light.control-icon-unchecked:hover {
|
||||
border: 1px solid $--asset-label-btn-border-color;
|
||||
z-index: 2;
|
||||
}
|
||||
.nz-btn.nz-btn-size-normal.nz-btn-style-light.control-icon-unchecked {
|
||||
.nz-btn.nz-btn-size-normal.nz-btn-style-light.control-icon-unchecked,
|
||||
.nz-btn.nz-btn-size-normal.nz-btn-style-light.control-icon-checked {
|
||||
margin-right: -1px;
|
||||
}
|
||||
.project-calendar.nz-input-group-middle {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-top: 1px solid $--border-color-base;
|
||||
border-bottom: 1px solid $--border-color-base;
|
||||
border-top: 1px solid $--border-color-light;
|
||||
border-bottom: 1px solid $--border-color-light;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -130,7 +132,7 @@
|
||||
.nz-table-list .el-table--border {
|
||||
.gutter {
|
||||
position: fixed;
|
||||
right: 31px;
|
||||
right: 21px;
|
||||
height: 41px;
|
||||
border-bottom: 1px solid $--border-color-light;
|
||||
background-color: $--background-color-empty;
|
||||
@@ -240,6 +242,16 @@
|
||||
border: 0 !important;
|
||||
box-shadow: 0 0 0px 0px rgba(0, 0, 0, 0);
|
||||
}
|
||||
.recordRules-query .sub-container .nz-table-list {
|
||||
height: 100%;
|
||||
}
|
||||
.recordRules-query .bottom-data-list .nz-btn-group .nz-input-group-middle input {
|
||||
border-right: 0 !important;
|
||||
}
|
||||
.recordRules-query .bottom-data-list .nz-btn-group.nz-btn-group-size-normal.nz-btn-group-light {
|
||||
border: 0 !important;
|
||||
box-shadow: 0 0 0px 0px rgba(0, 0, 0, 0);
|
||||
}
|
||||
/* end--二级顶部工具栏*/
|
||||
|
||||
.log-no-data {
|
||||
@@ -257,16 +269,72 @@
|
||||
// process network vsys comment 二级页面
|
||||
#processBottomTab,
|
||||
#networkBottomTab,
|
||||
#vsysBottomTab {
|
||||
#vsysBottomTab,
|
||||
#sftpBottomTab,
|
||||
#terminalLogCMDTab,
|
||||
#recordRuleEvalLog {
|
||||
.sub-container .nz-table-list {
|
||||
height: 100%;
|
||||
}
|
||||
#assetProcessTable,
|
||||
#assetNetworkTable,
|
||||
#assetVsysTable {
|
||||
#assetVsysTable,
|
||||
#terminalLogSftpTable,
|
||||
#recordRuleEvalLogTable {
|
||||
height: calc(100% - 15px) !important;
|
||||
}
|
||||
}
|
||||
|
||||
#assetProcessTable {
|
||||
.el-popover__reference {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.bar {
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
border-radius: 0;
|
||||
margin-right: 0px;
|
||||
line-height: 100%;
|
||||
}
|
||||
.process-name {
|
||||
height: 100%;
|
||||
margin-left: 6px;
|
||||
line-height: 24px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
#container {
|
||||
width: 120px;
|
||||
min-width: 120px;
|
||||
height: 18px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.percentage {
|
||||
flex-grow: 1;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.el-progress-bar__outer {
|
||||
border-radius: 2px;
|
||||
background-color: #e6eaed;
|
||||
}
|
||||
.el-progress-bar__inner {
|
||||
border-radius: 0;
|
||||
}
|
||||
.active-icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
#assetNetworkTable {
|
||||
.process-name {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
// comments
|
||||
#commentBottomTab {
|
||||
.sub-container .nz-table-list {
|
||||
@@ -365,3 +433,10 @@
|
||||
box-sizing: content-box;
|
||||
}
|
||||
}
|
||||
|
||||
//record command 二级页面搜索
|
||||
#terminalLogRecordTab {
|
||||
.pagination-bottom{
|
||||
bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
outline: none;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
button:hover {
|
||||
button:hover:not(.footer__btn) {
|
||||
background: $--background-color-empty;
|
||||
}
|
||||
.nz-btn-style-normal {
|
||||
|
||||
@@ -122,25 +122,39 @@
|
||||
}
|
||||
}
|
||||
.dashboard-select-tail{
|
||||
width: 162px;
|
||||
background: #FF9219;
|
||||
margin: 0 auto;
|
||||
border: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
.dashboard-select-add{
|
||||
width: 88%;
|
||||
flex: 1;
|
||||
height: 30px;
|
||||
background: #FF9219;
|
||||
border-radius: 2px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
i{
|
||||
color: #fff;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
.dashboard-addBy-template{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-left: 1px solid #fff;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
}
|
||||
.pop-item-wider{
|
||||
@@ -166,3 +180,12 @@
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-addBy-template-menu{
|
||||
width: 162px;
|
||||
// padding: 8px 0;
|
||||
box-sizing: border-box;
|
||||
.el-dropdown-menu__item{
|
||||
// line-height: 32px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
.nz-dialog.snapshot-dialog{
|
||||
.el-dialog__header{
|
||||
padding: 15px;
|
||||
padding-right: 40px;
|
||||
border-bottom: 1px solid $--border-color-light;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
.el-dialog__title{
|
||||
font-family: Roboto-Medium;
|
||||
font-size: 16px;
|
||||
color: $--color-text-primary;
|
||||
letter-spacing: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
.el-dialog__body{
|
||||
padding: 20px;
|
||||
padding-bottom: 30px;
|
||||
.snapshot-name,.snapshot-time{
|
||||
font-family: Roboto-Regular;
|
||||
font-size: 14px;
|
||||
color: $--color-text-regular;
|
||||
letter-spacing: 0;
|
||||
font-weight: 400;
|
||||
}
|
||||
.el-progress-bar{
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
.el-progress-bar__outer{
|
||||
height: 20px;
|
||||
border-radius: 0;
|
||||
background-color: $--background-color-2;
|
||||
border: 1px solid $--border-color-light;
|
||||
box-sizing: border-box;
|
||||
overflow: unset;
|
||||
.el-progress-bar__inner{
|
||||
transition: width 0.3s linear;
|
||||
border-radius: 0;
|
||||
background-color:#3B92F1;
|
||||
height: 18px;
|
||||
// height: 20px;
|
||||
// position: absolute;
|
||||
// left: -1px;
|
||||
// top: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.snapshot-elapsed{
|
||||
font-family: Roboto-Black;
|
||||
font-size: 12px;
|
||||
color: $--color-text-regular;
|
||||
letter-spacing: 0;
|
||||
line-height: 17px;
|
||||
font-weight: 400;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.snapshot-msg{
|
||||
font-family: Roboto-Regular;
|
||||
font-size: 14px;
|
||||
color: $--color-text-regular;
|
||||
letter-spacing: 0;
|
||||
line-height: 16px;
|
||||
font-weight: 400;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
.el-dialog__footer{
|
||||
padding: 12px 20px;
|
||||
border-top: 1px solid $--border-color-light;
|
||||
.el-message-box__btns{
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,6 +189,9 @@
|
||||
.sub-box {
|
||||
padding: 0 10px;
|
||||
}
|
||||
.asset-dropdown.right-box-select-top{
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.props-box {
|
||||
.metric-selector-title {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.endpoint-query-tab {
|
||||
.endpoint-query-tab,.recordRules-query-tab {
|
||||
.el-dialog__body {
|
||||
height: calc(100% - 48px) !important;
|
||||
padding-bottom: 0 !important;
|
||||
@@ -31,4 +31,4 @@
|
||||
cursor: not-allowed;
|
||||
background-color: #f4f4f5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
@import './charts/chart.scss';
|
||||
@import './charts/chart-list.scss';
|
||||
@import './cli/webSSH.scss';
|
||||
@import './cli/fileDirectory.scss';
|
||||
@import './cli/fileListState.scss';
|
||||
@import './cli/webSSHNew.scss';
|
||||
@import './common/alert/alertLabel.scss';
|
||||
@import './common/alert/alertStateInfo.scss';
|
||||
@import './common/alert/alertRuleInfo.scss';
|
||||
@@ -26,6 +29,7 @@
|
||||
@import './common/popBox/selectPanel.scss';
|
||||
@import './common/popBox/selectDashboard.scss';
|
||||
@import './common/popBox/selectWalk.scss';
|
||||
@import './common/popBox/snapshotProgress.scss';
|
||||
@import './common/project/popData/Info.scss';
|
||||
@import './common/project/L5/popData/common.scss';
|
||||
@import './common/project/L5/CanvasContextMenu.scss';
|
||||
|
||||
@@ -42,3 +42,9 @@
|
||||
color: $--color-text-primary;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.agent{
|
||||
.message-zindex{
|
||||
z-index: 1000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
margin: 0px;
|
||||
.el-form{
|
||||
.el-form {
|
||||
padding-left: 15px;
|
||||
}
|
||||
.el-tag.el-tag--info {
|
||||
@@ -36,34 +36,52 @@
|
||||
.el-input.el-input--small {
|
||||
width: calc(100% - 49px);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#system-basic{
|
||||
#system-basic {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.el-form-item__content{
|
||||
.el-form-item__content {
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.system-config-form{
|
||||
.system-config-form.basicForm {
|
||||
.vue-tags-input {
|
||||
max-width: unset !important;
|
||||
}
|
||||
.vue-tags-input.interface-name .ti-input{
|
||||
padding: 0px !important;
|
||||
}
|
||||
.vue-tags-input .ti-input {
|
||||
min-height: 32px;
|
||||
padding: 0px 0px 0px 15px !important;
|
||||
}
|
||||
.vue-tags-input .ti-input .ti-new-tag-input-wrapper {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.vue-tags-input.interface-name .ti-input .ti-new-tag-input-wrapper {
|
||||
padding: 5px 0px 5px 7px;
|
||||
}
|
||||
}
|
||||
.system-config-form {
|
||||
width: 61.8% !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.linkBox{
|
||||
.linkBox {
|
||||
max-height: 800px;
|
||||
width: 800px;
|
||||
}
|
||||
.scrollBox{
|
||||
.scrollBox {
|
||||
position: relative;
|
||||
height: 600px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.linkTitle{
|
||||
.linkTitle {
|
||||
display: flex;
|
||||
align-items:center;
|
||||
align-items: center;
|
||||
border-bottom: 2px solid $--border-color-base;
|
||||
color: #6b778c;
|
||||
font-size: 12px;
|
||||
@@ -71,40 +89,40 @@
|
||||
line-height: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.handle{
|
||||
.handle {
|
||||
cursor: move !important;
|
||||
padding:0 5px;
|
||||
padding: 0 5px;
|
||||
line-height: 34px;
|
||||
}
|
||||
.linkBtn{
|
||||
.linkBtn {
|
||||
height: 28px;
|
||||
line-height: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
.linkTitleHandle{
|
||||
.linkTitleHandle {
|
||||
padding: 0 13px;
|
||||
}
|
||||
.linkAddBox{
|
||||
.linkAddBox {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid $--border-color-base;
|
||||
font-size: 13px;
|
||||
line-height: 34px;
|
||||
}
|
||||
.linkContent{
|
||||
.linkContent {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
font-size: 13px;
|
||||
line-height: 34px;
|
||||
}
|
||||
.linkContent:not(:last-child){
|
||||
.linkContent:not(:last-child) {
|
||||
border-bottom: 1px solid $--border-color-base;
|
||||
}
|
||||
.linkFormContent{
|
||||
.linkFormContent {
|
||||
display: flex;
|
||||
line-height: 34px;
|
||||
}
|
||||
.linkTitleName{
|
||||
.linkTitleName {
|
||||
width: 100px;
|
||||
margin-right: 12px;
|
||||
overflow: hidden;
|
||||
@@ -112,12 +130,12 @@
|
||||
white-space: nowrap;
|
||||
height: 31px;
|
||||
}
|
||||
.linkTitleUrl{
|
||||
.linkTitleUrl {
|
||||
width: 462px;
|
||||
margin-right: 12px;
|
||||
height: 31px;
|
||||
}
|
||||
.linkTitleUrlContent{
|
||||
.linkTitleUrlContent {
|
||||
display: inline-block;
|
||||
width: 460px;
|
||||
overflow: hidden;
|
||||
@@ -127,39 +145,39 @@
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
.linkFormBtn .nz-icon-delete{
|
||||
.linkFormBtn .nz-icon-delete {
|
||||
cursor: pointer;
|
||||
color: $--color-primary;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.linkFormBtn .nz-icon-edit{
|
||||
.linkFormBtn .nz-icon-edit {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.nz-icon-create-square{
|
||||
.nz-icon-create-square {
|
||||
cursor: pointer;
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
.el-form-item--small .el-form-item__error{
|
||||
.el-form-item--small .el-form-item__error {
|
||||
padding-top: 0;
|
||||
}
|
||||
.linkUrlTip{
|
||||
.linkUrlTip {
|
||||
width: 430px;
|
||||
}
|
||||
.system-config-form.terminal .el-input-number--small{
|
||||
.system-config-form.terminal .el-input-number--small {
|
||||
width: 512px;
|
||||
}
|
||||
.system-config-form.basicForm .el-input-number--small{
|
||||
.system-config-form.basicForm .el-input-number--small {
|
||||
width: 512px;
|
||||
}
|
||||
.system-config-form .el-input input{
|
||||
.system-config-form .el-input input {
|
||||
text-align: left;
|
||||
}
|
||||
.utc-item {
|
||||
color: $--color-text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
.system-title{
|
||||
.system-title {
|
||||
font-size: 14px;
|
||||
color: $--color-text-regular;
|
||||
letter-spacing: 0;
|
||||
@@ -168,7 +186,7 @@
|
||||
font-weight: 500;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.system-title-border{
|
||||
.system-title-border {
|
||||
border-top: 1px dashed $--border-color-light;
|
||||
padding-top: 30px;
|
||||
width: 699px;
|
||||
@@ -178,19 +196,25 @@
|
||||
background-color: $--background-color-empty;
|
||||
padding: 10px;
|
||||
.el-form-item:last-of-type.monitorLastEle {
|
||||
.el-form-item__content{
|
||||
.el-form-item__content {
|
||||
margin-left: 180px !important;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.el-tabs__nav-scroll{
|
||||
.el-form-item:last-of-type.monitorLastElement {
|
||||
.el-form-item__content {
|
||||
margin-left: 180px !important;
|
||||
}
|
||||
}
|
||||
.el-tabs__nav-scroll {
|
||||
background-color: $--background-color-empty;
|
||||
}
|
||||
.el-tabs__nav-scroll,.el-tabs__header,.el-tabs__nav-wrap{
|
||||
.el-tabs__nav-scroll,
|
||||
.el-tabs__header,
|
||||
.el-tabs__nav-wrap {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.el-form-item:last-of-type {
|
||||
|
||||
.el-form-item__content {
|
||||
margin-left: 0 !important;
|
||||
text-align: center;
|
||||
@@ -200,13 +224,14 @@
|
||||
}
|
||||
}
|
||||
.full-table {
|
||||
.el-tabs__content{
|
||||
height: calc( 100% - 100px);
|
||||
.el-tabs__content {
|
||||
height: calc(100% - 100px);
|
||||
}
|
||||
.list-page .main-container{
|
||||
.list-page .main-container {
|
||||
padding: unset;
|
||||
}
|
||||
.table-column-setting,.pagination-bottom{
|
||||
.table-column-setting,
|
||||
.pagination-bottom {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -218,17 +243,17 @@
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active {
|
||||
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
|
||||
color: $--color-primary;
|
||||
background: $--background-color-empty;
|
||||
border-bottom: none;
|
||||
margin-left: .1px;
|
||||
margin-left: 0.1px;
|
||||
}
|
||||
.el-tabs--border-card>.el-tabs__header .el-tabs__item:not(.is-disabled):hover {
|
||||
.el-tabs--border-card > .el-tabs__header .el-tabs__item:not(.is-disabled):hover {
|
||||
color: $--color-primary;
|
||||
opacity: .8;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.el-tabs--border-card>.el-tabs__header .el-tabs__item {
|
||||
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
|
||||
height: 40px;
|
||||
background: $--background-color-base;
|
||||
border: 1px solid $--border-color-light;
|
||||
@@ -236,7 +261,7 @@
|
||||
border-top-right-radius: 4px;
|
||||
margin-top: 0;
|
||||
}
|
||||
.el-tabs--border-card>.el-tabs__header .el-tabs__item:not(:first-child) {
|
||||
.el-tabs--border-card > .el-tabs__header .el-tabs__item:not(:first-child) {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.el-input-group__prepend {
|
||||
@@ -249,7 +274,10 @@
|
||||
border: 1px solid $--border-color-light;
|
||||
border-left: none;
|
||||
}
|
||||
.el-input-number__decrease,.el-input-number__increase,.el-input-number__decrease.is-disabled,.el-input-number__increase.is-disabled {
|
||||
.el-input-number__decrease,
|
||||
.el-input-number__increase,
|
||||
.el-input-number__decrease.is-disabled,
|
||||
.el-input-number__increase.is-disabled {
|
||||
background-color: $--popover-background-color;
|
||||
}
|
||||
.el-input-number__decrease {
|
||||
@@ -273,21 +301,21 @@
|
||||
border-color: $--color-primary;
|
||||
}
|
||||
}
|
||||
.system-config-form .el-form-item__content{
|
||||
.system-config-form .el-form-item__content {
|
||||
width: 512px;
|
||||
}
|
||||
|
||||
.system-config-form .el-input{
|
||||
.system-config-form .el-input {
|
||||
width: 512px;
|
||||
text-align: left;
|
||||
}
|
||||
.system-tabs {
|
||||
box-shadow: unset !important;
|
||||
border:unset;
|
||||
border: unset;
|
||||
border-top: unset;
|
||||
height: 100%;
|
||||
}
|
||||
.system-tabs.el-tabs--border-card{
|
||||
.system-tabs.el-tabs--border-card {
|
||||
box-shadow: unset !important;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
@@ -295,7 +323,7 @@
|
||||
border-left: unset;
|
||||
background-color: $--background-color-empty;
|
||||
}
|
||||
.reset-form .el-checkbox-group{
|
||||
.reset-form .el-checkbox-group {
|
||||
margin-left: -28px !important;
|
||||
}
|
||||
.el-form-item__tip {
|
||||
@@ -318,22 +346,32 @@
|
||||
margin-bottom: 54px;
|
||||
}
|
||||
@keyframes warnBackground {
|
||||
0% {background-color: #FFFFFF;}
|
||||
25% {background-color: #EF7458;}
|
||||
50% {background-color: #FFFFFF;}
|
||||
75% {background-color: #EF7458;}
|
||||
100% {background-color: #FFFFFF;}
|
||||
0% {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
25% {
|
||||
background-color: #ef7458;
|
||||
}
|
||||
50% {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
75% {
|
||||
background-color: #ef7458;
|
||||
}
|
||||
100% {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
}
|
||||
.warn-pop {
|
||||
background-color: #FEF0F0;
|
||||
border-color: #FEF0F0;
|
||||
color:#F66C6C;
|
||||
background-color: #fef0f0;
|
||||
border-color: #fef0f0;
|
||||
color: #f66c6c;
|
||||
}
|
||||
.warn-pop .popper__arrow:after{
|
||||
border-top-color: #FEF0F0 !important;
|
||||
.warn-pop .popper__arrow:after {
|
||||
border-top-color: #fef0f0 !important;
|
||||
}
|
||||
.system .logo-upload-tip{
|
||||
color:#F66C6C;
|
||||
.system .logo-upload-tip {
|
||||
color: #f66c6c;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
.el-pagination{
|
||||
font-size: 14px;
|
||||
.btn-prev, .btn-next{
|
||||
color: $--background-color-empty;
|
||||
color: $--color-text-regular;
|
||||
font-size: 14px;
|
||||
margin: 0 5px;
|
||||
border: none;
|
||||
@@ -195,6 +195,9 @@
|
||||
.el-dialog__headerbtn{
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
.el-dialog__body{
|
||||
|
||||
}
|
||||
.el-button{
|
||||
//background-color: $--background-color-1 !important;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
border: 1px solid $--border-color-light;
|
||||
}
|
||||
}
|
||||
.not-fixed-height.no-resize.no-close{
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.query-row {
|
||||
display: flex;
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
|
||||
.date-pick-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,6 +5,153 @@
|
||||
"css_prefix_text": "nz-icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "680988",
|
||||
"name": "属性",
|
||||
"font_class": "shuxing",
|
||||
"unicode": "e785",
|
||||
"unicode_decimal": 59269
|
||||
},
|
||||
{
|
||||
"icon_id": "33167519",
|
||||
"name": "套接字文件",
|
||||
"font_class": "taojieziwenjian",
|
||||
"unicode": "e7bb",
|
||||
"unicode_decimal": 59323
|
||||
},
|
||||
{
|
||||
"icon_id": "33166559",
|
||||
"name": "目录链接",
|
||||
"font_class": "mululianjie",
|
||||
"unicode": "e7b9",
|
||||
"unicode_decimal": 59321
|
||||
},
|
||||
{
|
||||
"icon_id": "33165863",
|
||||
"name": "套接字文件链接",
|
||||
"font_class": "taojieziwenjianlianjie",
|
||||
"unicode": "e7ba",
|
||||
"unicode_decimal": 59322
|
||||
},
|
||||
{
|
||||
"icon_id": "33158668",
|
||||
"name": "文件链接",
|
||||
"font_class": "wenjianlianjie",
|
||||
"unicode": "e7b5",
|
||||
"unicode_decimal": 59317
|
||||
},
|
||||
{
|
||||
"icon_id": "33158669",
|
||||
"name": "管道文件链接",
|
||||
"font_class": "guandaowenjianlianjie",
|
||||
"unicode": "e7b6",
|
||||
"unicode_decimal": 59318
|
||||
},
|
||||
{
|
||||
"icon_id": "33158670",
|
||||
"name": "块设备文件链接",
|
||||
"font_class": "kuaishebeiwenjianlianjie",
|
||||
"unicode": "e7b7",
|
||||
"unicode_decimal": 59319
|
||||
},
|
||||
{
|
||||
"icon_id": "33158671",
|
||||
"name": "字符串设备文件链接",
|
||||
"font_class": "zifuchuanshebeiwenjianlianjie",
|
||||
"unicode": "e7b8",
|
||||
"unicode_decimal": 59320
|
||||
},
|
||||
{
|
||||
"icon_id": "33158636",
|
||||
"name": "管道文件",
|
||||
"font_class": "guandaowenjian",
|
||||
"unicode": "e7b1",
|
||||
"unicode_decimal": 59313
|
||||
},
|
||||
{
|
||||
"icon_id": "33158637",
|
||||
"name": "链接文件",
|
||||
"font_class": "lianjiewenjian",
|
||||
"unicode": "e7b2",
|
||||
"unicode_decimal": 59314
|
||||
},
|
||||
{
|
||||
"icon_id": "33158639",
|
||||
"name": "块设备文件",
|
||||
"font_class": "kuaishebeiwenjian",
|
||||
"unicode": "e7b3",
|
||||
"unicode_decimal": 59315
|
||||
},
|
||||
{
|
||||
"icon_id": "33158641",
|
||||
"name": "字符设备文件",
|
||||
"font_class": "zifushebeiwenjian",
|
||||
"unicode": "e7b4",
|
||||
"unicode_decimal": 59316
|
||||
},
|
||||
{
|
||||
"icon_id": "33112141",
|
||||
"name": "home",
|
||||
"font_class": "home",
|
||||
"unicode": "e7af",
|
||||
"unicode_decimal": 59311
|
||||
},
|
||||
{
|
||||
"icon_id": "32964483",
|
||||
"name": "File",
|
||||
"font_class": "File",
|
||||
"unicode": "e7ae",
|
||||
"unicode_decimal": 59310
|
||||
},
|
||||
{
|
||||
"icon_id": "32961611",
|
||||
"name": "Clear",
|
||||
"font_class": "Clear",
|
||||
"unicode": "e7b0",
|
||||
"unicode_decimal": 59312
|
||||
},
|
||||
{
|
||||
"icon_id": "32660007",
|
||||
"name": "Folder ",
|
||||
"font_class": "Folder",
|
||||
"unicode": "e7ad",
|
||||
"unicode_decimal": 59309
|
||||
},
|
||||
{
|
||||
"icon_id": "32659266",
|
||||
"name": "file transfer",
|
||||
"font_class": "a-filetransfer",
|
||||
"unicode": "e7a7",
|
||||
"unicode_decimal": 59303
|
||||
},
|
||||
{
|
||||
"icon_id": "32659269",
|
||||
"name": "reconnect",
|
||||
"font_class": "reconnect",
|
||||
"unicode": "e7a8",
|
||||
"unicode_decimal": 59304
|
||||
},
|
||||
{
|
||||
"icon_id": "32659270",
|
||||
"name": "upper level",
|
||||
"font_class": "a-upperlevel",
|
||||
"unicode": "e7a9",
|
||||
"unicode_decimal": 59305
|
||||
},
|
||||
{
|
||||
"icon_id": "32659271",
|
||||
"name": "new folder",
|
||||
"font_class": "a-newfolder",
|
||||
"unicode": "e7aa",
|
||||
"unicode_decimal": 59306
|
||||
},
|
||||
{
|
||||
"icon_id": "32659272",
|
||||
"name": "SFTP",
|
||||
"font_class": "SFTP",
|
||||
"unicode": "e7ab",
|
||||
"unicode_decimal": 59307
|
||||
},
|
||||
{
|
||||
"icon_id": "586976",
|
||||
"name": "map-sankey",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -74,7 +74,7 @@
|
||||
|
||||
.el-icon {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-size: 12px !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,8 @@ $--tooltip-background-color: #222329;
|
||||
$--tooltip-border-color: rgba(112,116,122,0.6);
|
||||
/* 17.label*/
|
||||
$--label-background-color: $--background-color-empty;
|
||||
|
||||
/* 18 进度条颜色 */
|
||||
$--el-progress-bar__outer: #19191C;
|
||||
/*** themes/common.scss是与主题切换无关的变量 ***/
|
||||
@import './src/common/var.scss';
|
||||
@import './common.scss';
|
||||
|
||||
@@ -254,7 +254,8 @@ $--tooltip-background-color: #ffffff;
|
||||
$--tooltip-border-color: rgba(119,131,145,0.6);
|
||||
/* 17.label*/
|
||||
$--label-background-color: #D8d8d8;
|
||||
|
||||
/* 18 进度条颜色 */
|
||||
$--el-progress-bar__outer: #ebeef5;
|
||||
/*** themes/common.scss是与主题切换无关的变量 ***/
|
||||
@import './src/common/var.scss';
|
||||
@import './common.scss';
|
||||
|
||||
@@ -1270,6 +1270,10 @@ li {
|
||||
&>span{
|
||||
margin-right: 12px;
|
||||
}
|
||||
.exists-select{
|
||||
top: auto !important;
|
||||
left: auto !important;
|
||||
}
|
||||
}
|
||||
.import-select-list{
|
||||
.import-select-item{
|
||||
@@ -1282,7 +1286,7 @@ li {
|
||||
}
|
||||
.import-failContent-dialog{
|
||||
.el-dialog__header{
|
||||
padding: 14px;
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid $--border-color-light;
|
||||
}
|
||||
.el-dialog__body{
|
||||
@@ -1314,9 +1318,9 @@ li {
|
||||
}
|
||||
}
|
||||
.result-detail{
|
||||
height: 182px;
|
||||
height: 184px;
|
||||
margin: 10px 0;
|
||||
padding: 16px 0;
|
||||
padding: 18px 0;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
&>div{
|
||||
@@ -1325,7 +1329,7 @@ li {
|
||||
.nz-icon-override{
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
top: 3px;
|
||||
right: 15px;
|
||||
}
|
||||
.import-result-item {
|
||||
@@ -1415,7 +1419,7 @@ li {
|
||||
.dropdown-item-active {
|
||||
color: $--color-primary !important;
|
||||
font-weight: bold;
|
||||
background-color: #FAFAFA;
|
||||
background-color: $--background-color-base;
|
||||
}
|
||||
.el-dropdown-multi .el-dropdown-menu__item:focus {
|
||||
color: $--color-text-regular;
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
:close-delay=10
|
||||
trigger="hover"
|
||||
popper-class="chart-error-popper">
|
||||
<div >{{errorText}}</div>
|
||||
<span slot="reference" class="panel-info-corner panel-info-corner--error">
|
||||
<i class="nz-icon nz-icon-warning fa"></i>
|
||||
<span class="panel-info-corner-inner"></span>
|
||||
</span>
|
||||
</el-popover>
|
||||
<div >{{errorText}}</div>
|
||||
<span slot="reference" class="panel-info-corner panel-info-corner--error">
|
||||
<i class="nz-icon nz-icon-warning fa"></i>
|
||||
<span class="panel-info-corner-inner"></span>
|
||||
</span>
|
||||
</el-popover>
|
||||
</span>
|
||||
<span v-if="!isError&&!showAllData&&allDataLength>20" class="chart-header-error moreTitle">
|
||||
<el-popover
|
||||
@@ -20,16 +20,16 @@
|
||||
:close-delay=10
|
||||
trigger="hover"
|
||||
popper-class="chart-warring-popper">
|
||||
<div class="moreTitle" @click="loadMore">{{$t('dashboard.panel.moreTitle')}}{{$t('dashboard.panel.showAll')}}{{allDataLength}}</div>
|
||||
<span slot="reference" class="panel-info-corner panel-info-corner--error" @click="loadMore">
|
||||
<i class="nz-icon nz-icon-warning fa"></i>
|
||||
<span class="panel-info-corner-inner"></span>
|
||||
</span>
|
||||
<div class="moreTitle" @click="loadMore">{{$t('dashboard.panel.moreTitle')}}{{$t('dashboard.panel.showAll')}}{{allDataLength}}</div>
|
||||
<span slot="reference" class="panel-info-corner panel-info-corner--error" @click="loadMore">
|
||||
<i class="nz-icon nz-icon-warning fa"></i>
|
||||
<span class="panel-info-corner-inner"></span>
|
||||
</span>
|
||||
</el-popover>
|
||||
</span>
|
||||
<div class="chart-header__title" :title="chartInfo.name">
|
||||
<div class="chart-header__title" :title="nameFormate">
|
||||
<slot name="title-icon"></slot>
|
||||
{{chartInfo.name}}
|
||||
{{nameFormate}}
|
||||
</div>
|
||||
<div class="chart-header__tools">
|
||||
<span v-if="chartInfo.remark" class="chart-header__tool top-tool-btn-group">
|
||||
@@ -51,7 +51,7 @@
|
||||
></pick-time>
|
||||
</span>
|
||||
<span class="chart-header__tool" v-if="showSaveBtn(from)">
|
||||
<button id="endpoint-query-full-chart-save" v-has="'main_add'" class="nz-btn nz-btn-size-large nz-btn-style-normal" @click="saveChart">{{$t('dashboard.metric.saveChart')}}</button>
|
||||
<button id="endpoint-query-full-chart-save" v-has="'main_add'" class="nz-btn nz-btn-size-large nz-btn-style-normal" @click="saveChart">{{$t('dashboard.metric.saveChart')}}</button>
|
||||
</span>
|
||||
<span class="chart-header__tool" @click="closeDialog" :title="$t('overall.close')">
|
||||
<i class="nz-icon nz-icon-close" style="font-size: 16px;"></i>
|
||||
@@ -159,6 +159,7 @@ export default {
|
||||
showUnit (type) {
|
||||
switch (type) {
|
||||
case 'endpointQuery' :
|
||||
case 'recordRulesQuery' :
|
||||
return true
|
||||
default: return false
|
||||
}
|
||||
@@ -166,6 +167,7 @@ export default {
|
||||
showSaveBtn (type) {
|
||||
switch (type) {
|
||||
case 'endpointQuery' :
|
||||
case 'recordRulesQuery' :
|
||||
return true
|
||||
default: return false
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ const unitOptions = [
|
||||
}
|
||||
]
|
||||
const units = []
|
||||
window.onload = function () {
|
||||
window.addEventListener('load', function () {
|
||||
if (units.length < 1) {
|
||||
unitOptions.forEach((item, index) => {
|
||||
item.children.forEach((n, i) => {
|
||||
@@ -707,8 +707,7 @@ window.onload = function () {
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
export default {
|
||||
unitOptions: function () {
|
||||
return unitOptions
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
</span>
|
||||
</el-popover>
|
||||
</span>
|
||||
<div class="chart-header__title" v-if="!isGroup" :title="chartInfo.name">{{chartInfo.name}}</div>
|
||||
<div class="chart-header__title" v-if="!isGroup" :title="nameFormate">{{nameFormate}}</div>
|
||||
<div class="chart-header__title groupTitle" v-else >
|
||||
<span @click="groupShow"> <i class="nz-icon" :class="chartInfo.param.collapse ? 'nz-icon-arrow-right': 'nz-icon-arrow-down'"></i></span>
|
||||
{{chartInfo.name}}
|
||||
<span @click="groupShow" style="cursor:pointer"> <i class="nz-icon" :class="chartInfo.param.collapse ? 'nz-icon-arrow-right': 'nz-icon-arrow-down'"></i></span>
|
||||
{{nameFormate}}
|
||||
<span v-show="chartInfo.param.collapse" class="collapse-content">({{chartData ? chartData.length : 0}} charts)</span>
|
||||
</div>
|
||||
<div class="temp"></div>
|
||||
@@ -56,7 +56,7 @@
|
||||
<i class="nz-icon nz-icon-info-normal tool__icon"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<span v-if="chartInfo.type=='group'" class="chart-header__tool" @click="addChartGroup">
|
||||
<span v-if="chartInfo.type=='group'&&!chartInfo.repeatIndex" class="chart-header__tool" @click="addChartGroup">
|
||||
<!-- <el-tooltip :content="$t('button.add')" effect="light" placement="top" > -->
|
||||
<i class="nz-icon nz-icon-plus tool__icon" :title="$t('tip.add')"></i>
|
||||
<!-- </el-tooltip> -->
|
||||
@@ -71,7 +71,7 @@
|
||||
<i class="nz-icon nz-icon-maxview tool__icon"></i>
|
||||
</div>
|
||||
</span>
|
||||
<span class="chart-header__tool">
|
||||
<span class="chart-header__tool" v-if="!chartInfo.repeatIndex">
|
||||
<el-dropdown v-clickoutside="clickos" v-has="['main_edit','main_delete','main_add']" trigger="click">
|
||||
<i class="el-icon-more tool__icon" @click.stop="dropdownMenuShow = !dropdownMenuShow" :title="$t('overall.more')"></i>
|
||||
<el-dropdown-menu style="display: none" class="temp-dropdown"></el-dropdown-menu>
|
||||
|
||||
@@ -86,6 +86,39 @@ export default {
|
||||
this.$emit('unitChange', val)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
variablesArr () {
|
||||
return this.$store.getters.getVariablesArr
|
||||
},
|
||||
// 所有类型 chart name 支持变量替换
|
||||
nameFormate () {
|
||||
let str = this.chartInfo.name
|
||||
// group图表设置repeat的name替换
|
||||
if (this.chartInfo.repeatVariable) {
|
||||
const variable = this.chartInfo.repeatVariable
|
||||
const reg = new RegExp('\\$' + variable, 'g')
|
||||
str = str.replace(reg, this.chartInfo.repeatValue.replace(/\\"/g, '"').replace(/\\'/g, "'"))
|
||||
}
|
||||
let confirmReg = []
|
||||
this.variablesArr.forEach(item => {
|
||||
const reg = '$' + item.name // 后续需要考虑 item,name 使用特殊字符的问题
|
||||
const index = this.chartInfo.name.indexOf(reg)
|
||||
if (index !== -1) {
|
||||
confirmReg.push(item)
|
||||
}
|
||||
})
|
||||
confirmReg = this.$loadsh.orderBy(confirmReg, function (item) { // 根据 匹配的name的长度排序 避免匹配的 $a 没匹配 $asset的问题
|
||||
return item.name.length
|
||||
}, 'desc')
|
||||
if (confirmReg.length) {
|
||||
confirmReg.forEach(item => {
|
||||
const reg = new RegExp('\\$' + item.name, 'g') // 后续需要考虑 item,name 使用特殊字符的问题
|
||||
str = str.replace(reg, item.checked.map(label => label.replace(/\\"/g, '"').replace(/\\'/g, "'")).join('+'))
|
||||
})
|
||||
}
|
||||
return str
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isError: {
|
||||
immediate: true,
|
||||
|
||||
@@ -243,7 +243,7 @@ export default {
|
||||
},
|
||||
movedEvent (i, newX, newY) {
|
||||
if (!this.isGroup) {
|
||||
this.moveChart()
|
||||
this.moveChart(i, newX, newY)
|
||||
this.onScroll(this.scrollTop)
|
||||
} else {
|
||||
bus.$emit('groupChildMove')
|
||||
@@ -280,9 +280,32 @@ export default {
|
||||
this.$set(this.copyDataList, index, chart)
|
||||
this.onScroll(this.scrollTop)
|
||||
},
|
||||
moveChart () {
|
||||
moveChart (id, newX, newY) {
|
||||
if (!this.groupInfo) {
|
||||
const moveItem = this.copyDataList.find(item => item.id == id)
|
||||
const moveIndex = this.copyDataList.findIndex(item => item.id == id)
|
||||
const repeatArr = []
|
||||
this.copyDataList.forEach((item, index) => {
|
||||
const moveId = String(id).split('-repeat-')[0]
|
||||
const repeatId = String(item.id).split('-repeat-')[0]
|
||||
if (moveId == repeatId && moveIndex != index) {
|
||||
repeatArr.push({
|
||||
id: item.id,
|
||||
y: item.y
|
||||
})
|
||||
}
|
||||
})
|
||||
repeatArr.sort((a, b) => a.y - b.y)
|
||||
this.copyDataList.forEach(item => {
|
||||
repeatArr.forEach((subItem, subIndex) => {
|
||||
if (item.id == subItem.id) {
|
||||
item.y = moveItem.y + ((subIndex + 1) * 0.03)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
this.onScroll(this.scrollTop)
|
||||
const arr = this.copyDataList.filter(item => !item.staic)
|
||||
const arr = this.copyDataList.filter(item => !item.staic && !item.repeatIndex)
|
||||
const charts = []
|
||||
let weight = 0
|
||||
arr.forEach(item => {
|
||||
@@ -393,7 +416,7 @@ export default {
|
||||
bus.$emit('refreshPanel')
|
||||
},
|
||||
createChartSuccess (params) {
|
||||
const arr = this.copyDataList.filter(item => !item.staic)
|
||||
const arr = this.copyDataList.filter(item => !item.staic && !item.repeatIndex)
|
||||
const charts = []
|
||||
let weight = 0
|
||||
arr.forEach(item => {
|
||||
@@ -453,6 +476,10 @@ export default {
|
||||
},
|
||||
// 比较变量 图表是否显示/隐藏
|
||||
compareVariables () {
|
||||
// 防止group中的chartList执行
|
||||
if (this.groupInfo) {
|
||||
return
|
||||
}
|
||||
const isRegExp = (v) => {
|
||||
let isReg
|
||||
try {
|
||||
@@ -539,7 +566,105 @@ export default {
|
||||
}
|
||||
})
|
||||
this.onScroll(this.scrollTop)
|
||||
},
|
||||
|
||||
// group设置repeat 便利变量重复渲染图表
|
||||
repeatVariableFn () {
|
||||
// 防止group中的chartList执行
|
||||
if (this.groupInfo) {
|
||||
return
|
||||
}
|
||||
// 先删除掉复制的数据
|
||||
for (let index = 0; index < this.copyDataList.length; index++) {
|
||||
const item = this.copyDataList[index]
|
||||
if (item.repeatIndex > 0) {
|
||||
this.copyDataList.splice(index, 1)
|
||||
index--
|
||||
} else if (item.repeatIndex == 0) {
|
||||
// 置为原来的数据
|
||||
delete item.repeatIndex
|
||||
delete item.repeatVariable
|
||||
delete item.repeatValue
|
||||
item.children && item.children.forEach(children => {
|
||||
delete children.repeatIndex
|
||||
delete children.repeatVariable
|
||||
delete children.repeatValue
|
||||
})
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
// 先让数组根据 y 排序 之后直接判断顺序 即可判断 Group 是否相邻
|
||||
let arr = this.$loadsh.cloneDeep(this.copyDataList)
|
||||
arr = this.$loadsh.orderBy(arr, function (item) {
|
||||
return item.y
|
||||
})
|
||||
const variablesRepeat = {}
|
||||
for (let index = 0; index < arr.length; index++) { // 遍历找出所有需要 repeat的group 按照 name进行多次的分组
|
||||
const item = arr[index]
|
||||
const repeatVariable = this.$loadsh.get(item.param.repeat, 'variable')
|
||||
if (item.type === 'group' && repeatVariable && this.$loadsh.get(this.showHidden[item.id], 'visibility') !== 'hidden') {
|
||||
const itemPrev = arr[index - 1]
|
||||
const repeatPrevVariable = this.$loadsh.get(itemPrev.param.repeat, 'variable')
|
||||
if (itemPrev && itemPrev.type === 'group' && repeatPrevVariable === repeatVariable) {
|
||||
const arr = variablesRepeat[repeatVariable]
|
||||
arr[arr.length - 1].repeatArr.push(item)
|
||||
arr[arr.length - 1].lastGroup = item
|
||||
} else {
|
||||
if (variablesRepeat[repeatVariable]) {
|
||||
variablesRepeat[repeatVariable].push({
|
||||
repeatArr: [item],
|
||||
lastGroup: item
|
||||
})
|
||||
} else {
|
||||
variablesRepeat[repeatVariable] = [{
|
||||
repeatArr: [item],
|
||||
lastGroup: item
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.keys(variablesRepeat).forEach(key => { // 遍历 variablesRepeat 确定需要插入的数组
|
||||
const findVariables = this.variablesArr.find(item => item.name == key)
|
||||
findVariables && findVariables.checked.forEach((subItem, subIndex) => {
|
||||
variablesRepeat[key].forEach(group => {
|
||||
group.repeatArr.forEach(item => {
|
||||
if (subIndex > 0) {
|
||||
// 复制数据 重新设置id
|
||||
const repeatItem = this.$loadsh.cloneDeep(item)
|
||||
repeatItem.id = item.id + '-' + 'repeat-' + subIndex
|
||||
repeatItem.i = repeatItem.id
|
||||
repeatItem.repeatIndex = subIndex
|
||||
repeatItem.repeatVariable = key
|
||||
repeatItem.repeatValue = subItem
|
||||
repeatItem.y = group.lastGroup.y
|
||||
repeatItem.children && repeatItem.children.forEach(children => {
|
||||
children.id = children.id + '-' + 'repeat-' + subIndex
|
||||
children.repeatIndex = subIndex
|
||||
children.repeatVariable = key
|
||||
children.repeatValue = subItem
|
||||
})
|
||||
// 复制数据
|
||||
this.copyDataList.push(repeatItem)
|
||||
} else {
|
||||
const findItem = this.copyDataList.find(chart => chart.id === item.id)
|
||||
this.$set(findItem, 'repeatIndex', 0)
|
||||
this.$set(findItem, 'repeatVariable', key)
|
||||
this.$set(findItem, 'repeatValue', subItem)
|
||||
findItem.children && findItem.children.forEach(children => {
|
||||
this.$set(children, 'repeatIndex', 0)
|
||||
this.$set(children, 'repeatVariable', key)
|
||||
this.$set(children, 'repeatValue', subItem)
|
||||
})
|
||||
this.$refs['chart' + findItem.id] && this.$refs['chart' + findItem.id][0] && this.$refs['chart' + findItem.id][0].getChartData()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
created () {
|
||||
this.firstInit = true
|
||||
@@ -572,9 +697,11 @@ export default {
|
||||
},
|
||||
// 监听变量数组
|
||||
variablesArr: {
|
||||
handler () {
|
||||
handler (newVal, oldVal) {
|
||||
// 比较变量 图表是否显示/隐藏
|
||||
this.compareVariables()
|
||||
|
||||
this.repeatVariableFn()
|
||||
}
|
||||
},
|
||||
panelLock: {
|
||||
@@ -673,6 +800,8 @@ export default {
|
||||
this.copyDataList = JSON.parse(JSON.stringify(tempList))
|
||||
// 比较变量 图表是否显示/隐藏
|
||||
this.compareVariables()
|
||||
|
||||
this.repeatVariableFn()
|
||||
tempList = null
|
||||
setTimeout(() => {
|
||||
this.gridLayoutShow = true
|
||||
|
||||
@@ -207,9 +207,16 @@ export default {
|
||||
value = self.$loadsh.get(myParams, label)
|
||||
}
|
||||
if (label) {
|
||||
const reg = new RegExp(label + '=".+?"')
|
||||
const reg = new RegExp(label + '=".+?"', 'g')
|
||||
if (reg.test(legend)) {
|
||||
const find = legend.match(reg)[0]
|
||||
const ans = legend.match(reg)
|
||||
let find = ''
|
||||
ans.forEach(item => {
|
||||
const index = legend.indexOf(item)
|
||||
if (legend[index - 1] !== '_') {
|
||||
find = item
|
||||
}
|
||||
})
|
||||
value = find.substr(find.indexOf('"') + 1, find.lastIndexOf('"') - find.indexOf('"') - 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,9 +187,15 @@ export default {
|
||||
if (!this.chartInfo.oldElements) { // 创建一个备份 用于判断变量替换 能拿到原本变量的位置
|
||||
this.chartInfo.oldElements = this.chartInfo.elements ? JSON.parse(JSON.stringify(this.chartInfo.elements)) : []
|
||||
}
|
||||
this.chartInfo.elements = this.chartInfo.oldElements.filter(item => item.state) // 处理不显示的表达式
|
||||
this.chartInfo.elements = this.chartInfo.elements.map(item => { // 处理表达式的变量
|
||||
const variables = this.variablesReplace(item.expression)
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
this.chartInfo.elements = this.$loadsh.cloneDeep(this.chartInfo.oldElements.filter(item => item.state)) // 处理不显示的表达式
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
this.chartInfo.elements = this.chartInfo.elements.map((item, index) => { // 处理表达式的变量
|
||||
// group图表设置repeat的表达式替换
|
||||
if (this.chartInfo.repeatVariable) {
|
||||
item.expression = this.variablesReplaceRepeat(item.expression)
|
||||
}
|
||||
const variables = this.variablesReplace((item.expression))
|
||||
this.myVariables.push(variables)
|
||||
return {
|
||||
...item,
|
||||
@@ -211,7 +217,7 @@ export default {
|
||||
switch (this.chartInfo.datasource) {
|
||||
case 'metrics':
|
||||
case 'logs': {
|
||||
if (this.from === fromRoute.chartTemp) {
|
||||
if (this.from === fromRoute.chartTemp || this.from === fromRoute.dashboardTemp) {
|
||||
setTimeout(() => {
|
||||
this.chartData = [chartTempData.data.result]
|
||||
this.chartData.forEach(item => {
|
||||
@@ -230,7 +236,7 @@ export default {
|
||||
urlPre += '/logs/loki'
|
||||
}
|
||||
let requests = elements.map((element) => {
|
||||
if (this.from === fromRoute.chartTemp) {
|
||||
if (this.from === fromRoute.chartTemp || this.from === fromRoute.dashboardTemp) {
|
||||
return chartTempData
|
||||
}
|
||||
let query = `${urlPre}/api/v1/query_range?start=${startTime}&end=${endTime}&step=${step}`
|
||||
@@ -260,7 +266,7 @@ export default {
|
||||
})
|
||||
if (this.multipleTime) {
|
||||
const multipleRequests = elements.map((element) => {
|
||||
if (this.from === fromRoute.chartTemp) {
|
||||
if (this.from === fromRoute.chartTemp || this.from === fromRoute.dashboardTemp) {
|
||||
return chartTempData
|
||||
}
|
||||
let query = `${urlPre}/api/v1/query_range?start=${startTime - this.minusTime / 1000}&end=${endTime - this.minusTime / 1000}&step=${step}`
|
||||
@@ -325,7 +331,7 @@ export default {
|
||||
}
|
||||
case 'system': {
|
||||
this.chartInfo.elements = this.chartInfo.param.datasource
|
||||
if (this.from === fromRoute.chartTemp) {
|
||||
if (this.from === fromRoute.chartTemp || this.from === fromRoute.dashboardTemp) {
|
||||
setTimeout(() => {
|
||||
this.chartData = [chartTempData.data.result]
|
||||
this.loading = false
|
||||
@@ -569,11 +575,19 @@ export default {
|
||||
if (confirmReg.length) {
|
||||
confirmReg.forEach(item => {
|
||||
const reg = new RegExp('\\$' + item.name, 'g') // 后续需要考虑 item,name 使用特殊字符的问题
|
||||
str = str.replace(reg, item.checked.map(label => label.replace(/\"/g, '\\"').replace(/\'/g, "\\'")).join('|'))
|
||||
str = str.replace(reg, item.checked.map(label => label.replace(/\\"/g, '"').replace(/\\'/g, "'")).join('|'))
|
||||
})
|
||||
}
|
||||
return str
|
||||
},
|
||||
// group图表repeat 表达式替换
|
||||
variablesReplaceRepeat (expression) {
|
||||
let str = expression
|
||||
const variable = this.chartInfo.repeatVariable
|
||||
const reg = new RegExp('\\$' + variable, 'g')
|
||||
str = str.replace(reg, this.chartInfo.repeatValue.replace(/\\"/g, '"').replace(/\\'/g, "'"))
|
||||
return str
|
||||
},
|
||||
getHexagonFigureData () {
|
||||
return new Promise(resolve => {
|
||||
this.$get('stat/alertMessage/topN', { size: 48, dimension: 'module' }).then(response => {
|
||||
@@ -766,7 +780,7 @@ export default {
|
||||
},
|
||||
variablesArr: {
|
||||
handler (n) {
|
||||
const elements = this.chartInfo.oldElements || []
|
||||
const elements = this.$loadsh.cloneDeep(this.chartInfo.oldElements) || []
|
||||
const variables = elements.map((element) => {
|
||||
return this.variablesReplace(element.expression)
|
||||
})
|
||||
|
||||
@@ -8,15 +8,31 @@
|
||||
</style>
|
||||
<template>
|
||||
<div :id="'ternimalContainer'+idIndex" class="console">
|
||||
<div class="ternimal-header">
|
||||
<span style="color: #fff">
|
||||
<div class="active-icon" :class="isLogin ? 'green-bg': 'red-bg'"></div>
|
||||
{{userName}}
|
||||
</span>
|
||||
<span style="color: #fff">
|
||||
<i class="nz-icon nz-icon-reconnect" v-show="isInit" style="margin-right: 22px" @click="reconnect"></i>
|
||||
<i class="nz-icon nz-icon-SFTP" v-show="isLogin" v-if="userName && terminalType == '1'" style="margin-right: 22px" @click="showFileDir(true)"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div :id="'terminal'+idIndex" ></div>
|
||||
<fileDirectory v-clickoutside="closeFileDir" :uuid="terminal.uuid" v-show="fileDirectoryShow" @close="showFileDir(false)" :fileDirectoryShow="fileDirectoryShow" ref="fileDirectory"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Terminal from '../common/js/Xterm'
|
||||
import fileDirectory from './fileDirectory'
|
||||
export default {
|
||||
name: 'console',
|
||||
components: {
|
||||
fileDirectory
|
||||
},
|
||||
props: {
|
||||
terminal: { },
|
||||
terminalType: { default: '1' },
|
||||
idIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
@@ -40,6 +56,8 @@ export default {
|
||||
obj: {
|
||||
id: 2
|
||||
},
|
||||
isLogin: false,
|
||||
isInit:false,
|
||||
successBackContent: 'Connecting to',
|
||||
failBackContent: 'Sorry',
|
||||
connectFailContent: 'Connection failed',
|
||||
@@ -47,7 +65,9 @@ export default {
|
||||
psdCont: 'password: ',
|
||||
conFinish: false,
|
||||
conSuccessNum: 0,
|
||||
inputSecret: false
|
||||
inputSecret: false,
|
||||
userName: '',
|
||||
fileDirectoryShow: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -65,7 +85,7 @@ export default {
|
||||
const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
|
||||
consoleBox.style.height = `${consoleHeigt - 55}px`
|
||||
// 调整终端可视区域高度
|
||||
document.getElementsByClassName('xterm-screen')[this.idIndex].style.height = `${consoleHeigt - 10}px`
|
||||
document.getElementsByClassName('xterm-screen')[this.idIndex].style.height = `${consoleHeigt - 10 - 30}px`
|
||||
this.$nextTick(() => { // 解决进入全屏和退出全屏是底部隐藏
|
||||
this.setFontSize(this.fontSize)
|
||||
})
|
||||
@@ -130,8 +150,7 @@ export default {
|
||||
focusConsole () {
|
||||
this.term.focus()
|
||||
},
|
||||
create () {
|
||||
const that = this
|
||||
beforeCreate () {
|
||||
let rows = this.termimalRows
|
||||
if (this.isFullScreen) {
|
||||
// 容器高度设置100%
|
||||
@@ -157,6 +176,42 @@ export default {
|
||||
})
|
||||
this.term.open(terminalContainer)
|
||||
this.term.focus()
|
||||
const params = {
|
||||
width: this.terminal.width,
|
||||
height: this.terminal.height,
|
||||
cols: this.terminal.cols,
|
||||
rows: this.terminal.rows,
|
||||
host: this.$loadsh.get(this.terminal, 'custom.host', ''),
|
||||
port: this.$loadsh.get(this.terminal, 'custom.port', ''),
|
||||
assetId: this.$loadsh.get(this.terminal, 'assetId', ''),
|
||||
accountId: this.$loadsh.get(this.terminal, 'accountId', ''),
|
||||
authProtocol: this.$loadsh.get(this.terminal, 'custom.authProtocol', ''),
|
||||
authProtocolPort: this.$loadsh.get(this.terminal, 'custom.authProtocolPort', ''),
|
||||
authType: this.$loadsh.get(this.terminal, 'custom.authType', ''),
|
||||
authUsername: this.$loadsh.get(this.terminal, 'custom.authUsername', ''),
|
||||
authPin: this.$loadsh.get(this.terminal, 'custom.authPin', ''),
|
||||
authPriKey: this.$loadsh.get(this.terminal, 'custom.authPriKey', ''),
|
||||
authUserTip: this.$loadsh.get(this.terminal, 'custom.authUserTip', ''),
|
||||
authPinTip: this.$loadsh.get(this.terminal, 'custom.authPinTip', '')
|
||||
}
|
||||
this.$post('/terminal/login', params).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.terminal.uuid = res.data.uuid
|
||||
this.userName = res.data.authUsername + '@' + res.data.host
|
||||
this.host = res.data.host
|
||||
this.create()
|
||||
} else {
|
||||
this.terminal.uuid = res.data.uuid
|
||||
this.userName = res.data.authUsername + '@' + res.data.host
|
||||
this.host = res.data.host
|
||||
params.name = this.terminal.name
|
||||
this.$emit('loginFail', params)
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
create () {
|
||||
const that = this
|
||||
const token = localStorage.getItem('nz-token')
|
||||
let baseUrl = JSON.parse(JSON.stringify(this.$axios.defaults.baseURL))
|
||||
const protocol = window.location.protocol.indexOf('https') > -1 ? 'wss' : 'ws'
|
||||
@@ -177,8 +232,10 @@ export default {
|
||||
})
|
||||
}
|
||||
this.terminalSocket = new WebSocket(url)
|
||||
// 连接成功
|
||||
// 连接成功onclose
|
||||
this.terminalSocket.onopen = () => {
|
||||
this.isLogin = true
|
||||
this.isInit = true
|
||||
}
|
||||
// 登录后,你输入的内容从后台服务返回
|
||||
this.term.on('data', function (data) {
|
||||
@@ -192,7 +249,6 @@ export default {
|
||||
// 返回
|
||||
this.terminalSocket.onmessage = function (evt) {
|
||||
let backContent = evt.data
|
||||
|
||||
const welComIndex = backContent.indexOf(that.welcomeBackContent)
|
||||
if (welComIndex > -1) { // 无服务器信息(只与nezha进行了连接)
|
||||
const connectResult = {
|
||||
@@ -235,13 +291,16 @@ export default {
|
||||
}
|
||||
// 关闭
|
||||
this.terminalSocket.onclose = () => {
|
||||
this.isLogin = false
|
||||
// 报错sorry的,还没来得及看信息就关闭
|
||||
// this.$emit("closeConsole",this.terminal.name);//
|
||||
this.term && this.term.setOption('disableStdin', true)
|
||||
}
|
||||
|
||||
// 错误
|
||||
this.terminalSocket.onerror = (e) => {}
|
||||
this.terminalSocket.onerror = (e) => {
|
||||
this.isLogin = false
|
||||
}
|
||||
// 选中 复制
|
||||
this.term.on('selection', function () {})
|
||||
this.term.attachCustomKeyEventHandler(function (ev) { })
|
||||
@@ -281,7 +340,7 @@ export default {
|
||||
rows: this.term.rows
|
||||
}
|
||||
// 调整终端可视区域高度
|
||||
document.getElementsByClassName('xterm-screen')[this.idIndex].style.height = height + 'px'
|
||||
document.getElementsByClassName('xterm-screen')[this.idIndex].style.height = height - 30 + 'px'
|
||||
this.$nextTick(() => {
|
||||
this.term.resize(this.term.cols, this.term.rows)
|
||||
this.$post('terminal/resize', winStyle).then(response => {
|
||||
@@ -292,10 +351,33 @@ export default {
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
reconnect () {
|
||||
this.isLogin = false
|
||||
this.closeSocket()
|
||||
this.term.off('selection')
|
||||
this.term.off('data')
|
||||
this.beforeCreate()
|
||||
},
|
||||
closeFileDir () {
|
||||
this.showFileDir(false)
|
||||
},
|
||||
showFileDir (show) {
|
||||
if (JSON.stringify(show) == JSON.stringify(this.fileDirectoryShow)) {
|
||||
return
|
||||
}
|
||||
if (show) {
|
||||
this.fileDirectoryShow = show
|
||||
}
|
||||
let animationClass = ''
|
||||
animationClass = show ? 'backInUp' : 'backOutDown'
|
||||
this.animateCSS(this.$refs.fileDirectory.$el, animationClass).then((message) => {
|
||||
this.fileDirectoryShow = show
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.create()
|
||||
this.beforeCreate()
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.closeSocket()
|
||||
@@ -304,3 +386,6 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
|
||||
329
nezha-fronted/src/components/cli/consoleNew.vue
Normal file
329
nezha-fronted/src/components/cli/consoleNew.vue
Normal file
@@ -0,0 +1,329 @@
|
||||
<style scoped>
|
||||
.console{
|
||||
height: 100%;
|
||||
padding:5px 5px;
|
||||
background-color: black;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div :id="'ternimalContainer'+idIndex" class="console">
|
||||
<div :id="'terminal'+idIndex" style="height: 100%"></div>
|
||||
<fileDirectory :host="host" v-clickoutside="closeFileDir" :uuid="terminal.uuid" v-show="fileDirectoryShow" @close="showFileDir(false)" :fileDirectoryShow="fileDirectoryShow" ref="fileDirectory"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Terminal from '../common/js/Xterm'
|
||||
import fileDirectory from './fileDirectory'
|
||||
export default {
|
||||
name: 'console',
|
||||
components: {
|
||||
fileDirectory
|
||||
},
|
||||
props: {
|
||||
terminal: { },
|
||||
terminalType: { default: '1' },
|
||||
idIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
isFullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
fontSize: {}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
term: null,
|
||||
terminalSocket: null,
|
||||
termimalRows: 15,
|
||||
termimalHeight: 270,
|
||||
topMenuHeight: 30,
|
||||
dragHeigh: 8,
|
||||
minRow: 1,
|
||||
fontSpaceHeight: 2, // 一行高度=fontSize+fontSpaceHeight
|
||||
obj: {
|
||||
id: 2
|
||||
},
|
||||
isInit: false,
|
||||
successBackContent: 'Connecting to',
|
||||
failBackContent: 'Sorry',
|
||||
connectFailContent: 'Connection failed',
|
||||
welcomeBackContent: 'Welcome',
|
||||
psdCont: 'password: ',
|
||||
conFinish: false,
|
||||
conSuccessNum: 0,
|
||||
inputSecret: false,
|
||||
userName: '',
|
||||
fileDirectoryShow: false,
|
||||
host: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
methods: {
|
||||
prompt (term) {
|
||||
term.write('\r\n ')// term.write('\r\n~$ ');
|
||||
},
|
||||
resize (consoleHeigt, consoleWidth) {
|
||||
this.term.fit()
|
||||
this.resizeServiceConsole()
|
||||
},
|
||||
resizeServiceConsole () {
|
||||
const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
|
||||
const width = document.body.clientWidth// 可视宽度
|
||||
const height = parseInt(consoleBox.offsetHeight)
|
||||
const winStyle = {
|
||||
width: width,
|
||||
height: height - 100,
|
||||
cols: this.term.cols, // cols和rows在resizeConsole方法已经设置
|
||||
rows: this.term.rows
|
||||
}
|
||||
this.$post('terminal/resize', winStyle).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.term.fit()
|
||||
} else {
|
||||
this.$message.error(response.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
focusConsole () {
|
||||
this.term.focus()
|
||||
},
|
||||
beforeCreate () {
|
||||
let rows = this.termimalRows
|
||||
// const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
|
||||
const height = document.body.clientHeight// 高度
|
||||
// consoleBox.style.height = `${height - 120}px`
|
||||
rows = (height - this.topMenuHeight) / (this.fontSize + this.fontSpaceHeight)
|
||||
rows = parseInt(rows)
|
||||
const terminalContainer = document.getElementById('terminal' + this.idIndex)
|
||||
this.term = new Terminal({
|
||||
rows: rows, // 15行大概300px高,无法设置heigh,只能设置rows
|
||||
cursorStyle: 'block', // 光标样式 null | 'block' | 'underline' | 'bar'
|
||||
disableStdin: false, // 是否应禁用输入
|
||||
fontSize: this.fontSize
|
||||
})
|
||||
this.term.open(terminalContainer)
|
||||
this.term.focus()
|
||||
const params = {
|
||||
width: this.terminal.width,
|
||||
height: this.terminal.height,
|
||||
cols: this.terminal.cols,
|
||||
rows: this.terminal.rows,
|
||||
host: this.$loadsh.get(this.terminal, 'custom.host', ''),
|
||||
port: this.$loadsh.get(this.terminal, 'custom.port', ''),
|
||||
assetId: this.$loadsh.get(this.terminal, 'assetId', ''),
|
||||
accountId: this.$loadsh.get(this.terminal, 'accountId', ''),
|
||||
authProtocol: this.$loadsh.get(this.terminal, 'custom.authProtocol', ''),
|
||||
authProtocolPort: this.$loadsh.get(this.terminal, 'custom.authProtocolPort', ''),
|
||||
authType: this.$loadsh.get(this.terminal, 'custom.authType', ''),
|
||||
authUsername: this.$loadsh.get(this.terminal, 'custom.authUsername', ''),
|
||||
authPin: this.$loadsh.get(this.terminal, 'custom.authPin', ''),
|
||||
authPriKey: this.$loadsh.get(this.terminal, 'custom.authPriKey', ''),
|
||||
authUserTip: this.$loadsh.get(this.terminal, 'custom.authUserTip', ''),
|
||||
authPinTip: this.$loadsh.get(this.terminal, 'custom.authPinTip', '')
|
||||
}
|
||||
this.$post('/terminal/login', params).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.terminal.uuid = res.data.uuid
|
||||
this.$forceUpdate()
|
||||
this.terminal.userName = res.data.authUsername + '@' + res.data.host
|
||||
this.host = res.data.host
|
||||
this.create()
|
||||
} else {
|
||||
this.terminal.uuid = res.data.uuid
|
||||
this.terminal.userName = res.data.authUsername + '@' + res.data.host
|
||||
this.host = res.data.host
|
||||
params.name = this.terminal.name
|
||||
this.$emit('loginFail', params)
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
create () {
|
||||
const that = this
|
||||
const token = localStorage.getItem('nz-token')
|
||||
let baseUrl = JSON.parse(JSON.stringify(this.$axios.defaults.baseURL))
|
||||
const protocol = window.location.protocol.indexOf('https') > -1 ? 'wss' : 'ws'
|
||||
if (baseUrl.startsWith('/')) {
|
||||
baseUrl = `${protocol}://` + window.location.host + baseUrl
|
||||
} else {
|
||||
baseUrl = baseUrl.replace('http://', 'ws://').replace('https://', 'wss://')
|
||||
}
|
||||
let url = ''
|
||||
this.terminal.height = document.body.clientHeight - 100
|
||||
if (this.terminal.type === 'asset') {
|
||||
url = baseUrl + '/terminal.ws?width=' + this.terminal.width + '&height=' + this.terminal.height + '&cols=' + this.terminal.cols + '&rows=' + this.terminal.rows + '&token=' + token + '&assetId=' + this.terminal.assetId + '&accountId=' + this.terminal.accountId + '&uuid=' + this.terminal.uuid
|
||||
} else if (this.terminal.type === 'custom') {
|
||||
url = baseUrl + '/terminal.ws?width=' + this.terminal.width + '&height=' + this.terminal.height + '&cols=' + this.terminal.cols + '&rows=' + this.terminal.rows + '&token=' + token + '&accountId=' + this.terminal.accountId + '&uuid=' + this.terminal.uuid
|
||||
Object.keys(this.terminal.custom).forEach(key => {
|
||||
if (this.terminal.custom[key]) {
|
||||
url += '&' + key + '=' + this.terminal.custom[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.terminalSocket = new WebSocket(url)
|
||||
// 连接成功onclose
|
||||
this.terminalSocket.onopen = () => {
|
||||
this.terminal.isLogin = true
|
||||
this.isInit = true
|
||||
}
|
||||
// 登录后,你输入的内容从后台服务返回
|
||||
this.term.on('data', function (data) {
|
||||
/*
|
||||
let code = data.charCodeAt(0);
|
||||
if(code==13){
|
||||
}else {
|
||||
//that.term.write(data);
|
||||
} */
|
||||
})
|
||||
// 返回
|
||||
this.terminalSocket.onmessage = function (evt) {
|
||||
let backContent = evt.data
|
||||
const welComIndex = backContent.indexOf(that.welcomeBackContent)
|
||||
if (welComIndex > -1) { // 无服务器信息(只与nezha进行了连接)
|
||||
const connectResult = {
|
||||
title: '',
|
||||
color: 1
|
||||
}
|
||||
that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
|
||||
} else {
|
||||
const successContentIndex = backContent.indexOf(that.successBackContent)
|
||||
if (successContentIndex > -1) {
|
||||
// that.conFinish = true;
|
||||
const startIndex = successContentIndex + that.successBackContent.length + 1
|
||||
backContent = backContent.substring(startIndex)
|
||||
const endIndex = backContent.indexOf('\r\n')
|
||||
const title = backContent.substring(0, endIndex)
|
||||
const connectResult = {
|
||||
title: title,
|
||||
color: 2
|
||||
}
|
||||
that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
|
||||
} else { // 失败
|
||||
const failContentIndex = backContent.indexOf(that.failBackContent)
|
||||
const connectFailIndex = backContent.indexOf(that.connectFailContent)
|
||||
if (failContentIndex > -1) {
|
||||
// that.conFinish = true;
|
||||
const connectResult = {
|
||||
title: '',
|
||||
color: 3
|
||||
}
|
||||
that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
|
||||
} else if (connectFailIndex > -1) {
|
||||
const connectResult = {
|
||||
title: '',
|
||||
color: 3
|
||||
}
|
||||
that.$emit('refreshConsoleTitle', connectResult)// 1:grey 2 green 3 red
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 关闭
|
||||
this.terminalSocket.onclose = () => {
|
||||
this.terminal.isLogin = false
|
||||
// 报错sorry的,还没来得及看信息就关闭
|
||||
// this.$emit("closeConsole",this.terminal.name);//
|
||||
this.term && this.term.setOption('disableStdin', true)
|
||||
}
|
||||
|
||||
// 错误
|
||||
this.terminalSocket.onerror = (e) => {
|
||||
this.terminal.isLogin = false
|
||||
}
|
||||
// 选中 复制
|
||||
this.term.on('selection', function () {})
|
||||
this.term.attachCustomKeyEventHandler(function (ev) { })
|
||||
|
||||
this.term.attach(this.terminalSocket)
|
||||
this.term._initialized = true
|
||||
this.term.fit()// 自适应大小(使终端的尺寸和几何尺寸适合于终端容器的尺寸) 只是width
|
||||
this.$nextTick(() => { // 解决进入全屏和退出全屏是底部隐藏
|
||||
this.setFontSize(this.fontSize)
|
||||
})
|
||||
},
|
||||
|
||||
closeSocket () {
|
||||
if (this.terminalSocket) {
|
||||
this.terminalSocket.close()
|
||||
this.terminalSocket = ''
|
||||
}
|
||||
if (this.term) {
|
||||
this.term.destroy()
|
||||
}
|
||||
// 初始化console的高度
|
||||
this.conFinish = false
|
||||
},
|
||||
setFontSize (fontSize) {
|
||||
this.term && this.term.setOption('fontSize', fontSize)
|
||||
const consoleBox = document.getElementById('ternimalContainer' + this.idIndex)
|
||||
const width = document.body.clientWidth// 可视宽度
|
||||
let height = parseInt(consoleBox.offsetHeight)
|
||||
if (height == null || !height) { height = this.termimalHeight }
|
||||
const winStyle = {
|
||||
width: width,
|
||||
height: height,
|
||||
cols: this.term.cols, // cols和rows在resizeConsole方法已经设置
|
||||
rows: this.term.rows
|
||||
}
|
||||
// 调整终端可视区域高度
|
||||
// document.getElementsByClassName('xterm-screen')[this.idIndex].style.height = height - 30 + 'px'
|
||||
this.$nextTick(() => {
|
||||
this.term.resize(this.term.cols, this.term.rows)
|
||||
this.$post('terminal/resize', winStyle).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.term.fit()
|
||||
} else {
|
||||
this.$message.error(response.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
reconnect () {
|
||||
this.terminal.isLogin = false
|
||||
this.closeSocket()
|
||||
this.term.off('selection')
|
||||
this.term.off('data')
|
||||
this.beforeCreate()
|
||||
},
|
||||
closeFileDir () {
|
||||
this.showFileDir(false)
|
||||
},
|
||||
showFileDir (show) {
|
||||
if (JSON.stringify(show) == JSON.stringify(this.fileDirectoryShow)) {
|
||||
return
|
||||
}
|
||||
if (show) {
|
||||
this.fileDirectoryShow = show
|
||||
}
|
||||
let animationClass = ''
|
||||
animationClass = show ? 'backInRight' : 'backOutRight'
|
||||
this.animateCSS(this.$refs.fileDirectory.$el, animationClass).then((message) => {
|
||||
this.fileDirectoryShow = show
|
||||
})
|
||||
},
|
||||
enterStr (message) {
|
||||
if (this.terminalSocket && this.terminal.isLogin) {
|
||||
this.terminalSocket.send(message)
|
||||
setTimeout(()=>{
|
||||
this.terminalSocket.send('\n')
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.beforeCreate()
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.closeSocket()
|
||||
this.term.off('selection')
|
||||
this.term.off('data')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
616
nezha-fronted/src/components/cli/fileDirectory.vue
Normal file
616
nezha-fronted/src/components/cli/fileDirectory.vue
Normal file
@@ -0,0 +1,616 @@
|
||||
<template>
|
||||
<div class="fileDirectory">
|
||||
<div class="file-directory-header">
|
||||
{{$t('terminal.sftp')}}
|
||||
<span class="header-option">
|
||||
<i class="nz-icon nz-icon-upload" @click="uploadFile"></i>
|
||||
<i class="nz-icon nz-icon-close" @click="$emit('close')"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="file-directory-path" v-clickoutside="hideEditPath">
|
||||
<span v-show="!editPathShow" class="breadcrumb-box">
|
||||
<span @click="getSftpPath('/')" class="breadcrumb-item breadcrumb-action"><i class="nz-icon nz-icon-home"/></span>
|
||||
<span v-for="(item,index) in breadcrumb" :key="index" class="breadcrumb-item">
|
||||
/<span class="breadcrumb-action" @click="gotoPath(item,index)">{{item}}</span>
|
||||
</span>
|
||||
<i class="nz-icon nz-icon-edit" @click="showEditPath"/>
|
||||
</span>
|
||||
<span v-show="editPathShow" style="display: inline-block;flex: 1;padding-right: 40px">
|
||||
<el-input v-model="editPath" size="mini" @keyup.enter.native="goEditPath">
|
||||
<span slot="suffix">
|
||||
{{$t('terminal.confirm')}}
|
||||
</span>
|
||||
</el-input>
|
||||
</span>
|
||||
<div class="path-option">
|
||||
<span style="margin-right: 5px">Show hide File: </span>
|
||||
<el-switch v-model="showHideFile"/>
|
||||
<i class="nz-icon nz-icon-a-newfolder" @click="newFolderBoxShow = true"></i>
|
||||
<i class="nz-icon nz-icon-upload" @click="uploadFile"></i>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style="padding: 0 20px;height: calc(100% - 50px)" v-my-loading="fileDirectoryLoading">
|
||||
<div class="directory-content-header">
|
||||
<div class="text-ellipsis file-name">
|
||||
<div class="file-arrow-header" style="cursor: pointer" @click.stop="orderBy('nameOrderType','' , 'name')">
|
||||
<div>
|
||||
{{$t('overall.name')}}
|
||||
</div>
|
||||
<div class="nz-arrow-box">
|
||||
<div class="nz-arrow-up" :class="{
|
||||
'is-select': nameOrderType === 'asc'
|
||||
}" @click.stop="orderBy('nameOrderType','asc' , 'name')"></div>
|
||||
<div class="nz-arrow-down" :class="{
|
||||
'is-select': nameOrderType === 'desc'
|
||||
}" @click.stop="orderBy('nameOrderType','desc', 'name')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-ellipsis file-size">
|
||||
<div class="file-arrow-header" style="cursor: pointer" @click.stop="orderBy('sizeOrderType','' , 'size')">
|
||||
<div>
|
||||
{{$t('backup.size')}}
|
||||
</div>
|
||||
<div class="nz-arrow-box">
|
||||
<div class="nz-arrow-up" :class="{
|
||||
'is-select': sizeOrderType === 'asc'
|
||||
}" @click.stop="orderBy('sizeOrderType','asc' , 'size')"></div>
|
||||
<div class="nz-arrow-down" :class="{
|
||||
'is-select': sizeOrderType === 'desc'
|
||||
}" @click.stop="orderBy('sizeOrderType','desc', 'size')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-ellipsis file-date">
|
||||
<div class="file-arrow-header" style="cursor: pointer" @click.stop="orderBy('dateOrderType','' , 'cts')">
|
||||
<div>
|
||||
{{$t('issue.createTime')}}
|
||||
</div>
|
||||
<div class="nz-arrow-box" style="">
|
||||
<div class="nz-arrow-up" :class="{
|
||||
'is-select': dateOrderType === 'asc'
|
||||
}" @click.stop="orderBy('dateOrderType','asc', 'cts')"></div>
|
||||
<div class="nz-arrow-down" :class="{
|
||||
'is-select': dateOrderType === 'desc'
|
||||
}" @click.stop="orderBy('dateOrderType','desc', 'cts')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-ellipsis file-opt">
|
||||
{{$t('overall.option')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="file-directory-content"
|
||||
onselectstart="return false;"
|
||||
style="-moz-user-select:none;">
|
||||
<div v-if="fileDirectory !== '/'" @dblclick.prevent="backFileDirectory" class="file-item">
|
||||
<div class="text-ellipsis file-name">
|
||||
<i class="nz-icon nz-icon-Folder colorFA901C" style="margin-right: 3px"/>
|
||||
..
|
||||
<!-- {{$t('terminal.back')}}-->
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item,index) in fileList"
|
||||
v-show="showHideFile || !item.isHide"
|
||||
:key="index" class="file-item"
|
||||
onselectstart="return false;"
|
||||
style="-moz-user-select:none;"
|
||||
@dblclick.prevent="selectFile(item)"
|
||||
>
|
||||
<div class="text-ellipsis file-name">
|
||||
<i class="nz-icon" :class="selIcon(item)"/>
|
||||
<i class="nz-icon nz-icon-link" v-if="item.isLink"/>
|
||||
{{item.name}} <span v-if="item.isLink">-> {{item.linkName}}</span>
|
||||
</div>
|
||||
<div class="text-ellipsis file-size">
|
||||
<span v-if="!item.isDir">{{bytes(item.size, 0, 0)}}</span>
|
||||
</div>
|
||||
<div class="text-ellipsis file-date">
|
||||
<span>{{momentTz(item.cts * 1000)}}</span>
|
||||
</div>
|
||||
<div class="text-ellipsis file-opt">
|
||||
<i class="nz-icon nz-icon-shuxing" @click.stop="showFileInfo(item)"/>
|
||||
<el-dropdown size="medium" trigger="click" @command="tableOperation">
|
||||
<div class="table-operation-item table-operation-item--more" @click.stop="" :title="$t('overall.moreOperations')">
|
||||
<i class="nz-icon nz-icon-more3"></i>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown" class="right-box-select-top right-public-box-dropdown-top">
|
||||
<el-dropdown-item
|
||||
:command="['rename', item]">
|
||||
<i class="nz-icon nz-icon-edit"></i>
|
||||
<span class="operation-dropdown-text">
|
||||
{{$t('terminal.rename')}}
|
||||
</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:disabled="item.isDir"
|
||||
:command="['download', item]">
|
||||
<i class="nz-icon nz-icon-download1"></i>
|
||||
<span class="operation-dropdown-text">
|
||||
{{$t('overall.download')}}
|
||||
</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:disabled="item.isDir"
|
||||
:command="['del', item]">
|
||||
<i class="nz-icon nz-icon-delete"></i>
|
||||
<span class="operation-dropdown-text">
|
||||
{{$t('overall.delete')}}
|
||||
</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<!-- <i class="nz-icon nz-icon-download1" v-if="!item.isDir" @click="downloadFile(item)"></i>-->
|
||||
<!-- <i class="nz-icon nz-icon-delete" v-if="!item.isDir" @click="delFile(item)"></i>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("overall.newFolder")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="newFolderBoxShow"
|
||||
@close="newFolder(false)"
|
||||
>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 100px;flex-shrink: 1;text-transform: capitalize">{{$t('overall.folderName')}}</div>
|
||||
<el-input v-model="folder" size="small" style="flex: 1"/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button el-button--small el-button--default" @click="newFolder(false)">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="newFolder(true)">
|
||||
<span style="text-transform:Capitalize">{{$t('overall.create')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("terminal.rename")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="renameBox"
|
||||
@close="renameBox = false"
|
||||
>
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 100px;flex-shrink: 1;text-transform: capitalize">{{$t('overall.name')}}</div>
|
||||
<el-input v-model="renameStr" size="small" style="flex: 1"/>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button el-button--small el-button--default" @click="renameBox = false">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="setRename">
|
||||
<span style="text-transform:Capitalize">{{$t('overall.save')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("overall.delete")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="delDialog"
|
||||
@close="delDialog = false"
|
||||
>
|
||||
<div style="display: flex; align-items: center" v-if="delObj">
|
||||
{{$t('terminal.delinfo',{fileName: delObj.name})}}
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button el-button--small el-button--default" @click="delDialog = false" >
|
||||
<span>{{$t('tip.no')}}</span>
|
||||
</button>
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="delFile">
|
||||
<span style="text-transform:Capitalize">{{$t('tip.yes')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- fileInfo-->
|
||||
<el-dialog
|
||||
class="nz-dialog snapshot-dialog"
|
||||
width="472px"
|
||||
:title='$t("overall.labels")'
|
||||
destroy-on-close
|
||||
:modal-append-to-body="false"
|
||||
:visible.sync="fileInfoShow"
|
||||
@close="fileInfoShow = false"
|
||||
>
|
||||
<div v-if="fileInfo">
|
||||
<div class="file-info-item-header">
|
||||
<i class="nz-icon" :class="selIcon(fileInfo)"/>
|
||||
{{fileInfo.name}}
|
||||
</div>
|
||||
<div v-for="item in fileAttr" :key="item.name" class="file-info-item">
|
||||
<div class="file-info-item-left" :class="{'is-disabled': fileInfo.isDir && item.key =='size'}">
|
||||
{{$t(item.name)}} :
|
||||
</div>
|
||||
<div class="file-info-item-right">
|
||||
{{selInfo(fileInfo, item.key)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button class="nz-btn el-button--small nz-btn-style-normal" @click="fileInfoShow = false">
|
||||
<span style="text-transform:Capitalize">{{$t('overall.close')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import chartDataFormat from '@/components/chart/chartDataFormat'
|
||||
export default {
|
||||
name: 'fileDirectory',
|
||||
props: {
|
||||
uuid: {},
|
||||
fileDirectoryShow: {},
|
||||
host: {}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
fileDirectory: '/',
|
||||
sizeOrderType: 0,
|
||||
dateOrderType: 0,
|
||||
nameOrderType: 0,
|
||||
breadcrumb: [],
|
||||
fileList: [],
|
||||
oldFileList: [],
|
||||
newFolderBoxShow: false,
|
||||
folder: '',
|
||||
fileDirectoryLoading: false,
|
||||
timer: '',
|
||||
editPathShow: false,
|
||||
editPath: '',
|
||||
showHideFile: false,
|
||||
delObj: '',
|
||||
delDialog: false,
|
||||
renameBox: false,
|
||||
renameStr: '',
|
||||
fileInfo: '',
|
||||
fileInfoShow: false,
|
||||
fileAttr: [
|
||||
{ name: 'overall.type', key: 'isDir' },
|
||||
{ name: 'config.operationlog.ip', key: 'ip' },
|
||||
{ name: 'asset.location', key: 'location' },
|
||||
{ name: 'backup.size', key: 'size' },
|
||||
{ name: 'terminal.modifyTime', key: 'uts' },
|
||||
{ name: 'Owner', key: 'Owner' },
|
||||
{ name: 'dashboard.panel.chartForm.group', key: 'group' },
|
||||
{ name: 'config.menus.perms', key: 'permissionsString' }
|
||||
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
updateUuid () {
|
||||
return this.$store.getters.getUpdateUuid
|
||||
},
|
||||
updateIndex () {
|
||||
return this.$store.getters.getUpdateIndex
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// this.init()
|
||||
},
|
||||
watch: {
|
||||
fileDirectoryShow (n) {
|
||||
if (n) {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
updateIndex (n) {
|
||||
if (this.updateUuid == this.uuid) {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
this.timer = setTimeout(() => {
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
this.timer = null
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
bytes: chartDataFormat.getUnit(7).compute,
|
||||
init () {
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
},
|
||||
showEditPath () {
|
||||
this.editPath = this.fileDirectory
|
||||
this.editPathShow = true
|
||||
},
|
||||
hideEditPath () {
|
||||
this.editPath = ''
|
||||
this.editPathShow = false
|
||||
},
|
||||
goEditPath () {
|
||||
this.getSftpPath(this.editPath)
|
||||
setTimeout(() => {
|
||||
this.editPath = ''
|
||||
this.editPathShow = false
|
||||
})
|
||||
},
|
||||
selectFile (item) {
|
||||
if (item.isDir) {
|
||||
const path = this.fileDirectory == '/' ? '' : this.fileDirectory
|
||||
this.getSftpPath(path + '/' + item.name)
|
||||
}
|
||||
return false
|
||||
},
|
||||
showFileInfo (item) {
|
||||
this.fileInfo = item
|
||||
this.fileInfoShow = true
|
||||
},
|
||||
newFolder (flag) {
|
||||
if (!flag) {
|
||||
this.newFolderBoxShow = false
|
||||
this.folder = ''
|
||||
return
|
||||
}
|
||||
const path = this.fileDirectory == '/' ? '' : this.fileDirectory
|
||||
const params = {
|
||||
uuid: this.uuid,
|
||||
path: path + '/' + this.folder
|
||||
}
|
||||
this.$post('/terminal/sftp/mkdir', params).then(res => {
|
||||
this.newFolderBoxShow = false
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
})
|
||||
},
|
||||
backFileDirectory () {
|
||||
const arr = this.fileDirectory.split('/')
|
||||
arr.pop()
|
||||
const path = arr.join('/')
|
||||
this.getSftpPath(path || '/')
|
||||
return false
|
||||
},
|
||||
gotoPath (item, index) {
|
||||
const path = '/' + this.breadcrumb.slice(0, index + 1).join('/')
|
||||
this.getSftpPath(path || '/')
|
||||
},
|
||||
getSftpPath (path) {
|
||||
const params = {
|
||||
uuid: this.uuid,
|
||||
path: path,
|
||||
showHideFile: this.showHideFile
|
||||
}
|
||||
this.fileDirectoryLoading = true
|
||||
this.$post('/terminal/sftp/ls', params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.fileDirectoryLoading = false
|
||||
this.fileDirectory = res.data.path
|
||||
res.data.list.forEach(item => {
|
||||
if (item.name[0] === '.') {
|
||||
item.isHide = true
|
||||
}
|
||||
})
|
||||
this.fileList = res.data.list
|
||||
this.oldFileList = res.data.list
|
||||
this.editPath = ''
|
||||
this.breadcrumb = res.data.path.split('/').filter(item => item)
|
||||
if (this.nameOrderType) {
|
||||
this.orderBy('nameOrderType',this.nameOrderType , 'name')
|
||||
}
|
||||
if (this.sizeOrderType) {
|
||||
this.orderBy('sizeOrderType',this.sizeOrderType , 'size')
|
||||
}
|
||||
if (this.dateOrderType) {
|
||||
this.orderBy('dateOrderType',this.dateOrderType , 'cts')
|
||||
}
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
this.editPath = ''
|
||||
}
|
||||
})
|
||||
},
|
||||
uploadFile () {
|
||||
const params = {
|
||||
uuid: this.uuid,
|
||||
path: this.fileDirectory,
|
||||
myId: 'upload' + this.uuid + new Date().getTime(),
|
||||
type: 'upload',
|
||||
isStart: false,
|
||||
isFinish: false,
|
||||
isError: false,
|
||||
importFileList: [],
|
||||
total: '',
|
||||
speed: '',
|
||||
fileLength: '',
|
||||
startTime: '',
|
||||
cancel: '',
|
||||
axios: '',
|
||||
timer: '',
|
||||
done: 0,
|
||||
delObj: ''
|
||||
}
|
||||
this.$store.dispatch('uploadFile', params)
|
||||
},
|
||||
downloadFile (item) {
|
||||
if (item.timer) {
|
||||
clearTimeout(item.timer)
|
||||
}
|
||||
item.timer = setTimeout(() => {
|
||||
const path = this.fileDirectory == '/' ? '' : this.fileDirectory
|
||||
const params = {
|
||||
...item,
|
||||
uuid: this.uuid,
|
||||
path: path + '/' + item.name,
|
||||
myId: 'download' + this.uuid + new Date().getTime(),
|
||||
type: 'download',
|
||||
isStart: false,
|
||||
isFinish: false,
|
||||
isError: false,
|
||||
total: '',
|
||||
speed: '',
|
||||
fileLength: '',
|
||||
startTime: '',
|
||||
cancel: '',
|
||||
axios: ''
|
||||
}
|
||||
this.$store.dispatch('dispatchAddFileList', params)
|
||||
}, 300)
|
||||
},
|
||||
setRename () {
|
||||
this.renameBox = false
|
||||
},
|
||||
delFile () {
|
||||
const item = this.delObj
|
||||
const path = this.fileDirectory == '/' ? '' : this.fileDirectory
|
||||
const params = {
|
||||
uuid: this.uuid,
|
||||
path: path + '/' + item.name
|
||||
}
|
||||
this.$post('/terminal/sftp/rm', params).then(res => {
|
||||
if (res.code == 200) {
|
||||
this.delDialog = false
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
} else {
|
||||
this.delDialog = false
|
||||
this.getSftpPath(this.fileDirectory)
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
selIcon (item) {
|
||||
// console.log(item)
|
||||
const hz = item.name.split('.')[1]
|
||||
if (item.isDir) {
|
||||
return 'nz-icon-Folder colorFA901C'
|
||||
}
|
||||
if (item.isReg) {
|
||||
return 'nz-icon-File'
|
||||
}
|
||||
if (item.isFifo) {
|
||||
return 'nz-icon-guandaowenjian'
|
||||
}
|
||||
if (item.isSock) {
|
||||
return 'nz-icon-taojieziwenjian'
|
||||
}
|
||||
if (item.isBlk) {
|
||||
return 'nz-icon-kuaishebeiwenjian'
|
||||
}
|
||||
return 'nz-icon-File'
|
||||
},
|
||||
selInfo (item, key) {
|
||||
if (key === 'isDir') {
|
||||
if (item.isDir) {
|
||||
return this.$t('terminal.catalogueFile')
|
||||
} else {
|
||||
return this.$t('backup.File')
|
||||
}
|
||||
}
|
||||
if (key === 'ip') {
|
||||
return this.host
|
||||
}
|
||||
// fileAttr: [
|
||||
// { name: 'overall.type', key: 'isDir' },
|
||||
// { name: 'config.operationlog.ip', key: 'ip' },
|
||||
// { name: 'asset.location', key: 'location' },
|
||||
// { name: 'backup.size', key: 'size' },
|
||||
// { name: 'terminal.modifyTime', key: 'uts' },
|
||||
// { name: 'Owner', key: 'Owner' },
|
||||
// { name: 'dashboard.panel.chartForm.group', key: 'group' },
|
||||
// { name: 'config.menus.perms', key: 'permissionsString' }
|
||||
//
|
||||
// ]
|
||||
if (key === 'location') {
|
||||
return this.fileDirectory
|
||||
}
|
||||
if (key === 'size' && !item.isDir) {
|
||||
return this.bytes(item.size, 0, 0)
|
||||
} else if (key === 'size' && item.isDir) {
|
||||
return ''
|
||||
}
|
||||
if (key === 'uts') {
|
||||
return this.momentTz(item.uts * 1000)
|
||||
}
|
||||
if (key === 'Owner') {
|
||||
return item.uid
|
||||
}
|
||||
if (key === 'group') {
|
||||
return item.gid
|
||||
}
|
||||
if (key === 'permissionsString') {
|
||||
return item.permissionsString
|
||||
}
|
||||
return '-'
|
||||
},
|
||||
orderBy (key, type, order) {
|
||||
let orderType = type
|
||||
if (!orderType) {
|
||||
orderType = this[key] === 'asc' ? 'desc' : 'asc'
|
||||
}
|
||||
this.sizeOrderType = 0
|
||||
this.dateOrderType = 0
|
||||
this.nameOrderType = 0
|
||||
if (this[key] == orderType) {
|
||||
this[key] = 0
|
||||
this.fileList = this.oldFileList
|
||||
} else if (orderType == 'nameOrderType') {
|
||||
this[key] = orderType
|
||||
let isDirArr = this.oldFileList.filter(item => item.isDir)
|
||||
let isRegArr = this.oldFileList.filter(item => !item.isDir)
|
||||
isDirArr = this.$loadsh.orderBy(isDirArr, [user => user.name.toLowerCase()], [orderType])
|
||||
isRegArr = this.$loadsh.orderBy(isRegArr, [user => user.name.toLowerCase()], [orderType])
|
||||
this.fileList = []
|
||||
if (orderType === 'asc') {
|
||||
this.fileList = this.fileList.concat(isDirArr, isRegArr)
|
||||
} else {
|
||||
this.fileList = this.fileList.concat(isRegArr, isDirArr)
|
||||
}
|
||||
} else {
|
||||
this[key] = orderType
|
||||
let isDirArr = this.oldFileList.filter(item => item.isDir)
|
||||
let isRegArr = this.oldFileList.filter(item => !item.isDir)
|
||||
isDirArr = this.$loadsh.orderBy(isDirArr, order, orderType)
|
||||
isRegArr = this.$loadsh.orderBy(isRegArr, order, orderType)
|
||||
this.fileList = []
|
||||
if (orderType === 'asc') {
|
||||
this.fileList = this.fileList.concat(isDirArr, isRegArr)
|
||||
} else {
|
||||
this.fileList = this.fileList.concat(isRegArr, isDirArr)
|
||||
}
|
||||
}
|
||||
},
|
||||
tableOperation ([command, row, param]) {
|
||||
switch (command) {
|
||||
case 'rename':
|
||||
this.renameStr = row.name
|
||||
this.renameBox = true
|
||||
break
|
||||
case 'download':
|
||||
this.downloadFile(row)
|
||||
break
|
||||
case 'del':
|
||||
this.delObj = row
|
||||
this.delDialog = true
|
||||
// this.delFile(row)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
288
nezha-fronted/src/components/cli/fileListState.vue
Normal file
288
nezha-fronted/src/components/cli/fileListState.vue
Normal file
@@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 显示进度-->
|
||||
<div class="file-state-panel" v-show="fileStateBox && fileList.length" :style="{'top': position.top + 'px', right: '10px'}" ref="fileStatePanel" :class="position.top>0? 'translationOriginDown': 'translationOriginUp'">
|
||||
<div class="file-state-panel-header">
|
||||
<span class="file-state-panel-title">{{$t('terminal.filetransfer')}}</span>
|
||||
<i class="nz-icon nz-icon-Clear" @click="clearFileList"></i>
|
||||
</div>
|
||||
<div class="file-state-panel-content" v-if="fileList.length">
|
||||
<div v-for="item in fileList" :key="item.myId" class="file-state-panel-item">
|
||||
<div class="item-icon"> <i class="nz-icon" :class="{'nz-icon-upload':item.type === 'upload','nz-icon-download1':item.type === 'download'}"/></div>
|
||||
<div class="item-progress">
|
||||
<div class="item-progress-top text-ellipsis">{{item.name}}</div>
|
||||
<div class="item-progress-middle">
|
||||
<el-progress :show-text="false" :percentage="item.done" :color="customColorMethod.bind(item)"></el-progress>
|
||||
</div>
|
||||
<div class="item-progress-bottom">
|
||||
<span>{{bytes(item.total, 0, 0)}}</span>
|
||||
<span v-if="!item.isFinish && !item.isError">{{item.speed}}</span>
|
||||
<span v-if="item.isFinish">Completed</span>
|
||||
<span v-if="item.isError">Error</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-state">
|
||||
<i v-if="item.isFinish" class="nz-icon nz-icon-check" @click="removeRecord(item)"/>
|
||||
<i v-else class="nz-icon nz-icon-close" @click="removeRecord(item)"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="file-nodata">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#nz-icon-no-data-list"></use>
|
||||
</svg>
|
||||
<div class="table-no-data__title">No results found</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 上传文件-->
|
||||
<div style="display: none">
|
||||
<el-upload
|
||||
:ref="'upload'"
|
||||
:auto-upload="false"
|
||||
:on-change="importChange"
|
||||
:multiple="false"
|
||||
:file-list="importFileList"
|
||||
action=""
|
||||
class="upload-demo"
|
||||
drag>
|
||||
</el-upload>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios'
|
||||
import chartDataFormat from '@/components/chart/chartDataFormat'
|
||||
export default {
|
||||
name: 'fileListState',
|
||||
computed: {
|
||||
fileList () {
|
||||
return this.$store.getters.getFileList
|
||||
},
|
||||
uploadItem () {
|
||||
return this.$store.getters.getUploadItem
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
myFileList: [],
|
||||
importFileList: [],
|
||||
position: {
|
||||
top: 50,
|
||||
right: 0
|
||||
},
|
||||
fileStateBox: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fileList: {
|
||||
immediate: true,
|
||||
handler (n) {
|
||||
if (!n.length) {
|
||||
this.fileStateBox = false
|
||||
}
|
||||
n.forEach(item => {
|
||||
if (!item.isStart) {
|
||||
item.total = 1
|
||||
item.fileLength = 0
|
||||
item.startTime = new Date().getTime()
|
||||
item.speed = '0b/s'
|
||||
if (item.type === 'download') {
|
||||
item.isStart = true
|
||||
this.download(item)
|
||||
}
|
||||
if (item.type === 'upload') {
|
||||
item.isStart = true
|
||||
this.upload(item)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
uploadItem: {
|
||||
handler (n) {
|
||||
if (n && n.myId) {
|
||||
this.$refs.upload.$children[0].$refs.input.click()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
bytes: chartDataFormat.getUnit(7).compute,
|
||||
customColorMethod (percentage, item) {
|
||||
if (percentage < 100) {
|
||||
return '#3B92F1'
|
||||
} else {
|
||||
return '#21BF9A'
|
||||
}
|
||||
},
|
||||
download (item) {
|
||||
const self = this
|
||||
const CancelToken = axios.CancelToken
|
||||
item.cancel = CancelToken.source()
|
||||
item.startTime = new Date().getTime()
|
||||
const params = {
|
||||
uuid: item.uuid,
|
||||
path: item.path
|
||||
}
|
||||
axios.post('/terminal/sftp/download', {
|
||||
...params
|
||||
}, {
|
||||
responseType: 'blob',
|
||||
cancelToken: item.cancel.token,
|
||||
onDownloadProgress: function (progressEvent) {
|
||||
// 处理原生进度事件
|
||||
item.total = progressEvent.total
|
||||
item.fileLength = progressEvent.loaded
|
||||
item.speed = item.fileLength / ((new Date().getTime() - item.startTime) / 1000)
|
||||
item.speed = self.bytes(item.speed, 0, 0) + '/s'
|
||||
item.done = (item.fileLength / item.total) * 100
|
||||
// this.$set(this.fileList, 0,item)
|
||||
}
|
||||
}).then(res => {
|
||||
item.isFinish = true
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
// 兼容ie11
|
||||
const blobObject = new Blob([res.data])
|
||||
window.navigator.msSaveOrOpenBlob(blobObject, item.name)
|
||||
} else {
|
||||
const url = URL.createObjectURL(new Blob([res.data]))
|
||||
const a = document.createElement('a')
|
||||
document.body.appendChild(a) // 此处增加了将创建的添加到body当中
|
||||
a.href = url
|
||||
a.download = item.name
|
||||
a.target = '_blank'
|
||||
a.click()
|
||||
a.remove() // 将a标签移除
|
||||
}
|
||||
}, error => {
|
||||
const $self = this
|
||||
const reader = new FileReader()
|
||||
reader.onload = function (event) {
|
||||
const responseText = reader.result
|
||||
const exception = JSON.parse(responseText)
|
||||
if (exception.message) {
|
||||
$self.$message.error(exception.message)
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
reader.readAsText(error.response.data)
|
||||
})
|
||||
},
|
||||
importChange (file, fileList) {
|
||||
if (fileList.length > 0) {
|
||||
this.uploadItem.importFileList = [fileList[fileList.length - 1]]
|
||||
}
|
||||
if (this.uploadItem.importFileList.length) {
|
||||
this.$store.dispatch('dispatchAddFileList', this.uploadItem)
|
||||
}
|
||||
},
|
||||
removeRecord (item) {
|
||||
if (!item.isFinish) {
|
||||
item.cancel.cancel('operation canceled by the user.')
|
||||
if (item.done || (item.fileLength === item.total)) { // 取消 上传 50-100
|
||||
clearInterval(item.timer)
|
||||
if (item.tid) {
|
||||
this.$delete('/terminal/sftp/cancel/' + item.tid).then(res => {
|
||||
if (res.code === 200) {
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$store.dispatch('dispatchDelFileList', item)
|
||||
},
|
||||
upload (item) {
|
||||
const self = this
|
||||
const CancelToken = axios.CancelToken
|
||||
item.cancel = CancelToken.source()
|
||||
const form = new FormData()
|
||||
const importFile = item.importFileList[0]
|
||||
item.name = importFile.name
|
||||
form.append('file', importFile.raw)
|
||||
form.append('uuid', item.uuid)
|
||||
form.append('path', item.path)
|
||||
axios({
|
||||
url: '/terminal/sftp/upload',
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
data: form,
|
||||
cancelToken: item.cancel.token,
|
||||
onUploadProgress: function (progressEvent) {
|
||||
// 处理原生进度事件
|
||||
item.total = progressEvent.total
|
||||
item.fileLength = progressEvent.loaded
|
||||
item.speed = item.fileLength / ((new Date().getTime() - item.startTime) / 1000)
|
||||
item.speed = self.bytes(item.speed, 0, 0) + '/s'
|
||||
item.done = (item.fileLength / (item.total * 2)) * 100
|
||||
}
|
||||
|
||||
}).then(response => {
|
||||
const res = response.data
|
||||
// item.isFinish = true
|
||||
if (res.code == 200) {
|
||||
self.nextUpload(item, res.data.tid)
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
nextUpload (item, tid) {
|
||||
// this.$message.success(response.msg)
|
||||
item.timer = setInterval(() => { // 上传 50-100
|
||||
item.tid = tid
|
||||
this.$get('/terminal/sftp/process/' + tid).then((res) => {
|
||||
item.done = 50 + parseInt(res.data.done) / 2
|
||||
item.speed = (item.fileLength + (item.done * 0.01 * item.total)) / ((new Date().getTime() - item.startTime) / 1000)
|
||||
item.speed = this.bytes(item.speed, 0, 0) + '/s'
|
||||
if (item.done === 100) {
|
||||
item.isFinish = true
|
||||
clearInterval(item.timer)
|
||||
// todo 上传成功后 刷新对应terminal
|
||||
this.$store.dispatch('upDateConsole', item.uuid)
|
||||
}
|
||||
})
|
||||
}, 200)
|
||||
},
|
||||
fileStateShow (flag, type) {
|
||||
if (JSON.stringify(flag) == JSON.stringify(this.fileStateBox)) {
|
||||
return
|
||||
}
|
||||
if (flag) {
|
||||
this.fileStateBox = flag
|
||||
if (type === 'down') {
|
||||
this.position = {
|
||||
top: 45,
|
||||
right: 0
|
||||
}
|
||||
} else {
|
||||
this.position = {
|
||||
top: -195,
|
||||
right: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
let animationClass = ''
|
||||
animationClass = flag ? 'zoomIn' : 'zoomOut'
|
||||
this.animateCSS(this.$refs.fileStatePanel, animationClass).then((message) => {
|
||||
this.fileStateBox = flag
|
||||
})
|
||||
},
|
||||
clearFileList () {
|
||||
this.fileList.forEach(item => {
|
||||
this.removeRecord(item)
|
||||
})
|
||||
setTimeout(() => {
|
||||
this.$store.dispatch('dispatchFileList', [])
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
96
nezha-fronted/src/components/cli/terminal.vue
Normal file
96
nezha-fronted/src/components/cli/terminal.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<div class="webTerminal">
|
||||
<div class="web-terminal-header">
|
||||
<div> <img alt="loading..." height="26" :src="logo?logo:require('../../assets/img/logo1-2.png')"/>Web terminal</div>
|
||||
<div>
|
||||
<div class="console-title-icon" style='right: 106px;display: inline;position: absolute' @click="showFileState" v-show="fileList.length">
|
||||
<i class="nz-icon nz-icon-a-filetransfer" :title="$t('terminal.filetransfer')"></i>
|
||||
<span v-show="fileList.length>0" class="right-tip">{{fileList.length<=99?fileList.length:'99+'}}</span>
|
||||
</div>
|
||||
{{name}}</div>
|
||||
</div>
|
||||
<fileListState v-clickoutside="hideFileState" ref="fileListState"/>
|
||||
<webSSHNew ref="websshNew" />
|
||||
<el-input :placeholder="'发送文本到所有SSH终端'" size="small" class="shell-input" v-model="message" @keyup.enter.native="sendMessage"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import webSSHNew from '@/components/cli/webSSHNew'
|
||||
import fileListState from './fileListState'
|
||||
export default {
|
||||
name: 'terminal',
|
||||
components: {
|
||||
webSSHNew,
|
||||
fileListState
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
logo: '',
|
||||
fileListStateType: '',
|
||||
message: '',
|
||||
name: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language () { return this.$store.getters.getLanguage },
|
||||
fileList () {
|
||||
return this.$store.getters.getFileList
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const self = this
|
||||
window.addEventListener('setItemEvent', function (e) {
|
||||
if (e.key == 'nz-sys-logo' && e.value) {
|
||||
self.logo = e.value
|
||||
}
|
||||
})
|
||||
this.logo = localStorage.getItem('nz-sys-logo')
|
||||
},
|
||||
mounted () {
|
||||
const self = this
|
||||
this.name = localStorage.getItem('nz-username')
|
||||
window.onbeforeunload = () => {
|
||||
const opener = window.opener
|
||||
opener.postMessage(
|
||||
JSON.stringify({
|
||||
close: true
|
||||
})
|
||||
)
|
||||
}
|
||||
window.addEventListener('message', function (e) {
|
||||
if (e.data) {
|
||||
try {
|
||||
const data = JSON.parse(e.data)
|
||||
self.$get('asset/asset/' + data.id).then(res => {
|
||||
const asset = res.data
|
||||
self.$refs.websshNew.addConsole(asset.id, asset.manageIp, '', '', 'asset')
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
showFileState () {
|
||||
let type = 'down'
|
||||
this.fileListStateType = type = 'down'
|
||||
this.$refs.fileListState.fileStateShow(!this.$refs.fileListState.fileStateBox, type)
|
||||
},
|
||||
hideFileState () {
|
||||
this.$refs.fileListState.fileStateShow(false, this.fileListStateType)
|
||||
},
|
||||
sendMessage () {
|
||||
this.$refs.websshNew.sendMessage(this.message)
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -31,15 +31,23 @@
|
||||
:popper-class="'popover-webshell'"
|
||||
>
|
||||
<div>
|
||||
Session ID : {{item.uuid.slice(0,7).toLocaleUpperCase()}}
|
||||
Session ID : {{item.terminal.uuid.slice(0,7).toLocaleUpperCase()}}
|
||||
</div>
|
||||
<span slot="reference"> <i class="nz-icon nz-icon-about" /></span>
|
||||
</el-popover>
|
||||
<div :class="{'active-icon grey':item.circleColor == 1,'active-icon green':item.circleColor == 2,'active-icon red':item.circleColor == 3}"
|
||||
style="margin-top: 0px;"></div>{{item.title}}
|
||||
</span>
|
||||
|
||||
<my-console :fontSize="fontSize" :idIndex="index" :isFullScreen="isFullScreen" :ref="'console'+index" :terminal="item.terminal" @closeConsole="removeTab" @refreshConsoleTitle="refreshTabTitle"></my-console>
|
||||
<my-console
|
||||
:fontSize="fontSize"
|
||||
:terminalType="item.terminal.terminalType"
|
||||
:idIndex="index"
|
||||
:isFullScreen="isFullScreen"
|
||||
:ref="'console'+index"
|
||||
:terminal="item.terminal"
|
||||
@loginFail="loginFail"
|
||||
@closeConsole="removeTab"
|
||||
@refreshConsoleTitle="refreshTabTitle"
|
||||
></my-console>
|
||||
|
||||
</el-tab-pane>
|
||||
<el-tab-pane key="add" name="addConsole" style="width: 20px">
|
||||
@@ -59,13 +67,17 @@
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="console-icon">
|
||||
<div class="console-title-icon" style='right: 106px;display: inline;' @click="showFileState" v-show="fileList.length">
|
||||
<i class="nz-icon nz-icon-a-filetransfer" :title="$t('terminal.filetransfer')"></i>
|
||||
<span v-show="fileList.length>0" class="right-tip">{{fileList.length<=99?fileList.length:'99+'}}</span>
|
||||
</div>
|
||||
<i @click="minScreen" class="nz-icon nz-icon-minus console-title-icon" style='right: 76px;' :title="$t('overall.shrink')"></i>
|
||||
<i @click="fullScreen" class="el-icon-full-screen console-title-icon" style='right: 46px;' v-if="!isFullScreen" :title="$t('dashboard.screen')"></i>
|
||||
<i @click="exitFullScreen" class="nz-icon nz-icon-exit-full-screen console-title-icon" style='right: 46px;' v-else :title="$t('dashboard.screen.exit')"></i>
|
||||
<i @click="closeConsole" class="nz-icon nz-icon-close console-title-icon" style='right: 16px;' :title="$t('overall.close')"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<fileListState v-clickoutside="hideFileState" ref="fileListState"/>
|
||||
<div >
|
||||
<el-dialog :modal-append-to-body='false' :show-close="true" :title="uploadBox.title" :visible.sync="uploadBox.showUpload" @close="closeDialog" class="nz-dialog" width="500px" >
|
||||
<div >
|
||||
@@ -255,21 +267,27 @@
|
||||
|
||||
<script>
|
||||
import Console from './console'
|
||||
import fileListState from './fileListState'
|
||||
import uuidv1 from 'uuid/v1'
|
||||
import axios from 'axios'
|
||||
import { host, port } from '@/components/common/js/validate'
|
||||
export default {
|
||||
name: 'webSSH',
|
||||
components: {
|
||||
'my-console': Console
|
||||
'my-console': Console,
|
||||
fileListState
|
||||
},
|
||||
computed: {
|
||||
language () { return this.$store.getters.getLanguage }
|
||||
language () { return this.$store.getters.getLanguage },
|
||||
fileList () {
|
||||
return this.$store.getters.getFileList
|
||||
}
|
||||
},
|
||||
data () {
|
||||
const termFontSize = parseInt(localStorage.getItem('termFontSize'))
|
||||
return {
|
||||
selectValue: 'SSH',
|
||||
fileListStateType: 'down',
|
||||
searchMetrics: [
|
||||
{
|
||||
value: 'SSH',
|
||||
@@ -307,9 +325,9 @@ export default {
|
||||
isFullScreen: false,
|
||||
closeConfirmShow: false,
|
||||
closeRemember: false,
|
||||
initConsoleHeight: 300, // 只读,初始化高度
|
||||
consoleHeight: 250, // console高度
|
||||
resizeConsoleHeight: 250, // resize后的高度,用于记录最大化、最小化前的高度
|
||||
initConsoleHeight: 500, // 只读,初始化高度
|
||||
consoleHeight: 450, // console高度
|
||||
resizeConsoleHeight: 450, // resize后的高度,用于记录最大化、最小化前的高度
|
||||
currentTransform: 0,
|
||||
editableTabsValue: '-1', // 当前显示的console
|
||||
currentIndex: '-1',
|
||||
@@ -510,6 +528,7 @@ export default {
|
||||
host: this.customConnect.host,
|
||||
port: this.customConnect.port,
|
||||
authType: this.customConnect.authType,
|
||||
terminalType: this.customConnect.authProtocol,
|
||||
authUsername: encodeURIComponent(this.customConnect.authUsername),
|
||||
authPin: this.encode(this.customConnect.authPin),
|
||||
authPriKey: encodeURIComponent(this.customConnect.authPriKey),
|
||||
@@ -519,9 +538,16 @@ export default {
|
||||
authProtocol: encodeURIComponent(this.customConnect.authProtocol)
|
||||
}
|
||||
}
|
||||
this.editableTabsValue = newTabName
|
||||
this.editableTabs.push(console)
|
||||
|
||||
if (id) {
|
||||
this.$get('/asset/asset/' + id).then(res => {
|
||||
console.terminal.terminalType = res.data.type.authProtocol
|
||||
this.editableTabsValue = newTabName
|
||||
this.editableTabs.push(console)
|
||||
})
|
||||
} else {
|
||||
this.editableTabsValue = newTabName
|
||||
this.editableTabs.push(console)
|
||||
}
|
||||
setTimeout(function () {
|
||||
const tabScroll = document.getElementsByClassName('el-tabs__nav is-top')
|
||||
const tabViewWidth = document.getElementsByClassName('el-tabs__nav-scroll')
|
||||
@@ -620,9 +646,23 @@ export default {
|
||||
this.$store.commit('removeConsole')
|
||||
|
||||
if (this.editableTabs.length <= 0) {
|
||||
this.closeConsole()
|
||||
// this.closeConsole()
|
||||
}
|
||||
},
|
||||
loginFail (params) {
|
||||
this.removeTab(params.name)
|
||||
setTimeout(() => {
|
||||
if (params.assetId) {
|
||||
this.assetShowChange()
|
||||
} else {
|
||||
this.customConnect = {
|
||||
authType: Number(params.authType),
|
||||
...params
|
||||
}
|
||||
this.customShow = true
|
||||
}
|
||||
})
|
||||
},
|
||||
/* 活动标签切换时触发 */
|
||||
beforeLeave (currentName, oldName) {
|
||||
// 重点,如果name是add,则什么都不触发
|
||||
@@ -969,6 +1009,25 @@ export default {
|
||||
authProtocolPort: '',
|
||||
authProtocol: 1
|
||||
}
|
||||
},
|
||||
showFileState () {
|
||||
let type = 'down'
|
||||
const targetDiv = document.getElementById('shell-service')
|
||||
let height = targetDiv.style.height
|
||||
if (height) {
|
||||
height = height.slice(0, -2)
|
||||
if (height < 265) {
|
||||
this.fileListStateType = type = 'up'
|
||||
} else {
|
||||
this.fileListStateType = type = 'down'
|
||||
}
|
||||
} else {
|
||||
this.fileListStateType = type = 'down'
|
||||
}
|
||||
this.$refs.fileListState.fileStateShow(!this.$refs.fileListState.fileStateBox, type)
|
||||
},
|
||||
hideFileState () {
|
||||
this.$refs.fileListState.fileStateShow(false, this.fileListStateType)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -996,6 +1055,10 @@ export default {
|
||||
})
|
||||
const targetDiv = document.getElementById('shell-service')
|
||||
targetDiv.style.height = this.webSSHHeight
|
||||
if (!this.webSSHHeight) {
|
||||
this.initConsoleHeight = this.initConsoleHeight > (window.innerHeight * 0.4) ? this.initConsoleHeight : (window.innerHeight * 0.4)
|
||||
targetDiv.style.height = this.initConsoleHeight + 'px'
|
||||
}
|
||||
}
|
||||
this.$store.state.consoleShow = false
|
||||
}
|
||||
@@ -1004,6 +1067,7 @@ export default {
|
||||
created () {
|
||||
// window.addEventListener('resize',this.windowChange);
|
||||
window.addEventListener('resize', this.debounce(this.windowChange, 1000), false)
|
||||
this.initConsoleHeight = this.initConsoleHeight > (window.innerHeight * 0.4) ? this.initConsoleHeight : (window.innerHeight * 0.4)
|
||||
},
|
||||
mounted () {
|
||||
|
||||
|
||||
702
nezha-fronted/src/components/cli/webSSHNew.vue
Normal file
702
nezha-fronted/src/components/cli/webSSHNew.vue
Normal file
@@ -0,0 +1,702 @@
|
||||
<template>
|
||||
<div class="ani-webSHH-height web-terminal-new" id="web-terminal-new">
|
||||
<el-tabs :before-leave="beforeLeave"
|
||||
@tab-click="handleClick"
|
||||
@tab-remove="removeTab"
|
||||
type="border-card"
|
||||
v-model="editableTabsValue" >
|
||||
<el-tab-pane :key="item.name"
|
||||
:label="item.title"
|
||||
:name="item.name"
|
||||
closable
|
||||
v-for="(item, index) in editableTabs"
|
||||
>
|
||||
<!-- tab显示的内容 1 grey,2 green, 3 red-->
|
||||
<span slot="label" class="el-tabs__item-label">
|
||||
<div class="active-icon" :class="item.terminal.isLogin ? 'green-bg': 'red-bg'"></div>
|
||||
<div class="el-tabs__item-label-name text-ellipsis">
|
||||
{{item.terminal.userName}}
|
||||
</div>
|
||||
<el-popover
|
||||
slot="label"
|
||||
placement="bottom"
|
||||
:ref="'popover' + index"
|
||||
width="180"
|
||||
trigger="click"
|
||||
:popper-class="'popover-webshell popover-webshell-new'"
|
||||
>
|
||||
<div class="popover-webshell-box">
|
||||
<div class="webshell-box-top">
|
||||
Session ID : {{item.terminal.uuid.slice(0,7).toLocaleUpperCase()}}
|
||||
</div>
|
||||
<div class="webshell-box-middle" v-show="item.terminal.userName">
|
||||
<div @click="duplicate(item, index)" class="webshell-box-item">
|
||||
<i class="nz-icon nz-icon-override"/>
|
||||
{{$t('overall.duplicate')}}
|
||||
</div>
|
||||
<div @click="reconnect(item, index)" v-show="item.terminal.userName" class="webshell-box-item">
|
||||
<i class="nz-icon nz-icon-reconnect"></i>
|
||||
{{$t('terminal.reconnect')}}
|
||||
</div>
|
||||
<div @click="showFileDir(item, index)" class="webshell-box-item" v-if="item.terminal.isLogin && item.terminal.terminalType == '1'">
|
||||
<i class="nz-icon nz-icon-SFTP"></i>
|
||||
{{$t('terminal.sftp')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="webshell-box-item webshell-box-bottom" @click="closeShell(item,index)">
|
||||
<div >
|
||||
<i class="nz-icon nz-icon-close"/>
|
||||
{{$t('overall.close')}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<span slot="reference" class="icon-reference"> <i class="nz-icon nz-icon-more1" /></span>
|
||||
</el-popover>
|
||||
</span>
|
||||
|
||||
<terminal
|
||||
:fontSize="fontSize"
|
||||
:terminalType="item.terminal.terminalType"
|
||||
:idIndex="index"
|
||||
:ref="'console'+index"
|
||||
:terminal="item.terminal"
|
||||
@loginFail="loginFail"
|
||||
@closeConsole="removeTab"
|
||||
@refreshConsoleTitle="refreshTabTitle"
|
||||
></terminal>
|
||||
|
||||
</el-tab-pane>
|
||||
<el-tab-pane key="add" name="addConsole" class="add-console" style="width: 20px">
|
||||
<el-popover
|
||||
slot="label"
|
||||
placement="bottom-start"
|
||||
width="150"
|
||||
trigger="hover"
|
||||
:popper-class="'popover-webshell'"
|
||||
>
|
||||
<div>
|
||||
<div class="popover-webshell-item" @click="assetShowChange"><i class="nz-icon nz-icon-menu-assets" />{{$t('webshell.selAsset')}}</div>
|
||||
<div class="popover-webshell-item" @click="customShow=true"><i class="nz-icon nz-icon-edit" />{{$t('webshell.custom')}}</div>
|
||||
</div>
|
||||
<span slot="reference" style="padding:8px;font-size:20px;font-weight:bold;">+</span>
|
||||
</el-popover>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<!--弹窗-->
|
||||
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="assetShow" @close="closeAssetCustom" class="nz-dialog" width="620px">
|
||||
<div slot="title">{{$t('webshell.connect')}}</div>
|
||||
<div >
|
||||
<el-form label-width="120px" size="small" :model="assetContent" label-position = "top" :rules="rules" ref="assetConnect" v-my-loading="assetLoading" >
|
||||
<el-form-item :label='$t("overall.asset")' prop="assetId" class="flex">
|
||||
<el-dropdown trigger="click" class="header-el-dropdown">
|
||||
<span class="el-dropdown-link">
|
||||
<span>{{selectValue}}</span>
|
||||
<span><i class="el-icon-arrow-down el-icon--right"></i></span>
|
||||
</span>
|
||||
<el-dropdown-menu style="width: 118px" class="el-dropdown__width right-box-select-top right-public-box-dropdown-top" placement="bottom-end" slot="dropdown">
|
||||
<el-dropdown-item
|
||||
@click.native="selectAssetAuth(item.label, item.value)"
|
||||
v-for="item in searchMetrics"
|
||||
:key="item.value"><i class="nz-icon" :class="item.icon" style="margin-right: 5px"/>{{item.label}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<v-selectpage
|
||||
ref="selectPage"
|
||||
style="flex: 1"
|
||||
data="asset/asset"
|
||||
:params="selectPageParams"
|
||||
:tb-columns="columns"
|
||||
key-field="id"
|
||||
show-field="manageIp"
|
||||
search-field="manageIp"
|
||||
v-model="assetContent.assetId"
|
||||
size="small"
|
||||
:language="language"
|
||||
:placeholder="$t('dashboard.panel.chartForm.selectAsset')"
|
||||
id="box-input-asset-id"
|
||||
:result-format="resultFormat"></v-selectpage>
|
||||
<button :disabled="prevent_opt.save" class="nz-btn nz-btn-size-normal nz-btn-style-normal" type="button" @click.prevent="connect">Connect</button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog :modal-append-to-body='false' :show-close="true" :visible.sync="customShow" @close="closeAssetCustom" class="nz-dialog" width="620px"destroy-on-close >
|
||||
<div slot="title">{{$t('webshell.connect')}}</div>
|
||||
<div >
|
||||
<el-form label-width="120px" size="small" :model="customConnect" label-position = "top" :rules=" customConnect.authProtocol ===2 ? rulesCustom2: rulesCustom" ref="customConnect" v-my-loading="assetLoading" class="custom">
|
||||
<el-form-item :label='$t("webshell.protocol")' prop="authProtocol">
|
||||
<el-select @change="protocolChange" value-key="id" popper-class="config-dropdown w260 right-box-select-top right-public-box-dropdown-top" v-model="customConnect.authProtocol" placeholder="" size="small" id="webshell-box-input-protocol">
|
||||
<el-option v-for="item in authProtocol" :id="'dc-principal-op-'+item.value" :key="item.value" :label="item.name" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("asset.authType")' prop="authType" @change="authTypeChange" >
|
||||
<el-select value-key="id" popper-class="config-dropdown w260 right-box-select-top right-public-box-dropdown-top" v-model="customConnect.authType" :disabled="customConnect.authProtocol === 2" placeholder="" size="small" id="webshell-box-input-protocol">
|
||||
<el-option v-for="item in authType" :id="'dc-principal-op-'+item.value" :key="item.value" :label="item.name" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("asset.host")' prop="host">
|
||||
<el-input v-model="customConnect.host" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("asset.port")' prop="port">
|
||||
<el-input v-model="customConnect.port" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("profile.username")' prop="authUsername">
|
||||
<el-input v-model="customConnect.authUsername" size="small" autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="customConnect.authType === 2"
|
||||
:label='$t("asset.talon.token")'
|
||||
prop="authPriKey"
|
||||
>
|
||||
<el-input v-model="customConnect.authPriKey" size="small" autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("login.pin")' prop="authPin"
|
||||
:rules="[
|
||||
{ required: customConnect.authType ===1, message:$t('validate.required'), trigger: 'change'},
|
||||
]">
|
||||
<el-input v-model="customConnect.authPin" size="small" type="password" autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="customConnect.authProtocol === 2"
|
||||
:label='$t("asset.usernamePrompt")'
|
||||
prop="authUserTip">
|
||||
<el-input v-model="customConnect.authUserTip" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="customConnect.authProtocol === 2"
|
||||
:label='$t("asset.pinPrompt")'
|
||||
prop="authPinTip"
|
||||
>
|
||||
<el-input v-model="customConnect.authPinTip" size="small"/>
|
||||
</el-form-item>
|
||||
<div class="right-box__footer custom-footer">
|
||||
<button id="asset-edit-cancel" @click="customShow=false" class="footer__btn footer__btn--light" type="button">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
<button id="asset-edit-save" :disabled="prevent_opt.save" class="footer__btn" @click.prevent="connect" type="button">
|
||||
<span>{{$t('webshell.connect')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import terminal from './consoleNew'
|
||||
import { host, port } from '@/components/common/js/validate'
|
||||
export default {
|
||||
name: 'webSSH',
|
||||
components: {
|
||||
terminal
|
||||
},
|
||||
computed: {
|
||||
language () { return this.$store.getters.getLanguage },
|
||||
fileList () {
|
||||
return this.$store.getters.getFileList
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tabIndex: 0,
|
||||
editableTabs: [],
|
||||
editableTabsValue: '',
|
||||
fontSize: 16,
|
||||
assetShow: false,
|
||||
selectValue: 'SSH',
|
||||
fileListStateType: 'down',
|
||||
searchMetrics: [
|
||||
{
|
||||
value: 'SSH',
|
||||
label: 'SSH'
|
||||
},
|
||||
{
|
||||
value: 'Telnet',
|
||||
label: 'Telnet'
|
||||
}
|
||||
],
|
||||
selectPageParams: {
|
||||
authProtocol: 1
|
||||
},
|
||||
authProtocol: [
|
||||
{
|
||||
value: 1,
|
||||
name: 'SSH'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
name: 'TELNET'
|
||||
}
|
||||
],
|
||||
authType: [
|
||||
{
|
||||
value: 1,
|
||||
name: 'Password'
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
name: 'Key'
|
||||
}
|
||||
],
|
||||
consoleShow: false,
|
||||
closeConfirmShow: false,
|
||||
customConnect: {
|
||||
host: '',
|
||||
port: 22,
|
||||
authType: 1,
|
||||
authUsername: '',
|
||||
authPin: '',
|
||||
authPriKey: '',
|
||||
authUserTip: '',
|
||||
authPinTip: '',
|
||||
authProtocolPort: '',
|
||||
authProtocol: 1
|
||||
},
|
||||
columns: [
|
||||
{ title: 'ID', data: 'id' },
|
||||
{
|
||||
title: 'Name',
|
||||
data: function (row) {
|
||||
if (row.name.length > 15) {
|
||||
return row.name.substring(0, 12) + '...'
|
||||
}
|
||||
return row.name
|
||||
}
|
||||
},
|
||||
{ title: 'Manage Ip', data: 'manageIp' },
|
||||
{
|
||||
title: 'Type',
|
||||
data: (row) => {
|
||||
return row.type ? row.type.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Model',
|
||||
data: (row) => {
|
||||
return row.model ? row.model.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Datacenter',
|
||||
data: (row) => {
|
||||
return row.dc ? row.dc.name : ''
|
||||
}
|
||||
}
|
||||
],
|
||||
rules: {
|
||||
assetId: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
rulesCustom: {
|
||||
authProtocol: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authType: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
host: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' },
|
||||
{ validator: host, trigger: 'change' }
|
||||
],
|
||||
port: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' },
|
||||
{ validator: port, trigger: 'change' }
|
||||
],
|
||||
authUsername: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authPin: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
]
|
||||
// authUserTip: [
|
||||
// { validator: this.authUserTipValid, trigger: 'change' }
|
||||
// ],
|
||||
// authPinTip: [
|
||||
// { validator: this.authPinTipValid, trigger: 'change' }
|
||||
// ],
|
||||
// authPriKey: [
|
||||
// { validator: this.authPriKeyValid, trigger: 'change' }
|
||||
// ]
|
||||
},
|
||||
rulesCustom2: {
|
||||
authProtocol: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authType: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
host: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' },
|
||||
{ validator: host, trigger: 'change' }
|
||||
],
|
||||
port: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' },
|
||||
{ validator: port, trigger: 'change' }
|
||||
],
|
||||
authUsername: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authPin: [
|
||||
{ required: false, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authUserTip: [
|
||||
{ required: false, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authPinTip: [
|
||||
{ required: false, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
authPriKey: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
assetData: [],
|
||||
assetLoading: false,
|
||||
assetContent: {
|
||||
assetId: ''
|
||||
},
|
||||
customShow: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectAssetAuth (val, label) {
|
||||
this.$refs.selectPage.remove()
|
||||
if (val) {
|
||||
this.selectValue = val
|
||||
if (val === 'SSH') {
|
||||
this.selectPageParams = { authProtocol: 1, pageNumber: 1 }
|
||||
} else {
|
||||
this.selectPageParams = { authProtocol: 2, pageNumber: 1 }
|
||||
}
|
||||
} else {
|
||||
label = 'SSH'
|
||||
this.selectPageParams = { authProtocol: 1, pageNumber: 1 }
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.$refs.selectPage.pageChange()
|
||||
}, 100)
|
||||
},
|
||||
assetShowChange () {
|
||||
this.assetShow = true
|
||||
this.selectValue = 'SSH'
|
||||
this.selectPageParams = { authProtocol: 1, pageNumber: 1 }
|
||||
if (this.$refs.selectPage) {
|
||||
this.$refs.selectPage.remove()
|
||||
this.$refs.selectPage.pageChange()
|
||||
}
|
||||
// this.getAssetData()
|
||||
},
|
||||
/* 活动标签切换时触发 */
|
||||
beforeLeave (currentName, oldName) {
|
||||
// 重点,如果name是add,则什么都不触发
|
||||
if (currentName === 'add') {
|
||||
this.addTab()
|
||||
return false
|
||||
} else {
|
||||
// 切换tab
|
||||
this.$nextTick(() => {
|
||||
if (this.editableTabs && this.editableTabs.length > 0) {
|
||||
this.editableTabs.forEach((tab, index) => {
|
||||
if (tab.name === currentName) {
|
||||
this.$refs['console' + index][0].focusConsole()
|
||||
this.currentUuid = tab.terminal.uuid
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
this.currentIndex = currentName
|
||||
}
|
||||
},
|
||||
handleClick () {
|
||||
|
||||
},
|
||||
windowChange () { // 窗口大小改变
|
||||
// alert('winChange');
|
||||
if (this.editableTabs && this.editableTabs.length > 0) {
|
||||
this.editableTabs.forEach((tab, index) => {
|
||||
this.$refs['console' + index][0].resize()
|
||||
})
|
||||
}
|
||||
},
|
||||
removeTab (targetName) {
|
||||
const tabs = this.editableTabs
|
||||
let activeName = this.editableTabsValue
|
||||
if (activeName === targetName) {
|
||||
tabs.forEach((tab, index) => {
|
||||
if (tab.name === targetName) {
|
||||
const nextTab = tabs[index + 1] || tabs[index - 1]
|
||||
if (nextTab) {
|
||||
activeName = nextTab.name
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
this.editableTabsValue = activeName
|
||||
this.editableTabs = tabs.filter(tab => tab.name !== targetName)
|
||||
|
||||
if (this.editableTabs.length <= 0) {
|
||||
// this.closeConsole()
|
||||
}
|
||||
},
|
||||
loginFail (params) {
|
||||
this.removeTab(params.name)
|
||||
setTimeout(() => {
|
||||
if (params.assetId) {
|
||||
this.assetShowChange()
|
||||
} else {
|
||||
this.customConnect = {
|
||||
...params,
|
||||
authType: Number(params.authType),
|
||||
authPin: atob(decodeURIComponent(params.authPin))
|
||||
}
|
||||
this.customShow = true
|
||||
}
|
||||
})
|
||||
},
|
||||
refreshTabTitle (connectResult) {
|
||||
if (this.editableTabs && this.editableTabs.length > 0) {
|
||||
this.editableTabs.forEach((tab, index) => {
|
||||
if (tab.name === this.editableTabsValue) {
|
||||
if (connectResult.title && connectResult.title != '') {
|
||||
tab.title = connectResult.title
|
||||
}
|
||||
tab.circleColor = connectResult.color
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
cancleConfirm () {
|
||||
this.closeConfirmShow = false
|
||||
},
|
||||
resultFormat (resp) {
|
||||
if (resp && resp.data) {
|
||||
const assetData = {}
|
||||
assetData.list = resp.data.list
|
||||
assetData.totalRow = resp.data.total
|
||||
return assetData
|
||||
}
|
||||
},
|
||||
getAssetData () {
|
||||
this.assetLoading = true
|
||||
this.$get('asset/asset', { pageSize: -1, typeIds: '1,2' }).then(res => {
|
||||
this.assetLoading = false
|
||||
this.assetData = res.data.list
|
||||
})
|
||||
},
|
||||
connect () {
|
||||
this.prevent_opt.save = true
|
||||
if (this.assetShow) {
|
||||
this.$refs.assetConnect.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$get('asset/asset/' + this.assetContent.assetId).then(res => {
|
||||
const asset = res.data
|
||||
this.addConsole(asset.id, asset.manageIp, '', '', 'asset')
|
||||
this.assetShow = false
|
||||
this.prevent_opt.save = false
|
||||
})
|
||||
} else {
|
||||
this.prevent_opt.save = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$refs.customConnect.validate((valid) => {
|
||||
if (valid) {
|
||||
this.addConsole('', this.customConnect.host, '', this.customConnect.port, 'custom')
|
||||
this.customShow = false
|
||||
this.prevent_opt.save = false
|
||||
} else {
|
||||
this.prevent_opt.save = false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
protocolChange () {
|
||||
if (this.customConnect.authProtocol === 1) {
|
||||
this.customConnect.authUserTip = ''
|
||||
this.customConnect.authPinTip = ''
|
||||
this.customConnect.port = 22
|
||||
} else {
|
||||
this.customConnect.authPriKey = ''
|
||||
this.customConnect.port = 23
|
||||
this.customConnect.authType = 1
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.$refs.customConnect.clearValidate()
|
||||
})
|
||||
},
|
||||
authTypeChange () {
|
||||
if (this.customConnect.authType === 1) {
|
||||
this.customConnect.authPriKey = ''
|
||||
}
|
||||
},
|
||||
encode (str) {
|
||||
// 对编码的字符串转化base64
|
||||
const base64 = encodeURIComponent(btoa(str))
|
||||
return base64
|
||||
},
|
||||
closeAssetCustom () {
|
||||
this.assetShow = false
|
||||
this.customShow = false
|
||||
this.assetContent.assetId = ''
|
||||
this.customConnect = {
|
||||
host: '',
|
||||
port: 22,
|
||||
authType: 1,
|
||||
authUsername: '',
|
||||
authPin: '',
|
||||
authPriKey: '',
|
||||
authUserTip: '',
|
||||
authPinTip: '',
|
||||
authProtocolPort: '',
|
||||
authProtocol: 1
|
||||
}
|
||||
},
|
||||
addConsole (id, host, accountId, port, type) {
|
||||
if (!id) { id = '' }
|
||||
if (!host) { host = '' }
|
||||
if (!accountId) { accountId = '' }
|
||||
if (!port) { port = '' }
|
||||
const uuid = ''
|
||||
const newTabName = ++this.tabIndex + ''
|
||||
let title = host
|
||||
if (port) {
|
||||
title = title + ':' + port
|
||||
}
|
||||
if (!title) {
|
||||
title = this.$t('webshell.shellTitle')
|
||||
}
|
||||
const width = document.body.clientWidth// 可视宽度
|
||||
const console = {
|
||||
title: title,
|
||||
name: newTabName,
|
||||
circleColor: 1, // 1 grey,2 green, 3 red
|
||||
uuid: uuid,
|
||||
showTooltip: false,
|
||||
terminal: {
|
||||
name: newTabName,
|
||||
cols: 225,
|
||||
rows: 200,
|
||||
width: width,
|
||||
height: this.consoleHeight,
|
||||
assetId: id,
|
||||
accountId: accountId,
|
||||
uuid: uuid,
|
||||
type: type,
|
||||
username: '',
|
||||
isLogin: false
|
||||
}
|
||||
}
|
||||
if (type === 'custom') {
|
||||
console.terminal.custom = {
|
||||
host: this.customConnect.host,
|
||||
port: this.customConnect.port,
|
||||
authType: this.customConnect.authType,
|
||||
terminalType: this.customConnect.authProtocol,
|
||||
authUsername: encodeURIComponent(this.customConnect.authUsername),
|
||||
authPin: this.encode(this.customConnect.authPin),
|
||||
authPriKey: encodeURIComponent(this.customConnect.authPriKey),
|
||||
authUserTip: encodeURIComponent(this.customConnect.authUserTip),
|
||||
authPinTip: encodeURIComponent(this.customConnect.authPinTip),
|
||||
authProtocolPort: encodeURIComponent(this.customConnect.authProtocolPort),
|
||||
authProtocol: encodeURIComponent(this.customConnect.authProtocol)
|
||||
}
|
||||
}
|
||||
if (id) {
|
||||
this.$get('/asset/asset/' + id).then(res => {
|
||||
console.terminal.terminalType = res.data.type.authProtocol
|
||||
console.terminal.username = ''
|
||||
this.editableTabsValue = newTabName
|
||||
this.editableTabs.push(console)
|
||||
})
|
||||
} else {
|
||||
console.terminal.username = ''
|
||||
console.terminal.terminalType = this.customConnect.authProtocol
|
||||
this.editableTabsValue = newTabName
|
||||
this.editableTabs.push(console)
|
||||
}
|
||||
},
|
||||
duplicate (item, index) {
|
||||
if (item.terminal.assetId) {
|
||||
const newTabName = ++this.tabIndex + ''
|
||||
this.editableTabsValue = newTabName
|
||||
const console = JSON.parse(JSON.stringify(item))
|
||||
console.name = newTabName
|
||||
console.terminal.name = newTabName
|
||||
console.terminal.isLogin = false
|
||||
this.editableTabs.push(console)
|
||||
} else {
|
||||
this.customConnect = {
|
||||
...item.terminal.custom,
|
||||
authType: Number(item.terminal.custom.authType),
|
||||
authPin: atob(decodeURIComponent(item.terminal.custom.authPin))
|
||||
}
|
||||
this.customShow = true
|
||||
}
|
||||
if (this.$refs['popover' + index] && this.$refs['popover' + index][0]) {
|
||||
this.$refs['popover' + index][0].doClose()
|
||||
}
|
||||
},
|
||||
debounce (operate, delay) {
|
||||
let time = null
|
||||
let timer = null
|
||||
let newTime = null
|
||||
function task () {
|
||||
newTime = +new Date()
|
||||
if (newTime - time < delay) {
|
||||
timer = setTimeout(task, delay)
|
||||
} else {
|
||||
operate()
|
||||
timer = null
|
||||
}
|
||||
time = newTime
|
||||
}
|
||||
return function () {
|
||||
// 更新时间戳
|
||||
time = +new Date()
|
||||
if (!timer) {
|
||||
timer = setTimeout(task, delay)
|
||||
}
|
||||
}
|
||||
},
|
||||
reconnect (item, index) {
|
||||
this.$refs['console' + index][0].reconnect()
|
||||
if (this.$refs['popover' + index] && this.$refs['popover' + index][0]) {
|
||||
this.$refs['popover' + index][0].doClose()
|
||||
}
|
||||
},
|
||||
showFileDir (item, index) {
|
||||
this.$refs['console' + index][0].showFileDir(true)
|
||||
if (this.$refs['popover' + index] && this.$refs['popover' + index][0]) {
|
||||
this.$refs['popover' + index][0].doClose()
|
||||
}
|
||||
},
|
||||
closeShell (item, index) {
|
||||
this.removeTab(item.name)
|
||||
if (this.$refs['popover' + index] && this.$refs['popover' + index][0]) {
|
||||
this.$refs['popover' + index][0].doClose()
|
||||
}
|
||||
},
|
||||
sendMessage (message) {
|
||||
this.editableTabs.forEach((item, index) => {
|
||||
this.$refs['console' + index][0].enterStr(message)
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
created () {
|
||||
},
|
||||
mounted () {
|
||||
window.addEventListener('resize', this.debounce(this.windowChange, 1000), false)
|
||||
},
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('resize', this.debounce(this.windowChange, 1000), false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@@ -27,8 +27,9 @@
|
||||
<endpoint-tab v-if="from === fromRoute.asset && targetTab === fromRoute.endpoint" v-show="subResizeShow" :from="from" :obj="obj" @changeTab="changeTab" :targetTab.sync="targetTab"></endpoint-tab>
|
||||
|
||||
<!--terminal-log的记录和回放-->
|
||||
<terminal-log-cmd-tab v-if="from === fromRoute.terminalLog && targetTab === 'cmdTab'" :from="from" :obj="obj" :tabs="tabs.terminalLog.cmd" @changeTab="changeTab" :targetTab.sync="targetTab"></terminal-log-cmd-tab>
|
||||
<terminal-log-record-tab v-if="from === fromRoute.terminalLog && targetTab === 'recordTab'" ref="reminalLogRecordTab" :from="from" :obj="obj" :tabs="tabs.terminalLog.record" @changeTab="changeTab" :targetTab.sync="targetTab"></terminal-log-record-tab>
|
||||
<terminal-log-cmd-tab v-if="from === fromRoute.terminalLog && targetTab === 'cmdTab'" :from="from" :obj="obj" :tabs="hasTerminalLogTabs" @changeTab="changeTab" :targetTab.sync="targetTab"></terminal-log-cmd-tab>
|
||||
<terminal-log-sftp-tab v-if="from === fromRoute.terminalLog && targetTab === 'sftpTab' && obj.protocol == 'SSH'" :from="from" :obj="obj" :tabs="hasTerminalLogTabs" @changeTab="changeTab" :targetTab.sync="targetTab"></terminal-log-sftp-tab>
|
||||
<terminal-log-record-tab v-if="from === fromRoute.terminalLog && targetTab === 'recordTab'" ref="reminalLogRecordTab" :from="from" :obj="obj" :tabs="hasTerminalLogTabs" @changeTab="changeTab" :targetTab.sync="targetTab"></terminal-log-record-tab>
|
||||
<terminal-log-monitor-tab v-if="from === fromRoute.terminalLog && targetTab === 'monitorTab'" :from="from" :obj="obj" :tabs="tabs.terminalLog.monitor" @changeTab="changeTab" @exit="closeSubList" :targetTab.sync="targetTab"></terminal-log-monitor-tab>
|
||||
|
||||
<asset-tab v-if="from === fromRoute.dc && targetTab === 'asset'" :tabs="tabs.dc.asset" ref="assetTab" :from="from" :obj="obj" @changeTab="changeTab" @exit="closeSubList" :targetTab.sync="targetTab"></asset-tab>
|
||||
@@ -56,7 +57,9 @@
|
||||
<log-bottom-tab v-if="from === fromRoute.endpoint && targetTab === 'log' && hasLogConfig" :sign="sign+'log'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="endpointTabs" :targetTab.sync="targetTab" @changeTab="changeTab"></log-bottom-tab>
|
||||
<alertMessageTabNew v-if="from === fromRoute.endpoint && targetTab === 'endpointAlertMessage'" :sign="sign+'alert'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="endpointTabs" :targetTab.sync="targetTab" @changeTab="changeTab"></alertMessageTabNew>
|
||||
<!--chartTemp的Tab-->
|
||||
<panel-tab-new @exit="closeSubList" @getTableData="getTableData" :paramsType="'template'" v-if="from === fromRoute.chartTemp && targetTab === 'panel'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.chartTemp.chartTempTabTitle" :targetTab.sync="targetTab" @changeTab="changeTab"></panel-tab-new>
|
||||
<panel-tab-new @exit="closeSubList" @getTableData="getTableData" :paramsType="'template'" v-if="from === fromRoute.chartTemp && targetTab === 'panel'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.chartTemp.chartTempTabTitle" :targetTab.sync="targetTab" @changeTab="changeTab"></panel-tab-new>
|
||||
<!--dashboardTemp的Tab-->
|
||||
<panel-tab-new @exit="closeSubList" @getTableData="getTableData" :paramsType="'template'" v-if="from === fromRoute.dashboardTemp && targetTab === 'panel'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.dashboardTemp.dashboardTempTabTitle" :targetTab.sync="targetTab" @changeTab="changeTab"></panel-tab-new>
|
||||
<!--alertRule Tab-->
|
||||
<alertMessageTabNew v-if="from === fromRoute.alertRule && targetTab === 'alertRuleAlertMessage'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.alertRule.alertRule" @changeTab="changeTab" :targetTab.sync="targetTab"></alertMessageTabNew>
|
||||
<alertRuleEvalLog v-if="from === fromRoute.alertRule && targetTab === 'evalLog'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.alertRule.alertRule" @changeTab="changeTab" :targetTab.sync="targetTab"></alertRuleEvalLog>
|
||||
@@ -67,11 +70,12 @@
|
||||
<!-- ipam -->
|
||||
<ip-details v-if="from === fromRoute.ipam && targetTab === 'ipam'" :from="from" :obj="obj" :tabs="tabs.ipam" @changeTab="changeTab" :targetTab.sync="targetTab"></ip-details>
|
||||
<!-- recordRule 下滑-->
|
||||
<record-rule-eval-log v-if="from === fromRoute.recordRule && targetTab === 'recordRule'" :from="from" :obj="obj" :tabs="tabs.recordRule" @changeTab="changeTab" :targetTab.sync="targetTab"></record-rule-eval-log>
|
||||
<record-rule-eval-log v-if="from === fromRoute.recordRule && targetTab === 'recordRule'" :from="from" :obj="obj" :tabs="tabs.recordRule.evalLog" @changeTab="changeTab" :targetTab.sync="targetTab"></record-rule-eval-log>
|
||||
<recordRulesQuery v-if="from === fromRoute.recordRule && targetTab === 'Metrics'" :from="from" :obj="obj" :tabs="tabs.recordRule.Metrics" @changeTab="changeTab" :targetTab.sync="targetTab"></recordRulesQuery>
|
||||
<!--alertRule Tab-->
|
||||
<alertMessageTabNew v-if="from === fromRoute.alertSilence && targetTab === 'alertMessageTab'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.alertSilence" @changeTab="changeTab" :targetTab.sync="targetTab"></alertMessageTabNew>
|
||||
<!--issue Tab-->
|
||||
<!-- <issueTab v-if="from === fromRoute.issue && targetTab === 'issue'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.alertSilence" @changeTab="changeTab" :targetTab.sync="targetTab"></issueTab>-->
|
||||
<!-- <issueTab v-if="from === fromRoute.issue && targetTab === 'issue'" v-show="subResizeShow" :from="from" :obj="obj" :tabs="tabs.alertSilence" @changeTab="changeTab" :targetTab.sync="targetTab"></issueTab> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,10 +91,12 @@ import assetSubTab from './tabs/assetSubTab'
|
||||
import commentsBottomTab from './tabs/commentsBottomTab'
|
||||
import vsysBottomTab from './tabs/vsysBottomTab'
|
||||
import endpointQuery from './tabs/endpointQuery'
|
||||
import recordRulesQuery from './tabs/recordRulesQuery'
|
||||
import endpointTab from './tabs/endpointTab'
|
||||
import endpointTabNew from './tabs/endpointTabNew'
|
||||
import panelTabNew from './tabs/panelTabNew'
|
||||
import terminalLogRecordTab from './tabs/terminalLogRecordTab'
|
||||
import terminalLogSftpTab from './tabs/terminalLogSftpTab'
|
||||
import terminalLogMonitorTab from './tabs/terminalLogMonitorTab'
|
||||
import terminalLogCMDTab from './tabs/terminalLogCMDTab'
|
||||
import operationLogTab from './tabs/operationLogTab'
|
||||
@@ -117,6 +123,7 @@ export default {
|
||||
alertMessageTab,
|
||||
endpointTab,
|
||||
terminalLogRecordTab,
|
||||
terminalLogSftpTab,
|
||||
terminalLogMonitorTab,
|
||||
operationLogTab,
|
||||
terminalLogTab,
|
||||
@@ -130,6 +137,7 @@ export default {
|
||||
alertRuleEvalLog,
|
||||
IpDetails,
|
||||
recordRuleEvalLog,
|
||||
recordRulesQuery,
|
||||
issueTab,
|
||||
commentsBottomTab,
|
||||
vsysBottomTab
|
||||
@@ -157,15 +165,15 @@ export default {
|
||||
terminalLog: {
|
||||
monitor: [
|
||||
{ prop: 'monitorTab', name: this.$t('config.terminallog.monitor.monitor'), active: true }
|
||||
],
|
||||
cmd: [
|
||||
{ prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: true },
|
||||
{ prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: false }
|
||||
],
|
||||
record: [
|
||||
{ prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: false },
|
||||
{ prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: true }
|
||||
]
|
||||
// // cmd: [
|
||||
// // { prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: true },
|
||||
// // { prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: false }
|
||||
// // ],
|
||||
// // record: [
|
||||
// // { prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: false },
|
||||
// // { prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: true }
|
||||
// // ]
|
||||
},
|
||||
user: {
|
||||
operationLog: [
|
||||
@@ -206,6 +214,11 @@ export default {
|
||||
{ prop: 'panel', name: this.$t('overall.tempPrev') }
|
||||
]
|
||||
},
|
||||
dashboardTemp: {
|
||||
dashboardTempTabTitle: [
|
||||
{ prop: 'panel', name: this.$t('overall.dashboardTemp') }
|
||||
]
|
||||
},
|
||||
alertRule: {
|
||||
alertRule: [
|
||||
{ prop: 'alertRuleAlertMessage', name: this.$t('overall.alert') },
|
||||
@@ -238,9 +251,16 @@ export default {
|
||||
ipam: [
|
||||
{ prop: 'ipam', name: this.$t('ipam.subnet.ipDetails'), active: true }
|
||||
],
|
||||
recordRule: [
|
||||
{ prop: 'recordRule', name: this.$t('overall.alertRuleEvalLog'), active: true }
|
||||
],
|
||||
recordRule: {
|
||||
Metrics: [
|
||||
{ prop: 'Metrics', name: this.$t('overall.metric'), active: true },
|
||||
{ prop: 'recordRule', name: this.$t('overall.alertRuleEvalLog'), active: false }
|
||||
],
|
||||
evalLog: [
|
||||
{ prop: 'Metrics', name: this.$t('overall.metric'), active: false },
|
||||
{ prop: 'recordRule', name: this.$t('overall.alertRuleEvalLog'), active: true }
|
||||
]
|
||||
},
|
||||
alertSilence: [
|
||||
{ prop: 'alertMessageTab', name: this.$t('overall.alert'), active: true }
|
||||
],
|
||||
@@ -251,6 +271,17 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasTerminalLogTabs () {
|
||||
const hasSftp = this.obj && this.obj.protocol == 'SSH'
|
||||
const tabs = [
|
||||
{ prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd') },
|
||||
{ prop: 'recordTab', name: this.$t('config.terminallog.record.record') }
|
||||
]
|
||||
if (hasSftp) {
|
||||
tabs.splice(1, 0, { prop: 'sftpTab', name: 'SFTP ' })
|
||||
}
|
||||
return tabs
|
||||
},
|
||||
hasLogConfig () {
|
||||
const config = this.obj.configs.find(c => c.type === 'logs')
|
||||
return config && config.enable === 1
|
||||
@@ -258,7 +289,7 @@ export default {
|
||||
assetTabs () {
|
||||
const hasSub = this.obj && this.obj.childrenNum
|
||||
const hasProcess = this.obj && this.obj.clientState == '1'
|
||||
const hasVays = this.obj && this.obj.model.tsgAppliance == '1'
|
||||
const hasVays = this.obj && this.obj.model && this.obj.model.tsgAppliance == '1'
|
||||
const tabs = [
|
||||
{ prop: 'panelTab', name: this.$t('overall.dashboard') },
|
||||
{ prop: 'alertMessageTab', name: this.$t('overall.alert') },
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="margin-r-20 nz-btn-group">
|
||||
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" id="endpoint-query-changetime" :title="$t('overall.decreaseTime')"><i class="el-icon-d-arrow-left"></i></button>
|
||||
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" style="height:32px" id="endpoint-query-changetime" :title="$t('overall.decreaseTime')"><i class="el-icon-d-arrow-left"></i></button>
|
||||
<my-date-picker
|
||||
v-model="formatTime"
|
||||
type="datetime"
|
||||
@@ -36,7 +36,7 @@
|
||||
:format="timeFormatStrToDatePickFormat(timeFormatMain)"
|
||||
>
|
||||
</my-date-picker>
|
||||
<button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append" :title="$t('overall.increaseTime')"><i class="el-icon-d-arrow-right"></i></button>
|
||||
<button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append" style="height:32px" :title="$t('overall.increaseTime')"><i class="el-icon-d-arrow-right"></i></button>
|
||||
</div>
|
||||
<div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light" style="height: 28px;">
|
||||
<button class="nz-btn nz-btn-size-normal nz-btn-style-light" :class="{'control-icon-unchecked':selectedEndpoints.length<1,'control-icon-checked':selectedEndpoints.length>0}" @click="viewGraph" :title="$t('overall.showLineChart')">
|
||||
@@ -81,7 +81,7 @@ import endpointQueryTab from '@/components/common/table/special/endpointQueryTab
|
||||
import bus from '@/libs/bus'
|
||||
import detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin'
|
||||
export default {
|
||||
name: 'endpointTab',
|
||||
name: 'endpointQuery',
|
||||
mixins: [subDataListMixin, detailViewRightMixin],
|
||||
props: {
|
||||
from: {}
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
>
|
||||
<template v-slot:title><span :title="obj.name">{{obj.name}}</span></template>
|
||||
<template v-slot:top-tool-right>
|
||||
<!-- asset -->
|
||||
<div v-if="from === fromRoute.asset" style="display: flex">
|
||||
<pick-time ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false" :sign="'panel' + obj.id"></pick-time>
|
||||
<button id="panel-add-chart" v-has="'main_add'" :title="$t('overall.createChart')" class="top-tool-btn margin-r-10"
|
||||
type="button" @click="addChart">
|
||||
<button id="panel-add-chart" v-has="'main_add'" :title="$t('overall.createChart')" class="top-tool-btn margin-r-10" type="button" @click="addChart">
|
||||
<i class="nz-icon-create-square nz-icon"></i>
|
||||
</button>
|
||||
<top-tool-more-options
|
||||
<top-tool-more-options
|
||||
ref="topTool"
|
||||
:delete-objs="batchDeleteObjs"
|
||||
id="asset-list"
|
||||
@@ -38,24 +38,25 @@
|
||||
@panelLockChange="panelLockChange"
|
||||
>
|
||||
<template v-slot:after>
|
||||
<el-dropdown-item v-has="'main_add'">
|
||||
<!-- <el-dropdown-item v-has="'main_add'">
|
||||
<div id="chart-temp-add" @click="addChartByTemp"><i class="nz-icon nz-icon-add"></i>{{ $t('overall.AddByTemplate') }}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has="'main_edit'">
|
||||
<div id="chart-temp-sync" @click="chartBySync"><i class="nz-icon nz-icon-sync"></i>{{ $t('overall.syncChart') }}</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-item> -->
|
||||
<el-dropdown-item v-has="'panel_view'">
|
||||
<div id="chart-export-html" @click="exportType"><i class="nz-icon nz-icon-kuaizhao"></i>{{ $t('overall.snapshoot') }}</div>
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</top-tool-more-options>
|
||||
</div>
|
||||
<!-- endpoint -->
|
||||
<div v-else-if="from === fromRoute.endpoint" style="display: flex">
|
||||
<pick-time ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false" :sign="'panel' + obj.id"></pick-time>
|
||||
<button id="endpoint-create-chart" v-has="'main_add'" :title="$t('overall.createChart')" class="top-tool-btn margin-r-10" @click.stop="addChart">
|
||||
<i class="nz-icon nz-icon-create-square"></i>
|
||||
</button>
|
||||
<top-tool-more-options
|
||||
<top-tool-more-options
|
||||
ref="topTool"
|
||||
:delete-objs="batchDeleteObjs"
|
||||
id="asset-list"
|
||||
@@ -74,24 +75,36 @@
|
||||
@panelLockChange="panelLockChange"
|
||||
>
|
||||
<template v-slot:after>
|
||||
<el-dropdown-item v-has="'main_add'">
|
||||
<!-- <el-dropdown-item v-has="'main_add'">
|
||||
<div id="chart-temp-add" @click="addChartByTemp"><i class="nz-icon nz-icon-add"></i>{{ $t('overall.AddByTemplate') }}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-has="'main_edit'">
|
||||
<div id="chart-temp-sync" @click="chartBySync"><i class="nz-icon nz-icon-sync"></i>{{ $t('overall.syncChart') }}</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-item> -->
|
||||
<el-dropdown-item v-has="'panel_view'">
|
||||
<div id="chart-export-html" @click="exportType"><i class="nz-icon nz-icon-kuaizhao"></i>{{ $t('overall.snapshoot') }}</div>
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</top-tool-more-options>
|
||||
</div>
|
||||
<div v-else-if="from === fromRoute.chartTemp">
|
||||
<!-- chartTemp -->
|
||||
<div v-else-if="from === fromRoute.chartTemp">
|
||||
<button id="panel-lock" :title='panelLock ? $t("overall.unlocked") : $t("overall.locked")' class="top-tool-btn margin-r-10" @click="panelLockChange(!panelLock)" type="button">
|
||||
<i :class="{'nz-icon nz-icon-lock':!panelLock,'nz-icon nz-icon-unlock':panelLock}"></i>
|
||||
</button>
|
||||
<button @click="chartBySync" id="chart-sync" :title="$t('overall.syncChart')" class="top-tool-btn margin-r-10"
|
||||
type="button">
|
||||
<i :class="{'nz-icon nz-icon-lock':!panelLock,'nz-icon nz-icon-unlock':panelLock}"></i>
|
||||
</button>
|
||||
<button @click="chartBySync" id="chart-sync" :title="$t('overall.syncChart')" class="top-tool-btn margin-r-10" type="button">
|
||||
<i class="nz-icon nz-icon-sync"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- dashboardTemp -->
|
||||
<div v-else-if="from === fromRoute.dashboardTemp">
|
||||
<button id="endpoint-create-chart" v-has="'main_add'" :title="$t('overall.createChart')" class="top-tool-btn margin-r-10" @click.stop="addChart">
|
||||
<i class="nz-icon nz-icon-create-square"></i>
|
||||
</button>
|
||||
<button id="panel-lock" :title='panelLock ? $t("overall.unlocked") : $t("overall.locked")' class="top-tool-btn margin-r-10" @click="panelLockChange(!panelLock)" type="button">
|
||||
<i :class="{'nz-icon nz-icon-lock':!panelLock,'nz-icon nz-icon-unlock':panelLock}"></i>
|
||||
</button>
|
||||
<button @click="chartBySync" id="chart-sync" :title="$t('overall.syncChart')" class="top-tool-btn margin-r-10" type="button">
|
||||
<i class="nz-icon nz-icon-sync"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -123,8 +136,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</nz-bottom-data-list>
|
||||
|
||||
<transition name="right-box">
|
||||
<!-- <chart-box v-if="rightBox.chart.show" ref="addChartModal" :chart="chart" :from="from" :panel-data="panelData" :show-panel="showPanel" @close="closeRightBox" @delete-chart="delChart" @on-create-success="createSuccess" @on-delete-success="delChartOk"></chart-box>-->
|
||||
<!-- <chart-box v-if="rightBox.chart.show" ref="addChartModal" :chart="chart" :from="from" :panel-data="panelData" :show-panel="showPanel" @close="closeRightBox" @delete-chart="delChart" @on-create-success="createSuccess" @on-delete-success="delChartOk"></chart-box> -->
|
||||
<chart-right-box
|
||||
v-if="chartRightBoxShow"
|
||||
v-my-loading="rightBox.loading"
|
||||
@@ -149,6 +163,8 @@
|
||||
|
||||
<script>
|
||||
// import chartBox from '../../../page/dashboard/chartBox'
|
||||
import * as echarts from 'echarts'
|
||||
import { chartCache } from '@/components/common/js/common'
|
||||
import chartRightBox from '@/components/common/rightBox/chart/chartRightBox'
|
||||
import chartList from '@/components/chart/chartList'
|
||||
import bus from '../../../../libs/bus'
|
||||
@@ -574,12 +590,31 @@ export default {
|
||||
this.showPanel.id = this.filter.panelId = 0
|
||||
this.getData(this.filter)
|
||||
}
|
||||
} else if (this.from === this.fromRoute.dashboardTemp) {
|
||||
this.$get('visual/panel', { type: 'template', ids: this.obj.id }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.panelData = response.data.list
|
||||
if (this.panelData.length > 0) {
|
||||
this.filter.panelId = this.panelData[0].id
|
||||
this.showPanel = this.$loadsh.cloneDeep(this.panelData[0])
|
||||
this.variables = this.$loadsh.get(this.panelData, '[0].param.variables')
|
||||
this.getData(this.filter)
|
||||
}
|
||||
}
|
||||
}).catch((error) => {
|
||||
if (error) {
|
||||
console.error(error)
|
||||
this.$message.error(error.toString())
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$get('visual/panel', { type: this.from, link: linkId || this.obj.id }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.panelData = response.data.list
|
||||
if (this.panelData.length > 0) {
|
||||
this.showPanel.id = this.filter.panelId = this.panelData[0].id
|
||||
// this.showPanel.id = this.filter.panelId = this.panelData[0].id
|
||||
this.filter.panelId = this.panelData[0].id
|
||||
this.showPanel = this.$loadsh.cloneDeep(this.panelData[0])
|
||||
this.variables = this.$loadsh.get(this.panelData, '[0].param.variables')
|
||||
this.getData(this.filter)
|
||||
}
|
||||
@@ -855,6 +890,31 @@ export default {
|
||||
this.disposeChart()
|
||||
}
|
||||
}
|
||||
},
|
||||
// 监听图表联动配置panelId
|
||||
'showPanel.param.chartShare': {
|
||||
handler (value) {
|
||||
// 每次切换联动模式 tooltip设置显示
|
||||
const option = {
|
||||
tooltip: {
|
||||
className: 'chart-time-series'
|
||||
}
|
||||
}
|
||||
for (const key in chartCache) {
|
||||
if (!chartCache[key] || chartCache[key].group !== 'timeSeriesGroup') {
|
||||
continue
|
||||
}
|
||||
chartCache[key].setOption(option)
|
||||
}
|
||||
this.$store.commit('setCurrentMousemove', 0)
|
||||
if (value && value !== 'none') {
|
||||
this.$store.commit('setConnect', value)
|
||||
echarts.connect('timeSeriesGroup')
|
||||
} else {
|
||||
this.$store.commit('setConnect', value)
|
||||
echarts.disconnect('timeSeriesGroup')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
@@ -862,6 +922,11 @@ export default {
|
||||
document.querySelector('#tableList') && document.querySelector('#tableList').removeEventListener('mouseleave', this.tableListLeave)
|
||||
this.scrollbarWrap && this.scrollbarWrap.removeEventListener('scroll', bus.debounce)
|
||||
this.$store.dispatch('dispatchPanelLock', { flag: true })
|
||||
|
||||
// 页面销毁 清除图表联动
|
||||
this.$store.commit('setCurrentMousemove', 0)
|
||||
this.$store.commit('setConnect', 'none')
|
||||
echarts.disconnect('timeSeriesGroup')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
:showTitle='showTitle'
|
||||
:obj='obj'
|
||||
:tableId="tableId"
|
||||
:api="url"
|
||||
:custom-table-title.sync="tools.customTableTitle"
|
||||
:layout="['elementSet']"
|
||||
:search-msg="searchMsg"
|
||||
:tabs="tabs"
|
||||
:targetTab="targetTab"
|
||||
:showPagination="false"
|
||||
@search="search"
|
||||
@changeTab="changeTab"
|
||||
>
|
||||
id="recordRuleEvalLog"
|
||||
:api="url"
|
||||
:custom-table-title.sync="tools.customTableTitle"
|
||||
:layout="['elementSet']"
|
||||
:search-msg="searchMsg"
|
||||
:tabs="tabs"
|
||||
:targetTab="targetTab"
|
||||
:showPagination="false"
|
||||
@search="search"
|
||||
@changeTab="changeTab">
|
||||
<template v-slot:title><span :title="obj.name">{{obj.name}}</span></template>
|
||||
<template v-slot>
|
||||
<recordRuleEvalLogTable
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="full-width-height recordRules-query">
|
||||
<nz-bottom-data-list
|
||||
:showTitle='showTitle'
|
||||
:obj='obj'
|
||||
:layout="[]"
|
||||
:tabs="tabs"
|
||||
:targetTab="targetTab"
|
||||
:showPagination="false"
|
||||
@changeTab="changeTab"
|
||||
:customTool="true"
|
||||
class="full-width-height"
|
||||
>
|
||||
<template v-slot:title><span :title="obj.name">{{obj.name}}</span></template>
|
||||
<template v-slot:top-tool-right>
|
||||
<div class="top-tool-right">
|
||||
<div class="top-tool-search margin-r-20">
|
||||
<el-input ref="elementQuery" @clear="clearInput" id="elementQuery" @focus="focusInput" @blur="blurInput" v-model="queryExpression" class="query-input-inactive" size="mini" clearable :placeholder="$t('project.endpoint.promExpr')" >
|
||||
<i slot="suffix" class="el-input__icon nz-icon nz-icon-search" style="float:right" @click="focusInput"></i>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="margin-r-20 nz-btn-group">
|
||||
<button @click="changeTime(-10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-prepend" style="height:32px" id="recordRules-query-changetime" :title="$t('overall.decreaseTime')"><i class="el-icon-d-arrow-left"></i></button>
|
||||
<my-date-picker
|
||||
v-model="formatTime"
|
||||
type="datetime"
|
||||
size="mini"
|
||||
class="project-calendar nz-input-group-middle"
|
||||
clearable
|
||||
:time-arrow-control="true"
|
||||
placeholder="Moment"
|
||||
:value-format="timeFormatStrToDatePickFormat(timeFormatMain)"
|
||||
:format="timeFormatStrToDatePickFormat(timeFormatMain)"
|
||||
>
|
||||
</my-date-picker>
|
||||
<button @click="changeTime(10)" class="nz-btn nz-btn-size-normal nz-btn-style-light change-time-height nz-input-group-append" style="height:32px" :title="$t('overall.increaseTime')"><i class="el-icon-d-arrow-right"></i></button>
|
||||
</div>
|
||||
<div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light" style="height: 28px;">
|
||||
<button class="nz-btn nz-btn-size-normal nz-btn-style-light" :class="{'control-icon-unchecked':selectedrecordRules.length<1,'control-icon-checked':selectedrecordRules.length>0}" @click="viewGraph" :title="$t('overall.showLineChart')">
|
||||
<i class="nz-icon nz-icon-chart" :class="{'control-icon-unchecked':selectedrecordRules.length<1,'control-icon-checked':selectedrecordRules.length>0}"></i>
|
||||
</button>
|
||||
<button @click="dropdownHandler(dropdownShow)" class="nz-btn nz-btn-size-normal nz-btn-style-light export-dropdown-btn" id="browser-go">
|
||||
<i class="nz-icon nz-icon-arrow-down"></i>
|
||||
<transition name="el-zoom-in-top">
|
||||
<div v-if="dropdownShow" class="recordRules-query-dropdown el-popover" style="right: 11px;top: 33px;">
|
||||
<span style="padding-top: 2px">{{$t('project.endpoint.hideSameLabels')}}</span>
|
||||
<el-switch v-model="hideSameLabels" size="small"></el-switch>
|
||||
</div>
|
||||
</transition>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot>
|
||||
<recordRulesQueryTab
|
||||
ref="recordRulesQueryTab"
|
||||
:orderByFa="'id'"
|
||||
:from="from"
|
||||
:obj="obj"
|
||||
:formatTime="formatTime"
|
||||
:hideSameLabels="hideSameLabels"
|
||||
:queryExpression="queryExpression"
|
||||
@changSelection="changSelectionF"
|
||||
@selectedrecordRulesChange="selectedrecordRulesChange"
|
||||
/>
|
||||
</template>
|
||||
</nz-bottom-data-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||
import recordRulesQueryTab from '@/components/common/table/special/recordRulesQueryTab'
|
||||
import bus from '@/libs/bus'
|
||||
import detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin'
|
||||
export default {
|
||||
name: 'recordRulesQuery',
|
||||
mixins: [subDataListMixin, detailViewRightMixin],
|
||||
props: {
|
||||
from: {}
|
||||
},
|
||||
components: {
|
||||
nzBottomDataList,
|
||||
recordRulesQueryTab
|
||||
},
|
||||
watch: {
|
||||
obj: {
|
||||
immediate: true,
|
||||
handler (n) {
|
||||
this.searchLabel = {}
|
||||
this.formatTime = bus.timeFormate(new Date(bus.computeTimezoneTime(new Date())))
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
nowTime: '',
|
||||
rightBox: {
|
||||
editShow: false,
|
||||
show: false
|
||||
},
|
||||
fromBottom: true,
|
||||
selectedrecordRules: [],
|
||||
queryExpression: '',
|
||||
dropdownShow: false,
|
||||
timeout: null,
|
||||
formatTime: '',
|
||||
hideSameLabels: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
focusInput () {
|
||||
let classVal = document.getElementById('elementQuery').parentElement.getAttribute('class')
|
||||
classVal = classVal.replace('query-input-inactive', 'query-input-active')
|
||||
document.getElementById('elementQuery').parentElement.setAttribute('class', classVal)
|
||||
this.$refs.elementQuery.focus()
|
||||
},
|
||||
blurInput () {
|
||||
if (!this.queryExpression || this.queryExpression == '') {
|
||||
setTimeout(function () {
|
||||
let classVal = document.getElementById('elementQuery').parentElement.getAttribute('class')
|
||||
classVal = classVal.replace('query-input-active', 'query-input-inactive')
|
||||
document.getElementById('elementQuery').parentElement.setAttribute('class', classVal)
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
clearInput () {
|
||||
this.$refs.elementQuery.focus()
|
||||
},
|
||||
changeTime (size, unit) {
|
||||
this.formatTime = this.getTime(size, unit)
|
||||
},
|
||||
getTime (size, unit) { // 计算时间
|
||||
const now = !this.formatTime ? new Date(bus.computeTimezone(new Date().getTime())) : new Date(bus.formateTimeToTime(this.formatTime))
|
||||
if (unit) {
|
||||
switch (unit) {
|
||||
case 'y':
|
||||
now.setFullYear(now.getFullYear() + size)
|
||||
break
|
||||
case 'M':
|
||||
now.setMonth(now.getMonth() + size)
|
||||
break
|
||||
case 'd':
|
||||
now.setDate(now.getDate() + size)
|
||||
break
|
||||
case 'h':
|
||||
now.setHours(now.getHours() + size)
|
||||
break
|
||||
case 'm':
|
||||
now.setMinutes(now.getMinutes() + size)
|
||||
break
|
||||
case 's':
|
||||
now.setSeconds(now.getSeconds() + size)
|
||||
break
|
||||
default:
|
||||
console.error('unit error')
|
||||
}
|
||||
} else {
|
||||
now.setSeconds(now.getSeconds() + size)
|
||||
}
|
||||
const year = now.getFullYear()
|
||||
let month = now.getMonth() + 1
|
||||
month = month < 10 ? '0' + month : month
|
||||
let day = now.getDate()
|
||||
day = day < 10 ? '0' + day : day
|
||||
let hour = now.getHours()
|
||||
hour = hour < 10 ? '0' + hour : hour
|
||||
let minute = now.getMinutes()
|
||||
minute = minute < 10 ? '0' + minute : minute
|
||||
let second = now.getSeconds()
|
||||
second = second < 10 ? '0' + second : second
|
||||
const str = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
|
||||
return bus.timeFormate(new Date(str))
|
||||
},
|
||||
viewGraph () {
|
||||
this.$refs.recordRulesQueryTab.viewGraph()
|
||||
},
|
||||
dropdownHandler (show) {
|
||||
if (!show) {
|
||||
this.dropdownShow = true
|
||||
} else {
|
||||
this.dropdownShow = false
|
||||
}
|
||||
},
|
||||
changSelectionF (arr) {
|
||||
this.changSelection = arr
|
||||
},
|
||||
selectedrecordRulesChange (n) {
|
||||
this.selectedrecordRules = n
|
||||
},
|
||||
toTop (wrap) {
|
||||
let currentTop = wrap.scrollTop
|
||||
const interval = currentTop / 10
|
||||
const intervalFunc = setInterval(function () { // 花200ms分10次回到顶部,模拟动画效果
|
||||
if (currentTop === 0) {
|
||||
clearInterval(intervalFunc)
|
||||
} else {
|
||||
currentTop = (currentTop - interval) < interval * 0.5 ? 0 : currentTop - interval
|
||||
wrap.scrollTop = currentTop
|
||||
}
|
||||
}, 20)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<nz-bottom-data-list
|
||||
:showPagination="false"
|
||||
:showTitle='showTitle'
|
||||
:obj='obj'
|
||||
:layout="[]"
|
||||
@@ -35,14 +36,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataListMixin from '@/components/common/mixin/dataList'
|
||||
// import dataListMixin from '@/components/common/mixin/dataList'
|
||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||
import detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin'
|
||||
|
||||
export default {
|
||||
name: 'terminalLogRecordTab',
|
||||
mixins: [dataListMixin, subDataListMixin, detailViewRightMixin],
|
||||
mixins: [subDataListMixin, detailViewRightMixin],
|
||||
components: {
|
||||
nzBottomDataList
|
||||
},
|
||||
@@ -50,7 +51,7 @@ export default {
|
||||
calcTime () {
|
||||
return function (time) {
|
||||
if (this.obj.startTime) {
|
||||
const startTime = new Date(this.utcTimeToTimezoneStr(this.obj.startTime)).getTime()
|
||||
const startTime = this.momentStrToTimestamp(this.utcTimeToTimezoneStr(this.obj.startTime))
|
||||
if (startTime) {
|
||||
const thisTime = startTime + time
|
||||
return this.momentTz(thisTime)
|
||||
@@ -92,7 +93,8 @@ export default {
|
||||
records: [ // 加载更多时有多个record,否则只有一个
|
||||
|
||||
],
|
||||
tableId: 'terminaLogCMDTab'
|
||||
tableId: 'terminaLogCMDTab',
|
||||
detailType: 'list'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
:targetTab="targetTab"
|
||||
@changeTab="changeTab"
|
||||
:title="'Session ID'"
|
||||
id="terminalLogRecordTab"
|
||||
>
|
||||
<template v-slot:title><span :title="obj.uuid.substring(0, 8).toUpperCase()">{{obj.uuid.substring(0, 8).toUpperCase()}}</span></template>
|
||||
<template v-slot>
|
||||
@@ -36,14 +37,14 @@
|
||||
<script>
|
||||
import Terminal from '../../js/Xterm'
|
||||
import bus from '../../../../libs/bus'
|
||||
import dataListMixin from '@/components/common/mixin/dataList'
|
||||
// import dataListMixin from '@/components/common/mixin/dataList'
|
||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||
import detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin'
|
||||
|
||||
export default {
|
||||
name: 'terminalLogReplayTab',
|
||||
mixins: [dataListMixin, subDataListMixin, detailViewRightMixin],
|
||||
mixins: [subDataListMixin, detailViewRightMixin],
|
||||
components: {
|
||||
nzBottomDataList
|
||||
},
|
||||
@@ -77,7 +78,8 @@ export default {
|
||||
speedOffset: 0, // 快进倍数index
|
||||
progress: 0, // 进度条进度
|
||||
needSkip: true, // 是否跳过无操作时间,为true时表示需要,即不跳过无操作时间
|
||||
timeUsed: 0
|
||||
timeUsed: 0,
|
||||
detailType: 'list'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<nz-bottom-data-list
|
||||
:showTitle='showTitle'
|
||||
:obj='obj'
|
||||
:tableId="tableId"
|
||||
id="sftpBottomTab"
|
||||
:api="url"
|
||||
:custom-table-title.sync="tools.customTableTitle"
|
||||
:layout="['elementSet']"
|
||||
:tabs="tabs"
|
||||
:targetTab="targetTab"
|
||||
:showPagination="false"
|
||||
@changeTab="changeTab"
|
||||
:title="'Session ID'"
|
||||
>
|
||||
<template v-slot:title><span :title="obj.uuid.substring(0, 8).toUpperCase()">{{obj.uuid.substring(0, 8).toUpperCase()}}</span></template>
|
||||
<template v-slot>
|
||||
<terminalLogSftpTable
|
||||
ref="dataTable"
|
||||
:orderByFa="'id'"
|
||||
v-my-loading="tools.loading"
|
||||
:loading="tools.loading"
|
||||
:api="url"
|
||||
:custom-table-title="tools.customTableTitle"
|
||||
:height="subTableHeight"
|
||||
:table-data="tableData"
|
||||
:terminaLogTab="true"
|
||||
@del="del"
|
||||
@edit="edit"
|
||||
@tableDataSort="tableDataSort"
|
||||
@reload="getTableData"
|
||||
@selectionChange="selectionChange"></terminalLogSftpTable>
|
||||
</template>
|
||||
</nz-bottom-data-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dataListMixin from '@/components/common/mixin/dataList'
|
||||
import subDataListMixin from '@/components/common/mixin/subDataList'
|
||||
import nzBottomDataList from '@/components/common/bottomBox/nzBottomDataList'
|
||||
import terminalLogSftpTable from '@/components/common/table/settings/terminalLogSftpTable'
|
||||
import detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin'
|
||||
|
||||
export default {
|
||||
name: 'sftpBottomTab',
|
||||
mixins: [dataListMixin, subDataListMixin, detailViewRightMixin],
|
||||
components: {
|
||||
nzBottomDataList,
|
||||
terminalLogSftpTable
|
||||
},
|
||||
props: {
|
||||
obj: Object,
|
||||
showTitle: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
url: '/terminal/sftp/log/',
|
||||
tableId: 'sftpTable', // 需要分页的table的id,用于记录每页数量
|
||||
detailType: 'list',
|
||||
searchMsg: { // 给搜索框子组件传递的信息
|
||||
zheze_none: true,
|
||||
searchLabelList: []
|
||||
},
|
||||
searchLabel: {},
|
||||
tableData: [],
|
||||
orderBy: { order: 'ascending', prop: 'id' }
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
obj: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (n) {
|
||||
this.getTableData()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getTableData () {
|
||||
this.$set(this.searchLabel, 'uuid', this.obj.uuid)
|
||||
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
|
||||
this.$set(this.searchLabel, 'pageSize', -1)
|
||||
this.tools.loading = true
|
||||
this.$get(this.url, this.searchLabel).then(response => {
|
||||
this.tools.loading = false
|
||||
if (response.code === 200) {
|
||||
// this.tableData = response.data.list
|
||||
this.tableData = this.filterShowData(response.data.list, this.orderBy)
|
||||
if (!this.scrollbarWrap && this.$refs.dataTable && this.$refs.dataTable.$refs.dataTable) {
|
||||
this.$nextTick(() => {
|
||||
this.scrollbarWrap = this.$refs.dataTable.$refs.dataTable.bodyWrapper
|
||||
this.toTopBtnHandler(this.scrollbarWrap)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 数据排序
|
||||
tableDataSort (item) {
|
||||
this.orderBy = item
|
||||
this.filterShowData(this.tableData, item)
|
||||
},
|
||||
filterShowData (source, ord) {
|
||||
let orderBy = null
|
||||
orderBy = ord
|
||||
if (orderBy.order === 'ascending') {
|
||||
source = source.sort(this.$tableSet.asce(orderBy.prop))
|
||||
}
|
||||
if (orderBy.order === 'descending') {
|
||||
source = source.sort(this.$tableSet.desc(orderBy.prop))
|
||||
}
|
||||
return source
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -6,7 +6,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<button v-if="this.type === 'btn'" class="table-operation-item delete-button" :id="id" @click="batchDelete" :title="$t('overall.delete')"><i class="nz-icon nz-icon-delete"></i></button>
|
||||
<div v-if="this.type === 'link'" :id="id" @click="batchDelete" :title="$t('overall.delete')">
|
||||
<div v-if="this.type === 'link'" :id="id" @click="batchDelete">
|
||||
<span><i class="nz-icon nz-icon-delete" ></i>{{title}}</span>
|
||||
</div>
|
||||
<el-dialog
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<li
|
||||
v-for="(item,index) in tableData"
|
||||
:key="index"
|
||||
class="detail-row"
|
||||
class="detail-row"
|
||||
:id="'globalSearch' + item.id"
|
||||
:class="item.id === detailViewRightObj.id ? 'selected' : ''"
|
||||
@click="detailViewRightShow(item)"
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
<endpoint-tab :showTitle="false" v-if="from === fromRoute.asset && targetTab === fromRoute.endpoint" v-show="subResizeShow" :from="from" :obj="obj" @changeTab="changeTab" :targetTab="targetTab"></endpoint-tab>
|
||||
|
||||
<!--terminal-log的记录和回放-->
|
||||
<terminal-log-cmd-tab :showTitle="false" v-if="from === fromRoute.terminalLog && targetTab === 'cmdTab'" :from="from" :obj="obj" :tabs="tabs.terminalLog.cmd" @changeTab="changeTab" :targetTab="targetTab"></terminal-log-cmd-tab>
|
||||
<terminal-log-record-tab :showTitle="false" v-if="from === fromRoute.terminalLog && targetTab === 'recordTab'" :from="from" :obj="obj" :tabs="tabs.terminalLog.record" @changeTab="changeTab" :targetTab="targetTab"></terminal-log-record-tab>
|
||||
<terminal-log-cmd-tab :showTitle="false" v-if="from === fromRoute.terminalLog && targetTab === 'cmdTab'" :from="from" :obj="obj" :tabs="hasTerminalLogTabs" @changeTab="changeTab" :targetTab="targetTab"></terminal-log-cmd-tab>
|
||||
<terminal-log-sftp-tab :showTitle="false" v-if="from === fromRoute.terminalLog && targetTab === 'sftpTab' && obj.protocol == 'SSH'" :from="from" :obj="obj" :tabs="hasTerminalLogTabs" @changeTab="changeTab" :targetTab.sync="targetTab"></terminal-log-sftp-tab>
|
||||
<terminal-log-record-tab :showTitle="false" v-if="from === fromRoute.terminalLog && targetTab === 'recordTab'" :from="from" :obj="obj" :tabs="hasTerminalLogTabs" @changeTab="changeTab" :targetTab="targetTab"></terminal-log-record-tab>
|
||||
<terminal-log-monitor-tab :showTitle="false" v-if="from === fromRoute.terminalLog && targetTab === 'monitorTab'" :from="from" :obj="obj" :tabs="tabs.terminalLog.monitor" @changeTab="changeTab" @exit="closeSubList" :targetTab="targetTab"></terminal-log-monitor-tab>
|
||||
|
||||
<asset-tab :showTitle="false" v-if="from === fromRoute.dc && targetTab === 'asset'" :tabs="tabs.dc.asset" ref="assetTab" :from="from" :obj="obj" @changeTab="changeTab" @exit="closeSubList" :targetTab="targetTab"></asset-tab>
|
||||
@@ -62,6 +63,7 @@ import endpointTab from '@/components/common/bottomBox/tabs/endpointTab'
|
||||
import endpointTabNew from '@/components/common/bottomBox/tabs/endpointTabNew'
|
||||
import panelTabNew from '@/components/common/bottomBox/tabs/panelTabNew'
|
||||
import terminalLogRecordTab from '@/components/common/bottomBox/tabs/terminalLogRecordTab'
|
||||
import terminalLogSftpTab from '@/components/common/bottomBox/tabs/terminalLogSftpTab'
|
||||
import terminalLogMonitorTab from '@/components/common/bottomBox/tabs/terminalLogMonitorTab'
|
||||
import terminalLogCMDTab from '@/components/common/bottomBox/tabs/terminalLogCMDTab'
|
||||
import operationLogTab from '@/components/common/bottomBox/tabs/operationLogTab'
|
||||
@@ -83,6 +85,7 @@ export default {
|
||||
alertMessageTab,
|
||||
endpointTab,
|
||||
terminalLogRecordTab,
|
||||
terminalLogSftpTab,
|
||||
terminalLogMonitorTab,
|
||||
operationLogTab,
|
||||
terminalLogTab,
|
||||
@@ -133,15 +136,15 @@ export default {
|
||||
terminalLog: {
|
||||
monitor: [
|
||||
{ prop: 'monitorTab', name: this.$t('config.terminallog.monitor.monitor'), active: true }
|
||||
],
|
||||
cmd: [
|
||||
{ prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: true },
|
||||
{ prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: false }
|
||||
],
|
||||
record: [
|
||||
{ prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: false },
|
||||
{ prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: true }
|
||||
]
|
||||
// cmd: [
|
||||
// { prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: true },
|
||||
// { prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: false }
|
||||
// ],
|
||||
// record: [
|
||||
// { prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd'), active: false },
|
||||
// { prop: 'recordTab', name: this.$t('config.terminallog.record.record'), active: true }
|
||||
// ]
|
||||
},
|
||||
user: {
|
||||
operationLog: [
|
||||
@@ -213,6 +216,17 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasTerminalLogTabs () {
|
||||
const hasSftp = this.obj && this.obj.protocol == 'SSH'
|
||||
const tabs = [
|
||||
{ prop: 'cmdTab', name: this.$t('config.terminallog.cmd.cmd') },
|
||||
{ prop: 'recordTab', name: this.$t('config.terminallog.record.record') }
|
||||
]
|
||||
if (hasSftp) {
|
||||
tabs.splice(1, 0, { prop: 'sftpTab', name: 'SFTP ' })
|
||||
}
|
||||
return tabs
|
||||
},
|
||||
hasLogConfig () {
|
||||
const config = this.obj.configs.find(c => c.type === 'logs')
|
||||
return config && config.enable === 1
|
||||
|
||||
@@ -418,10 +418,10 @@ export const fromRoute = {
|
||||
assetType: 'assetType',
|
||||
assetState: 'assetState',
|
||||
assetLabel: 'assetLabel',
|
||||
expressionTemplate: 'expressionTemplate',
|
||||
user: 'user',
|
||||
agent: 'agent',
|
||||
recordRule: 'recordRule',
|
||||
recordRulesQuery: 'recordRulesQuery',
|
||||
issue: 'issue',
|
||||
dc: 'dc',
|
||||
role: 'role',
|
||||
@@ -437,6 +437,8 @@ export const fromRoute = {
|
||||
ipam: 'ipam',
|
||||
apiKey: 'apiKey',
|
||||
chartTemp: 'chartTemp',
|
||||
dashboardTemp: 'dashboardTemp',
|
||||
expressionTemplate: 'expressionTemplate',
|
||||
backups: 'backups',
|
||||
ping: 'ping',
|
||||
trace: 'trace'
|
||||
|
||||
@@ -335,6 +335,22 @@ export default {
|
||||
}
|
||||
this.silenceBoxShow = true
|
||||
},
|
||||
metricTarget (row, type) {
|
||||
const protocol = row.configs[0].config.protocol
|
||||
const host = row.configs[0].config.host
|
||||
const port = row.configs[0].config.port
|
||||
const metricsPath = row.configs[0].config.metrics_path
|
||||
const params = row.configs[0].config.params
|
||||
let str = ''
|
||||
if (!lodash.isEmpty(params)) {
|
||||
for (const key in params) {
|
||||
str += key + '=' + params[key] + '&'
|
||||
}
|
||||
}
|
||||
const linkTarget = `${protocol}://${host}:${port + metricsPath}${str ? '?' + str.slice(0, str.length - 1) : ''}`
|
||||
// window.open(linkTarget, 'target')
|
||||
window.open(linkTarget)
|
||||
},
|
||||
topology (row, type) {
|
||||
const chartInfo = lodash.cloneDeep(defaultData)
|
||||
chartInfo.id = row.id
|
||||
@@ -1326,10 +1342,12 @@ export default {
|
||||
}
|
||||
let localStorageTableTitle = localStorage.getItem('nz-tableTitle-' + localStorage.getItem('nz-username') + '-' + this.tableId)
|
||||
localStorageTableTitle = localStorageTableTitle ? JSON.parse(localStorageTableTitle) : tableTitle
|
||||
this.tools.customTableTitle = tableTitle.map((item, index) => { // 修复切换中英文的问题
|
||||
item.show = localStorageTableTitle[index].show
|
||||
return item
|
||||
})
|
||||
if (tableTitle) {
|
||||
this.tools.customTableTitle = tableTitle.map((item, index) => { // 修复切换中英文的问题
|
||||
item.show = localStorageTableTitle[index].show
|
||||
return item
|
||||
})
|
||||
}
|
||||
if (localStorageTableTitle && (localStorageTableTitle.length > tableTitle.length)) {
|
||||
const arr = localStorageTableTitle.splice(tableTitle.length, localStorageTableTitle.length)
|
||||
arr.forEach(item => {
|
||||
|
||||
@@ -33,7 +33,10 @@ export default {
|
||||
changeDetailType (flag) {
|
||||
setTimeout(() => {
|
||||
const query = { ...this.$route.query, detailType: flag }
|
||||
query.bottomBox = this.detailType !== 'view'
|
||||
if (this.detailType == 'view') {
|
||||
delete query.bottomBox
|
||||
delete query.selectObj
|
||||
}
|
||||
this.$router.replace({ query: query }).catch(err => {})
|
||||
}, 100)
|
||||
if (this.detailType === flag) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import i18n from '@/components/common/i18n'
|
||||
import { getUUID } from '../js/common'
|
||||
export default {
|
||||
data () {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import bus from '@/libs/bus'
|
||||
import { Loading } from 'element-ui'
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
|
||||
@@ -95,6 +95,22 @@ export default {
|
||||
this.$copyText(txt).then(() => {
|
||||
this.$message.success({ message: this.$t('overall.copySuccess') })
|
||||
})
|
||||
},
|
||||
animateCSS (node, animation, prefix = 'animate__') {
|
||||
// We create a Promise and return it
|
||||
return new Promise((resolve, reject) => {
|
||||
const animationName = `${prefix}${animation}`
|
||||
node.classList.add(`${prefix}animated`, animationName)
|
||||
|
||||
// When the animation ends, we clean the classes and resolve the Promise
|
||||
function handleAnimationEnd (event) {
|
||||
event.stopPropagation()
|
||||
node.classList.remove(`${prefix}animated`, animationName)
|
||||
resolve('Animation ended')
|
||||
}
|
||||
|
||||
node.addEventListener('animationend', handleAnimationEnd, { once: true })
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,66 +61,122 @@ export default {
|
||||
params.bottomBox = false
|
||||
params.targetTab = this.$route.query.targetTab
|
||||
}
|
||||
if (!params.targetTab) delete params.targetTab
|
||||
if (!params.bottomBox) delete params.bottomBox
|
||||
if (this.detailType === 'list' && this.$refs[detailType]) {
|
||||
params.selectObj = JSON.stringify({
|
||||
const obj = {
|
||||
id: this.$refs[detailType].bottomBox.object.id,
|
||||
name: this.$refs[detailType].bottomBox.object.name,
|
||||
configs: this.$refs[detailType].bottomBox.object.configs ? this.$refs[detailType].bottomBox.object.configs.map(item => { return { type: item.type, enable: item.enable } }) : '',
|
||||
childrenNum: this.$refs[detailType].bottomBox.object.childrenNum || '',
|
||||
clientState: this.$refs[detailType].bottomBox.object.clientState || '',
|
||||
protocol: this.$refs[detailType].bottomBox.object.protocol || '',
|
||||
uuid: this.$refs[detailType].bottomBox.object.uuid || '',
|
||||
startTime: this.$refs[detailType].bottomBox.object.startTime || '',
|
||||
model: {
|
||||
tsgAppliance: this.$refs[detailType].bottomBox.object.model ? this.$refs[detailType].bottomBox.object.model.tsgAppliance : ''
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.$refs[detailType].bottomBox.object.configs) {
|
||||
// 判断是JSON字符串还是对象
|
||||
if (typeof (this.$refs[detailType].bottomBox.object.configs) == 'string') {
|
||||
obj.configs = JSON.parse(this.$refs[detailType].bottomBox.object.configs).map(item => { return { type: item.type, enable: item.enable } })
|
||||
} else {
|
||||
obj.configs = this.$refs[detailType].bottomBox.object.configs.map(item => { return { type: item.type, enable: item.enable } })
|
||||
}
|
||||
}
|
||||
this.removeEmpty(obj)
|
||||
if (JSON.stringify(obj) != '{}') {
|
||||
params.selectObj = JSON.stringify(obj)
|
||||
}
|
||||
} else if (this.$refs[detailType] && this.$refs[detailType].detailViewRightObj) {
|
||||
this.$nextTick(() => {
|
||||
params.selectObj = JSON.stringify({
|
||||
const obj = {
|
||||
id: this.$refs[detailType].detailViewRightObj.id,
|
||||
name: this.$refs[detailType].detailViewRightObj.name,
|
||||
configs: this.$refs[detailType].detailViewRightObj.configs ? this.$refs[detailType].detailViewRightObj.configs.map(item => { return { type: item.type, enable: item.enable } }) : '',
|
||||
childrenNum: this.$refs[detailType].detailViewRightObj.childrenNum || '',
|
||||
clientState: this.$refs[detailType].detailViewRightObj.clientState || '',
|
||||
protocol: this.$refs[detailType].detailViewRightObj.protocol || '',
|
||||
uuid: this.$refs[detailType].detailViewRightObj.uuid || '',
|
||||
startTime: this.$refs[detailType].detailViewRightObj.startTime || '',
|
||||
model: {
|
||||
tsgAppliance: this.$refs[detailType].detailViewRightObj.model ? this.$refs[detailType].detailViewRightObj.model.tsgAppliance : ''
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.$refs[detailType].detailViewRightObj.configs) {
|
||||
// 判断是JSON字符串还是对象
|
||||
if (typeof (this.$refs[detailType].detailViewRightObj.configs) == 'string') {
|
||||
obj.configs = JSON.parse(this.$refs[detailType].detailViewRightObj.configs).map(item => { return { type: item.type, enable: item.enable } })
|
||||
} else {
|
||||
obj.configs = this.$refs[detailType].detailViewRightObj.configs.map(item => { return { type: item.type, enable: item.enable } })
|
||||
}
|
||||
}
|
||||
this.removeEmpty(obj)
|
||||
if (JSON.stringify(obj) != '{}') {
|
||||
params.selectObj = JSON.stringify(obj)
|
||||
}
|
||||
})
|
||||
}
|
||||
this.$router.replace({ path: path, query: params }).catch(err => {})
|
||||
} else if (from === 'nzDatalist' && this.bottomBox) {
|
||||
params.bottomBox = this.bottomBox.showSubList
|
||||
params.targetTab = this.bottomBox.targetTab
|
||||
params.selectObj = JSON.stringify({
|
||||
id: this.bottomBox.object.id,
|
||||
name: this.bottomBox.object.name,
|
||||
configs: this.bottomBox.object.configs ? this.bottomBox.object.configs.map(item => { return { type: item.type, enable: item.enable } }) : '',
|
||||
childrenNum: this.bottomBox.object.childrenNum || '',
|
||||
clientState: this.bottomBox.object.clientState || '',
|
||||
uuid: this.bottomBox.object.uuid || '',
|
||||
startTime: this.bottomBox.object.startTime || '',
|
||||
model: {
|
||||
tsgAppliance: this.bottomBox.object.model ? this.bottomBox.object.model.tsgAppliance : ''
|
||||
if (!params.targetTab) delete params.targetTab
|
||||
if (!params.bottomBox) delete params.bottomBox
|
||||
if (this.bottomBox.showSubList) { // 关闭bottomBox打开还是关闭
|
||||
const obj = {
|
||||
id: this.bottomBox.object.id,
|
||||
name: this.bottomBox.object.name,
|
||||
childrenNum: this.bottomBox.object.childrenNum || '',
|
||||
clientState: this.bottomBox.object.clientState || '',
|
||||
protocol: this.bottomBox.object.protocol || '',
|
||||
uuid: this.bottomBox.object.uuid || '',
|
||||
startTime: this.bottomBox.object.startTime || '',
|
||||
model: {
|
||||
tsgAppliance: this.bottomBox.object.model ? this.bottomBox.object.model.tsgAppliance : ''
|
||||
}
|
||||
}
|
||||
})
|
||||
if (this.bottomBox.object.configs) {
|
||||
// 判断是JSON字符串还是对象
|
||||
if (typeof (this.bottomBox.object.configs) == 'string') {
|
||||
obj.configs = JSON.parse(this.bottomBox.object.configs).map(item => { return { type: item.type, enable: item.enable } })
|
||||
} else {
|
||||
obj.configs = this.bottomBox.object.configs.map(item => { return { type: item.type, enable: item.enable } })
|
||||
}
|
||||
}
|
||||
this.removeEmpty(obj)
|
||||
if (JSON.stringify(obj) != '{}') {
|
||||
params.selectObj = JSON.stringify(obj)
|
||||
}
|
||||
} else {
|
||||
delete params.selectObj
|
||||
}
|
||||
this.$router.replace({ path: path, query: params }).catch(err => {})
|
||||
} else if (from === 'nzDetailList' && this.detailViewRightObj) {
|
||||
params.targetTab = this.$route.query.targetTab
|
||||
params.selectObj = JSON.stringify({
|
||||
const obj = {
|
||||
id: this.detailViewRightObj.id,
|
||||
name: this.detailViewRightObj.name,
|
||||
configs: this.detailViewRightObj.configs ? this.detailViewRightObj.configs.map(item => { return { type: item.type, enable: item.enable } }) : '',
|
||||
childrenNum: this.detailViewRightObj.childrenNum || '',
|
||||
clientState: this.detailViewRightObj.clientState || '',
|
||||
protocol: this.detailViewRightObj.protocol || '',
|
||||
uuid: this.detailViewRightObj.uuid || '',
|
||||
startTime: this.detailViewRightObj.startTime || '',
|
||||
model: {
|
||||
tsgAppliance: this.detailViewRightObj.model ? this.detailViewRightObj.model.tsgAppliance : ''
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.detailViewRightObj.configs) {
|
||||
// 判断是JSON字符串还是对象
|
||||
if (typeof (this.detailViewRightObj.configs) == 'string') {
|
||||
obj.configs = JSON.parse(this.detailViewRightObj.configs).map(item => { return { type: item.type, enable: item.enable } })
|
||||
} else {
|
||||
obj.configs = this.detailViewRightObj.configs.map(item => { return { type: item.type, enable: item.enable } })
|
||||
}
|
||||
}
|
||||
this.removeEmpty(obj)
|
||||
if (JSON.stringify(obj) != '{}') {
|
||||
params.selectObj = JSON.stringify(obj)
|
||||
}
|
||||
this.$router.replace({ path: path, query: params }).catch(err => {})
|
||||
} else if (from === 'bottomBox' && this.targetTab) {
|
||||
params.targetTab = this.targetTab
|
||||
@@ -153,6 +209,26 @@ export default {
|
||||
setTimeout(() => {
|
||||
$temp.$refs[formName].validate()
|
||||
}, 100)
|
||||
},
|
||||
// 清除空数据
|
||||
removeEmpty (obj) {
|
||||
if (!obj) {
|
||||
return
|
||||
}
|
||||
Object.keys(obj).forEach(key => {
|
||||
// 属性为对象
|
||||
if (Object.prototype.toString.call(obj[key]) === '[object Object]' && (JSON.stringify(obj[key]) != '{}')) {
|
||||
this.removeEmpty(obj[key])
|
||||
}
|
||||
// 属性值为空
|
||||
if (!obj[key]) {
|
||||
delete obj[key]
|
||||
}
|
||||
// 属性为空对象
|
||||
if ((Array.isArray(obj[key]) && !obj[key].length) || (JSON.stringify(obj[key]) == '{}')) {
|
||||
delete obj[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ export default {
|
||||
metrics_storage_s3_endpoint: '',
|
||||
metrics_storage_s3_secret_access_key: '',
|
||||
metrics_storage_type: '',
|
||||
prometheus_federation_enabled: ''
|
||||
prometheus_federation_enabled: '',
|
||||
interface_name: []
|
||||
},
|
||||
monitorRules: {
|
||||
// alert_api: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
|
||||
@@ -118,12 +119,18 @@ export default {
|
||||
terminal_timeout: 30,
|
||||
terminal_telnet_user_tip: 'ogin:',
|
||||
terminal_telnet_pin_tip: 'assword:',
|
||||
terminal_record_local_retention: 365
|
||||
terminal_record_local_retention: 365,
|
||||
terminal_storage_type: '',
|
||||
terminal_storage_s3_endpoint: '',
|
||||
terminal_storage_s3_bucket: '',
|
||||
terminal_storage_s3_access_key: '',
|
||||
terminal_storage_s3_secret_access_key: ''
|
||||
},
|
||||
terminalCopy: null,
|
||||
terminalRules: {
|
||||
terminal_timeout: [{ validator: positiveInteger, trigger: 'blur' }],
|
||||
terminal_record_local_retention: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }]
|
||||
terminal_record_local_retention: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }],
|
||||
terminal_storage_type: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
|
||||
},
|
||||
ldap: {
|
||||
ldap_address: '',
|
||||
@@ -253,6 +260,13 @@ export default {
|
||||
this.$refs.emailForm.clearValidate()
|
||||
}
|
||||
if (type == 'monitor') {
|
||||
if(response.data.interface_name){
|
||||
let arr = response.data.interface_name.split(',')
|
||||
this.monitor.interface_name = arr.map(item=>{
|
||||
return {text: item}
|
||||
|
||||
})
|
||||
}
|
||||
localStorage.setItem('nz-prometheus-federation-enabled', this.monitor.prometheus_federation_enabled)
|
||||
}
|
||||
this[type + 'Copy'] = Object.assign({}, this[type])
|
||||
@@ -270,6 +284,12 @@ export default {
|
||||
param.map_center_config = JSON.stringify(mapConfig)
|
||||
param.pin_policy = JSON.stringify(this.basic.pin_policy)
|
||||
}
|
||||
if(type == 'monitor') {
|
||||
let str = this.monitor.interface_name.map(item=>{
|
||||
return item.text
|
||||
})
|
||||
param.interface_name = str.join(',')
|
||||
}
|
||||
const postParam = Object.assign({}, param)
|
||||
for (const key in postParam[type]) {
|
||||
postParam[type][key] = postParam[type][key] + ''
|
||||
|
||||
@@ -78,6 +78,10 @@ export default {
|
||||
this.$emit('topology', row, param)
|
||||
break
|
||||
}
|
||||
case 'metricTarget': {
|
||||
this.$emit('metricTarget', row, param)
|
||||
break
|
||||
}
|
||||
default:
|
||||
this.$emit(command, row, param)
|
||||
break
|
||||
|
||||
@@ -198,9 +198,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
dateChange (val) {
|
||||
console.log(val)
|
||||
const startTime = this.momentTz(this.momentStrToTimestamp(val))
|
||||
console.log(this.stepSearchTime[1], this.stepSearchTime[0])
|
||||
const end = this.momentStrToTimestamp(val) + this.momentStrToTimestamp(this.stepSearchTime[1]) - this.momentStrToTimestamp(this.stepSearchTime[0])
|
||||
const endTime = this.momentTz(end, this.multipleTime)
|
||||
this.$set(this.searchTime, 0, startTime)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="choose-box-content" :title="item.checked.map(value=> labelValue[item.name].find(labelObj=>labelObj.value === value).label).join(' + ')">
|
||||
{{item.checked.map(value=> labelValue[item.name].find(labelObj=>labelObj.value === value).label).join(' + ')}}
|
||||
</div>
|
||||
<i class="nz-icon nz-icon-arrow-down6"/>
|
||||
<i class="nz-icon nz-icon-arrow-down6" style="cursor:pointer"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
@@ -389,13 +389,22 @@ export default {
|
||||
})
|
||||
},
|
||||
close () {
|
||||
let flag = false
|
||||
this.labelArr.forEach((item) => {
|
||||
if (item.visible && item.multi) {
|
||||
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
|
||||
flag = true
|
||||
}
|
||||
item.visible = false
|
||||
})
|
||||
if (flag) {
|
||||
const oldVariables = this.$store.state.panel.variablesArr
|
||||
// 如果新旧值相等 则不执行
|
||||
if (JSON.stringify(oldVariables) !== JSON.stringify(this.labelArr)) {
|
||||
this.$store.dispatch('dispatchVariablesArr', [...this.labelArr])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.dispatch('dispatchVariablesArr', [])
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
<div class="dashboard-select-tail">
|
||||
<span class="dashboard-select-add" v-has="'main_add'" :title='$t("dashboard.panel.createPanelTitleSec")' @click="toAdd">
|
||||
<i class="nz-icon nz-icon-create-square"></i> {{$t('overall.addDashboard')}}
|
||||
</span>
|
||||
<slot name="button"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pop-item-wider">
|
||||
@@ -169,10 +167,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 新增仪表盘
|
||||
toAdd () {
|
||||
this.$parent.toAdd()
|
||||
},
|
||||
// 左侧tab点击
|
||||
tabChange (value) {
|
||||
if (this.currentTab !== value) {
|
||||
|
||||
@@ -30,48 +30,24 @@
|
||||
:title="importBox.title"
|
||||
:visible.sync="importBox.show"
|
||||
width="580px"
|
||||
:modal-append-to-body="false"
|
||||
:append-to-body="true"
|
||||
@close="closeDialog"
|
||||
:class="{'import-failContent-dialog':importBox.type==3&&resultNew}"
|
||||
:class="{'import-failContent-dialog':importBox.type==3}"
|
||||
class="nz-dialog">
|
||||
|
||||
<!-- 导入 -->
|
||||
<div v-if="importBox.type == 1&&!importNew">
|
||||
<div class="upload-body" style="margin:10px 0;">
|
||||
<el-upload :id="id+'-xlsx-input-file'" ref="uploadExcel" :auto-upload="false" :file-list="importFileList" :on-change="importChange" accept=".xlsx,.xls" action="" class="upload-demo" drag>
|
||||
<div slot="tip" class="el-upload__tip" style="margin-top: 0;">{{$t('overall.importTip')}}</div>
|
||||
<i class="nz-icon nz-icon-upload"></i>
|
||||
<div class="el-upload__text">{{$t('overall.dragFileTip')}},{{$t('overall.or')}} <em>{{$t('overall.clickUpload')}}</em></div>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="el-message-box__btns" style="text-align: right;">
|
||||
<button :id="id+'-xlsx-import-template'" class="nz-btn el-button el-button--default el-button--small" @click="downloadTemplate()">
|
||||
<span>{{$t('upload.template')}}</span>
|
||||
</button>
|
||||
<button :id="id+'-xlsx-import-add'" :class="{'nz-btn-disabled':prevent_opt.import}" :disabled="prevent_opt.import" class="nz-btn el-button el-button--default el-button--small" @click="importExcel">
|
||||
<span>{{$t('overall.importExcel')}}</span>
|
||||
</button>
|
||||
<button :id="id+'-xlsx-import-esc'" class="nz-btn el-button el-button--default el-button--small" @click="closeDialog">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新版导入 -->
|
||||
<div v-if="importBox.type == 1&&importNew">
|
||||
<div v-if="importBox.type == 1">
|
||||
<div class="upload-body">
|
||||
<el-upload :id="id+'-xlsx-input-file'" ref="uploadExcel" :auto-upload="false" :file-list="importFileList" :on-change="importChange" accept=".xlsx,.xls,.csv,.json" action="" class="import-upload" drag>
|
||||
<el-upload :id="id+'-xlsx-input-file'" ref="uploadExcel" :auto-upload="false" :file-list="importFileList" :on-change="importChange" :accept="!isDashboard?'.xlsx,.xls,.csv,.json':'.json'" action="" class="import-upload" drag>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">{{$t('overall.dragFileTip')}},{{$t('overall.or')}} <em>{{$t('overall.clickUpload')}}</em></div>
|
||||
<div class="el-upload__tip" >{{$t('overall.importSupport')}}</div>
|
||||
<div class="el-upload__tip" >{{!isDashboard?$t('overall.importSupport'):$t('overall.supportJson')}}</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
<div class="import-select">
|
||||
<div v-if="showEexisted" class="exists">
|
||||
<div class="exists">
|
||||
<span>{{$t('overall.existed')}}</span>
|
||||
<el-select v-model="importBox.existed" style="flex:1" size="medium" popper-class="exists-select">
|
||||
<el-select v-model="importBox.existed" :popper-append-to-body="false" style="flex:1" size="medium" popper-class="exists-select">
|
||||
<el-option
|
||||
v-for="item in existedArr"
|
||||
:key="item.value"
|
||||
@@ -81,7 +57,7 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<ul class="import-select-list">
|
||||
<li v-if="showIgnoreError" class="import-select-item">
|
||||
<li class="import-select-item">
|
||||
<el-checkbox v-model="importBox.ignoreError">{{$t('overall.ignoreError')}}</el-checkbox>
|
||||
</li>
|
||||
<li v-if="showSyncDashboard" class="import-select-item">
|
||||
@@ -95,6 +71,7 @@
|
||||
<div class="footer">
|
||||
<div class="el-message-box__btns" style="text-align: right;">
|
||||
<el-popover
|
||||
v-if="!isDashboard"
|
||||
placement="bottom-start"
|
||||
trigger="click">
|
||||
<div class="template-pop">
|
||||
@@ -133,7 +110,7 @@
|
||||
<div class="export-box">
|
||||
<span class="export-title">{{$t('export.fileFormat')}}</span>
|
||||
<el-radio-group v-model="importBox.format" size="small">
|
||||
<el-radio-button :label="item.value" v-for="(item,index) in formatArr" :key="index">{{item.name}}</el-radio-button>
|
||||
<el-radio-button :label="item.value" v-for="(item,index) in formatArr" :key="index" :disabled="isDashboard&&item.name!='JSON'">{{item.name}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
@@ -149,64 +126,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导入结果(不展示导出失败记录) -->
|
||||
<div v-if="importBox.type==3&&!resultNew">
|
||||
<div class="upload-body result-body">
|
||||
<div v-if="importResult&&importResult.failNum">
|
||||
<div class="result-title-top">
|
||||
<div class="">
|
||||
<i class="nz-icon nz-icon-import-success"/>
|
||||
<span>{{$t('overall.result.successNum',{successNum:importResult.successNum})}}</span><br/>
|
||||
</div>
|
||||
<div class="">
|
||||
<i class="nz-icon nz-icon-import-failed"/>
|
||||
<span>{{$t('overall.result.failedNum',{failedNum:importResult.failNum,total:importResult.totalNum})}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="importResult&&importResult.failDetail" class="result-detail">
|
||||
<div style="height: 100%; overflow: auto">
|
||||
<template v-for="(item, index) in importResult.failDetail">
|
||||
<div :key="index" class="import-result-block">
|
||||
<div class="import-result-item">
|
||||
<div style="display: flex;">
|
||||
<span class="import-result-item-left">•</span>
|
||||
<div class="line-num">{{$t('overall.result.line',[item.lineNo])}}</div>
|
||||
</div>
|
||||
<div class="line-content" :title="item.errorMsg">{{item.errorMsg}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="result-success-box">
|
||||
<div>
|
||||
<i class="nz-icon nz-icon-import-success"/>
|
||||
</div>
|
||||
<div class="result-success-txt">{{$t('overall.result.successfully')}}</div>
|
||||
<div class="result-success-txt">
|
||||
{{$t('overall.result.imported')}}
|
||||
<span v-if="importResult">{{importResult.successNum}}</span>
|
||||
{{$t('overall.result.records')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="el-message-box__btns">
|
||||
<button :id="id+'-xlsx-import-rollback'" class="nz-btn el-button el-button--small nz-btn-style-error" @click="rollbackImport">
|
||||
<span>{{$t('overall.rollbackImport')}}</span>
|
||||
</button>
|
||||
<button :id="id+'-xlsx-import-close'" class="nz-btn el-button el-button--small el-button--default" @click="closeDialog">
|
||||
<span>{{$t('overall.close')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导入结果(展示导出失败记录) -->
|
||||
<div v-if="importBox.type==3&&resultNew">
|
||||
<div v-if="importBox.type==3">
|
||||
<div class="upload-body result-body">
|
||||
<!-- 失败提示 -->
|
||||
<div v-if="importResult&&importResult.failNum">
|
||||
@@ -348,29 +269,13 @@ export default {
|
||||
deleteObjs: Array,
|
||||
exportBoxShow: {
|
||||
type: Boolean, default: false
|
||||
},
|
||||
// 已存在的内容处理方式
|
||||
showEexisted: {
|
||||
type: Boolean, default: true
|
||||
},
|
||||
// 遇到错误是否继续导入
|
||||
showIgnoreError: {
|
||||
type: Boolean, default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language () { return this.$store.getters.getLanguage },
|
||||
// 是否展示新版导入
|
||||
importNew () {
|
||||
// chartTemplate dashboard
|
||||
const arr = ['/visual/panel/import']
|
||||
return !arr.some(item => item === this.importUrl)
|
||||
},
|
||||
// 是否展示新版导入结果
|
||||
resultNew () {
|
||||
// chartTemplate dashboard导入样式维持原状
|
||||
const arr = ['/visual/panel/import']
|
||||
return !arr.some(item => item === this.importUrl)
|
||||
// 判断是否是dashboard
|
||||
isDashboard () {
|
||||
return this.importUrl === '/visual/panel/import'
|
||||
},
|
||||
// 是否同步更新关联的dashboard
|
||||
showSyncDashboard () {
|
||||
@@ -492,12 +397,8 @@ export default {
|
||||
this.prevent_opt.import = true
|
||||
const form = new FormData()
|
||||
form.append('file', this.importFile.raw)
|
||||
if (this.showEexisted) {
|
||||
form.append('existed', this.importBox.existed)
|
||||
}
|
||||
if (this.showIgnoreError) {
|
||||
form.append('ignoreError', Number(this.importBox.ignoreError))
|
||||
}
|
||||
form.append('existed', this.importBox.existed)
|
||||
form.append('ignoreError', Number(this.importBox.ignoreError))
|
||||
if (this.showSyncDashboard) {
|
||||
form.append('syncDashboard', Number(this.importBox.syncDashboard))
|
||||
}
|
||||
@@ -632,6 +533,9 @@ export default {
|
||||
delete params.end_time
|
||||
delete params.id
|
||||
delete params.searchName
|
||||
delete params.value
|
||||
params.ids = params.panelId
|
||||
delete params.panelId
|
||||
}
|
||||
params.language = localStorage.getItem('nz-language') || 'en'
|
||||
params.format = this.importBox.format
|
||||
@@ -660,8 +564,7 @@ export default {
|
||||
delete params.end_time
|
||||
delete params.id
|
||||
delete params.searchName
|
||||
}
|
||||
if (this.importUrl.indexOf('panel') > -1) {
|
||||
delete params.value
|
||||
delete params.panelId
|
||||
}
|
||||
// if (this.importUrl.indexOf('endpoint') > -1){
|
||||
@@ -694,8 +597,7 @@ export default {
|
||||
delete params.end_time
|
||||
delete params.id
|
||||
delete params.searchName
|
||||
}
|
||||
if (this.importUrl.indexOf('panel') > -1) {
|
||||
delete params.value
|
||||
delete params.panelId
|
||||
}
|
||||
// if (this.importUrl.indexOf('endpoint') > -1){
|
||||
@@ -779,12 +681,10 @@ export default {
|
||||
uInt8Array[i] = raw.charCodeAt(i)
|
||||
}
|
||||
const link = document.createElement('a')
|
||||
const blob = new Blob([uInt8Array], {
|
||||
type: 'application/vnd.ms-excel'
|
||||
})
|
||||
const blob = new Blob([uInt8Array])
|
||||
link.style.display = 'none'
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.setAttribute('download', 'failed_records' + '-' + this.getTimeString() + '.xlsx')
|
||||
link.setAttribute('download', 'failed_records' + '-' + this.getTimeString() + '.json')
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
@@ -792,6 +692,10 @@ export default {
|
||||
showImportBox (type) {
|
||||
this.importBox.show = true
|
||||
this.importBox.type = type
|
||||
// isDashboard 只支持JSON
|
||||
if (this.isDashboard) {
|
||||
this.importBox.format = 3
|
||||
}
|
||||
if (type == 2 && (!this.showCur)) {
|
||||
this.exportCur()
|
||||
return
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
:use-chart-unit="false"
|
||||
class="pickTime margin-r-10">
|
||||
</pick-time>
|
||||
<button v-has="'project_edit'" class="top-tool-btn margin-r-10" type="button" @click="editTopology" :title="$t('overall.edit')">
|
||||
<button v-has="'project_edit'" class="top-tool-btn margin-r-10" type="button" @click="editTopology(false)" :title="$t('overall.edit')">
|
||||
<i class="nz-icon nz-icon-edit"></i>
|
||||
</button>
|
||||
<button class="top-tool-btn" type="button" @click="changeScreen" :title="topoScreen? $t('dashboard.screen.exit') : $t('dashboard.screen')">
|
||||
@@ -662,6 +662,7 @@ export default {
|
||||
init () {
|
||||
// canvasOptions.on = this.onMessage
|
||||
this.reload()
|
||||
this.popDataShowUpdate('', false)
|
||||
},
|
||||
|
||||
reload () {
|
||||
@@ -1982,7 +1983,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
editTopology (val) {
|
||||
editTopology (isPreview) {
|
||||
this.editTopologyFlag = true
|
||||
this.showNoData = false
|
||||
this.topoScreenState = JSON.parse(JSON.stringify(this.topoScreen))
|
||||
@@ -2027,6 +2028,13 @@ export default {
|
||||
item.animatePlay = false
|
||||
item.fontColor = item.data.fontColor || '#222222'
|
||||
}
|
||||
if (isPreview) {
|
||||
const scale = getTopology(this.topologyIndex).store.data.scale
|
||||
item.x = item.x / scale
|
||||
item.y = item.y / scale
|
||||
item.width = item.width / scale
|
||||
item.height = item.height / scale
|
||||
}
|
||||
getTopology(this.topologyIndex)._setValue(item)
|
||||
})
|
||||
getTopology(this.topologyIndex).render(true)
|
||||
@@ -2212,7 +2220,7 @@ export default {
|
||||
},
|
||||
previewExit () { // 继续编辑
|
||||
this.isPreview = false
|
||||
this.editTopology()
|
||||
this.editTopology(true)
|
||||
},
|
||||
|
||||
// 联动 project
|
||||
@@ -2407,7 +2415,6 @@ export default {
|
||||
window.removeEventListener('click', this.contextmenuNone)
|
||||
},
|
||||
destroyed () {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -104,7 +104,15 @@ export default {
|
||||
if (data.type === 0 || data.type === 1) {
|
||||
data.lineWidth = data.data.lineWidth
|
||||
}
|
||||
getTopology(this.topologyIndex).setValue(data)
|
||||
const obj = this.$loadsh.cloneDeep(data)
|
||||
delete obj.x
|
||||
delete obj.y
|
||||
delete obj.center
|
||||
delete obj.ex
|
||||
delete obj.ey
|
||||
delete obj.width
|
||||
delete obj.height
|
||||
getTopology(this.topologyIndex).setValue(obj)
|
||||
},
|
||||
pensActive (pens) {
|
||||
this.props = {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<el-form ref="assetTypeForm" :model="editAssetType" :rules="rules" label-position="top" label-width="120px">
|
||||
<!--name-->
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="64" show-word-limit v-model.trim="editAssetType.name" size="small" type="text"></el-input>
|
||||
<el-input maxlength="64" show-word-limit v-model="editAssetType.name" size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<!--vm-->
|
||||
<el-form-item :label='$t("config.assetType.vm")' prop="vm">
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<el-input
|
||||
v-if="whoshow === 3 ? true : false"
|
||||
size="small"
|
||||
v-model.trim="editBackup.repeat"
|
||||
v-model="editBackup.repeat"
|
||||
id="chart-box-title"
|
||||
@change="inputchange"
|
||||
>
|
||||
@@ -68,7 +68,7 @@
|
||||
<el-input
|
||||
v-if="whoshow === 2 ? true : false"
|
||||
size="small"
|
||||
v-model.trim="editBackup.repeat"
|
||||
v-model="editBackup.repeat"
|
||||
id="chart-box-title"
|
||||
@change="inputchange"
|
||||
>
|
||||
@@ -120,7 +120,7 @@
|
||||
<el-input
|
||||
maxlength="64"
|
||||
size="small"
|
||||
v-model.trim="editBackup.retention"
|
||||
v-model="editBackup.retention"
|
||||
id="chart-box-title"
|
||||
@change="inputchange"
|
||||
></el-input>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<el-form ref="modelForm" :model="editModel" :rules="rules" label-position="top" label-width="120px">
|
||||
<!--name-->
|
||||
<el-form-item :label="$t('config.model.name')" prop="name">
|
||||
<el-input maxlength="64" show-word-limit v-model.trim="editModel.name" size="small" type="text"></el-input>
|
||||
<el-input maxlength="64" show-word-limit v-model="editModel.name" size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<!--brand-->
|
||||
<el-form-item :label='$t("asset.brand")' prop="brandId">
|
||||
@@ -21,12 +21,12 @@
|
||||
</el-form-item>
|
||||
<!-- type -->
|
||||
<el-form-item :label='$t("overall.type")' prop="typeId">
|
||||
<el-select value-key="id" allow-create class="right-box__select" popper-class="right-box-select-top prevent-clickoutside" :filterable="true" v-model="editModel.typeId" placeholder="" size="small" id="module-box-input-project">
|
||||
<el-select :disabled='editModel.id !== ""' value-key="id" allow-create class="right-box__select" popper-class="right-box-select-top prevent-clickoutside" :filterable="true" v-model="editModel.typeId" placeholder="" size="small" id="module-box-input-project">
|
||||
<el-option v-for="(item, index) in typeDataList" :key="index" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- ChartTemplate -->
|
||||
<el-form-item :label="$t('overall.chartTemp')" prop="ChartTemplate">
|
||||
<!-- <el-form-item :label="$t('overall.chartTemp')" prop="ChartTemplate">
|
||||
<v-selectpage
|
||||
:data="chartlList"
|
||||
:tb-columns="ChartSearchShowFields"
|
||||
@@ -45,10 +45,29 @@
|
||||
@values="(data) => {editModel.chartIds = data.map(d => d.id).join(',')}"
|
||||
:result-format="resultFormat"
|
||||
></v-selectpage>
|
||||
</el-form-item> -->
|
||||
<!-- DashboardTemplate -->
|
||||
<el-form-item :label="$t('model.dashboardtemplate')" prop="panelId" ref="dashboardTemplate">
|
||||
<v-selectpage
|
||||
:data="dashboardList"
|
||||
:tb-columns="DashboardSearchShowFields"
|
||||
:params="{
|
||||
varType: 1,type: 'template'}"
|
||||
:multiple="false"
|
||||
:language="language"
|
||||
title="DashboardSearch"
|
||||
key-field="id"
|
||||
:width="634"
|
||||
v-model="editModel.panelId"
|
||||
show-field="name"
|
||||
class="form-control"
|
||||
@values="(data) => {editModel.panelId = data.map(d => d.id).join(',')}"
|
||||
:result-format="resultFormat"
|
||||
></v-selectpage>
|
||||
</el-form-item>
|
||||
<!-- sys object id -->
|
||||
<el-form-item :label="$t('config.model.sysObjectId')" prop="sysObjectId">
|
||||
<el-input maxlength="64" show-word-limit v-model.trim="editModel.sysObjectId" size="small" type="text"></el-input>
|
||||
<el-input maxlength="64" show-word-limit v-model="editModel.sysObjectId" size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<!--remark-->
|
||||
<el-form-item :label="$t('overall.remark')" prop="remark">
|
||||
@@ -100,11 +119,17 @@ export default {
|
||||
brandList: [], // brand 列表数据
|
||||
editModule: {},
|
||||
typeDataList: [],
|
||||
chartlList: [], // chart 列表数据
|
||||
ChartSearchShowFields: [ // ChartSearch 下拉搜索表头
|
||||
// chartlList: [], // chart 列表数据
|
||||
dashboardList: [], // dashboard 列表数据
|
||||
// ChartSearchShowFields: [ // ChartSearch 下拉搜索表头
|
||||
// { title: 'ID', data: 'id' },
|
||||
// { title: this.$t('overall.name'), data: 'name', key: 'name' },
|
||||
// { title: this.$t('overall.type'), data: 'type', key: 'type' },
|
||||
// { title: this.$t('overall.remark'), data: 'remark', key: 'remark' }
|
||||
// ],
|
||||
DashboardSearchShowFields: [ // DashboardSearch 下拉搜索表头
|
||||
{ title: 'ID', data: 'id' },
|
||||
{ title: this.$t('overall.name'), data: 'name', key: 'name' },
|
||||
{ title: this.$t('overall.type'), data: 'type', key: 'type' },
|
||||
{ title: this.$t('overall.remark'), data: 'remark', key: 'remark' }
|
||||
],
|
||||
url: 'asset/model',
|
||||
@@ -134,13 +159,15 @@ export default {
|
||||
handler (n) {
|
||||
this.isEdit = true
|
||||
this.editModel = JSON.parse(JSON.stringify(n))
|
||||
this.editModel.panelId = n.panelId ? n.panelId + '' : ''
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getBrandList()
|
||||
this.modelTypeList()
|
||||
this.ChartTemplateList()
|
||||
// this.ChartTemplateList()
|
||||
this.DashboardTemplateList()
|
||||
},
|
||||
methods: {
|
||||
clickOutside () {
|
||||
@@ -154,8 +181,12 @@ export default {
|
||||
saveModel () {
|
||||
this.$refs.modelForm.validate((valid) => {
|
||||
if (valid) {
|
||||
const params = {
|
||||
...this.editModel,
|
||||
panelId: this.editModel.panelId == '' ? null : Number(this.editModel.panelId)
|
||||
}
|
||||
if (this.editModel.id) {
|
||||
this.$put(this.url, this.editModel).then(res => {
|
||||
this.$put(this.url, params).then(res => {
|
||||
this.prevent_opt.save = false
|
||||
if (res.code === 200) {
|
||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||
@@ -165,7 +196,7 @@ export default {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$post(this.url, this.editModel).then(res => {
|
||||
this.$post(this.url, params).then(res => {
|
||||
this.prevent_opt.save = false
|
||||
if (res.code === 200) {
|
||||
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||
@@ -225,10 +256,16 @@ export default {
|
||||
return assetData
|
||||
}
|
||||
},
|
||||
/* 获取chart列表数据 */
|
||||
ChartTemplateList () {
|
||||
this.$get('visual/panel/chart', { pageSize: -1, varType: 1, panelId: 0, groupId: 0, returnChildren: 0 }).then(res => {
|
||||
this.chartlList = res.data.list
|
||||
// /* 获取chart列表数据 */
|
||||
// ChartTemplateList () {
|
||||
// this.$get('visual/panel/chart', { pageSize: -1, varType: 1, panelId: 0, groupId: 0, returnChildren: 0 }).then(res => {
|
||||
// this.chartlList = res.data.list
|
||||
// })
|
||||
// },
|
||||
/* 获取Dashboard列表数据 */
|
||||
DashboardTemplateList () {
|
||||
this.$get('visual/panel', { pageSize: -1, varType: 1, type: 'template' }).then(res => {
|
||||
this.dashboardList = res.data.list
|
||||
})
|
||||
},
|
||||
modelTypeList () {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<!--name-->
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="64" placeholder="" id="role-box-input-name"
|
||||
show-word-limit size="small" type="text" v-model.trim="editRole.name"></el-input>
|
||||
show-word-limit size="small" type="text" v-model="editRole.name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('overall.remark')">
|
||||
<el-input maxlength="256" show-word-limit :rows="2" size='small' type="textarea" v-model="editRole.remark" id="role-box-input-remark"/>
|
||||
|
||||
@@ -11,22 +11,22 @@
|
||||
<el-form ref="userForm" :model="editUser" :rules="editUser.id ? rules2 : rules" label-position="top" label-width="120px">
|
||||
<!--name-->
|
||||
<el-form-item :label="$t('config.user.name')" prop="name">
|
||||
<el-input id="account-input-name" v-model.trim="editUser.name" :disabled="editUser.username==='admin' && editUser.id==1"
|
||||
<el-input id="account-input-name" v-model="editUser.name" :disabled="editUser.username==='admin' && editUser.id==1"
|
||||
maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<!--username-->
|
||||
<el-form-item :label="$t('login.username')" prop="username">
|
||||
<el-input id="account-input-username" v-model.trim="editUser.username" :disabled="editUser.username==='admin' && editUser.id==1"
|
||||
<el-input id="account-input-username" v-model="editUser.username" :disabled="editUser.username==='admin' && editUser.id==1"
|
||||
maxlength="64" placeholder="" show-word-limit size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<!--password-->
|
||||
<el-form-item :label="$t('login.pin')" prop="pin">
|
||||
<el-input id="account-input-password" v-model.trim="editUser.pin" maxlength="64" placeholder=""
|
||||
<el-input id="account-input-password" v-model="editUser.pin" maxlength="64" placeholder=""
|
||||
show-word-limit size="small" type="password" @blur="pinBlur" autocomplete="new-password"></el-input>
|
||||
</el-form-item>
|
||||
<!--pinChange-->
|
||||
<el-form-item :label="$t('profile.confirmPassword')" label-width="200px" prop="pinChange">
|
||||
<el-input id="account-input-pinChange" v-model.trim="editUser.pinChange" maxlength="64" placeholder=""
|
||||
<el-input id="account-input-pinChange" v-model="editUser.pinChange" maxlength="64" placeholder=""
|
||||
show-word-limit size="small" type="password"></el-input>
|
||||
</el-form-item>
|
||||
<!--mfaLevel-->
|
||||
@@ -46,7 +46,7 @@
|
||||
</el-form-item>
|
||||
<!--email-->
|
||||
<el-form-item :label="$t('config.system.email.email')" prop="email">
|
||||
<el-input id="account-input-email" v-model.trim="editUser.email" maxlength="64" show-word-limit placeholder="" size="small" type="text"></el-input>
|
||||
<el-input id="account-input-email" v-model="editUser.email" maxlength="64" show-word-limit placeholder="" size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<!--mobile-->
|
||||
<el-form-item :label="$t('profile.mobile')" prop="mobile">
|
||||
@@ -221,7 +221,7 @@ export default {
|
||||
/* 密码失去焦点 检验确认密码 */
|
||||
pinBlur () {
|
||||
if (this.editUser.pin && this.editUser.pinChange) {
|
||||
this.$refs.accountForm.validateField('pinChange')
|
||||
this.$refs.userForm.validateField('pinChange')
|
||||
}
|
||||
},
|
||||
getRoles () {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<el-form ref="agentForm" :model="editPromServer" :rules="rules" label-position = "top" label-width="120px">
|
||||
<!-- name-->
|
||||
<el-form-item :label='$t("overall.name")' prop="name">
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model.trim="editPromServer.name" size="small" id="agent-box-input-name"></el-input>
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model="editPromServer.name" size="small" id="agent-box-input-name"></el-input>
|
||||
</el-form-item>
|
||||
<!--DC-->
|
||||
<el-form-item :label="$t('overall.dc')" prop="dc.name">
|
||||
@@ -119,6 +119,12 @@ export default {
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
token: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
],
|
||||
protocol: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
editPromServer: {},
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<el-form ref="alertRuleForm" :model="editAlertRule" :rules="rules" label-position = "top" label-width="120px">
|
||||
<!--name-->
|
||||
<el-form-item :label='$t("overall.name")' prop="name">
|
||||
<el-input id="alert-box-input-name" ref="alertName" v-model.trim="editAlertRule.name" maxlength="64" placeholder="" show-word-limit size="small"></el-input>
|
||||
<el-input id="alert-box-input-name" ref="alertName" v-model="editAlertRule.name" maxlength="64" placeholder="" show-word-limit size="small"></el-input>
|
||||
</el-form-item>
|
||||
<!--type-->
|
||||
<el-form-item :label="$t('overall.type')" prop="type" class="half-form-item">
|
||||
@@ -295,7 +295,7 @@
|
||||
<el-form-item :label="$t('dashboard.panel.receivers')" prop="receiver" :rules="[{ required: editAlertRule.notifyExpired || editAlertRule.notifyActive, message: this.$t('validate.required'), trigger: 'blur' }]">
|
||||
<el-select
|
||||
id="alert-box-input-receiver"
|
||||
v-model.trim="editAlertRule.receiverShow"
|
||||
v-model="editAlertRule.receiverShow"
|
||||
class="right-box__select"
|
||||
filterable
|
||||
multiple
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
:rules="rules" label-position="top" label-width="120px">
|
||||
<el-form-item :label='$t("overall.name")' class="range-name" prop="name">
|
||||
<el-input
|
||||
v-model.trim="editAlertSilence.name" :placeholder="''"
|
||||
v-model="editAlertSilence.name" :placeholder="''"
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
size="small">
|
||||
@@ -311,7 +311,7 @@ export default {
|
||||
rangeTimeCallback () {
|
||||
if (this.editAlertSilence.time) {
|
||||
const num = new Date(this.editAlertSilence.endAt).getTime() - new Date(this.editAlertSilence.startAt).getTime()
|
||||
this.rangeTime = num / (60 * 60 * 1000)// 以小时为单位
|
||||
this.rangeTime = parseInt(num / (60 * 60 * 1000))// 以小时为单位
|
||||
} else {
|
||||
this.rangeTime = null
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="container__form">
|
||||
<el-form ref="apiKeyBoxForm" :model="apiKeyBox" :rules="rules" label-position="top" label-width="120px">
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="64" show-word-limit v-model.trim="apiKeyBox.name" size="small" type="text"></el-input>
|
||||
<el-input maxlength="64" show-word-limit v-model="apiKeyBox.name" size="small" type="text"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('config.system.apiKey.expireAt')"
|
||||
|
||||
@@ -32,19 +32,19 @@
|
||||
</el-form-item>
|
||||
<!-- 第三级:Auth type = username | key -->
|
||||
<el-form-item :label="$t('profile.username')" prop="authUsername">
|
||||
<el-input v-model.trim="editData.authUsername" size="small"/>
|
||||
<el-input v-model="editData.authUsername" size="small"/>
|
||||
</el-form-item>
|
||||
<template v-if="editData.authType === assetConstants.authTypeData.key">
|
||||
<!-- Key支持私钥 -->
|
||||
<el-form-item :label="$t('asset.privateKey')" prop="authPriKey">
|
||||
<el-input v-model.trim="editData.authPriKey" size="small" type="password" autocomplete="new-password"/>
|
||||
<el-input v-model="editData.authPriKey" size="small" type="password" autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item :label="$t('login.pin')" prop="authPin">
|
||||
<el-input v-model.trim="editData.authPin" size="small" type="password" autocomplete="new-password"/>
|
||||
<el-input v-model="editData.authPin" size="small" type="password" autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('asset.port')" prop="authProtocolPort">
|
||||
<el-input v-model.trim="editData.authProtocolPort" size="small"/>
|
||||
<el-input v-model="editData.authProtocolPort" size="small"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -52,16 +52,16 @@
|
||||
<template v-if="editData.authProtocol === assetConstants.authProtocolData.telnet">
|
||||
<div class="form__sub-title">TELNET</div>
|
||||
<el-form-item :label="$t('profile.username')" prop="authUsername">
|
||||
<el-input v-model.trim="editData.authUsername" size="small"/>
|
||||
<el-input v-model="editData.authUsername" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('login.pin')" prop="authPin">
|
||||
<el-input v-model.trim="editData.authPin" size="small"/>
|
||||
<el-input v-model="editData.authPin" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('asset.usernamePrompt')" prop="authUserTip">
|
||||
<el-input v-model.trim="editData.authUserTip" size="small"/>
|
||||
<el-input v-model="editData.authUserTip" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('asset.pinPrompt')" prop="authPinTip">
|
||||
<el-input v-model.trim="editData.authPinTip" size="small"/>
|
||||
<el-input v-model="editData.authPinTip" size="small"/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
@@ -83,16 +83,16 @@
|
||||
</template>
|
||||
<template v-if="label.action !== 1">
|
||||
<template v-if="label.type.toUpperCase() === assetConstants.labelTypeData.TEXT">
|
||||
<el-input v-model.trim="label.value" size="small"/>
|
||||
<el-input v-model="label.value" size="small"/>
|
||||
</template>
|
||||
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.MULTITEXT">
|
||||
<div v-for="(value, i) in label.value" :key="i" class="label__multi-text">
|
||||
<el-input v-model.trim="label.value[i]" size="small" style="margin-right: 15px;"/>
|
||||
<el-input v-model="label.value[i]" size="small" style="margin-right: 15px;"/>
|
||||
<span :style="{'opacity': label.value.length > 1 ? 1 : 0.5}" @click="label.value.length > 1 ? label.value.splice(i, 1) : ''" :title="$t('overall.delete')"><i class="nz-icon nz-icon-minus"></i></span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.TEXTAREA">
|
||||
<el-input v-model.trim="label.value" :maxlength="4096" size="small" :rows="2" show-word-limit type="textarea"/>
|
||||
<el-input v-model="label.value" :maxlength="4096" size="small" :rows="2" show-word-limit type="textarea"/>
|
||||
</template>
|
||||
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.RADIO">
|
||||
<el-radio v-for="item in JSON.parse(label.param).items" :key="item.name" v-model="label.value" :label="item.name">{{item.name}}</el-radio>
|
||||
@@ -108,10 +108,10 @@
|
||||
</el-select>
|
||||
</template>
|
||||
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.INTEGER">
|
||||
<el-input v-model.trim="label.value" oninput="value=value.replace(/[^\d]/g,'')" size="small"></el-input>
|
||||
<el-input v-model="label.value" oninput="value=value.replace(/[^\d]/g,'')" size="small"></el-input>
|
||||
</template>
|
||||
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.DOUBLE">
|
||||
<el-input v-model.trim="label.value" oninput="value=value.replace(/[^0-9.]/g,'')" size="small"></el-input>
|
||||
<el-input v-model="label.value" oninput="value=value.replace(/[^0-9.]/g,'')" size="small"></el-input>
|
||||
</template>
|
||||
<template v-else-if="label.type.toUpperCase() === assetConstants.labelTypeData.DATETIME">
|
||||
<template v-if="JSON.parse(label.param).subType === assetConstants.labelSubTypeData.time">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="container__form">
|
||||
<el-form ref="form" :model="editAsset" :rules="rules" label-position="top" label-width="120px">
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="128" show-word-limit v-model.trim="editAsset.name" size="small"/>
|
||||
<el-input maxlength="128" show-word-limit v-model="editAsset.name" size="small"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('overall.type')" prop="typeId">
|
||||
<select-asset-type id="asset-type" :asset-type-data="options.typeOptions" :show-type="editAsset.type" size="small"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="container__form">
|
||||
<el-form label-width="120px" :model="editAssetMeta" label-position = "top" ref="editAssetMetaForm" :rules="rules">
|
||||
<el-form-item :label='$t("overall.name")' prop="name">
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model.trim="editAssetMeta.name" size="small" id="editAssetMeta-box-input-name"></el-input>
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model="editAssetMeta.name" size="small" id="editAssetMeta-box-input-name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("overall.key")' prop="metaKey">
|
||||
<el-input placeholder="" maxlength="128" show-word-limit v-model="editAssetMeta.metaKey" size="small" id="editAssetMeta-box-input-key"></el-input>
|
||||
@@ -70,7 +70,7 @@
|
||||
<el-row v-for="(item,index) in editAssetMeta.param.items" :key="index" class="asset-meta-param-row">
|
||||
<el-col :span="12">
|
||||
<el-form-item :prop="'param.items.'+ index + '.name'" :rules="[{ required: true, message: $t('validate.required'), trigger: 'blur'},{ validator: checkItems, trigger: 'blur' }]">
|
||||
<el-input v-model.trim = "item.name" size="small" @input="(val)=>{inputChange(index, val)}" :ref="'metaNameOption'+index"></el-input>
|
||||
<el-input v-model = "item.name" size="small" @input="(val)=>{inputChange(index, val)}" :ref="'metaNameOption'+index"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="container__form">
|
||||
<el-form label-width="120px" :model="editMetaGroup" label-position = "top" ref="editMetaGroupForm">
|
||||
<el-form-item :label='$t("overall.name")' prop="name" :rules="{required: true, message: $t('validate.required'), trigger: 'blur'}">
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model.trim="editMetaGroup.name" size="small" id="editMetaGroup-box-input-name"></el-input>
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model="editMetaGroup.name" size="small" id="editMetaGroup-box-input-name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("overall.remark")' prop="remark">
|
||||
<el-input placeholder="" maxlength="256" type="textarea" show-word-limit v-model="editMetaGroup.remark" size="small" :rows="2" id="editMetaGroup-box-input-remark"></el-input>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<el-form :model="editAssetState" :rules="rules" class="right-box-form right-box-form-left" label-position="top" label-width="120px" ref="assetStateForm">
|
||||
<!--name-->
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input id="asset-state-input-name" placeholder="" size="small" type="text" v-model.trim="editAssetState.name"></el-input>
|
||||
<el-input id="asset-state-input-name" placeholder="" size="small" type="text" v-model="editAssetState.name"></el-input>
|
||||
</el-form-item>
|
||||
<!--ping-->
|
||||
<el-form-item label="Ping">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="right-box-form-box">
|
||||
<el-form class="right-box-form right-box-form-left" label-width="120px" label-position = "top" :model="editCabinet" ref="cabinetForm" :rules="rules">
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input size='mini' maxlength="64" show-word-limit v-model.trim="editCabinet.name" id="cabinet-box-input-name"/>
|
||||
<el-input size='mini' maxlength="64" show-word-limit v-model="editCabinet.name" id="cabinet-box-input-name"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('overall.dc')" prop="idcId">
|
||||
<el-input v-if="dcDisabled" size='mini' v-model="currentDc.name" disabled id="cabinet-box-input-dc"/>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
</div>
|
||||
<transition name="el-zoom-in-top">
|
||||
<el-row v-show="expressionsShow[index-1].show">
|
||||
<el-form-item :prop="'elements.' + (index -1) + '.expression'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}">
|
||||
<el-form-item :prop="'elements.' + (index -1) + '.expression'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}">
|
||||
<promql-input
|
||||
:from-father-data="true"
|
||||
:metricOptionsParent="metricOptions"
|
||||
@@ -480,7 +480,7 @@
|
||||
<el-row v-if="chartConfig.param.enable.thresholds && isThresholdConfig(chartConfig.type)">
|
||||
<el-form-item
|
||||
v-for="(item,index) in chartConfig.param.thresholds"
|
||||
:key="index"
|
||||
:key="item.color + '' + index"
|
||||
class="thresholds-item"
|
||||
:prop="'param.thresholds.' + index + '.value'"
|
||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<el-form ref="chartForm" :model="editChart" :rules="rules" label-position= "top" label-width="120px">
|
||||
<el-form-item :label='$t("overall.name")' prop="name">
|
||||
<div style="display:flex;align-items:center">
|
||||
<el-input style="flex:1;margin-right:10px" maxlength="64" show-word-limit size="small" v-model.trim="editChart.name" id="chart-box-title"></el-input>
|
||||
<el-input style="flex:1;margin-right:10px" maxlength="64" show-word-limit size="small" v-model="editChart.name" id="chart-box-title"></el-input>
|
||||
<!-- 显示头部 -->
|
||||
<div class="choose-header-btn" v-if="editChart.param&&editChart.param.showHeader!==0" @click="switchHeader(0)" :title="$t('overall.visible')">
|
||||
<i class="nz-icon nz-icon-mimakejian"></i>
|
||||
@@ -33,7 +33,7 @@
|
||||
<!--panel-->
|
||||
<el-form-item
|
||||
class="form-item--half-width"
|
||||
v-if="showPanel.type !== fromRoute.project && showPanel.type !== fromRoute.asset && showPanel.type !== fromRoute.endpoint && showPanel.type !== fromRoute.model && from!=='chartTemp'"
|
||||
v-if="showPanel.type !== fromRoute.project && showPanel.type !== fromRoute.asset && showPanel.type !== fromRoute.endpoint && showPanel.type !== fromRoute.model && from!=='chartTemp' && from!=='dashboardTemp'"
|
||||
:label="$t('overall.dashboard')"
|
||||
prop="panelName"
|
||||
>
|
||||
@@ -67,11 +67,11 @@
|
||||
</div>
|
||||
<!--remark-->
|
||||
<el-form-item :label="$t('overall.remark')">
|
||||
<el-input maxlength="256" show-word-limit v-model.trim="editChart.remark" size="small" :rows="2" type="textarea"/>
|
||||
<el-input maxlength="256" show-word-limit v-model="editChart.remark" size="small" :rows="2" type="textarea"/>
|
||||
</el-form-item>
|
||||
<!--remark-->
|
||||
<el-form-item :label="$t('overall.link')" v-if="editChart.param">
|
||||
<el-input maxlength="256" show-word-limit v-model.trim="editChart.param.link" size="small" :rows="2" type="textarea"/>
|
||||
<el-input maxlength="256" show-word-limit v-model="editChart.param.link" size="small" :rows="2" type="textarea"/>
|
||||
</el-form-item>
|
||||
|
||||
<!--title-->
|
||||
@@ -164,12 +164,6 @@ export default {
|
||||
fromEndpoint: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
variables: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
mixins: [rz, editRigthBox],
|
||||
@@ -183,6 +177,9 @@ export default {
|
||||
computed: {
|
||||
chartLastPosition () {
|
||||
return this.$store.getters.getChartLastPosition
|
||||
},
|
||||
variables () {
|
||||
return this.$store.state.panel.variablesArr
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@@ -580,6 +577,11 @@ export default {
|
||||
result: ''
|
||||
}
|
||||
}
|
||||
if (obj.type === 'group' && !obj.param.repeat) {
|
||||
obj.param.repeat = {
|
||||
variable: ''
|
||||
}
|
||||
}
|
||||
// this.editChart.varType = 1
|
||||
if (obj.param.enable.legend && !obj.param.legend) {
|
||||
obj.param.legend = { placement: 'bottom', values: [], show: true }
|
||||
|
||||
@@ -247,6 +247,46 @@
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<!-- repeat -->
|
||||
<div v-if="params.type === 'group'">
|
||||
<div class="form__sub-title">
|
||||
<span>{{$t('dashboard.repeat')}}</span>
|
||||
<el-switch
|
||||
v-model="chartConfig.param.enable.repeat"
|
||||
size="small"
|
||||
@change="change"
|
||||
></el-switch>
|
||||
</div>
|
||||
<transition name="el-zoom-in-top">
|
||||
<div
|
||||
v-if="chartConfig.param.enable.repeat"
|
||||
class="form-items--half-width-group"
|
||||
>
|
||||
<!-- variable -->
|
||||
<el-form-item
|
||||
:label="$t('dashboard.panel.variableName')"
|
||||
class="form-item--half-width"
|
||||
prop="param.repeat.variable"
|
||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||
>
|
||||
<el-select
|
||||
v-model="chartConfig.param.repeat.variable"
|
||||
:placeholder="$t('el.select.placeholder')"
|
||||
popper-class="right-box-select-top prevent-clickoutside"
|
||||
size="small"
|
||||
@change="change"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in variables"
|
||||
:key="item.name"
|
||||
:label="$t(item.name)"
|
||||
:value="item.name"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
@@ -320,7 +360,8 @@ export default {
|
||||
link: this.chartConfig.param.link,
|
||||
collapse: true,
|
||||
enable: {
|
||||
visibility: false
|
||||
visibility: false,
|
||||
repeat: false
|
||||
},
|
||||
showHeader: this.chartConfig.param.showHeader,
|
||||
visibility: {
|
||||
@@ -328,6 +369,9 @@ export default {
|
||||
operator: 'equal',
|
||||
varValue: '',
|
||||
result: 'show'
|
||||
},
|
||||
repeat: {
|
||||
variable: ''
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
@@ -396,7 +396,7 @@
|
||||
<el-row v-if="chartConfig.param.enable.thresholds && isThresholdConfig(chartConfig.type)">
|
||||
<el-form-item
|
||||
v-for="(item,index) in chartConfig.param.thresholds"
|
||||
:key="index"
|
||||
:key="item.color + '' + index"
|
||||
class="thresholds-item"
|
||||
:prop="'param.thresholds.' + index + '.value'"
|
||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
<!--type-->
|
||||
<el-form-item v-if="from !== fromRoute.endpoint" :label="$t('dashboard.panel.chartForm.varType')" prop="varType">
|
||||
<el-select id="chart-box-group"
|
||||
v-model="editChartTemp.varType"
|
||||
class="right-box__select"
|
||||
clearable
|
||||
placeholder=""
|
||||
popper-class="prevent-clickoutside right-box-select-top"
|
||||
size="small"
|
||||
value-key="chartType"
|
||||
@change="varTypeChange">
|
||||
v-model="editChartTemp.varType"
|
||||
class="right-box__select"
|
||||
clearable
|
||||
placeholder=""
|
||||
popper-class="prevent-clickoutside right-box-select-top"
|
||||
size="small"
|
||||
value-key="chartType"
|
||||
@change="varTypeChange">
|
||||
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in varTypeArr">
|
||||
<span class="panel-dropdown-label-txt" >{{item.name}}</span>
|
||||
</el-option>
|
||||
@@ -61,17 +61,18 @@
|
||||
<!-- 选择资产,穿梭框 -->
|
||||
<template v-if="showTransfer">
|
||||
<div class="form__sub-title">{{editChartTemp.varType === 1 ? $t('overall.asset') : $t('project.endpoint.endpoint')}}</div>
|
||||
<nz-transfer ref="transfer"
|
||||
:from="from"
|
||||
:page-obj="transfer.pageObj"
|
||||
:search-msg="transfer.searchMsg"
|
||||
:table-data="transfer.tableData"
|
||||
:tableTitle="transferTableTitle"
|
||||
style="margin-bottom: 20px;"
|
||||
@pageNo="pageNoChange"
|
||||
@leftToRight="addAsset"
|
||||
@rightToLeft="removeAsset"
|
||||
@search="search">
|
||||
<nz-transfer
|
||||
ref="transfer"
|
||||
:from="from"
|
||||
:page-obj="transfer.pageObj"
|
||||
:search-msg="transfer.searchMsg"
|
||||
:table-data="transfer.tableData"
|
||||
:tableTitle="transferTableTitle"
|
||||
style="margin-bottom: 20px;"
|
||||
@pageNo="pageNoChange"
|
||||
@leftToRight="addAsset"
|
||||
@rightToLeft="removeAsset"
|
||||
@search="search">
|
||||
<template v-slot:title>{{$t('overall.selected')}}</template>
|
||||
</nz-transfer>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<div v-clickoutside="{obj: editDashboard, func: esc}" class="right-box right-box-dashboard-temp">
|
||||
<div class="right-box__header">
|
||||
<div class="header__title">{{$t("dashboard.panel.createPanelTitle")}}</div>
|
||||
<div class="header__operation">
|
||||
<span v-cancel="{obj: editDashboard, func: esc}"><i class="nz-icon nz-icon-close" :title="$t('overall.close')"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-box__container">
|
||||
<div class="container__form">
|
||||
<el-form ref="form" :model="editDashboard" :rules="rules" label-position="top" label-width="120px">
|
||||
<!-- name -->
|
||||
<el-form-item :label='$t("overall.name")' prop="name">
|
||||
<el-input v-model="editDashboard.name" maxlength="64" placeholder="" show-word-limit size="small"></el-input>
|
||||
</el-form-item>
|
||||
<!-- dashboardTemplate -->
|
||||
<el-form-item :label="$t('upload.template')" prop="tmplId">
|
||||
<v-selectpage
|
||||
:data="templateList"
|
||||
:tb-columns="ChartSearchShowFields"
|
||||
:multiple="false"
|
||||
:language="language"
|
||||
key-field="id"
|
||||
show-field="name"
|
||||
:width="640"
|
||||
v-model="editDashboard.tmplId"
|
||||
class="form-control"
|
||||
:result-format="resultFormat"
|
||||
@values="tempChange"
|
||||
></v-selectpage>
|
||||
</el-form-item>
|
||||
<!-- link -->
|
||||
<el-form-item v-if="templateType" :label="templateType==1?$t('asset.asset'):$t('asset.endpoint')" prop="link" key="link">
|
||||
<v-selectpage
|
||||
:data="dataList"
|
||||
:tb-columns="templateType==1?assetColumns:endpointColumns"
|
||||
:multiple="false"
|
||||
:language="language"
|
||||
key-field="id"
|
||||
show-field="name"
|
||||
:width="640"
|
||||
v-model="editDashboard.link"
|
||||
class="form-control"
|
||||
:result-format="resultFormat"
|
||||
@values="linkChange"
|
||||
></v-selectpage>
|
||||
</el-form-item>
|
||||
<!--description-->
|
||||
<el-form-item :label='$t("overall.remark")' prop="description">
|
||||
<el-input
|
||||
v-model="editDashboard.description"
|
||||
maxlength="256"
|
||||
:rows="2"
|
||||
show-word-limit
|
||||
size="small"
|
||||
type="textarea">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-box__footer">
|
||||
<button id="asset-edit-cancel" v-cancel="{obj: editDashboard, func: esc}" class="footer__btn footer__btn--light">
|
||||
<span>{{$t('overall.cancel')}}</span>
|
||||
</button>
|
||||
<button id="asset-edit-save" :class="{'footer__btn--disabled': prevent_opt.save}" :disabled="prevent_opt.save" class="footer__btn" @click="save">
|
||||
<span>{{$t('overall.save')}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import bus from '@/libs/bus'
|
||||
import editRigthBox from '../mixin/editRigthBox'
|
||||
export default {
|
||||
props: {
|
||||
},
|
||||
mixins: [editRigthBox],
|
||||
data () {
|
||||
return {
|
||||
url: '/visual/panel/fromTmpl',
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
],
|
||||
tmplId: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
],
|
||||
link: [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
ChartSearchShowFields: [ // ChartSearch 下拉搜索表头
|
||||
{ title: 'ID', data: 'id' },
|
||||
{
|
||||
title: this.$t('overall.name'),
|
||||
data: function (row) {
|
||||
if (row.name.length > 15) {
|
||||
return row.name.substring(0, 12) + '...'
|
||||
}
|
||||
return row.name
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('dashboard.panel.chartForm.varType'),
|
||||
data: function (row) {
|
||||
let str
|
||||
switch (row.varType) {
|
||||
case 0 : str = 'None'; break
|
||||
case 1 : str = 'Asset'; break
|
||||
case 2 : str = 'Endpoint'; break
|
||||
}
|
||||
return str
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('overall.remark'),
|
||||
data: function (row) {
|
||||
if (row.remark && row.remark.length > 15) {
|
||||
return row.remark.substring(0, 12) + '...'
|
||||
}
|
||||
return row.remark
|
||||
}
|
||||
}
|
||||
],
|
||||
// asset表头
|
||||
assetColumns: [
|
||||
{ title: 'id', data: 'id' },
|
||||
{
|
||||
title: this.$t('overall.name'),
|
||||
data: function (row) {
|
||||
if (row.name.length > 15) {
|
||||
return row.name.substring(0, 12) + '...'
|
||||
}
|
||||
return row.name
|
||||
}
|
||||
},
|
||||
{ title: 'Manage Ip', data: 'manageIp' },
|
||||
{
|
||||
title: this.$t('overall.type'),
|
||||
data: (row) => {
|
||||
return row.type ? row.type.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('asset.model'),
|
||||
data: (row) => {
|
||||
return row.model ? row.model.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('overall.dc'),
|
||||
data: (row) => {
|
||||
return row.dc ? row.dc.name : ''
|
||||
}
|
||||
}
|
||||
],
|
||||
// endpoint表头
|
||||
endpointColumns: [
|
||||
{ title: 'ID', data: 'id' },
|
||||
{
|
||||
title: this.$t('overall.name'),
|
||||
data: function (row) {
|
||||
if (row.name.length > 15) {
|
||||
return row.name.substring(0, 12) + '...'
|
||||
}
|
||||
return row.name
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('overall.project'),
|
||||
data: (row) => {
|
||||
return row.project ? row.project.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('asset.asset'),
|
||||
data: (row) => {
|
||||
return row.asset ? row.asset.name : ''
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('overall.module'),
|
||||
data: (row) => {
|
||||
return row.module ? row.module.name : ''
|
||||
}
|
||||
}
|
||||
],
|
||||
editDashboard: {
|
||||
name: '',
|
||||
type: 'dashboard',
|
||||
tmplId: '',
|
||||
link: '',
|
||||
description: ''
|
||||
},
|
||||
templateList: [],
|
||||
dataList: [],
|
||||
templateType: undefined // 选中模板的varType
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language () { return this.$store.getters.getLanguage }
|
||||
},
|
||||
created () {
|
||||
this.isEdit = true
|
||||
this.getDashboardTempData()
|
||||
},
|
||||
methods: {
|
||||
// 选中的模板变化
|
||||
tempChange: bus.debounce(function (val) {
|
||||
const newValue = this.$loadsh.get(val, ['0', 'varType'])
|
||||
const oldValue = this.templateType
|
||||
this.templateType = newValue
|
||||
// 判断varType是否变化
|
||||
if (oldValue != newValue) {
|
||||
this.getTableData()
|
||||
}
|
||||
this.$refs.form.validateField('tmplId')
|
||||
}, 50),
|
||||
// 校验
|
||||
linkChange: bus.debounce(function () {
|
||||
this.$refs.form.validateField('link')
|
||||
}, 50),
|
||||
// 获取dashboard模板列表
|
||||
getDashboardTempData () {
|
||||
this.$get('visual/panel', { type: 'template', pageSize: -1 }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.templateList = response.data.list
|
||||
}
|
||||
})
|
||||
},
|
||||
// 根据选中模板vartype请求数据
|
||||
getTableData () {
|
||||
this.editDashboard.link = ''
|
||||
this.dataList = []
|
||||
if (this.templateType === 1) {
|
||||
this.getAssetData()
|
||||
} else if (this.templateType === 2) {
|
||||
this.getEndpointData()
|
||||
}
|
||||
},
|
||||
// 获取asset列表
|
||||
getAssetData () {
|
||||
this.$get('asset/asset', { pageSize: -1 }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.dataList = response.data.list
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取endpoint列表
|
||||
getEndpointData () {
|
||||
this.$get('monitor/endpoint', { pageSize: -1 }).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.dataList = response.data.list
|
||||
}
|
||||
})
|
||||
},
|
||||
save () {
|
||||
if (this.prevent_opt.save) {
|
||||
return
|
||||
}
|
||||
this.prevent_opt.save = true
|
||||
const params = this.$loadsh.cloneDeep(this.editDashboard)
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
// 模板varType ≠ 0时link有效且必填
|
||||
if (this.templateType == 0) {
|
||||
delete params.link
|
||||
}
|
||||
this.$post(this.url, params).then(response => {
|
||||
this.prevent_opt.save = false
|
||||
if (response.code === 200) {
|
||||
this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') })
|
||||
this.esc(true)
|
||||
} else {
|
||||
this.$message.error(response.msg)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.prevent_opt.save = false
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
resultFormat (resp) {
|
||||
if (resp && resp.data) {
|
||||
const assetData = {}
|
||||
assetData.list = resp.data.list
|
||||
assetData.totalRow = resp.data.total
|
||||
return assetData
|
||||
}
|
||||
},
|
||||
/* 关闭弹框 */
|
||||
esc (refresh) {
|
||||
this.prevent_opt.save = false
|
||||
this.$emit('close', refresh)
|
||||
},
|
||||
clickOutside () {
|
||||
this.esc(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="container__form">
|
||||
<el-form label-width="120px" size="small" :model="editDc" label-position = "top" :rules="rules" ref="dcForm">
|
||||
<el-form-item :label='$t("overall.name")' prop="name">
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model.trim="editDc.name" size="small" id="dc-box-input-name"></el-input>
|
||||
<el-input placeholder="" maxlength="64" show-word-limit v-model="editDc.name" size="small" id="dc-box-input-name"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label='$t("asset.location")' prop="location">
|
||||
<el-input placeholder="" maxlength="256" show-word-limit v-model="editDc.location" size="small" id="dc-box-input-location"></el-input>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
</el-form-item>
|
||||
<!--name-->
|
||||
<el-form-item v-if="optionType!=='batch'" :label='$t("overall.name")' label-width="125px" prop="name">
|
||||
<el-input id="module-box-input-name" v-model.trim="editEndpoint.name" maxlength="64" placeholder="" show-word-limit size="small"></el-input>
|
||||
<el-input id="module-box-input-name" v-model="editEndpoint.name" maxlength="64" placeholder="" show-word-limit size="small"></el-input>
|
||||
</el-form-item>
|
||||
<!--Enpoint template-->
|
||||
<div class="right-box-sub-title">{{ $t("overall.config") }}
|
||||
@@ -627,7 +627,7 @@
|
||||
<el-form-item
|
||||
:label="'Format'"
|
||||
:prop="'configs.1.config.'+ index +'.pipeline.' + index2 + '.format'"
|
||||
:rules="[{ required: true, message: $t('validate.required'), trigger: 'blur' }]"
|
||||
:rules="[{ required: true, message: $t('validate.required'), trigger: 'change' }]"
|
||||
>
|
||||
<!-- <el-input v-model="item2.format" placeholder="key" size="mini"></el-input> -->
|
||||
<el-select v-model="item2.format" :id="'timestamp' + index +'-' + index2" class="right-box__select" placeholder="" popper-class="right-box-select-top prevent-clickoutside" size="small">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="container__form container__form-width">
|
||||
<el-form ref="ExprTempForm" :model="editExprTemp" :rules="rules" label-position="top" label-width="120px">
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="64" show-word-limit v-model.trim="editExprTemp.name" :placeholder="$t('overall.placeHolder')" size="small"></el-input>
|
||||
<el-input maxlength="64" show-word-limit v-model="editExprTemp.name" :placeholder="$t('overall.placeHolder')" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dashboard.panel.chartForm.group')" prop="gname">
|
||||
<!--<el-input v-model="editExprTemp.gname" size="small" :placeholder="$t('overall.placeHolder')"></el-input>-->
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="container__form">
|
||||
<el-form :model="editipDetails" label-position="top" label-width="120px" :rules="rules" ref="ipDetailsForm">
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="64" rows="4" show-word-limit placeholder="" v-model.trim="editipDetails.name" size="small"></el-input>
|
||||
<el-input maxlength="64" rows="4" show-word-limit placeholder="" v-model="editipDetails.name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="IP" prop="addr">
|
||||
<el-input maxlength="256" rows="4" show-word-limit placeholder="" v-model="editipDetails.addr" size="small"></el-input>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="container__form">
|
||||
<el-form :model="editipam" label-position = "top" label-width="120px" :rules="rules" ref="ipamForm">
|
||||
<el-form-item :label="$t('overall.name')" prop="name">
|
||||
<el-input maxlength="64" rows="4" show-word-limit placeholder="" v-model.trim="editipam.name" size="small"></el-input>
|
||||
<el-input maxlength="64" rows="4" show-word-limit placeholder="" v-model="editipam.name" size="small"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('overall.type')" prop="type">
|
||||
<el-select id="account-input-language"
|
||||
@@ -132,7 +132,7 @@ export default {
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
],
|
||||
'dc.name': [
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
|
||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
dcData: []
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<!-- title -->
|
||||
<el-form-item :label='$t("project.topology.title")' prop="name">
|
||||
<el-input
|
||||
v-model.trim="editIssue.name"
|
||||
v-model="editIssue.name"
|
||||
:placeholder="''"
|
||||
maxlength="64"
|
||||
show-word-limit
|
||||
@@ -84,7 +84,7 @@
|
||||
<el-form-item :label='$t("issue.reporter")' prop="rid">
|
||||
<el-select
|
||||
id="issue-box-input-receiver"
|
||||
v-model.trim="editIssue.rid"
|
||||
v-model="editIssue.rid"
|
||||
class="right-box__select"
|
||||
filterable
|
||||
placeholder=""
|
||||
@@ -106,7 +106,7 @@
|
||||
<el-form-item :label='$t("issue.assignee")' prop="aid">
|
||||
<el-select
|
||||
id="issue-box-input-receiver"
|
||||
v-model.trim="editIssue.aid"
|
||||
v-model="editIssue.aid"
|
||||
class="right-box__select"
|
||||
filterable
|
||||
placeholder=""
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user