diff --git a/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.scss b/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.scss new file mode 100644 index 000000000..fd51997a1 --- /dev/null +++ b/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.scss @@ -0,0 +1,36 @@ +@import 'font'; +@import 'color-palette'; + +:host { + .text { + overflow: hidden; + @include ellipsis-overflow(); + @include body-1-regular($gray-7); + padding-right: 8px; + } + + .copy-button { + visibility: hidden; + } +} + +.text-with-copy-action-cell { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + + &.first-column { + @include body-1-medium($gray-9); + } + + &:hover { + .copy-button { + visibility: visible; + } + } +} + +.clickable { + @include link-hover(); +} diff --git a/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.test.ts b/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.test.ts new file mode 100644 index 000000000..bc1380797 --- /dev/null +++ b/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.test.ts @@ -0,0 +1,75 @@ +import { FormattingModule } from '@hypertrace/common'; +import { ButtonSize, CopyToClipboardComponent } from '@hypertrace/components'; +import { byText, createComponentFactory } from '@ngneat/spectator/jest'; +import { MockComponent } from 'ng-mocks'; +import { TableCellStringParser } from '../../data-parsers/table-cell-string-parser'; +import { tableCellColumnProvider, tableCellDataProvider, tableCellProviders } from '../../test/cell-providers'; +import { TextWithCopyActionTableCellRendererComponent } from './text-with-copy-table-cell-renderer.component'; + +describe('Text with copy action table cell renderer component', () => { + const buildComponent = createComponentFactory({ + component: TextWithCopyActionTableCellRendererComponent, + imports: [FormattingModule], + declarations: [MockComponent(CopyToClipboardComponent)], + providers: [ + tableCellProviders( + { + id: 'test' + }, + new TableCellStringParser(undefined!) + ) + ], + shallow: true + }); + + test('should render a plain string', () => { + const spectator = buildComponent({ + providers: [tableCellDataProvider('test-text')] + }); + + expect(spectator.query('.text')).toHaveText('test-text'); + }); + + test('should render a missing string', () => { + const spectator = buildComponent(); + + expect(spectator.query('.text')).toHaveText(''); + }); + + test('should render the copy action button as expected', () => { + const spectator = buildComponent({ providers: [tableCellDataProvider('test-text')] }); + expect(spectator.query('.copy-button')).toExist(); + expect(spectator.query(CopyToClipboardComponent)?.label).toBe(''); + expect(spectator.query(CopyToClipboardComponent)?.size).toBe(ButtonSize.ExtraSmall); + expect(spectator.query(CopyToClipboardComponent)?.text).toBe('test-text'); + }); + + test('should not render the copy action button if string is empty', () => { + const spectator = buildComponent({ providers: [tableCellDataProvider('')] }); + expect(spectator.query('.copy-button')).not.toExist(); + }); + + test('should add clickable class for clickable columns', () => { + const spectator = buildComponent({ + providers: [ + tableCellDataProvider('test-text'), + tableCellColumnProvider({ + id: 'test', + onClick: () => { + /* NOOP */ + } + }) + ] + }); + + expect(spectator.query('.text-with-copy-action-cell')).toHaveClass('clickable'); + }); + + test('should not add clickable class for columns without a click handler', () => { + const spectator = buildComponent({ + providers: [tableCellDataProvider('test-text')] + }); + + expect(spectator.query(byText('test-text'))).not.toHaveClass('clickable'); + }); +}); diff --git a/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.ts b/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.ts new file mode 100644 index 000000000..b5ecffa0f --- /dev/null +++ b/projects/components/src/table/cells/data-renderers/text-with-copy/text-with-copy-table-cell-renderer.component.ts @@ -0,0 +1,31 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ButtonSize } from '../../../../button/button'; +import { TableCellRenderer } from '../../table-cell-renderer'; +import { TableCellRendererBase } from '../../table-cell-renderer-base'; +import { CoreTableCellParserType } from '../../types/core-table-cell-parser-type'; +import { CoreTableCellRendererType } from '../../types/core-table-cell-renderer-type'; +import { TableCellAlignmentType } from '../../types/table-cell-alignment-type'; + +@Component({ + selector: 'ht-text-table-with-copy-cell-renderer', + styleUrls: ['./text-with-copy-table-cell-renderer.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + template: ` +