Refactor/user avatar to principal (#9069)
* Fix some ium stylings * Extend create service to also test with empty names * Add PrincipalLike type to pass around non-created placeholder refs * Add icon-context * Move principal rendering to its own module * Fix emit create new placeholder to principals * Revert op-principal for now * Add memberships form API to properly post * Fix types for returned principals * Move untilDestroyed in role * Filter input if not string in role-search * Pass correct inputs to success component * Return principal after saving membership * Fix small stuff around the ium * Fix the way HalResources are selected and passed * Move principal module to be exported by common * Disable quotemark in tslint until eslint is enabled * Fix image path in success * Adapt modal to run all steps in one within the modal helper component * Several fixes to modals * Fix ium success component styles, * Registration modal y-overflow * Add SMTP parameters to .env.example * Add disabled option to op-option-list, disabled placeholder users for non-ee instances * Add correct ee link to placeholder user option * Fix build * Removed unused sass files * Fix principal search not found indicator, added placeholder add image * Fix enterprise edition url, use dirty instead of touched check * Use backend class names for frontend principal types * Fix duplicate import and principal type usage * Also disable banners if with_ee is present in test * Extend specs for placeholders * Fix disabled attribute * Extend spec WIP * Improved inline-validation styles, fixed more PrincipalType usages * Add group happy path test, fix more PrincipalType usage * Fix a translation * Revert line deletion * Rewrite same spec examples into shared examples * Fix name of shared example * Dont run assets:clean to remove angular assets * Output whether assets are there at all * Update user-avatar usages to principal * Fix some op-principal usages * Fix principal typing * Remove ls of non-existent directory * Rename more user-avatar instances * Avatars now render correctly * Fix an op-principal instance, default to avatar class for avatars * Always add principal id to default principal tag * Small fixes to op-principal * Fix multiline user display * Dirty fix for capybara click events * Update avatar sizing * Fixed some specs * Fix unit specs * Added op-link styles * Fix add placeholder image link * Remove byebug debugger statements Co-authored-by: Oliver Günther <mail@oliverguenther.de>pull/9099/head
parent
b609964818
commit
beb4e6ba50
@ -1,94 +0,0 @@ |
||||
import { Injectable } from "@angular/core"; |
||||
import { PathHelperService } from "core-app/modules/common/path-helper/path-helper.service"; |
||||
import { ColorsService } from "core-app/modules/common/colors/colors.service"; |
||||
import { APIV3Service } from "core-app/modules/apiv3/api-v3.service"; |
||||
|
||||
export interface UserLike { |
||||
name:string; |
||||
id:string|number|null; |
||||
} |
||||
|
||||
@Injectable({ providedIn: 'root' }) |
||||
export class UserAvatarRendererService { |
||||
|
||||
constructor(private pathHelper:PathHelperService, |
||||
private apiV3Service:APIV3Service, |
||||
private colors:ColorsService) { |
||||
|
||||
} |
||||
|
||||
renderMultiple(container:HTMLElement, |
||||
users:UserLike[], |
||||
renderName = true, |
||||
multiLine = false) { |
||||
|
||||
const span = document.createElement('span'); |
||||
|
||||
|
||||
for (let i = 0; i < users.length; i++) { |
||||
const avatar = document.createElement('span'); |
||||
if (multiLine) { |
||||
avatar.classList.add('user-avatar--multi-line'); |
||||
} |
||||
|
||||
this.render(avatar, users[i], renderName); |
||||
|
||||
if (!multiLine && i < users.length - 1) { |
||||
const sep = document.createElement('span'); |
||||
sep.textContent = ', '; |
||||
avatar.appendChild(sep); |
||||
} |
||||
|
||||
span.appendChild(avatar); |
||||
} |
||||
|
||||
container.appendChild(span); |
||||
} |
||||
|
||||
render(container:HTMLElement, |
||||
user:UserLike, |
||||
renderName = true, |
||||
classes = 'avatar-medium'):void { |
||||
const userInitials = this.getInitials(user.name); |
||||
const colorCode = this.colors.toHsl(user.name); |
||||
|
||||
let fallback = document.createElement('div'); |
||||
fallback.className = classes; |
||||
fallback.classList.add('avatar-default'); |
||||
fallback.textContent = userInitials; |
||||
fallback.style.background = colorCode; |
||||
|
||||
container.appendChild(fallback); |
||||
|
||||
if (renderName) { |
||||
const name = document.createElement('span'); |
||||
name.textContent = user.name; |
||||
container.appendChild(name); |
||||
} |
||||
|
||||
// Avoid using the image when ID is null
|
||||
if (!user.id) { |
||||
return; |
||||
} |
||||
|
||||
const image = new Image(); |
||||
image.className = classes; |
||||
image.classList.add('avatar--fallback'); |
||||
image.src = this.apiV3Service.users.id(user.id).avatar.toString(); |
||||
image.title = user.name; |
||||
image.alt = user.name; |
||||
image.onload = function () { |
||||
fallback.replaceWith(image); |
||||
(fallback as any) = undefined; |
||||
}; |
||||
} |
||||
|
||||
private getInitials(name:string) { |
||||
const characters = [...name]; |
||||
const lastSpace = name.lastIndexOf(' '); |
||||
const first = characters[0]?.toUpperCase(); |
||||
const last = name[lastSpace + 1]?.toUpperCase(); |
||||
|
||||
return [first, last].join(""); |
||||
} |
||||
} |
@ -1,56 +0,0 @@ |
||||
//-- copyright
|
||||
// OpenProject is an open source project management software.
|
||||
// Copyright (C) 2012-2021 the OpenProject GmbH
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version 3.
|
||||
//
|
||||
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// See docs/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
import { UserResource } from 'core-app/modules/hal/resources/user-resource'; |
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input } from "@angular/core"; |
||||
import { PathHelperService } from "core-app/modules/common/path-helper/path-helper.service"; |
||||
import { UserAvatarRendererService } from "core-components/user/user-avatar/user-avatar-renderer.service"; |
||||
|
||||
export const userAvatarSelector = 'user-avatar'; |
||||
|
||||
@Component({ |
||||
selector: userAvatarSelector, |
||||
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
template: '' |
||||
}) |
||||
export class UserAvatarComponent implements AfterViewInit { |
||||
/** If coming from angular, pass a user resource if available */ |
||||
@Input() public user?:UserResource; |
||||
|
||||
constructor(protected elementRef:ElementRef, |
||||
protected avatarRenderer:UserAvatarRendererService, |
||||
protected pathHelper:PathHelperService) { |
||||
} |
||||
|
||||
public ngAfterViewInit() { |
||||
const element = this.elementRef.nativeElement; |
||||
const user = this.user || { name: element.dataset.userName!, id: element.dataset.userId }; |
||||
this.avatarRenderer.render(element, user, false, element.dataset.classList); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,16 @@ |
||||
.op-link |
||||
color: var(--content-link-color) |
||||
text-decoration: none |
||||
background: 0 |
||||
border: 0 |
||||
font: inherit |
||||
cursor: pointer |
||||
|
||||
&:hover, |
||||
&:active |
||||
color: var(--content-link-hover-active-color) |
||||
text-decoration: underline |
||||
|
||||
&:focus |
||||
color: var(--content-link-hover-active-color) |
||||
|
@ -1,4 +1,5 @@ |
||||
@import './input/input' |
||||
@import './link/link' |
||||
@import './form-field/form-field' |
||||
@import './option-list/option-list' |
||||
@import './export-options/export-options' |
||||
|
@ -1,3 +0,0 @@ |
||||
import {HalResource} from "core-app/modules/hal/resources/hal-resource"; |
||||
|
||||
export type PrincipalLike = HalResource|{ name: string}; |
@ -0,0 +1,5 @@ |
||||
import {UserResource} from "core-app/modules/hal/resources/user-resource"; |
||||
import {PlaceholderUserResource} from "core-app/modules/hal/resources/placeholder-user-resource"; |
||||
import {GroupResource} from "core-app/modules/hal/resources/group-resource"; |
||||
|
||||
export type PrincipalLike = UserResource|PlaceholderUserResource|GroupResource|{ id?:string, name:string, href?:string }; |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Loading…
Reference in new issue