@parca/profile 0.16.232 → 0.16.233

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/MatchersInput/index.js +1 -1
  3. package/dist/MetricsGraph/index.d.ts +2 -3
  4. package/dist/MetricsGraph/index.js +12 -11
  5. package/dist/MetricsGraph/useMetricsGraphDimensions.d.ts +0 -1
  6. package/dist/MetricsGraph/useMetricsGraphDimensions.js +0 -3
  7. package/dist/ProfileExplorer/ProfileExplorerCompare.js +2 -1
  8. package/dist/ProfileExplorer/ProfileExplorerSingle.js +2 -1
  9. package/dist/ProfileIcicleGraph/index.js +1 -1
  10. package/dist/ProfileMetricsGraph/index.js +2 -2
  11. package/dist/ProfileSelector/index.js +38 -37
  12. package/dist/ProfileTypeSelector/index.js +1 -1
  13. package/dist/ProfileView/ViewSelector.d.ts +2 -1
  14. package/dist/ProfileView/ViewSelector.js +2 -2
  15. package/dist/ProfileView/VisualizationPanel.js +1 -1
  16. package/dist/ProfileView/index.js +12 -10
  17. package/dist/TopTable/index.js +1 -1
  18. package/dist/components/ProfileShareButton/index.js +2 -2
  19. package/dist/styles.css +1 -1
  20. package/package.json +3 -3
  21. package/src/MatchersInput/index.tsx +1 -1
  22. package/src/MetricsGraph/index.tsx +83 -42
  23. package/src/MetricsGraph/useMetricsGraphDimensions.ts +0 -4
  24. package/src/ProfileExplorer/ProfileExplorerCompare.tsx +17 -12
  25. package/src/ProfileExplorer/ProfileExplorerSingle.tsx +21 -22
  26. package/src/ProfileIcicleGraph/index.tsx +1 -2
  27. package/src/ProfileMetricsGraph/index.tsx +2 -6
  28. package/src/ProfileSelector/index.tsx +70 -59
  29. package/src/ProfileTypeSelector/index.tsx +2 -1
  30. package/src/ProfileView/ViewSelector.tsx +3 -0
  31. package/src/ProfileView/VisualizationPanel.tsx +9 -6
  32. package/src/ProfileView/index.tsx +101 -93
  33. package/src/TopTable/index.tsx +11 -9
  34. package/src/components/ProfileShareButton/index.tsx +10 -3
@@ -13,6 +13,7 @@
13
13
 
14
14
  import {Profiler, ProfilerProps, useEffect, useMemo, useState} from 'react';
15
15
 
16
+ import {Icon} from '@iconify/react';
16
17
  import {Table as ArrowTable} from 'apache-arrow';
17
18
  import cx from 'classnames';
18
19
  import {scaleLinear} from 'd3';
@@ -35,9 +36,9 @@ import {
35
36
  } from '@parca/client';
36
37
  import {
37
38
  Button,
38
- Card,
39
39
  ConditionalWrapper,
40
40
  KeyDownProvider,
41
+ UserPreferences,
41
42
  useParcaContext,
42
43
  useURLState,
43
44
  } from '@parca/components';
@@ -347,104 +348,111 @@ export const ProfileView = ({
347
348
  }
348
349
  };
349
350
 
351
+ // TODO: this is just a placeholder, we need to replace with an actually informative and accurate title (cc @metalmatze)
352
+ const profileSourceString = profileSource?.toString();
353
+ const headerParts = profileSourceString?.split('"') ?? [];
354
+
350
355
  return (
351
356
  <KeyDownProvider>
352
357
  <ProfileViewContextProvider value={{profileSource, sampleUnit}}>
353
- <div className="py-3">
354
- <Card>
355
- <Card.Body>
356
- <div className="flex w-full py-3">
357
- <div className="flex space-x-4 lg:w-1/2">
358
- <div className="flex space-x-1">
359
- {profileSource !== undefined && queryClient !== undefined ? (
360
- <ProfileShareButton
361
- queryRequest={profileSource.QueryRequest()}
362
- queryClient={queryClient}
363
- />
364
- ) : null}
365
-
366
- <Button
367
- color="neutral"
368
- onClick={e => {
369
- e.preventDefault();
370
- onDownloadPProf();
371
- }}
372
- disabled={pprofDownloading}
373
- >
374
- {pprofDownloading != null && pprofDownloading
375
- ? 'Downloading'
376
- : 'Download pprof'}
377
- </Button>
378
- </div>
379
- <FilterByFunctionButton navigateTo={navigateTo} />
380
- </div>
381
-
382
- <div className="ml-auto flex gap-2">
383
- <ViewSelector
384
- defaultValue=""
385
- navigateTo={navigateTo}
386
- position={-1}
387
- placeholderText="Add panel..."
388
- primary
389
- addView={true}
390
- disabled={isMultiPanelView || dashboardItems.length < 1}
391
- />
392
- </div>
393
- </div>
394
-
395
- <div className="w-full" ref={ref}>
396
- {isLoaderVisible ? (
397
- <>{loader}</>
398
- ) : (
399
- <DragDropContext onDragEnd={onDragEnd}>
400
- <Droppable droppableId="droppable" direction="horizontal">
401
- {provided => (
402
- <div
403
- ref={provided.innerRef}
404
- className="flex w-full justify-between space-x-4"
405
- {...provided.droppableProps}
358
+ <div className="mb-4 flex w-full items-center justify-between">
359
+ <div className="max-w-[500px]">
360
+ <div className="text-sm font-medium capitalize">{headerParts[0].replace(/"/g, '')}</div>
361
+ <div className="text-xs">{headerParts[headerParts.length - 1].replace(/"/g, '')}</div>
362
+ </div>
363
+
364
+ <div className="flex items-center justify-end gap-x-2">
365
+ <FilterByFunctionButton navigateTo={navigateTo} />
366
+ <UserPreferences
367
+ customButton={
368
+ <Button className="gap-2" variant="neutral">
369
+ Preferences
370
+ <Icon icon="pajamas:preferences" width={20} />
371
+ </Button>
372
+ }
373
+ />
374
+ {profileSource !== undefined && queryClient !== undefined ? (
375
+ <ProfileShareButton
376
+ queryRequest={profileSource.QueryRequest()}
377
+ queryClient={queryClient}
378
+ />
379
+ ) : null}
380
+ <Button
381
+ className="gap-2"
382
+ variant="neutral"
383
+ onClick={e => {
384
+ e.preventDefault();
385
+ onDownloadPProf();
386
+ }}
387
+ disabled={pprofDownloading}
388
+ >
389
+ {pprofDownloading != null && pprofDownloading ? 'Downloading...' : 'Download pprof'}
390
+ <Icon icon="material-symbols:download" width={20} />
391
+ </Button>
392
+ <ViewSelector
393
+ defaultValue=""
394
+ navigateTo={navigateTo}
395
+ position={-1}
396
+ placeholderText="Add panel"
397
+ icon={<Icon icon="material-symbols:add" width={20} />}
398
+ addView={true}
399
+ disabled={isMultiPanelView || dashboardItems.length < 1}
400
+ />
401
+ </div>
402
+ </div>
403
+
404
+ <div className="w-full" ref={ref}>
405
+ {isLoaderVisible ? (
406
+ <>{loader}</>
407
+ ) : (
408
+ <DragDropContext onDragEnd={onDragEnd}>
409
+ <Droppable droppableId="droppable" direction="horizontal">
410
+ {provided => (
411
+ <div
412
+ ref={provided.innerRef}
413
+ className={cx(
414
+ 'grid w-full gap-2',
415
+ isMultiPanelView ? 'grid-cols-2' : 'grid-cols-1'
416
+ )}
417
+ {...provided.droppableProps}
418
+ >
419
+ {dashboardItems.map((dashboardItem, index) => {
420
+ return (
421
+ <Draggable
422
+ key={dashboardItem}
423
+ draggableId={dashboardItem}
424
+ index={index}
425
+ isDragDisabled={!isMultiPanelView}
406
426
  >
407
- {dashboardItems.map((dashboardItem, index) => {
408
- return (
409
- <Draggable
410
- key={dashboardItem}
411
- draggableId={dashboardItem}
427
+ {(provided, snapshot: {isDragging: boolean}) => (
428
+ <div
429
+ ref={provided.innerRef}
430
+ {...provided.draggableProps}
431
+ key={dashboardItem}
432
+ className={cx(
433
+ 'w-full rounded p-2 shadow dark:border-gray-500 dark:bg-gray-700',
434
+ snapshot.isDragging ? 'bg-gray-200' : 'bg-white'
435
+ )}
436
+ >
437
+ <VisualizationPanel
438
+ handleClosePanel={handleClosePanel}
439
+ isMultiPanelView={isMultiPanelView}
440
+ dashboardItem={dashboardItem}
441
+ getDashboardItemByType={getDashboardItemByType}
442
+ dragHandleProps={provided.dragHandleProps}
443
+ navigateTo={navigateTo}
412
444
  index={index}
413
- isDragDisabled={!isMultiPanelView}
414
- >
415
- {(provided, snapshot: {isDragging: boolean}) => (
416
- <div
417
- ref={provided.innerRef}
418
- {...provided.draggableProps}
419
- key={dashboardItem}
420
- className={cx(
421
- 'rounded border border-gray-300 p-3 dark:border-gray-500 dark:bg-gray-700',
422
- isMultiPanelView ? 'w-1/2' : 'w-full',
423
- snapshot.isDragging ? 'bg-gray-200' : 'bg-white'
424
- )}
425
- >
426
- <VisualizationPanel
427
- handleClosePanel={handleClosePanel}
428
- isMultiPanelView={isMultiPanelView}
429
- dashboardItem={dashboardItem}
430
- getDashboardItemByType={getDashboardItemByType}
431
- dragHandleProps={provided.dragHandleProps}
432
- navigateTo={navigateTo}
433
- index={index}
434
- />
435
- </div>
436
- )}
437
- </Draggable>
438
- );
439
- })}
440
- </div>
441
- )}
442
- </Droppable>
443
- </DragDropContext>
445
+ />
446
+ </div>
447
+ )}
448
+ </Draggable>
449
+ );
450
+ })}
451
+ </div>
444
452
  )}
445
- </div>
446
- </Card.Body>
447
- </Card>
453
+ </Droppable>
454
+ </DragDropContext>
455
+ )}
448
456
  </div>
449
457
  </ProfileViewContextProvider>
450
458
  </KeyDownProvider>
@@ -199,15 +199,17 @@ export const TopTable = React.memo(function TopTable({
199
199
  }
200
200
  setActionButtons(
201
201
  dashboardItems.length > 1 ? (
202
- <Button
203
- color="neutral"
204
- onClick={clearSelection}
205
- className="w-auto"
206
- variant="neutral"
207
- disabled={currentSearchString === undefined || currentSearchString.length === 0}
208
- >
209
- Clear selection
210
- </Button>
202
+ <div className="ml-2">
203
+ <Button
204
+ color="neutral"
205
+ onClick={clearSelection}
206
+ className="w-auto"
207
+ variant="neutral"
208
+ disabled={currentSearchString === undefined || currentSearchString.length === 0}
209
+ >
210
+ Clear selection
211
+ </Button>
212
+ </div>
211
213
  ) : (
212
214
  <></>
213
215
  )
@@ -85,7 +85,7 @@ const ProfileShareModal = ({
85
85
  </p>
86
86
  {!isShared || error?.length > 0 ? (
87
87
  <>
88
- <p className="mt-3 mb-2 text-sm text-gray-500 dark:text-gray-300">
88
+ <p className="mb-2 mt-3 text-sm text-gray-500 dark:text-gray-300">
89
89
  Enter a description (optional)
90
90
  </p>
91
91
  <textarea
@@ -94,6 +94,7 @@ const ProfileShareModal = ({
94
94
  onChange={e => setDescription(e.target.value)}
95
95
  ></textarea>
96
96
  <Button
97
+ variant="primary"
97
98
  className="mt-4"
98
99
  onClick={e => {
99
100
  e.preventDefault();
@@ -126,8 +127,14 @@ const ProfileShareButton = ({queryRequest, queryClient, disabled = false}: Props
126
127
 
127
128
  return (
128
129
  <>
129
- <Button color="neutral" onClick={() => setIsOpen(true)} disabled={disabled}>
130
- <Icon icon="ei:share-apple" width={20} />
130
+ <Button
131
+ variant="neutral"
132
+ onClick={() => setIsOpen(true)}
133
+ disabled={disabled}
134
+ className="gap-2"
135
+ >
136
+ Share profile
137
+ <Icon icon="material-symbols:share" width={20} />
131
138
  </Button>
132
139
  <ProfileShareModal
133
140
  isOpen={isOpen}