Compare commits

...

175 Commits
v9.5.0 ... main

Author SHA1 Message Date
dependabot[bot]
0c2cfa5630
build(deps-dev): bump vite from 6.2.6 to 6.3.4 (#468) 2025-05-01 16:42:57 +08:00
Fine0830
5e6e5aa737
Fix: correct the same labels for metrics (#467) 2025-04-24 11:58:29 +08:00
Fine0830
a4cd265d45
refactor: use the Fetch API to instead of Axios (#466) 2025-04-22 11:41:29 +08:00
peachisai
0ef6b57cae
Add the Flink icon and descriptions (#465) 2025-04-17 19:27:58 +08:00
Fine0830
687ae07bb0
feat: enhance the trace table graph for multiple refs (#464) 2025-04-14 21:12:48 +08:00
dependabot[bot]
0775bf0034
build(deps-dev): bump vite from 6.2.5 to 6.2.6 (#463) 2025-04-12 10:39:21 +08:00
Fine0830
5c322d960f
feat: enhance the trace tree to support displaying multiple refs of spans and distinguishing different parents. (#462) 2025-04-08 20:44:36 +08:00
dependabot[bot]
df2d07f508
build(deps-dev): bump vite from 6.2.4 to 6.2.5 (#461) 2025-04-07 09:44:10 +08:00
dependabot[bot]
105450071e
build(deps-dev): bump vite from 6.2.3 to 6.2.4 (#460)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.2.3 to 6.2.4.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.2.4/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.2.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 07:32:25 +08:00
Fine0830
39b4626317
feat: enhance trace list graph (#459) 2025-03-28 10:34:01 +08:00
dependabot[bot]
0ea8335fee
build(deps-dev): bump vite from 6.1.1 to 6.2.3 (#458) 2025-03-26 09:39:39 +08:00
dependabot[bot]
0d2bedf529
build(deps): bump axios from 1.7.5 to 1.8.2 (#456) 2025-03-09 19:11:40 +08:00
dependabot[bot]
b525f84fa0
build(deps): bump vue-i18n from 9.2.2 to 9.14.3 (#455) 2025-03-09 19:04:12 +08:00
Fine0830
1fe58f5f6c
build: remove lodash library (#454) 2025-03-06 17:10:54 +08:00
周小杰
012ae1db6c
fix: time range when generate link (#453) 2025-03-06 15:47:55 +08:00
Zixin Zhou
79ec865ee7
Add skywalking go agent self observability menu (#452) 2025-03-02 18:48:14 +08:00
Fine0830
9ab8ac44bc
add pagination for endpoint list (#451) 2025-02-28 17:15:55 +08:00
Fine0830
7a690e6704
feat: add topN selector for endpoint list (#450) 2025-02-28 16:19:27 +08:00
Fine0830
65607a5540
fix echarts tooltips (#449) 2025-02-24 16:38:17 +08:00
Fine0830
5bb4218bfe
feat: Implement the legend selector in metrics charts (#447) 2025-02-20 16:19:22 +08:00
Fine0830
2b6f3ecaa8
build: bump up dependencies (#448) 2025-02-20 13:49:58 +08:00
Fine0830
2246a9a045
fix name in routes (#446) 2025-02-13 18:06:56 +08:00
dependabot[bot]
9318d32b0b
build(deps-dev): bump vite from 4.5.3 to 4.5.9 (#445) 2025-01-22 14:19:08 +08:00
Fine0830
8ea50c8680
feat: visualize Snapshot on Alerting page (#444) 2025-01-13 17:24:32 +08:00
Fine0830
55b3867bea
fix: set up async profiling tasks (#443) 2024-12-30 15:51:26 +08:00
Super-Lu
c33d6c4180
Fix the issue where when initiating a query on the endpoint topology page, if the query parameters contain the ID of the virtual endpoint User, all link information will be retrieved. (#442) 2024-12-21 20:25:44 +08:00
dependabot[bot]
70ea9fd06f
build(deps): bump nanoid from 3.3.7 to 3.3.8 (#441) 2024-12-15 14:55:06 +08:00
Fine0830
2fca7a79a2
fix unit (#440) 2024-12-09 17:12:57 +08:00
Fine0830
f5cfb030a3
fix style (#439) 2024-12-04 10:29:30 +08:00
Fine0830
fbeeca8d9a
Fix Async Profiling widget (#438) 2024-12-03 19:16:51 +08:00
Fine0830
ea0f5e5f62
Feat: Polish Async profiling widget (#437) 2024-12-03 12:41:51 +08:00
Fine0830
8771ce4a19
refactor: polish Trace Profiling widget (#436) 2024-12-02 15:10:24 +08:00
Fine0830
99a2461734
update style (#435) 2024-11-28 21:35:44 +08:00
Fine0830
fb0817eed8
feat: implement Async Profiling widget (#434) 2024-11-28 17:50:43 +08:00
Fine0830
e164d87209
Fix: releases an existing object URL (#433) 2024-11-25 11:26:42 +08:00
Fine0830
5c92a46569
Refactor copy util with Web API (#432) 2024-11-24 17:25:13 +08:00
Zixin Zhou
aff69c057f
feat: Add support collapse span (#431) 2024-11-23 19:55:54 +08:00
Fine0830
7338cec6b4
fix metrics query (#430) 2024-11-22 15:53:37 +08:00
Fine0830
536df8c052
feat: Split topology metric query to avoid exceeding the maximum query complexity (#429) 2024-11-14 11:38:13 +08:00
Fine0830
64d4a2b59b
hide entrances to unrelated dashboards in topn list (#428) 2024-11-08 10:03:49 +08:00
Fine0830
6e1a6cf19b
fix (#427) 2024-11-07 12:41:19 +08:00
Fine0830
aeddb39637
feat: implement owner option for TopList widgets in related trace options (#426) 2024-11-07 10:31:06 +08:00
Fine0830
14fa5d65b6
feat: View data value related dashboards in TopList widgets (#425) 2024-11-05 11:21:08 +08:00
Fine0830
224e761d70
Fix initialization dashboards (#424) 2024-10-24 15:49:02 +08:00
Fine0830
4c60f69aef
Fix Value Mappings (#423) 2024-10-18 14:48:55 +08:00
Zixin Zhou
0007e3e3ae
Update mappingTip (#422) 2024-10-18 14:36:25 +08:00
Fine0830
b6522f4555
feat: support ranges for Value Mappings (#421) 2024-10-18 10:31:17 +08:00
Fine0830
bddbe40974
add duration (#420) 2024-10-16 10:26:45 +08:00
Fine0830
61449f4b17
feat: add content decorations to Table and Card widgets (#419) 2024-10-15 16:25:21 +08:00
Zixin Zhou
a92365efcf
feat: add support for case-insensitive search in the dashboard list (#418) 2024-10-07 23:14:22 +08:00
Fine0830
d65c18bd38
feat: add queries for alarm tags (#417) 2024-09-29 15:15:35 +08:00
dependabot[bot]
a5b0acda06
build(deps): bump rollup from 3.29.4 to 3.29.5 (#416) 2024-09-27 14:51:12 +08:00
Chen Ziyan
e251626374
feat: add skywalking java agent self observability menu (#415) 2024-09-15 00:25:40 +08:00
Fine0830
ed0ec0ac1f
fix pagination (#414) 2024-09-05 18:51:04 +08:00
Fine0830
1945f23419
fix selectors (#413) 2024-09-05 11:46:28 +08:00
Fine0830
d10f4ca0cc
add loading animations (#412) 2024-08-30 11:38:06 +08:00
Fine0830
a5073dd3d4
build(deps): bump up dependencies to fix CVEs (#408) 2024-08-26 12:13:03 +08:00
dependabot[bot]
ddcc49cb42
build(deps): bump axios and start-server-and-test (#411) 2024-08-26 10:34:10 +08:00
Fine0830
ae63538baf
feat: improve dashboard queries to make page opening brisker (#410) 2024-08-22 16:47:50 +08:00
Fine0830
d9f819d143
fix: correct services and instances when changing page numbers (#409) 2024-08-16 10:52:52 +08:00
Starry
3c8b316b76
feat: introduce flame graph to the trace profiling (#407) 2024-08-05 20:48:42 +08:00
Fine0830
6b2b6a5dd2
feat: set a maximum 20 entities per query in service/instance/endpoint list widgets (#406) 2024-07-30 20:44:55 +08:00
Fine0830
4e00073ec2
fix: highlight keywords in logs (#405) 2024-07-30 10:39:18 +08:00
Fine0830
8f179f00a2
feat: polish error nodes in trace widget (#404) 2024-07-17 00:02:08 -07:00
mrproliu
fe6e853c57
Adding cilium icon for hierarchy (#403) 2024-07-08 09:29:15 +08:00
mrproliu
f664e786ac
Adding cilium icon and i18n for menu (#402) 2024-06-28 17:17:23 +08:00
寻找的人
b6f57aa54e
Add a SolonMVC icon (#401) 2024-06-20 19:29:58 +08:00
dependabot[bot]
afb70a371b
build(deps-dev): bump ws from 8.11.0 to 8.17.1 (#400) 2024-06-18 10:17:20 +08:00
Starry
c35bdce399
fix: browser log (#399) 2024-06-04 08:51:43 +08:00
Starry
5419a69700
feat: highlight search log keywords (#398) 2024-06-02 18:33:43 +08:00
Fine0830
065337c344
Fix the topology layout for there are multiple independent network relationships (#397) 2024-05-24 17:15:31 +08:00
Starry
21fe455fd6
fix: browser log display (#396) 2024-05-21 23:11:23 +08:00
Starry
88dbee311c
fix: statistics span data (#395) 2024-05-18 13:45:02 +08:00
Fine0830
9001a96128
fix: widget title and tips (#394) 2024-05-11 13:44:11 +08:00
Fine0830
e4b2203cf6
fix: update (#393) 2024-04-19 15:54:17 +08:00
Chen Ziyan
54c236bacf
fix: optimize search reset and format in marketplace (#392) 2024-04-18 17:27:56 +08:00
Chen Ziyan
f001290658
docs: update img of ActiveMQ (#388) 2024-04-17 12:35:41 +08:00
Starry
13b2693f29
fix: css details (#391) 2024-04-17 09:53:43 +08:00
Fine0830
731d652a7d
fix: polish (#390) 2024-04-16 17:52:51 +08:00
Fine0830
7f6e4d09c0
Fix the Table widget (#389) 2024-04-16 15:00:18 +08:00
Fine0830
12cd279c90
Feat: enhance the Trace widget for batch consuming spans (#387) 2024-04-15 15:33:09 +08:00
Fine0830
62eb054ff5
fix: remove unused configurations (#386) 2024-04-12 18:08:47 +08:00
Fine0830
e0bbe99b6c
fix: remove metrics for unreal nodes (#385) 2024-04-12 13:25:34 +08:00
Fine0830
03f321b62a
refactor: remove the General metric mode and related logical code (#384) 2024-04-11 17:50:43 +08:00
Fine0830
460b24f42c
feat: support the SINGLE_VALUE for table widgets (#383) 2024-04-10 23:35:15 +08:00
Fine0830
fd2c7ca716
feat: enhance metric labels (#382) 2024-04-10 16:40:14 +08:00
Fine0830
8bc6761468
feat: add workflow icon (#381) 2024-04-06 19:44:58 +08:00
Starry
8746d3c985
feat: add Support for dragging in the trace panel (#377) 2024-04-06 19:17:17 +08:00
songzhendong
c18058765a
Add Airflow monitor (#379) 2024-04-06 19:14:24 +08:00
dependabot[bot]
b9e0eadecb
build(deps-dev): bump axios from 0.25.0 to 1.6.8 (#380) 2024-04-06 19:09:41 +08:00
dependabot[bot]
680f1263a5
build(deps-dev): bump vite from 4.5.2 to 4.5.3 (#378) 2024-04-06 19:00:30 +08:00
Chen Ziyan
0e0b4e1ff1
fix(doc): fix the dev local port (#375) 2024-03-12 18:11:50 +08:00
Fine0830
2faeecebcc
Fix: refresh nodes/calls metrics as global duration changes for Topology widget, change date picker theme (#374) 2024-03-04 11:48:55 +08:00
Fine0830
e25bf9ee8b
fix: end loading without query results (#373) 2024-02-26 19:57:02 +08:00
周小杰
d0ebdefcee
fix: remove click event after unmounted (#372) 2024-02-21 16:42:56 +08:00
peachisai
7342036646
Update i18n for rocketmq monitoring (#359) 2024-02-20 21:25:52 +08:00
Fine0830
8e58f000a0
refactor: change the nodes type for Hierarchy Topology (#371) 2024-02-02 11:50:43 +08:00
dependabot[bot]
931cea4c4c
build(deps-dev): bump vite from 4.0.5 to 4.5.2 (#366) 2024-01-31 12:37:37 +08:00
Fine0830
ccb4d78f6b
feat: add the layers filed and associate layers dashboards for the service topology nodes (#370) 2024-01-30 15:59:16 +08:00
Fine0830
860af150f7
fix: enhance VNode logic and support multiple Trace IDs in span's ref (#369) 2024-01-29 23:09:00 +08:00
Fine0830
7d24e065e9
feat: add the not found page (#368) 2024-01-24 16:09:15 +08:00
Fine0830
7aef327d2e
fix: resizing window causes the trace graph to display incorrectly (#367) 2024-01-22 22:07:03 +08:00
Fine0830
f76500bb6e
fix: optimize tooltips style (#365) 2024-01-18 11:43:07 +08:00
Fine0830
63e01540dc
fix: list (#364) 2024-01-17 12:21:07 +08:00
Fine0830
a46b91d1cf
fix: import dashboard templates (#363) 2024-01-16 18:23:55 +08:00
Fine0830
5061b19cf7
fix: polish the hierarchy topology and dashboard configs (#362) 2024-01-16 17:04:21 +08:00
Fine0830
f809123b4f
fix: link addresses on hierarchy topology nodes (#361) 2024-01-15 22:04:39 +08:00
Fine0830
306508856b
feat: implement the Service and Instance hierarchy topology. (#360) 2024-01-13 11:05:32 +08:00
Fine0830
867af6924d
feat: add expressions to dashboard configurations on the dashboard list page (#358) 2024-01-11 13:40:37 +08:00
dependabot[bot]
4ec99fc868
build(deps): bump follow-redirects from 1.15.2 to 1.15.4 (#357) 2024-01-10 17:55:48 +08:00
苗大
b5c135b811
perf(Theme): add theme change animation (#356) 2024-01-04 15:49:36 +08:00
Fine0830
300ec27ec4
feat: add isDefault to the dashboard configuration (#355) 2024-01-03 19:11:37 +08:00
何延龙
c5d80d96fb
fix: set default route (#354) 2023-12-26 19:56:42 +08:00
Fine0830
001fa25a3b
feat: support Tabs in the widget visiable when MQE expressions (#353) 2023-12-20 17:58:00 +08:00
Fine0830
0d82507a87
fix: span related logs (#352) 2023-12-05 20:09:23 -08:00
Fine0830
591484b11c
fix: Trace associates with Log widget (#351)
* fix: view logs on trace widget

* fix: service
2023-12-04 16:45:07 +08:00
Fine0830
b2ab93926d
feat: support search on Marketplace (#350) 2023-11-30 07:30:01 -08:00
Fine0830
a1c7a00a83
refactor: change router components (#349) 2023-11-27 21:08:19 -08:00
Fine0830
20e3ef12fe
style: add underline for text widget (#348) 2023-11-28 11:14:06 +08:00
block666
0ea95b1ca6
Remove the description of OpenFunction in the UI. (#347) 2023-11-27 07:50:05 -08:00
Fine0830
a18ac3372e
fix: change colors to match dark theme for Network Profiling (#346) 2023-11-26 04:02:41 -08:00
Fine0830
c1c086d999
fix: change metrics config, fix tab routes (#345) 2023-11-25 21:15:43 -08:00
Fine0830
ac57b229fc
feat: enhance topology layout and fix calls metrics (#344) 2023-11-23 16:37:26 +08:00
Fine0830
d8a3c27345
fix: Log associate with Trace (#343) 2023-11-22 13:03:59 +08:00
Rick
03e1508afc
feat: support to save and load theme setting from localStorage (#342) 2023-11-21 16:48:57 +08:00
Fine0830
8618a9440e
fix: polish list style (#341) 2023-11-21 11:24:27 +08:00
Fine0830
02c5724859
fix: change log widget and loading mask style (#340) 2023-11-17 13:16:48 +08:00
Fine0830
c6d1c49569
refactor: enhance the Log widget (#339) 2023-11-17 10:15:39 +08:00
weixiang1862
8f3ce7d371
feat: add Nginx menu i18n (#338) 2023-11-16 21:23:10 +08:00
Fine0830
2085dc84b9
fix: set the height for trace widget (#337) 2023-11-16 11:44:34 +08:00
Fine0830
a4271bb479
feat: enhance the Dark Theme (#336) 2023-11-15 19:53:23 +08:00
Fine0830
832dc1676b
feat: implement the Dark Theme (#334) 2023-11-14 20:37:15 +08:00
dependabot[bot]
780104c5d2
build(deps): bump axios from 0.24.0 to 1.6.0 (#335) 2023-11-11 17:41:00 +08:00
Fine0830
d86543aeed
refactor: update Logs view (#333)
New columns of the Log View
1. Timestamp + Raw log(content) as column one, 70% of the initial table width. No separate timestamp column. The first column should be timestamp - content
2. Level tag(key=level)'s value. This could be missed from tags, if so, keep the column empty.
3. Trace link. If trace ID exists, generate a link to trace. Don't need to put the relative trace ID in the text.
4. Still keep details pop-up style.
2023-11-01 22:45:45 +08:00
Fine0830
d2eae87957
feat: add a title and a description for trace segments (#332) 2023-10-23 17:42:02 +08:00
Fine0830
d9064e8b45
fix: avoid querying data with empty parameters (#331)
* fix: Avoid querying data with empty parameters
2023-10-23 10:37:43 +08:00
peachisai
6fb4f074c1
add a netty icon (#330) 2023-10-21 22:46:17 +08:00
Xiangying Meng
f88c8a9771
feat(pulsar): add new menu for pulsar monitoring (#329) 2023-10-21 16:45:57 +08:00
dependabot[bot]
1be2792ff4
build(deps): bump @cypress/request and cypress (#327) 2023-10-19 17:41:18 +08:00
dependabot[bot]
037c2bbb11
build(deps-dev): bump @babel/traverse from 7.22.5 to 7.23.2 (#326) 2023-10-19 17:34:55 +08:00
Fine0830
70063c376f
Fix tooltip style to support multiple metrics scrolling view in a metrics graph (#325) 2023-10-08 10:58:47 +08:00
zhourunjie1988
e42734ba80
fix: icons display in trace tree diagram (#324) 2023-09-26 17:20:05 +08:00
Fine0830
102436ca51
feat: add shortName for service (#323) 2023-09-20 21:16:41 +08:00
何延龙
d00fe6df9e
fix: the display height of the link tree structure (#322) 2023-09-20 15:50:45 +08:00
吴晟 Wu Sheng
6872ad5bf2
Update README.md (#321) 2023-09-20 12:19:20 +08:00
Fine0830
3dc929dd53
refactor: update pagination (#320) 2023-09-20 11:57:52 +08:00
Fine0830
310fff4b28
fix: independent widget duration (#319) 2023-09-19 17:47:59 +08:00
Zhu Wang
63e97edae7
feat(kafka): add new menu for kafka monitoring (#318) 2023-09-07 14:51:51 +08:00
Fine0830
56a02293cf
fix: update alerting detail style (#317) 2023-09-01 15:38:22 +08:00
Fine0830
b7115a4e47
fix: update Marketplace title and breadcrumb component style (#316) 2023-09-01 11:18:11 +08:00
Fine0830
6b1a2fa9f8
fix: update name (#315) 2023-08-31 18:12:22 +08:00
Fine0830
ce4608ad4b
fix: path (#314) 2023-08-30 20:05:59 +08:00
Fine0830
dce1035f2e
feat: implement a breadcrumb component as navigation (#313) 2023-08-30 19:06:40 +08:00
Fine0830
60a4232759
feat: implement MQE on topology widget (#312) 2023-08-22 23:34:16 +08:00
SimonHu1993
8c1ddb109c
fix: getEndpoints keyword blank (#310) 2023-08-09 09:56:32 +08:00
Fine0830
08db5a0440
fix: selector (#309) 2023-08-01 15:41:16 +08:00
Fine0830
344f2a6608
fix: cannot access uninitialized variable on Safari (#308) 2023-08-01 15:12:00 +08:00
lsq27
39c584bce6
fix: remove node-sass (#307) 2023-07-31 08:16:31 +08:00
lsq27
eb0b860c3a
fix: commit error on Windows (#306) 2023-07-30 16:07:14 +08:00
Fine0830
1e55eb2029
fix: polish names and descriptions on the marketplace page (#305) 2023-07-24 11:21:21 +08:00
block666
90505810ab
Fix Virtual_MQ spelling mistake (#304) 2023-07-22 12:09:19 -04:00
Fine0830
169793bdff
feat: use title instead of i18nKey for menus. (#303) 2023-07-21 23:06:31 -07:00
weixiang1862
3bdd1d1c67
feat: add MongoDB menu i18n(#11045) (#302) 2023-07-19 11:02:08 +08:00
pg.yang
7478ec85b1
fix: update multiple language titles of menus for more accurate/consistent (#301) 2023-07-16 21:45:07 +08:00
Fine0830
115deecff1
fix: set chart label (#300) 2023-07-15 23:45:09 +08:00
Fine0830
077b68ebbd
feat: menus support for multiple languages (#299) 2023-07-12 18:07:34 +08:00
Fine0830
5367af47c4
feat: enhance the marketplace page (#298) 2023-07-11 22:32:36 +08:00
Fine0830
a521e041a7
feat: Implement customize menus (#297) 2023-07-11 17:19:30 +08:00
Fine0830
64293da11c
fix: minTraceDuration and maxTraceDuration types (#295) 2023-07-05 14:57:33 +08:00
pw151294
30a9cb1c87
fix: init minTime to Infinity (#294) 2023-07-01 14:39:00 +08:00
Fine0830
9827b6766a
build: bump dependencies to fix vulnerabilities (#293) 2023-06-28 21:19:01 +08:00
Fine0830
9ac1265e7f
feat(style): add scss variables (#291) 2023-06-28 15:46:27 +08:00
Fine0830
63db3fbc2e
fix: update the title of instance list and notices in the continue profiling (#289) 2023-06-25 22:41:45 +08:00
Fine0830
cc367dd29c
fix: add a link to explain the expression metric, add units in the continue profiling widget (#288) 2023-06-21 18:08:47 +08:00
Fine0830
1ba56ca0cd
fix: calculate string width to set Tabs name width (#286) 2023-06-20 18:04:41 +08:00
292 changed files with 14525 additions and 14892 deletions

View File

@ -37,7 +37,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [18.x, 20.x, 22.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}

View File

@ -1,3 +1,4 @@
#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@ -17,7 +18,6 @@
# under the License.
#
#!/bin/sh
# shellcheck source=./_/husky.sh
. "$(dirname "$0")/_/husky.sh"

View File

@ -1,3 +1,4 @@
#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@ -17,7 +18,6 @@
# under the License.
#
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"

View File

@ -34,14 +34,15 @@ npm install
npm run dev
```
The default UI address is `http://localhost:8080`.
The default UI address is `http://localhost:3000`.
# Contact Us
- Submit an [issue](https://github.com/apache/skywalking/issues) if you face some issues. Submit a [discussion](https://github.com/apache/skywalking/discussions) if you want to propose new feature or have any question.
- Mailing list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe the mailing list.
- Join Slack. Send `Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
- QQ Group: 392443393, 901167865
- Mail list: **dev@skywalking.apache.org**. Mail to `dev-subscribe@skywalking.apache.org`, follow the reply to subscribe to the mail list.
- Send `Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
- For Chinese speaker, send `[CN] Request to join SkyWalking slack` mail to the mail list(`dev@skywalking.apache.org`), we will invite you in.
- Twitter, [ASFSkyWalking](https://twitter.com/AsfSkyWalking)
- [bilibili B 站 视频](https://space.bilibili.com/390683219)
# License

View File

@ -17,34 +17,10 @@
module.exports = {
ignores: [(commit) => commit.includes("init")],
extends: ["@commitlint/config-conventional"],
rules: {
"body-leading-blank": [2, "always"],
"footer-leading-blank": [1, "always"],
"header-max-length": [2, "always", 108],
"subject-empty": [2, "never"],
"type-empty": [2, "never"],
"subject-case": [0],
"type-enum": [
2,
"always",
[
"feat",
"fix",
"perf",
"style",
"docs",
"test",
"refactor",
"build",
"ci",
"chore",
"revert",
"wip",
"workflow",
"types",
"release",
],
],
},
};

13089
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "skywalking-booster-ui",
"version": "9.4.0",
"version": "10.2.0",
"private": true,
"scripts": {
"dev": "vite",
@ -18,41 +18,38 @@
"check-components-types": "if (! git diff --quiet -U0 ./src/types); then echo 'type files are not updated correctly'; git diff -U0 ./src/types; exit 1; fi"
},
"dependencies": {
"axios": "^0.24.0",
"d3": "^7.3.0",
"d3-flame-graph": "^4.1.3",
"d3-tip": "^0.9.1",
"echarts": "^5.2.2",
"element-plus": "^2.1.0",
"lodash": "^4.17.21",
"element-plus": "^2.9.4",
"monaco-editor": "^0.34.1",
"pinia": "^2.0.28",
"vis-timeline": "^7.5.1",
"vue": "^3.2.45",
"vue-grid-layout": "^3.0.0-beta1",
"vue-i18n": "^9.1.9",
"vue-i18n": "^9.14.3",
"vue-router": "^4.1.6",
"vue-types": "^4.1.1"
},
"devDependencies": {
"@commitlint/cli": "^17.3.0",
"@commitlint/config-conventional": "^17.3.0",
"@commitlint/cli": "^17.6.6",
"@commitlint/config-conventional": "^17.6.6",
"@rushstack/eslint-patch": "^1.1.4",
"@types/d3": "^7.1.0",
"@types/d3-tip": "^3.5.5",
"@types/echarts": "^4.9.12",
"@types/jsdom": "^20.0.1",
"@types/lodash": "^4.14.179",
"@types/node": "^18.11.12",
"@types/three": "^0.131.0",
"@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^11.0.0",
"@vue/test-utils": "^2.2.6",
"@vue/tsconfig": "^0.1.3",
"@vueuse/core": "^9.6.0",
"cypress": "^12.0.2",
"cypress": "^13.3.2",
"eslint": "^8.22.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-vue": "^9.3.0",
@ -60,26 +57,25 @@
"jsdom": "^20.0.3",
"lint-staged": "^13.2.1",
"mockjs": "^1.1.0",
"node-sass": "^8.0.0",
"npm-run-all": "^4.1.5",
"postcss-html": "^1.3.0",
"postcss-scss": "^4.0.2",
"prettier": "^2.7.1",
"sass": "^1.56.1",
"start-server-and-test": "^1.15.2",
"stylelint": "^15.6.0",
"sass": "^1.85.0",
"start-server-and-test": "^2.0.5",
"stylelint": "15.9.0",
"stylelint-config-html": "^1.0.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-prettier": "9.0.4",
"stylelint-config-standard": "^33.0.0",
"stylelint-order": "^6.0.3",
"typescript": "~4.7.4",
"unplugin-auto-import": "^0.7.0",
"unplugin-vue-components": "^0.19.2",
"vite": "^4.0.5",
"typescript": "^5.7.3",
"unplugin-auto-import": "^0.18.2",
"unplugin-vue-components": "^0.27.3",
"vite": "^6.3.4",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-svg-icons": "^2.0.1",
"vitest": "^0.25.6",
"vue-tsc": "^1.0.12"
"vitest": "^3.0.5",
"vue-tsc": "^2.2.2"
},
"browserslist": [
"> 1%",
@ -99,10 +95,7 @@
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
"prettier --write"
],
"package.json": [
"prettier --write"
],
"*.md": [
"package.json, *.md": [
"prettier --write"
]
}

View File

@ -27,10 +27,11 @@ limitations under the License. -->
}
}, 500);
</script>
<style>
<style lang="scss">
#app {
color: #2c3e50;
color: $font-color;
height: 100%;
overflow: hidden;
background-color: $layout-background;
}
</style>

View File

@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg t="1655799536378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9286" width="48" height="48"><path d="M563.2 614.4v51.2c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2v-51.2H409.6c-30.72 0-51.2-20.48-51.2-51.2s20.48-51.2 51.2-51.2h51.2V460.8c0-30.72 20.48-51.2 51.2-51.2s51.2 20.48 51.2 51.2v51.2h51.2c30.72 0 51.2 20.48 51.2 51.2s-20.48 51.2-51.2 51.2h-51.2z m51.2-563.2c158.72 15.36 281.6 143.36 281.6 307.2v512c0 56.32-46.08 102.4-102.4 102.4h-563.2c-56.32 0-102.4-46.08-102.4-102.4V153.6c0-56.32 46.08-102.4 102.4-102.4H614.4z m163.84 230.4c-25.6-61.44-76.8-107.52-138.24-122.88v71.68c0 30.72 20.48 51.2 51.2 51.2h87.04zM537.6 153.6h-256c-30.72 0-51.2 20.48-51.2 51.2v614.4c0 30.72 20.48 51.2 51.2 51.2h460.8c30.72 0 51.2-20.48 51.2-51.2V384h-153.6c-56.32 0-102.4-46.08-102.4-102.4V153.6z" fill="#707070" p-id="9287"></path></svg>
<svg t="1655799536378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9286" width="48" height="48"><path d="M563.2 614.4v51.2c0 30.72-20.48 51.2-51.2 51.2s-51.2-20.48-51.2-51.2v-51.2H409.6c-30.72 0-51.2-20.48-51.2-51.2s20.48-51.2 51.2-51.2h51.2V460.8c0-30.72 20.48-51.2 51.2-51.2s51.2 20.48 51.2 51.2v51.2h51.2c30.72 0 51.2 20.48 51.2 51.2s-20.48 51.2-51.2 51.2h-51.2z m51.2-563.2c158.72 15.36 281.6 143.36 281.6 307.2v512c0 56.32-46.08 102.4-102.4 102.4h-563.2c-56.32 0-102.4-46.08-102.4-102.4V153.6c0-56.32 46.08-102.4 102.4-102.4H614.4z m163.84 230.4c-25.6-61.44-76.8-107.52-138.24-122.88v71.68c0 30.72 20.48 51.2 51.2 51.2h87.04zM537.6 153.6h-256c-30.72 0-51.2 20.48-51.2 51.2v614.4c0 30.72 20.48 51.2 51.2 51.2h460.8c30.72 0 51.2-20.48 51.2-51.2V384h-153.6c-56.32 0-102.4-46.08-102.4-102.4V153.6z" p-id="9287"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M856.32 428.064a32 32 0 0 0-32 32v163.328H372.48c-0.896 0-1.664 0.448-2.56 0.512v-177.696h244.48a32 32 0 1 0 0-64H130.56c-0.896 0-1.664 0.448-2.56 0.512V231.68h488.16a32 32 0 1 0 0-64H96a32 32 0 0 0-32 32v701.824a32 32 0 0 0 32 32h760.32a32 32 0 0 0 32-32V460.064a32 32 0 0 0-32-32zM128 445.728c0.896 0.064 1.664 0.512 2.56 0.512h175.36v423.264H128V445.728z m241.92 423.776v-182.624c0.896 0.064 1.664 0.512 2.56 0.512h451.84v182.08h-454.4zM960 174.656h-61.376V113.28a32 32 0 1 0-64 0v61.344H752.64a32 32 0 1 0 0 64h81.984v81.984a32 32 0 1 0 64 0V238.656H960a32 32 0 1 0 0-64z" fill="#2c2c2c"></path></svg>
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32"><path d="M856.32 428.064a32 32 0 0 0-32 32v163.328H372.48c-0.896 0-1.664 0.448-2.56 0.512v-177.696h244.48a32 32 0 1 0 0-64H130.56c-0.896 0-1.664 0.448-2.56 0.512V231.68h488.16a32 32 0 1 0 0-64H96a32 32 0 0 0-32 32v701.824a32 32 0 0 0 32 32h760.32a32 32 0 0 0 32-32V460.064a32 32 0 0 0-32-32zM128 445.728c0.896 0.064 1.664 0.512 2.56 0.512h175.36v423.264H128V445.728z m241.92 423.776v-182.624c0.896 0.064 1.664 0.512 2.56 0.512h451.84v182.08h-454.4zM960 174.656h-61.376V113.28a32 32 0 1 0-64 0v61.344H752.64a32 32 0 1 0 0 64h81.984v81.984a32 32 0 1 0 64 0V238.656H960a32 32 0 1 0 0-64z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,18 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M512 992c-83.2 0-166.4-19.2-243.2-64-89.6-51.2-160-134.4-204.8-230.4C25.6 601.6 19.2 486.4 51.2 390.4c25.6-102.4 89.6-192 172.8-256C307.2 70.4 409.6 38.4 518.4 38.4c19.2 0 32 12.8 32 32s-19.2 25.6-38.4 25.6c-89.6 0-179.2 32-256 83.2S128 313.6 108.8 403.2s-12.8 185.6 19.2 268.8c32 83.2 96 153.6 179.2 198.4 76.8 44.8 172.8 64 262.4 51.2 89.6-12.8 172.8-51.2 236.8-115.2s108.8-147.2 115.2-236.8c12.8-89.6-6.4-185.6-51.2-262.4-6.4-12.8-6.4-32 12.8-44.8 12.8-12.8 38.4-6.4 44.8 12.8 51.2 89.6 76.8 198.4 57.6 300.8-12.8 102.4-64 204.8-134.4 275.2-76.8 76.8-172.8 121.6-275.2 134.4-19.2 6.4-44.8 6.4-64 6.4z" p-id="8538"></path><path d="M512 480c-19.2 0-32-12.8-32-32V64c0-19.2 12.8-32 32-32s32 12.8 32 32v384c0 19.2-12.8 32-32 32z" p-id="8539"></path><path d="M512 608c-12.8 0-25.6 0-38.4-6.4-12.8-6.4-19.2-12.8-32-19.2-6.4-12.8-12.8-19.2-19.2-32-6.4-12.8-6.4-25.6-6.4-38.4 0-25.6 12.8-51.2 25.6-70.4 38.4-38.4 102.4-38.4 134.4 0 19.2 19.2 32 44.8 32 70.4 0 25.6-12.8 51.2-25.6 70.4-19.2 12.8-44.8 25.6-70.4 25.6z m0-128c-6.4 0-19.2 6.4-25.6 6.4 0 6.4-6.4 19.2-6.4 25.6v12.8c0 6.4 6.4 6.4 6.4 12.8 0 0 6.4 6.4 12.8 6.4 12.8 6.4 25.6 0 32-6.4 6.4-6.4 12.8-19.2 12.8-25.6 0-6.4-6.4-19.2-6.4-25.6-6.4 0-19.2-6.4-25.6-6.4z" p-id="8540"></path><path d="M512 800c-51.2 0-102.4-12.8-147.2-38.4-57.6-32-96-83.2-121.6-140.8-19.2-57.6-25.6-121.6-6.4-185.6 19.2-64 51.2-115.2 102.4-153.6C384 243.2 448 224 512 224c19.2 0 32 12.8 32 32s-12.8 32-32 32c-51.2 0-96 19.2-134.4 44.8-38.4 32-70.4 76.8-83.2 121.6s-6.4 96 12.8 140.8c19.2 44.8 51.2 83.2 96 108.8 44.8 25.6 89.6 32 140.8 25.6 51.2-6.4 96-32 128-64s57.6-83.2 64-128c6.4-51.2-6.4-96-25.6-140.8-12.8-12.8-6.4-32 6.4-38.4 12.8-6.4 32-6.4 44.8 12.8 32 57.6 44.8 121.6 38.4 179.2-6.4 64-38.4 121.6-83.2 166.4-44.8 44.8-102.4 76.8-166.4 83.2H512z"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,17 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M18.984 18q1.219 0 2.109-0.891t0.891-2.109-0.891-2.109-2.109-0.891h-1.5v-0.516q0-2.297-1.594-3.891t-3.891-1.594q-1.875 0-3.328 1.125t-1.969 2.859h-0.703q-1.641 0-2.813 1.195t-1.172 2.836 1.172 2.813 2.813 1.172h12.984zM19.359 10.031q1.922 0.141 3.281 1.57t1.359 3.398q0 2.063-1.477 3.539t-3.539 1.477h-12.984q-2.484 0-4.242-1.758t-1.758-4.242q0-2.203 1.57-3.961t3.773-1.992q0.984-1.828 2.766-2.953t3.891-1.125q2.531 0 4.711 1.781t2.648 4.266z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,17 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M16.359 14.016h3.375q0.281-1.313 0.281-2.016t-0.281-2.016h-3.375q0.141 0.984 0.141 2.016t-0.141 2.016zM14.578 19.547q1.172-0.375 2.438-1.43t1.922-2.133h-2.953q-0.469 1.875-1.406 3.563zM14.344 14.016q0.141-0.984 0.141-2.016t-0.141-2.016h-4.688q-0.141 0.984-0.141 2.016t0.141 2.016h4.688zM12 19.969q1.313-1.922 1.922-3.984h-3.844q0.609 2.063 1.922 3.984zM8.016 8.016q0.563-2.016 1.406-3.563-1.172 0.375-2.461 1.43t-1.898 2.133h2.953zM5.063 15.984q0.609 1.078 1.898 2.133t2.461 1.43q-0.938-1.688-1.406-3.563h-2.953zM4.266 14.016h3.375q-0.141-0.984-0.141-2.016t0.141-2.016h-3.375q-0.281 1.313-0.281 2.016t0.281 2.016zM12 4.031q-1.313 1.922-1.922 3.984h3.844q-0.609-2.063-1.922-3.984zM18.938 8.016q-0.656-1.078-1.922-2.133t-2.438-1.43q0.844 1.547 1.406 3.563h2.953zM12 2.016q4.125 0 7.055 2.93t2.93 7.055-2.93 7.055-7.055 2.93-7.055-2.93-2.93-7.055 2.93-7.055 7.055-2.93z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,16 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg width="16" height="16" viewBox="20 0 70 72" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m49.72 45.923-5.505-9.69 5.505-9.69h10.974l5.506 9.69-5.506 9.69H49.72ZM49.72 69.367l-5.505-9.69 5.505-9.689h10.974l5.506 9.69-5.506 9.69H49.72ZM49.72 22.477l-5.505-9.689 5.505-9.69h10.974l5.506 9.69-5.506 9.69H49.72ZM70.06 57.644l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H70.06ZM70.06 34.2l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H70.06ZM29.357 57.644l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H29.357ZM29.357 34.2l-5.506-9.69 5.506-9.69h10.974l5.506 9.69-5.506 9.69H29.357Z" stroke="#141A1F" stroke-width="2.771"/><path d="M10.784 95.947c1.026.007 " fill="#141A1F"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,38 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg width="2400" height="2400" viewBox="0 0 200 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrowhead" markerWidth="8" markerHeight="8" refX="2" refY="2.5" orient="auto">
<polygon points="0 0, 3 2.5, 0 5" fill="white" />
</marker>
</defs>
<line x1="0" y1="20" x2="42" y2="20" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
<line x1="0" y1="50" x2="42" y2="50" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
<line x1="0" y1="80" x2="42" y2="80" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
<line x1="49" y1="10" x2="139" y2="10" stroke="white" stroke-width="7" />
<line x1="49" y1="90" x2="139" y2="90" stroke="white" stroke-width="7" />
<line x1="49" y1="10" x2="50" y2="90" stroke="white" stroke-width="7" />
<ellipse cx="140" cy="50" rx="10" ry="40" fill="none" stroke="white" stroke-width="7" />
<line x1="147" y1="20" x2="190" y2="20" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
<line x1="149" y1="50" x2="190" y2="50" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
<line x1="147" y1="80" x2="190" y2="80" stroke="white" stroke-width="7" marker-end="url(#arrowhead)" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,17 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M3.984 11.016v1.969h2.016v-1.969h-2.016zM2.016 14.016v-4.031h19.969v4.031h-19.969zM6 6.984v-1.969h-2.016v1.969h2.016zM2.016 3.984h19.969v4.031h-19.969v-4.031zM3.984 17.016v1.969h2.016v-1.969h-2.016zM2.016 20.016v-4.031h19.969v4.031h-19.969z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -13,4 +13,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg t="1654161407133" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1721" width="16" height="16"><path d="M804.224 86.144c0-19.264-15.616-34.944-34.944-34.944l-734.336 0c-19.264 0-34.944 15.68-34.944 34.944l0 82.048 804.224 0 0-82.048zM738.88 602.432c0 47.072-38.176 85.248-85.248 85.248s-85.248-38.176-85.248-85.248c0-47.072 38.176-85.248 85.248-85.248s85.248 38.176 85.248 85.248zM804.992 264.64l0-62.976-804.224 0 0 665.408c0 18.56 14.656 33.472 32.96 34.56l402.24 0c61.12 44.544 136.192 71.168 217.664 71.168 204.544 0 370.368-165.824 370.368-370.368 0-150.592-89.984-279.936-219.008-337.792zM412.096 298.24l30.528 0c-10.624 7.36-20.8 15.36-30.528 23.744l0-23.744zM63.04 298.24l153.024 0 0 153.024-153.024 0 0-153.024zM216.064 805.056l-153.024 0 0-153.024 153.024 0 0 153.024zM219.136 631.232l-153.024 0 0-153.024 153.024 0 0 153.024zM237.568 805.056l0-153.024 49.408 0c7.488 55.936 27.264 107.904 56.832 153.024l-106.24 0zM284.672 631.232l-44.032 0 0-153.024 64.384 0c-13.824 38.848-21.824 80.576-21.824 124.224 0 9.728 0.768 19.264 1.472 28.8zM390.592 341.76c-31.168 31.424-56.512 68.544-74.88 109.44l-78.144 0 0-152.96 153.024 0 0 43.52zM899.136 638.4l-63.36 12.864c-4.288 16.064-10.688 31.296-18.816 45.376l35.712 53.888-50.944 50.944-53.888-35.712c-14.08 8.128-29.312 14.528-45.376 18.816l-12.864 63.36-72 0-12.864-63.36c-16.064-4.288-31.296-10.688-45.376-18.816l-53.888 35.712-50.944-50.944 35.712-53.888c-8.128-14.08-14.528-29.312-18.816-45.376l-63.36-12.864 0-72 63.36-12.864c4.352-16.064 10.688-31.296 18.816-45.312l-35.712-53.952 50.944-50.944 53.888 35.776c14.08-8.128 29.312-14.464 45.376-18.816l12.864-63.36 72 0 12.864 63.36c16.064 4.288 31.296 10.688 45.376 18.816l53.888-35.712 50.944 50.944-35.712 53.824c8.128 14.08 14.528 29.312 18.816 45.376l63.36 12.864 0 72z" p-id="1722" fill="#707070"></path></svg>
<svg t="1654161407133" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1721" width="16" height="16"><path d="M804.224 86.144c0-19.264-15.616-34.944-34.944-34.944l-734.336 0c-19.264 0-34.944 15.68-34.944 34.944l0 82.048 804.224 0 0-82.048zM738.88 602.432c0 47.072-38.176 85.248-85.248 85.248s-85.248-38.176-85.248-85.248c0-47.072 38.176-85.248 85.248-85.248s85.248 38.176 85.248 85.248zM804.992 264.64l0-62.976-804.224 0 0 665.408c0 18.56 14.656 33.472 32.96 34.56l402.24 0c61.12 44.544 136.192 71.168 217.664 71.168 204.544 0 370.368-165.824 370.368-370.368 0-150.592-89.984-279.936-219.008-337.792zM412.096 298.24l30.528 0c-10.624 7.36-20.8 15.36-30.528 23.744l0-23.744zM63.04 298.24l153.024 0 0 153.024-153.024 0 0-153.024zM216.064 805.056l-153.024 0 0-153.024 153.024 0 0 153.024zM219.136 631.232l-153.024 0 0-153.024 153.024 0 0 153.024zM237.568 805.056l0-153.024 49.408 0c7.488 55.936 27.264 107.904 56.832 153.024l-106.24 0zM284.672 631.232l-44.032 0 0-153.024 64.384 0c-13.824 38.848-21.824 80.576-21.824 124.224 0 9.728 0.768 19.264 1.472 28.8zM390.592 341.76c-31.168 31.424-56.512 68.544-74.88 109.44l-78.144 0 0-152.96 153.024 0 0 43.52zM899.136 638.4l-63.36 12.864c-4.288 16.064-10.688 31.296-18.816 45.376l35.712 53.888-50.944 50.944-53.888-35.712c-14.08 8.128-29.312 14.528-45.376 18.816l-12.864 63.36-72 0-12.864-63.36c-16.064-4.288-31.296-10.688-45.376-18.816l-53.888 35.712-50.944-50.944 35.712-53.888c-8.128-14.08-14.528-29.312-18.816-45.376l-63.36-12.864 0-72 63.36-12.864c4.352-16.064 10.688-31.296 18.816-45.312l-35.712-53.952 50.944-50.944 53.888 35.776c14.08-8.128 29.312-14.464 45.376-18.816l12.864-63.36 72 0 12.864 63.36c16.064 4.288 31.296 10.688 45.376 18.816l53.888-35.712 50.944 50.944-35.712 53.824c8.128 14.08 14.528 29.312 18.816 45.376l63.36 12.864 0 72z" p-id="1722"></path></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -12,4 +12,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg t="1655695739627" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2218" width="48" height="48"><path d="M173.292308 177.230769C86.646154 265.846154 39.384615 382.030769 39.384615 504.123077 39.384615 531.692308 61.046154 551.384615 86.646154 551.384615s47.261538-21.661538 47.261538-47.261538c-1.969231-96.492308 37.415385-189.046154 106.338462-257.969231s163.446154-106.338462 257.969231-106.338461c27.569231 0 47.261538-21.661538 47.261538-47.261539 0-27.569231-21.661538-47.261538-47.261538-47.261538C378.092308 43.323077 259.938462 90.584615 173.292308 177.230769z m57.107692 326.892308c0 27.569231 19.692308 47.261538 47.261538 47.261538s47.261538-21.661538 47.261539-47.261538c0-45.292308 17.723077-90.584615 51.2-122.092308 33.476923-33.476923 76.8-49.230769 122.092308-51.2 27.569231 0 47.261538-21.661538 47.261538-47.261538 0-27.569231-19.692308-47.261538-47.261538-47.261539-70.892308 0-139.815385 27.569231-191.015385 76.8-7.876923 9.846154-80.738462 82.707692-76.8 191.015385z m665.6-204.8c-17.723077-23.630769-41.353846-51.2-45.292308-55.138462-5.907692-3.938462-13.784615-7.876923-21.661538-7.876923-7.876923 0-15.753846 1.969231-19.692308 7.876923L610.461538 441.107692c-47.261538-39.384615-118.153846-37.415385-163.446153 7.876923-45.292308 45.292308-47.261538 116.184615-7.876923 163.446154l-191.015385 191.015385c-5.907692 5.907692-9.846154 13.784615-9.846154 21.661538 0 9.846154 3.938462 19.692308 11.815385 25.6l53.16923 39.384616c72.861538 57.107692 163.446154 88.615385 259.938462 88.615384 232.369231 0 421.415385-189.046154 421.415385-421.415384 0-94.523077-33.476923-185.107692-88.615385-257.969231z" p-id="2219" fill="#707070"></path></svg>
<svg t="1655695739627" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2218" width="48" height="48"><path d="M173.292308 177.230769C86.646154 265.846154 39.384615 382.030769 39.384615 504.123077 39.384615 531.692308 61.046154 551.384615 86.646154 551.384615s47.261538-21.661538 47.261538-47.261538c-1.969231-96.492308 37.415385-189.046154 106.338462-257.969231s163.446154-106.338462 257.969231-106.338461c27.569231 0 47.261538-21.661538 47.261538-47.261539 0-27.569231-21.661538-47.261538-47.261538-47.261538C378.092308 43.323077 259.938462 90.584615 173.292308 177.230769z m57.107692 326.892308c0 27.569231 19.692308 47.261538 47.261538 47.261538s47.261538-21.661538 47.261539-47.261538c0-45.292308 17.723077-90.584615 51.2-122.092308 33.476923-33.476923 76.8-49.230769 122.092308-51.2 27.569231 0 47.261538-21.661538 47.261538-47.261538 0-27.569231-19.692308-47.261538-47.261538-47.261539-70.892308 0-139.815385 27.569231-191.015385 76.8-7.876923 9.846154-80.738462 82.707692-76.8 191.015385z m665.6-204.8c-17.723077-23.630769-41.353846-51.2-45.292308-55.138462-5.907692-3.938462-13.784615-7.876923-21.661538-7.876923-7.876923 0-15.753846 1.969231-19.692308 7.876923L610.461538 441.107692c-47.261538-39.384615-118.153846-37.415385-163.446153 7.876923-45.292308 45.292308-47.261538 116.184615-7.876923 163.446154l-191.015385 191.015385c-5.907692 5.907692-9.846154 13.784615-9.846154 21.661538 0 9.846154 3.938462 19.692308 11.815385 25.6l53.16923 39.384616c72.861538 57.107692 163.446154 88.615385 259.938462 88.615384 232.369231 0 421.415385-189.046154 421.415385-421.415384 0-94.523077-33.476923-185.107692-88.615385-257.969231z" p-id="2219"></path></svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,16 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/chart</title><path d="M5.55 3.824L6.853 5.78a.3.3 0 0 0 .384.102l1.526-.764a.3.3 0 0 1 .384.102l1.65 2.476a.3.3 0 0 0 .462.045l1.229-1.229a.3.3 0 0 1 .512.212v4.243H5V3.99a.3.3 0 0 1 .55-.167zM13 12a1 1 0 0 1 0 2H3.833A1.833 1.833 0 0 1 2 12.167V3a1 1 0 1 1 2 0v9h9z" id="a"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,18 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg t="1704964118567" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5167">
<path d="M900.032 646.016h-56.064V502.976a16 16 0 0 0-16-16H544v-96h62.976c22.144 0 40-17.92 40-40V161.024a40 40 0 0 0-40-40H417.024a40 40 0 0 0-40 40v189.952c0 22.144 17.92 40 40 40H480v96H195.968a16 16 0 0 0-16 16v143.04h-55.936a38.016 38.016 0 0 0-38.016 38.016v176c0 20.928 17.024 37.952 37.952 37.952h176a38.016 38.016 0 0 0 38.016-38.016v-176a38.016 38.016 0 0 0-37.952-37.952h-56V550.976H480v95.04h-56a38.016 38.016 0 0 0-38.016 38.016v176c0 20.928 17.024 37.952 38.016 37.952h176a38.016 38.016 0 0 0 38.016-38.016v-176a38.016 38.016 0 0 0-38.016-37.952H544V550.976h236.032v95.04h-56.064a38.016 38.016 0 0 0-37.952 38.016v176c0 20.928 17.024 37.952 38.016 37.952h176a38.016 38.016 0 0 0 37.952-38.016v-176a38.016 38.016 0 0 0-38.016-37.952zM440.96 184.96h141.952v141.952H441.024V185.024zM278.016 838.016H145.92V705.92h132.032v132.032z m299.968 0H446.08V705.92H577.92v132.032z m300.032 0h-132.032V705.92h132.032v132.032z" p-id="5168"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,18 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>scatter_plot</title>
<path d="M13.594 17.578q0-1.219 0.891-2.109t2.109-0.891 2.109 0.891 0.891 2.109-0.891 2.109-2.109 0.891-2.109-0.891-0.891-2.109zM8.016 6q0-1.219 0.891-2.109t2.109-0.891 2.109 0.891 0.891 2.109-0.891 2.109-2.109 0.891-2.109-0.891-0.891-2.109zM3.984 14.016q0-1.219 0.891-2.109t2.109-0.891 2.109 0.891 0.891 2.109-0.891 2.109-2.109 0.891-2.109-0.891-0.891-2.109z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,17 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M12.984 14.859q1.266-0.375 1.875-1.875h7.125q-0.375 3.609-2.836 6.141t-6.164 2.859v-7.125zM14.859 11.016q-0.563-1.5-1.875-1.875v-7.125q3.703 0.328 6.164 2.859t2.836 6.141h-7.125zM11.016 9.141q-0.797 0.328-1.406 1.125t-0.609 1.734 0.609 1.734 1.406 1.125v7.125q-3.797-0.375-6.398-3.234t-2.602-6.75 2.602-6.75 6.398-3.234v7.125z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,138 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400.000000 400.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,400.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1737 3725 c-379 -61 -696 -224 -968 -495 -249 -248 -403 -533 -481
-890 -20 -93 -22 -133 -22 -340 0 -207 2 -247 22 -339 48 -217 123 -407 231
-581 253 -406 658 -688 1141 -791 91 -20 135 -23 330 -24 172 0 246 4 315 17
361 69 669 231 926 487 271 272 438 604 494 983 23 154 16 448 -15 593 -147
694 -668 1214 -1366 1365 -130 29 -472 37 -607 15z m461 -131 c24 -3 52 -14
63 -25 23 -23 25 -76 3 -100 -15 -17 -15 -19 0 -34 25 -26 20 -82 -10 -112
-25 -25 -28 -25 -112 -19 -48 4 -88 8 -89 10 -1 1 4 60 12 131 8 72 15 137 15
145 0 17 14 17 118 4z m-359 -30 c30 -22 61 -89 61 -137 0 -48 -22 -102 -48
-116 -23 -12 -163 -43 -169 -38 -7 7 -53 280 -48 285 8 9 78 20 130 21 32 1
59 -5 74 -15z m564 -8 c7 -8 22 -44 31 -80 l18 -66 62 48 c48 38 66 47 85 43
23 -6 18 -12 -58 -71 -76 -61 -83 -69 -98 -122 -12 -43 -21 -58 -34 -58 -28 0
-30 14 -10 73 l19 56 -29 93 c-16 51 -29 94 -29 96 0 8 31 0 43 -12z m-858
-45 c0 -8 -30 -27 -69 -43 -38 -15 -71 -30 -74 -32 -4 -4 17 -76 22 -76 1 0
31 11 66 25 76 30 90 31 90 7 0 -13 -19 -24 -70 -42 -61 -21 -69 -27 -64 -45
15 -46 24 -65 32 -65 5 0 42 14 82 30 57 23 75 27 82 18 4 -7 8 -16 8 -19 0
-7 -180 -79 -197 -79 -6 0 -28 44 -49 98 -20 53 -43 112 -51 131 -7 19 -11 36
-9 38 10 11 173 71 186 70 8 -1 15 -9 15 -16z m-257 -157 c26 -29 28 -61 6
-92 -12 -17 -12 -22 -2 -22 7 0 42 -13 77 -29 62 -28 63 -29 41 -44 -21 -15
-26 -14 -59 2 -20 10 -53 24 -73 30 -37 12 -37 13 -96 -25 -2 -1 13 -27 32
-58 34 -52 35 -56 17 -65 -17 -10 -27 2 -92 101 -39 62 -74 119 -76 128 -2 9
14 26 44 44 119 73 138 76 181 30z m-292 -145 c3 -6 -19 -37 -52 -70 l-58 -59
29 -30 29 -30 56 55 c48 47 59 54 69 42 10 -12 2 -24 -44 -68 l-56 -52 32 -33
32 -33 64 59 c52 47 68 57 78 47 11 -10 -1 -27 -66 -92 l-80 -80 -99 105 c-55
58 -100 108 -100 111 0 10 139 139 150 139 5 0 12 -5 16 -11z m1197 -44 c494
-74 896 -467 982 -959 19 -113 19 -299 0 -410 -73 -416 -377 -773 -776 -910
-142 -48 -213 -59 -384 -59 -175 -1 -241 10 -400 65 -383 131 -680 481 -761
893 -22 115 -20 335 5 450 79 372 314 669 656 831 214 102 441 135 678 99z
m-1319 -258 c81 -91 95 -110 86 -126 -9 -18 -14 -18 -122 16 -62 19 -117 38
-123 41 -10 6 17 -27 109 -133 41 -46 48 -60 39 -73 -13 -20 0 -23 -160 28
-89 28 -133 47 -133 56 0 28 27 25 134 -15 73 -26 103 -34 94 -23 -7 9 -43 50
-80 91 -55 61 -65 78 -57 93 13 25 30 23 147 -15 l103 -33 -82 82 c-67 67 -80
85 -74 103 4 12 10 21 14 19 4 -2 51 -51 105 -111z m2502 -151 c38 -38 44 -77
19 -126 -19 -37 -43 -50 -95 -50 -61 0 -100 41 -100 105 0 40 5 52 31 76 46
42 99 41 145 -5z m-2677 -171 c16 -8 41 -29 56 -47 24 -29 27 -38 23 -91 -4
-54 -8 -63 -41 -93 -32 -30 -44 -34 -90 -34 -126 0 -200 102 -150 207 9 20 30
44 47 54 38 23 115 25 155 4z m-145 -306 c35 -16 50 -59 42 -124 l-6 -54 32
-5 c18 -3 44 -7 58 -8 19 -2 24 -8 22 -23 -2 -11 -5 -21 -6 -22 -5 -6 -272 30
-280 37 -5 5 -4 42 3 87 9 63 16 82 37 101 28 24 60 28 98 11z m2717 -590 c14
-7 18 -16 14 -27 -4 -9 -20 -52 -36 -95 l-29 -78 33 -13 c77 -32 72 -34 105
51 29 75 55 102 67 70 3 -7 -7 -48 -24 -90 l-29 -76 55 -21 c30 -11 58 -18 62
-15 5 2 23 45 41 95 31 87 41 99 68 82 10 -7 2 -36 -32 -126 -25 -65 -47 -120
-49 -123 -3 -2 -82 26 -177 62 -95 36 -175 65 -177 65 -9 0 1 33 39 137 24 62
44 113 46 113 2 0 12 -5 23 -11z m34 -411 c80 -57 145 -106 145 -109 0 -3 -6
-14 -14 -24 -13 -18 -17 -16 -79 28 -36 26 -69 47 -74 47 -10 0 -113 -145
-113 -158 0 -7 61 -53 122 -93 14 -9 -11 -52 -26 -46 -10 4 -288 198 -304 212
-6 5 18 45 26 45 5 0 36 -21 71 -46 34 -25 64 -44 65 -42 1 2 25 35 52 73 28
39 53 75 57 81 4 7 -18 29 -58 55 -35 24 -65 49 -65 55 0 16 23 35 38 29 7 -2
78 -51 157 -107z m-2350 -142 c35 -15 65 -59 65 -96 0 -54 -57 -110 -112 -110
-13 0 -37 9 -55 20 -69 41 -63 154 9 185 42 18 51 18 93 1z m2003 -75 c8 -5
12 -17 10 -27 -3 -14 -11 -18 -33 -17 -82 7 -145 -48 -145 -126 0 -89 73 -161
162 -161 43 0 54 4 84 34 27 27 34 42 34 74 0 32 4 41 22 45 29 8 38 1 38 -31
-1 -38 -32 -102 -66 -133 -75 -69 -196 -57 -276 28 -27 28 -58 99 -58 132 0
65 56 152 115 177 34 15 94 18 113 5z m-247 -340 c79 -74 145 -138 147 -142 2
-4 -7 -13 -19 -19 -19 -11 -26 -7 -65 31 l-43 42 -68 -31 -68 -32 -3 -64 c-2
-55 -6 -66 -23 -71 -11 -4 -23 -5 -25 -2 -3 2 -9 94 -14 203 -8 180 -7 200 8
212 9 7 19 11 23 10 4 -2 71 -63 150 -137z m-321 34 c58 -30 78 -120 40 -182
-19 -31 -48 -44 -151 -67 l-26 -6 14 -60 c15 -68 12 -80 -20 -80 -20 0 -24 12
-56 173 -19 94 -36 179 -38 188 -4 12 11 19 64 31 90 20 138 21 173 3z m-334
-207 c38 -105 71 -195 72 -200 2 -4 -10 -8 -26 -8 -28 0 -32 5 -49 58 l-20 57
-79 3 -79 3 -27 -54 c-24 -49 -29 -54 -53 -50 -14 3 -25 9 -23 13 2 3 41 88
87 188 112 243 106 244 197 -10z"/>
<path d="M2120 3537 c0 -14 -2 -32 -6 -40 -4 -11 6 -16 43 -20 54 -6 83 5 83
32 0 27 -24 43 -75 49 -43 4 -45 3 -45 -21z"/>
<path d="M2105 3399 c-4 -22 -5 -42 -2 -45 9 -10 77 -16 101 -10 52 13 44 70
-12 86 -68 19 -79 14 -87 -31z"/>
<path d="M1697 3533 c-13 -3 -17 -11 -14 -26 3 -12 11 -58 18 -102 7 -44 14
-81 15 -83 7 -10 96 13 113 29 39 36 21 165 -24 183 -18 7 -80 6 -108 -1z"/>
<path d="M1156 3310 l-47 -30 22 -33 c12 -17 24 -34 25 -36 6 -7 94 50 103 67
5 10 5 27 0 40 -12 31 -45 28 -103 -8z"/>
<path d="M1060 2137 c-20 -10 -25 -20 -25 -52 0 -37 4 -42 53 -75 79 -52 68
-97 -21 -88 -23 2 -32 -1 -32 -12 0 -11 14 -16 57 -18 48 -2 60 0 77 19 40 43
27 78 -46 125 -71 45 -70 68 5 72 35 2 52 7 52 16 0 26 -78 34 -120 13z"/>
<path d="M1230 2020 c0 -123 1 -130 20 -130 17 0 20 7 20 43 l1 42 20 -25 c12
-14 27 -33 34 -43 8 -11 22 -17 35 -15 21 3 20 4 -9 43 -38 50 -38 61 0 105
29 34 29 35 8 38 -12 2 -26 -4 -34 -15 -7 -10 -22 -29 -34 -43 l-20 -25 -1 78
c0 70 -2 77 -20 77 -19 0 -20 -7 -20 -130z"/>
<path d="M2030 1976 c0 -130 1 -136 20 -136 20 0 20 5 18 132 -3 117 -5 133
-20 136 -16 3 -18 -8 -18 -132z"/>
<path d="M2133 2103 c-10 -3 -13 -40 -13 -134 0 -121 1 -129 19 -129 16 0 20
8 23 43 l3 42 30 -42 c20 -28 38 -42 53 -43 12 0 22 3 22 6 0 3 -16 26 -35 51
l-35 46 35 43 c40 48 42 54 18 54 -10 0 -35 -19 -55 -42 l-37 -43 -1 78 c0 75
-2 81 -27 70z"/>
<path d="M2310 2090 c0 -13 7 -20 20 -20 13 0 20 7 20 20 0 13 -7 20 -20 20
-13 0 -20 -7 -20 -20z"/>
<path d="M1410 2073 c0 -5 7 -30 15 -58 9 -27 20 -67 26 -87 5 -22 16 -38 24
-38 8 0 15 -4 15 -8 0 -17 -25 -32 -52 -32 -18 0 -28 -5 -28 -15 0 -22 72 -20
92 3 9 9 28 60 42 112 15 52 29 103 32 113 5 15 1 18 -17 15 -17 -2 -25 -12
-32 -38 -23 -94 -29 -110 -36 -106 -5 3 -11 20 -15 38 -17 85 -27 108 -46 108
-11 0 -20 -3 -20 -7z"/>
<path d="M1766 2031 c-3 -4 -8 -35 -12 -67 -8 -75 -19 -96 -28 -58 -25 105
-26 105 -53 102 -23 -3 -29 -10 -41 -58 -15 -63 -32 -88 -32 -48 0 14 -3 40
-7 59 -5 28 -7 30 -14 14 -13 -35 -10 -112 6 -125 29 -24 49 -7 67 55 9 33 17
62 18 65 1 3 11 -24 23 -60 19 -57 25 -65 47 -65 22 0 27 7 37 50 7 28 16 71
19 98 5 39 4 47 -9 47 -9 0 -18 -4 -21 -9z"/>
<path d="M1853 2033 c-7 -2 -13 -12 -13 -20 0 -12 7 -14 31 -9 34 7 69 -8 69
-28 0 -8 -17 -16 -42 -20 -53 -9 -68 -21 -68 -57 0 -43 21 -57 90 -56 l60 0 0
68 c0 103 -19 130 -90 128 -14 0 -31 -3 -37 -6z m87 -128 c0 -18 -7 -26 -24
-31 -30 -7 -46 1 -46 25 0 24 9 31 42 31 23 0 28 -4 28 -25z"/>
<path d="M2317 2033 c-4 -3 -7 -48 -7 -100 0 -86 1 -93 20 -93 19 0 20 7 20
100 0 77 -3 100 -13 100 -8 0 -17 -3 -20 -7z"/>
<path d="M2400 1938 c0 -91 1 -98 20 -98 17 0 19 8 22 78 l3 77 35 0 35 0 3
-77 c3 -70 5 -78 22 -78 18 0 20 7 20 78 0 106 -9 117 -94 118 l-66 1 0 -99z"/>
<path d="M2642 2025 l-33 -14 4 -73 c2 -40 -1 -84 -7 -97 -9 -20 -6 -27 17
-47 51 -43 147 -23 147 30 0 31 -16 43 -78 57 -64 15 -67 29 -7 29 58 0 90 28
81 71 -3 15 -1 31 4 34 39 24 -74 32 -128 10z m74 -29 c27 -20 7 -51 -32 -51
-23 0 -30 5 -32 24 -6 38 29 52 64 27z m-8 -151 c14 -4 22 -13 20 -23 -4 -22
-60 -28 -77 -9 -15 19 -3 49 18 43 9 -2 26 -7 39 -11z"/>
<path d="M549 2531 c-50 -50 -35 -120 33 -151 52 -24 80 -25 117 -5 72 37 56
137 -26 171 -52 22 -91 18 -124 -15z"/>
<path d="M471 2222 c-10 -19 -18 -99 -11 -105 3 -2 24 -7 47 -10 l42 -5 7 54
c4 37 2 59 -6 69 -17 21 -67 19 -79 -3z"/>
<path d="M2571 750 c0 -25 4 -66 7 -91 l7 -46 57 27 57 27 -65 64 -64 63 1
-44z"/>
<path d="M2247 708 c-25 -7 -36 -15 -33 -23 2 -7 10 -41 17 -74 l12 -62 31 6
c84 17 103 26 114 50 17 37 15 59 -9 89 -23 29 -61 33 -132 14z"/>
<path d="M1927 590 l-36 -75 60 -9 c33 -5 62 -7 64 -4 4 4 -4 28 -47 148 -4 9
-19 -14 -41 -60z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,15 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg t="1688979849484" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2698"><path d="M384 469.333333H213.333333c-46.933333 0-85.333333-38.4-85.333333-85.333333V213.333333c0-46.933333 38.4-85.333333 85.333333-85.333333h170.666667c46.933333 0 85.333333 38.4 85.333333 85.333333v170.666667c0 46.933333-38.4 85.333333-85.333333 85.333333zM213.333333 213.333333v170.666667h170.666667V213.333333H213.333333z" p-id="2699"></path><path d="M170.666667 554.666667h256c25.6 0 42.666667 17.066667 42.666666 42.666666v256c0 25.6-17.066667 42.666667-42.666666 42.666667H170.666667c-25.6 0-42.666667-17.066667-42.666667-42.666667v-256c0-25.6 17.066667-42.666667 42.666667-42.666666z" p-id="2700"></path><path d="M384 896H213.333333c-46.933333 0-85.333333-38.4-85.333333-85.333333v-170.666667c0-46.933333 38.4-85.333333 85.333333-85.333333h170.666667c46.933333 0 85.333333 38.4 85.333333 85.333333v170.666667c0 46.933333-38.4 85.333333-85.333333 85.333333z m-170.666667-256v170.666667h170.666667v-170.666667H213.333333z" p-id="2701"></path><path d="M695.466667 115.2c17.066667-17.066667 42.666667-17.066667 59.733333 0l149.333333 149.333333c17.066667 17.066667 17.066667 42.666667 0 59.733334l-149.333333 149.333333c-17.066667 17.066667-42.666667 17.066667-59.733333 0l-149.333334-145.066667c-17.066667-17.066667-17.066667-42.666667 0-59.733333l149.333334-153.6z" p-id="2702"></path><path d="M810.666667 896h-170.666667c-46.933333 0-85.333333-38.4-85.333333-85.333333v-170.666667c0-46.933333 38.4-85.333333 85.333333-85.333333h170.666667c46.933333 0 85.333333 38.4 85.333333 85.333333v170.666667c0 46.933333-38.4 85.333333-85.333333 85.333333z m-170.666667-256v170.666667h170.666667v-170.666667h-170.666667z" p-id="2703"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,29 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<?xml version="1.0" encoding="UTF-8"?>
<svg width="3450px" height="1823px" viewBox="0 0 3450 1823" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.3 (57544) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" transform="translate(0.000000, -29.000000)">
<path d="M1050.01772,1394.31899 C1050.01772,1615.24051 912.21519,1851.47342 474.746835,1851.47342 C310.696203,1851.47342 192.579747,1836.16203 87.5873418,1812.10127 C65.7139241,1807.72658 46.0278481,1792.41519 46.0278481,1768.35443 L46.0278481,1610.86582 C46.0278481,1586.80506 65.7139241,1569.30633 87.5873418,1569.30633 L91.9620253,1569.30633 C179.455696,1580.24304 398.189873,1591.17975 479.121519,1591.17975 C673.794937,1591.17975 732.853165,1521.18481 732.853165,1394.31899 C732.853165,1309.01266 691.293671,1265.26582 546.929114,1179.95949 L258.2,1007.15949 C54.7772152,886.855696 0.0936708861,759.989873 0.0936708861,606.875949 C0.0936708861,366.268354 140.083544,191.281013 546.929114,191.281013 C691.293671,191.281013 892.529114,213.15443 966.898734,230.653165 C988.772152,235.027848 1006.27089,250.339241 1006.27089,272.212658 L1006.27089,434.075949 C1006.27089,455.949367 990.959494,473.448101 969.086076,473.448101 L964.711392,473.448101 C820.346835,460.324051 675.982278,451.574684 533.805063,451.574684 C371.941772,451.574684 304.134177,508.44557 304.134177,606.875949 C304.134177,679.058228 341.318987,722.805063 483.496203,801.549367 L745.977215,948.101266 C986.58481,1081.52911 1050.01772,1221.51899 1050.01772,1394.31899 Z M2852.63038,644.060759 C2852.63038,646.248101 2852.63038,648.435443 2852.63038,650.622785 L2653.58228,1656.8 C2627.33418,1788.04051 2592.33671,1840.53671 2458.90886,1840.53671 L2399.85063,1840.53671 C2281.73418,1840.53671 2220.48861,1783.66582 2192.05316,1669.92405 L2019.25316,1000.59747 C2017.06582,991.848101 2017.06582,989.660759 2012.69114,989.660759 C2008.31646,989.660759 2008.31646,991.848101 2006.12911,1000.59747 L1833.32911,1669.92405 C1804.89367,1783.66582 1743.6481,1840.53671 1625.53165,1840.53671 L1566.47342,1840.53671 C1433.04557,1840.53671 1398.0481,1788.04051 1371.8,1656.8 L1172.7519,650.622785 C1172.7519,648.435443 1172.7519,646.248101 1172.7519,644.060759 C1172.7519,620 1192.43797,600.313924 1216.49873,600.313924 L1428.67089,600.313924 C1450.5443,600.313924 1465.8557,620 1468.04304,639.686076 L1605.84557,1564.93165 C1608.03291,1584.61772 1612.40759,1595.55443 1616.78228,1595.55443 C1621.15696,1595.55443 1627.71899,1586.80506 1632.09367,1564.93165 L1813.64304,829.98481 C1835.51646,744.678481 1861.76456,735.929114 1936.13418,735.929114 L2089.2481,735.929114 C2163.61772,735.929114 2189.86582,744.678481 2211.73924,829.98481 L2393.28861,1564.93165 C2397.66329,1586.80506 2404.22532,1595.55443 2408.6,1595.55443 C2412.97468,1595.55443 2417.34937,1584.61772 2419.53671,1564.93165 L2557.33924,639.686076 C2559.52658,620 2574.83797,600.313924 2596.71139,600.313924 L2808.88354,600.313924 C2832.9443,600.313924 2852.63038,620 2852.63038,644.060759 Z" id="Sw" fill="#1368B3"></path>
<g id="moon-o" transform="translate(2932.164557, 596.000000) rotate(-183.000000) translate(-2932.164557, -596.000000) translate(2415.708861, 26.379747)" fill="#D8D8D8" fill-rule="nonzero">
<path d="M1025.31646,927.371333 C992.796119,932.841177 959.292071,935.576099 925.845888,935.576099 C590.40035,935.576099 318.259524,661.909325 318.259524,324.582876 C318.259524,209.134252 351.705707,96.3623597 412.290747,0 C171.802278,71.8062511 0,293.684076 0,557.342199 C0,878.317305 259.46831,1139.24051 578.65368,1139.24051 C753.17563,1139.24051 916.818891,1059.22949 1025.31646,927.371333 Z" id="Shape"></path>
</g>
</g>
</g>
</svg>

View File

@ -0,0 +1,16 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>icn/epic</title><path d="M5.156 4l-.811 2h7.31l-.811-2H5.156zM4.55 2h6.9c.368 0 .702.235.85.6l1.622 4c.205.505-.009 1.095-.478 1.316a.87.87 0 0 1-.371.084H2.927C2.415 8 2 7.552 2 7c0-.138.026-.274.078-.4l1.622-4c.148-.365.481-.6.85-.6zM3 9h10a1 1 0 0 1 0 2H3a1 1 0 0 1 0-2zm0 3h10a1 1 0 0 1 0 2H3a1 1 0 0 1 0-2z" id="a"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,17 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<svg t="1712402256302" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1578">
<path d="M640 885.589333a39.424 39.424 0 0 1-32.938667 46.634667A483.413333 483.413333 0 0 1 512 938.666667a295.68 295.68 0 0 1-92.117333-16.768 32.085333 32.085333 0 1 1 13.568-62.72 415.658667 415.658667 0 0 0 78.549333 15.36 295.722667 295.722667 0 0 0 75.434667-4.266667c20.181333-9.514667 47.317333-9.216 52.565333 15.36z m-397.824-307.968a160.597333 160.597333 0 0 1 156.842667 164.096 198.314667 198.314667 0 0 1-6.954667 48.426667 154.325333 154.325333 0 0 1-149.930667 115.712 164.266667 164.266667 0 0 1 0-328.192z m539.605333 0a164.266667 164.266667 0 1 1-156.842666 164.096 160.597333 160.597333 0 0 1 156.885333-164.096z m-30.122666-262.058666A344.917333 344.917333 0 0 1 853.333333 497.024c1.109333 16.768-1.749333 38.826667-30.08 41.258667a32.554667 32.554667 0 0 1-33.493333-26.325334 334.848 334.848 0 0 0-80.341333-146.304 34.517333 34.517333 0 0 1-4.992-54.613333 33.408 33.408 0 0 1 47.232 4.693333z m-417.706667-4.48c13.269333 16.64 4.821333 28.501333-8.789333 48.512A422.4 422.4 0 0 0 256 517.802667a33.152 33.152 0 0 1-36.821333 26.709333 31.573333 31.573333 0 0 1-27.52-32.512 89.6 89.6 0 0 1 3.797333-29.226667 402.773333 402.773333 0 0 1 93.312-177.536 30.592 30.592 0 0 1 45.184 5.845334zM512 85.333333a164.266667 164.266667 0 1 1-156.842667 164.096A160.597333 160.597333 0 0 1 512 85.333333z" p-id="1579"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
src/assets/img/technologies/ACTIVEMQ.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

BIN
src/assets/img/tools/MQ.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

View File

@ -443,15 +443,15 @@ limitations under the License. -->
});
</script>
<style scoped>
<style lang="scss" scoped>
.calendar {
float: left;
user-select: none;
color: #3d444f;
color: $font-color;
}
.calendar + .calendar {
border-left: solid 1px #eaeaea;
border-left: solid 1px var(--sw-border-color-light);
margin-left: 5px;
padding-left: 5px;
}
@ -464,7 +464,7 @@ limitations under the License. -->
}
.calendar-head a {
color: #666;
color: var(--sw-topology-color);
cursor: pointer;
display: inline-block;
text-align: center;
@ -479,7 +479,7 @@ limitations under the License. -->
.calendar-head .calendar-year-select,
.calendar-head .calendar-month-select {
font-size: 12px;
font-size: $font-size-smaller;
padding: 0 2px;
position: relative;
}
@ -524,8 +524,8 @@ limitations under the License. -->
float: left;
}
.calendar-week:before,
.calendar-date:before {
.calendar-week::before,
.calendar-date::before {
content: "";
display: inline-block;
height: 100%;
@ -539,27 +539,27 @@ limitations under the License. -->
}
.calendar-date-out {
color: #ccc;
color: $disabled-color;
}
.calendar-date:hover,
.calendar-date-on {
color: #3f97e3;
background-color: #f8f8f8;
color: $font-color;
background-color: $theme-background;
}
.calendar-date-selected,
.calendar-date-selected:hover {
color: #fff;
color: $text-color;
font-weight: bold;
border-radius: 14px;
background: #3f97e3;
background: $active-background;
}
.calendar-date-disabled {
cursor: not-allowed !important;
color: #ccc !important;
background: #fff !important;
color: $disabled-color !important;
background: $theme-background !important;
}
.calendar-foot {
@ -568,7 +568,7 @@ limitations under the License. -->
.calendar-hour {
display: inline-block;
border: 1px solid #e6e5e5;
border: 1px solid var(--sw-border-color-light);
color: #9e9e9e;
}
@ -591,7 +591,7 @@ limitations under the License. -->
width: 100%;
height: 100%;
position: absolute;
background: #fff;
background: $theme-background;
left: 0;
top: 0;
}
@ -626,7 +626,7 @@ limitations under the License. -->
margin-top: -30px;
height: 30px;
line-height: 30px;
background: #fff;
background: $theme-background;
text-align: center;
font-weight: bold;
}

View File

@ -13,6 +13,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<SelectorLegend
:data="option.legend.data"
:show="legendSelector.isSelector"
:isConfigPage="legendSelector.isConfigPage"
:colors="option.color"
@change="changeLegend"
/>
<div class="chart" ref="chartRef" :style="`height:${height};width:${width};`">
<div v-if="!available" class="no-data">No Data</div>
<div
@ -53,6 +60,8 @@ limitations under the License. -->
import { addResizeListener, removeResizeListener } from "@/utils/event";
import Trace from "@/views/dashboard/related/trace/Index.vue";
import associateProcessor from "@/hooks/useAssociateProcessor";
import { WidgetType } from "@/views/dashboard/data";
import SelectorLegend from "./Legend.vue";
/*global Nullable, defineProps, defineEmits, Indexable*/
const emits = defineEmits(["select"]);
@ -63,7 +72,7 @@ limitations under the License. -->
const currentParams = ref<Nullable<EventParams>>(null);
const showTrace = ref<boolean>(false);
const traceOptions = ref<{ type: string; filters?: unknown }>({
type: "Trace",
type: WidgetType.Trace,
});
const menuPos = reactive<{ x: number; y: number }>({ x: NaN, y: NaN });
const props = defineProps({
@ -83,6 +92,10 @@ limitations under the License. -->
type: Array as PropType<{ widgetId: string }[]>,
default: () => [],
},
legendSelector: {
type: Object as PropType<Indexable>,
default: () => ({ isConfigPage: false, isSelector: false }),
},
});
const available = computed(
() =>
@ -102,6 +115,7 @@ limitations under the License. -->
if (!instance) {
return;
}
instance.on("click", (params: EventParams) => {
currentParams.value = params;
if (props.option.series.type === "sankey") {
@ -202,6 +216,23 @@ limitations under the License. -->
});
}
function changeLegend(names: string[]) {
const instance = getInstance();
for (const item of props.option.legend.data) {
if (names.includes(item.name)) {
instance.dispatchAction({
type: "legendSelect",
name: item.name,
});
} else {
instance.dispatchAction({
type: "legendUnSelect",
name: item.name,
});
}
}
}
watch(
() => props.option,
(newVal, oldVal) => {
@ -232,14 +263,12 @@ limitations under the License. -->
</script>
<style lang="scss" scoped>
.no-data {
font-size: 12px;
font-size: $font-size-smaller;
height: 100%;
box-sizing: border-box;
display: -webkit-box;
-webkit-box-orient: horizontal;
-webkit-box-pack: center;
-webkit-box-align: center;
color: #666;
align-items: center;
justify-content: center;
display: flex;
color: var(--text-color-placeholder);
}
.chart {
@ -252,11 +281,11 @@ limitations under the License. -->
display: block;
white-space: nowrap;
z-index: 9999999;
box-shadow: #ddd 1px 2px 10px;
box-shadow: var(--sw-topology-box-shadow);
transition: all cubic-bezier(0.075, 0.82, 0.165, 1) linear;
background-color: rgb(255, 255, 255);
background-color: var(--sw-bg-color-overlay);
border-radius: 4px;
color: rgb(51, 51, 51);
color: $font-color;
padding: 5px;
}
@ -266,8 +295,8 @@ limitations under the License. -->
cursor: pointer;
&:hover {
color: #409eff;
background-color: #eee;
color: $active-color;
background-color: $popper-hover-bg-color;
}
}
</style>

View File

@ -0,0 +1,74 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<Selector
class="mb-10"
multiple
:value="legend"
size="small"
:options="Options"
@change="changeLegend"
filterable
collapseTags
collapseTagsTooltip
v-if="show"
/>
</template>
<script lang="ts" setup>
import { computed, ref, watch } from "vue";
import type { PropType } from "vue";
import type { Option } from "@/types/app";
import Selector from "./Selector.vue";
const props = defineProps({
data: {
type: Array as PropType<{ name: string }[]>,
default: () => [],
},
colors: {
type: Array as PropType<string[]>,
default: () => [],
},
show: {
type: Boolean,
default: false,
},
isConfigPage: {
type: Boolean,
default: false,
},
});
const emits = defineEmits(["change"]);
const legend = ref<string[]>([]);
const Options = computed(() =>
props.data.map((d: { name: string }, index: number) => ({
label: d.name,
value: d.name,
color: props.colors[index % props.colors.length],
})),
);
function changeLegend(opt: Option[]) {
legend.value = opt.map((d: Option) => d.value);
emits("change", legend.value);
}
watch(
() => props.data,
() => {
legend.value = props.data.map((d) => d.name);
},
);
</script>

View File

@ -0,0 +1,107 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<el-select
:size="size"
v-model="selected"
:placeholder="placeholder"
@change="changeSelected"
:multiple="multiple"
:disabled="disabled"
:style="{ borderRadius }"
:clearable="clearable"
:remote="isRemote"
:reserve-keyword="isRemote"
:remote-method="remoteMethod"
:filterable="filterable"
:collapse-tags="collapseTags"
:collapse-tags-tooltip="collapseTagsTooltip"
>
<el-option
v-for="(item, index) in options"
:key="`${item.value}${index}`"
:label="item.label || ''"
:value="item.value || ''"
:disabled="item.disabled || false"
>
<div class="flex items-center">
<el-tag :color="item.color" class="mr-5" size="small" />
<span :style="{ color: item.color }">{{ item.label }}</span>
</div>
</el-option>
</el-select>
</template>
<script lang="ts" setup>
import { ref, watch } from "vue";
import type { PropType } from "vue";
/*global defineProps, defineEmits, Indexable*/
const emit = defineEmits(["change", "query"]);
const props = defineProps({
options: {
type: Array as PropType<
({
label: string | number;
value: string | number;
color: string;
} & { disabled?: boolean })[]
>,
default: () => [],
},
value: {
type: [Array, String, Number, undefined] as PropType<any>,
default: () => [],
},
size: { type: null, default: "default" },
placeholder: {
type: [String, undefined] as PropType<string>,
default: "Select a option",
},
borderRadius: { type: Number, default: 3 },
multiple: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
clearable: { type: Boolean, default: false },
isRemote: { type: Boolean, default: false },
filterable: { type: Boolean, default: true },
collapseTags: { type: Boolean, default: false },
collapseTagsTooltip: { type: Boolean, default: false },
});
const selected = ref<string[] | string>(props.value);
function changeSelected() {
const options = props.options.filter((d: Indexable) =>
props.multiple ? selected.value.includes(d.value) : selected.value === d.value,
);
emit("change", options);
}
function remoteMethod(query: string) {
if (props.isRemote) {
emit("query", query);
}
}
watch(
() => props.value,
(data) => {
selected.value = data;
},
);
</script>
<style lang="scss" scoped>
.el-input__inner {
border-radius: unset !important;
}
</style>

View File

@ -85,20 +85,20 @@ limitations under the License. -->
.bar-select {
position: relative;
justify-content: space-between;
border: 1px solid #ddd;
background: #fff;
border: 1px solid var(--el-border-color);
background: $theme-background;
border-radius: 3px;
color: #000;
font-size: 12px;
color: $font-color;
font-size: $font-size-smaller;
height: 24px;
.selected {
padding: 0 3px;
border-radius: 3px;
margin: 3px;
color: #409eff;
background-color: #fafafa;
border: 1px solid #e8e8e8;
color: $active-color;
background-color: var(--theme-background);
border: 1px solid var(--el-color-primary);
text-align: center;
}
}
@ -112,7 +112,7 @@ limitations under the License. -->
width: 100%;
padding: 2px 10px;
overflow: auto;
color: #606266;
color: var(--sw-setting-color);
position: relative;
&:hover {
@ -126,20 +126,20 @@ limitations under the License. -->
position: absolute;
right: 5px;
top: 0;
font-size: 14px;
font-size: $font-size-normal;
display: none;
color: #aaa;
cursor: pointer;
}
.opt-wrapper {
color: #606266;
color: var(--sw-setting-color);
position: absolute;
top: 26px;
left: 0;
background: #fff;
box-shadow: 0 1px 6px rgba(99, 99, 99, 0.2);
border: 1px solid #ddd;
background-color: $theme-background;
box-shadow: 0 1px 6px rgb(99 99 99 / 20%);
border: 1px solid var(--el-border-color);
width: 100%;
border-radius: 0 0 3px 3px;
border-right-width: 1px !important;
@ -164,12 +164,12 @@ limitations under the License. -->
padding: 7px 15px;
&.select-disabled {
color: #409eff;
color: $active-color;
cursor: not-allowed;
}
&:hover {
background-color: #f5f5f5;
background-color: var(--layout-background);
}
}
</style>

View File

@ -26,10 +26,12 @@ limitations under the License. -->
:reserve-keyword="isRemote"
:remote-method="remoteMethod"
:filterable="filterable"
:collapse-tags="collapseTags"
:collapse-tags-tooltip="collapseTagsTooltip"
>
<el-option
v-for="item in options"
:key="item.value || ''"
v-for="(item, index) in options"
:key="`${item.value}${index}`"
:label="item.label || ''"
:value="item.value || ''"
:disabled="item.disabled || false"
@ -41,11 +43,6 @@ limitations under the License. -->
import { ref, watch } from "vue";
import type { PropType } from "vue";
// interface Option {
// label: string | number;
// value: string | number;
// }
/*global defineProps, defineEmits, Indexable*/
const emit = defineEmits(["change", "query"]);
const props = defineProps({
@ -73,6 +70,8 @@ limitations under the License. -->
clearable: { type: Boolean, default: false },
isRemote: { type: Boolean, default: false },
filterable: { type: Boolean, default: true },
collapseTags: { type: Boolean, default: false },
collapseTagsTooltip: { type: Boolean, default: false },
});
const selected = ref<string[] | string>(props.value);

94
src/components/Tags.vue Normal file
View File

@ -0,0 +1,94 @@
<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<span :class="vertical ? 'vertical' : 'horizontal'" v-for="tag in dynamicTags" :key="tag">
<el-tag closable :disable-transitions="false" @close="handleClose(tag)">
{{ tag }}
</el-tag>
</span>
<el-input
v-if="inputVisible"
ref="InputRef"
v-model="inputValue"
class="ml-5 input-name"
size="small"
@keyup.enter="handleInputConfirm"
@blur="handleInputConfirm"
/>
<el-button v-else size="small" @click="showInput"> + {{ text }} </el-button>
</template>
<script lang="ts" setup>
import { nextTick, ref, watch } from "vue";
import type { PropType } from "vue";
import { ElInput } from "element-plus";
/*global defineProps, defineEmits*/
const emits = defineEmits(["change"]);
const props = defineProps({
tags: {
type: Array as PropType<string[]>,
default: () => [],
},
text: { type: String, default: "" },
vertical: { type: Boolean, default: false },
});
const inputValue = ref("");
const dynamicTags = ref<string[]>(props.tags || []);
const inputVisible = ref(false);
const InputRef = ref<InstanceType<typeof ElInput>>();
const handleClose = (tag: string) => {
dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1);
};
const showInput = () => {
inputVisible.value = true;
nextTick(() => {
InputRef.value!.input!.focus();
});
};
const handleInputConfirm = () => {
if (inputValue.value) {
dynamicTags.value.push(inputValue.value);
}
inputVisible.value = false;
inputValue.value = "";
emits("change", dynamicTags.value);
};
watch(
() => props.tags,
() => {
dynamicTags.value = props.tags || [];
},
);
</script>
<style lang="scss" scoped>
.input-name {
width: 250px;
}
.vertical {
display: block;
margin-bottom: 5px;
}
.horizontal {
display: inline-block;
margin-right: 5px;
}
</style>

View File

@ -302,7 +302,7 @@ limitations under the License. -->
transform: scaleY(0.8);
}
to {
100% {
opacity: 1;
transform: scaleY(1);
}
@ -314,7 +314,7 @@ limitations under the License. -->
transform: scaleY(1);
}
to {
100% {
opacity: 0;
transform: scaleY(0.8);
}
@ -343,7 +343,7 @@ limitations under the License. -->
cursor: pointer;
}
.datepicker-close:before {
.datepicker-close::before {
display: block;
content: "";
position: absolute;
@ -354,14 +354,14 @@ limitations under the License. -->
margin-left: -8px;
margin-top: -8px;
text-align: center;
color: #fff;
color: $text-color;
border-radius: 50%;
background: #ccc
background: $disabled-color
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA3IDciIHdpZHRoPSI3IiBoZWlnaHQ9IjciPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik01LjU4LDVsMi44LTIuODFBLjQxLjQxLDAsMSwwLDcuOCwxLjZMNSw0LjQxLDIuMiwxLjZhLjQxLjQxLDAsMCwwLS41OC41OGgwTDQuNDIsNSwxLjYyLDcuOGEuNDEuNDEsMCwwLDAsLjU4LjU4TDUsNS41OCw3LjgsOC4zOWEuNDEuNDEsMCwwLDAsLjU4LS41OGgwWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEuNSAtMS40OCkiIHN0eWxlPSJmaWxsOiNmZmYiLz48L3N2Zz4NCg==")
no-repeat 50% 50%;
}
.datepicker__clearable:hover:before {
.datepicker__clearable:hover::before {
display: none;
}
@ -369,7 +369,7 @@ limitations under the License. -->
display: block;
}
.datepicker-close:hover:before {
.datepicker-close:hover::before {
background-color: #afafaf;
}
@ -385,7 +385,7 @@ limitations under the License. -->
padding: 0 5px;
width: 100%;
user-select: none;
font-family: "Monaco";
font-family: Monaco;
letter-spacing: -0.7px;
}
@ -399,7 +399,6 @@ limitations under the License. -->
cursor: not-allowed;
background-color: #ebebe4;
border-color: #e5e5e5;
-webkit-box-shadow: none;
box-shadow: none;
}
@ -409,9 +408,9 @@ limitations under the License. -->
transition: all 200ms ease;
opacity: 1;
transform: scaleY(1);
font-size: 12px;
background: #fff;
box-shadow: 0 1px 6px rgba(99, 99, 99, 0.2);
font-size: $font-size-smaller;
background: $theme-background;
box-shadow: 0 1px 6px rgb(99 99 99 / 20%);
margin-top: 2px;
outline: 0;
padding: 5px;
@ -448,7 +447,7 @@ limitations under the License. -->
width: 100px;
height: 100%;
padding: 5px;
border-right: solid 1px #eaeaea;
border-right: solid 1px var(--sw-border-color-light);
}
&__shortcut {
@ -457,8 +456,8 @@ limitations under the License. -->
border: 0;
background-color: transparent;
line-height: 34px;
font-size: 12px;
color: #666;
font-size: $font-size-smaller;
color: var(--sw-topology-color);
text-align: left;
outline: none;
cursor: pointer;
@ -497,7 +496,7 @@ limitations under the License. -->
.datepicker-btn {
padding: 5px 10px;
background: #3f97e3;
color: #fff;
color: $text-color;
border-radius: 2px;
display: inline-block;
cursor: pointer;
@ -525,7 +524,7 @@ limitations under the License. -->
cursor: pointer;
margin: 10px 0 0 5px;
padding: 5px 15px;
color: #ffffff;
color: $text-color;
}
.datepicker__buttons .datepicker__button-select {
@ -533,6 +532,6 @@ limitations under the License. -->
}
.datepicker__buttons .datepicker__button-cancel {
background: #666;
background: var(--sw-topology-color);
}
</style>

View File

@ -18,9 +18,10 @@ import type { App } from "vue";
import Icon from "./Icon.vue";
import TimePicker from "./TimePicker.vue";
import Selector from "./Selector.vue";
import Graph from "./Graph.vue";
import Graph from "./Graph/Graph.vue";
import Radio from "./Radio.vue";
import SelectSingle from "./SelectSingle.vue";
import Tags from "./Tags.vue";
import VueGridLayout from "vue-grid-layout";
const components: Indexable = {
@ -31,6 +32,7 @@ const components: Indexable = {
Graph,
Radio,
SelectSingle,
Tags,
};
const componentsName: string[] = Object.keys(components);

View File

@ -26,3 +26,8 @@ export const Languages = [
{ label: "Chinese", value: "zh" },
{ label: "Spanish", value: "es" },
];
export enum Themes {
Dark = "dark",
Light = "light",
}

75
src/graphql/base.ts Normal file
View File

@ -0,0 +1,75 @@
/*
* Licensed to Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Apache Software Foundation (ASF) licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const Timeout = 2 * 60 * 1000;
export let globalAbortController = new AbortController();
export function abortRequestsAndUpdate() {
globalAbortController.abort(`Request timeout ${Timeout}ms`);
globalAbortController = new AbortController();
}
class HTTPError extends Error {
response;
constructor(response: Response, detailText = "") {
super(detailText || response.statusText);
this.name = "HTTPError";
this.response = response;
}
}
const BasePath = `/graphql`;
export async function httpQuery({
path = "",
method = "GET",
json,
headers = {},
}: {
path?: string;
method: string;
json: unknown;
headers: Recordable;
}) {
const timeoutId = setTimeout(() => {
abortRequestsAndUpdate();
}, Timeout);
const url = `${BasePath}${path}`;
const response: Response = await fetch(url, {
method,
headers: {
"Content-Type": "application/json",
accept: "application/json",
...headers,
},
body: JSON.stringify(json),
signal: globalAbortController.signal,
})
.catch((error) => {
throw new HTTPError(error);
})
.finally(() => {
clearTimeout(timeoutId);
});
if (response.ok) {
return response.json();
} else {
console.error(new HTTPError(response));
}
}

View File

@ -14,20 +14,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { AxiosResponse } from "axios";
import axios from "axios";
import { cancelToken } from "@/utils/cancelToken";
import { httpQuery } from "./base";
async function query(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
const res: AxiosResponse = await axios.post(
"/graphql",
{ query: param.queryStr, variables: { ...param.conditions } },
{ cancelToken: cancelToken() },
);
if (res.data.errors) {
res.data.errors = res.data.errors.map((e: { message: string }) => e.message).join(" ");
async function fetchQuery(param: { queryStr: string; conditions: { [key: string]: unknown } }) {
const response = await httpQuery({
method: "post",
json: { query: param.queryStr, variables: { ...param.conditions } },
headers: {},
});
if (response.errors) {
response.errors = response.errors.map((e: { message: string }) => e.message).join(" ");
}
return res;
return response;
}
export default query;
export default fetchQuery;

View File

@ -24,6 +24,7 @@ export const Alarm = {
message
startTime
scope
name
tags {
key
value
@ -43,6 +44,46 @@ export const Alarm = {
startTime
endTime
}
snapshot {
expression
metrics {
name
results {
metric {
labels {
key
value
}
}
values {
id
owner {
scope
serviceID
serviceName
normal
serviceInstanceID
serviceInstanceName
endpointID
endpointName
}
value
traceID
}
}
}
}
}
}`,
};
export const AlarmTagKeys = {
variable: "$duration: Duration!",
query: `
tagKeys: queryAlarmTagAutocompleteKeys(duration: $duration)`,
};
export const AlarmTagValues = {
variable: "$tagKey: String!, $duration: Duration!",
query: `
tagValues: queryAlarmTagAutocompleteValues(tagKey: $tagKey, duration: $duration)`,
};

View File

@ -26,3 +26,26 @@ export const OAPTimeInfo = {
export const OAPVersion = {
query: `version { version }`,
};
export const MenuItems = {
query: `
getMenuItems {
title
icon
layer
activate
description
documentLink
i18nKey
subItems {
title
icon
layer
activate
description
documentLink
i18nKey
}
}
`,
};

View File

@ -0,0 +1,80 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const GetAsyncTaskList = {
variable: "$request: AsyncProfilerTaskListRequest!",
query: `
asyncTaskList: queryAsyncProfilerTaskList(request: $request) {
errorReason
tasks {
id
serviceId
serviceInstanceIds
createTime
events
duration
execArgs
}
}
`,
};
export const GetAsyncProfileTaskProcess = {
variable: "$taskId: String!",
query: `
taskProgress: queryAsyncProfilerTaskProgress(taskId: $taskId) {
logs {
id
instanceId
instanceName
operationType
operationTime
}
errorInstanceIds
successInstanceIds
}
`,
};
export const CreateAsyncProfileTask = {
variable: "$asyncProfilerTaskCreationRequest: AsyncProfilerTaskCreationRequest!",
query: `
task: createAsyncProfilerTask(asyncProfilerTaskCreationRequest: $asyncProfilerTaskCreationRequest) {
id
errorReason
code
}
`,
};
export const GetAsyncProfileAnalyze = {
variable: "$request: AsyncProfilerAnalyzationRequest!",
query: `
analysisResult: queryAsyncProfilerAnalyze(request: $request) {
tree {
type
elements {
id
parentId
symbol: codeSignature
dumpCount: total
self
}
}
}
`,
};

View File

@ -14,22 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const TypeOfMetrics = {
variable: "$name: String!",
query: `typeOfMetrics(name: $name)`,
};
export const listMetrics = {
variable: "$regex: String",
query: `
metrics: listMetrics(regex: $regex) {
value: name
label: name
type
catalog
}
`,
};
export const getAllTemplates = {
query: `

View File

@ -24,6 +24,7 @@ export const Services = {
group
layers
normal
shortName
}
`,
};
@ -72,9 +73,9 @@ export const Processes = {
};
export const Endpoints = {
variable: "$serviceId: ID!, $keyword: String!",
variable: "$serviceId: ID!, $keyword: String!, $duration: Duration, $limit: Int!",
query: `
pods: findEndpoint(serviceId: $serviceId, keyword: $keyword, limit: 20) {
pods: findEndpoint(serviceId: $serviceId, keyword: $keyword, limit: $limit, duration: $duration) {
id
value: name
label: name

View File

@ -23,6 +23,7 @@ export const ServicesTopology = {
name
type
isReal
layers
}
calls {
id
@ -99,3 +100,56 @@ export const ProcessTopology = {
}
`,
};
export const HierarchyServiceTopology = {
variable: "$serviceId: ID!, $layer: String!",
query: `
hierarchyServiceTopology: getServiceHierarchy(serviceId: $serviceId, layer: $layer) {
relations {
upperService {
id
name
layer
normal
}
lowerService {
id
name
layer
normal
}
}
}`,
};
export const HierarchyInstanceTopology = {
variable: "$instanceId: ID!, $layer: String!",
query: `
hierarchyInstanceTopology: getInstanceHierarchy(instanceId: $instanceId, layer: $layer) {
relations {
upperInstance {
id
name
layer
normal
serviceName
serviceId
}
lowerInstance {
id
name
layer
normal
serviceName
serviceId
}
}
}`,
};
export const ListLayerLevels = {
query: `
levels: listLayerLevels {
layer
level
}
`,
};

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { AxiosPromise, AxiosResponse } from "axios";
import axios from "axios";
import { cancelToken } from "@/utils/cancelToken";
import { httpQuery } from "./base";
import * as app from "./query/app";
import * as selector from "./query/selector";
import * as dashboard from "./query/dashboard";
@ -28,6 +26,7 @@ import * as alarm from "./query/alarm";
import * as event from "./query/event";
import * as ebpf from "./query/ebpf";
import * as demandLog from "./query/demand-log";
import * as asyncProfile from "./query/async-profile";
const query: { [key: string]: string } = {
...app,
@ -41,32 +40,27 @@ const query: { [key: string]: string } = {
...event,
...ebpf,
...demandLog,
...asyncProfile,
};
class Graphql {
private queryData = "";
public query(queryData: string) {
this.queryData = queryData;
queryData = "";
query(data: string) {
this.queryData = data;
return this;
}
public params(variablesData: unknown): AxiosPromise<void> {
return axios
.post(
"/graphql",
{
async params(variables: unknown) {
const response = await httpQuery({
method: "post",
headers: {},
json: {
query: query[this.queryData],
variables: variablesData,
variables,
},
{ cancelToken: cancelToken() },
)
.then((res: AxiosResponse) => {
if (res.data.errors) {
res.data.errors = res.data.errors.map((e: { message: string }) => e.message).join(" ");
}
return res;
})
.catch((err: Error) => {
throw err;
});
if (response.errors) {
response.errors = response.errors.map((e: { message: string }) => e.message).join(" ");
}
return response;
}
}

View File

@ -15,6 +15,8 @@
* limitations under the License.
*/
import { Alarm } from "../fragments/alarm";
import { Alarm, AlarmTagKeys, AlarmTagValues } from "../fragments/alarm";
export const queryAlarms = `query queryAlarms(${Alarm.variable}) {${Alarm.query}}`;
export const queryAlarmTagValues = `query queryTagValues(${AlarmTagValues.variable}) {${AlarmTagValues.query}}`;
export const queryAlarmTagKeys = `query queryTagKeys(${AlarmTagKeys.variable}) {${AlarmTagKeys.query}}`;

View File

@ -14,8 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { OAPTimeInfo, OAPVersion } from "../fragments/app";
import { OAPTimeInfo, OAPVersion, MenuItems } from "../fragments/app";
export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`;
export const queryOAPVersion = `query ${OAPVersion.query}`;
export const queryMenuItems = `query menuItems {${MenuItems.query}}`;

View File

@ -0,0 +1,31 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
GetAsyncTaskList,
GetAsyncProfileTaskProcess,
CreateAsyncProfileTask,
GetAsyncProfileAnalyze,
} from "../fragments/async-profile";
export const getAsyncTaskList = `query getAsyncTaskList(${GetAsyncTaskList.variable}) {${GetAsyncTaskList.query}}`;
export const getAsyncProfileTaskProcess = `query getAsyncProfileTaskProcess(${GetAsyncProfileTaskProcess.variable}) {${GetAsyncProfileTaskProcess.query}}`;
export const saveAsyncProfileTask = `mutation createAsyncProfileTask(${CreateAsyncProfileTask.variable}) {${CreateAsyncProfileTask.query}}`;
export const getAsyncProfileAnalyze = `query getAsyncProfileAnalyze(${GetAsyncProfileAnalyze.variable}) {${GetAsyncProfileAnalyze.query}}`;

View File

@ -14,18 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
TypeOfMetrics,
listMetrics,
getAllTemplates,
addTemplate,
changeTemplate,
deleteTemplate,
} from "../fragments/dashboard";
export const queryTypeOfMetrics = `query typeOfMetrics(${TypeOfMetrics.variable}) {${TypeOfMetrics.query}}`;
export const queryMetrics = `query queryData(${listMetrics.variable}) {${listMetrics.query}}`;
import { getAllTemplates, addTemplate, changeTemplate, deleteTemplate } from "../fragments/dashboard";
export const addNewTemplate = `mutation template(${addTemplate.variable}) {${addTemplate.query}}`;

View File

@ -14,9 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InstanceTopology, EndpointTopology, ServicesTopology, ProcessTopology } from "../fragments/topology";
import {
InstanceTopology,
EndpointTopology,
ServicesTopology,
ProcessTopology,
HierarchyServiceTopology,
HierarchyInstanceTopology,
ListLayerLevels,
} from "../fragments/topology";
export const getInstanceTopology = `query queryData(${InstanceTopology.variable}) {${InstanceTopology.query}}`;
export const getEndpointTopology = `query queryData(${EndpointTopology.variable}) {${EndpointTopology.query}}`;
export const getServicesTopology = `query queryData(${ServicesTopology.variable}) {${ServicesTopology.query}}`;
export const getProcessTopology = `query queryData(${ProcessTopology.variable}) {${ProcessTopology.query}}`;
export const getHierarchyInstanceTopology = `query queryData(${HierarchyInstanceTopology.variable}) {${HierarchyInstanceTopology.query}}`;
export const getHierarchyServiceTopology = `query queryData(${HierarchyServiceTopology.variable}) {${HierarchyServiceTopology.query}}`;
export const queryListLayerLevels = `query queryLayerLevels {${ListLayerLevels.query}}`;

View File

@ -14,32 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export enum MetricQueryTypes {
ReadMetricsValue = "readMetricsValue",
ReadMetricsValues = "readMetricsValues",
SortMetrics = "sortMetrics",
ReadLabeledMetricsValues = "readLabeledMetricsValues",
READHEATMAP = "readHeatMap",
ReadSampledRecords = "readSampledRecords",
ReadRecords = "readRecords",
ReadNullableMetricsValue = "readNullableMetricsValue",
}
export const MaximumEntities = 20;
export enum Calculations {
Percentage = "percentage",
ByteToKB = "byteToKB",
ByteToMB = "byteToMB",
ByteToGB = "byteToGB",
Apdex = "apdex",
ConvertSeconds = "convertSeconds",
ConvertMilliseconds = "convertMilliseconds",
MsToS = "msTos",
Average = "average",
PercentageAvg = "percentageAvg",
ApdexAvg = "apdexAvg",
SecondToDay = "secondToDay",
NanosecondToMillisecond = "nanosecondToMillisecond",
}
export enum sizeEnum {
XS = "XS",
SM = "SM",
@ -68,50 +44,6 @@ screenMap.set(sizeEnum.XL, screenEnum.XL);
screenMap.set(sizeEnum.XXL, screenEnum.XXL);
export const RespFields: Indexable = {
readMetricsValues: `{
label
values {
values {value isEmptyValue}
}
}`,
readMetricsValue: ``,
readNullableMetricsValue: `{
value
isEmptyValue
}`,
sortMetrics: `{
name
id
value
refId
}`,
readLabeledMetricsValues: `{
label
values {
values {value isEmptyValue}
}
}`,
readHeatMap: `{
values {
id
values
}
buckets {
min
max
}
}`,
readSampledRecords: `{
name
value
refId
}`,
readRecords: `{
id
name
value
refId
}`,
execExpression: `{
type
results {
@ -125,8 +57,60 @@ export const RespFields: Indexable = {
name: id
value
refId: traceID
owner {
scope
serviceID
serviceName
normal
serviceInstanceID
serviceInstanceName
endpointID
endpointName
}
}
}
error
}`,
};
export const DarkChartColors = [
"#79bbff",
"#a0a7e6",
"#30A4EB",
"#45BFC0",
"#ebbf93",
"#884dde",
"#1bbf93",
"#7289ab",
"#f56c6c",
"#81feb7",
"#4094fa",
"#ff894d",
"#884dde",
"#ebbf93",
"#fedc6d",
"#da7cfa",
"#b88230",
"#a0cfff",
];
export const LightChartColors = [
"#3f96e3",
"#a0a7e6",
"#45BFC0",
"#FFCC55",
"#FF6A84",
"#c23531",
"#2f4554",
"#61a0a8",
"#d48265",
"#91c7ae",
"#749f83",
"#ca8622",
"#bda29a",
"#6e7074",
"#546570",
"#c4ccd3",
];
export const MaxQueryLength = 120;

View File

@ -47,11 +47,11 @@ export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void)
function getWindowWidth() {
const width = document.body.clientWidth;
const xs = screenMap.get(sizeEnum.XS) || "";
const sm = screenMap.get(sizeEnum.SM) || "";
const md = screenMap.get(sizeEnum.MD) || "";
const lg = screenMap.get(sizeEnum.LG) || "";
const xl = screenMap.get(sizeEnum.XL) || "";
const xs = screenMap.get(sizeEnum.XS) || 0;
const sm = screenMap.get(sizeEnum.SM) || 0;
const md = screenMap.get(sizeEnum.MD) || 0;
const lg = screenMap.get(sizeEnum.LG) || 0;
const xl = screenMap.get(sizeEnum.XL) || 0;
if (width < xs) {
screenRef.value = sizeEnum.XS;
} else if (width < sm) {

View File

@ -17,15 +17,25 @@
import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard";
import type { LayoutConfig } from "@/types/dashboard";
import { ConfigFieldTypes } from "@/views/dashboard/data";
export default function getDashboard(param?: { name: string; layer: string; entity: string }) {
export default function getDashboard(param?: { name?: string; layer: string; entity: string }, t?: string) {
const type = t || ConfigFieldTypes.NAME; // "NAME" or "ISDEFAULT"
const dashboardStore = useDashboardStore();
const opt = param || dashboardStore.currentDashboard;
const list = JSON.parse(sessionStorage.getItem("dashboards") || "[]");
const dashboard = list.find(
let dashboard: Recordable;
if (type === ConfigFieldTypes.NAME) {
dashboard = list.find(
(d: { name: string; layer: string; entity: string }) =>
d.name === opt.name && d.entity === opt.entity && d.layer === opt.layer,
);
} else {
dashboard = list.find(
(d: { name: string; layer: string; entity: string; isDefault: boolean }) =>
d.isDefault && d.entity === opt.entity && d.layer === opt.layer,
);
}
const all = dashboardStore.layout;
const widgets: LayoutConfig[] = [];
for (const item of all) {
@ -52,6 +62,9 @@ export default function getDashboard(param?: { name: string; layer: string; enti
filters,
};
dashboardStore.setWidget(item);
if (widget.id === sourceId) {
return;
}
const targetTabIndex = (widget.id || "").split("-");
const sourceTabindex = (sourceId || "").split("-") || [];
let container: Nullable<Element>;

View File

@ -30,6 +30,8 @@ import { useDebounceFn } from "@vueuse/core";
import { useEventListener } from "./useEventListener";
import { useBreakpoint } from "./useBreakpoint";
import echarts from "@/utils/echarts";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
export type ECOption = echarts.ComposeOption<
| BarSeriesOption
@ -44,8 +46,9 @@ export type ECOption = echarts.ComposeOption<
>;
export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" | "default" = "default"): Indexable {
const appStore = useAppStoreWithOut();
const getDarkMode = computed(() => {
return theme === "default" ? "light" : theme;
return appStore.theme === "default" ? Themes.Light : theme;
});
let chartInstance: Nullable<echarts.ECharts> = null;
let resizeFn: Fn = resize;
@ -55,7 +58,7 @@ export function useECharts(elRef: Ref<HTMLDivElement>, theme: "light" | "dark" |
resizeFn = useDebounceFn(resize, 200);
const getOptions = computed(() => {
if (getDarkMode.value !== "dark") {
if (getDarkMode.value !== Themes.Dark) {
return cacheOptions.value as ECOption;
}
return {

View File

@ -14,40 +14,46 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RespFields } from "./data";
import { ExpressionResultType } from "@/views/dashboard/data";
import { RespFields, MaximumEntities, MaxQueryLength } from "./data";
import { EntityType, ExpressionResultType } from "@/views/dashboard/data";
import { ElMessage } from "element-plus";
import { useTopologyStore } from "@/store/modules/topology";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app";
import type { MetricConfigOpt } from "@/types/dashboard";
import type { Instance, Endpoint, Service } from "@/types/selector";
import type { Node, Call } from "@/types/topology";
export async function useExpressionsQueryProcessor(config: Indexable) {
function expressionsGraphqlPods() {
function chunkArray(array: any[], chunkSize: number) {
const result = [];
for (let i = 0; i < array.length; i += chunkSize) {
result.push(array.slice(i, i + chunkSize));
}
return result;
}
export async function useDashboardQueryProcessor(configList: Indexable[]) {
function expressionsGraphql(config: Indexable, idx: number) {
if (!(config.metrics && config.metrics[0])) {
return;
}
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
if (!selectorStore.currentService && dashboardStore.entity !== "All") {
return;
}
const conditions: Recordable = {
duration: appStore.durationTime,
};
const variables: string[] = [`$duration: Duration!`];
const conditions: Recordable = {};
const variables: string[] = [];
const isRelation = ["ServiceRelation", "ServiceInstanceRelation", "EndpointRelation", "ProcessRelation"].includes(
dashboardStore.entity,
);
if (isRelation && !selectorStore.currentDestService) {
return;
}
const fragment = config.metrics.map((name: string, index: number) => {
variables.push(`$expression${index}: String!`, `$entity${index}: Entity!`);
conditions[`expression${index}`] = name;
if (idx === 0) {
variables.push(`$entity: Entity!`);
const entity = {
serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value,
normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal,
@ -75,19 +81,21 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value
: undefined,
};
conditions[`entity${index}`] = entity;
conditions[`entity`] = entity;
}
const fragment = config.metrics.map((name: string, index: number) => {
variables.push(`$expression${idx}${index}: String!`);
conditions[`expression${idx}${index}`] = name;
return `expression${index}: execExpression(expression: $expression${index}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
return `expression${idx}${index}: execExpression(expression: $expression${idx}${index}, entity: $entity, duration: $duration)${RespFields.execExpression}`;
});
const queryStr = `query queryData(${variables}) {${fragment}}`;
return {
queryStr,
variables,
fragment,
conditions,
};
}
function expressionsSource(resp: { errors: string; data: Indexable }) {
function expressionsSource(config: Indexable, resp: { errors: string; data: Indexable | any }) {
if (resp.errors) {
ElMessage.error(resp.errors);
return { source: {}, tips: [], typesOfMQE: [] };
@ -96,13 +104,17 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
ElMessage.error("The query is wrong");
return { source: {}, tips: [], typesOfMQE: [] };
}
if (resp.data.error) {
ElMessage.error(resp.data.error);
return { source: {}, tips: [], typesOfMQE: [] };
}
const tips: string[] = [];
const source: { [key: string]: unknown } = {};
const source: Indexable<unknown> = {};
const keys = Object.keys(resp.data);
const typesOfMQE: string[] = [];
for (let i = 0; i < config.metrics.length; i++) {
const c: MetricConfigOpt = (config.metricConfig && config.metricConfig[i]) || {};
const metricConfig: MetricConfigOpt = (config.metricConfig && config.metricConfig[i]) || {};
const obj = resp.data[keys[i]] || {};
const results = obj.results || [];
const name = config.metrics[i];
@ -111,26 +123,19 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
tips.push(obj.error);
typesOfMQE.push(type);
if (!obj.error) {
if (type === ExpressionResultType.TIME_SERIES_VALUES) {
if (results.length === 1) {
source[c.label || name] = results[0].values.map((d: { value: unknown }) => d.value) || [];
} else {
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
if ([ExpressionResultType.SINGLE_VALUE, ExpressionResultType.TIME_SERIES_VALUES].includes(type)) {
for (const item of results) {
let label =
item.metric &&
item.metric.labels.map((d: { key: string; value: string }) => `${d.key}=${d.value}`).join(",");
const values = item.values.map((d: { value: unknown }) => d.value) || [];
const index = item.metric.labels[0].value;
const indexNum = labels.findIndex((_, i: number) => i === Number(index));
if (labels[indexNum] && indexNum > -1) {
source[labels[indexNum]] = values;
} else {
source[index] = values;
if (results.length === 1) {
// If the metrics label does not exist, use the configuration label or expression
label = label ? `${metricConfig.label || name}, ${label}` : metricConfig.label || name;
}
source[label] = values;
}
}
}
if (type === ExpressionResultType.SINGLE_VALUE) {
source[c.label || name] = (results[0].values[0] || {}).value;
}
if (([ExpressionResultType.RECORD_LIST, ExpressionResultType.SORTED_LIST] as string[]).includes(type)) {
source[name] = results[0].values;
}
@ -139,24 +144,69 @@ export async function useExpressionsQueryProcessor(config: Indexable) {
return { source, tips, typesOfMQE };
}
const params = await expressionsGraphqlPods();
if (!params) {
return { source: {}, tips: [], typesOfMQE: [] };
async function fetchMetrics(configArr: any) {
const appStore = useAppStoreWithOut();
const variables: string[] = [`$duration: Duration!`];
let fragments = "";
let conditions: Recordable<unknown> = {
duration: appStore.durationTime,
};
for (let i = 0; i < configArr.length; i++) {
const params = await expressionsGraphql(configArr[i], i);
if (params) {
fragments += params?.fragment;
conditions = { ...conditions, ...params.conditions };
variables.push(...params.variables);
}
}
if (!fragments) {
return { 0: { source: {}, tips: [], typesOfMQE: [] } };
}
const queryStr = `query queryData(${variables}) {${fragments}}`;
const dashboardStore = useDashboardStore();
const json = await dashboardStore.fetchMetricValue(params);
const json = await dashboardStore.fetchMetricValue({
queryStr,
conditions,
});
if (json.errors) {
ElMessage.error(json.errors);
return { source: {}, tips: [], typesOfMQE: [] };
return { 0: { source: {}, tips: [], typesOfMQE: [] } };
}
const data = expressionsSource(json);
try {
const pageData: Recordable = {};
return data;
for (let i = 0; i < configArr.length; i++) {
const resp: any = {};
for (let m = 0; m < configArr[i].metrics.length; m++) {
resp[`expression${i}${m}`] = json.data[`expression${i}${m}`];
}
const data = expressionsSource(configArr[i], { ...json, data: resp });
const id = configArr[i].id;
pageData[id] = data;
}
return pageData;
} catch (error) {
console.error(error);
return { 0: { source: {}, tips: [], typesOfMQE: [] } };
}
}
const partArr = chunkArray(configList, 6);
const promiseArr = partArr.map((d: Array<Indexable>) => fetchMetrics(d));
const responseList = await Promise.all(promiseArr);
let resp = {};
for (const item of responseList) {
resp = {
...resp,
...item,
};
}
return resp;
}
export async function useExpressionsQueryPodsMetrics(
pods: Array<(Instance | Endpoint | Service) & Indexable>,
allPods: Array<(Instance | Endpoint | Service) & Indexable>,
config: {
expressions: string[];
subExpressions: string[];
@ -164,7 +214,7 @@ export async function useExpressionsQueryPodsMetrics(
},
scope: string,
) {
function expressionsGraphqlPods() {
function expressionsGraphqlPods(pods: Array<(Instance | Endpoint | Service) & Indexable>) {
const metrics: string[] = [];
const subMetrics: string[] = [];
config.expressions = config.expressions || [];
@ -196,18 +246,22 @@ export async function useExpressionsQueryPodsMetrics(
variables.push(`$entity${index}: Entity!`);
conditions[`entity${index}`] = entity;
const f = metrics.map((name: string, idx: number) => {
variables.push(`$expression${index}${idx}: String!`);
conditions[`expression${index}${idx}`] = name;
if (index === 0) {
variables.push(`$expression${idx}: String!`);
conditions[`expression${idx}`] = name;
}
let str = "";
if (config.subExpressions[idx]) {
variables.push(`$subExpression${index}${idx}: String!`);
conditions[`subExpression${index}${idx}`] = config.subExpressions[idx];
str = `subexpression${index}${idx}: execExpression(expression: $subExpression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
if (index === 0) {
variables.push(`$subExpression${idx}: String!`);
conditions[`subExpression${idx}`] = config.subExpressions[idx];
}
str = `subexpression${index}${idx}: execExpression(expression: $subExpression${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
}
return (
str +
`expression${index}${idx}: execExpression(expression: $expression${index}${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`
`expression${index}${idx}: execExpression(expression: $expression${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`
);
});
return f;
@ -218,7 +272,10 @@ export async function useExpressionsQueryPodsMetrics(
return { queryStr, conditions };
}
function expressionsPodsSource(resp: { errors: string; data: Indexable }): Indexable {
function expressionsPodsSource(
resp: { errors: string; data: Indexable },
pods: Array<(Instance | Endpoint | Service) & Indexable>,
): Indexable {
if (resp.errors) {
ElMessage.error(resp.errors);
return {};
@ -299,15 +356,159 @@ export async function useExpressionsQueryPodsMetrics(
return { data, names, subNames, metricConfigArr, metricTypesArr, expressionsTips, subExpressionsTips };
}
async function fetchPodsExpressionValues(pods: Array<(Instance | Endpoint | Service) & Indexable>) {
const dashboardStore = useDashboardStore();
const params = await expressionsGraphqlPods();
const params = await expressionsGraphqlPods(pods);
const json = await dashboardStore.fetchMetricValue(params);
if (json.errors) {
ElMessage.error(json.errors);
return {};
}
const expressionParams = expressionsPodsSource(json);
const expressionParams = expressionsPodsSource(json, pods);
return expressionParams;
}
const result = [];
for (let i = 0; i < allPods.length; i += MaximumEntities) {
result.push(allPods.slice(i, i + MaximumEntities));
}
const promiseArr = result.map((d: Array<(Instance | Endpoint | Service) & Indexable>) =>
fetchPodsExpressionValues(d),
);
const responseList = await Promise.all(promiseArr);
let resp: Indexable = { data: [], expressionsTips: [], subExpressionsTips: [] };
for (const item of responseList) {
resp = {
...item,
data: [...resp.data, ...item.data],
expressionsTips: [...resp.expressionsTips, ...item.expressionsTips],
subExpressionsTips: [...resp.subExpressionsTips, ...item.subExpressionsTips],
};
}
return resp;
}
export function useQueryTopologyExpressionsProcessor(metrics: string[], instances: (Call | Node)[]) {
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
function getExpressionQuery(partMetrics?: string[]) {
const conditions: { [key: string]: unknown } = {
duration: appStore.durationTime,
};
const variables: string[] = [`$duration: Duration!`];
const fragmentList = instances.map((d: any, index: number) => {
let serviceName;
let destServiceName;
let endpointName;
let serviceInstanceName;
let destServiceInstanceName;
let destEndpointName;
let normal = false;
let destNormal;
if (d.sourceObj && d.targetObj) {
// instances = Calls
serviceName = d.sourceObj.serviceName || d.sourceObj.name;
destServiceName = d.targetObj.serviceName || d.targetObj.name;
normal = d.sourceObj.normal || d.sourceObj.isReal || false;
destNormal = d.targetObj.normal || d.targetObj.isReal || false;
if (EntityType[4].value === dashboardStore.entity) {
serviceInstanceName = d.sourceObj.name;
destServiceInstanceName = d.targetObj.name;
}
if (EntityType[2].value === dashboardStore.entity) {
endpointName = d.sourceObj.name;
destEndpointName = d.targetObj.name;
}
} else {
// instances = Nodes
serviceName = d.serviceName || d.name;
normal = d.normal || d.isReal || false;
if (EntityType[3].value === dashboardStore.entity) {
serviceInstanceName = d.name;
}
if (EntityType[4].value === dashboardStore.entity) {
serviceInstanceName = d.name;
}
if (EntityType[2].value === dashboardStore.entity) {
endpointName = d.name;
}
}
const entity = {
serviceName,
normal,
serviceInstanceName,
endpointName,
destServiceName,
destNormal: destServiceName ? destNormal : undefined,
destServiceInstanceName,
destEndpointName,
};
variables.push(`$entity${index}: Entity!`);
conditions[`entity${index}`] = entity;
const f = (partMetrics || metrics).map((name: string, idx: number) => {
if (index === 0) {
variables.push(`$expression${idx}: String!`);
conditions[`expression${idx}`] = name;
}
return `expression${index}${idx}: execExpression(expression: $expression${idx}, entity: $entity${index}, duration: $duration)${RespFields.execExpression}`;
});
return f;
});
const fragment = fragmentList.flat(1).join(" ");
const queryStr = `query queryData(${variables}) {${fragment}}`;
return { queryStr, conditions };
}
function handleExpressionValues(partMetrics: string[], resp: { [key: string]: any }) {
const obj: Indexable = {};
for (let idx = 0; idx < instances.length; idx++) {
for (let index = 0; index < partMetrics.length; index++) {
const k = "expression" + idx + index;
if (partMetrics[index]) {
if (!obj[partMetrics[index]]) {
obj[partMetrics[index]] = {
values: [],
};
}
obj[partMetrics[index]].values.push({
value: resp[k] && resp[k].results[0] && resp[k].results[0].values[0].value,
id: instances[idx].id,
});
}
}
}
return obj;
}
async function fetchMetrics(partMetrics: string[]) {
const topologyStore = useTopologyStore();
const param = getExpressionQuery(partMetrics);
const res = await topologyStore.getTopologyExpressionValue(param);
if (res.errors) {
ElMessage.error(res.errors);
return;
}
return handleExpressionValues(partMetrics, res.data);
}
async function getMetrics() {
const count = Math.floor(MaxQueryLength / instances.length);
const metricsArr = chunkArray(metrics, count);
const promiseArr = metricsArr.map((d: string[]) => fetchMetrics(d));
const responseList = await Promise.all(promiseArr);
let resp = {};
for (const item of responseList) {
resp = {
...resp,
...item,
};
}
return resp;
}
return { getMetrics, getExpressionQuery };
}

View File

@ -16,6 +16,9 @@
*/
import type { LegendOptions } from "@/types/dashboard";
import { isDef } from "@/utils/is";
import { DarkChartColors, LightChartColors } from "./data";
import { useAppStoreWithOut } from "@/store/modules/app";
import { Themes } from "@/constants/data";
export default function useLegendProcess(legend?: LegendOptions) {
let isRight = false;
@ -32,7 +35,7 @@ export default function useLegendProcess(legend?: LegendOptions) {
if (keys.length === 1) {
return false;
}
if (legend && legend.asTable) {
if (legend && (legend.asTable || legend.asSelector)) {
return false;
}
return true;
@ -96,37 +99,11 @@ export default function useLegendProcess(legend?: LegendOptions) {
return { source, headers };
}
function chartColors(keys: string[]) {
let color: string[] = [];
switch (keys.length) {
case 2:
color = ["#FF6A84", "#a0b1e6"];
break;
case 1:
color = ["#3f96e3"];
break;
default:
color = [
"#30A4EB",
"#45BFC0",
"#FFCC55",
"#FF6A84",
"#a0a7e6",
"#c23531",
"#2f4554",
"#61a0a8",
"#d48265",
"#91c7ae",
"#749f83",
"#ca8622",
"#bda29a",
"#6e7074",
"#546570",
"#c4ccd3",
];
break;
}
return color;
function chartColors() {
const appStore = useAppStoreWithOut();
const list = appStore.theme === Themes.Dark ? DarkChartColors : LightChartColors;
return list;
}
return { showEchartsLegend, isRight, aggregations, chartColors };
}

View File

@ -1,41 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { MetricQueryTypes, Calculations } from "./data";
import { MetricModes } from "@/views/dashboard/data";
export function useListConfig(config: Indexable, index: number) {
if (config.metricModes === MetricModes.Expression) {
return {
isLinear: false,
isAvg: true,
};
}
const i = Number(index);
const types = [Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg];
const calculation = config.metricConfig && config.metricConfig[i] && config.metricConfig[i].calculation;
const isLinear =
[MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) &&
!types.includes(calculation);
const isAvg =
[MetricQueryTypes.ReadMetricsValues, MetricQueryTypes.ReadLabeledMetricsValues].includes(config.metricTypes[i]) &&
types.includes(calculation);
return {
isLinear,
isAvg,
};
}

View File

@ -1,437 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import dayjs from "dayjs";
import { RespFields, MetricQueryTypes, Calculations } from "./data";
import { ElMessage } from "element-plus";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app";
import type { Instance, Endpoint, Service } from "@/types/selector";
import type { MetricConfigOpt } from "@/types/dashboard";
export function useQueryProcessor(config: Indexable) {
if (!(config.metrics && config.metrics[0])) {
return;
}
if (!(config.metricTypes && config.metricTypes[0])) {
return;
}
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const selectorStore = useSelectorStore();
if (!selectorStore.currentService && dashboardStore.entity !== "All") {
return;
}
const conditions: Recordable = {
duration: appStore.durationTime,
};
const variables: string[] = [`$duration: Duration!`];
const isRelation = ["ServiceRelation", "ServiceInstanceRelation", "EndpointRelation", "ProcessRelation"].includes(
dashboardStore.entity,
);
if (isRelation && !selectorStore.currentDestService) {
return;
}
const fragment = config.metrics.map((name: string, index: number) => {
const metricType = config.metricTypes[index] || "";
const c = (config.metricConfig && config.metricConfig[index]) || {};
if ([MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics].includes(metricType)) {
variables.push(`$condition${index}: TopNCondition!`);
conditions[`condition${index}`] = {
name,
parentService: ["All"].includes(dashboardStore.entity) ? null : selectorStore.currentService.value,
normal: selectorStore.currentService ? selectorStore.currentService.normal : true,
topN: Number(c.topN) || 10,
order: c.sortOrder || "DES",
};
} else {
const entity = {
serviceName: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.value,
normal: dashboardStore.entity === "All" ? undefined : selectorStore.currentService.normal,
serviceInstanceName: ["ServiceInstance", "ServiceInstanceRelation", "ProcessRelation"].includes(
dashboardStore.entity,
)
? selectorStore.currentPod && selectorStore.currentPod.value
: undefined,
endpointName: dashboardStore.entity.includes("Endpoint")
? selectorStore.currentPod && selectorStore.currentPod.value
: undefined,
processName: dashboardStore.entity.includes("Process")
? selectorStore.currentProcess && selectorStore.currentProcess.value
: undefined,
destNormal: isRelation ? selectorStore.currentDestService.normal : undefined,
destServiceName: isRelation ? selectorStore.currentDestService.value : undefined,
destServiceInstanceName: ["ServiceInstanceRelation", "ProcessRelation"].includes(dashboardStore.entity)
? selectorStore.currentDestPod && selectorStore.currentDestPod.value
: undefined,
destEndpointName:
dashboardStore.entity === "EndpointRelation"
? selectorStore.currentDestPod && selectorStore.currentDestPod.value
: undefined,
destProcessName: dashboardStore.entity.includes("ProcessRelation")
? selectorStore.currentDestProcess && selectorStore.currentDestProcess.value
: undefined,
};
if ([MetricQueryTypes.ReadRecords].includes(metricType)) {
variables.push(`$condition${index}: RecordCondition!`);
conditions[`condition${index}`] = {
name,
parentEntity: entity,
topN: Number(c.topN) || 10,
order: c.sortOrder || "DES",
};
} else {
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
variables.push(`$labels${index}: [String!]!`);
conditions[`labels${index}`] = labels;
}
variables.push(`$condition${index}: MetricsCondition!`);
conditions[`condition${index}`] = {
name,
entity,
};
}
}
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
return `${name}${index}: ${metricType}(condition: $condition${index}, labels: $labels${index}, duration: $duration)${RespFields[metricType]}`;
}
const t = metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType;
return `${name}${index}: ${t}(condition: $condition${index}, duration: $duration)${RespFields[t]}`;
});
const queryStr = `query queryData(${variables}) {${fragment}}`;
return {
queryStr,
conditions,
};
}
export function useSourceProcessor(
resp: { errors: string; data: Indexable },
config: {
metrics: string[];
metricTypes: string[];
metricConfig: MetricConfigOpt[];
},
) {
if (resp.errors) {
ElMessage.error(resp.errors);
return {};
}
if (!resp.data) {
ElMessage.error("The query is wrong");
return {};
}
const source: { [key: string]: unknown } = {};
const keys = Object.keys(resp.data);
config.metricTypes.forEach((type: string, index) => {
const m = config.metrics[index];
const c = (config.metricConfig && config.metricConfig[index]) || {};
if (type === MetricQueryTypes.ReadMetricsValues) {
source[c.label || m] = (resp.data[keys[index]] && calculateExp(resp.data[keys[index]].values.values, c)) || [];
}
if (type === MetricQueryTypes.ReadLabeledMetricsValues) {
const resVal = Object.values(resp.data)[0] || [];
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
for (const item of resVal) {
const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) =>
d.isEmptyValue ? NaN : aggregation(Number(d.value), c),
);
const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
if (labels[indexNum] && indexNum > -1) {
source[labels[indexNum]] = values;
} else {
source[item.label] = values;
}
}
}
if (type === MetricQueryTypes.ReadMetricsValue) {
const v = Object.values(resp.data)[0] || {};
source[m] = v.isEmptyValue ? NaN : aggregation(Number(v.value), c);
}
if (
(
[MetricQueryTypes.ReadRecords, MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.SortMetrics] as string[]
).includes(type)
) {
source[m] = (Object.values(resp.data)[0] || []).map((d: { value: unknown; name: string }) => {
d.value = aggregation(Number(d.value), c);
return d;
});
}
if (type === MetricQueryTypes.READHEATMAP) {
const resVal = Object.values(resp.data)[0] || {};
const nodes = [] as Indexable[];
if (!(resVal && resVal.values)) {
source[m] = { nodes: [] };
return;
}
resVal.values.forEach((items: { values: number[] }, x: number) => {
const grids = items.values.map((val: number, y: number) => [x, y, val]);
nodes.push(...grids);
});
let buckets = [] as Indexable[];
if (resVal.buckets.length) {
buckets = [resVal.buckets[0].min, ...resVal.buckets.map((item: { min: string; max: string }) => item.max)];
}
source[m] = { nodes, buckets }; // nodes: number[][]
}
});
return source;
}
export function useQueryPodsMetrics(
pods: Array<(Instance | Endpoint | Service) & Indexable>,
config: {
metrics: string[];
metricTypes: string[];
metricConfig: MetricConfigOpt[];
},
scope: string,
) {
const metricTypes = (config.metricTypes || []).filter((m: string) => m);
if (!metricTypes.length) {
return;
}
const metrics = (config.metrics || []).filter((m: string) => m);
if (!metrics.length) {
return;
}
const appStore = useAppStoreWithOut();
const selectorStore = useSelectorStore();
const conditions: { [key: string]: unknown } = {
duration: appStore.durationTime,
};
const variables: string[] = [`$duration: Duration!`];
const currentService = selectorStore.currentService || {};
const fragmentList = pods.map((d: (Instance | Endpoint | Service) & Indexable, index: number) => {
const param = {
serviceName: scope === "Service" ? d.label : currentService.label,
serviceInstanceName: scope === "ServiceInstance" ? d.label : undefined,
endpointName: scope === "Endpoint" ? d.label : undefined,
normal: scope === "Service" ? d.normal : currentService.normal,
};
const f = metrics.map((name: string, idx: number) => {
const metricType = metricTypes[idx] || "";
variables.push(`$condition${index}${idx}: MetricsCondition!`);
conditions[`condition${index}${idx}`] = {
name,
entity: param,
};
let labelStr = "";
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
const c = config.metricConfig[idx] || {};
variables.push(`$labels${index}${idx}: [String!]!`);
labelStr = `labels: $labels${index}${idx}, `;
const labels = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
conditions[`labels${index}${idx}`] = labels;
}
const t =
metricType === MetricQueryTypes.ReadMetricsValue ? MetricQueryTypes.ReadNullableMetricsValue : metricType;
return `${name}${index}${idx}: ${t}(condition: $condition${index}${idx}, ${labelStr}duration: $duration)${RespFields[t]}`;
});
return f;
});
const fragment = fragmentList.flat(1).join(" ");
const queryStr = `query queryData(${variables}) {${fragment}}`;
return { queryStr, conditions };
}
export function usePodsSource(
pods: Array<Instance | Endpoint>,
resp: { errors: string; data: Indexable },
config: {
metrics: string[];
metricTypes: string[];
metricConfig: MetricConfigOpt[];
},
): Indexable {
if (resp.errors) {
ElMessage.error(resp.errors);
return {};
}
const names: string[] = [];
const metricConfigArr: MetricConfigOpt[] = [];
const metricTypesArr: string[] = [];
const data = pods.map((d: any, idx: number) => {
config.metrics.map((name: string, index: number) => {
const c: any = (config.metricConfig && config.metricConfig[index]) || {};
const key = name + idx + index;
if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValue) {
const v = resp.data[key];
d[name] = v.isEmptyValue ? NaN : aggregation(v.value, c);
if (idx === 0) {
names.push(name);
metricConfigArr.push(c);
metricTypesArr.push(config.metricTypes[index]);
}
}
if (config.metricTypes[index] === MetricQueryTypes.ReadMetricsValues) {
d[name] = {};
if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) {
d[name]["avg"] = calculateExp(resp.data[key].values.values, c);
}
d[name]["values"] = resp.data[key].values.values.map((val: { value: number; isEmptyValue: boolean }) =>
val.isEmptyValue ? NaN : aggregation(val.value, c),
);
if (idx === 0) {
names.push(name);
metricConfigArr.push(c);
metricTypesArr.push(config.metricTypes[index]);
}
}
if (config.metricTypes[index] === MetricQueryTypes.ReadLabeledMetricsValues) {
const resVal = resp.data[key] || [];
const labels = (c.label || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
const labelsIdx = (c.labelsIndex || "").split(",").map((item: string) => item.replace(/^\s*|\s*$/g, ""));
for (let i = 0; i < resVal.length; i++) {
const item = resVal[i];
const values = item.values.values.map((d: { value: number; isEmptyValue: boolean }) =>
d.isEmptyValue ? NaN : aggregation(Number(d.value), c),
);
const indexNum = labelsIdx.findIndex((d: string) => d === item.label);
let key = item.label;
if (labels[indexNum] && indexNum > -1) {
key = labels[indexNum];
}
if (!d[key]) {
d[key] = {};
}
if ([Calculations.Average, Calculations.ApdexAvg, Calculations.PercentageAvg].includes(c.calculation)) {
d[key]["avg"] = calculateExp(item.values.values, c);
}
d[key]["values"] = values;
if (idx === 0) {
names.push(key);
metricConfigArr.push({ ...c, index: i });
metricTypesArr.push(config.metricTypes[index]);
}
}
}
});
return d;
});
return { data, names, metricConfigArr, metricTypesArr };
}
export function useQueryTopologyMetrics(metrics: string[], ids: string[]) {
const appStore = useAppStoreWithOut();
const conditions: { [key: string]: unknown } = {
duration: appStore.durationTime,
ids,
};
const variables: string[] = [`$duration: Duration!`, `$ids: [ID!]!`];
const fragmentList = metrics.map((d: string, index: number) => {
conditions[`m${index}`] = d;
variables.push(`$m${index}: String!`);
return `${d}: getValues(metric: {
name: $m${index}
ids: $ids
}, duration: $duration) {
values {
id
value
}
}`;
});
const queryStr = `query queryData(${variables}) {${fragmentList.join(" ")}}`;
return { queryStr, conditions };
}
export function calculateExp(
list: { value: number; isEmptyValue: boolean }[],
config: { calculation?: string },
): (number | string)[] {
const arr = list.filter((d: { value: number; isEmptyValue: boolean }) => !d.isEmptyValue);
const sum = arr.length ? arr.map((d: { value: number }) => Number(d.value)).reduce((a, b) => a + b) : 0;
let data: (number | string)[] = [];
switch (config.calculation) {
case Calculations.Average:
data = [(sum / arr.length).toFixed(2)];
break;
case Calculations.PercentageAvg:
data = [(sum / arr.length / 100).toFixed(2)];
break;
case Calculations.ApdexAvg:
data = [(sum / arr.length / 10000).toFixed(2)];
break;
default:
data = list.map((d: { value: number; isEmptyValue: boolean }) =>
d.isEmptyValue ? NaN : aggregation(d.value, config),
);
break;
}
return data;
}
export function aggregation(val: number, config: { calculation?: string }): number | string {
let data: number | string = Number(val);
switch (config.calculation) {
case Calculations.Percentage:
data = (val / 100).toFixed(2);
break;
case Calculations.PercentageAvg:
data = (val / 100).toFixed(2);
break;
case Calculations.ByteToKB:
data = (val / 1024).toFixed(2);
break;
case Calculations.ByteToMB:
data = (val / 1024 / 1024).toFixed(2);
break;
case Calculations.ByteToGB:
data = (val / 1024 / 1024 / 1024).toFixed(2);
break;
case Calculations.Apdex:
data = (val / 10000).toFixed(2);
break;
case Calculations.ConvertSeconds:
data = dayjs(val * 1000).format("YYYY-MM-DD HH:mm:ss");
break;
case Calculations.ConvertMilliseconds:
data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
break;
case Calculations.MsToS:
data = (val / 1000).toFixed(2);
break;
case Calculations.SecondToDay:
data = (val / 86400).toFixed(2);
break;
case Calculations.NanosecondToMillisecond:
data = (val / 1000 / 1000).toFixed(2);
break;
case Calculations.ApdexAvg:
data = (val / 10000).toFixed(2);
break;
default:
data;
break;
}
return data;
}

47
src/hooks/useSnapshot.ts Normal file
View File

@ -0,0 +1,47 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { MetricsResults } from "@/types/dashboard";
export function useSnapshot(metrics: { name: string; results: MetricsResults[] }[]) {
function processResults() {
const sources = metrics.map((metric: { name: string; results: MetricsResults[] }) => {
const values = metric.results.map(
(r: { values: { value: string }[]; metric: { labels: { key: string; value: string }[] } }) => {
const arr = r.values.map((v: { value: string }) => Number(v.value));
if (!r.metric.labels.length) {
return { values: arr };
}
const name = r.metric.labels
.map(
(label: { key: string; value: string }) =>
`${metric.name}${label ? "{" : ""}${label.key}=${label.value}${label ? "}" : ""}`,
)
.join(",");
return { name, values: arr };
},
);
return { name: metric.name, values };
});
return sources;
}
return {
processResults,
};
}

View File

@ -24,7 +24,7 @@ limitations under the License. -->
<style lang="scss" scoped>
.app-main {
height: calc(100% - 40px);
background: #f7f9fa;
background: $layout-background;
overflow: auto;
}
</style>

View File

@ -14,7 +14,31 @@ See the License for the specific language governing permissions and
limitations under the License. -->
<template>
<div class="nav-bar flex-h">
<div class="title">{{ route.name === "ViewWidget" ? "" : appStore.pageTitle || t(pageName) }}</div>
<el-breadcrumb
:separator-icon="ArrowRight"
class="title flex-h"
v-if="pathNames.length"
:style="{ '--el-text-color-placeholder': '#666' }"
>
<el-breadcrumb-item
v-for="(path, index) in pathNames"
:key="index"
:replace="true"
:to="{ path: getName(path).path || '' }"
>
<el-dropdown size="small" placement="bottom" :persistent="false">
<span class="cp name">{{ getName(path).name }}</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="setName(p)" v-for="(p, index) in path" :key="index">
<span>{{ p.name }}</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-breadcrumb-item>
</el-breadcrumb>
<div class="title" v-else>{{ pageTitle }}</div>
<div class="app-config">
<span class="red" v-show="timeRange">{{ t("timeTips") }}</span>
<TimePicker
@ -24,11 +48,20 @@ limitations under the License. -->
@input="changeTimeRange"
/>
<span> UTC{{ appStore.utcHour >= 0 ? "+" : "" }}{{ `${appStore.utcHour}:${appStore.utcMin}` }} </span>
<span class="ml-5" ref="themeSwitchRef">
<el-switch
v-model="theme"
:active-icon="Moon"
:inactive-icon="Sunny"
inline-prompt
@change="handleChangeTheme"
/>
</span>
<span title="refresh" class="ghost ml-5 cp" @click="handleReload">
<Icon iconName="retry" :loading="appStore.autoRefresh" class="middle" />
</span>
<span class="version ml-5 cp">
<el-popover trigger="hover" width="250" placement="bottom" effect="light" :content="appStore.version">
<el-popover trigger="hover" :width="250" placement="bottom" :content="appStore.version">
<template #reference>
<span>
<Icon iconName="info_outline" size="middle" />
@ -40,25 +73,109 @@ limitations under the License. -->
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from "vue";
import { useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
import timeFormat from "@/utils/timeFormat";
import { Themes } from "@/constants/data";
import router from "@/router";
import { useAppStoreWithOut } from "@/store/modules/app";
import { useDashboardStore } from "@/store/modules/dashboard";
import type { DashboardItem } from "@/types/dashboard";
import timeFormat from "@/utils/timeFormat";
import { MetricCatalog } from "@/views/dashboard/data";
import { ArrowRight, Moon, Sunny } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
/*global Indexable */
const { t } = useI18n();
const { t, te } = useI18n();
const appStore = useAppStoreWithOut();
const dashboardStore = useDashboardStore();
const route = useRoute();
const pageName = ref<string>("");
const pathNames = ref<{ path?: string; name: string; selected: boolean }[][]>([]);
const timeRange = ref<number>(0);
const pageTitle = ref<string>("");
const theme = ref<boolean>(true);
const themeSwitchRef = ref<HTMLElement>();
const savedTheme = window.localStorage.getItem("theme-is-dark");
if (savedTheme === "false") {
theme.value = false;
}
if (savedTheme === "") {
// read the theme preference from system setting if there is no user setting
theme.value = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
}
changeTheme();
resetDuration();
getVersion();
const setConfig = (value: string) => {
pageName.value = value || "";
};
getNavPaths();
function changeTheme() {
const root = document.documentElement;
if (theme.value) {
root.classList.add(Themes.Dark);
root.classList.remove(Themes.Light);
appStore.setTheme(Themes.Dark);
} else {
root.classList.add(Themes.Light);
root.classList.remove(Themes.Dark);
appStore.setTheme(Themes.Light);
}
window.localStorage.setItem("theme-is-dark", String(theme.value));
}
function handleChangeTheme() {
const x = themeSwitchRef.value?.offsetLeft ?? 0;
const y = themeSwitchRef.value?.offsetTop ?? 0;
const endRadius = Math.hypot(Math.max(x, innerWidth - x), Math.max(y, innerHeight - y));
// compatibility handling
if (!document.startViewTransition) {
changeTheme();
return;
}
// api: https://developer.chrome.com/docs/web-platform/view-transitions
const transition = document.startViewTransition(() => {
changeTheme();
});
transition.ready.then(() => {
const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`];
document.documentElement.animate(
{
clipPath: !theme.value ? clipPath.reverse() : clipPath,
},
{
duration: 500,
easing: "ease-in",
pseudoElement: !theme.value ? "::view-transition-old(root)" : "::view-transition-new(root)",
},
);
});
}
function getName(list: any[]) {
return list.find((d: any) => d.selected) || {};
}
function setName(item: any) {
pathNames.value = pathNames.value.map((list: { path?: string; name: string; selected: boolean }[]) => {
const p = list.find((i: any) => i.entity === item.entity && item.layer === i.layer && i.name === item.name);
if (p) {
list = list.map((d: any) => {
d.selected = false;
if (d.entity === item.entity && item.layer === d.layer && d.name === item.name) {
d.selected = true;
}
return d;
});
}
return list;
});
item.path && router.push(item.path);
}
function handleReload() {
const gap = appStore.duration.end.getTime() - appStore.duration.start.getTime();
@ -73,19 +190,138 @@ limitations under the License. -->
}
appStore.setDuration(timeFormat(val));
}
setConfig(String(route.meta.title));
watch(
() => route.meta.title,
(title: unknown) => {
setConfig(String(title));
function getNavPaths() {
pathNames.value = [];
pageTitle.value = "";
const dashboard = dashboardStore.currentDashboard;
if (!(dashboard && dashboard.name)) {
updateNavTitle();
return;
}
const root =
dashboardStore.dashboards.filter((d: DashboardItem) => d.isRoot && dashboard.layer === d.layer)[0] || {};
for (const item of appStore.allMenus) {
if (item.subItems && item.subItems.length) {
for (const subItem of item.subItems) {
if (subItem.layer === root.layer) {
root.path = subItem.path;
}
}
} else {
if (item.layer === root.layer) {
root.path = item.path;
}
}
}
pathNames.value.push([{ ...root, selected: true }]);
if (dashboard.entity === MetricCatalog.ALL) {
return;
}
if (dashboard.entity === MetricCatalog.SERVICE) {
pathNames.value.push([
{
name: dashboard.name,
selected: true,
},
]);
return;
}
const serviceDashboards = dashboardStore.dashboards.filter(
(d: DashboardItem) => MetricCatalog.SERVICE === d.entity && dashboard.layer === d.layer,
);
if (!serviceDashboards.length) {
return;
}
const serviceId = route.params.serviceId;
const list = serviceDashboards.map((d: { path: string } & DashboardItem, index: number) => {
let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
if (serviceId) {
path = `/dashboard/${d.layer}/${d.entity}/${serviceId}/${d.name}`;
}
const selected = index === 0;
return {
...d,
path,
selected,
};
});
pathNames.value.push(list);
const podId = route.params.podId;
if (dashboard.entity === MetricCatalog.ENDPOINT_RELATION) {
const endpointDashboards = dashboardStore.dashboards.filter(
(d: DashboardItem) => MetricCatalog.ENDPOINT === d.entity && dashboard.layer === d.layer,
);
const list = endpointDashboards.map((d: { path: string } & DashboardItem, index: number) => {
let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
if (podId) {
path = `/dashboard/${d.layer}/${d.entity}/${serviceId}/${podId}/${d.name}`;
}
const selected = index === 0;
return {
...d,
path,
selected,
};
});
pathNames.value.push(list);
}
const destServiceId = route.params.destServiceId;
if (dashboard.entity === MetricCatalog.SERVICE_INSTANCE_RELATION) {
const serviceRelationDashboards = dashboardStore.dashboards.filter(
(d: DashboardItem) => MetricCatalog.SERVICE_RELATION === d.entity && dashboard.layer === d.layer,
);
const list = serviceRelationDashboards.map((d: { path: string } & DashboardItem, index: number) => {
let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
if (destServiceId) {
path = `/dashboard/related/${d.layer}/${d.entity}/${serviceId}/${destServiceId}/${d.name}`;
}
const selected = index === 0;
return {
...d,
path,
selected,
};
});
pathNames.value.push(list);
}
if ([MetricCatalog.Process, MetricCatalog.PROCESS_RELATION].includes(dashboard.entity)) {
const InstanceDashboards = dashboardStore.dashboards.filter(
(d: DashboardItem) => MetricCatalog.SERVICE_INSTANCE === d.entity && dashboard.layer === d.layer,
);
const list = InstanceDashboards.map((d: { path: string } & DashboardItem, index: number) => {
let path = `/dashboard/${d.layer}/${d.entity}/${d.name}`;
if (podId) {
path = `/dashboard/${d.layer}/${d.entity}/${serviceId}/${podId}/${d.name}`;
}
const selected = index === 0;
return {
...d,
path,
selected,
};
});
pathNames.value.push(list);
}
pathNames.value.push([
{
name: dashboard.name,
selected: true,
},
]);
}
async function getVersion() {
const res = await appStore.fetchVersion();
if (res.errors) {
ElMessage.error(res.errors);
}
}
function resetDuration() {
const { duration }: Indexable = route.params;
if (duration) {
@ -99,32 +335,45 @@ limitations under the License. -->
appStore.updateUTC(d.utc);
}
}
function updateNavTitle() {
const key = String(route.meta.i18nKey);
pageTitle.value = te(key) ? t(key) : String(route.meta.title);
}
watch(
() => [dashboardStore.currentDashboard, route.name],
() => {
getNavPaths();
},
);
</script>
<style lang="scss" scoped>
.nav-bar {
padding: 5px 10px;
padding: 5px;
text-align: left;
justify-content: space-between;
background-color: #fafbfc;
border-bottom: 1px solid #dfe4e8;
color: #222;
font-size: 12px;
}
.nav-bar.dark {
background-color: #333840;
border-bottom: 1px solid #252a2f;
color: #fafbfc;
background-color: $theme-background;
border-bottom: 1px solid $border-color;
color: $font-color;
font-size: $font-size-smaller;
}
.title {
font-size: 14px;
font-size: $font-size-normal;
font-weight: 500;
height: 28px;
line-height: 28px;
padding-top: 5px;
}
.nav-tabs {
padding: 10px;
}
.name {
display: inline-block;
max-width: 250px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
</style>

View File

@ -36,19 +36,21 @@ limitations under the License. -->
<Icon size="lg" :iconName="menu.meta.icon" />
</el-icon>
<span class="title" :class="isCollapse ? 'collapse' : ''">
{{ t(menu.meta.title) }}
{{ te(menu.meta.i18nKey) ? t(menu.meta.i18nKey) : menu.meta.title }}
</span>
</router-link>
</template>
<el-menu-item-group>
<el-menu-item v-for="(m, idx) in filterMenus(menu.children)" :index="m.name" :key="idx">
<router-link class="items" :to="m.path">
<span class="title">{{ m.meta && t(m.meta.title) }}</span>
<span class="title">
{{ m.meta && (te(m.meta.i18nKey) ? t(m.meta.i18nKey) : m.meta.title) }}
</span>
</router-link>
</el-menu-item>
</el-menu-item-group>
</el-sub-menu>
<el-menu-item :index="String(menu.name)" @click="changePage(menu)" v-else>
<el-menu-item :index="String(menu.name)" v-else>
<el-icon class="menu-icons" :style="{ marginRight: '12px' }" @mouseover="setCollapse">
<router-link class="items menu-title" :to="menu.children[0].path">
<Icon size="lg" :iconName="menu.meta.icon" />
@ -56,7 +58,9 @@ limitations under the License. -->
</el-icon>
<template #title>
<router-link class="items menu-title" :to="menu.children[0].path">
<span class="title">{{ t(menu.meta.title) }}</span>
<span class="title">
{{ te(menu.meta.i18nKey) ? t(menu.meta.i18nKey) : menu.meta.title }}
</span>
</router-link>
</template>
</el-menu-item>
@ -67,7 +71,7 @@ limitations under the License. -->
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ref, watch } from "vue";
import type { RouteRecordRaw } from "vue-router";
import { useRouter, useRoute } from "vue-router";
import { useI18n } from "vue-i18n";
@ -75,11 +79,13 @@ limitations under the License. -->
import { useAppStoreWithOut } from "@/store/modules/app";
/*global Recordable*/
const { t, te } = useI18n();
const appStore = useAppStoreWithOut();
const { t } = useI18n();
const name = ref<string>(String(useRouter().currentRoute.value.name));
const theme = ["VirtualMachine", "Kubernetes"].includes(name.value || "") ? ref("light") : ref("black");
const routes = ref<RouteRecordRaw[] | any>(useRouter().options.routes);
const router = useRouter();
const name = ref<string>(String(router.currentRoute.value.name));
const routes = ref<RouteRecordRaw[] | any>(
(router.options.routes || []).filter((d: any) => d.meta && d.meta.activate),
);
const route = useRoute();
const isCollapse = ref(true);
const showMenu = ref(true);
@ -93,11 +99,9 @@ limitations under the License. -->
if (route.name === "ViewWidget") {
showMenu.value = false;
}
const changePage = (menu: RouteRecordRaw) => {
theme.value = ["VirtualMachine", "Kubernetes"].includes(String(menu.name)) ? "light" : "black";
};
const filterMenus = (menus: Recordable[]) => {
return menus.filter((d) => d.meta && !d.meta.notShow);
return menus.filter((d) => d.meta && !d.meta.notShow && d.meta.activate);
};
function setCollapse() {
open.value = true;
@ -112,6 +116,13 @@ limitations under the License. -->
isCollapse.value = true;
open.value = false;
}
watch(
() => route.name,
() => {
name.value = String(route.name);
},
);
</script>
<style lang="scss" scoped>
@ -132,12 +143,12 @@ limitations under the License. -->
.el-menu-vertical:not(.el-menu--collapse) {
width: 220px;
font-size: 14px;
font-size: $font-size-normal;
}
.logo-icon-collapse {
width: 65px;
margin: 5px 0 10px 0;
margin: 5px 0 10px;
text-align: center;
}
@ -169,7 +180,7 @@ limitations under the License. -->
.version {
color: #eee;
font-size: 12px;
font-size: $font-size-smaller;
cursor: pointer;
padding-left: 23px;
margin-bottom: 10px;

View File

@ -14,15 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import enTitles from "./menus/en";
const msg = {
general: "General Service",
...enTitles,
services: "Services",
service: "Service",
traces: "Traces",
metrics: "Metrics",
serviceMesh: "Service Mesh",
infrastructure: "Infrastructure",
virtualMachine: "Virtual Machine",
dashboardNew: "New Dashboard",
dashboardList: "Dashboard List",
logs: "Logs",
@ -35,12 +33,9 @@ const msg = {
mySQL: "MySQL/MariaDB",
serviceName: "Service Name",
technologies: "Technologies",
generalServicePanel: "General Service Panel",
health: "Health",
groupName: "Group Name",
topologies: "Topologies",
dataPanel: "Data Plane",
controlPanel: "Control Plane",
eventList: "Event List",
newDashboard: "Create a new dashboard",
dashboardEdit: "Edit the dashboard",
@ -99,14 +94,13 @@ const msg = {
editTab: "Enable editing tab names",
label: "Service Name",
id: "Service ID",
setRoot: "Set this to root",
setNormal: "Set this to normal",
setRoot: "Set Normal to Root",
setNormal: "Set Root to Normal",
export: "Export Dashboard Templates",
import: "Import Dashboard Templates",
yes: "Yes",
no: "No",
tableHeaderCol1: "Name of the first column of the table",
tableHeaderCol2: "Name of the second column of the table",
tableHeaderCol2: "Name of the last column of the table",
showXAxis: "Show X Axis",
showYAxis: "Show Y Axis",
nameError: "The dashboard name cannot be duplicate",
@ -117,20 +111,9 @@ const msg = {
rename: "Rename",
deleteTitle: "Are you sure you want to delete this?",
rootTitle: "Are you sure you want to set this?",
selfObservability: "Self Observability",
satellite: "Satellite",
skyWalkingServer: "SkyWalking Server",
functions: "Functions",
browser: "Browser",
linux: "Linux",
editWarning: "You are entering edit mode",
viewWarning: "You are entering view mode",
virtualDatabase: "Virtual Database",
virtualCache: "Virtual Cache",
reloadDashboards: "Reload dashboards",
kubernetesService: "Service",
kubernetesCluster: "Cluster",
kubernetes: "Kubernetes",
textUrl: "Text Hyperlink",
textAlign: "Text Align",
metricLabel: "Metric Label",
@ -156,9 +139,6 @@ const msg = {
enableAssociate: "Enable association",
text: "Text",
query: "Query",
postgreSQL: "PostgreSQL",
endpointTips: "The table shows up to 20 pieces of endpoints.",
apisix: "APISIX",
viewTrace: "View Related Traces",
relatedTraceOptions: "Related Trace Options",
setLatencyDuration: "Latency Related Metrics",
@ -173,6 +153,7 @@ const msg = {
legendOptions: "Legend Options",
showLegend: "Show Legend",
asTable: "As Table",
asSelector: "As Selector",
toTheRight: "To The Right",
legendValues: "Legend Values",
minDuration: "Minimal Request Duration",
@ -183,7 +164,6 @@ const msg = {
iframeSrc: "Iframe Link",
generateLink: "Generate Link",
setDuration: "Lock Query Duration",
openFunction: "OpenFunction",
period: "Period",
windows: "Windows",
seconds: "Seconds",
@ -282,7 +262,6 @@ const msg = {
aggregation: "Calculation",
unit: "Unit",
labelsIndex: "Label Subscript",
group: "Service Group",
browserView: "Browser",
sortOrder: "Sort Order",
chartType: "Chart Type",
@ -305,7 +284,8 @@ const msg = {
errorInfo: "Error Info",
stack: "Stack",
serviceVersion: "Service Version",
errorPage: "Error Page",
pagePath: "Page Path",
errorUrl: "Error Url",
category: "Category",
grade: "Grade",
relatedTraceLogs: "Related Logs",
@ -316,11 +296,12 @@ const msg = {
return: "Return",
isError: "Error",
contentType: "Content Type",
content: "Content",
content: "Timestamp - Content",
level: "Level",
viewLogs: "View Logs",
logsTagsTip: `Only tags defined in the core/default/searchableLogsTags are searchable.
Check more details on the Configuration Vocabulary page`,
keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this.",
keywordsOfContentLogTips: "Current storage of SkyWalking OAP server does not support this",
setEvent: "Set Event",
viewAttributes: "View",
attributes: "Attributes",
@ -375,20 +356,8 @@ const msg = {
addKeywordsOfContent: "Please input a keyword of content",
addExcludingKeywordsOfContent: "Please input a keyword of excluding content",
noticeTag: "Please press Enter after inputting a tag(key=value).",
conditionNotice: "Notice: Please press Enter after inputting a key of content, exclude key of content(key=value).",
conditionNotice: "Notice: Please press Enter after inputting a key of content, exclude key of content(key=value)",
language: "Language",
gateway: "Gateway",
virtualMQ: "Virtual MQ",
AWSCloud: "AWS Cloud",
AWSCloudEKS: "EKS",
AWSCloudS3: "S3",
AWSCloudDynamoDB: "DynamoDB",
AWSGateway: "AWS API Gateway",
APIGateway: "API Gateway",
redis: "Redis",
elasticsearch: "Elasticsearch",
mq: "MQ",
rabbitMQ: "RabbitMQ",
save: "Save",
editStrategy: "Edit Policies",
policyList: "Policy List",
@ -399,11 +368,34 @@ const msg = {
uriRegex: "URI Regex",
uriList: "URI List",
processes: "Processes",
monitorInstances: "Monitor Instances",
monitorInstances: "Monitoring Instances",
processDashboards: "Process Dashboards",
instanceDashboards: "Instance Dashboards",
detailLabel: "Detail Label",
summary: "Summary",
detail: "Detail",
marketplace: "Marketplace",
menus: "Menus",
saveReload: "Save and reload the page",
document: "Documentation",
addExpressions: "Add Expressions",
expressions: "Expression",
unhealthyExpression: "Unhealthy Expression",
traceDesc:
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
tabExpressions: "Tab Expressions",
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
valueMappings: "Value Mappings",
mappingTip: "Notice: The mapping key is a Regex string, e.g. ^([0-9])$",
valueDashboard: "Data Value Related Dashboard",
viewValueDashboard: "View Dashboard",
errorInstances: "Error Instances",
successInstances: "Success Instances",
profilingEvents: "Async Profiling Events",
execArgs: "Exec Args",
instances: "Instances",
snapshot: "Snapshot",
expression: "Expression",
};
export default msg;

View File

@ -14,15 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import esTitles from "./menus/es";
const msg = {
...esTitles,
general: "Servicio General",
services: "Servicios",
service: "Servicio",
traces: "Trazas",
metrics: "Métricas",
serviceMesh: "Malla de Servicios",
infrastructure: "Infraestructura",
virtualMachine: "Máquina Virtual",
dashboardNew: "Nuevo Panel",
dashboardList: "Listado Paneles",
logs: "Logs",
@ -35,12 +34,9 @@ const msg = {
mySQL: "MySQL/MariaDB",
serviceName: "Nombre Servicio",
technologies: "Tecnologías",
generalServicePanel: "Panel Servicio General",
health: "Salud",
groupName: "Nombre Grupo",
topologies: "Topologías",
dataPanel: "Plano de Datos",
controlPanel: "Plano de Control",
eventList: "Listado Eventos",
newDashboard: "Crear panel nuevo",
dashboardEdit: "Editar el panel",
@ -105,8 +101,7 @@ const msg = {
import: "Importar Plantilla Panel",
yes: "Sí",
no: "No",
tableHeaderCol1: "Nombre de la primera columna de la tabla",
tableHeaderCol2: "Nombre de la segunda columna de la tabla",
tableHeaderCol2: "Nombre de la Último columna de la tabla",
showXAxis: "Mostrar Eje X",
showYAxis: "Mostrar Eje Y",
nameError: "El nombre del panel no puede ser duplicado",
@ -117,20 +112,9 @@ const msg = {
rename: "Renombrar",
deleteTitle: "¿Está seguro que quiere eliminarlo?",
rootTitle: "¿Está seguro que quiere establecerlo?",
selfObservability: "Autoobservabilidad",
satellite: "Satéllite",
skyWalkingServer: "Servidor SkyWalking",
functions: "Funciones",
browser: "Navegador",
linux: "Linux",
editWarning: "Estás entrando en modo edición",
viewWarning: "Estás entrando en modo visualización",
virtualDatabase: "Base de Datos Virtual",
virtualCache: "Caché virtual",
reloadDashboards: "Recargar Panel",
kubernetesService: "Servicio",
kubernetesCluster: "Cluster",
kubernetes: "Kubernetes",
textUrl: "Hipervínculo de Texto",
textAlign: "Alineación de Texto",
metricLabel: "Etiqueta de Métrica",
@ -154,9 +138,6 @@ const msg = {
"El nombre sólo admite chino e inglés, líneas horizontales y subrayado, y la longitud del nombre no excederá de 300 caracteres",
enableAssociate: "Activar asociación",
query: "Consulta",
postgreSQL: "PostgreSQL",
endpointTips: "Aquí, la tabla muestra hasta 20 punto final.",
apisix: "APISIX",
queryOrder: "Consulta por duración",
setOrder: "Orden de consulta",
latency: "Retraso",
@ -166,7 +147,6 @@ const msg = {
iframeSrc: "Enlace Iframe",
generateLink: "Generar enlaces",
setDuration: "Duración de la consulta de bloqueo",
openFunction: "OpenFunction",
seconds: "Segundos",
hourTip: "Seleccione Hora",
minuteTip: "Seleccione Minuto",
@ -280,7 +260,6 @@ const msg = {
aggregation: "Cálculo",
unit: "Unidad",
labelsIndex: "Subíndice Etiqueta",
group: "Grupo Servicio",
browserView: "Navegador",
sortOrder: "Orden de clasificación",
chartType: "Tipo Gráfico",
@ -303,7 +282,8 @@ const msg = {
errorInfo: "Info Error",
stack: "Pila",
serviceVersion: "Versión Servicio",
errorPage: "Página de Error",
pagePath: "Página de Error",
errorUrl: "Ruta de Error",
category: "Categoría",
grade: "Grado",
relatedTraceLogs: "Registro de Datos Relacionados",
@ -315,10 +295,11 @@ const msg = {
isError: "Error",
contentType: "Tipo de Contenido",
content: "Contenido",
level: "Level",
viewLogs: "Ver Registro de Datos",
logsTagsTip: `Solamente etiquetas definidas en core/default/searchableLogsTags pueden ser buscadas.
Más información en la página de Vocabulario de Configuración`,
keywordsOfContentLogTips: "El almacenamiento actual del servidor SkyWalking OAP no lo soporta.",
keywordsOfContentLogTips: "El almacenamiento actual del servidor SkyWalking OAP no lo soporta",
setEvent: "Establecer Evento",
viewAttributes: "Ver",
serviceEvents: "Eventos Servico",
@ -375,18 +356,6 @@ const msg = {
conditionNotice:
"Aviso: Por favor presione Intro después de introducir una clave de contenido, excluir clave de contenido(clave=valor).",
language: "Lenguaje",
gateway: "Puerta",
virtualMQ: "MQ virtual",
AWSCloud: "AWS Cloud",
AWSCloudEKS: "EKS",
AWSCloudS3: "S3",
AWSCloudDynamoDB: "DynamoDB",
AWSGateway: "AWS API Gateway",
APIGateway: "API Gateway",
redis: "Redis",
elasticsearch: "Elasticsearch",
mq: "MQ",
rabbitMQ: "RabbitMQ",
save: "Salvar",
editStrategy: "Estrategia editorial",
policyList: "Lista de políticas",
@ -404,5 +373,29 @@ const msg = {
detailLabel: "Detail Label",
summary: "Summary",
detail: "Detail",
marketplace: "Marketplace",
menus: "Menus",
saveReload: "Save and reload the page",
document: "Documentation",
addExpressions: "Add Expressions",
expressions: "Expression",
unhealthyExpression: "Unhealthy Expression",
traceDesc:
"The trace segment serves as a representation of a trace portion executed within one single OS process, such as a JVM. It comprises a collection of spans, typically associated with and collected from a single request or execution context.",
tabExpressions: "Tab Expressions",
hierarchyNodeMetrics: "Metrics for Hierarchy Graph Node",
hierarchyNodeDashboard: "As dashboard for Hierarchy Graph Node",
valueMappings: "Value Mappings",
mappingTip: "Aviso: La clave de mapeo es una cadena Regex, p. ej. ^([0-9])$",
valueDashboard: "Data Value Related Dashboard",
viewValueDashboard: "View Dashboard",
errorInstances: "Error Instances",
successInstances: "Success Instances",
profilingEvents: "Async Profiling Events",
execArgs: "Exec Args",
instances: "Instances",
snapshot: "Snapshot",
expression: "Expression",
asSelector: "As Selector",
};
export default msg;

View File

@ -0,0 +1,147 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const titles = {
// General Service
general_service: "General Service",
general_service_desc:
"Observe services and relative direct dependencies through telemetry data collected from SkyWalking Agents.",
general_service_services: "Services",
general_service_services_desc: "Observe services through telemetry data collected from SkyWalking Agent.",
general_service_virtual_database: "Visual Database",
general_service_virtual_database_desc:
"Observe the virtual databases which are conjectured by language agents through various plugins.",
general_service_virtual_cache: "Visual Cache",
general_service_virtual_cache_desc:
"Observe the virtual cache servers which are conjectured by language agents through various plugins.",
general_service_virtual_mq: "Virtual MQ",
general_service_virtual_mq_desc:
"Observe the virtual message queue servers which are conjectured by language agents through various plugins.",
// Workflow Scheduler
workflow_scheduler: "Workflow Scheduler",
workflow_scheduler_desc: "Provide monitoring for workflow scheduling systems.",
workflow_scheduler_airflow: "Airflow",
workflow_scheduler_airflow_desc: "Observe tasks through telemetry data collected from Apache Airflow.",
// Service Mesh
service_mesh: "Service Mesh",
service_mesh_desc:
"Service Mesh(Istio) addresses the challenges developers and operators face with a distributed or microservices architecture.",
service_mesh_service: "Services",
service_mesh_service_desc:
"Observe Service Mesh through telemetry data collected from Envoy Access Log Service (ALS).",
service_mesh_control_plane: "Control Plane",
service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.",
service_mesh_data_plane: "Data Plane",
service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.",
// Kubernetes
kubernetes: "Kubernetes",
kubernetes_desc:
"Kubernetes is an open-source container orchestration system for automating software deployment, scaling, and management.",
kubernetes_cluster: "Cluster",
kubernetes_cluster_desc: "Provide monitoring of the status and resources of the K8S Cluster.",
kubernetes_service: "Service",
kubernetes_service_desc: "Observe Service status and resources from Kubernetes.",
// Infrastructure
infrastructure: "Infrastructure",
infrastructure_desc:
"Operation Systems act as the infrastructure of the whole IT system. Its observabilities provide the fundamentals for all distributed and modern complex systems running.",
infrastructure_linux: "Linux",
infrastructure_linux_desc: "Provide Linux Operation System(OS) monitoring.",
infrastructure_windows: "Windows",
infrastructure_windows_desc: "Provide Windows Operation System(OS) monitoring.",
// AWS Cloud
aws_cloud: "AWS Cloud",
aws_cloud_desc: "Amazon Web Services(AWS) offers reliable, scalable, and inexpensive cloud computing services.",
aws_cloud_eks: "EKS",
aws_cloud_eks_desc: "Provide AWS Cloud EKS monitoring through AWS Container Insights Receiver.",
aws_cloud_s3: "S3",
aws_cloud_s3_desc: "Provide AWS Cloud S3 monitoring through AWS FireHose Receiver.",
aws_cloud_dynamodb: "DynamoDB",
aws_cloud_dynamodb_desc: "Provide DynamoDB monitoring through AWS FireHose Receiver.",
aws_cloud_api_gateway: "API Gateway",
aws_cloud_api_gateway_desc: "Provide AWS Cloud API Gateway monitoring through AWS FireHose Receiver.",
// Browser
browser: "Browser",
browser_desc: "Provide Browser-Side monitoring of Web-App, Versions and Pages, through Apache SkyWalking Client JS.",
// Gateway
gateway: "Gateway",
gateway_desc:
"API gateway is an API management tool that sits between a client and a collection of backend services.",
gateway_nginx: "Nginx",
gateway_nginx_desc: "Provide Nginx monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_apisix: "APISIX",
gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_aws_api_gateway: "AWS API Gateway",
gateway_aws_api_gateway_desc: "Provide AWS Cloud API Gateway monitoring through AWS FireHose Receiver.",
// Database
database: "Database",
database_desc:
"The database is the organized collection of structured information, or data, typically stored electronically in a computer system.",
database_mysql_mariadb: "MySQL/MariaDB",
database_mysql_mariadb_desc:
"Provide MySQL and MariaDB Server monitoring through OpenTelemetry's Prometheus Receiver.",
database_postgresql: "PostgreSQL",
database_postgresql_desc: "Provide PostgreSQL monitoring through OpenTelemetry's Prometheus Receiver.",
database_dynamodb: "DynamoDB",
database_dynamodb_desc: "Provide DynamoDB monitoring through Amazon CloudWatch.",
database_redis: "Redis",
database_redis_desc: "Provide Redis monitoring through OpenTelemetry's Prometheus Receiver.",
database_elasticsearch: "Elasticsearch",
database_elasticsearch_desc: "Provide Elasticsearch Server monitoring through OpenTelemetry's Prometheus Receiver.",
database_mongodb: "MongoDB",
database_mongodb_desc: "Provide MongoDB monitoring through OpenTelemetry's Prometheus Receiver.",
// Message Queue
mq: "Message Queue",
mq_desc:
"A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.",
mq_rabbitmq: "RabbitMQ",
mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.",
mq_kafka: "Kafka",
mq_kafka_desc: "Provide Kafka monitoring through OpenTelemetry's Prometheus Receiver.",
mq_pulsar: "Pulsar",
mq_pulsar_desc: "Provide Pulsar monitoring through OpenTelemetry's Prometheus Receiver.",
mq_rocketmq: "RocketMQ",
mq_rocketmq_desc: "Provide RocketMQ monitoring through OpenTelemetry's Prometheus Receiver.",
// self observability
self_observability: "Self Observability",
self_observability_desc:
"Self Observability provides the observabilities for running components and servers from the SkyWalking ecosystem.",
self_observability_oap: "SkyWalking Server",
self_observability_oap_desc:
"The OAP backend cluster itself is a distributed streaming process system, this is the monitoring for the OAP backend itself.",
self_observability_satellite: "Satellite",
self_observability_satellite_desc:
"Satellite: an open-source agent designed for the cloud-native infrastructures, which provides a low-cost, high-efficient, and more secure way to collect telemetry data. It is the recommended load balancer for telemetry collecting.",
self_observability_java_agent: "SkyWalking Java Agent",
self_observability_java_agent_desc:
"The self observability of SkyWalking Java Agent, which provides the abilities to measure the tracing performance and error statistics of plugins.",
self_observability_go_agent: "SkyWalking Go Agent",
self_observability_go_agent_desc:
"The self observability of SkyWalking Go Agent, which provides the abilities to measure the tracing performance and error statistics of plugins.",
cilium: "Cilium",
cilium_desc:
"Cilium is a CNI plugin for Kubernetes that provides eBPF-based networking, security, and load balancing.",
cilium_service: "Cilium Service",
cilium_service_desc: "Observe Service status and resources from Cilium Hubble.",
data_processing_engine: "Data Processing Engine",
data_processing_engine_desc:
"A data processing engine is a system designed to efficiently process, transform, and analyze large-scale data in real time or batch mode.",
data_processing_engine_flink: "Flink",
data_processing_engine_flink_desc:
"Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments, perform computations at in-memory speed and at any scale.",
};
export default titles;

View File

@ -0,0 +1,148 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const titles = {
// General Service
general_service: "Servicio General",
general_service_desc:
"Observar el servicio y las dependencias relativamente directas a través de los datos de telemetría recopilados del agente skywalking.",
general_service_services: "Servicios",
general_service_services_desc: "Observe services through telemetry data collected from SkyWalking Agent.",
general_service_virtual_database: "Base de Datos Virtual",
general_service_virtual_database_desc:
"Observe the virtual databases which are conjectured by language agents through various plugins.",
general_service_virtual_cache: "Caché virtual",
general_service_virtual_cache_desc:
"Observe the virtual cache servers which are conjectured by language agents through various plugins.",
general_service_virtual_mq: "MQ virtual",
general_service_virtual_mq_desc:
"Observe the virtual message queue servers which are conjectured by language agents through various plugins.",
// Workflow Scheduler
workflow_scheduler: "Flujo de trabajo",
workflow_scheduler_desc: "Proporcionar monitoreo para sistemas de programación de flujos de trabajo.",
workflow_scheduler_airflow: "Airflow",
workflow_scheduler_airflow_desc:
"Observando tareas a través de los datos de telemetría recopilados desde Apache Airflow.",
// Service Mesh
service_mesh: "Malla de Servicios",
service_mesh_desc:
"La red de servicios (istio) resuelve los desafíos que enfrentan los desarrolladores y operadores a través de una arquitectura distribuida o de microservicio.",
service_mesh_service: "Servicios",
service_mesh_service_desc:
"Observe Service Mesh through telemetry data collected from Envoy Access Log Service (ALS).",
service_mesh_control_plane: "Plano de Control",
service_mesh_control_plane_desc: "Provide monitoring of the behavior of Istio through its self-monitoring metrics.",
service_mesh_data_plane: "Plano de Datos",
service_mesh_data_plane_desc: "Observe Envoy Proxy through Envoy Metrics Service.",
// Kubernetes
kubernetes: "Kubernetes",
kubernetes_desc:
"Kubernetes is an open-source container orchestration system for automating software deployment, scaling, and management.",
kubernetes_cluster: "Cluster",
kubernetes_cluster_desc: "Provide monitoring of the status and resources of the K8S Cluster.",
kubernetes_service: "Servicio",
kubernetes_service_desc: "Observe Service status and resources from Kubernetes.",
// Infrastructure
infrastructure: "Infraestructura",
infrastructure_desc:
"Operation Systems act as the infrastructure of the whole IT system. Its observabilities provide the fundamentals for all distributed and modern complex systems running.",
infrastructure_linux: "Linux",
infrastructure_linux_desc: "Provide Linux Operation System(OS) monitoring.",
infrastructure_windows: "Windows",
infrastructure_windows_desc: "Provide Windows Operation System(OS) monitoring.",
// AWS Cloud
aws_cloud: "AWS Cloud",
aws_cloud_desc: "Amazon Web Services(AWS) offers reliable, scalable, and inexpensive cloud computing services.",
aws_cloud_eks: "EKS",
aws_cloud_eks_desc: "Provide AWS Cloud EKS monitoring through AWS Container Insights Receiver.",
aws_cloud_s3: "S3",
aws_cloud_s3_desc: "Provide AWS Cloud S3 monitoring through AWS FireHose Receiver.",
aws_cloud_dynamodb: "DynamoDB",
aws_cloud_dynamodb_desc: "Provide DynamoDB monitoring through Amazon CloudWatch.",
aws_cloud_api_gateway: "API Gateway",
aws_cloud_api_gateway_desc: "Provide AWS Cloud API Gateway monitoring through AWS FireHose Receiver.",
// Browser
browser: "Navegador",
browser_desc: "Provide Browser-Side monitoring of Web-App, Versions and Pages, through Apache SkyWalking Client JS.",
// Gateway
gateway: "Puerta",
gateway_desc:
"API gateway is an API management tool that sits between a client and a collection of backend services.",
gateway_nginx: "Nginx",
gateway_nginx_desc: "Provide Nginx monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_apisix: "APISIX",
gateway_apisix_desc: "Provide APISIX monitoring through OpenTelemetry's Prometheus Receiver.",
gateway_aws_api_gateway: "AWS API Gateway",
gateway_aws_api_gateway_desc: "Provide AWS Cloud API Gateway monitoring through AWS FireHose Receiver.",
// Database
database: "Base de Datos",
database_desc:
"The database is the organized collection of structured information, or data, typically stored electronically in a computer system.",
database_mysql_mariadb: "MySQL/MariaDB",
database_mysql_mariadb_desc:
"Provide MySQL and MariaDB Server monitoring through OpenTelemetry's Prometheus Receiver.",
database_postgresql: "PostgreSQL",
database_postgresql_desc: "Provide PostgreSQL monitoring through OpenTelemetry's Prometheus Receiver.",
database_dynamodb: "DynamoDB",
database_dynamodb_desc: "Provide DynamoDB monitoring through Amazon CloudWatch.",
database_redis: "Redis",
database_redis_desc: "Provide Redis monitoring through OpenTelemetry's Prometheus Receiver.",
database_elasticsearch: "Elasticsearch",
database_elasticsearch_desc: "Provide Elasticsearch Server monitoring through OpenTelemetry's Prometheus Receiver.",
database_mongodb: "MongoDB",
database_mongodb_desc: "Provide MongoDB monitoring through OpenTelemetry's Prometheus Receiver.",
// Message Queue
mq: "Message Queue",
mq_desc:
"A message queue is a form of asynchronous service-to-service communication used in serverless and microservices architectures.",
mq_rabbitmq: "RabbitMQ",
mq_rabbitmq_desc: "Provide RabbitMQ monitoring through OpenTelemetry's Prometheus Receiver.",
mq_kafka: "Kafka",
mq_kafka_desc: "Provide Kafka monitoring through OpenTelemetry's Prometheus Receiver.",
mq_pulsar: "Pulsar",
mq_pulsar_desc: "Provide Pulsar monitoring through OpenTelemetry's Prometheus Receiver.",
mq_rocketmq: "RocketMQ",
mq_rocketmq_desc: "Provide RocketMQ monitoring through OpenTelemetry's Prometheus Receiver.",
// self observability
self_observability: "Self Observability",
self_observability_desc:
"Self Observability provides the observabilities for running components and servers from the SkyWalking ecosystem.",
self_observability_oap: "SkyWalking Server",
self_observability_oap_desc:
"The OAP backend cluster itself is a distributed streaming process system, this is the monitoring for the OAP backend itself.",
self_observability_satellite: "Satellite",
self_observability_satellite_desc:
"Satellite: an open-source agent designed for the cloud-native infrastructures, which provides a low-cost, high-efficient, and more secure way to collect telemetry data. It is the recommended load balancer for telemetry collecting.",
self_observability_java_agent: "SkyWalking Java Agent",
self_observability_java_agent_desc:
"La auto-observabilidad de SkyWalking Java Agent, que proporciona la capacidad de medir el rendimiento del trazado y las estadísticas de errores de los plugins.",
self_observability_go_agent: "SkyWalking Go Agent",
self_observability_go_agent_desc:
"La auto-observabilidad de SkyWalking Go Agent, que proporciona la capacidad de medir el rendimiento del trazado y las estadísticas de errores de los plugins.",
cilium: "Cilium",
cilium_desc:
"Cilium es un complemento CNI para Kubernetes que proporciona redes, seguridad y equilibrio de carga basados en eBPF.",
cilium_service: "Cilium Service",
cilium_service_desc: "Observe el estado del servicio y los recursos de Cilium Hubble.",
data_processing_engine: "Data Processing Engine",
data_processing_engine_desc:
"A data processing engine is a system designed to efficiently process, transform, and analyze large-scale data in real time or batch mode.",
data_processing_engine_flink: "Flink",
data_processing_engine_flink_desc:
"Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments, perform computations at in-memory speed and at any scale.",
};
export default titles;

View File

@ -0,0 +1,129 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const titles = {
// General Service
general_service: "常规服务",
general_service_desc: "通过从SkyWalking代理收集的遥测数据来观察服务和相对直接的依赖关系。",
general_service_services: "服务",
general_service_services_desc: "通过SkyWalking Agent收集的遥测数据观察服务。",
general_service_virtual_database: "虚拟数据库",
general_service_virtual_database_desc: "观察语言代理通过各种插件推测的虚拟数据库。",
general_service_virtual_cache: "虚拟缓存",
general_service_virtual_cache_desc: "观察语言代理通过各种插件推测的虚拟缓存服务器。",
general_service_virtual_mq: "虚拟消息队列",
general_service_virtual_mq_desc: "观察语言代理通过各种插件推测的虚拟消息队列服务器。",
// Workflow Scheduler
workflow_scheduler: "工作流调度",
workflow_scheduler_desc: "提供工作流调度系统监控。",
workflow_scheduler_airflow: "Airflow",
workflow_scheduler_airflow_desc: "通过从Apache Airflow收集的遥测数据观察任务。",
// Service Mesh
service_mesh: "服务网格",
service_mesh_desc: "服务网格Istio通过分布式或微服务架构解决了开发人员和运营商面临的挑战。",
service_mesh_service: "服务",
service_mesh_service_desc: "通过从Envoy访问日志服务ALS收集的遥测数据观察服务网格。",
service_mesh_control_plane: "控制平面",
service_mesh_control_plane_desc: "通过Istio的自我监控指标提供对其行为的监控。",
service_mesh_data_plane: "数据平面",
service_mesh_data_plane_desc: "通过Envoy Metrics Service观察Envoy Proxy。",
// Kubernetes
kubernetes: "Kubernetes",
kubernetes_desc: "Kubernetes是一个开源的容器编排系统用于自动化软件部署、扩展和管理。",
kubernetes_cluster: "集群",
kubernetes_cluster_desc: "提供对K8S集群的状态和资源的监控。",
kubernetes_service: "服务",
kubernetes_service_desc: "从Kubernetes中观察服务状态和资源。",
// Infrastructure
infrastructure: "基础设施",
infrastructure_desc: "操作系统是整个IT系统的基础设施。它的可观察性为所有分布式和现代复杂系统的运行提供了基础。",
infrastructure_linux: "Linux",
infrastructure_linux_desc: "提供Linux操作系统OS监控。",
infrastructure_windows: "Windows",
infrastructure_windows_desc: "提供Windows操作系统OS监控。",
// AWS Cloud
aws_cloud: "AWS云服务",
aws_cloud_desc: "亚马逊网络服务AWS提供可靠、可扩展且价格低廉的云计算服务。",
aws_cloud_eks: "EKS",
aws_cloud_eks_desc: "通过AWS Container Insights Receiver提供AWS Cloud EKS监控。",
aws_cloud_s3: "S3",
aws_cloud_s3_desc: "通过AWS FireHose Receiver提供AWS Cloud S3监控",
aws_cloud_dynamodb: "DynamoDB",
aws_cloud_dynamodb_desc: "通过AWS FireHose Receiver提供DynamoDB监控。",
aws_cloud_api_gateway: "API Gateway",
aws_cloud_api_gateway_desc: "通过AWS FireHose Receiver提供AWS Cloud API网关监控。",
// Browser
browser: "Browser",
browser_desc: "通过Apache SkyWalking Client JS提供Web应用程序、版本和页面的浏览器端监控。",
// Gateway
gateway: "网关",
gateway_desc: "API网关是位于客户端和后端服务集合之间的API管理工具。",
gateway_nginx: "Nginx",
gateway_nginx_desc: "通过OpenTelemetry的Prometheus接收器提供Nginx监控。",
gateway_apisix: "APISIX",
gateway_apisix_desc: "通过OpenTelemetry的Prometheus接收器提供APISIX监控。",
gateway_aws_api_gateway: "AWS API Gateway",
gateway_aws_api_gateway_desc: "通过AWS FireHose Receiver提供AWS Cloud API网关监控。",
// Database
database: "数据库",
database_desc: "数据库是结构化信息或数据的有组织的集合,通常以电子方式存储在计算机系统中。",
database_mysql_mariadb: "MySQL/MariaDB",
database_mysql_mariadb_desc: "通过OpenTelemetry的Prometheus接收器提供MySQL和MariaDB服务器监控。",
database_postgresql: "PostgreSQL",
database_postgresql_desc: "通过OpenTelemetry的Prometheus接收器提供PostgreSQL监控。",
database_dynamodb: "DynamoDB",
database_dynamodb_desc: "通过AWS FireHose Receiver提供DynamoDB监控。",
database_redis: "Redis",
database_redis_desc: "通过OpenTelemetry的Prometheus接收器提供Redis监控。",
database_elasticsearch: "Elasticsearch",
database_elasticsearch_desc: "通过OpenTelemetry的Prometheus接收器提供Elasticsearch服务器监控。",
database_mongodb: "MongoDB",
database_mongodb_desc: "通过OpenTelemetry的Prometheus接收器提供MongoDB监控。",
// Message Queue
mq: "消息队列",
mq_desc: "消息队列是无服务器和微服务架构中使用的异步服务对服务通信的一种形式。",
mq_rabbitmq: "RabbitMQ",
mq_rabbitmq_desc: "通过OpenTelemetry的Prometheus接收器提供RabbitMQ监控。",
mq_kafka: "Kafka",
mq_Kafka_desc: "通过OpenTelemetry的Prometheus接收器提供Kafka监控。",
mq_pulsar: "Pulsar",
mq_Pulsar_desc: "通过OpenTelemetry的Prometheus接收器提供Pulsar监控。",
mq_rocketmq: "RocketMQ",
mq_rocketmq_desc: "通过OpenTelemetry的Prometheus接收器提供RocketMQ监控。",
// self observability
self_observability: "自监控",
self_observability_desc: "自观察性为运行SkyWalking生态系统中的组件和服务器提供了可观察性。",
self_observability_oap: "SkyWalking服务",
self_observability_oap_desc: "OAP后端集群本身是一个分布式流处理系统这是对OAP后端本身的监控。",
self_observability_satellite: "Satellite",
self_observability_satellite_desc:
"Satellite为云原生基础设施设计的开源代理提供了一种低成本、高效、更安全的遥测数据收集方式。它是遥测采集的推荐负载均衡器。",
self_observability_java_agent: "SkyWalking Java Agent",
self_observability_java_agent_desc: "SkyWalking Java Agent 自监控提供了对 agent 插件的性能追踪和错误统计。",
self_observability_go_agent: "SkyWalking Go Agent",
self_observability_go_agent_desc: "SkyWalking Go Agent 自监控提供了对 agent 插件的性能追踪和错误统计。",
cilium: "Cilium",
cilium_desc: "Cilium是Kubernetes上的CNI插件提供基于eBPF的网络、安全和负载均衡。",
cilium_service: "Cilium服务",
cilium_service_desc: "通过Cilium Hubble收集的遥测数据观察服务。",
data_processing_engine: "数据处理引擎",
data_processing_engine_desc: "数据处理引擎是一个用于高效地在实时或批处理模式下处理、转换和分析大规模数据的系统。",
data_processing_engine_flink: "Flink",
data_processing_engine_flink_desc:
"Apache Flink 是一个框架和分布式处理引擎用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。",
};
export default titles;

View File

@ -14,14 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import zhTitles from "./menus/zh";
const msg = {
general: "普通服务",
...zhTitles,
services: "服务",
traces: "跟踪",
metrics: "指标",
serviceMesh: "服务网格",
infrastructure: "基础设施",
virtualMachine: "虚拟机",
dashboardNew: "新建仪表板",
dashboardHome: "仪表盘首页",
dashboardList: "仪表盘列表",
@ -38,8 +36,6 @@ const msg = {
health: "健康",
groupName: "群名称",
topologies: "拓扑图",
dataPanel: "数据平面",
controlPanel: "控制平面",
eventList: "事件列表",
newDashboard: "新增仪表盘",
dashboardEdit: "编辑仪表盘",
@ -103,8 +99,7 @@ const msg = {
import: "导入仪表板模板",
yes: "是",
no: "否",
tableHeaderCol1: "表格的第一列的名称",
tableHeaderCol2: "表格的第二列的名称",
tableHeaderCol2: "表格的最后一列的名称",
showXAxis: "显示X轴",
showYAxis: "显示Y轴",
nameError: "仪表板名称不能重复",
@ -115,20 +110,9 @@ const msg = {
rename: "重命名",
deleteTitle: "确定删除吗?",
rootTitle: "确定设置为Root吗",
selfObservability: "自监控",
satellite: "Satellite",
skyWalkingServer: "SkyWalking服务",
functions: "Functions",
linux: "Linux",
browser: "浏览器",
editWarning: "你正在进入编辑模式",
viewWarning: "你正在进入预览模式",
virtualDatabase: "虚拟数据库",
virtualCache: "虚拟缓存",
reloadDashboards: "重新加载仪表盘",
kubernetesService: "服务",
kubernetesCluster: "集群",
kubernetes: "Kubernetes",
textUrl: "文本超链接",
textAlign: "文本对齐",
metricLabel: "指标标签",
@ -153,9 +137,6 @@ const msg = {
duplicateName: "重复的名称",
text: "文本",
query: "查询",
postgreSQL: "PostgreSQL",
endpointTips: "这里最多展示20条endpoints。",
apisix: "APISIX",
viewTrace: "查看相关Trace",
relatedTraceOptions: "相关的Trace选项",
setLatencyDuration: "延迟相关指标",
@ -170,6 +151,7 @@ const msg = {
legendOptions: "图例选项",
showLegend: "显示图例",
asTable: "作为表格",
asSelector: "作为选择器",
toTheRight: "在右边",
legendValues: "图例值",
minDuration: "最小请求持续时间",
@ -180,7 +162,6 @@ const msg = {
iframeSrc: "Iframe链接",
generateLink: "生成链接",
setDuration: "锁定查询持续时间",
openFunction: "OpenFunction",
period: "周期",
windows: "Windows",
seconds: "秒",
@ -283,7 +264,6 @@ const msg = {
aggregation: "计算",
unit: "单位",
labelsIndex: "标签下标",
group: "服务组",
browserView: "浏览器视图",
sortOrder: "排序方式",
chartType: "图表类型",
@ -301,7 +281,8 @@ const msg = {
errorInfo: "错误信息",
stack: "堆栈",
serviceVersion: "服务版本",
errorPage: "错误页面",
pagePath: "错误页面",
errorUrl: "错误路径",
category: "类别",
grade: "等级",
relatedTraceLogs: "相关的日志",
@ -312,7 +293,8 @@ const msg = {
return: "返回",
isError: "错误",
contentType: "内容类型",
content: "内容",
content: "时间戳 - 内容",
level: "Level",
viewLogs: "查看日志",
logsTagsTip: "只有core/default/searchableLogsTags中定义的标记才可搜索。查看配置词汇表页面上的更多详细信息。",
keywordsOfContentLogTips: "SkyWalking OAP服务器的当前存储不支持此操作",
@ -373,18 +355,6 @@ const msg = {
noticeTag: "请输入一个标签(key=value)之后回车",
conditionNotice: "请输入一个内容关键词或者内容不包含的关键词(key=value)之后回车",
language: "语言",
gateway: "网关",
virtualMQ: "虚拟消息队列",
AWSCloud: "AWS云服务",
AWSCloudEKS: "EKS",
AWSCloudS3: "S3",
AWSCloudDynamoDB: "DynamoDB",
AWSGateway: "AWS API Gateway",
APIGateway: "API Gateway",
redis: "Redis",
elasticsearch: "Elasticsearch",
mq: "消息队列",
rabbitMQ: "RabbitMQ",
save: "保存",
editStrategy: "编辑策略",
policyList: "策略列表",
@ -402,5 +372,28 @@ const msg = {
detailLabel: "详细标签",
summary: "概括",
detail: "详细",
marketplace: "市场",
menusManagement: "菜单",
saveReload: "保存并重新加载页面",
document: "文档",
addExpressions: "添加表达式",
expressions: "表达式",
unhealthyExpression: "非健康表达式",
traceDesc:
"Trace Segment代表在单一操作系统进程例如JVM中执行的追踪部分。它包含了一组跨度spans这些跨度通常与单一请求或执行上下文关联。",
tabExpressions: "Tab表达式",
hierarchyNodeMetrics: "层次图节点的指标",
hierarchyNodeDashboard: "作为层次图节点的dashboard",
valueMappings: "值映射",
mappingTip: "注意: 映射键是一个正则表达式字符串,比如 ^([0-9])$",
valueDashboard: "数据值相关的仪表板",
viewValueDashboard: "查看仪表板",
errorInstances: "错误的实例",
successInstances: "成功的实例",
profilingEvents: "异步分析事件",
execArgs: "String任务扩展",
instances: "实例",
snapshot: "快照",
expression: "表达式",
};
export default msg;

View File

@ -15,8 +15,8 @@
* limitations under the License.
*/
import { createApp } from "vue";
import { ElLoading } from "element-plus";
import App from "./App.vue";
import router from "./router";
import { store } from "./store";
import components from "@/components";
import i18n from "./locales";
@ -24,6 +24,11 @@ import { useAppStoreWithOut } from "@/store/modules/app";
import "./styles/index.ts";
import "virtual:svg-icons-register";
const loading = ElLoading.service({
lock: true,
text: "Loading...",
background: "rgba(0, 0, 0, 0.8)",
});
const app = createApp(App);
const appStore = useAppStoreWithOut();
@ -33,6 +38,9 @@ app.use(store);
mountApp();
async function mountApp() {
await appStore.getActivateMenus();
await appStore.queryOAPTimeInfo();
app.use(router).mount("#app");
const router = await import("./router");
app.use(router.default).mount("#app");
loading.close();
}

View File

@ -16,22 +16,25 @@
*/
import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue";
import Alarm from "@/views/Alarm.vue";
export const routesAlarm: Array<RouteRecordRaw> = [
{
path: "",
name: "Alarm",
meta: {
title: "alarm",
i18nKey: "alarm",
icon: "spam",
hasGroup: false,
activate: true,
title: "Alerting",
},
component: Layout,
children: [
{
path: "/alerting",
name: "Alarm",
component: () => import("@/views/Alarm.vue"),
name: "ViewAlarm",
component: Alarm,
},
],
},

View File

@ -16,6 +16,10 @@
*/
import type { RouteRecordRaw } from "vue-router";
import Layout from "@/layout/Index.vue";
import List from "@/views/dashboard/List.vue";
import New from "@/views/dashboard/New.vue";
import Edit from "@/views/dashboard/Edit.vue";
import Widget from "@/views/dashboard/Widget.vue";
export const routesDashboard: Array<RouteRecordRaw> = [
{
@ -23,51 +27,57 @@ export const routesDashboard: Array<RouteRecordRaw> = [
component: Layout,
name: "Dashboard",
meta: {
title: "dashboards",
i18nKey: "dashboards",
icon: "dashboard_customize",
hasGroup: true,
activate: true,
title: "Dashboards",
},
children: [
{
path: "/dashboard/list",
component: () => import("@/views/dashboard/List.vue"),
component: List,
name: "List",
meta: {
title: "dashboardList",
i18nKey: "dashboardList",
activate: true,
title: "Dashboard List",
},
},
{
path: "/dashboard/new",
component: () => import("@/views/dashboard/New.vue"),
component: New,
name: "New",
meta: {
title: "dashboardNew",
i18nKey: "dashboardNew",
activate: true,
title: "New Dashboard",
},
},
{
path: "",
redirect: "/dashboard/:layerId/:entity/:name",
name: "Create",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
meta: {
notShow: true,
},
children: [
{
path: "/dashboard/:layerId/:entity/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "CreateChild",
},
{
path: "/dashboard/:layerId/:entity/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "CreateActiveTabIndex",
},
],
},
{
path: "",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "View",
redirect: "/dashboard/:layerId/:entity/:serviceId/:name",
meta: {
@ -76,12 +86,12 @@ export const routesDashboard: Array<RouteRecordRaw> = [
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewChild",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewActiveTabIndex",
},
],
@ -89,20 +99,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{
path: "",
redirect: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
name: "ViewServiceRelation",
component: Edit,
name: "ServiceRelations",
meta: {
notShow: true,
},
children: [
{
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewServiceRelation",
},
{
path: "/dashboard/related/:layerId/:entity/:serviceId/:destServiceId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewServiceRelationActiveTabIndex",
},
],
@ -110,20 +120,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{
path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
name: "ViewPod",
component: Edit,
name: "Pods",
meta: {
notShow: true,
},
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewPod",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewPodActiveTabIndex",
},
],
@ -131,20 +141,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{
path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
name: "ViewProcess",
component: Edit,
name: "Processes",
meta: {
notShow: true,
},
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewProcess",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewProcessActiveTabIndex",
},
],
@ -152,20 +162,20 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{
path: "",
redirect: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
name: "PodRelation",
component: Edit,
name: "PodRelations",
meta: {
notShow: true,
},
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewPodRelation",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:destServiceId/:destPodId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewPodRelationActiveTabIndex",
},
],
@ -174,25 +184,25 @@ export const routesDashboard: Array<RouteRecordRaw> = [
path: "",
redirect:
"/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
name: "ProcessRelation",
component: Edit,
name: "ProcessRelations",
meta: {
notShow: true,
},
children: [
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewProcessRelation",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/tab/:activeTabIndex",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewProcessRelationActiveTabIndex",
},
{
path: "/dashboard/:layerId/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:name/duration/:duration",
component: () => import("@/views/dashboard/Edit.vue"),
component: Edit,
name: "ViewProcessRelationDuration",
},
],
@ -200,14 +210,14 @@ export const routesDashboard: Array<RouteRecordRaw> = [
{
path: "",
name: "Widget",
component: () => import("@/views/dashboard/Widget.vue"),
component: Widget,
meta: {
notShow: true,
},
children: [
{
path: "/page/:layer/:entity/:serviceId/:podId/:processId/:destServiceId/:destPodId/:destProcessId/:config/:duration?",
component: () => import("@/views/dashboard/Widget.vue"),
component: Widget,
name: "ViewWidget",
},
],

View File

@ -1,95 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default [
{
path: "",
name: "AWSCloud",
meta: {
title: "AWSCloud",
icon: "cloud_queue",
hasGroup: true,
},
redirect: "/aws-eks",
children: [
{
path: "/aws-eks",
name: "AWSCloudEKS",
meta: {
title: "AWSCloudEKS",
layer: "AWS_EKS",
},
},
{
path: "/aws-eks/tab/:activeTabIndex",
name: "EKSActiveTabIndex",
meta: {
notShow: true,
layer: "AWS_EKS",
},
},
{
path: "/aws-s3",
name: "AWSCloudS3",
meta: {
title: "AWSCloudS3",
layer: "AWS_S3",
},
},
{
path: "/aws-s3/tab/:activeTabIndex",
name: "S3ActiveTabIndex",
meta: {
notShow: true,
layer: "AWS_S3",
},
},
{
path: "/aws-dynamodb",
name: "AWSCloudDynamoDB",
meta: {
title: "AWSCloudDynamoDB",
layer: "AWS_DYNAMODB",
},
},
{
path: "/aws-dynamodb/tab/:activeTabIndex",
name: "DynamoDBActiveTabIndex",
meta: {
notShow: true,
layer: "AWS_DYNAMODB",
},
},
{
path: "/aws-api-gateway",
name: "APIGateway",
meta: {
title: "APIGateway",
layer: "AWS_GATEWAY",
},
},
{
path: "/aws-api-gateway/tab/:activeTabIndex",
name: "APIGatewayActiveTabIndex",
meta: {
notShow: true,
layer: "AWS_GATEWAY",
},
},
],
},
];

View File

@ -1,111 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default [
{
path: "",
name: "Database",
meta: {
title: "database",
icon: "storage",
hasGroup: true,
},
redirect: "/mySQL",
children: [
{
path: "/mySQL",
name: "MySQL",
meta: {
title: "mySQL",
layer: "MYSQL",
},
},
{
path: "/mySQL/tab/:activeTabIndex",
name: "MySQLActiveTabIndex",
meta: {
notShow: true,
layer: "MYSQL",
},
},
{
path: "/postgreSQL",
name: "PostgreSQL",
meta: {
title: "postgreSQL",
layer: "POSTGRESQL",
},
},
{
path: "/postgreSQL/tab/:activeTabIndex",
name: "PostgreSQLActiveTabIndex",
meta: {
notShow: true,
layer: "POSTGRESQL",
},
},
{
path: "/aws-dynamodb",
name: "AWSCloudDynamoDB",
meta: {
title: "AWSCloudDynamoDB",
layer: "AWS_DYNAMODB",
},
},
{
path: "/aws-dynamodb/tab/:activeTabIndex",
name: "DynamoDBActiveTabIndex",
meta: {
notShow: true,
layer: "AWS_DYNAMODB",
},
},
{
path: "/redis",
name: "Redis",
meta: {
title: "redis",
layer: "REDIS",
},
},
{
path: "/redis/tab/:activeTabIndex",
name: "RedisActiveTabIndex",
meta: {
notShow: true,
layer: "REDIS",
},
},
{
path: "/elasticsearch",
name: "Elasticsearch",
meta: {
title: "elasticsearch",
layer: "ELASTICSEARCH",
},
},
{
path: "/elasticsearch/tab/:activeTabIndex",
name: "ElasticsearchActiveTabIndex",
meta: {
notShow: true,
layer: "ELASTICSEARCH",
},
},
],
},
];

View File

@ -1,63 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default [
{
path: "",
name: "Gateway",
meta: {
title: "gateway",
icon: "gateway",
hasGroup: true,
},
redirect: "/apisix",
children: [
{
path: "/apisix",
name: "APISIX",
meta: {
title: "apisix",
layer: "APISIX",
},
},
{
path: "/apisix/tab/:activeTabIndex",
name: "APISIXActiveTabIndex",
meta: {
notShow: true,
layer: "APISIX",
},
},
{
path: "/aws-gateway",
name: "AWSGateway",
meta: {
title: "AWSGateway",
layer: "AWS_GATEWAY",
},
},
{
path: "/aws-gateway/tab/:activeTabIndex",
name: "GatewayActiveTabIndex",
meta: {
notShow: true,
layer: "AWS_GATEWAY",
},
},
],
},
];

View File

@ -1,94 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default [
{
path: "",
name: "General",
meta: {
title: "general",
icon: "chart",
hasGroup: true,
},
children: [
{
path: "/general",
name: "GeneralServices",
meta: {
title: "services",
layer: "GENERAL",
},
},
{
path: "/general/tab/:activeTabIndex",
name: "GeneralServicesActiveTabIndex",
meta: {
notShow: true,
layer: "GENERAL",
},
},
{
path: "/database",
name: "VirtualDatabase",
meta: {
title: "virtualDatabase",
layer: "VIRTUAL_DATABASE",
},
},
{
path: "/database/tab/:activeTabIndex",
name: "VirtualDatabaseActiveTabIndex",
meta: {
notShow: true,
layer: "VIRTUAL_DATABASE",
},
},
{
path: "/cache",
name: "VirtualCache",
meta: {
title: "virtualCache",
layer: "VIRTUAL_CACHE",
},
},
{
path: "/cache/tab/:activeTabIndex",
name: "VirtualCacheActiveTabIndex",
meta: {
notShow: true,
layer: "VIRTUAL_CACHE",
},
},
{
path: "/mq",
name: "VirtualMQ",
meta: {
title: "virtualMQ",
layer: "VIRTUAL_MQ",
},
},
{
path: "/mq/tab/:activeTabIndex",
name: "VirtualMQActiveTabIndex",
meta: {
notShow: true,
layer: "VIRTUAL_MQ",
},
},
],
},
];

View File

@ -1,41 +0,0 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import general from "./general";
import serviceMesh from "./serviceMesh";
import database from "./database";
import infrastructure from "./infrastructure";
import selfObservability from "./selfObservability";
import functions from "./functions";
import browser from "./browser";
import k8s from "./k8s";
import gateway from "./gateway";
import aws from "./aws";
import mq from "./mq";
export default [
...general,
...serviceMesh,
...functions,
...k8s,
...infrastructure,
...aws,
...browser,
...gateway,
...database,
...mq,
...selfObservability,
];

Some files were not shown because too many files have changed in this diff Show More