From 6898389e0e43ed1c7770050d2f0d90d424627be2 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 18 Oct 2022 16:29:47 +0200 Subject: [PATCH] Show identifier image if avatar cannot be loaded. --- .../framework/angular/avatar.component.html | 2 +- .../app/framework/angular/avatar.component.ts | 18 ++++- .../app/framework/angular/avatar.stories.tsx | 77 +++++++++++++++++++ frontend/src/app/theme/_common.scss | 2 +- 4 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 frontend/src/app/framework/angular/avatar.stories.tsx diff --git a/frontend/src/app/framework/angular/avatar.component.html b/frontend/src/app/framework/angular/avatar.component.html index 19663b362..f1c5c770c 100644 --- a/frontend/src/app/framework/angular/avatar.component.html +++ b/frontend/src/app/framework/angular/avatar.component.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/app/framework/angular/avatar.component.ts b/frontend/src/app/framework/angular/avatar.component.ts index 89d3ae445..a0e132841 100644 --- a/frontend/src/app/framework/angular/avatar.component.ts +++ b/frontend/src/app/framework/angular/avatar.component.ts @@ -27,9 +27,15 @@ export class AvatarComponent implements OnChanges { public imageSource?: string | null; public imageSize = '50px'; + public actualImage: string | undefined | null; + public ngOnChanges(changes: SimpleChanges) { + if (changes['image']) { + this.actualImage = this.image; + } + if (changes['image'] || changes['identifier']) { - this.imageSource = this.image || this.createSvg(); + this.updateSource(); } if (changes['size']) { @@ -37,6 +43,16 @@ export class AvatarComponent implements OnChanges { } } + private updateSource() { + this.imageSource = this.actualImage || this.createSvg(); + } + + public unsetImage() { + this.actualImage = null; + + this.updateSource(); + } + private createSvg() { if (this.identifier) { return `data:image/svg+xml;utf8,${picasso(this.identifier)}`; diff --git a/frontend/src/app/framework/angular/avatar.stories.tsx b/frontend/src/app/framework/angular/avatar.stories.tsx new file mode 100644 index 000000000..7805ba08d --- /dev/null +++ b/frontend/src/app/framework/angular/avatar.stories.tsx @@ -0,0 +1,77 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { moduleMetadata } from '@storybook/angular'; +import { Meta, Story } from '@storybook/angular/types-6-0'; +import { AvatarComponent, SqxFrameworkModule } from '@app/framework'; + +export default { + title: 'Framework/Avatar', + component: AvatarComponent, + argTypes: { + image: { + control: 'text', + }, + identifier: { + control: 'text', + }, + size: { + control: 'number', + }, + }, + decorators: [ + moduleMetadata({ + imports: [ + BrowserAnimationsModule, + SqxFrameworkModule, + SqxFrameworkModule.forRoot(), + ], + }), + ], +} as Meta; + +const Template: Story = (args: AvatarComponent) => ({ + props: args, +}); + +export const Empty = Template.bind({}); + +Empty.args = { +}; + +export const Image = Template.bind({}); + +Image.args = { + image: 'https://via.placeholder.com/50', +}; + +export const InvalidImage = Template.bind({}); + +InvalidImage.args = { + image: 'https://invalid-url', +}; + +export const Identifier = Template.bind({}); + +Identifier.args = { + identifier: 'image', +}; + +export const Large = Template.bind({}); + +Large.args = { + identifier: 'image', + size: 200, +}; + +export const InvalidImageWithFallback = Template.bind({}); + +InvalidImageWithFallback.args = { + image: 'https://invalid-url', + identifier: 'image', +}; \ No newline at end of file diff --git a/frontend/src/app/theme/_common.scss b/frontend/src/app/theme/_common.scss index 2424b70c0..97e207e9f 100644 --- a/frontend/src/app/theme/_common.scss +++ b/frontend/src/app/theme/_common.scss @@ -22,7 +22,7 @@ body { } hr { - background-color: $color-border; + border-color: $color-border; } // Common style for user email.