From c1b77c6e5c3684426cb229077dfab3159de45f58 Mon Sep 17 00:00:00 2001
From: OZGCloud <ozgcloud@mgm-tp.com>
Date: Thu, 31 Oct 2024 14:57:47 +0100
Subject: [PATCH] OZG-6423 OZG-7064 Replace mat icons in user icon component

---
 alfa-client/libs/design-system/src/index.ts   |  2 +
 .../error-icon/error-icon.component.spec.ts   | 21 +++++++
 .../icons/error-icon/error-icon.component.ts  | 28 +++++++++
 .../icons/error-icon/error-icon.stories.ts    | 27 ++++++++
 .../icons/user-icon/user-icon.component.ts    |  4 +-
 .../lib/user-icon/user-icon.component.html    | 27 ++++----
 .../lib/user-icon/user-icon.component.scss    | 61 -------------------
 .../lib/user-icon/user-icon.component.spec.ts | 13 ++--
 .../src/lib/user-icon/user-icon.component.ts  | 19 +-----
 .../src/lib/user-profile.module.ts            | 17 ++++--
 10 files changed, 113 insertions(+), 106 deletions(-)
 create mode 100644 alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.spec.ts
 create mode 100644 alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.ts
 create mode 100644 alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.stories.ts
 delete mode 100644 alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.scss

diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts
index dae1c087a8..66c369f9fa 100644
--- a/alfa-client/libs/design-system/src/index.ts
+++ b/alfa-client/libs/design-system/src/index.ts
@@ -20,6 +20,7 @@ export * from './lib/icons/bescheid-generate-icon/bescheid-generate-icon.compone
 export * from './lib/icons/bescheid-upload-icon/bescheid-upload-icon.component';
 export * from './lib/icons/close-icon/close-icon.component';
 export * from './lib/icons/edit-icon/edit-icon.component';
+export * from './lib/icons/error-icon/error-icon.component';
 export * from './lib/icons/exclamation-icon/exclamation-icon.component';
 export * from './lib/icons/external-unit-icon/external-unit-icon.component';
 export * from './lib/icons/file-icon/file-icon.component';
@@ -35,6 +36,7 @@ export * from './lib/icons/search-icon/search-icon.component';
 export * from './lib/icons/send-icon/send-icon.component';
 export * from './lib/icons/spinner-icon/spinner-icon.component';
 export * from './lib/icons/stamp-icon/stamp-icon.component';
+export * from './lib/icons/user-icon/user-icon.component';
 export * from './lib/icons/users-icon/users-icon.component';
 export * from './lib/instant-search/instant-search/instant-search.component';
 export * from './lib/instant-search/instant-search/instant-search.model';
diff --git a/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.spec.ts b/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.spec.ts
new file mode 100644
index 0000000000..c6f909f03c
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ErrorIconComponent } from './error-icon.component';
+
+describe('ErrorIconComponent', () => {
+  let component: ErrorIconComponent;
+  let fixture: ComponentFixture<ErrorIconComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ErrorIconComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(ErrorIconComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.ts
new file mode 100644
index 0000000000..efe33c3a26
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.component.ts
@@ -0,0 +1,28 @@
+import { NgClass } from '@angular/common';
+import { Component, Input } from '@angular/core';
+import { twMerge } from 'tailwind-merge';
+import { IconVariants, iconVariants } from '../iconVariants';
+
+@Component({
+  selector: 'ods-error-icon',
+  standalone: true,
+  imports: [NgClass],
+  template: `<svg
+    viewBox="0 0 24 24"
+    [ngClass]="[twMerge(iconVariants({ size }), 'fill-error', class)]"
+    aria-hidden="true"
+    fill="inherit"
+    xmlns="http://www.w3.org/2000/svg"
+  >
+    <path
+      d="M12 17C12.2833 17 12.5208 16.9042 12.7125 16.7125C12.9042 16.5208 13 16.2833 13 16C13 15.7167 12.9042 15.4792 12.7125 15.2875C12.5208 15.0958 12.2833 15 12 15C11.7167 15 11.4792 15.0958 11.2875 15.2875C11.0958 15.4792 11 15.7167 11 16C11 16.2833 11.0958 16.5208 11.2875 16.7125C11.4792 16.9042 11.7167 17 12 17ZM11 13H13V7H11V13ZM12 22C10.6167 22 9.31667 21.7375 8.1 21.2125C6.88333 20.6875 5.825 19.975 4.925 19.075C4.025 18.175 3.3125 17.1167 2.7875 15.9C2.2625 14.6833 2 13.3833 2 12C2 10.6167 2.2625 9.31667 2.7875 8.1C3.3125 6.88333 4.025 5.825 4.925 4.925C5.825 4.025 6.88333 3.3125 8.1 2.7875C9.31667 2.2625 10.6167 2 12 2C13.3833 2 14.6833 2.2625 15.9 2.7875C17.1167 3.3125 18.175 4.025 19.075 4.925C19.975 5.825 20.6875 6.88333 21.2125 8.1C21.7375 9.31667 22 10.6167 22 12C22 13.3833 21.7375 14.6833 21.2125 15.9C20.6875 17.1167 19.975 18.175 19.075 19.075C18.175 19.975 17.1167 20.6875 15.9 21.2125C14.6833 21.7375 13.3833 22 12 22ZM12 20C14.2333 20 16.125 19.225 17.675 17.675C19.225 16.125 20 14.2333 20 12C20 9.76667 19.225 7.875 17.675 6.325C16.125 4.775 14.2333 4 12 4C9.76667 4 7.875 4.775 6.325 6.325C4.775 7.875 4 9.76667 4 12C4 14.2333 4.775 16.125 6.325 17.675C7.875 19.225 9.76667 20 12 20Z"
+    />
+  </svg>`,
+})
+export class ErrorIconComponent {
+  @Input() size: IconVariants['size'] = 'medium';
+  @Input() class: string = undefined;
+
+  readonly iconVariants = iconVariants;
+  readonly twMerge = twMerge;
+}
diff --git a/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.stories.ts b/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.stories.ts
new file mode 100644
index 0000000000..5f77738047
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/icons/error-icon/error-icon.stories.ts
@@ -0,0 +1,27 @@
+import type { Meta, StoryObj } from '@storybook/angular';
+
+import { ErrorIconComponent } from './error-icon.component';
+
+const meta: Meta<ErrorIconComponent> = {
+  title: 'Icons/Error icon',
+  component: ErrorIconComponent,
+  excludeStories: /.*Data$/,
+  tags: ['autodocs'],
+};
+
+export default meta;
+type Story = StoryObj<ErrorIconComponent>;
+
+export const Default: Story = {
+  args: { size: 'medium' },
+  argTypes: {
+    size: {
+      control: 'select',
+      options: ['small', 'medium', 'large', 'extra-large', 'full'],
+      description: 'Size of icon. Property "full" means 100%',
+      table: {
+        defaultValue: { summary: 'medium' },
+      },
+    },
+  },
+};
diff --git a/alfa-client/libs/design-system/src/lib/icons/user-icon/user-icon.component.ts b/alfa-client/libs/design-system/src/lib/icons/user-icon/user-icon.component.ts
index 90c01e353f..a3a53a9097 100644
--- a/alfa-client/libs/design-system/src/lib/icons/user-icon/user-icon.component.ts
+++ b/alfa-client/libs/design-system/src/lib/icons/user-icon/user-icon.component.ts
@@ -10,13 +10,13 @@ import { IconVariants, iconVariants } from '../iconVariants';
   imports: [CommonModule, ExclamationIconComponent],
   template: `
     <svg
-      viewBox="0 0 47 47"
+      viewBox="0 0 112 112"
       fill="none"
       xmlns="http://www.w3.org/2000/svg"
       [ngClass]="[twMerge(iconVariants({ size }), 'fill-ozggray-300', class)]"
     >
       <path
-        d="M23.5 3.91663C12.69 3.91663 3.91669 12.69 3.91669 23.5C3.91669 34.31 12.69 43.0833 23.5 43.0833C34.31 43.0833 43.0834 34.31 43.0834 23.5C43.0834 12.69 34.31 3.91663 23.5 3.91663ZM23.5 9.79163C26.7509 9.79163 29.375 12.4158 29.375 15.6666C29.375 18.9175 26.7509 21.5416 23.5 21.5416C20.2492 21.5416 17.625 18.9175 17.625 15.6666C17.625 12.4158 20.2492 9.79163 23.5 9.79163ZM23.5 37.6C18.6042 37.6 14.2763 35.0933 11.75 31.2941C11.8088 27.397 19.5834 25.2625 23.5 25.2625C27.3971 25.2625 35.1913 27.397 35.25 31.2941C32.7238 35.0933 28.3959 37.6 23.5 37.6Z"
+        d="M56 0.970734C25.6239 0.970734 0.970886 25.6239 0.970886 56C0.970886 86.3761 25.6239 111.029 56 111.029C86.3761 111.029 111.029 86.3761 111.029 56C111.029 25.6239 86.3761 0.970734 56 0.970734ZM56 17.4795C65.135 17.4795 72.5087 24.8534 72.5087 33.9881C72.5087 43.1232 65.135 50.4969 56 50.4969C46.8652 50.4969 39.4912 43.1232 39.4912 33.9881C39.4912 24.8534 46.8652 17.4795 56 17.4795ZM56 95.621C42.2428 95.621 30.0814 88.5772 22.9825 77.9014C23.1477 66.9506 44.9943 60.9526 56 60.9526C66.9508 60.9526 88.8525 66.9506 89.0175 77.9014C81.9189 88.5772 69.7575 95.621 56 95.621Z"
       />
     </svg>
   `,
diff --git a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.html b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.html
index 7c3ff63447..e74237977c 100644
--- a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.html
+++ b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.html
@@ -27,29 +27,26 @@
   <div
     [matTooltipDisabled]="disableTooltip"
     data-test-class="user-profile-icon"
-    [class.initials]="!!userProfileStateResource.resource || userProfileStateResource.error"
-    class="user-profile"
+    class="relative flex size-9 items-center justify-center overflow-hidden rounded-full text-lg text-whitetext"
+    [class.bg-ozggray-900]="userProfileStateResource.resource || errorMessageCode === messageCode.RESOURCE_NOT_FOUND"
     [matTooltip]="tooltip"
   >
     <ng-container *ngIf="userProfileStateResource.resource; else noUser">
       <span data-test-class="user-profile-assigned">{{ initials }}</span>
     </ng-container>
     <ng-template #noUser>
-      <mat-icon *ngIf="!userProfileStateResource.error" data-test-class="user-profile-unassigned"
-        >account_circle_outline</mat-icon
-      >
-      <span
-        *ngIf="errorMessageCode === messageCode.RESOURCE_NOT_FOUND"
-        data-test-class="user-profile-user-not-found"
-        >!</span
-      >
-      <mat-icon
+      <ods-user-icon
+        *ngIf="!userProfileStateResource.error"
+        data-test-class="user-profile-unassigned"
+        class="size-9 fill-ozggray-800"
+        style="--mdc-icon-button-icon-size: 36px"
+      />
+      <span *ngIf="errorMessageCode === messageCode.RESOURCE_NOT_FOUND" data-test-class="user-profile-user-not-found">!</span>
+      <ods-error-icon
         *ngIf="errorMessageCode === messageCode.SERVICE_UNAVAILABLE"
-        class="unavailable"
         data-test-class="user-profile-service-unavailable"
-        >error_outline</mat-icon
-      >
+        style="--mdc-icon-button-icon-size: 42px"
+      />
     </ng-template>
-    <div class="picture"></div>
   </div>
 </ozgcloud-spinner>
diff --git a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.scss b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.scss
deleted file mode 100644
index dda9a87b9b..0000000000
--- a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.scss
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den
- * Ministerpräsidenten des Landes Schleswig-Holstein
- * Staatskanzlei
- * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
- *
- * Lizenziert unter der EUPL, Version 1.2 oder - sobald
- * diese von der Europäischen Kommission genehmigt wurden -
- * Folgeversionen der EUPL ("Lizenz");
- * Sie dürfen dieses Werk ausschließlich gemäß
- * dieser Lizenz nutzen.
- * Eine Kopie der Lizenz finden Sie hier:
- *
- * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * Sofern nicht durch anwendbare Rechtsvorschriften
- * gefordert oder in schriftlicher Form vereinbart, wird
- * die unter der Lizenz verbreitete Software "so wie sie
- * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
- * ausdrücklich oder stillschweigend - verbreitet.
- * Die sprachspezifischen Genehmigungen und Beschränkungen
- * unter der Lizenz sind dem Lizenztext zu entnehmen.
- */
-@use 'sass:map';
-@use '@angular/material' as mat;
-@import 'variables';
-
-.user-profile {
-  width: 36px;
-  height: 36px;
-  border-radius: 50%;
-  position: relative;
-  overflow: hidden;
-
-  &.initials {
-    background-color: #3e3e3e;
-    color: #fff;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-size: 18px;
-  }
-}
-
-mat-icon {
-  color: $grey;
-  position: absolute;
-  left: 50%;
-  top: 50%;
-  transform: scale(1.78) translate(-50%, -50%);
-  transform-origin: left top;
-}
-
-span {
-  line-height: 1;
-}
-
-mat-icon.unavailable {
-  background-color: #fff;
-  color: mat.get-color-from-palette($warnPalette);
-}
diff --git a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.spec.ts b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.spec.ts
index c2c4f8ef45..7c3850d8e8 100644
--- a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.spec.ts
+++ b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.spec.ts
@@ -31,15 +31,12 @@ import {
 } from '@alfa-client/tech-shared';
 import { getElementFromFixture } from '@alfa-client/test-utils';
 import { SpinnerComponent } from '@alfa-client/ui';
-import {
-  NO_NAME_MESSAGE,
-  UserProfileResource,
-  userProfileMessage,
-} from '@alfa-client/user-profile-shared';
+import { NO_NAME_MESSAGE, UserProfileResource, userProfileMessage } from '@alfa-client/user-profile-shared';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MatIcon } from '@angular/material/icon';
 import { MatTooltipModule } from '@angular/material/tooltip';
 import { faker } from '@faker-js/faker';
+import { ErrorIconComponent, UserIconComponent as OdsUserIconComponent } from '@ods/system';
 import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
 import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
 import { MockComponent, MockModule } from 'ng-mocks';
@@ -64,6 +61,8 @@ describe('UserIconComponent', () => {
         MatIcon,
         MockComponent(SpinnerComponent),
         MockModule(MatTooltipModule),
+        MockComponent(ErrorIconComponent),
+        MockComponent(OdsUserIconComponent),
       ],
     });
   });
@@ -183,9 +182,7 @@ describe('UserIconComponent', () => {
 
     describe('on unexpected error', () => {
       it('should return empty string on non existing messageCode issue', () => {
-        component.userProfileStateResource = createErrorStateResource(
-          createApiErrorWithMessageCode(faker.random.word()),
-        );
+        component.userProfileStateResource = createErrorStateResource(createApiErrorWithMessageCode(faker.random.word()));
 
         const tooltip = component.getErrorTooltip();
 
diff --git a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.ts b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.ts
index 2a5c2244d1..1ee555b593 100644
--- a/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.ts
+++ b/alfa-client/libs/user-profile/src/lib/user-icon/user-icon.component.ts
@@ -21,30 +21,17 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
+import { ApiError, MessageCode, StateResource, createEmptyStateResource, hasStateResourceError } from '@alfa-client/tech-shared';
+import { UserProfileResource, getUserName, getUserNameInitials, userProfileMessage } from '@alfa-client/user-profile-shared';
 import { Component, Input, SimpleChanges } from '@angular/core';
-import {
-  ApiError,
-  createEmptyStateResource,
-  hasStateResourceError,
-  MessageCode,
-  StateResource,
-} from '@alfa-client/tech-shared';
-import {
-  getUserName,
-  getUserNameInitials,
-  userProfileMessage,
-  UserProfileResource,
-} from '@alfa-client/user-profile-shared';
 import { isUndefined } from 'lodash-es';
 
 @Component({
   selector: 'alfa-user-icon',
   templateUrl: './user-icon.component.html',
-  styleUrls: ['./user-icon.component.scss'],
 })
 export class UserIconComponent {
-  @Input() userProfileStateResource: StateResource<UserProfileResource> =
-    createEmptyStateResource<UserProfileResource>();
+  @Input() userProfileStateResource: StateResource<UserProfileResource> = createEmptyStateResource<UserProfileResource>();
   @Input() disableTooltip: boolean = false;
 
   readonly messageCode = MessageCode;
diff --git a/alfa-client/libs/user-profile/src/lib/user-profile.module.ts b/alfa-client/libs/user-profile/src/lib/user-profile.module.ts
index fe2547f655..c6cdcd1a5a 100644
--- a/alfa-client/libs/user-profile/src/lib/user-profile.module.ts
+++ b/alfa-client/libs/user-profile/src/lib/user-profile.module.ts
@@ -21,12 +21,13 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-import { RouterModule } from '@angular/router';
 import { TechSharedModule } from '@alfa-client/tech-shared';
 import { UiModule } from '@alfa-client/ui';
 import { UserProfileSharedModule } from '@alfa-client/user-profile-shared';
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { RouterModule } from '@angular/router';
+import { ErrorIconComponent, UserIconComponent as OdsUserIconComponent } from '@ods/system';
 import { AssignUserProfileButtonContainerComponent } from './assign-user-profile-button-container/assign-user-profile-button-container.component';
 import { LinkWithUserNameTooltipContainerComponent } from './link-with-user-name-tooltip-container/link-with-user-name-tooltip-container.component';
 import { LinkWithUserNameTooltipComponent } from './link-with-user-name-tooltip-container/link-with-user-name-tooltip/link-with-user-name-tooltip.component';
@@ -48,7 +49,15 @@ import { UserProfileSearchComponent } from './user-profile-search-container/user
 import { UserProfileComponent } from './user-profile/user-profile.component';
 
 @NgModule({
-  imports: [CommonModule, TechSharedModule, UiModule, UserProfileSharedModule, RouterModule],
+  imports: [
+    CommonModule,
+    TechSharedModule,
+    UiModule,
+    UserProfileSharedModule,
+    RouterModule,
+    OdsUserIconComponent,
+    ErrorIconComponent,
+  ],
   declarations: [
     UserIconComponent,
     UserProfileInVorgangContainerComponent,
-- 
GitLab