Skip to content
Snippets Groups Projects
Commit 2e53b59a authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-6423 OZG-7064 Replace mat icons in user icon...

Merge pull request 'OZG-6423 OZG-7064 Replace mat icons in user icon component' (#813) from OZG-6423-replace-mat-icons into master

Reviewed-on: https://git.ozg-sh.de/ozgcloud-app/alfa/pulls/813


Reviewed-by: default avatarOZGCloud <ozgcloud@mgm-tp.com>
parents 31da07fd f635082c
Branches
Tags
No related merge requests found
Showing
with 113 additions and 106 deletions
...@@ -22,6 +22,7 @@ export * from './lib/icons/bescheid-upload-icon/bescheid-upload-icon.component'; ...@@ -22,6 +22,7 @@ export * from './lib/icons/bescheid-upload-icon/bescheid-upload-icon.component';
export * from './lib/icons/check-icon/check-icon.component'; export * from './lib/icons/check-icon/check-icon.component';
export * from './lib/icons/close-icon/close-icon.component'; export * from './lib/icons/close-icon/close-icon.component';
export * from './lib/icons/edit-icon/edit-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/exclamation-icon/exclamation-icon.component';
export * from './lib/icons/external-unit-icon/external-unit-icon.component'; export * from './lib/icons/external-unit-icon/external-unit-icon.component';
export * from './lib/icons/file-icon/file-icon.component'; export * from './lib/icons/file-icon/file-icon.component';
...@@ -37,6 +38,7 @@ export * from './lib/icons/search-icon/search-icon.component'; ...@@ -37,6 +38,7 @@ export * from './lib/icons/search-icon/search-icon.component';
export * from './lib/icons/send-icon/send-icon.component'; export * from './lib/icons/send-icon/send-icon.component';
export * from './lib/icons/spinner-icon/spinner-icon.component'; export * from './lib/icons/spinner-icon/spinner-icon.component';
export * from './lib/icons/stamp-icon/stamp-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/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.component';
export * from './lib/instant-search/instant-search/instant-search.model'; export * from './lib/instant-search/instant-search/instant-search.model';
......
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();
});
});
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;
}
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' },
},
},
},
};
...@@ -10,13 +10,13 @@ import { IconVariants, iconVariants } from '../iconVariants'; ...@@ -10,13 +10,13 @@ import { IconVariants, iconVariants } from '../iconVariants';
imports: [CommonModule, ExclamationIconComponent], imports: [CommonModule, ExclamationIconComponent],
template: ` template: `
<svg <svg
viewBox="0 0 47 47" viewBox="0 0 112 112"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
[ngClass]="[twMerge(iconVariants({ size }), 'fill-ozggray-300', class)]" [ngClass]="[twMerge(iconVariants({ size }), 'fill-ozggray-300', class)]"
> >
<path <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> </svg>
`, `,
......
...@@ -27,29 +27,26 @@ ...@@ -27,29 +27,26 @@
<div <div
[matTooltipDisabled]="disableTooltip" [matTooltipDisabled]="disableTooltip"
data-test-class="user-profile-icon" data-test-class="user-profile-icon"
[class.initials]="!!userProfileStateResource.resource || userProfileStateResource.error" class="relative flex size-9 items-center justify-center overflow-hidden rounded-full text-lg text-whitetext"
class="user-profile" [class.bg-ozggray-900]="userProfileStateResource.resource || errorMessageCode === messageCode.RESOURCE_NOT_FOUND"
[matTooltip]="tooltip" [matTooltip]="tooltip"
> >
<ng-container *ngIf="userProfileStateResource.resource; else noUser"> <ng-container *ngIf="userProfileStateResource.resource; else noUser">
<span data-test-class="user-profile-assigned">{{ initials }}</span> <span data-test-class="user-profile-assigned">{{ initials }}</span>
</ng-container> </ng-container>
<ng-template #noUser> <ng-template #noUser>
<mat-icon *ngIf="!userProfileStateResource.error" data-test-class="user-profile-unassigned" <ods-user-icon
>account_circle_outline</mat-icon *ngIf="!userProfileStateResource.error"
> data-test-class="user-profile-unassigned"
<span class="size-9 fill-ozggray-800"
*ngIf="errorMessageCode === messageCode.RESOURCE_NOT_FOUND" style="--mdc-icon-button-icon-size: 36px"
data-test-class="user-profile-user-not-found" />
>!</span <span *ngIf="errorMessageCode === messageCode.RESOURCE_NOT_FOUND" data-test-class="user-profile-user-not-found">!</span>
> <ods-error-icon
<mat-icon
*ngIf="errorMessageCode === messageCode.SERVICE_UNAVAILABLE" *ngIf="errorMessageCode === messageCode.SERVICE_UNAVAILABLE"
class="unavailable"
data-test-class="user-profile-service-unavailable" data-test-class="user-profile-service-unavailable"
>error_outline</mat-icon style="--mdc-icon-button-icon-size: 42px"
> />
</ng-template> </ng-template>
<div class="picture"></div>
</div> </div>
</ozgcloud-spinner> </ozgcloud-spinner>
/**
* 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.m2-get-color-from-palette($warnPalette);
}
...@@ -31,15 +31,12 @@ import { ...@@ -31,15 +31,12 @@ import {
} from '@alfa-client/tech-shared'; } from '@alfa-client/tech-shared';
import { getElementFromFixture } from '@alfa-client/test-utils'; import { getElementFromFixture } from '@alfa-client/test-utils';
import { SpinnerComponent } from '@alfa-client/ui'; import { SpinnerComponent } from '@alfa-client/ui';
import { import { NO_NAME_MESSAGE, UserProfileResource, userProfileMessage } from '@alfa-client/user-profile-shared';
NO_NAME_MESSAGE,
UserProfileResource,
userProfileMessage,
} from '@alfa-client/user-profile-shared';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatIcon } from '@angular/material/icon'; import { MatIcon } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTooltipModule } from '@angular/material/tooltip';
import { faker } from '@faker-js/faker'; import { faker } from '@faker-js/faker';
import { ErrorIconComponent, UserIconComponent as OdsUserIconComponent } from '@ods/system';
import { getDataTestClassOf } from 'libs/tech-shared/test/data-test'; import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile'; import { createUserProfileResource } from 'libs/user-profile-shared/test/user-profile';
import { MockComponent, MockModule } from 'ng-mocks'; import { MockComponent, MockModule } from 'ng-mocks';
...@@ -64,6 +61,8 @@ describe('UserIconComponent', () => { ...@@ -64,6 +61,8 @@ describe('UserIconComponent', () => {
MatIcon, MatIcon,
MockComponent(SpinnerComponent), MockComponent(SpinnerComponent),
MockModule(MatTooltipModule), MockModule(MatTooltipModule),
MockComponent(ErrorIconComponent),
MockComponent(OdsUserIconComponent),
], ],
}); });
}); });
...@@ -183,9 +182,7 @@ describe('UserIconComponent', () => { ...@@ -183,9 +182,7 @@ describe('UserIconComponent', () => {
describe('on unexpected error', () => { describe('on unexpected error', () => {
it('should return empty string on non existing messageCode issue', () => { it('should return empty string on non existing messageCode issue', () => {
component.userProfileStateResource = createErrorStateResource( component.userProfileStateResource = createErrorStateResource(createApiErrorWithMessageCode(faker.word.sample()));
createApiErrorWithMessageCode(faker.word.sample()),
);
const tooltip = component.getErrorTooltip(); const tooltip = component.getErrorTooltip();
......
...@@ -21,30 +21,17 @@ ...@@ -21,30 +21,17 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen * Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen. * 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 { 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'; import { isUndefined } from 'lodash-es';
@Component({ @Component({
selector: 'alfa-user-icon', selector: 'alfa-user-icon',
templateUrl: './user-icon.component.html', templateUrl: './user-icon.component.html',
styleUrls: ['./user-icon.component.scss'],
}) })
export class UserIconComponent { export class UserIconComponent {
@Input() userProfileStateResource: StateResource<UserProfileResource> = @Input() userProfileStateResource: StateResource<UserProfileResource> = createEmptyStateResource<UserProfileResource>();
createEmptyStateResource<UserProfileResource>();
@Input() disableTooltip: boolean = false; @Input() disableTooltip: boolean = false;
readonly messageCode = MessageCode; readonly messageCode = MessageCode;
......
...@@ -21,12 +21,13 @@ ...@@ -21,12 +21,13 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen * Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen. * 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 { TechSharedModule } from '@alfa-client/tech-shared';
import { UiModule } from '@alfa-client/ui'; import { UiModule } from '@alfa-client/ui';
import { UserProfileSharedModule } from '@alfa-client/user-profile-shared'; 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 { 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 { 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'; 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 ...@@ -48,7 +49,15 @@ import { UserProfileSearchComponent } from './user-profile-search-container/user
import { UserProfileComponent } from './user-profile/user-profile.component'; import { UserProfileComponent } from './user-profile/user-profile.component';
@NgModule({ @NgModule({
imports: [CommonModule, TechSharedModule, UiModule, UserProfileSharedModule, RouterModule], imports: [
CommonModule,
TechSharedModule,
UiModule,
UserProfileSharedModule,
RouterModule,
OdsUserIconComponent,
ErrorIconComponent,
],
declarations: [ declarations: [
UserIconComponent, UserIconComponent,
UserProfileInVorgangContainerComponent, UserProfileInVorgangContainerComponent,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment