diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index bee21b2aaf..caccac38cb 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -100,19 +100,19 @@ import { CreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; import { - ThemedCreateCommunityParentSelectorComponent + ThemedCreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/themed-create-community-parent-selector.component'; import { CreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; import { - ThemedCreateItemParentSelectorComponent + ThemedCreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/themed-create-item-parent-selector.component'; import { CreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component'; import { - ThemedCreateCollectionParentSelectorComponent + ThemedCreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/themed-create-collection-parent-selector.component'; import { CommunitySearchResultListElementComponent @@ -124,19 +124,19 @@ import { EditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; import { - ThemedEditItemSelectorComponent + ThemedEditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/themed-edit-item-selector.component'; import { EditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; import { - ThemedEditCommunitySelectorComponent + ThemedEditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/themed-edit-community-selector.component'; import { EditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; import { - ThemedEditCollectionSelectorComponent + ThemedEditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/themed-edit-collection-selector.component'; import { RoleDirective } from './roles/role.directive'; import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component'; @@ -242,9 +242,10 @@ import { } from './object-list/listable-notification-object/listable-notification-object.component'; import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component'; import { MetadataFieldWrapperComponent } from './metadata-field-wrapper/metadata-field-wrapper.component'; -import { LogInExternalProviderComponent } from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; - - +import { + LogInExternalProviderComponent +} from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; +import { ShortNumberPipe } from './utils/short-number.pipe'; const MODULES = [ CommonModule, @@ -283,6 +284,7 @@ const PIPES = [ ObjNgFor, BrowserOnlyPipe, MarkdownPipe, + ShortNumberPipe ]; const COMPONENTS = [ diff --git a/src/app/shared/utils/short-number.pipe.spec.ts b/src/app/shared/utils/short-number.pipe.spec.ts new file mode 100644 index 0000000000..99fb246f54 --- /dev/null +++ b/src/app/shared/utils/short-number.pipe.spec.ts @@ -0,0 +1,96 @@ +import { TestBed } from '@angular/core/testing'; + +import { ShortNumberPipe } from './short-number.pipe'; + +describe('ShortNumber Pipe', () => { + + let shortNumberPipe: ShortNumberPipe; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + ShortNumberPipe + ], + }).compileComponents(); + + shortNumberPipe = TestBed.inject(ShortNumberPipe); + }); + + it('should not transform with an invalid number', async () => { + await testTransform( + 'tre', + 'tre' + ); + }); + + it('should not transform with an empty string', async () => { + await testTransform( + '', + '' + ); + }); + + it('should not transform with zero', async () => { + await testTransform( + 0, + '0' + ); + }); + + it('should render 1K', async () => { + await testTransform( + '1000', + '1K' + ); + }); + + it('should render 1K', async () => { + await testTransform( + 1000, + '1K' + ); + }); + + it('should render 19.3K', async () => { + await testTransform( + 19300, + '19.3K' + ); + }); + + it('should render 1M', async () => { + await testTransform( + 1000000, + '1M' + ); + }); + + it('should render 1B', async () => { + await testTransform( + 1000000000, + '1B' + ); + }); + + it('should render 1T', async () => { + await testTransform( + 1000000000000, + '1T' + ); + }); + + it('should render 1Q', async () => { + await testTransform( + 1000000000000000, + '1Q' + ); + }); + + async function testTransform(input: any, output: string) { + expect( + await shortNumberPipe.transform(input) + ).toMatch( + output + ); + } +}); diff --git a/src/app/shared/utils/short-number.pipe.ts b/src/app/shared/utils/short-number.pipe.ts new file mode 100644 index 0000000000..e4d5cf8356 --- /dev/null +++ b/src/app/shared/utils/short-number.pipe.ts @@ -0,0 +1,40 @@ +import { Pipe, PipeTransform } from '@angular/core'; +import { isEmpty } from '../empty.util'; + + +@Pipe({ + name: 'dsShortNumber' +}) +export class ShortNumberPipe implements PipeTransform { + + transform(number: number, args?: any): any { + // will only work value is a valid number + if (isNaN(number) || isEmpty(number) || number === 0) { + return number; + } + + let abs = Math.abs(number); + const rounder = Math.pow(10, 1); + const isNegative = number < 0; // will also work for Negetive numbers + let key = ''; + + const powers = [ + {key: 'Q', value: Math.pow(10, 15)}, + {key: 'T', value: Math.pow(10, 12)}, + {key: 'B', value: Math.pow(10, 9)}, + {key: 'M', value: Math.pow(10, 6)}, + {key: 'K', value: 1000} + ]; + + for (let i = 0; i < powers.length; i++) { + let reduced = abs / powers[i].value; + reduced = Math.round(reduced * rounder) / rounder; + if (reduced >= 1) { + abs = reduced; + key = powers[i].key; + break; + } + } + return (isNegative ? '-' : '') + abs + key; + } +}