@perses-dev/tempo-plugin 0.48.0 → 0.49.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/TraceQLEditor.js +57 -16
- package/dist/cjs/components/complete.js +27 -8
- package/dist/cjs/index.js +1 -2
- package/dist/cjs/model/index.js +1 -1
- package/dist/cjs/plugins/tempo-trace-query/TempoTraceQuery.js +1 -0
- package/dist/cjs/plugins/tempo-trace-query/TempoTraceQueryEditor.js +48 -9
- package/dist/cjs/plugins/tempo-trace-query/get-trace-data.js +12 -12
- package/dist/cjs/plugins/tempo-trace-query/query-editor-model.js +44 -3
- package/dist/cjs/test/mock-data.js +160 -138
- package/dist/components/TraceQLEditor.d.ts.map +1 -1
- package/dist/components/TraceQLEditor.js +59 -18
- package/dist/components/TraceQLEditor.js.map +1 -1
- package/dist/components/complete.d.ts +0 -1
- package/dist/components/complete.d.ts.map +1 -1
- package/dist/components/complete.js +27 -8
- package/dist/components/complete.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/model/api-types.d.ts +4 -0
- package/dist/model/api-types.d.ts.map +1 -1
- package/dist/model/api-types.js.map +1 -1
- package/dist/model/index.d.ts +5 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +1 -1
- package/dist/model/index.js.map +1 -1
- package/dist/model/trace-query-model.d.ts +1 -0
- package/dist/model/trace-query-model.d.ts.map +1 -1
- package/dist/model/trace-query-model.js.map +1 -1
- package/dist/plugins/tempo-trace-query/TempoTraceQuery.d.ts +2 -1
- package/dist/plugins/tempo-trace-query/TempoTraceQuery.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/TempoTraceQuery.js +1 -0
- package/dist/plugins/tempo-trace-query/TempoTraceQuery.js.map +1 -1
- package/dist/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/TempoTraceQueryEditor.js +52 -13
- package/dist/plugins/tempo-trace-query/TempoTraceQueryEditor.js.map +1 -1
- package/dist/plugins/tempo-trace-query/get-trace-data.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/get-trace-data.js +12 -12
- package/dist/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
- package/dist/plugins/tempo-trace-query/query-editor-model.d.ts +9 -0
- package/dist/plugins/tempo-trace-query/query-editor-model.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/query-editor-model.js +35 -0
- package/dist/plugins/tempo-trace-query/query-editor-model.js.map +1 -1
- package/dist/test/mock-data.d.ts.map +1 -1
- package/dist/test/mock-data.js +160 -138
- package/dist/test/mock-data.js.map +1 -1
- package/package.json +4 -4
- package/dist/cjs/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +0 -61
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.d.ts +0 -13
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.d.ts.map +0 -1
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +0 -53
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js.map +0 -1
|
@@ -43,6 +43,12 @@ _export(exports, {
|
|
|
43
43
|
return MOCK_TRACE_RESPONSE_SMALL;
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
|
+
function addParentReferences(span) {
|
|
47
|
+
for (const child of span.childSpans){
|
|
48
|
+
child.parentSpan = span;
|
|
49
|
+
addParentReferences(child);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
46
52
|
const MOCK_TRACE_RESPONSE = {
|
|
47
53
|
batches: [
|
|
48
54
|
{
|
|
@@ -2452,159 +2458,175 @@ const MOCK_TRACE_DATA_SEARCHRESULT = {
|
|
|
2452
2458
|
executedQueryString: 'duration > 900ms'
|
|
2453
2459
|
}
|
|
2454
2460
|
};
|
|
2455
|
-
const
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
}
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
name: 'k6'
|
|
2479
|
-
};
|
|
2480
|
-
const span4 = {
|
|
2481
|
-
resource: authServiceResource,
|
|
2482
|
-
scope: k6scope,
|
|
2483
|
-
childSpans: [],
|
|
2484
|
-
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2485
|
-
spanId: 'AYBIFdTlycc=',
|
|
2486
|
-
parentSpanId: 'hGe8oRN3wWY=',
|
|
2487
|
-
name: 'authenticate',
|
|
2488
|
-
kind: 'SPAN_KIND_SERVER',
|
|
2489
|
-
startTimeUnixMs: 1718122135970.602,
|
|
2490
|
-
endTimeUnixMs: 1718122136107.7405,
|
|
2491
|
-
attributes: [],
|
|
2492
|
-
events: [],
|
|
2493
|
-
status: {
|
|
2494
|
-
message: 'Forbidden',
|
|
2495
|
-
code: 'STATUS_CODE_ERROR'
|
|
2496
|
-
}
|
|
2497
|
-
};
|
|
2498
|
-
const span3 = {
|
|
2499
|
-
resource: shopBackendResource,
|
|
2500
|
-
scope: k6scope,
|
|
2501
|
-
childSpans: [],
|
|
2502
|
-
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2503
|
-
spanId: 'r2NxHHPjciM=',
|
|
2504
|
-
parentSpanId: 'nCLrd8tcFMc=',
|
|
2505
|
-
name: 'get-article',
|
|
2506
|
-
kind: 'SPAN_KIND_CLIENT',
|
|
2507
|
-
startTimeUnixMs: 1718122135965.2107,
|
|
2508
|
-
endTimeUnixMs: 1718122136520.158,
|
|
2509
|
-
attributes: [
|
|
2510
|
-
{
|
|
2511
|
-
key: 'http.method',
|
|
2512
|
-
value: {
|
|
2513
|
-
stringValue: 'DELETE'
|
|
2514
|
-
}
|
|
2515
|
-
}
|
|
2516
|
-
],
|
|
2517
|
-
events: [],
|
|
2518
|
-
status: {}
|
|
2519
|
-
};
|
|
2520
|
-
const span2 = {
|
|
2521
|
-
resource: shopBackendResource,
|
|
2522
|
-
scope: k6scope,
|
|
2523
|
-
childSpans: [
|
|
2524
|
-
span4
|
|
2525
|
-
],
|
|
2526
|
-
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2527
|
-
spanId: 'hGe8oRN3wWY=',
|
|
2528
|
-
parentSpanId: 'nCLrd8tcFMc=',
|
|
2529
|
-
name: 'authenticate',
|
|
2530
|
-
kind: 'SPAN_KIND_CLIENT',
|
|
2531
|
-
startTimeUnixMs: 1718122135954.7656,
|
|
2532
|
-
endTimeUnixMs: 1718122136154.2273,
|
|
2533
|
-
attributes: [
|
|
2534
|
-
{
|
|
2535
|
-
key: 'net.transport',
|
|
2536
|
-
value: {
|
|
2537
|
-
stringValue: 'ip_tcp'
|
|
2538
|
-
}
|
|
2539
|
-
}
|
|
2540
|
-
],
|
|
2541
|
-
events: [
|
|
2542
|
-
{
|
|
2543
|
-
timeUnixMs: 1718122136068.6138,
|
|
2544
|
-
name: 'event_k6.7W272ywYih',
|
|
2461
|
+
const MOCK_TRACE_DATA_TRACE = {
|
|
2462
|
+
trace: {
|
|
2463
|
+
rootSpan: {
|
|
2464
|
+
resource: {
|
|
2465
|
+
serviceName: 'shop-backend',
|
|
2466
|
+
attributes: [
|
|
2467
|
+
{
|
|
2468
|
+
key: 'service.name',
|
|
2469
|
+
value: {
|
|
2470
|
+
stringValue: 'shop-backend'
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
]
|
|
2474
|
+
},
|
|
2475
|
+
scope: {
|
|
2476
|
+
name: 'k6'
|
|
2477
|
+
},
|
|
2478
|
+
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2479
|
+
spanId: 'nCLrd8tcFMc=',
|
|
2480
|
+
name: 'article-to-cart',
|
|
2481
|
+
kind: 'SPAN_KIND_SERVER',
|
|
2482
|
+
startTimeUnixMs: 1718122135898.4426,
|
|
2483
|
+
endTimeUnixMs: 1718122136696.6519,
|
|
2545
2484
|
attributes: [
|
|
2546
2485
|
{
|
|
2547
|
-
key: '
|
|
2486
|
+
key: 'http.url',
|
|
2548
2487
|
value: {
|
|
2549
|
-
stringValue: '
|
|
2488
|
+
stringValue: 'https://shop-backend.local:8523/article-to-cart'
|
|
2550
2489
|
}
|
|
2551
2490
|
},
|
|
2552
2491
|
{
|
|
2553
|
-
key: '
|
|
2492
|
+
key: 'http.status_code',
|
|
2554
2493
|
value: {
|
|
2555
|
-
|
|
2494
|
+
intValue: '202'
|
|
2556
2495
|
}
|
|
2496
|
+
}
|
|
2497
|
+
],
|
|
2498
|
+
events: [],
|
|
2499
|
+
status: {},
|
|
2500
|
+
childSpans: [
|
|
2501
|
+
{
|
|
2502
|
+
resource: {
|
|
2503
|
+
serviceName: 'shop-backend',
|
|
2504
|
+
attributes: [
|
|
2505
|
+
{
|
|
2506
|
+
key: 'service.name',
|
|
2507
|
+
value: {
|
|
2508
|
+
stringValue: 'shop-backend'
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
]
|
|
2512
|
+
},
|
|
2513
|
+
scope: {
|
|
2514
|
+
name: 'k6'
|
|
2515
|
+
},
|
|
2516
|
+
childSpans: [
|
|
2517
|
+
{
|
|
2518
|
+
resource: {
|
|
2519
|
+
serviceName: 'auth-service',
|
|
2520
|
+
attributes: [
|
|
2521
|
+
{
|
|
2522
|
+
key: 'service.name',
|
|
2523
|
+
value: {
|
|
2524
|
+
stringValue: 'auth-service'
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
]
|
|
2528
|
+
},
|
|
2529
|
+
scope: {
|
|
2530
|
+
name: 'k6'
|
|
2531
|
+
},
|
|
2532
|
+
childSpans: [],
|
|
2533
|
+
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2534
|
+
spanId: 'AYBIFdTlycc=',
|
|
2535
|
+
parentSpanId: 'hGe8oRN3wWY=',
|
|
2536
|
+
name: 'authenticate',
|
|
2537
|
+
kind: 'SPAN_KIND_SERVER',
|
|
2538
|
+
startTimeUnixMs: 1718122135970.602,
|
|
2539
|
+
endTimeUnixMs: 1718122136107.7405,
|
|
2540
|
+
attributes: [],
|
|
2541
|
+
events: [],
|
|
2542
|
+
status: {
|
|
2543
|
+
message: 'Forbidden',
|
|
2544
|
+
code: 'STATUS_CODE_ERROR'
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
],
|
|
2548
|
+
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2549
|
+
spanId: 'hGe8oRN3wWY=',
|
|
2550
|
+
parentSpanId: 'nCLrd8tcFMc=',
|
|
2551
|
+
name: 'authenticate',
|
|
2552
|
+
kind: 'SPAN_KIND_CLIENT',
|
|
2553
|
+
startTimeUnixMs: 1718122135954.7656,
|
|
2554
|
+
endTimeUnixMs: 1718122136154.2273,
|
|
2555
|
+
attributes: [
|
|
2556
|
+
{
|
|
2557
|
+
key: 'net.transport',
|
|
2558
|
+
value: {
|
|
2559
|
+
stringValue: 'ip_tcp'
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
],
|
|
2563
|
+
events: [
|
|
2564
|
+
{
|
|
2565
|
+
timeUnixMs: 1718122136068.6138,
|
|
2566
|
+
name: 'event_k6.7W272ywYih',
|
|
2567
|
+
attributes: [
|
|
2568
|
+
{
|
|
2569
|
+
key: 'k6.sJekvnAr5h7vJfK',
|
|
2570
|
+
value: {
|
|
2571
|
+
stringValue: 'SZ9vwpLkAzAm2Bju1VJroUlGD8u3pS'
|
|
2572
|
+
}
|
|
2573
|
+
},
|
|
2574
|
+
{
|
|
2575
|
+
key: 'k6.81JLO5NlT1lAeF1',
|
|
2576
|
+
value: {
|
|
2577
|
+
stringValue: '4AzrPTOML11aIN3dYgbKSaAe9HErnZ'
|
|
2578
|
+
}
|
|
2579
|
+
},
|
|
2580
|
+
{
|
|
2581
|
+
key: 'k6.tdj0bfOxLndyJuN',
|
|
2582
|
+
value: {
|
|
2583
|
+
stringValue: 'PeMAsdQ5469IjQgGtifBA7OgfFdoMb'
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
]
|
|
2587
|
+
}
|
|
2588
|
+
],
|
|
2589
|
+
status: {}
|
|
2557
2590
|
},
|
|
2558
2591
|
{
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2592
|
+
resource: {
|
|
2593
|
+
serviceName: 'shop-backend',
|
|
2594
|
+
attributes: [
|
|
2595
|
+
{
|
|
2596
|
+
key: 'service.name',
|
|
2597
|
+
value: {
|
|
2598
|
+
stringValue: 'shop-backend'
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
]
|
|
2602
|
+
},
|
|
2603
|
+
scope: {
|
|
2604
|
+
name: 'k6'
|
|
2605
|
+
},
|
|
2606
|
+
childSpans: [],
|
|
2607
|
+
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2608
|
+
spanId: 'r2NxHHPjciM=',
|
|
2609
|
+
parentSpanId: 'nCLrd8tcFMc=',
|
|
2610
|
+
name: 'get-article',
|
|
2611
|
+
kind: 'SPAN_KIND_CLIENT',
|
|
2612
|
+
startTimeUnixMs: 1718122135965.2107,
|
|
2613
|
+
endTimeUnixMs: 1718122136520.158,
|
|
2614
|
+
attributes: [
|
|
2615
|
+
{
|
|
2616
|
+
key: 'http.method',
|
|
2617
|
+
value: {
|
|
2618
|
+
stringValue: 'DELETE'
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
],
|
|
2622
|
+
events: [],
|
|
2623
|
+
status: {}
|
|
2563
2624
|
}
|
|
2564
2625
|
]
|
|
2565
2626
|
}
|
|
2566
|
-
],
|
|
2567
|
-
status: {}
|
|
2568
|
-
};
|
|
2569
|
-
const span1 = {
|
|
2570
|
-
resource: shopBackendResource,
|
|
2571
|
-
scope: k6scope,
|
|
2572
|
-
childSpans: [
|
|
2573
|
-
span2,
|
|
2574
|
-
span3
|
|
2575
|
-
],
|
|
2576
|
-
traceId: '+9N4RSCdQ83M1BjcX5/wIQ==',
|
|
2577
|
-
spanId: 'nCLrd8tcFMc=',
|
|
2578
|
-
parentSpanId: undefined,
|
|
2579
|
-
name: 'article-to-cart',
|
|
2580
|
-
kind: 'SPAN_KIND_SERVER',
|
|
2581
|
-
startTimeUnixMs: 1718122135898.4426,
|
|
2582
|
-
endTimeUnixMs: 1718122136696.6519,
|
|
2583
|
-
attributes: [
|
|
2584
|
-
{
|
|
2585
|
-
key: 'http.url',
|
|
2586
|
-
value: {
|
|
2587
|
-
stringValue: 'https://shop-backend.local:8523/article-to-cart'
|
|
2588
|
-
}
|
|
2589
|
-
},
|
|
2590
|
-
{
|
|
2591
|
-
key: 'http.status_code',
|
|
2592
|
-
value: {
|
|
2593
|
-
intValue: '202'
|
|
2594
|
-
}
|
|
2595
|
-
}
|
|
2596
|
-
],
|
|
2597
|
-
events: [],
|
|
2598
|
-
status: {}
|
|
2599
|
-
};
|
|
2600
|
-
span4.parentSpan = span2;
|
|
2601
|
-
span2.parentSpan = span1;
|
|
2602
|
-
span3.parentSpan = span1;
|
|
2603
|
-
const MOCK_TRACE_DATA_TRACE = {
|
|
2604
|
-
trace: {
|
|
2605
|
-
rootSpan: span1
|
|
2606
2627
|
},
|
|
2607
2628
|
metadata: {
|
|
2608
2629
|
executedQueryString: '61a1487c461d9e08'
|
|
2609
2630
|
}
|
|
2610
2631
|
};
|
|
2632
|
+
addParentReferences(MOCK_TRACE_DATA_TRACE.trace.rootSpan);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TraceQLEditor.d.ts","sourceRoot":"","sources":["../../src/components/TraceQLEditor.tsx"],"names":[],"mappings":"AAeA,OAAmB,EAAc,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAErF,OAAO,EAAE,gBAAgB,EAAoB,MAAM,oBAAoB,CAAC;AAExE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,YAAY,CAAC;IAC5F,cAAc,EAAE,gBAAgB,CAAC;CAClC;AAED,wBAAgB,aAAa,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"TraceQLEditor.d.ts","sourceRoot":"","sources":["../../src/components/TraceQLEditor.tsx"],"names":[],"mappings":"AAeA,OAAmB,EAAc,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAErF,OAAO,EAAE,gBAAgB,EAAoB,MAAM,oBAAoB,CAAC;AAExE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,YAAY,CAAC;IAC5F,cAAc,EAAE,gBAAgB,CAAC;CAClC;AAED,wBAAgB,aAAa,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,2CA4D5E"}
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
14
|
import { useMemo } from 'react';
|
|
15
|
-
import { useTheme } from '@mui/material';
|
|
15
|
+
import { InputLabel, Stack, useTheme } from '@mui/material';
|
|
16
16
|
import CodeMirror, { EditorView } from '@uiw/react-codemirror';
|
|
17
17
|
import { isValidTraceId } from '@perses-dev/core';
|
|
18
18
|
import { TraceQLExtension } from './TraceQLExtension';
|
|
@@ -24,24 +24,65 @@ export function TraceQLEditor({ completeConfig, ...rest }) {
|
|
|
24
24
|
}, [
|
|
25
25
|
completeConfig
|
|
26
26
|
]);
|
|
27
|
+
const codemirrorTheme = useMemo(()=>{
|
|
28
|
+
// https://github.com/mui/material-ui/blob/v5.16.7/packages/mui-material/src/OutlinedInput/OutlinedInput.js#L43
|
|
29
|
+
const borderColor = theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)';
|
|
30
|
+
return EditorView.theme({
|
|
31
|
+
'&': {
|
|
32
|
+
backgroundColor: 'transparent !important',
|
|
33
|
+
border: `1px solid ${borderColor}`,
|
|
34
|
+
borderRadius: `${theme.shape.borderRadius}px`
|
|
35
|
+
},
|
|
36
|
+
'&.cm-focused.cm-editor': {
|
|
37
|
+
outline: 'none'
|
|
38
|
+
},
|
|
39
|
+
'.cm-content': {
|
|
40
|
+
padding: '8px'
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}, [
|
|
44
|
+
theme
|
|
45
|
+
]);
|
|
27
46
|
var _rest_value;
|
|
28
|
-
return /*#__PURE__*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
theme: isDarkMode ? 'dark' : 'light',
|
|
34
|
-
basicSetup: {
|
|
35
|
-
highlightActiveLine: false,
|
|
36
|
-
highlightActiveLineGutter: false,
|
|
37
|
-
foldGutter: false,
|
|
38
|
-
// The explore view accepts either a TraceQL query or a Trace ID as input. The lezer grammar marks Trace IDs as invalid,
|
|
39
|
-
// therefore let's disable syntax highlighting if the input is a Trace ID.
|
|
40
|
-
syntaxHighlighting: !isValidTraceId((_rest_value = rest.value) !== null && _rest_value !== void 0 ? _rest_value : '')
|
|
47
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
48
|
+
position: "relative",
|
|
49
|
+
sx: {
|
|
50
|
+
flexGrow: 1
|
|
41
51
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
children: [
|
|
53
|
+
/*#__PURE__*/ _jsx(InputLabel // reproduce the same kind of input label that regular MUI TextFields have
|
|
54
|
+
, {
|
|
55
|
+
shrink: true,
|
|
56
|
+
sx: {
|
|
57
|
+
position: 'absolute',
|
|
58
|
+
top: '-6px',
|
|
59
|
+
left: '10px',
|
|
60
|
+
padding: '0 4px',
|
|
61
|
+
color: theme.palette.text.primary,
|
|
62
|
+
backgroundColor: theme.palette.background.default,
|
|
63
|
+
zIndex: 1
|
|
64
|
+
},
|
|
65
|
+
children: "TraceQL Expression"
|
|
66
|
+
}),
|
|
67
|
+
/*#__PURE__*/ _jsx(CodeMirror, {
|
|
68
|
+
...rest,
|
|
69
|
+
theme: isDarkMode ? 'dark' : 'light',
|
|
70
|
+
basicSetup: {
|
|
71
|
+
lineNumbers: false,
|
|
72
|
+
highlightActiveLine: false,
|
|
73
|
+
highlightActiveLineGutter: false,
|
|
74
|
+
foldGutter: false,
|
|
75
|
+
// The explore view accepts either a TraceQL query or a Trace ID as input. The lezer grammar marks Trace IDs as invalid,
|
|
76
|
+
// therefore let's disable syntax highlighting if the input is a Trace ID.
|
|
77
|
+
syntaxHighlighting: !isValidTraceId((_rest_value = rest.value) !== null && _rest_value !== void 0 ? _rest_value : '')
|
|
78
|
+
},
|
|
79
|
+
extensions: [
|
|
80
|
+
EditorView.lineWrapping,
|
|
81
|
+
traceQLExtension,
|
|
82
|
+
codemirrorTheme
|
|
83
|
+
],
|
|
84
|
+
placeholder: 'Example: {span.http.method = "GET"}'
|
|
85
|
+
})
|
|
45
86
|
]
|
|
46
87
|
});
|
|
47
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/TraceQLEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useMemo } from 'react';\nimport { useTheme } from '@mui/material';\nimport CodeMirror, { EditorView, ReactCodeMirrorProps } from '@uiw/react-codemirror';\nimport { isValidTraceId } from '@perses-dev/core';\nimport { CompletionConfig, TraceQLExtension } from './TraceQLExtension';\n\nexport interface TraceQLEditorProps extends Omit<ReactCodeMirrorProps, 'theme' | 'extensions'> {\n completeConfig: CompletionConfig;\n}\n\nexport function TraceQLEditor({ completeConfig, ...rest }: TraceQLEditorProps) {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n\n const traceQLExtension = useMemo(() => {\n return TraceQLExtension(completeConfig);\n }, [completeConfig]);\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/components/TraceQLEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useMemo } from 'react';\nimport { InputLabel, Stack, useTheme } from '@mui/material';\nimport CodeMirror, { EditorView, ReactCodeMirrorProps } from '@uiw/react-codemirror';\nimport { isValidTraceId } from '@perses-dev/core';\nimport { CompletionConfig, TraceQLExtension } from './TraceQLExtension';\n\nexport interface TraceQLEditorProps extends Omit<ReactCodeMirrorProps, 'theme' | 'extensions'> {\n completeConfig: CompletionConfig;\n}\n\nexport function TraceQLEditor({ completeConfig, ...rest }: TraceQLEditorProps) {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n\n const traceQLExtension = useMemo(() => {\n return TraceQLExtension(completeConfig);\n }, [completeConfig]);\n\n const codemirrorTheme = useMemo(() => {\n // https://github.com/mui/material-ui/blob/v5.16.7/packages/mui-material/src/OutlinedInput/OutlinedInput.js#L43\n const borderColor = theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)';\n\n return EditorView.theme({\n '&': {\n backgroundColor: 'transparent !important', // required for dark mode\n border: `1px solid ${borderColor}`,\n borderRadius: `${theme.shape.borderRadius}px`,\n },\n '&.cm-focused.cm-editor': {\n outline: 'none', // remove dotted outline on focus\n },\n '.cm-content': {\n padding: '8px',\n },\n });\n }, [theme]);\n\n return (\n <Stack position=\"relative\" sx={{ flexGrow: 1 }}>\n <InputLabel // reproduce the same kind of input label that regular MUI TextFields have\n shrink\n sx={{\n position: 'absolute',\n top: '-6px',\n left: '10px',\n padding: '0 4px',\n color: theme.palette.text.primary,\n backgroundColor: theme.palette.background.default,\n zIndex: 1,\n }}\n >\n TraceQL Expression\n </InputLabel>\n <CodeMirror\n {...rest}\n theme={isDarkMode ? 'dark' : 'light'}\n basicSetup={{\n lineNumbers: false,\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n foldGutter: false,\n // The explore view accepts either a TraceQL query or a Trace ID as input. The lezer grammar marks Trace IDs as invalid,\n // therefore let's disable syntax highlighting if the input is a Trace ID.\n syntaxHighlighting: !isValidTraceId(rest.value ?? ''),\n }}\n extensions={[EditorView.lineWrapping, traceQLExtension, codemirrorTheme]}\n placeholder='Example: {span.http.method = \"GET\"}'\n />\n </Stack>\n );\n}\n"],"names":["useMemo","InputLabel","Stack","useTheme","CodeMirror","EditorView","isValidTraceId","TraceQLExtension","TraceQLEditor","completeConfig","rest","theme","isDarkMode","palette","mode","traceQLExtension","codemirrorTheme","borderColor","backgroundColor","border","borderRadius","shape","outline","padding","position","sx","flexGrow","shrink","top","left","color","text","primary","background","default","zIndex","basicSetup","lineNumbers","highlightActiveLine","highlightActiveLineGutter","foldGutter","syntaxHighlighting","value","extensions","lineWrapping","placeholder"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,OAAO,QAAQ,QAAQ;AAChC,SAASC,UAAU,EAAEC,KAAK,EAAEC,QAAQ,QAAQ,gBAAgB;AAC5D,OAAOC,cAAcC,UAAU,QAA8B,wBAAwB;AACrF,SAASC,cAAc,QAAQ,mBAAmB;AAClD,SAA2BC,gBAAgB,QAAQ,qBAAqB;AAMxE,OAAO,SAASC,cAAc,EAAEC,cAAc,EAAE,GAAGC,MAA0B;IAC3E,MAAMC,QAAQR;IACd,MAAMS,aAAaD,MAAME,OAAO,CAACC,IAAI,KAAK;IAE1C,MAAMC,mBAAmBf,QAAQ;QAC/B,OAAOO,iBAAiBE;IAC1B,GAAG;QAACA;KAAe;IAEnB,MAAMO,kBAAkBhB,QAAQ;QAC9B,+GAA+G;QAC/G,MAAMiB,cAAcN,MAAME,OAAO,CAACC,IAAI,KAAK,UAAU,wBAAwB;QAE7E,OAAOT,WAAWM,KAAK,CAAC;YACtB,KAAK;gBACHO,iBAAiB;gBACjBC,QAAQ,CAAC,UAAU,EAAEF,YAAY,CAAC;gBAClCG,cAAc,CAAC,EAAET,MAAMU,KAAK,CAACD,YAAY,CAAC,EAAE,CAAC;YAC/C;YACA,0BAA0B;gBACxBE,SAAS;YACX;YACA,eAAe;gBACbC,SAAS;YACX;QACF;IACF,GAAG;QAACZ;KAAM;QA4BkCD;IA1B5C,qBACE,MAACR;QAAMsB,UAAS;QAAWC,IAAI;YAAEC,UAAU;QAAE;;0BAC3C,KAACzB,WAAW,0EAA0E;;gBACpF0B,MAAM;gBACNF,IAAI;oBACFD,UAAU;oBACVI,KAAK;oBACLC,MAAM;oBACNN,SAAS;oBACTO,OAAOnB,MAAME,OAAO,CAACkB,IAAI,CAACC,OAAO;oBACjCd,iBAAiBP,MAAME,OAAO,CAACoB,UAAU,CAACC,OAAO;oBACjDC,QAAQ;gBACV;0BACD;;0BAGD,KAAC/B;gBACE,GAAGM,IAAI;gBACRC,OAAOC,aAAa,SAAS;gBAC7BwB,YAAY;oBACVC,aAAa;oBACbC,qBAAqB;oBACrBC,2BAA2B;oBAC3BC,YAAY;oBACZ,wHAAwH;oBACxH,0EAA0E;oBAC1EC,oBAAoB,CAACnC,eAAeI,CAAAA,cAAAA,KAAKgC,KAAK,cAAVhC,yBAAAA,cAAc;gBACpD;gBACAiC,YAAY;oBAACtC,WAAWuC,YAAY;oBAAE7B;oBAAkBC;iBAAgB;gBACxE6B,aAAY;;;;AAIpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/components/complete.ts"],"names":[],"mappings":"AAaA,OAAO,EAAc,iBAAiB,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/components/complete.ts"],"names":[],"mappings":"AAaA,OAAO,EAAc,iBAAiB,EAAE,gBAAgB,EAAwB,MAAM,0BAA0B,CAAC;AAEjH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAYrC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,uGAAuG;AACvG,KAAK,eAAe,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,WAAW,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,QAAQ,CAC5B,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,iBAAiB,EACjC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAWlC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,SAAS,CA4HxG"}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
+
import { insertCompletionText } from '@codemirror/autocomplete';
|
|
13
14
|
import { syntaxTree } from '@codemirror/language';
|
|
14
15
|
import { String as StringType, FieldExpression, AttributeField, Resource, Identifier, Span, SpansetFilter, FieldOp } from '@grafana/lezer-traceql';
|
|
15
16
|
export async function complete({ state, pos }, client) {
|
|
@@ -185,8 +186,7 @@ export async function complete({ state, pos }, client) {
|
|
|
185
186
|
scopes: [
|
|
186
187
|
{
|
|
187
188
|
kind: 'TagValue',
|
|
188
|
-
tag: attribute
|
|
189
|
-
quotes: true
|
|
189
|
+
tag: attribute
|
|
190
190
|
}
|
|
191
191
|
],
|
|
192
192
|
from: pos
|
|
@@ -196,7 +196,8 @@ export async function complete({ state, pos }, client) {
|
|
|
196
196
|
case StringType:
|
|
197
197
|
var _node_parent_parent_parent_firstChild, _node_parent_parent_parent, _node_parent_parent, _node_parent5;
|
|
198
198
|
// autocomplete { resource.service.name="
|
|
199
|
-
|
|
199
|
+
// do not autocomplete if cursor is after closing quotes { resource.service.name=""
|
|
200
|
+
if (((_node_parent5 = node.parent) === null || _node_parent5 === void 0 ? void 0 : (_node_parent_parent = _node_parent5.parent) === null || _node_parent_parent === void 0 ? void 0 : (_node_parent_parent_parent = _node_parent_parent.parent) === null || _node_parent_parent_parent === void 0 ? void 0 : (_node_parent_parent_parent_firstChild = _node_parent_parent_parent.firstChild) === null || _node_parent_parent_parent_firstChild === void 0 ? void 0 : _node_parent_parent_parent_firstChild.type.id) === FieldExpression && !/^".*"$/.test(state.sliceDoc(node.from, pos))) {
|
|
200
201
|
const fieldExpr = node.parent.parent.parent.firstChild;
|
|
201
202
|
const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);
|
|
202
203
|
return {
|
|
@@ -216,6 +217,8 @@ export async function complete({ state, pos }, client) {
|
|
|
216
217
|
if (((_node_prevSibling = node.prevSibling) === null || _node_prevSibling === void 0 ? void 0 : _node_prevSibling.type.id) === FieldOp && ((_node_parent6 = node.parent) === null || _node_parent6 === void 0 ? void 0 : (_node_parent_firstChild4 = _node_parent6.firstChild) === null || _node_parent_firstChild4 === void 0 ? void 0 : _node_parent_firstChild4.type.id) === FieldExpression) {
|
|
217
218
|
const fieldExpr = node.parent.firstChild;
|
|
218
219
|
const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);
|
|
220
|
+
// ignore leading " in { name="HT
|
|
221
|
+
const from = state.sliceDoc(node.from, node.from + 1) === '"' ? node.from + 1 : node.from;
|
|
219
222
|
return {
|
|
220
223
|
scopes: [
|
|
221
224
|
{
|
|
@@ -223,7 +226,7 @@ export async function complete({ state, pos }, client) {
|
|
|
223
226
|
tag: attribute
|
|
224
227
|
}
|
|
225
228
|
],
|
|
226
|
-
from
|
|
229
|
+
from
|
|
227
230
|
};
|
|
228
231
|
}
|
|
229
232
|
// autocomplete { s
|
|
@@ -268,7 +271,7 @@ export async function complete({ state, pos }, client) {
|
|
|
268
271
|
break;
|
|
269
272
|
case 'TagValue':
|
|
270
273
|
if (client) {
|
|
271
|
-
results.push(completeTagValue(client, completion.tag
|
|
274
|
+
results.push(completeTagValue(client, completion.tag));
|
|
272
275
|
}
|
|
273
276
|
break;
|
|
274
277
|
}
|
|
@@ -286,7 +289,23 @@ async function completeTagName(client, scope) {
|
|
|
286
289
|
label: tag
|
|
287
290
|
}));
|
|
288
291
|
}
|
|
289
|
-
|
|
292
|
+
/**
|
|
293
|
+
* Add quotes to the completion text in case quotes are not present already.
|
|
294
|
+
* This handles the following cases:
|
|
295
|
+
* { name=HTTP
|
|
296
|
+
* { name="x
|
|
297
|
+
* { name="x" where cursor is after the 'x'
|
|
298
|
+
*/ function applyQuotedCompletion(view, completion, from, to) {
|
|
299
|
+
let insertText = completion.label;
|
|
300
|
+
if (view.state.sliceDoc(from - 1, from) !== '"') {
|
|
301
|
+
insertText = '"' + insertText;
|
|
302
|
+
}
|
|
303
|
+
if (view.state.sliceDoc(to, to + 1) !== '"') {
|
|
304
|
+
insertText = insertText + '"';
|
|
305
|
+
}
|
|
306
|
+
view.dispatch(insertCompletionText(view.state, insertText, from, to));
|
|
307
|
+
}
|
|
308
|
+
async function completeTagValue(client, tag) {
|
|
290
309
|
const response = await client.searchTagValues({
|
|
291
310
|
tag
|
|
292
311
|
});
|
|
@@ -295,8 +314,8 @@ async function completeTagValue(client, tag, quotes) {
|
|
|
295
314
|
switch(type){
|
|
296
315
|
case 'string':
|
|
297
316
|
completions.push({
|
|
298
|
-
|
|
299
|
-
|
|
317
|
+
label: value,
|
|
318
|
+
apply: applyQuotedCompletion
|
|
300
319
|
});
|
|
301
320
|
break;
|
|
302
321
|
case 'keyword':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/complete.ts"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';\nimport { syntaxTree } from '@codemirror/language';\nimport { EditorState } from '@codemirror/state';\nimport { Tree } from '@lezer/common';\nimport {\n String as StringType,\n FieldExpression,\n AttributeField,\n Resource,\n Identifier,\n Span,\n SpansetFilter,\n FieldOp,\n} from '@grafana/lezer-traceql';\nimport { TempoClient } from '../model/tempo-client';\n\n/** CompletionScope specifies the completion kind, e.g. whether to complete tag names or values etc. */\ntype CompletionScope =\n | { kind: 'Scopes' } // 'resource'|'span'\n | { kind: 'TagName'; scope: 'resource' | 'span' | 'intrinsic' }\n | { kind: 'TagValue'; tag: string; quotes?: boolean };\n\n/**\n * Completions specifies the identified scopes and position of the completion in the current editor text.\n * For example, when entering '{' the following completions are possible: Scopes(), TagName(scope=intrinsic)\n */\nexport interface Completions {\n scopes: CompletionScope[];\n from: number;\n to?: number;\n}\n\nexport async function complete(\n { state, pos }: CompletionContext,\n client?: TempoClient\n): Promise<CompletionResult | null> {\n // First, identify the completion scopes, for example Scopes() and TagName(scope=intrinsic)\n const completions = identifyCompletions(state, pos, syntaxTree(state));\n if (!completions) {\n // No completion scopes found for current cursor position.\n return null;\n }\n\n // Then, retrieve completion options for all identified scopes (from the Tempo API).\n const options = await retrieveOptions(completions.scopes, client);\n return { options, from: completions.from, to: completions.to };\n}\n\n/**\n * Identify completion scopes (e.g. TagValue) and position, based on the current node in the syntax tree.\n *\n * For development, you can visualize the tree of a TraceQL query using this tool:\n * https://github.com/grafana/lezer-traceql/blob/main/tools/tree-viz.html\n *\n * Function is exported for tests only.\n */\nexport function identifyCompletions(state: EditorState, pos: number, tree: Tree): Completions | undefined {\n const node = tree.resolveInner(pos, -1);\n\n switch (node.type.id) {\n case SpansetFilter:\n // autocomplete {\n // autocomplete {}\n // do not autocomplete if cursor is after } or { status=ok }\n if (\n (node.firstChild === null || node.firstChild?.type.id === 0) &&\n !state.sliceDoc(node.from, pos).includes('}')\n ) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n }\n break;\n\n case FieldExpression:\n // autocomplete { status=ok &&\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n\n case AttributeField:\n // autocomplete { resource.\n if (node.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: pos };\n }\n\n // autocomplete { span.\n if (node.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: pos };\n }\n\n // autocomplete { .\n if (state.sliceDoc(node.from, node.to) === '.') {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: pos,\n };\n }\n break;\n\n case Identifier:\n if (node.parent?.type.id === AttributeField) {\n const text = state.sliceDoc(node.parent.from, node.parent.to);\n // autocomplete { span:s\n // only intrinsic fields can have a : in the name.\n if (text.includes(':')) {\n return { scopes: [{ kind: 'TagName', scope: 'intrinsic' }], from: node.parent.from };\n }\n\n // autocomplete { resource.s\n if (node.parent?.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: node.from };\n }\n\n // autocomplete { span.s\n if (node.parent?.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: node.from };\n }\n\n // autocomplete { .s\n if (node.parent?.firstChild?.type.id === Identifier) {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: node.from,\n };\n }\n }\n break;\n\n case FieldOp:\n // autocomplete { status=\n // autocomplete { span.http.method=\n if (node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute, quotes: true }], from: pos };\n }\n break;\n\n case StringType:\n // autocomplete { resource.service.name=\"\n if (node.parent?.parent?.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.parent.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: node.from + 1 }; // node.from+1 to ignore leading \"\n }\n break;\n\n case 0 /* error node */:\n // autocomplete { status=e\n if (node.prevSibling?.type.id === FieldOp && node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: node.from };\n }\n\n // autocomplete { s\n // autocomplete { status=ok && s\n if (node.parent?.type.id === SpansetFilter || node.parent?.type.id === FieldExpression) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: node.from,\n };\n }\n break;\n }\n}\n\n/**\n * Retrieve all completion options based on the previously identified completion scopes.\n */\nasync function retrieveOptions(completions: CompletionScope[], client?: TempoClient): Promise<Completion[]> {\n const results: Array<Promise<Completion[]>> = [];\n\n for (const completion of completions) {\n switch (completion.kind) {\n case 'Scopes':\n results.push(Promise.resolve([{ label: 'span' }, { label: 'resource' }]));\n break;\n\n case 'TagName':\n if (client) {\n results.push(completeTagName(client, completion.scope));\n }\n break;\n\n case 'TagValue':\n if (client) {\n results.push(completeTagValue(client, completion.tag, completion.quotes));\n }\n break;\n }\n }\n\n // Retrieve options concurrently\n // e.g. for unscoped attribute fields, retrieve list of span and resource attributes concurrently.\n const options = await Promise.all(results);\n return options.flat();\n}\n\nasync function completeTagName(client: TempoClient, scope: 'resource' | 'span' | 'intrinsic'): Promise<Completion[]> {\n const response = await client.searchTags({ scope });\n return response.scopes.flatMap((scope) => scope.tags).map((tag) => ({ label: tag }));\n}\n\nasync function completeTagValue(client: TempoClient, tag: string, quotes?: boolean): Promise<Completion[]> {\n const response = await client.searchTagValues({ tag });\n const completions: Completion[] = [];\n for (const { type, value } of response.tagValues) {\n switch (type) {\n case 'string':\n completions.push({ displayLabel: value, label: quotes ? `\"${value}\"` : value });\n break;\n\n case 'keyword':\n case 'int':\n completions.push({ label: value });\n break;\n }\n }\n return completions;\n}\n"],"names":["syntaxTree","String","StringType","FieldExpression","AttributeField","Resource","Identifier","Span","SpansetFilter","FieldOp","complete","state","pos","client","completions","identifyCompletions","options","retrieveOptions","scopes","from","to","tree","node","resolveInner","type","id","firstChild","sliceDoc","includes","kind","scope","parent","text","fieldExpr","attribute","tag","quotes","prevSibling","results","completion","push","Promise","resolve","label","completeTagName","completeTagValue","all","flat","response","searchTags","flatMap","tags","map","searchTagValues","value","tagValues","displayLabel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/complete.ts"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Completion, CompletionContext, CompletionResult, insertCompletionText } from '@codemirror/autocomplete';\nimport { syntaxTree } from '@codemirror/language';\nimport { EditorState } from '@codemirror/state';\nimport { Tree } from '@lezer/common';\nimport {\n String as StringType,\n FieldExpression,\n AttributeField,\n Resource,\n Identifier,\n Span,\n SpansetFilter,\n FieldOp,\n} from '@grafana/lezer-traceql';\nimport { EditorView } from '@uiw/react-codemirror';\nimport { TempoClient } from '../model/tempo-client';\n\n/** CompletionScope specifies the completion kind, e.g. whether to complete tag names or values etc. */\ntype CompletionScope =\n | { kind: 'Scopes' } // 'resource'|'span'\n | { kind: 'TagName'; scope: 'resource' | 'span' | 'intrinsic' }\n | { kind: 'TagValue'; tag: string };\n\n/**\n * Completions specifies the identified scopes and position of the completion in the current editor text.\n * For example, when entering '{' the following completions are possible: Scopes(), TagName(scope=intrinsic)\n */\nexport interface Completions {\n scopes: CompletionScope[];\n from: number;\n to?: number;\n}\n\nexport async function complete(\n { state, pos }: CompletionContext,\n client?: TempoClient\n): Promise<CompletionResult | null> {\n // First, identify the completion scopes, for example Scopes() and TagName(scope=intrinsic)\n const completions = identifyCompletions(state, pos, syntaxTree(state));\n if (!completions) {\n // No completion scopes found for current cursor position.\n return null;\n }\n\n // Then, retrieve completion options for all identified scopes (from the Tempo API).\n const options = await retrieveOptions(completions.scopes, client);\n return { options, from: completions.from, to: completions.to };\n}\n\n/**\n * Identify completion scopes (e.g. TagValue) and position, based on the current node in the syntax tree.\n *\n * For development, you can visualize the tree of a TraceQL query using this tool:\n * https://github.com/grafana/lezer-traceql/blob/main/tools/tree-viz.html\n *\n * Function is exported for tests only.\n */\nexport function identifyCompletions(state: EditorState, pos: number, tree: Tree): Completions | undefined {\n const node = tree.resolveInner(pos, -1);\n\n switch (node.type.id) {\n case SpansetFilter:\n // autocomplete {\n // autocomplete {}\n // do not autocomplete if cursor is after } or { status=ok }\n if (\n (node.firstChild === null || node.firstChild?.type.id === 0) &&\n !state.sliceDoc(node.from, pos).includes('}')\n ) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n }\n break;\n\n case FieldExpression:\n // autocomplete { status=ok &&\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n\n case AttributeField:\n // autocomplete { resource.\n if (node.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: pos };\n }\n\n // autocomplete { span.\n if (node.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: pos };\n }\n\n // autocomplete { .\n if (state.sliceDoc(node.from, node.to) === '.') {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: pos,\n };\n }\n break;\n\n case Identifier:\n if (node.parent?.type.id === AttributeField) {\n const text = state.sliceDoc(node.parent.from, node.parent.to);\n // autocomplete { span:s\n // only intrinsic fields can have a : in the name.\n if (text.includes(':')) {\n return { scopes: [{ kind: 'TagName', scope: 'intrinsic' }], from: node.parent.from };\n }\n\n // autocomplete { resource.s\n if (node.parent?.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: node.from };\n }\n\n // autocomplete { span.s\n if (node.parent?.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: node.from };\n }\n\n // autocomplete { .s\n if (node.parent?.firstChild?.type.id === Identifier) {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: node.from,\n };\n }\n }\n break;\n\n case FieldOp:\n // autocomplete { status=\n // autocomplete { span.http.method=\n if (node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: pos };\n }\n break;\n\n case StringType:\n // autocomplete { resource.service.name=\"\n // do not autocomplete if cursor is after closing quotes { resource.service.name=\"\"\n if (\n node.parent?.parent?.parent?.firstChild?.type.id === FieldExpression &&\n !/^\".*\"$/.test(state.sliceDoc(node.from, pos))\n ) {\n const fieldExpr = node.parent.parent.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: node.from + 1 }; // node.from+1 to ignore leading \"\n }\n break;\n\n case 0 /* error node */:\n // autocomplete { status=e\n if (node.prevSibling?.type.id === FieldOp && node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n // ignore leading \" in { name=\"HT\n const from = state.sliceDoc(node.from, node.from + 1) === '\"' ? node.from + 1 : node.from;\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from };\n }\n\n // autocomplete { s\n // autocomplete { status=ok && s\n if (node.parent?.type.id === SpansetFilter || node.parent?.type.id === FieldExpression) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: node.from,\n };\n }\n break;\n }\n}\n\n/**\n * Retrieve all completion options based on the previously identified completion scopes.\n */\nasync function retrieveOptions(completions: CompletionScope[], client?: TempoClient): Promise<Completion[]> {\n const results: Array<Promise<Completion[]>> = [];\n\n for (const completion of completions) {\n switch (completion.kind) {\n case 'Scopes':\n results.push(Promise.resolve([{ label: 'span' }, { label: 'resource' }]));\n break;\n\n case 'TagName':\n if (client) {\n results.push(completeTagName(client, completion.scope));\n }\n break;\n\n case 'TagValue':\n if (client) {\n results.push(completeTagValue(client, completion.tag));\n }\n break;\n }\n }\n\n // Retrieve options concurrently\n // e.g. for unscoped attribute fields, retrieve list of span and resource attributes concurrently.\n const options = await Promise.all(results);\n return options.flat();\n}\n\nasync function completeTagName(client: TempoClient, scope: 'resource' | 'span' | 'intrinsic'): Promise<Completion[]> {\n const response = await client.searchTags({ scope });\n return response.scopes.flatMap((scope) => scope.tags).map((tag) => ({ label: tag }));\n}\n\n/**\n * Add quotes to the completion text in case quotes are not present already.\n * This handles the following cases:\n * { name=HTTP\n * { name=\"x\n * { name=\"x\" where cursor is after the 'x'\n */\nfunction applyQuotedCompletion(view: EditorView, completion: Completion, from: number, to: number) {\n let insertText = completion.label;\n if (view.state.sliceDoc(from - 1, from) !== '\"') {\n insertText = '\"' + insertText;\n }\n if (view.state.sliceDoc(to, to + 1) !== '\"') {\n insertText = insertText + '\"';\n }\n view.dispatch(insertCompletionText(view.state, insertText, from, to));\n}\n\nasync function completeTagValue(client: TempoClient, tag: string): Promise<Completion[]> {\n const response = await client.searchTagValues({ tag });\n const completions: Completion[] = [];\n for (const { type, value } of response.tagValues) {\n switch (type) {\n case 'string':\n completions.push({ label: value, apply: applyQuotedCompletion });\n break;\n\n case 'keyword':\n case 'int':\n completions.push({ label: value });\n break;\n }\n }\n return completions;\n}\n"],"names":["insertCompletionText","syntaxTree","String","StringType","FieldExpression","AttributeField","Resource","Identifier","Span","SpansetFilter","FieldOp","complete","state","pos","client","completions","identifyCompletions","options","retrieveOptions","scopes","from","to","tree","node","resolveInner","type","id","firstChild","sliceDoc","includes","kind","scope","parent","text","fieldExpr","attribute","tag","test","prevSibling","results","completion","push","Promise","resolve","label","completeTagName","completeTagValue","all","flat","response","searchTags","flatMap","tags","map","applyQuotedCompletion","view","insertText","dispatch","searchTagValues","value","tagValues","apply"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { TempoDatasource } from './plugins/tempo-datasource';
|
|
2
2
|
import { TempoTraceQuery } from './plugins/tempo-trace-query/TempoTraceQuery';
|
|
3
3
|
export { TempoTraceQuery, TempoDatasource };
|
|
4
|
-
export * from './model
|
|
5
|
-
export * from './model/tempo-selectors';
|
|
4
|
+
export * from './model';
|
|
6
5
|
export * from './components/TraceQLExtension';
|
|
7
6
|
//# sourceMappingURL=index.d.ts.map
|