Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eo, auth): visualize self better in actor-menu #3650

Merged
merged 10 commits into from
Oct 22, 2024
79 changes: 67 additions & 12 deletions libs/eo/auth/ui-actor-menu/actor-menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,46 @@ import { MatMenuModule } from '@angular/material/menu';
import { TranslocoPipe } from '@ngneat/transloco';
import { NgClass } from '@angular/common';

import { EoScrollViewComponent } from '@energinet-datahub/eo/shared/components/ui-scroll-view';
import { Actor } from '@energinet-datahub/eo/auth/domain';
import { translations } from '@energinet-datahub/eo/translations';
import { WattIconComponent } from '@energinet-datahub/watt/icon';

const selector = 'eo-actor-menu';

@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
encapsulation: ViewEncapsulation.None,
imports: [TranslocoPipe, MatMenuModule, NgClass],
imports: [TranslocoPipe, MatMenuModule, NgClass, EoScrollViewComponent, WattIconComponent],
selector,
styles: `
@use '@energinet-datahub/watt/utils' as watt;

${selector} .menu-trigger {
cursor: pointer;
pointer-events: none;

watt-icon {
display: none;
}

&.has-actors {
position: relative;
pointer-events: auto;
watt-icon {
display: flex;
color: #fff;
transition: transform 0.2s linear;
position: absolute;
top: 50%;
right: 8px;
transform: translate3d(0, -50%, 0);
}

&[aria-expanded='true'] watt-icon {
transform: translate3d(0, -50%, 0) rotate(180deg);
}
}
background-color: var(--watt-on-light-low-emphasis);
border-radius: 8px;
Expand All @@ -63,6 +84,8 @@ const selector = 'eo-actor-menu';

.actor-menu-panel {
--mat-menu-container-shape: 0;
--eo-scroll-view-padding: 0;
--eo-scroll-view-max-height: 112px;
width: 257px;
margin-bottom: var(--watt-space-s);
transition: width 0.2s linear;
Expand All @@ -75,6 +98,17 @@ const selector = 'eo-actor-menu';
width: 100%;
}

.menu-header {
padding: 4px 14px;
font-weight: 300;

&.other-organizations {
border-top: 1px solid var(--watt-color-neutral-grey-300);
margin-top: 12px;
padding-top: 14px;
}
}

.actor {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -112,18 +146,39 @@ const selector = 'eo-actor-menu';
{{ translations.actorMenu.tin | transloco: { tin: currentActor()?.tin } }}
</p>
<p class="watt-label">{{ currentActor()?.org_name }}</p>

<watt-icon name="down" size="s" />
</div>
<mat-menu #menu="matMenu" class="actor-menu-panel">
@for (actor of actors(); track $index) {
@if (actor.org_id !== currentActor()?.org_id) {
<button mat-menu-item (click)="selectActor(actor)">
<div class="actor">
<small class="actor__tin">{{ actor.tin }}</small>
<small class="actor__name">{{ actor.org_name }}</small>
</div>
</button>
}
@if (self()?.org_id !== currentActor()?.org_id) {
<p class="menu-header">
{{ translations.actorMenu.ownOrganization | transloco }}
</p>
<button mat-menu-item (click)="selectActor()">
<div class="actor">
<small class="actor__tin">{{ self()?.tin }}</small>
<small class="actor__name">{{ self()?.org_name }}</small>
</div>
</button>
}

@if (self()?.org_id !== currentActor()?.org_id) {
<p class="menu-header other-organizations">
{{ translations.actorMenu.otherOrganizations | transloco }}
</p>
}
<eo-scroll-view>
@for (actor of actors(); track $index) {
@if (actor.org_id !== currentActor()?.org_id && actor.org_id !== self()?.org_id) {
<button mat-menu-item (click)="selectActor(actor)">
<div class="actor">
<small class="actor__tin">{{ actor.tin }}</small>
<small class="actor__name">{{ actor.org_name }}</small>
</div>
</button>
}
}
</eo-scroll-view>
</mat-menu>
}
`,
Expand All @@ -137,10 +192,10 @@ export class EoActorMenuComponent {

protected translations = translations;

selectActor(actor: Actor) {
selectActor(actor?: Actor) {
// Wait to emit the selection until the menu has closed
setTimeout(() => {
this.actorSelected.emit(actor);
this.actorSelected.emit(actor ?? (this.self() as Actor));
}, 150);
}
}
2 changes: 2 additions & 0 deletions libs/eo/core/globalization/assets-localization/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ export const DA_TRANSLATIONS: TranslationKeys = {
actorMenu: {
tin: 'CVR / SE-nr: {{tin}} ',
onBehalfOf: '{{org_name}} på vegne af',
ownOrganization: 'Din organisation:',
otherOrganizations: 'Andre organisationer:',
},
topbar: {
help: '{{shared.help}}',
Expand Down
2 changes: 2 additions & 0 deletions libs/eo/core/globalization/assets-localization/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ export const EN_TRANSLATIONS: TranslationKeys = {
actorMenu: {
tin: 'CVR / TIN: {{tin}}',
onBehalfOf: '{{org_name}} on behalf of',
ownOrganization: 'Your organization:',
otherOrganizations: 'Other organizations:',
},
topbar: {
help: '{{shared.help}}',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ export interface TranslationKeys {
actorMenu: {
onBehalfOf: string;
tin: string;
ownOrganization: string;
otherOrganizations: string;
};
topbar: {
help: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ export const translations = {
actorMenu: {
onBehalfOf: 'actorMenu.onBehalfOf' as const,
tin: 'actorMenu.tin' as const,
ownOrganization: 'actorMenu.ownOrganization' as const,
otherOrganizations: 'actorMenu.otherOrganizations' as const,
} as const,
topbar: {
help: 'topbar.help' as const,
Expand Down
7 changes: 3 additions & 4 deletions libs/eo/core/shell/src/lib/eo-primary-navigation.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,10 @@ import { EoAccountMenuComponent } from './eo-account-menu';
<watt-nav-list-item link="{{ routes.claims }}">
{{ translations.sidebar.claims | transloco }}
</watt-nav-list-item>

<watt-nav-list-item link="{{ routes.certificates }}">
{{ translations.sidebar.certificates | transloco }}
</watt-nav-list-item>
}
<watt-nav-list-item link="{{ routes.certificates }}">
{{ translations.sidebar.certificates | transloco }}
</watt-nav-list-item>
<watt-nav-list-item link="{{ routes.transfer }}">
{{ translations.sidebar.transfers | transloco }}
</watt-nav-list-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,22 @@ const selector = 'eo-scroll-view';
encapsulation: ViewEncapsulation.None,
styles: [
`
:root {
--eo-scroll-view-padding: var(--watt-space-m);
--eo-scroll-view-max-height: calc(100vh - 300px);
}

${selector} {
display: block;
word-break: break-word;

padding: var(--watt-space-m);

padding: var(--eo-scroll-view-padding);
background: var(--watt-color-neutral-white);
border-radius: var(--watt-space-xs);
}

// This is the contents of the privacy policy with the custom scrollbar
${selector} .content {
max-height: calc(100vh - 300px);
max-height: var(--eo-scroll-view-max-height);
word-break: break-word;
overflow-y: scroll;
padding-right: var(--watt-space-m);
Expand Down
20 changes: 20 additions & 0 deletions libs/eo/shared/data-access-mocks/src/lib/authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,26 @@ function getReceivedConsents(apiBase: string) {
organizationName: 'Viggos Vindmøller',
tin: 77777777,
},
{
organizationId: 12345678,
organizationName: 'Startup I/S',
tin: 12345678,
},
{
organizationId: 55555555,
organizationName: 'Fabrikant',
tin: 55555555,
},
{
organizationId: 66666666,
organizationName: 'Bolighaj',
tin: 66666666,
},
{
organizationId: 28980671,
organizationName: 'Energinet',
tin: 28980671,
},
],
};
return HttpResponse.json(data, { status: 200 });
Expand Down