Commit a4e17813 authored by Alicia.DeDiosFuente's avatar Alicia.DeDiosFuente
Browse files

feat: add logo avatar to display this type of column in data table

parent 80c4b178
......@@ -150,6 +150,18 @@ export namespace AdminOrganizationalUnitAction {
export class GetPhotoFail extends ResourceLogoAction.GetPhotoFail {
}
@TypeDefaultAction(state)
export class GetPhotoByResId extends ResourceLogoAction.GetPhotoByResId {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdSuccess extends ResourceLogoAction.GetPhotoByResIdSuccess {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdFail extends ResourceLogoAction.GetPhotoByResIdFail {
}
@TypeDefaultAction(state)
export class UploadPhoto extends ResourceLogoAction.UploadPhoto {
}
......
import {adminUserActionNameSpace} from "@admin/user/stores/admin-user.action";
import {AdminUserStateModel} from "@admin/user/stores/admin-user.state";
import {
AdminUserAction,
adminUserActionNameSpace,
} from "@admin/user/stores/admin-user.action";
import {
AdminUserState,
AdminUserStateModel,
} from "@admin/user/stores/admin-user.state";
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
......@@ -12,6 +18,7 @@ import {AppState} from "@app/stores/app.state";
import {User} from "@models";
import {
Actions,
ofActionCompleted,
Store,
} from "@ngxs/store";
import {SharedAbstractListRoutable} from "@shared/components/routables/shared-abstract-list/shared-abstract-list.routable";
......@@ -19,7 +26,12 @@ import {FieldTypeEnum} from "@shared/enums/field-type.enum";
import {LabelTranslateEnum} from "@shared/enums/label-translate.enum";
import {LocalStateEnum} from "@shared/enums/local-state.enum";
import {RouterExtService} from "@shared/services/router-ext.service";
import {OrderEnum} from "solidify-frontend";
import {
OrderEnum,
MemoizedUtil,
QueryParameters,
} from "solidify-frontend";
import {DataTableComponentEnum} from "@shared/enums/data-table-component.enum";
@Component({
selector: "dlcm-admin-user-list-routable",
......@@ -32,6 +44,8 @@ export class AdminUserListRoutable extends SharedAbstractListRoutable<User, Admi
readonly KEY_BACK_BUTTON: string | undefined = LabelTranslateEnum.backToAdmin;
readonly KEY_PARAM_NAME: keyof User & string = "externalUid";
adminUserState: typeof AdminUserState = AdminUserState;
constructor(protected readonly _store: Store,
protected readonly _changeDetector: ChangeDetectorRef,
protected readonly _route: ActivatedRoute,
......@@ -57,6 +71,17 @@ export class AdminUserListRoutable extends SharedAbstractListRoutable<User, Admi
defineColumns(): void {
this.columns = [
{
field: "avatar",
header: LabelTranslateEnum.avatar,
order: OrderEnum.none,
resourceNameSpace: adminUserActionNameSpace,
resourceState: this.adminUserState as any,
isFilterable: false,
isSortable: false,
component: DataTableComponentEnum.logo,
isUser: true,
},
{
field: "lastName",
header: LabelTranslateEnum.lastName,
......@@ -83,5 +108,4 @@ export class AdminUserListRoutable extends SharedAbstractListRoutable<User, Admi
},
];
}
}
......@@ -150,6 +150,18 @@ export namespace AdminUserAction {
export class GetPhotoFail extends ResourceLogoAction.GetPhotoFail {
}
@TypeDefaultAction(state)
export class GetPhotoByResId extends ResourceLogoAction.GetPhotoByResId {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdSuccess extends ResourceLogoAction.GetPhotoByResIdSuccess {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdFail extends ResourceLogoAction.GetPhotoByResIdFail {
}
@TypeDefaultAction(state)
export class UploadPhoto extends ResourceLogoAction.UploadPhoto {
}
......
......@@ -172,6 +172,18 @@ export namespace DepositAction {
export class UploadPhotoFail extends ResourceLogoAction.UploadPhotoFail {
}
@TypeDefaultAction(state)
export class GetPhotoByResId extends ResourceLogoAction.GetPhotoByResId {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdSuccess extends ResourceLogoAction.GetPhotoByResIdSuccess {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdFail extends ResourceLogoAction.GetPhotoByResIdFail {
}
@TypeDefaultAction(state)
export class DeletePhoto extends ResourceLogoAction.DeletePhoto {
}
......
......@@ -186,7 +186,7 @@ export interface DepositStateModel extends ResourceLogoStateModel<Deposit> {
formPresentational: undefined,
depositModeTabEnum: ModeDepositTabEnum.UNDEFINED,
dataFileLogo: undefined,
isLoadingPhoto: false,
isLoadingLogo: false,
activeListTabStatus: DepositTabStatusEnum.inProgress,
},
children: [
......@@ -1020,7 +1020,7 @@ export class DepositState extends ResourceLogoState<DepositStateModel, Deposit>
@Action(DepositAction.GetPhoto)
getPhoto(ctx: StateContext<DepositStateModel>, action: DepositAction.GetPhoto): Observable<any> {
ctx.patchState({
isLoadingPhoto: true,
isLoadingLogo: true,
});
const depositId = ctx.getState().current.resId;
const datafileId = ctx.getState().dataFileLogo.resId;
......@@ -1089,7 +1089,7 @@ export class DepositState extends ResourceLogoState<DepositStateModel, Deposit>
const depositId = ctx.getState().current.resId;
ctx.patchState({
isLoadingPhoto: true,
isLoadingLogo: true,
});
return ctx.dispatch(new DepositDataFileAction.Delete(depositId, dataFileLogo.resId)).pipe(
......@@ -1107,7 +1107,7 @@ export class DepositState extends ResourceLogoState<DepositStateModel, Deposit>
@Action(DepositAction.DeletePhotoSuccess)
deletePhotoSuccess(ctx: StateContext<DepositStateModel>, action: DepositAction.DeletePhotoSuccess): void {
ctx.patchState({
isLoadingPhoto: false,
isLoadingLogo: false,
dataFileLogo: undefined,
logo: undefined,
});
......
......@@ -150,6 +150,18 @@ export namespace DepositOrganizationalUnitAction {
export class GetPhotoFail extends ResourceLogoAction.GetPhotoFail {
}
@TypeDefaultAction(state)
export class GetPhotoByResId extends ResourceLogoAction.GetPhotoByResId {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdSuccess extends ResourceLogoAction.GetPhotoByResIdSuccess {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdFail extends ResourceLogoAction.GetPhotoByResIdFail {
}
@TypeDefaultAction(state)
export class UploadPhoto extends ResourceLogoAction.UploadPhoto {
}
......
......@@ -150,6 +150,18 @@ export namespace PreservationSpaceOrganizationalUnitAction {
export class GetPhotoFail extends ResourceLogoAction.GetPhotoFail {
}
@TypeDefaultAction(state)
export class GetPhotoByResId extends ResourceLogoAction.GetPhotoByResId {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdSuccess extends ResourceLogoAction.GetPhotoByResIdSuccess {
}
@TypeDefaultAction(state)
export class GetPhotoByResIdFail extends ResourceLogoAction.GetPhotoByResIdFail {
}
@TypeDefaultAction(state)
export class UploadPhoto extends ResourceLogoAction.UploadPhoto {
}
......
......@@ -67,7 +67,7 @@ export abstract class SharedAbstractImageUploadWrapperContainer extends SharedAb
ngOnInit(): void {
super.ngOnInit();
this.isLoadingObs = MemoizedUtil.select(this._store, this.resourceLogoState, state => state["isLoadingPhoto"]);
this.isLoadingObs = MemoizedUtil.select(this._store, this.resourceLogoState, (state: ResourceLogoStateModel<any>) => state.isLoadingLogo);
this.photoObs = MemoizedUtil.select(this._store, this.resourceLogoState, (state: ResourceLogoStateModel<any>) => state.logo);
this._sharedUploadImageDialogData = this._defineSharedImageDialogData();
}
......
<div [dlcmSpinner]="isLoading"
[dlcmSpinnerStrokeWidth]="2"
[dlcmSpinnerDiameter]="24">
<div *ngIf="(this.photo | isNotNullNorUndefined) && (this.photo | isNonEmptyString); else noPhoto"
>
<img *ngIf="sanitizeUrl(this.photo) as image"
[src]="image"
alt="photo"
class="photo"
>
</div>
<ng-template #noPhoto>
<dlcm-shared-avatar *ngIf="this.isUser"
class="avatar-initial"
[user]="this.user"
></dlcm-shared-avatar>
</ng-template>
</div>
@import "../../../../../sass/abstracts/variables";
@import "../../../../../sass/abstracts/mixins";
$avatar-size: 45px;
:host {
background-color: transparent;
background-size: cover;
color: $white;
height: $avatar-size;
width: $avatar-size;
border-radius: 50%;
flex-shrink: 0;
object-fit: cover;
text-transform: uppercase;
display: flex;
justify-content: center;
align-items: center;
font-size: 17px;
font-weight: bold;
cursor: pointer;
.photo {
display: flex;
border-radius: 100%;
width: 100%;
height: 100%;
}
}
import {
Actions,
Store,
} from "@ngxs/store";
import {SharedAbstractContainer} from "@shared/components/containers/shared-abstract/shared-abstract.container";
import {
Component,
ChangeDetectionStrategy,
Input,
OnChanges,
ChangeDetectorRef,
} from "@angular/core";
import {
isFalse,
isNotNullNorUndefined,
isNullOrUndefined,
MemoizedUtil,
ResourceState,
ResourceStateModel,
Type,
MappingObjectUtil,
isEmptyString,
} from "solidify-frontend";
import {ResourceLogoNameSpace} from "@shared/stores/resource-logo/resource-logo-namespace.model";
import {
distinctUntilChanged,
filter,
takeWhile,
tap,
} from "rxjs/operators";
import {ResourceLogoStateModel} from "@shared/stores/resource-logo/resource-logo-state.model";
import {
Observable,
} from "rxjs/index";
import {
DomSanitizer,
SafeResourceUrl,
} from "@angular/platform-browser";
import {MappingObject} from "solidify-frontend/lib/models";
import {User} from "@models";
@Component({
selector: "dlcm-shared-logo-wrapper-container",
templateUrl: "./shared-logo-wrapper.container.html",
styleUrls: ["./shared-logo-wrapper.container.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SharedLogoWrapperContainer extends SharedAbstractContainer implements OnChanges {
_idResource: string;
isLoading: boolean = true;
@Input()
logoNamespace: ResourceLogoNameSpace;
@Input()
logoState: any;
@Input()
isUser: boolean = false;
@Input()
user: User;
@Input()
set id(id: string) {
this._idResource = id;
}
get id(): string {
return this._idResource;
}
listPhotosObs: Observable<MappingObject<string>>;
photo: string;
constructor(protected readonly _store: Store,
protected readonly _actions$: Actions,
private readonly _changeDetector: ChangeDetectorRef,
protected readonly _sanitizer: DomSanitizer) {
super();
}
ngOnChanges(): void {
if (isNotNullNorUndefined(this._idResource) && isNotNullNorUndefined(this.logoNamespace)) {
this.listPhotosObs = MemoizedUtil.select(this._store, this.logoState, (state: ResourceLogoStateModel<any>) => state.listLogo);
this.getLogo();
}
}
protected getLogo(): void {
this._store.dispatch(new this.logoNamespace.GetPhotoByResId(this._idResource));
const listPhotos = this._store.selectSnapshot((state: ResourceLogoStateModel<any>) => state.listLogo);
const photo = this.getPhoto(listPhotos);
if (isNullOrUndefined(photo)) {
this.subscribe(this.listPhotosObs.pipe(
distinctUntilChanged(),
filter(list => isNotNullNorUndefined(this.getPhoto(list))),
takeWhile((list) => this.isLoading === true),
tap((list) => {
this.photo = MappingObjectUtil.get(MemoizedUtil.selectSnapshot(this._store, this.logoState,(state: ResourceLogoStateModel<any>) => state.listLogo), this._idResource);
if (isNotNullNorUndefined(this.photo)) {
this.isLoading = false;
this._changeDetector.detectChanges();
}
})));
}
}
protected sanitizeUrl(url: string | undefined): undefined | SafeResourceUrl {
if (isNullOrUndefined(url)) {
return undefined;
} else {
return this._sanitizer.bypassSecurityTrustResourceUrl(url);
}
}
protected getPhoto(list: MappingObject <string>): string | undefined {
if (isNullOrUndefined(list)) {
return undefined;
}
const photo: string = MappingObjectUtil.get(list, this._idResource);
if (isNullOrUndefined(photo)) {
return undefined;
}
return photo;
}
}
......@@ -472,6 +472,16 @@
[statusModel]="enumUtil.getKeyValue(col.filterEnum, getData(rowData, col))"
[label]="undefined"
></dlcm-shared-status>
<ng-template [ngSwitchCase]="dataTableComponentEnum.logo">
<dlcm-shared-logo-wrapper-container [id]="getResId(rowData)"
[isUser]="col.isUser"
[user]="rowData"
[logoNamespace]="col.resourceNameSpace"
[logoState]="col.resourceState"
></dlcm-shared-logo-wrapper-container>
</ng-template>
</ng-container>
</ng-template>
......
......@@ -399,6 +399,10 @@ export class SharedDataTablePresentational<TResource extends BaseResource> exten
return row[field];
}
getResId(row: TResource): string {
return (row as TResource).resId;
}
private applyTypeToData(data: any, type: FieldTypeEnum): any {
if (isNullOrUndefined(data)) {
return StringUtil.stringEmpty;
......
......@@ -10,4 +10,5 @@ export enum DataTableComponentEnum {
adminResearchDomainLabel,
accessLevel,
status,
logo,
}
......@@ -6,5 +6,5 @@ export enum FieldTypeEnum {
searchableSingleSelect,
singleSelect,
size,
boolean
boolean,
}
......@@ -356,6 +356,7 @@ export class LabelTranslateEnum {
static members: string = MARK_AS_TRANSLATABLE("general.label.members");
static guidedTour: string = MARK_AS_TRANSLATABLE("general.label.guidedTour");
static lastSelection: string = MARK_AS_TRANSLATABLE("general.label.lastSelection");
static avatar: string = MARK_AS_TRANSLATABLE("general.label.avatar");
static hide: string = MARK_AS_TRANSLATABLE("general.link.hide");
static show: string = MARK_AS_TRANSLATABLE("general.link.show");
......
......@@ -35,4 +35,5 @@ export interface DataTableColumns<TResource extends BaseResourceType = any> {
minWidth?: string | undefined;
maxWidth?: string | undefined;
extraSearchQueryParam?: MappingObject | undefined;
isUser?: boolean;
}
......@@ -157,6 +157,7 @@ import {TourMatMenuModule} from "ngx-tour-md-menu";
import {SolidifyFrontendModule} from "solidify-frontend";
import {SharedBreadcrumbPresentational} from "./components/presentationals/shared-breadcrumb/shared-breadcrumb.presentational";
import {SharedPaginatorPresentational} from "./components/presentationals/shared-paginator/shared-paginator.presentational";
import {SharedLogoWrapperContainer} from "@shared/components/containers/shared-logo-wrapper/shared-logo-wrapper.container";
const routables = [
SharedFileAndAipInformationContainer,
......@@ -170,6 +171,7 @@ const containers = [
SharedImageUploadWrapperContainer,
SharedTablePersonOrgunitRoleContainer,
SharedAdditionalInformationPanelContainer,
SharedLogoWrapperContainer,
];
const dialogs = [
SharedBaseActionDialog,
......
......@@ -15,6 +15,18 @@ export class ResourceLogoActionHelper extends ResourceActionHelper {
return new resourceLogoNameSpace.GetPhotoFail(...args);
}
static getPhotoByResId(resourceLogoNameSpace: ResourceLogoNameSpace, ...args: ConstructorParameters<typeof ResourceLogoAction.GetPhotoByResId>): ResourceLogoAction.GetPhotoByResId {
return new resourceLogoNameSpace.GetPhotoByResId(...args);
}
static getPhotoByResIdSuccess(resourceLogoNameSpace: ResourceLogoNameSpace, ...args: ConstructorParameters<typeof ResourceLogoAction.GetPhotoByResIdSuccess>): ResourceLogoAction.GetPhotoByResIdSuccess {
return new resourceLogoNameSpace.GetPhotoByResIdSuccess(...args);
}
static getPhotoByResIdFail(resourceLogoNameSpace: ResourceLogoNameSpace, ...args: ConstructorParameters<typeof ResourceLogoAction.GetPhotoByResIdFail>): ResourceLogoAction.GetPhotoByResIdFail {
return new resourceLogoNameSpace.GetPhotoByResIdFail(...args);
}
static deletePhoto(resourceLogoNameSpace: ResourceLogoNameSpace, ...args: ConstructorParameters<typeof ResourceLogoAction.DeletePhoto>): ResourceLogoAction.DeletePhoto {
return new resourceLogoNameSpace.DeletePhoto(...args);
}
......
......@@ -13,4 +13,7 @@ export interface ResourceLogoNameSpace extends ResourceNameSpace {
GetPhoto: StoreActionClass;
GetPhotoSuccess: StoreActionClass;
GetPhotoFail: StoreActionClass;
GetPhotoByResId: StoreActionClass;
GetPhotoByResIdSuccess: StoreActionClass;
GetPhotoByResIdFail: StoreActionClass;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment