more frontend changes

This commit is contained in:
Diamantis Tziotzios 2023-11-24 18:42:23 +02:00
parent 8a20687491
commit 396c6e5b95
113 changed files with 5752 additions and 560 deletions

View File

@ -27,20 +27,18 @@ public class FieldSetPersist {
@NotEmpty(message = "{validation.empty}")
private String description = null;
@NotNull(message = "{validation.empty}")
@NotEmpty(message = "{validation.empty}")
// @NotNull(message = "{validation.empty}")
// @NotEmpty(message = "{validation.empty}")
private String extendedDescription = null;
@NotNull(message = "{validation.empty}")
@NotEmpty(message = "{validation.empty}")
// @NotNull(message = "{validation.empty}")
// @NotEmpty(message = "{validation.empty}")
private String additionalInformation = null;
@NotNull(message = "{validation.empty}")
@Valid
private MultiplicityPersist multiplicity= null;
@NotNull(message = "{validation.empty}")
private Boolean hasCommentField = null;
@NotNull(message = "{validation.empty}")

View File

@ -5,17 +5,12 @@ import jakarta.validation.constraints.NotNull;
public class MultiplicityPersist {
@NotNull(message = "{validation.empty}")
private Integer min = null;
@NotNull(message = "{validation.empty}")
private Integer max = null;
@NotNull(message = "{validation.empty}")
@NotEmpty(message = "{validation.empty}")
private String placeholder = null;
@NotNull(message = "{validation.empty}")
private Boolean tableView = null;
public Integer getMin() {

View File

@ -348,10 +348,10 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic
MultiplicityEntity data = new MultiplicityEntity();
if (persist == null) return data;
data.setMax(persist.getMax());
data.setMin(persist.getMin());
data.setPlaceholder(persist.getPlaceholder());
data.setTableView(persist.getTableView());
if (persist.getMax() != null) data.setMax(persist.getMax());
if (persist.getMin() != null) data.setMin(persist.getMin());
if (persist.getPlaceholder() != null) data.setPlaceholder(persist.getPlaceholder());
if (persist.getTableView() != null) data.setTableView(persist.getTableView());
return data;
}

View File

@ -0,0 +1,3 @@
export enum ContactInfoType {
Email = 0
}

View File

@ -1,10 +1,10 @@
export enum DescriptionTemplateFieldType {
COMBO_BOX = "combobox",
COMBO_BOX = "combobox", //Delete
AUTO_COMPLETE = "autocomplete",
WORD_LIST = "wordlist",
BOOLEAN_DECISION = "booleanDecision",
RADIO_BOX = "radiobox",
INTERNAL_DMP_ENTRIES = "internalDmpEntities",
INTERNAL_DMP_ENTRIES = "internalDmpEntities", //Delete
INTERNAL_DMP_ENTRIES_RESEARCHERS = "internalDmpResearchers",
INTERNAL_DMP_ENTRIES_DMPS = "internalDmpDmps",
INTERNAL_DMP_ENTRIES_DATASETS = "internalDmpDatasets",

View File

@ -0,0 +1,4 @@
export enum UserDescriptionTemplateRole {
Owner = 0,
Member = 1
}

View File

@ -43,23 +43,24 @@ import { QuickWizardService } from './services/quick-wizard/quick-wizard.service
import { SearchBarService } from './services/search-bar/search-bar.service';
import { TimezoneService } from './services/timezone/timezone-service';
import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service';
import { UserService } from './services/user/user.service';
import { UserServiceOld } from './services/user/user.service-old';
import { CollectionUtils } from './services/utilities/collection-utils.service';
import { TypeUtils } from './services/utilities/type-utils.service';
import { SpecialAuthGuard } from './special-auth-guard.service';
//import { KeycloakService } from 'keycloak-angular';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
import { FilterService } from '@common/modules/text-filter/filter-service';
import { DescriptionTemplateService } from './services/description-template/description-template.service';
import { PrincipalService } from './services/http/principal.service';
import { ReferenceTypeService } from './services/reference-type/reference-type.service';
import { ReferenceService } from './services/reference/reference.service';
import { SupportiveMaterialService } from './services/supportive-material/supportive-material.service';
import { TenantService } from './services/tenant/tenant.service';
import { UserSettingsHttpService } from './services/user-settings/user-settings-http.service';
import { UserSettingsService } from './services/user-settings/user-settings.service';
import { UserService } from './services/user/user.service';
import { FileUtils } from './services/utilities/file-utils.service';
import { QueryParamsService } from './services/utilities/query-params.service';
import { DescriptionTemplateService } from './services/description-template/description-template.service';
import { ReferenceTypeService } from './services/reference-type/reference-type.service';
import { TenantService } from './services/tenant/tenant.service';
//
//
// This is shared module that provides all the services. Its imported only once on the AppModule.
@ -112,7 +113,7 @@ export class CoreServiceModule {
ExternalResearcherService,
ExternalServiceService,
DatasetProfileService,
UserService,
UserServiceOld,
DmpInvitationService,
DatasetExternalAutocompleteService,
QuickWizardService,
@ -138,7 +139,8 @@ export class CoreServiceModule {
ReferenceService,
DescriptionTemplateService,
ReferenceTypeService,
TenantService
TenantService,
UserService
],
};
}

View File

@ -3,6 +3,7 @@ import { DescriptionTemplateFieldDataExternalDatasetType } from "@app/core/commo
import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type";
import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type";
import { DescriptionTemplateStatus } from "@app/core/common/enum/description-template-status";
import { UserDescriptionTemplateRole } from "@app/core/common/enum/user-description-template-role";
import { BaseEntityPersist } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
@ -14,6 +15,12 @@ export interface DescriptionTemplatePersist extends BaseEntityPersist {
type: Guid;
status: DescriptionTemplateStatus;
definition: DescriptionTemplateDefinitionPersist;
users: UserDescriptionTemplatePersist[];
}
export interface UserDescriptionTemplatePersist {
userId?: Guid;
role?: UserDescriptionTemplateRole;
}
export interface DescriptionTemplateDefinitionPersist {
@ -93,12 +100,10 @@ export interface DescriptionTemplateAutoCompleteDataPersist extends DescriptionT
export interface DescriptionTemplateBooleanDecisionDataPersist extends DescriptionTemplateBaseFieldDataPersist {
}
export interface DescriptionTemplateDatasetAutoCompleteDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateDatasetAutoCompleteDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateDmpAutoCompleteDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateDmpAutoCompleteDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateCheckBoxDataPersist extends DescriptionTemplateBaseFieldDataPersist {
@ -115,46 +120,41 @@ export interface DescriptionTemplateExternalDatasetDataPersist extends Descripti
export interface DescriptionTemplateFreeTextDataPersist extends DescriptionTemplateBaseFieldDataPersist {
}
export interface DescriptionTemplateLicenseDataPersist extends DescriptionTemplateBaseFieldDataPersist {
export interface DescriptionTemplatePlaceholderAndMultiplicityDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
}
export interface DescriptionTemplateOrganizationDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateLicenseDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplatePublicationDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateOrganizationDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplatePublicationDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateRadioBoxDataPersist extends DescriptionTemplateBaseFieldDataPersist {
options: DescriptionTemplateRadioBoxOptionPersist;
options: DescriptionTemplateRadioBoxOptionPersist[];
}
export interface DescriptionTemplateRegistryDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateRegistryDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateResearcherAutoCompleteDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateResearcherAutoCompleteDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateResearcherDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateResearcherDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateRichTextAreaDataPersist extends DescriptionTemplateBaseFieldDataPersist {
}
export interface DescriptionTemplateServiceDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateServiceDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateTagDataPersist extends DescriptionTemplateBaseFieldDataPersist {
}
export interface DescriptionTemplateTaxonomyDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateTaxonomyDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateTextAreaDataPersist extends DescriptionTemplateBaseFieldDataPersist {
@ -178,16 +178,13 @@ export interface DescriptionTemplateWordListDataPersist extends DescriptionTempl
multiList: boolean;
}
export interface DescriptionTemplateDataRepositoryDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateDataRepositoryDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplateJournalRepositoryDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplateJournalRepositoryDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
export interface DescriptionTemplatePublicationRepositoryDataPersist extends DescriptionTemplateBaseFieldDataPersist {
multiAutoComplete: boolean;
export interface DescriptionTemplatePublicationRepositoryDataPersist extends DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
}
//

View File

@ -1,12 +1,12 @@
import { DescriptionTemplateFieldDataComboBoxType } from "@app/core/common/enum/description-template-field-data-combobox-type";
import { DescriptionTemplateFieldDataExternalDatasetType } from "@app/core/common/enum/description-template-field-data-external-dataset-type";
import { DescriptionTemplateFieldDataInternalDmpEntryType } from "@app/core/common/enum/description-template-field-data-internal-dmp-entry-type";
import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type";
import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type";
import { DescriptionTemplateStatus } from "@app/core/common/enum/description-template-status";
import { UserDescriptionTemplateRole } from "@app/core/common/enum/user-description-template-role";
import { BaseEntity } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
import { DescriptionTemplateType } from "../description-template-type/description-template-type";
import { User } from "../user/user";
export interface DescriptionTemplate extends BaseEntity {
@ -18,6 +18,13 @@ export interface DescriptionTemplate extends BaseEntity {
type: DescriptionTemplateType;
status: DescriptionTemplateStatus;
definition: DescriptionTemplateDefinition;
users: UserDescriptionTemplate[];
}
export interface UserDescriptionTemplate extends BaseEntity {
descriptionTemplate?: DescriptionTemplate;
role?: UserDescriptionTemplateRole;
user?: User;
}
export interface DescriptionTemplateDefinition {
@ -63,13 +70,13 @@ export interface DescriptionTemplateFieldSet {
export interface DescriptionTemplateField {
id: Guid;
ordinal: number;
numbering: string;
schematics: string[];
defaultValue: string;
visibilityRules: DescriptionTemplateRule[];
validations: DescriptionTemplateFieldValidationType[];
numbering?: string;
schematics?: string[];
defaultValue?: string;
visibilityRules?: DescriptionTemplateRule[];
validations?: DescriptionTemplateFieldValidationType[];
includeInExport: boolean;
data: DescriptionTemplateBaseFieldData;
data?: DescriptionTemplateBaseFieldData;
}
export interface DescriptionTemplateRule {
@ -86,13 +93,14 @@ export interface DescriptionTemplateMultiplicity {
export interface DescriptionTemplateBaseFieldData {
label: string;
fieldType: DescriptionTemplateFieldType;
}
//
// Field Types
//
export interface DescriptionTemplateAutoCompleteData extends DescriptionTemplateComboBoxData {
export interface DescriptionTemplateAutoCompleteData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
autoCompleteSingleDataList: DescriptionTemplateAutoCompleteSingleData[];
}
@ -103,19 +111,13 @@ export interface DescriptionTemplateBooleanDecisionData extends DescriptionTempl
export interface DescriptionTemplateCheckBoxData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateComboBoxData extends DescriptionTemplateBaseFieldData {
type: DescriptionTemplateFieldDataComboBoxType;
}
export interface DescriptionTemplateCurrencyData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateDataRepositoryData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateDataRepositoryData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateDatasetAutoCompleteData extends DescriptionTemplateInternalDmpBaseData {
multiAutoComplete: boolean;
export interface DescriptionTemplateDatasetAutoCompleteData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateDatasetIdentifierData extends DescriptionTemplateBaseFieldData {
@ -124,75 +126,67 @@ export interface DescriptionTemplateDatasetIdentifierData extends DescriptionTem
export interface DescriptionTemplateDatePickerData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateDmpAutoCompleteData extends DescriptionTemplateInternalDmpBaseData {
multiAutoComplete: boolean;
export interface DescriptionTemplateDmpAutoCompleteData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateExternalDatasetData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
type: DescriptionTemplateFieldDataExternalDatasetType;
type?: DescriptionTemplateFieldDataExternalDatasetType;
}
export interface DescriptionTemplateFreeTextData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateInternalDmpBaseData extends DescriptionTemplateBaseFieldData {
type: DescriptionTemplateFieldDataInternalDmpEntryType;
}
export interface DescriptionTemplateLicenseData extends DescriptionTemplateBaseFieldData {
export interface DescriptionTemplatePlaceholderAndMultiplicityData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
}
export interface DescriptionTemplateOrganizationData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateLicenseData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplatePublicationData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateOrganizationData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplatePublicationData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateRadioBoxData extends DescriptionTemplateBaseFieldData {
options: DescriptionTemplateRadioBoxOption;
options: DescriptionTemplateRadioBoxOption[];
}
export interface DescriptionTemplateRegistryData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateRegistryData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateResearcherAutoCompleteData extends DescriptionTemplateInternalDmpBaseData {
multiAutoComplete: boolean;
export interface DescriptionTemplateResearcherAutoCompleteData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateResearcherData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateResearcherData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateRichTextAreaData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateServiceData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateServiceData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateTagData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateTaxonomyData extends DescriptionTemplateBaseFieldData {
multiAutoComplete: boolean;
export interface DescriptionTemplateTaxonomyData extends DescriptionTemplatePlaceholderAndMultiplicityData {
}
export interface DescriptionTemplateTextAreaData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateTextAreaData extends DescriptionTemplateBaseFieldData {
export interface DescriptionTemplateUploadData extends DescriptionTemplateBaseFieldData {
types: DescriptionTemplateUploadOption[];
maxFileSizeInMB: number;
}
export interface DescriptionTemplateValidationData extends DescriptionTemplateBaseFieldData {
}
export interface DescriptionTemplateWordListData extends DescriptionTemplateComboBoxData {
export interface DescriptionTemplateWordListData extends DescriptionTemplateBaseFieldData {
options: DescriptionTemplateComboBoxOption[];
multiList: boolean;
}

View File

@ -1,8 +1,72 @@
import { ContactInfoType } from "@app/core/common/enum/contact-info-type";
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
import { AppRole } from "../../common/enum/app-role";
import { Reference } from "../reference/reference";
export interface UserModel {
export interface UserModel { //TODO: Delete after refactor, since its old model.
id: String;
name: String;
appRoles: AppRole[];
email: String;
}
export interface User extends BaseEntity {
name: string;
additionalInfo: UserAdditionalInfo;
contacts: UserContactInfo[];
roles: UserRole[];
credentials: UserCredential[];
}
export interface UserPersist extends BaseEntityPersist {
name: String;
additionalInfo: UserAdditionalInfoPersist;
}
export interface UserAdditionalInfoPersist {
avatarUrl: String;
timezone: String;
culture: String;
language: String;
roleOrganization: String;
organizationId: Guid;
}
export interface UserAdditionalInfo {
avatarUrl: String;
timezone: String;
culture: String;
language: String;
roleOrganization: String;
organization: Reference;
}
export interface UserContactInfo {
id: Guid;
value: String;
type: ContactInfoType;
ordinal: number;
user: User;
createdAt: Date;
}
export interface UserRole {
id: Guid;
role: String;
user: User;
createdAt: Date;
}
export interface UserRolePatchPersist {
id: Guid;
roles: String[];
hash: string;
}
export interface UserCredential {
id: Guid;
externalId: String;
user: User;
createdAt: Date;
}

View File

@ -0,0 +1,23 @@
import { Lookup } from '@common/model/lookup';
import { Guid } from '@common/types/guid';
import { IsActive } from '../common/enum/is-active.enum';
export class UserLookup extends Lookup implements UserFilter {
ids: Guid[];
excludedIds: Guid[];
like: string;
emails: string[];
isActive: IsActive[];
constructor() {
super();
}
}
export interface UserFilter {
ids: Guid[];
excludedIds: Guid[];
like: string;
emails: string[];
isActive: IsActive[];
}

View File

@ -44,17 +44,17 @@ export class LoggingService {
switch (level) {
case LogLevel.Debug:
// tslint:disable-next-line:no-console
// console.debug(objects.join(', '));
console.debug(objects.join(', '));
break;
case LogLevel.Info:
// tslint:disable-next-line:no-console
// console.info(objects.join(', '));
console.info(objects.join(', '));
break;
case LogLevel.Warning:
// console.warn(objects.join(', '));
console.warn(objects.join(', '));
break;
case LogLevel.Error:
// console.error(objects.join(', '));
console.error(objects.join(', '));
break;
}
});

View File

@ -0,0 +1,64 @@
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { DataTableData } from '../../model/data-table/data-table-data';
import { DataTableRequest } from '../../model/data-table/data-table-request';
import { UserListingModel } from '../../model/user/user-listing';
import { UserCriteria } from '../../query/user/user-criteria';
import { BaseHttpService } from '../http/base-http.service';
import { ConfigurationService } from '../configuration/configuration.service';
import { UserCredentialModel } from '@app/core/model/user/user-credential';
@Injectable()
export class UserServiceOld {
private actionUrl: string;
private headers = new HttpHeaders();
constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) {
this.actionUrl = configurationService.server + 'user/';
}
getPaged(dataTableRequest: DataTableRequest<UserCriteria>): Observable<DataTableData<UserListingModel>> {
return this.http.post<DataTableData<UserListingModel>>(this.actionUrl + 'getPaged', JSON.stringify(dataTableRequest), { headers: this.headers });
}
getUser(id: String): Observable<UserListingModel> {
return this.http.get<UserListingModel>(this.actionUrl + id, { headers: this.headers });
}
getEmails(id: String): Observable<UserCredentialModel[]> {
return this.http.get<UserCredentialModel[]>(`${this.actionUrl}${id}/emails`, { headers: this.headers });
}
updateRoles(itemToUpdate: UserListingModel): Observable<UserListingModel> {
return this.http.post<UserListingModel>(this.actionUrl + 'updateRoles', JSON.stringify(itemToUpdate), { headers: this.headers });
}
delete(id: String): Observable<any> {
return this.http.delete<any>(this.actionUrl + id, { headers: this.headers });
}
getRecentActivity(): Observable<any[]> {
return this.http.get<any[]>(this.actionUrl + 'recentActivity', { headers: this.headers });
}
updateUserSettings(value: any): Observable<any[]> {
return this.http.post<any[]>(this.actionUrl + 'settings', value, { headers: this.headers });
}
getCollaboratorsPaged(dataTableRequest: DataTableRequest<UserCriteria>): Observable<DataTableData<UserListingModel>> {
return this.http.post<DataTableData<UserListingModel>>(this.actionUrl + 'getCollaboratorsPaged', JSON.stringify(dataTableRequest), { headers: this.headers });
}
getFromEmail(email: string): Observable<UserListingModel> {
return this.http.post<UserListingModel>(this.actionUrl + 'find', email, {headers: this.headers});
}
downloadCSV(): Observable<HttpResponse<Blob>> {
let headerCsv: HttpHeaders = this.headers.set('Content-Type', 'application/csv')
return this.httpClient.get(this.actionUrl + 'getCsv/', { responseType: 'blob', observe: 'response', headers: headerCsv });
}
}

View File

@ -1,64 +1,137 @@
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { DataTableData } from '../../model/data-table/data-table-data';
import { DataTableRequest } from '../../model/data-table/data-table-request';
import { UserListingModel } from '../../model/user/user-listing';
import { UserCriteria } from '../../query/user/user-criteria';
import { BaseHttpService } from '../http/base-http.service';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DataTableData } from '@app/core/model/data-table/data-table-data';
import { User, UserPersist, UserRolePatchPersist } from '@app/core/model/user/user';
import { UserLookup } from '@app/core/query/user.lookup';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { QueryResult } from '@common/model/query-result';
import { FilterService } from '@common/modules/text-filter/filter-service';
import { Guid } from '@common/types/guid';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { ConfigurationService } from '../configuration/configuration.service';
import { UserCredentialModel } from '@app/core/model/user/user-credential';
import { BaseHttpV2Service } from '../http/base-http-v2.service';
@Injectable()
export class UserService {
private actionUrl: string;
private headers = new HttpHeaders();
constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) {
this.actionUrl = configurationService.server + 'user/';
constructor(private http: BaseHttpV2Service, private httpClient: HttpClient, private configurationService: ConfigurationService, private filterService: FilterService) {
}
getPaged(dataTableRequest: DataTableRequest<UserCriteria>): Observable<DataTableData<UserListingModel>> {
return this.http.post<DataTableData<UserListingModel>>(this.actionUrl + 'getPaged', JSON.stringify(dataTableRequest), { headers: this.headers });
private get apiBase(): string { return `${this.configurationService.server}user`; }
query(q: UserLookup): Observable<QueryResult<User>> {
const url = `${this.apiBase}/query`;
return this.http.post<QueryResult<User>>(url, q).pipe(catchError((error: any) => throwError(error)));
}
getUser(id: String): Observable<UserListingModel> {
return this.http.get<UserListingModel>(this.actionUrl + id, { headers: this.headers });
getSingle(id: Guid, reqFields: string[] = []): Observable<User> {
const url = `${this.apiBase}/${id}`;
const options = { params: { f: reqFields } };
return this.http
.get<User>(url, options).pipe(
catchError((error: any) => throwError(error)));
}
getEmails(id: String): Observable<UserCredentialModel[]> {
return this.http.get<UserCredentialModel[]>(`${this.actionUrl}${id}/emails`, { headers: this.headers });
getByEmail(id: Guid, reqFields: string[] = []): Observable<User> {
const url = `${this.apiBase}/by-email/${id}`;
const options = { params: { f: reqFields } };
return this.http
.get<User>(url, options).pipe(
catchError((error: any) => throwError(error)));
}
updateRoles(itemToUpdate: UserListingModel): Observable<UserListingModel> {
return this.http.post<UserListingModel>(this.actionUrl + 'updateRoles', JSON.stringify(itemToUpdate), { headers: this.headers });
persist(item: UserPersist): Observable<User> {
const url = `${this.apiBase}/persist`;
return this.http
.post<User>(url, item).pipe(
catchError((error: any) => throwError(error)));
}
delete(id: String): Observable<any> {
return this.http.delete<any>(this.actionUrl + id, { headers: this.headers });
persistRoles(item: UserRolePatchPersist): Observable<User> {
const url = `${this.apiBase}/persist/roles`;
return this.http
.post<User>(url, item).pipe(
catchError((error: any) => throwError(error)));
}
getRecentActivity(): Observable<any[]> {
return this.http.get<any[]>(this.actionUrl + 'recentActivity', { headers: this.headers });
delete(id: Guid): Observable<User> {
const url = `${this.apiBase}/${id}`;
return this.http
.delete<User>(url).pipe(
catchError((error: any) => throwError(error)));
}
updateUserSettings(value: any): Observable<any[]> {
return this.http.post<any[]>(this.actionUrl + 'settings', value, { headers: this.headers });
exportCSV(): Observable<HttpResponse<Blob>> {
const url = `${this.apiBase}/export/csv`;
let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml');
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.JSONContentType]
};
return this.httpClient.get(url, { params: params, responseType: 'blob', observe: 'response', headers: headerXml });
}
getCollaboratorsPaged(dataTableRequest: DataTableRequest<UserCriteria>): Observable<DataTableData<UserListingModel>> {
return this.http.post<DataTableData<UserListingModel>>(this.actionUrl + 'getCollaboratorsPaged', JSON.stringify(dataTableRequest), { headers: this.headers });
uploadFile(file: FileList, labelSent: string, reqFields: string[] = []): Observable<DataTableData<User>> {
const url = `${this.apiBase}/xml/import`;
const params = new BaseHttpParams();
params.interceptorContext = {
excludedInterceptors: [InterceptorType.JSONContentType]
};
const formData = new FormData();
formData.append('file', file[0], labelSent);
return this.http.post(url, formData, { params: params });
}
getFromEmail(email: string): Observable<UserListingModel> {
return this.http.post<UserListingModel>(this.actionUrl + 'find', email, {headers: this.headers});
}
//
// Autocomplete Commons
//
// tslint:disable-next-line: member-ordering
singleAutocompleteConfiguration: SingleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.query(this.buildAutocompleteLookup()).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.query(this.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.query(this.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: User) => item.name,
titleFn: (item: User) => item.name,
valueAssign: (item: User) => item.id,
};
downloadCSV(): Observable<HttpResponse<Blob>> {
let headerCsv: HttpHeaders = this.headers.set('Content-Type', 'application/csv')
return this.httpClient.get(this.actionUrl + 'getCsv/', { responseType: 'blob', observe: 'response', headers: headerCsv });
}
// tslint:disable-next-line: member-ordering
multipleAutocompleteConfiguration: MultipleAutoCompleteConfiguration = {
initialItems: (excludedItems: any[], data?: any) => this.query(this.buildAutocompleteLookup(null, excludedItems ? excludedItems : null)).pipe(map(x => x.items)),
filterFn: (searchQuery: string, excludedItems: any[]) => this.query(this.buildAutocompleteLookup(searchQuery, excludedItems)).pipe(map(x => x.items)),
getSelectedItems: (selectedItems: any[]) => this.query(this.buildAutocompleteLookup(null, null, selectedItems)).pipe(map(x => x.items)),
displayFn: (item: User) => item.name,
titleFn: (item: User) => item.name,
valueAssign: (item: User) => item.id,
};
private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): UserLookup {
const lookup: UserLookup = new UserLookup();
lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }
if (ids && ids.length > 0) { lookup.ids = ids; }
lookup.isActive = [IsActive.Active];
lookup.project = {
fields: [
nameof<User>(x => x.id),
nameof<User>(x => x.name)
]
};
lookup.order = { items: [nameof<User>(x => x.name)] };
if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup;
}
}

View File

@ -21,6 +21,7 @@ import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type';
import { ReferenceTypeSourceType } from '@app/core/common/enum/reference-type-source-type';
import { ReferenceTypeExternalApiHTTPMethodType } from '@app/core/common/enum/reference-type-external-api-http-method-type';
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
@Injectable()
export class EnumUtils {
@ -296,4 +297,11 @@ export class EnumUtils {
case ReferenceTypeExternalApiHTTPMethodType.POST: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.POST');
}
}
toUserDescriptionTemplateRoleString(status: UserDescriptionTemplateRole): string {
switch (status) {
case UserDescriptionTemplateRole.Member: return this.language.instant('TYPES.USER-DESCRIPTION-TEMPLATE-ROLE.MEMBER');
case UserDescriptionTemplateRole.Owner: return this.language.instant('TYPES.USER-DESCRIPTION-TEMPLATE-ROLE.OWNER');
}
}
}

View File

@ -42,7 +42,7 @@ import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice';
import { EditorCustomValidators, EditorCustomValidatorsEnum } from './custom-validators/editor-custom-validators';
import { GENERAL_ANIMATIONS, STEPPER_ANIMATIONS } from './animations/animations';
import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type';
import { UserService } from '@app/core/services/user/user.service';
import { UserServiceOld } from '@app/core/services/user/user.service-old';
import { MatInput } from '@angular/material/input';
import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component';
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
@ -119,7 +119,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent
private visibilityRulesService: VisibilityRulesService,
private fb: UntypedFormBuilder,
private sidenavService: SideNavService,
private userService: UserService,
private userService: UserServiceOld,
private descriptionTemplateTypeService: DescriptionTemplateTypeService,
private fileUtils: FileUtils
) {

View File

@ -12,6 +12,16 @@ import { UserSettingsModule } from "@common/modules/user-settings/user-settings.
import { CommonUiModule } from '@common/ui/common-ui.module';
import { NgxDropzoneModule } from "ngx-dropzone";
import { DescriptionTemplateRoutingModule } from './description-template.routing';
import { DescriptionTemplateEditorCompositeFieldComponent } from './editor/components/composite-field/description-template-editor-composite-field.component';
import { DescriptionTemplateEditorDefaultValueComponent } from './editor/components/default-value/description-template-editor-default-value.component';
import { DescriptionTemplateEditorAutoCompleteFieldComponent } from './editor/components/field-type/auto-complete/description-template-editor-auto-complete-field.component';
import { DescriptionTemplateEditorMultiplicityFieldComponent } from './editor/components/field-type/multiplicity-field/description-template-editor-multiplicity-field.component';
import { DescriptionTemplateEditorPlaceholderFieldComponent } from './editor/components/field-type/placeholder-field/description-template-editor-placeholder-field.component';
import { DescriptionTemplateEditorWordListFieldComponent } from './editor/components/field-type/word-list/description-template-editor-word-list-field.component';
import { DescriptionTemplateEditorFieldComponent } from './editor/components/field/description-template-editor-field.component';
import { DescriptionTemplateEditorSectionFieldSetComponent } from './editor/components/section-fieldset/description-template-editor-section-fieldset.component';
import { DescriptionTemplateEditorSectionComponent } from './editor/components/section/description-template-editor-section.component';
import { DescriptionTemplateEditorRuleComponent } from './editor/components/visibility-rule/description-template-editor-visibility-rule.component';
import { DescriptionTemplateEditorComponent } from './editor/description-template-editor.component';
import { DescriptionTemplateTableOfContents } from './editor/table-of-contents/description-template-table-of-contents';
import { DescriptionTemplateTableOfContentsInternalSection } from './editor/table-of-contents/table-of-contents-internal-section/description-template-table-of-contents-internal-section';
@ -47,8 +57,20 @@ import { ImportDescriptionTemplateDialogComponent } from './listing/import-descr
DescriptionTemplateListingComponent,
DescriptionTemplateListingFiltersComponent,
ImportDescriptionTemplateDialogComponent,
DescriptionTemplateTableOfContents,
DescriptionTemplateTableOfContentsInternalSection
DescriptionTemplateTableOfContentsInternalSection,
DescriptionTemplateEditorSectionFieldSetComponent,
DescriptionTemplateEditorSectionComponent,
DescriptionTemplateEditorCompositeFieldComponent,
DescriptionTemplateEditorFieldComponent,
DescriptionTemplateEditorDefaultValueComponent,
DescriptionTemplateEditorRuleComponent,
DescriptionTemplateEditorAutoCompleteFieldComponent,
DescriptionTemplateEditorWordListFieldComponent,
DescriptionTemplateEditorPlaceholderFieldComponent,
DescriptionTemplateEditorMultiplicityFieldComponent,
]
})
export class DescriptionTemplateModule { }

View File

@ -0,0 +1,289 @@
<!-- MAIN CONTENT -->
<div class="main-content-page" [ngClass]="{'pb-2': !hasFocus}">
<!-- TITLE -->
<div class="col-12">
<div class="row fielset-header">
<mat-form-field class="numbering-label" [ngStyle]="calculateLabelWidth(numbering)">
<input [ngClass]="{'text-danger':form.get('title').invalid &&form.get('title').touched}" matInput type="text" [value]="numbering" disabled>
</mat-form-field>
<mat-form-field class="col field-title" floatLabel="never">
<textarea matInput type="text" [placeholder]="('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' |translate)+' '+('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.QUESTION'| translate)" #titleControl="matInput" [formControl]="this.form.get('title')"></textarea>
</mat-form-field>
</div>
</div>
<div style="position: relative;" class="col-12" *ngIf="hasFocus" [@fade-in]>
<div *ngIf="showDescription" class="mb-4">
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}</h5>
<rich-text-editor-component [parentFormGroup]="form" [controlName]="'description'" [id]="'editor1'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION'" [wrapperClasses]="'row'">
</rich-text-editor-component>
</div>
<div *ngIf="showExtendedDescription" class="mb-4">
<h5 style="font-weight: bold" class="row">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}</h5>
<rich-text-editor-component [parentFormGroup]="form" [controlName]="'extendedDescription'" [id]="'editor2'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION'" [wrapperClasses]="'row'">
</rich-text-editor-component>
</div>
<div class="row" *ngIf="showAdditionalInfo">
<mat-form-field class="col p-0 underline-line-field">
<input matInput type="text" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ADDITIONAL-INFORMATION' | translate}}" [formControl]="this.form.get('additionalInformation')" />
</mat-form-field>
</div>
<div class="row">
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pl-0 underline-line-field">
<input matInput placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MIN' | translate}}" type="number" [formControl]="form.get('multiplicity').get('min')" required>
<mat-error *ngIf="form.get('multiplicity').get('min').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pr-0 underline-line-field">
<input matInput placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-MAX' | translate}}" type="number" [formControl]="this.form.get('multiplicity').get('max')" required>
<mat-error *ngIf="form.get('multiplicity').get('max').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field *ngIf="isMultiplicityEnabled" class="col pl-0 underline-line-field">
<input matInput placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-PLACEHOLDER' | translate}}" type="text" [formControl]="form.get('multiplicity').get('placeholder')">
</mat-form-field>
</div>
<div class="row">
<mat-checkbox *ngIf="isMultiplicityEnabled" class="col pl-0 underline-line-field fieldset-checkbox-action-description-template-editor" [formControl]="form.get('multiplicity').get('tableView')">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-TABLEVIEW' | translate}}
</mat-checkbox>
</div>
</div>
<!-- FIELDS DETAILS AND ACTIONS -->
<div class="row">
<!-- FIELDS -->
<div #inputs transition-group class="col-12" *ngIf="hasFocus" [@fade-in]>
<div *ngFor="let field of fieldsArray.controls; let i=index;" class="row bg-white field-input mt-3" (click)="setTargetField(field)" transition-group-item>
<app-description-template-editor-field-component class="col-12" [form]="field" [showOrdinal]="false" [indexPath]="indexPath + 'f' + i" [viewOnly]="viewOnly" [expandView]="hasFocus" [canBeDeleted]="fieldsArray.length !=1" (delete)="deleteField(i)">
<div class="arrows mt-2">
<ul class="list-unstyled list-inline d-flex align-items-center">
<li *ngIf="canGoUp(i)" class="text-muted">
<mat-icon style="cursor: pointer;" (click)="move(i)" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.MOVE-UP' | translate">keyboard_arrow_up</mat-icon>
</li>
<li *ngIf="canGoDown(i)" class="text-muted">
<mat-icon style="cursor: pointer;" (click)="move(i, 'down')" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.MOVE-DOWN' | translate">keyboard_arrow_down</mat-icon>
</li>
</ul>
</div>
</app-description-template-editor-field-component>
<hr>
</div>
</div>
<!-- PREVIEW -->
{{firstField?.value | json}}
<div class="col-12 previewer">
<div *ngIf="hasFocus" class="d-flex mb-3" style="justify-content: space-between;">
<span class="previewer-text">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.PREVIEW' | translate}}</span>
<span [@fadeElement]="updatedClass" *ngIf="firstField?.get('data')?.get('fieldType')?.value">
<ng-container *ngIf="!previewDirty">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.STATUS.PREVIEW-UPDATED' | translate}}
</ng-container>
<ng-container *ngIf="previewDirty">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.STATUS.CALCULATING-PREVIEW' | translate}}
</ng-container>
</span>
</div>
<div [id]="'preview_container'+ form.get('id').value" class="w-100" style="margin-right: -15px; margin-left: -15px;">
<div *ngIf="previewForm && showPreview && firstField?.get('data')?.get('fieldType')?.value" [@fade-in-fast]>
<app-form-section-inner [form]="previewForm" [tableView]="form.getRawValue().multiplicity?.tableView" [datasetProfileId]="datasetProfileId">
</app-form-section-inner>
</div>
</div>
<div class="w-100" *ngIf="!firstField?.get('data')?.get('fieldType')?.value">
<em>
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.NOT-INITIALIZED' | translate}}
</em>
</div>
</div>
<div class="col-12">
<hr *ngIf="hasFocus">
</div>
</div>
<ng-container *ngIf="hasFocus">
<div class="row justify-content-end pt-2">
<div class="col-auto">
<ul class="list-unstyled list-inline fieldset-actions-list d-flex align-items-center text-primary-blue">
<li class="list-inline-item" *ngIf="!viewOnly">
<span [matMenuTriggerFor]="inputmenu" class="inputMenuTrigger">
<img src="/assets/images/editor/icons/add_input.svg" style="width: 18px;transform: translateY(-1px);" class="input_icon" alt="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.ADD-INPUT' | translate" />
<span class="fieldset-new-input-action">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.ADD-INPUT' | translate}}</span>
</span>
<mat-menu #inputmenu="matMenu" [class]="'add_input_menu'">
<mat-action-list>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.TEXT_AREA)">
<img src="/assets/images/editor/icons/text_area.svg" class="input_icon" alt="Text Area icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.TEXT_AREA)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA)">
<img src="/assets/images/editor/icons/text_area.svg" class="input_icon" alt="Rich Text Area icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.FREE_TEXT)">
<img src="/assets/images/editor/icons/free_text.svg" class="input_icon" alt="Free Text icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.FREE_TEXT)}}
</button>
<mat-divider></mat-divider>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.UPLOAD)">
<mat-icon class="input_icon" style="font-size: 14px; color: #129d99; display: inline-flex; align-items: center">upload</mat-icon>
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.UPLOAD)}}
</button>
<mat-divider></mat-divider>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION)">
<img src="/assets/images/editor/icons/boolean.svg" class="input_icon" alt="Boolean icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.RADIO_BOX)">
<img src="/assets/images/editor/icons/radio_box.svg" class="input_icon" alt="RadioBox icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.RADIO_BOX)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.COMBO_BOX)">
<span class="input_icon">
<img src="/assets/images/editor/icons/select.svg" alt="Select icon">
</span>
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.COMBO_BOX)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.CHECK_BOX)">
<img src="/assets/images/editor/icons/checkbox.svg" class="input_icon" alt="CheckBox Icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.CHECK_BOX)}}
</button>
<mat-divider></mat-divider>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.DATE_PICKER)">
<img src="/assets/images/editor/icons/date_picker.svg" class="input_icon" alt="DatePicker Icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.DATE_PICKER)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.CURRENCY)">
<img src="/assets/images/editor/icons/currency.svg" class="input_icon" alt="Currency Icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.CURRENCY)}}
</button>
<mat-divider></mat-divider>
<button mat-list-item (click)="$event.stopPropagation();" style="font-style: italic;">
<img src="/assets/images/editor/icons/api.svg" class="input_icon" alt="APIs icon">
APIs
</button>
<mat-action-list class="ml-4">
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.REGISTRIES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Registries icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.REGISTRIES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.SERVICES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Services icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.SERVICES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.RESEARCHERS)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Researchers icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.RESEARCHERS)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.ORGANIZATIONS)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Organizations icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.ORGANIZATIONS)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="External Datasets icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.DATA_REPOSITORIES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="DataRepositories icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.DATA_REPOSITORIES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.PUB_REPOSITORIES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="PubRepositories icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.PUB_REPOSITORIES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.JOURNAL_REPOSITORIES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="JournalRepositories icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.JOURNAL_REPOSITORIES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.TAXONOMIES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Taxonomies icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.TAXONOMIES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.LICENSES)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Licenses icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.LICENSES)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.PUBLICATIONS)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Publications icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.PUBLICATIONS)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.AUTO_COMPLETE)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Other icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.AUTO_COMPLETE)}}
</button>
</mat-action-list>
<mat-divider></mat-divider>
<button mat-list-item (click)="$event.stopPropagation();" style="font-style: italic;">
<img src="/assets/images/editor/icons/argos_entities.svg" class="input_icon" alt="Argos Entities icon">
Argos Entities
</button>
<mat-action-list class="ml-4">
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.InternalDmpEntities)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Internal Dmp icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.InternalDmpEntities)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.Tags)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Tags icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.Tags)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.DatasetIdentifier)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Datset Identifier icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.DatasetIdentifier)}}
</button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.Validation)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Validation icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.Validation)}}
</button>
</mat-action-list>
</mat-action-list>
</mat-menu>
</li>
<li class="list-inline-item">
<mat-checkbox class="fieldset-checkbox-action-description-template-editor" [formControl]="this.form.get('hasCommentField')" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.INCLUDE-COMMENT-FIELD' | translate">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.COMMENT-FIELD' | translate}}</mat-checkbox>
</li>
<li class="list-inline-item">
<mat-checkbox class="fieldset-checkbox-action-description-template-editor" [(checked)]="isMultiplicityEnabled" (change)="onIsMultiplicityEnabledChange($event)" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.ENABLE-MULTIPLICITY' | translate" [disabled]="viewOnly">
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.MULTIPLICITY' | translate}}
</mat-checkbox>
</li>
<li class="list-inline-item">
<mat-icon [matMenuTriggerFor]="menu" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELDSET.MORE' | translate" style="transform: translateY(-1px);">more_vert</mat-icon>
<mat-menu #menu="matMenu">
<!-- TODO to check -->
<mat-checkbox class="mat-menu-item" (click)="$event.stopPropagation()" [(ngModel)]="showDescription">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.DESCRIPTION' | translate}}</mat-checkbox>
<mat-checkbox class="mat-menu-item" (click)="$event.stopPropagation()" [(ngModel)]="showExtendedDescription">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXTENDED-DESCRIPTION' | translate}}</mat-checkbox>
<mat-checkbox class="mat-menu-item" (click)="$event.stopPropagation()" [(ngModel)]="showAdditionalInfo">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.ADDITIONAL-INFORMATION' | translate}}</mat-checkbox>
</mat-menu>
</li>
</ul>
</div>
</div>
</ng-container>
</div>

View File

@ -0,0 +1,146 @@
.full-width{
width: 100%;
}
.deleteBtn{
margin-right:0.7em;
}
.titleStile{
font-weight: bold;
}
//REFACTOR SECTION
//Palete
$blue-color : var(--primary-color);
$blue-color-light: #5cf7f2;
.actions-list{
border-radius: 7px;
box-shadow: 0 1px 0.8em $blue-color;
padding: 1em 0em;
font-size: small;
}
.field-container{
box-shadow: 0px 1px 2px rgb(173, 173, 173) ;
padding: 3em;
border-radius: .3em;
// border-left: 0.3em solid yellow;
padding-bottom: 2em;
margin-bottom: 2em;
}
.field-container-active{
box-shadow: 0px 1px 2px rgb(173, 173, 173) ;
padding: 3em;
border-radius: .3em;
border-left: 0.3em solid $blue-color;
padding-bottom: 2em;
margin-bottom: 2em;
}
.field-id-container{
background-color: $blue-color-light;
position: absolute;
right: 0;
top: 0;
padding: .6em 1.2em;
overflow: visible;
.field-id-container-icon{
position: absolute;
top: -50%;
}
}
.main-content-page{
padding: 0em 1.5em;
}
.fielset-header{
font-size: 1.5em;
font-weight: bold;
// .numbering{
// padding: 0.5em 0em;
// }
}
.fieldset-actions-list{
margin: 0;
cursor: pointer;
}
// ::ng-deep .main-content-page .fieldset-header .field-title .mat-form-field-infix{
// border-top: 0px;
// }
.numbering-label .mat-input-element:disabled{
color: #212121;
}
:host ::ng-deep .fieldset-checkbox-action-description-template-editor
{
.mat-checkbox-label{
font-size: 0.8em;
color: #212121;
transform: translateY(3px);
}
.mat-checkbox-frame{
border: 1px solid $blue-color ;
}
}
.fieldset-new-input-action {
font-size: 0.8em;
font-weight: 400;
color: #212121;
display: inline-block;
transform: translateY(1px);
}
.inputMenuTrigger {
margin-bottom: 0.3rem;
display: inline-block;
}
.previewer{
background-color: #129d9811;
padding: 2em;
border: 1px solid #70707015;
border-radius: 4px;
}
.input_icon{
width: 14px;
margin-right: 0.5em;
// display: flex;
// align-items: center;
}
::ng-deep .mat-menu-panel{
max-height: 32em;
}
:host ::ng-deep .fielset-header .mat-form-field-wrapper{
padding-bottom: 0px;
}
.previewer-text{
font-weight: bold;
font-style: italic;
}
.field-input {
position: relative;
}
.field-input .arrows {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
}

View File

@ -0,0 +1,871 @@
import { Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { AbstractControl, UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { MatDialog } from '@angular/material/dialog';
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
import { ValidationType } from '@app/core/common/enum/validation-type';
import {
DescriptionTemplateAutoCompleteData,
DescriptionTemplateBooleanDecisionData,
DescriptionTemplateCheckBoxData,
DescriptionTemplateComboBoxOption,
DescriptionTemplateCurrencyData,
DescriptionTemplateDataRepositoryData,
DescriptionTemplateDatasetIdentifierData,
DescriptionTemplateDatePickerData,
DescriptionTemplateDmpAutoCompleteData,
DescriptionTemplateExternalDatasetData,
DescriptionTemplateField,
DescriptionTemplateFreeTextData,
DescriptionTemplateLicenseData,
DescriptionTemplateOrganizationData,
DescriptionTemplatePublicationData,
DescriptionTemplateRadioBoxData,
DescriptionTemplateRegistryData,
DescriptionTemplateResearcherAutoCompleteData,
DescriptionTemplateRichTextAreaData,
DescriptionTemplateServiceData,
DescriptionTemplateTagData,
DescriptionTemplateTaxonomyData,
DescriptionTemplateTextAreaData,
DescriptionTemplateUploadData,
DescriptionTemplateValidationData,
DescriptionTemplateWordListData
} from '@app/core/model/description-template/description-template';
import { ConfigurationService } from "@app/core/services/configuration/configuration.service";
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import {
DatasetDescriptionSectionEditorModel
} from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
import { TransitionGroupComponent } from "@app/ui/transition-group/transition-group.component";
import { BaseComponent } from '@common/base/base.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { Subject } from 'rxjs';
import { debounceTime, delay, map, takeUntil, tap } from 'rxjs/operators';
import { GENERAL_ANIMATIONS } from '../../animations/animations';
import { EditorCustomValidators } from '../../custom-validators/editor-custom-validators';
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel } from '../../description-template-editor.model';
import { ViewStyleType } from '../field/view-style-enum';
@Component({
selector: 'app-description-template-editor-composite-field-component',
templateUrl: './description-template-editor-composite-field.component.html',
styleUrls: ['./description-template-editor-composite-field.component.scss'],
animations: [GENERAL_ANIMATIONS]
})
export class DescriptionTemplateEditorCompositeFieldComponent extends BaseComponent implements OnInit, OnChanges {
@Input() form: UntypedFormGroup;
@Input() indexPath: string;
@Input() viewOnly: boolean;
@Input() datasetProfileId?: string;
@Input() numbering: string;
@Input() hasFocus: boolean = false;
@ViewChild("inputs") inputs: TransitionGroupComponent;
showPreview: boolean = true;
previewDirty: boolean = false;
showDescription: boolean = true;
showAdditionalInfo: boolean = false;
showExtendedDescription: boolean = false;
previewForm: UntypedFormGroup = null;
// isComposite = false;
// isMultiplicityEnabled = false;
descriptionTemplateFieldTypeEnum = DescriptionTemplateFieldType;
private myCustomValidators: EditorCustomValidators = new EditorCustomValidators();
isMultiplicityEnabled = false;
constructor(
private dialog: MatDialog,
private language: TranslateService,
public enumUtils: EnumUtils,
public datasetProfileService: DescriptionTemplateService,
private configurationService: ConfigurationService
) {
super();
}
ngOnChanges(changes: SimpleChanges) {
// this.setTargetField(null);
// this.showExtendedDescription = !!this.form.get('extendedDescription').value;
// this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
// console.log(this.form.get('fields')['controls'])
if (changes['form']) {
try {
const multiplicity = this.form.get('multiplicity').value;
this.isMultiplicityEnabled = multiplicity.min > 0 || multiplicity.max > 0;
} catch {
this.isMultiplicityEnabled = false;
}
}
}
get firstField() {
try {
return (this.form.get('fields') as UntypedFormArray).at(0);
} catch {
return null;
}
}
ngOnInit() {
//this.addNewField();
// if (this.form.get('multiplicity')) {
// if (this.form.get('multiplicity').value.min > 1 || this.form.get('multiplicity').value.max > 1) {
// this.isMultiplicityEnabled = true;
// }
// }
// this.isComposite = (this.form.get('fields') as FormArray).length > 1;
if (this.viewOnly) {
this.form.get('hasCommentField').disable();
}
//SET UP TARGET FIELD
// if((this.form.get('fields') as FormArray).length>0){
// //get the first field in list
// this.targetField = (this.form.get('fields') as FormArray).at(0) as FormGroup;
// }
this.showExtendedDescription = !!this.form.get('extendedDescription').value;
this.showAdditionalInfo = !!this.form.get('additionalInformation').value;
this.form.valueChanges.pipe(takeUntil(this._destroyed)).subscribe(changes => {
// this.previewForm = null;
this.previewDirty = true;
this.generatePreviewForm();
});
this.previewSubject$
.pipe(debounceTime(600))
.pipe(
takeUntil(this._destroyed),
map(model => model.buildForm()),
map(updatedForm => {
const previewContainer = document.getElementById('preview_container' + this.form.get('id').value);
// let clientHeight = -1;
if (previewContainer) {
// console.log(previewContainer);
const clientHeight = previewContainer.clientHeight;
// console.log(clientHeight);
if (clientHeight) {
previewContainer.style.height = clientHeight.toString() + 'px';
// console.log('height:' ,previewContainer.style.height);
}
}
this.showPreview = false;
this.previewDirty = true;
this.previewForm = updatedForm;
return previewContainer;
}),
delay(100),
tap(previewContainer => {
this.showPreview = true;
this.previewDirty = false;
}),
delay(100)
)
.subscribe(previewContainer => {
if (previewContainer) {
previewContainer.style.height = 'auto';
}
// const updatedForm = model.buildForm();
// this.reloadPreview(updatedForm)
});
this.generatePreviewForm();
}
get updatedClass() {
if (this.previewDirty) return '';
else return 'updated';
}
private reloadPreview(updatedForm: UntypedFormGroup) {
setTimeout(() => {
const previewContainer = document.getElementById('preview_container' + this.form.get('id').value);
// let clientHeight = -1;
if (previewContainer) {
// console.log(previewContainer);
const clientHeight = previewContainer.clientHeight;
// console.log(clientHeight);
if (clientHeight) {
previewContainer.style.height = clientHeight.toString() + 'px';
// console.log('height:' ,previewContainer.style.height);
}
}
this.showPreview = false;
this.previewDirty = true;
this.previewForm = updatedForm;
setTimeout(() => {
this.showPreview = true;
this.previewDirty = false;
if (previewContainer) {
setTimeout(() => {
if (previewContainer) {
previewContainer.style.height = 'auto';
}
});
}
});
});
}
previewSubject$: Subject<DatasetDescriptionSectionEditorModel> = new Subject<DatasetDescriptionSectionEditorModel>();
private generatePreviewForm() {
// const formValue: DescriptionTemplateFieldSet = this.form.getRawValue();
// const fields: FieldDefinition[] = formValue.fields.map(editorField => this._fieldToFieldDefinition(editorField));
// const compositeField: CompositeField = {
// id: formValue.id,
// additionalInformation: formValue.additionalInformation,
// extendedDescription: formValue.extendedDescription,
// numbering: '',
// title: formValue.title,
// ordinal: formValue.ordinal,
// description: formValue.description,
// hasCommentField: formValue.hasCommentField,
// commentFieldValue: '',
// multiplicity: {
// max: formValue.multiplicity.max, min: formValue.multiplicity.min,
// placeholder: formValue.multiplicity.placeholder, tableView: formValue.multiplicity.tableView
// },
// multiplicityItems: null,
// fields: fields.map(editorField => {
// const model = new DatasetDescriptionFieldEditorModel().fromModel(editorField);
// if (model.data.fieldType === DescriptionTemplateFieldType.CheckBox) {
// model.value = model.value ? "true" : "false";//patch
// }
// return model;
// })
// }
// const section = new DatasetDescriptionSectionEditorModel();
// section.title = '';
// section.numbering = '';
// const compositeForm = new DatasetDescriptionCompositeFieldEditorModel().fromModel(compositeField)
// section.compositeFields = [compositeForm];
// this.previewSubject$.next(section);
}
// private _fieldToFieldDefinition(editorField: Field): FieldDefinition {
// const field = {
// id: editorField.id,
// title: '',
// page: editorField.page,
// numbering: '',
// multiplicity: null,
// multiplicityItems: null,
// viewStyle: editorField.viewStyle,
// defaultValue: editorField.defaultValue,
// value: null,
// validations: editorField.validations,
// } as FieldDefinition;
// field.data = editorField.data;
// // return new DatasetDescriptionFieldEditorModel().fromModel(field);
// return field;
// }
onIsCompositeChange(isComposite: boolean) {
if (!isComposite && (<UntypedFormArray>this.form.get('fields')).length > 1) {
for (let i = 0; i < (<UntypedFormArray>this.form.get('fields')).length - 1; i++) {
(<UntypedFormArray>this.form.get('fields')).removeAt(1);
}
(this.form.get('fields') as UntypedFormArray).controls.splice(1);
}
if ((<UntypedFormArray>this.form.get('fields')).length === 0) {
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel();
(<UntypedFormArray>this.form.get('fields')).push(field.buildForm());
}
}
onIsMultiplicityEnabledChange(isMultiplicityEnabled: MatCheckboxChange) {
const multiplicity = this.form.get('multiplicity') as UntypedFormGroup;
const minControl = multiplicity.get('min');
const maxControl = multiplicity.get('max');
const placeholder = multiplicity.get('placeholder');
const tableView = multiplicity.get('tableView');
if (isMultiplicityEnabled.checked) {
minControl.setValue(0);
maxControl.setValue(1);
placeholder.setValue('');
tableView.setValue(false);
} else {
minControl.setValue(0);
maxControl.setValue(0);
placeholder.setValue(null);
tableView.setValue(null);
}
this.isMultiplicityEnabled = isMultiplicityEnabled.checked;
minControl.updateValueAndValidity();
maxControl.updateValueAndValidity();
}
addNewField() {
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel();
field.id = Guid.create();
field.ordinal = (this.form.get('fields') as UntypedFormArray).length;
const fieldForm = field.buildForm();
// fieldForm.setValidators(this.customFieldValidator());
// fieldForm.get('viewStyle').get('renderStyle').setValidators(Validators.required);
(<UntypedFormArray>this.form.get('fields')).push(fieldForm);
this.setTargetField(fieldForm);
fieldForm.updateValueAndValidity();
}
DeleteField(index) {
const fieldsForm = <UntypedFormArray>this.form.get('fields');
fieldsForm.removeAt(index);
this.inputs.init();
// calculate ordinals
fieldsForm.controls.forEach((field, idx) => {
field.get('ordinal').setValue(idx);
field.updateValueAndValidity();
});
this.form.markAsDirty();//deactivate guard
}
getFieldTile(formGroup: UntypedFormGroup, index: number) {
if (formGroup.get('title') && formGroup.get('title').value && formGroup.get('title').value.length > 0) { return formGroup.get('title').value; }
return "Field " + (index + 1);
}
targetField: UntypedFormGroup;
validationTypeEnum = ValidationType;
addVisibilityRule(targetField: UntypedFormGroup) {
const rule: DescriptionTemplateRuleEditorModel = new DescriptionTemplateRuleEditorModel();
(<UntypedFormArray>targetField.get('visible').get('rules')).push(rule.buildForm());
}
toggleRequired(targetField: UntypedFormGroup, event: MatCheckboxChange) {
let validationsControl = targetField.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
if (event.checked) {
if (!validations.includes(ValidationType.Required)) {//IS ALREADY REQUIRED
// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
// validationsControl.updateValueAndValidity();
validations.push(ValidationType.Required);
// validationsControl.setValue(validations);
validationsControl.updateValueAndValidity();
}
} else {
validationsControl.setValue(validations.filter(validator => validator != ValidationType.Required));
validationsControl.updateValueAndValidity();
}
// if(validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED
// validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required));
// validationsControl.updateValueAndValidity();
// }else{
// //SET REQUIRED VALIDATOR
// console.log('setting required validator');
// validations.push(ValidationType.Required);
// validationsControl.setValue(validations);
// validationsControl.updateValueAndValidity();
// }
}
setTargetField(field: AbstractControl) {
this.targetField = <UntypedFormGroup>field;
}
deleteTargetField() {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: true
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this._deleteTargetField();
}
});
}
private _deleteTargetField() {
if (!this.targetField) return;
let index = -1;
const fields = this.form.get('fields') as UntypedFormArray;
for (let i = 0; i < fields.length; i++) {
let field = fields.at(i);
if (field.get('id').value === this.targetField.get('id').value) {//index found
index = i;
break;
}
}
if (index >= 0) {//target found in fields
this.DeleteField(index);
this.targetField = null;
}
}
deleteField(index: number) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: true
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.DeleteField(index);
}
});
}
addNewInput(type: DescriptionTemplateFieldType) {
const fieldsArray = this.form.get('fields') as UntypedFormArray;
let targetOrdinal = fieldsArray.length;
try {
targetOrdinal = fieldsArray.controls.map(control => control.get('ordinal').value).reduce((a, b) => Math.max(a, b)) + 1;
} catch {
}
const field = {
id: Guid.create(),
ordinal: targetOrdinal,
validations: [],
includeInExport: true
} as DescriptionTemplateField;
switch (type) {
case DescriptionTemplateFieldType.BOOLEAN_DECISION: {
const data: DescriptionTemplateBooleanDecisionData = {
label: '',
fieldType: DescriptionTemplateFieldType.BOOLEAN_DECISION,
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.CHECK_BOX: {
const data: DescriptionTemplateCheckBoxData = {
label: '',
fieldType: DescriptionTemplateFieldType.CHECK_BOX,
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.COMBO_BOX: {
const firstOption = { label: '', value: '' } as DescriptionTemplateComboBoxOption;
const data: DescriptionTemplateWordListData = {
label: '',
multiList: false,
options: [firstOption],
fieldType: DescriptionTemplateFieldType.WORD_LIST
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.AUTO_COMPLETE: {
const data: DescriptionTemplateAutoCompleteData = {
autoCompleteSingleDataList: [],
multiAutoComplete: false,
label: '',
fieldType: DescriptionTemplateFieldType.AUTO_COMPLETE
}
field.data = data;
break;
} case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES: {
const data: DescriptionTemplateDmpAutoCompleteData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DMPS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.FREE_TEXT: {
const data: DescriptionTemplateFreeTextData = {
label: '',
fieldType: DescriptionTemplateFieldType.FREE_TEXT
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RADIO_BOX: {
const data: DescriptionTemplateRadioBoxData = {
label: '',
options: [],
fieldType: DescriptionTemplateFieldType.RADIO_BOX
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TEXT_AREA: {
const data: DescriptionTemplateTextAreaData = {
label: '',
fieldType: DescriptionTemplateFieldType.TEXT_AREA
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RICH_TEXT_AREA: {
const data: DescriptionTemplateRichTextAreaData = {
label: '',
fieldType: DescriptionTemplateFieldType.RICH_TEXT_AREA
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.UPLOAD: {
const data: DescriptionTemplateUploadData = {
label: '',
types: [],
maxFileSizeInMB: this.configurationService.maxFileSizeInMB,
fieldType: DescriptionTemplateFieldType.UPLOAD
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATE_PICKER: {
const data: DescriptionTemplateDatePickerData = {
label: '',
fieldType: DescriptionTemplateFieldType.DATE_PICKER
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.EXTERNAL_DATASETS: {
const data: DescriptionTemplateExternalDatasetData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.EXTERNAL_DATASETS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATA_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.PUB_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.JOURNAL_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TAXONOMIES: {
const data: DescriptionTemplateTaxonomyData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.TAXONOMIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.LICENSES: {
const data: DescriptionTemplateLicenseData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.LICENSES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.PUBLICATIONS: {
const data: DescriptionTemplatePublicationData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.PUBLICATIONS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.REGISTRIES: {
const data: DescriptionTemplateRegistryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.REGISTRIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.SERVICES: {
const data: DescriptionTemplateServiceData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.SERVICES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TAGS: {
const data: DescriptionTemplateTagData = {
label: '',
fieldType: DescriptionTemplateFieldType.TAGS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RESEARCHERS: {
const data: DescriptionTemplateResearcherAutoCompleteData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_RESEARCHERS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.ORGANIZATIONS: {
const data: DescriptionTemplateOrganizationData = {
// autoCompleteSingleDataList: [], //TODO maybe remove
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.ORGANIZATIONS
};
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATASET_IDENTIFIER: {
const data: DescriptionTemplateDatasetIdentifierData = {
label: '',
fieldType: DescriptionTemplateFieldType.DATASET_IDENTIFIER
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.CURRENCY: {
const data: DescriptionTemplateCurrencyData = {
label: '',
fieldType: DescriptionTemplateFieldType.CURRENCY
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.VALIDATION: {
const data: DescriptionTemplateValidationData = {
label: '',
fieldType: DescriptionTemplateFieldType.VALIDATION
}
field.data = data;
break;
}
}
(<UntypedFormArray>this.form.get('fields')).push(new DescriptionTemplateFieldEditorModel().fromModel(field).buildForm());
this.inputs.init();
// fieldForm.get('viewStyle').get('renderStyle').updateValueAndValidity();
// fieldForm.get('data').updateValueAndValidity();
}
// private customFieldValidator(): ValidatorFn{
// return (control):ValidationErrors | null=>{
// DescriptionTemplateFieldType
// switch(control.get('viewStyle').get('renderStyle').value){
// case DescriptionTemplateFieldType.TextArea:
// return null;
// case DescriptionTemplateFieldType.BooleanDecision:
// return null;
// case DescriptionTemplateFieldType.ComboBox:
// return null;
// case DescriptionTemplateFieldType.CheckBox:
// return null;
// case DescriptionTemplateFieldType.FreeText:
// return null;
// case DescriptionTemplateFieldType.RadioBox:
// return null;
// case DescriptionTemplateFieldType.DatePicker:
// return null;
// case DescriptionTemplateFieldType.InternalDmpEntities:
// return null;
// case DescriptionTemplateFieldType.ExternalDatasets:
// return null;
// case DescriptionTemplateFieldType.DATA_REPOSITORIES:
// return null;
// case DescriptionTemplateFieldType.Registries:
// return null;
// case DescriptionTemplateFieldType.Services:
// return null;
// case DescriptionTemplateFieldType.Tags:
// return null;
// case DescriptionTemplateFieldType.Researchers:
// return null;
// case DescriptionTemplateFieldType.Organizations:
// return null;
// case DescriptionTemplateFieldType.DatasetIdentifier:
// return null;
// case DescriptionTemplateFieldType.Currency:
// return null;
// case DescriptionTemplateFieldType.Validation:
// return null;
// default:
// return {inputTypeNotValid: true}
// }
// }
// }
// private _atLeastOneElementListValidator(arrayToCheck): ValidatorFn{
// return (control: AbstractControl): ValidationErrors | null=>{
// const fa = control.get(arrayToCheck) as FormArray;
// if(fa.length === 0){
// return {emptyArray: true};
// }
// return null;
// }
// }
calculateLabelWidth(numbering: string) {
const width = numbering.split('.').reduce((acc, item) => item + acc, '').length;
return { 'width': width + 'em' }
}
get fieldsArray(): UntypedFormArray {
if (this.form && this.form.get('fields')) {
return this.form.get('fields') as UntypedFormArray;
}
return null;
}
move(index, direction: "up" | "down" = "up") {
this.inputs.init();
if (direction === "up" && this.canGoUp(index)) {
let temp = this.fieldsArray.at(index);
this.fieldsArray.removeAt(index);
this.fieldsArray.insert(index - 1, temp);
} else if (direction === "down" && this.canGoDown(index)) {
let temp = this.fieldsArray.at(index + 1);
this.fieldsArray.removeAt(index + 1);
this.fieldsArray.insert(index, temp);
}
this.fieldsArray.controls.forEach((field, index) => {
field.get('ordinal').setValue(index);
});
}
canGoUp(index: number): boolean {
return index > 0 && !this.viewOnly;
}
canGoDown(index: number): boolean {
return index < (this.fieldsArray.length - 1) && !this.viewOnly;
}
}

View File

@ -0,0 +1,79 @@
<div class="row">
<!-- BooleanDecision -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder">
<mat-option [value]="null">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' |
translate}}</mat-option>
<mat-option [value]="'true'">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES'
|
translate}}</mat-option>
<mat-option [value]="'false'">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO'
|
translate}}</mat-option>
</mat-select>
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- CheckBox -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.CHECK_BOX">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder">
<mat-option [value]="'true'">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.CHECKED' | translate}}</mat-option>
<mat-option [value]="'false'">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.UNCHECKED' | translate}}</mat-option>
</mat-select>
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- ComboBox -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.WORD_LIST">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder">
<mat-option [value]="null">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate }}</mat-option>
<mat-option *ngFor="let opt of formArrayOptions['controls']" [value]="opt.get('value').value">{{opt.get('label').value}}</mat-option>
</mat-select>
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- FreeText -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.FREE_TEXT">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form">
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- RadioBox -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.RADIO_BOX">
<mat-label>{{placeHolder}}</mat-label>
<mat-select [formControl]="form" [placeholder]="placeHolder">
<mat-option [value]="null">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate}}</mat-option>
<mat-option *ngFor="let opt of formArrayOptions['controls']" [value]="opt.get('value').value">{{opt.get('label').value}}</mat-option>
</mat-select>
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- TextArea -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.TEXT_AREA">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form">
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- RichTextArea -->
<mat-form-field class="col-md-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA">
<mat-label>{{placeHolder}}</mat-label>
<input matInput type="text" [placeholder]="placeHolder" [formControl]="form">
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<!-- DatePicker -->
<mat-form-field class="col-12" *ngIf="fieldType === descriptionTemplateFieldTypeEnum.DATE_PICKER">
<!--(focus)="date.open()" (click)="date.open()"-->
<mat-label>{{placeHolder}}</mat-label>
<input matInput [placeholder]="placeHolder" class="table-input" [matDatepicker]="date" [formControl]="form">
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
<mat-datepicker #date></mat-datepicker>
<mat-error *ngIf="form.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-error>
</mat-form-field>
</div>

View File

@ -0,0 +1,25 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormControl } from '@angular/forms';
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
@Component({
selector: 'app-description-template-editor-default-value-component',
templateUrl: './description-template-editor-default-value.component.html',
styleUrls: ['./description-template-editor-default-value.component.scss']
})
export class DescriptionTemplateEditorDefaultValueComponent implements OnInit {
@Input() fieldType: DescriptionTemplateFieldType;
@Input() form: UntypedFormControl;
@Input() formArrayOptions: UntypedFormArray;
@Input() placeHolder: String;
// @Input() required: Boolean;
descriptionTemplateFieldTypeEnum = DescriptionTemplateFieldType;
constructor() { }
ngOnInit() {
}
}

View File

@ -0,0 +1,92 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-auto">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-TITLE' | translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string" [formControl]="form.get('data').get('label')">
</mat-form-field>
<h6 class="col-12" style="font-weight: bold">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-SOURCE-TITLE' | translate}}</h6>
<div class="col-12 d-flex align-items-center" style="margin-bottom: 1em;">
<button mat-raised-button type="button" (click)="addSource()" style="margin-right: 2em;">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-ADD_SOURCE' | translate}}
</button>
<div class="d-flex" *ngIf="form.get('data').errors?.emptyArray && form.get('data').touched">
<mat-icon class="text-danger" matTooltip="At least one source must be provided.">warning_amber</mat-icon>
<small class="text-danger">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-OTHER-SOURCES-REQUIRED'| translate}}</small>
</div>
</div>
</div>
<div *ngFor="let singleForm of multiForm.controls; let i = index" class="row">
<mat-form-field class="col-md-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-METHOD' | translate}}</mat-label>
<mat-select [formControl]="singleForm.get('method')">
<mat-option *ngFor="let method of htmlMethods | keyvalue" [value]="method.value">{{method.value}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="col-md-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-URL' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('url')">
<mat-error *ngIf="singleForm.get('url').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-3">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-OPTIONS-ROOT' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('optionsRoot')">
<mat-error *ngIf="singleForm.get('optionsRoot').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-3">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-LABEL' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('autoCompleteOptions').get('label')">
<mat-error *ngIf="singleForm.get('autoCompleteOptions').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-3">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-VALUE' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('autoCompleteOptions').get('value')">
</mat-form-field>
<mat-form-field class="col-md-3">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-SOURCE' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('autoCompleteOptions').get('source')">
<mat-error *ngIf="singleForm.get('autoCompleteOptions').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-checkbox class="col-12" [formControl]="singleForm.get('hasAuth')">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-HAS-AUTH' | translate}}</mat-checkbox>
<div *ngIf="singleForm.get('hasAuth').value === true" class="col-12">
<mat-form-field class="col-md-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-METHOD' | translate}}</mat-label>
<mat-select [formControl]="singleForm.get('auth').get('method')">
<mat-option *ngFor="let method of htmlMethods | keyvalue" [value]="method.value">{{method.value}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="col-md-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-URL' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('auth').get('url')">
<mat-error *ngIf="singleForm.get('auth').get('url').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-TYPE' | translate}}</mat-label>
<mat-select [formControl]="singleForm.get('auth').get('type')">
<mat-option *ngFor="let type of authTypes | keyvalue" [value]="type.value">{{type.value}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="col-md-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-OPTIONS-ROOT' | translate}}</mat-label>
<input matInput [formControl]="singleForm.get('auth').get('path')">
<mat-error *ngIf="singleForm.get('auth').get('path').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-md-12">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-BODY' | translate}}</mat-label>
<textarea matInput [formControl]="singleForm.get('auth').get('body')"></textarea>
<mat-error *ngIf="singleForm.get('auth').get('body').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<button mat-button type="button" (click)="removeSource(i)"><mat-icon>delete</mat-icon></button>
</div>

View File

@ -0,0 +1,26 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { DescriptionTemplateAutoCompleteFieldEditorModel } from '../../../description-template-editor.model';
@Component({
selector: 'app-description-template-editor-auto-complete-field-component',
styleUrls: ['./description-template-editor-auto-complete-field.component.scss'],
templateUrl: './description-template-editor-auto-complete-field.component.html'
})
export class DescriptionTemplateEditorAutoCompleteFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
multiForm: UntypedFormArray;
ngOnInit() {
this.multiForm = (<UntypedFormArray>this.form.get('data').get('autoCompleteSingleDataList'));
}
addSource() {
(<UntypedFormArray>this.multiForm).push(new DescriptionTemplateAutoCompleteFieldEditorModel().buildForm());
}
removeSource(index: number) {
(<UntypedFormArray>this.multiForm).removeAt(index);
}
}

View File

@ -0,0 +1,9 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-DATASET-IDENTIFIER-TITLE'
| translate}}</h5>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-DATASET-IDENTIFIER-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,24 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { DatasetIdentifierDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/dataset-identifier-data-editor-models';
@Component({
selector: 'app-dataset-profile-editor-dataset-identifier-field-component',
styleUrls: ['./dataset-profile-editor-dataset-identifier-field.component.scss'],
templateUrl: './dataset-profile-editor-dataset-identifier-field.component.html'
})
export class DatasetProfileEditorDatasetIdentifierFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: DatasetIdentifierDataEditorModel = new DatasetIdentifierDataEditorModel();
constructor(private router: Router) {}
ngOnInit() {
if(this.router.url.includes('new')){
this.form.patchValue({'rdaCommonStandard': 'dataset.dataset_id'});
}
if (!this.form.get('data')) { this.form.addControl('data', this.data.buildForm()); }
}
}

View File

@ -0,0 +1,13 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-auto">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-TITLE' | translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-DATASETS-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,19 @@
import { OnInit, Input, Component } from "@angular/core";
import { UntypedFormGroup } from "@angular/forms";
import { DatasetProfileInternalDmpEntitiesType } from "../../../../../../../core/common/enum/dataset-profile-internal-dmp-entities-type";
import { DatasetsAutoCompleteFieldDataEditorModel } from "../../../../admin/field-data/datasets-autocomplete-field-data-editor-mode";
@Component({
selector: 'app-dataset-profile-editor-datasets-autocomplete-field-component',
styleUrls: ['./dataset-profile-editor-datasets-autocomplete-field.component.scss'],
templateUrl: './dataset-profile-editor-datasets-autocomplete-field.component.html'
})
export class DatasetProfileEditorDatasetsAutoCompleteFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: DatasetsAutoCompleteFieldDataEditorModel = new DatasetsAutoCompleteFieldDataEditorModel();
ngOnInit() {
this.data.type = DatasetProfileInternalDmpEntitiesType.Datasets;
}
}

View File

@ -0,0 +1,13 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-auto">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-TITLE' | translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-DMPS-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,20 @@
import { OnInit, Input, Component } from "@angular/core";
import { UntypedFormGroup } from "@angular/forms";
import { DatasetProfileInternalDmpEntitiesType } from "../../../../../../../core/common/enum/dataset-profile-internal-dmp-entities-type";
import { DatasetsAutoCompleteFieldDataEditorModel } from "../../../../admin/field-data/datasets-autocomplete-field-data-editor-mode";
import { DmpsAutoCompleteFieldDataEditorModel } from "../../../../admin/field-data/dmps-autocomplete-field-data-editor-model";
@Component({
selector: 'app-dataset-profile-editor-dmps-autocomplete-field-component',
styleUrls: ['./dataset-profile-editor-dmps-autocomplete-field.component.scss'],
templateUrl: './dataset-profile-editor-dmps-autocomplete-field.component.html'
})
export class DatasetProfileEditorDmpsAutoCompleteFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: DmpsAutoCompleteFieldDataEditorModel = new DatasetsAutoCompleteFieldDataEditorModel();
ngOnInit() {
this.data.type = DatasetProfileInternalDmpEntitiesType.Dmps;
}
}

View File

@ -0,0 +1,22 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-EXTERNAL-DATASETS-TITLE'
| translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-EXTERNAL-DATASETS-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
<mat-form-field class="col-6">
<mat-label>
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.EXTERNAL-DATASET-TYPE-NAME' | translate}}
</mat-label>
<mat-select [formControl]="form.get('data').get('type')">
<mat-option *ngFor="let type of externalDatasetTypes" [value]="type.value">{{type.label | translate}}</mat-option>
</mat-select>
</mat-form-field>
</div>

View File

@ -0,0 +1,41 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { DatePickerDataEditorModel } from '../../../../admin/field-data/date-picker-data-editor-models';
import { ExternalDatasetsDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/external-datasets-data-editor-models';
import { ExternalDatasetTypeEnum } from '@app/core/common/enum/external-dataset-type-enum';
@Component({
selector: 'app-dataset-profile-editor-external-datasets-field-component',
styleUrls: ['./dataset-profile-editor-external-datasets-field.component.scss'],
templateUrl: './dataset-profile-editor-external-datasets-field.component.html'
})
export class DatasetProfileEditorExternalDatasetsFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: ExternalDatasetsDataEditorModel = new ExternalDatasetsDataEditorModel();
externalDatasetTypes = [
... Object.keys(ExternalDatasetTypeEnum).map(key=>{
return {
label: this.parseExtrernalDatasetTypeKey(key),
value: ExternalDatasetTypeEnum[key]
};
})
];
ngOnInit() {
if (!this.form.get('data')) { this.form.addControl('data', this.data.buildForm()); }
}
parseExtrernalDatasetTypeKey(key: string): string{
if(ExternalDatasetTypeEnum[key] === ExternalDatasetTypeEnum.ProducedDataset){
return 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.EXTERNAL-DATASET-TYPES.PRODUCED';
}
if(ExternalDatasetTypeEnum[key] === ExternalDatasetTypeEnum.ReusedDataset){
return 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.EXTERNAL-DATASET-TYPES.REUSED';
}
if(ExternalDatasetTypeEnum[key] === ExternalDatasetTypeEnum.Other){
return 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.EXTERNAL-DATASET-TYPES.OTHER';
}
return key;
}
}

View File

@ -0,0 +1,12 @@
<div class="row">
<mat-form-field class="col-12">
<mat-select placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-INTERNAL-DMP-ENTITIES-TYPE' | translate}}" [formControl]="this.form.get('data').get('type')">
<mat-option [value]="options.Researchers">{{enumUtils.toDatasetProfileInternalDmpEntitiesTypeString(options.Researchers)}}</mat-option>
<mat-option [value]="options.Datasets">{{enumUtils.toDatasetProfileInternalDmpEntitiesTypeString(options.Datasets)}}</mat-option>
<mat-option [value]="options.Dmps">{{enumUtils.toDatasetProfileInternalDmpEntitiesTypeString(options.Dmps)}}</mat-option>
</mat-select>
</mat-form-field>
<app-dataset-profile-editor-researchers-auto-complete-field-component *ngIf="this.form.get('data').get('type').value === options.Researchers" class="col-12" [form]="form"></app-dataset-profile-editor-researchers-auto-complete-field-component>
<app-dataset-profile-editor-datasets-autocomplete-field-component *ngIf="this.form.get('data').get('type').value === options.Datasets" class="col-12" [form]="form"></app-dataset-profile-editor-datasets-autocomplete-field-component>
<app-dataset-profile-editor-dmps-autocomplete-field-component *ngIf="this.form.get('data').get('type').value === options.Dmps" class="col-12" [form]="form"></app-dataset-profile-editor-dmps-autocomplete-field-component>
</div>

View File

@ -0,0 +1,44 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { DatasetProfileInternalDmpEntitiesType } from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { DatasetsAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/datasets-autocomplete-field-data-editor-mode';
import { DmpsAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/dmps-autocomplete-field-data-editor-model';
import { ResearchersAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/researchers-auto-complete-field-data-editor-model';
import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-dataset-profile-internal-dmp-entities-field-component',
styleUrls: ['./dataset-profile-editor-internal-dmp-entities-field.component.scss'],
templateUrl: './dataset-profile-editor-internal-dmp-entities-field.component.html'
})
export class DatasetProfileEditorInternalDmpEntitiesFieldComponent extends BaseComponent implements OnInit {
@Input() form: UntypedFormGroup;
options = DatasetProfileInternalDmpEntitiesType;
constructor(
public enumUtils: EnumUtils
) { super() }
ngOnInit() {
this.setupListeners();
}
setupListeners() {
this.form.get('data').get('type').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => {
if (this.form.get('data')) { this.form.removeControl('data'); }
if (x === DatasetProfileInternalDmpEntitiesType.Researchers) {
this.form.addControl('data', new ResearchersAutoCompleteFieldDataEditorModel().buildForm());
} else if (x === DatasetProfileInternalDmpEntitiesType.Datasets) {
this.form.addControl('data', new DatasetsAutoCompleteFieldDataEditorModel().buildForm());
}
else if (x === DatasetProfileInternalDmpEntitiesType.Dmps) {
this.form.addControl('data', new DmpsAutoCompleteFieldDataEditorModel().buildForm());
}
this.setupListeners();
})
}
}

View File

@ -0,0 +1,10 @@
<div class="row" *ngIf="form.get('data')">
<!-- <h5 style="font-weight: bold" class="col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-LICENSES-TITLE' | translate}}</h5> -->
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-LABEL' | translate}}</mat-label>
<input matInput type="string" [formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,15 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
@Component({
selector: 'app-description-template-editor-multiplicity-field-component',
styleUrls: ['./description-template-editor-multiplicity-field.component.scss'],
templateUrl: './description-template-editor-multiplicity-field.component.html'
})
export class DescriptionTemplateEditorMultiplicityFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
ngOnInit() {
}
}

View File

@ -0,0 +1,9 @@
<div class="row" *ngIf="form.get('data')">
<!-- <h5 style="font-weight: bold" class="col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-FREE-TEXT-TITLE' | translate}}</h5> -->
<mat-form-field class="col-12">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-LABEL' | translate}}</mat-label>
<input matInput type="string" [formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,15 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
@Component({
selector: 'app-description-template-editor-placeholder-field-component',
styleUrls: ['./description-template-editor-placeholder-field.component.scss'],
templateUrl: './description-template-editor-placeholder-field.component.html'
})
export class DescriptionTemplateEditorPlaceholderFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
ngOnInit() {
}
}

View File

@ -0,0 +1,41 @@
<div class="row" *ngIf="form.get('data')">
<div class="col-12">
<h5 style="font-weight: bold; display: inline-block; margin-right: 2em;">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-TITLE'
| translate}}</h5>
<ng-container *ngIf="form.get('data').errors?.emptyArray && form.get('data').touched">
<mat-icon class="text-danger translateY-3">warning_amber</mat-icon>
<small class="text-danger">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-RADIO-AT-LEAST-ONE-REQUIRED'| translate}}</small>
</ng-container>
</div>
<!-- <mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field> -->
<div class="col-12">
<div *ngFor="let option of form.get('data').get('options')['controls'] index as i" class="row">
<mat-form-field class="col">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-LABEL' | translate}}</mat-label>
<input matInput type="string"
[formControl]="this.form.get('data').get('options').get(''+i).get('label')">
</mat-form-field>
<mat-form-field class="col">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RADIO-BOX-VALUE' | translate}}</mat-label>
<input matInput type="string"
[formControl]="this.form.get('data').get('options').get(''+i).get('value')">
</mat-form-field>
<button mat-icon-button class="col-auto" (click)="deleteRow(i)" type="button"
[disabled]="this.form.disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<div class="col-auto">
<button mat-icon-button (click)="addNewRow()" type="button">
<mat-icon>add</mat-icon>
</button>
</div>
</div>

View File

@ -0,0 +1,29 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { FieldDataOptionEditorModel } from '../../../../admin/field-data/field-data-option-editor-model';
import { RadioBoxFieldDataEditorModel } from '../../../../admin/field-data/radio-box-field-data-editor-model';
@Component({
selector: 'app-dataset-profile-editor-radio-box-field-component',
styleUrls: ['./dataset-profile-editor-radio-box-field.component.scss'],
templateUrl: './dataset-profile-editor-radio-box-field.component.html'
})
export class DatasetProfileEditorRadioBoxFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: RadioBoxFieldDataEditorModel = new RadioBoxFieldDataEditorModel();
ngOnInit() {
if (!this.form.get('data')) { this.form.addControl('data', this.data.buildForm()); }
}
addNewRow() {
const radioListOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
if (!this.form.get('data').get('options')) { (<UntypedFormGroup>this.form.get('data')).addControl('options', new UntypedFormBuilder().array([])); }
(<UntypedFormArray>this.form.get('data').get('options')).push(radioListOptions.buildForm());
}
deleteRow(intex: number) {
if (this.form.get('data').get('options')) { (<UntypedFormArray>this.form.get('data').get('options')).removeAt(intex); }
}
}

View File

@ -0,0 +1,13 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-auto">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-TITLE' | translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RESEARCHERS-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,19 @@
import { ResearchersAutoCompleteFieldDataEditorModel } from "../../../../admin/field-data/researchers-auto-complete-field-data-editor-model";
import { UntypedFormGroup } from "@angular/forms";
import { Input, Component, OnInit } from "@angular/core";
import { DatasetProfileInternalDmpEntitiesType } from "../../../../../../../core/common/enum/dataset-profile-internal-dmp-entities-type";
@Component({
selector: 'app-dataset-profile-editor-researchers-auto-complete-field-component',
styleUrls: ['./dataset-profile-editor-researchers-auto-complete-field.component.scss'],
templateUrl: './dataset-profile-editor-researchers-auto-complete-field.component.html'
})
export class DatasetProfileEditorResearchersAutoCompleteFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: ResearchersAutoCompleteFieldDataEditorModel = new ResearchersAutoCompleteFieldDataEditorModel();
ngOnInit() {
this.data.type = DatasetProfileInternalDmpEntitiesType.Researchers;
}
}

View File

@ -0,0 +1,12 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RESEARCHERS-TITLE'
| translate}}</h5>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiAutoComplete')">
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-AUTOCOMPLETE' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-RESEARCHERS-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,30 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { DatePickerDataEditorModel } from '../../../../admin/field-data/date-picker-data-editor-models';
import { ExternalDatasetsDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/external-datasets-data-editor-models';
import { DataRepositoriesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/data-repositories-data-editor-models';
import { RegistriesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/registries-data-editor-models';
import { ServicesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/services-data-editor-models';
import { TagsDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/tags-data-editor-models';
import { ResearchersDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/researchers-data-editor-models';
import { Router } from '@angular/router';
@Component({
selector: 'app-dataset-profile-editor-researchers-field-component',
styleUrls: ['./dataset-profile-editor-researchers-field.component.scss'],
templateUrl: './dataset-profile-editor-researchers-field.component.html'
})
export class DatasetProfileEditorResearchersFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: ResearchersDataEditorModel = new ResearchersDataEditorModel();
constructor(private router: Router) {}
ngOnInit() {
if(this.router.url.includes('new')){
this.form.patchValue({'rdaCommonStandard': 'dmp.contributor'});
}
if (!this.form.get('data')) { this.form.addControl('data', this.data.buildForm()); }
}
}

View File

@ -0,0 +1,9 @@
<div class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-12">{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-TAGS-TITLE'
| translate}}</h5>
<mat-form-field class="col-12">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-TAGS-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string"
[formControl]="form.get('data').get('label')">
</mat-form-field>
</div>

View File

@ -0,0 +1,29 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { DatePickerDataEditorModel } from '../../../../admin/field-data/date-picker-data-editor-models';
import { ExternalDatasetsDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/external-datasets-data-editor-models';
import { DataRepositoriesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/data-repositories-data-editor-models';
import { RegistriesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/registries-data-editor-models';
import { ServicesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/services-data-editor-models';
import { TagsDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/tags-data-editor-models';
import { Router } from '@angular/router';
@Component({
selector: 'app-dataset-profile-editor-tags-field-component',
styleUrls: ['./dataset-profile-editor-tags-field.component.scss'],
templateUrl: './dataset-profile-editor-tags-field.component.html'
})
export class DatasetProfileEditorTagsFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
private data: TagsDataEditorModel = new TagsDataEditorModel();
constructor(private router: Router) {}
ngOnInit() {
if(this.router.url.includes('new')){
this.form.patchValue({'rdaCommonStandard': 'dataset.keyword'});
}
if (!this.form.get('data')) { this.form.addControl('data', this.data.buildForm()); }
}
}

View File

@ -0,0 +1,55 @@
<!--[formGroup]="form"-->
<form class="row" *ngIf="form.get('data')">
<h5 style="font-weight: bold" class="col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-TITLE' | translate}}</h5>
<mat-form-field class="col-12">
<mat-label>
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-PLACEHOLDER' | translate}}
</mat-label>
<input matInput type="string" [formControl]="form.get('data').get('label')">
</mat-form-field>
<mat-form-field class="col-12">
<mat-label>
{{ "DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-MAX-FILE-SIZE" |
translate: { maxfilesize: getConfiguration().maxFileSizeInMB.toString() } }}
</mat-label>
<input matInput type="number" min="1" [max]="getConfiguration().maxFileSizeInMB" [formControl]="form.get('data').get('maxFileSizeInMB')">
</mat-form-field>
<mat-form-field class="col-12">
<mat-label>
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-SELECT-FILETYPE' | translate}}
</mat-label>
<mat-select multiple [formControl]="typesFormControl">
<mat-option *ngFor="let type of types; let i=index" [value]="type.value" (click)="selectedType(type)" [disabled]="form.get('data').get('types').disabled">
{{type.label}}
</mat-option>
</mat-select>
</mat-form-field>
<div class="col-12">
<div>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-CUSTOM-FILETYPE' | translate}}</div>
<ng-container *ngFor="let type of form.get('data').get('types')['controls'] index as i">
<div *ngIf="isCustomType(type.value.value)" class="row">
<mat-form-field class="col">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-LABEL' | translate}}</mat-label>
<input matInput type="string" [formControl]="this.form.get('data').get('types').get(''+i).get('label')">
</mat-form-field>
<mat-form-field class="col">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-UPLOAD-VALUE' | translate}}</mat-label>
<input matInput type="string" [formControl]="this.form.get('data').get('types').get(''+i).get('value')">
</mat-form-field>
<button mat-icon-button class="col-auto" (click)="deleteRow(i)" type="button" [disabled]="form.get('data').get('types').disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
</ng-container>
</div>
<div class="col-auto">
<button mat-icon-button (click)="addNewRow()" type="button" [disabled]="form.get('data').get('types').disabled">
<mat-icon>add</mat-icon>
</button>
</div>
</form>

View File

@ -0,0 +1,96 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { DescriptionTemplateUploadOption } from '@app/core/model/description-template/description-template';
import { ConfigurationService } from "@app/core/services/configuration/configuration.service";
@Component({
selector: 'app-description-template-editor-upload-field-component',
styleUrls: ['./description-template-editor-upload-field.component.scss'],
templateUrl: './description-template-editor-upload-field.component.html'
})
export class DescriptionTemplateEditorUploadFieldComponent implements OnInit {
types: Array<DescriptionTemplateUploadOption> = [
// images
{ label: "Animated Portable Network Graphics (APNG)", value: "image/apng" },
{ label: "AV1 Image File Format (AVIF)", value: "image/avif" },
{ label: "Graphics Interchange Format (GIF)", value: "image/gif" },
{ label: "Joint Photographic Expert Group image (JPEG)", value: "image/jpeg" },
{ label: "Portable Network Graphics (PNG)", value: "image/png" },
{ label: "Scalable Vector Graphics (SVG)", value: "image/svg+xml" },
{ label: "Web Picture format (WEBP)", value: "image/webp" },
{ label: "Tagged Image File Format (TIFF)", value: "image/tiff" },
// office word
{ label: "Microsoft Word 97-2003", value: "application/msword" }, // .doc, .dot
{ label: "Microsoft Word 2007-2013", value: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, // .docx
{ label: "OpenDocument Text", value: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, // .odt
// office excel
{ label: "Microsoft Excel 97-2003", value: "application/vnd.ms-excel" }, // .xls, .xlt, .xla
{ label: "Microsoft Excel 2007-2013", value: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, // .xlsx
{ label: "OpenDocument Spreadsheet", value: "application/vnd.oasis.opendocument.spreadsheet" }, // .ods
// office powerpoint
{ label: "Microsoft PowerPoint 97-2003", value: "application/vnd.ms-powerpoint" }, // .ppt, .pot, .pps, .ppa
{ label: "Microsoft PowerPoint 2007-2013", value: "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, // .pptx
{ label: "OpenDocument Presentation", value: "application/vnd.oasis.opendocument.presentation" }, // .odp
{ label: "Comma-Seperated Values (CSV)", value: "text/csv" },
{ label: "Adobe Portable Document Format (PDF)", value: "application/pdf" }
];
selected: string[] = [];
public typesFormControl = new UntypedFormControl();
@Input() form: UntypedFormGroup;
constructor(private configurationService: ConfigurationService) { }
ngOnInit() {
let typeValues: string[] = this.types.map(type => type.value);
if (this.form.get('data') && this.form.get('data').get('types')) {
for (let type of this.form.get('data').get('types').value) {
if (typeValues.indexOf(type.value) != -1) {
this.selected.push(type.value);
}
}
this.typesFormControl.setValue(this.selected);
}
}
selectedType(type: DescriptionTemplateUploadOption) {
if (!this.form.get('data').get('types').disabled) {
let index = this.selected.indexOf(type.value);
if (index == -1) {
this.selected.push(type.value);
this.addNewRow(type);
} else {
this.selected.splice(index, 1);
this.deleteRow(index);
}
}
}
isCustomType(value: string) {
return this.selected.indexOf(value) == -1;
}
addNewRow(type: DescriptionTemplateUploadOption = null) {
const typeListOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
if (type != null) {
typeListOptions.fromModel(type);
}
(<UntypedFormGroup>this.form.get('data')).addControl('types', new UntypedFormBuilder().array([]));
(<UntypedFormArray>this.form.get('data').get('types')).push(typeListOptions.buildForm());
}
deleteRow(index: number) {
if (this.form.get('data').get('types')) { (<UntypedFormArray>this.form.get('data').get('types')).removeAt(index); }
}
public getConfiguration() {
return this.configurationService;
}
}

View File

@ -0,0 +1,38 @@
<div class="row" *ngIf="form.get('data')">
<div class="col-12">
<h5 style="font-weight: bold; display: inline-block; margin-right: 2em;">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-WORD-LIST-TITLE' | translate}}</h5>
<ng-container *ngIf="form.get('data').errors?.emptyArray && form.get('data').touched">
<mat-icon class="text-danger translateY-3">warning_amber</mat-icon>
<small class="text-danger">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-SELECT-AT-LEAST-ONE-REQUIRED' |translate}}</small>
</ng-container>
</div>
<mat-checkbox class="col-auto" [formControl]="this.form.get('data').get('multiList')">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-MULTIPLE-WORDLIST' | translate}}
</mat-checkbox>
<mat-form-field class="col-12">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-WORD-LIST-PLACEHOLDER' | translate}}</mat-label>
<input matInput type="string" [formControl]="form.get('data').get('label')">
</mat-form-field>
<div class="col-12">
<div *ngFor="let option of form.get('data').get('options')['controls'] index as i" class="row">
<mat-form-field class="col">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-WORD-LIST-LABEL' | translate}}</mat-label>
<input matInput type="text" [formControl]="form.get('data').get('options').get(''+i).get('label')">
</mat-form-field>
<mat-form-field class="col">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-WORD-LIST-VALUE' | translate}}</mat-label>
<input matInput [formControl]="form.get('data').get('options').get(''+i).get('value')">
</mat-form-field>
<button mat-icon-button class="col-auto" (click)="deleteRow(i)" type="button" [disabled]="this.form.disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
<div class="col-auto"><button mat-icon-button (click)="addNewRow()">
<mat-icon>add</mat-icon>
</button></div>
</div>

View File

@ -0,0 +1,25 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { DescriptionTemplateComboBoxOptionEditorModel } from '../../../description-template-editor.model';
@Component({
selector: 'app-description-template-editor-word-list-field-component',
styleUrls: ['./description-template-editor-word-list-field.component.scss'],
templateUrl: './description-template-editor-word-list-field.component.html'
})
export class DescriptionTemplateEditorWordListFieldComponent implements OnInit {
@Input() form: UntypedFormGroup;
ngOnInit() {
}
addNewRow() {
const wordListOptions: DescriptionTemplateComboBoxOptionEditorModel = new DescriptionTemplateComboBoxOptionEditorModel();
(<UntypedFormArray>this.form.get('data').get('options')).push(wordListOptions.buildForm());
}
deleteRow(intex: number) {
if (this.form.get('data').get('options')) { (<UntypedFormArray>this.form.get('data').get('options')).removeAt(intex); }
}
}

View File

@ -0,0 +1,232 @@
<ng-container *ngIf="expandView">
<!-- ACTIONS PER FIELD -->
<div class="row justify-content-end mb-1 mr-2">
<ng-content></ng-content>
<div class="col-auto">
<ul class="list-unstyled list-inline d-flex align-items-center">
<li class="list-inline-item">
<mat-slide-toggle class="field-toggler" [checked]="isRequired" (change)="toggleRequired($event)" labelPosition="before" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.MAKE-IT-REQUIRED' | translate" [disabled]="!fieldType">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}
</mat-slide-toggle>
</li>
<li *ngIf="fieldType === descriptionTemplateFieldTypeEnum.FREE_TEXT" class="list-inline-item">
<mat-slide-toggle class="field-toggler" [checked]="isURL" (change)="toggleURL($event)" labelPosition="before" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.MAKE-IT-REQUIRED' | translate" [disabled]="!fieldType">
{{'GENERAL.VALIDATION.URL.LABEL' | translate}}
</mat-slide-toggle>
</li>
<!-- <li class="list-inline-item" *ngIf="!viewOnly && fieldType && canApplyVisibility">
<mat-icon style="cursor: pointer;" (click)="addNewRule()" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.ADD-VISIBILITY-RULE' | translate">visibility</mat-icon>
</li> -->
<li class="text-muted" *ngIf="!viewOnly && fieldType && canBeDeleted">
<mat-icon style="cursor: pointer; opacity: 0.7; transform:translateY(2px) translateX(10px) ;" (click)="onDelete()" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.DELETE-INPUT' | translate">delete</mat-icon>
</li>
</ul>
</div>
</div>
<div class="row">
<mat-form-field class="col-6">
<!-- NEW VERSION -->
<mat-select #select placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.VIEW-STYLE' | translate}}" [(ngModel)]="fieldType" (selectionChange)="onInputTypeChange()" [disabled]="viewOnly" [errorStateMatcher]="this">
<mat-select-trigger>
{{enumUtils.toDescriptionTemplateFieldTypeString(select.value)}}
</mat-select-trigger>
<mat-option [value]="descriptionTemplateFieldTypeEnum.TEXT_AREA">
<img src="/assets/images/editor/icons/text_area.svg" class="input_icon" alt="TextArea icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.TEXT_AREA)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA">
<img src="/assets/images/editor/icons/text_area.svg" class="input_icon" alt="RichTextArea icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.FREE_TEXT">
<img src="/assets/images/editor/icons/free_text.svg" class="input_icon" alt="FreeText icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.FREE_TEXT)}}
</mat-option>
<mat-divider></mat-divider>
<mat-option [value]="descriptionTemplateFieldTypeEnum.UPLOAD">
<!-- <img src="/assets/images/editor/icons/text_area.svg" class="input_icon" alt="Upload icon">-->
<mat-icon class="input_icon" style="font-size: 14px; color: #129d99; display: inline-flex; align-items: center">upload</mat-icon>
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.UPLOAD)}}
</mat-option>
<mat-divider></mat-divider>
<mat-option [value]="descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION">
<img src="/assets/images/editor/icons/boolean.svg" class="input_icon" alt="Boolean icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.RADIO_BOX">
<img src="/assets/images/editor/icons/radio_box.svg" class="input_icon" alt="RadioBox icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.RADIO_BOX)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.COMBO_BOX">
<span class="input_icon">
<img src="/assets/images/editor/icons/select.svg" style="padding-right: 7px;" alt="Select icon">
</span>
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.COMBO_BOX)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.CHECK_BOX">
<img src="/assets/images/editor/icons/checkbox.svg" class="input_icon" alt="CheckBox icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.CHECK_BOX)}}
</mat-option>
<!-- TODO -->
<mat-divider></mat-divider>
<mat-option [value]="descriptionTemplateFieldTypeEnum.DATE_PICKER">
<img src="/assets/images/editor/icons/date_picker.svg" class="input_icon" alt="DatePicker icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.DATE_PICKER)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.CURRENCY">
<img src="/assets/images/editor/icons/currency.svg" class="input_icon" alt="Current icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.CURRENCY)}}
</mat-option>
<mat-divider></mat-divider>
<!-- APIS -->
<mat-optgroup label="APIs">
<mat-option [value]="descriptionTemplateFieldTypeEnum.REGISTRIES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Registries icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.REGISTRIES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.SERVICES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Services icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.SERVICES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.RESEARCHERS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Researchers icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.RESEARCHERS)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.ORGANIZATIONS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Organizations icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.ORGANIZATIONS)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="ExternalDatasets icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.DATA_REPOSITORIES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="DataRepositories icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.DATA_REPOSITORIES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.PUB_REPOSITORIES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="PubRepositories icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.PUB_REPOSITORIES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.JOURNAL_REPOSITORIES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Journal Repositories icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.JOURNAL_REPOSITORIES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.TAXONOMIES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Taxonomies icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.TAXONOMIES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.LICENSES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="licenses icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.LICENSES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.PUBLICATIONS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Publications icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.PUBLICATIONS)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.AUTO_COMPLETE">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Other icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.AUTO_COMPLETE)}}
</mat-option>
</mat-optgroup>
<!-- TODO -->
<mat-divider></mat-divider>
<mat-optgroup label="Argos Entities">
<mat-option [value]="descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="InternalDmpEntities icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.TAGS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Tags icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.TAGS)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.DATASET_IDENTIFIER">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="DatasetIdentifier icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.DATASET_IDENTIFIER)}}
</mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.VALIDATION">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Validation icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.VALIDATION)}}
</mat-option>
</mat-optgroup>
</mat-select>
<!-- <mat-error *ngIf="this.form.get('data').get('fieldType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> -->
<mat-error>{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<!-- <mat-error *ngIf="this.form.hasError('inputTypeNotValid')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> -->
</mat-form-field>
<mat-form-field class="col-6">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}}</mat-label>
<app-multiple-auto-complete placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}}" [hidePlaceholder]="true" required='false' [separatorKeysCodes]="separatorKeysCodes" [formControl]="this.form.get('schematics')" [configuration]="semanticsAutoCompleteConfiguration">
</app-multiple-auto-complete>
</mat-form-field>
<mat-checkbox [formControl]="this.form.get('includeInExport')" class="col-6" [disabled]="viewOnly">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXPORT' | translate}}</mat-checkbox>
<!-- Default Value -->
<app-description-template-editor-default-value-component *ngIf="form.get('data')?.get('fieldType')?.value" class="col-6" [fieldType]="form.get('data').get('fieldType').value" [form]="this.form.get('defaultValue')" [formArrayOptions]="form.get('data')?.get('options')" [comboBoxType]="this.form.get('data')?.get('type')?.value" [internalDmpEntitiesType]="this.form.get('data')?.get('type')?.value" placeHolder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.DEFAULT-VALUE' | translate}}">
</app-description-template-editor-default-value-component>
<div class="col-12"></div>
<div class="col-auto mb-4 mt-2">
<div class="add-visibility-button" (click)="addNewRule()" *ngIf="!viewOnly && fieldType && canApplyVisibility">
<img src="/assets/images/editor/icons/add_visibility_rule_2.svg" class="visibility-icon" alt="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.ADD-VISIBILITY-RULE' | translate">
<span>{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FIELD.ADD-VISIBILITY-RULE' | translate}}</span>
</div>
</div>
</div>
<div class="row" *ngIf="this.form.get('data')?.get('fieldType')?.value">
<ng-container *ngIf="form.get('visibilityRules')?.value.length">
<h4 class="col-12" style="font-weight: bold">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.RULES-TITLE' | translate}}
</h4>
<app-description-template-editor-visibility-rule-component class="col-12" [form]="form.get('visibilityRules')" [viewStyleForCheck]="form.get('data').get('fieldType').value" [formArrayOptionsForCheck]="this.form.get('data')?.get('options')" [viewOnly]="viewOnly" [formControlForCheck]="form"></app-description-template-editor-visibility-rule-component>
<!-- <div class="col-12" *ngIf="!viewOnly">
<button mat-button class="full-width" (click)="addNewRule()" [disabled]="!form.get('data').get('fieldType').value">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.ACTIONS.ADD-RULE' | translate}}</button>
</div> -->
</ng-container>
</div>
<div class="row" [ngSwitch]="form.get('data')?.get('fieldType')?.value " *ngIf="expandView">
<app-description-template-editor-auto-complete-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.AUTO_COMPLETE" class="col-12" [form]="form"></app-description-template-editor-auto-complete-field-component>
<app-description-template-editor-word-list-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.WORD_LIST" class="col-12" [form]="form"></app-description-template-editor-word-list-field-component>
<app-description-template-editor-radio-box-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.RADIO_BOX" class="col-12" [form]="form"></app-description-template-editor-radio-box-field-component>
<app-description-template-editor-upload-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.UPLOAD" class="col-12" [form]="form"></app-description-template-editor-upload-field-component>
<!-- <app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.BOOLEAN_DECISION" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component> -->
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.CHECK_BOX" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.FREE_TEXT" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.TEXT_AREA" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.DATE_PICKER" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.TAGS" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.DATASET_IDENTIFIER" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.CURRENCY" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-placeholder-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.VALIDATION" class="col-12" [form]="form"></app-description-template-editor-placeholder-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES_RESEARCHERS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES_DMPS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.INTERNAL_DMP_ENTRIES_DATASETS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.EXTERNAL_DATASETS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.DATA_REPOSITORIES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.JOURNAL_REPOSITORIES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.PUB_REPOSITORIES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.LICENSES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.TAXONOMIES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.PUBLICATIONS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.REGISTRIES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.SERVICES" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.RESEARCHERS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
<app-description-template-editor-multiplicity-field-component *ngSwitchCase="descriptionTemplateFieldTypeEnum.ORGANIZATIONS" class="col-12" [form]="form"></app-description-template-editor-multiplicity-field-component>
</div>
</ng-container>

View File

@ -0,0 +1,66 @@
.full-width {
width: 100%;
}
.preview-box{
padding: 1em;
border: 1px solid #e8dcdc;
border-radius: 0.3em;
}
mat-radio-button{
padding-right: 1em;
}
li.list-inline-item{
color: var(--primary-color);
.mat-icon{
vertical-align: bottom;
}
}
:host ::ng-deep .field-toggler
{
.mat-slide-toggle-content{
font-size: 0.8em;
color: #212121;
}
.mat-slide-toggle.mat-checked .mat-slide-toggle-thumb {
background-color:var(--primary-color) ;
}
.mat-slide-toggle.mat-checked .mat-slide-toggle-bar {
background-color:rgba(0,178,159,0.34);
}
.mat-slide-toggle-bar{
height: 11.93px;
width: 26.42px;
}
.mat-slide-toggle-thumb-container{
top: -3px;
}
.mat-slide-toggle-thumb{
width: 16px;
height: 16px;
}
}
.input_icon{
width: 14px;
margin-right: 0.5em;
}
.visibility-icon{
width: 20px;
margin-right: 0.5em;
}
.add-visibility-button{
// display: flex;
// align-items: center;
width: auto;
cursor: pointer;
span{
font-weight: 400;
font-size: 0.8em;
}
}

View File

@ -0,0 +1,467 @@
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormGroupDirective, NgForm, UntypedFormArray, UntypedFormControl, UntypedFormGroup, } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
import { ValidationType } from '@app/core/common/enum/validation-type';
import {
DescriptionTemplateAutoCompleteData,
DescriptionTemplateBooleanDecisionData,
DescriptionTemplateCheckBoxData,
DescriptionTemplateComboBoxOption,
DescriptionTemplateCurrencyData,
DescriptionTemplateDataRepositoryData,
DescriptionTemplateDatasetIdentifierData,
DescriptionTemplateDatePickerData,
DescriptionTemplateDmpAutoCompleteData,
DescriptionTemplateExternalDatasetData,
DescriptionTemplateFreeTextData,
DescriptionTemplateLicenseData,
DescriptionTemplateOrganizationData,
DescriptionTemplatePublicationData,
DescriptionTemplateRadioBoxData,
DescriptionTemplateRegistryData,
DescriptionTemplateResearcherAutoCompleteData,
DescriptionTemplateRichTextAreaData,
DescriptionTemplateServiceData,
DescriptionTemplateTagData,
DescriptionTemplateTaxonomyData,
DescriptionTemplateTextAreaData,
DescriptionTemplateUploadData,
DescriptionTemplateValidationData,
DescriptionTemplateWordListData
} from '@app/core/model/description-template/description-template';
import { DescriptionTemplateFieldPersist } from '@app/core/model/description-template/description-template-persist';
import { ConfigurationService } from "@app/core/services/configuration/configuration.service";
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateRuleEditorModel } from '../../description-template-editor.model';
@Component({
selector: 'app-description-template-editor-field-component',
templateUrl: './description-template-editor-field.component.html',
styleUrls: ['./description-template-editor-field.component.scss']
})
export class DescriptionTemplateEditorFieldComponent extends BaseComponent implements OnInit, ErrorStateMatcher {
@Input() viewOnly: boolean;
@Input() form: UntypedFormGroup;
@Input() showOrdinal = true;
@Input() indexPath: string;
validationTypeEnum = ValidationType;
// isFieldMultiplicityEnabled = false;
fieldType: DescriptionTemplateFieldType;
descriptionTemplateFieldTypeEnum = DescriptionTemplateFieldType;
@Input() expandView: boolean = true;
@Input() canBeDeleted: boolean = true;
@Output() delete = new EventEmitter<void>();
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
semanticsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterSemantics.bind(this),
initialItems: (excludedItems: any[]) => this.filterSemantics('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x !== resultItem)))),
displayFn: (item) => item,
titleFn: (item) => item
}
filterSemantics(value: string): Observable<String[]> {
// return this.descriptionTemplateService.searchSemantics(value);
return of([]);
}
constructor(
public enumUtils: EnumUtils,
public descriptionTemplateService: DescriptionTemplateService,
private dialog: MatDialog,
private configurationService: ConfigurationService
) {
super();
}
isErrorState(control: UntypedFormControl, form: FormGroupDirective | NgForm): boolean {
if (this.form.get('data').untouched) return false;
return this.form.get('data').invalid;
}
ngOnInit() {
const fieldType = this.form.get('data').get('fieldType').value;
if (fieldType) {
this.fieldType = fieldType;
if (this.fieldType !== DescriptionTemplateFieldType.FREE_TEXT) {
this.setValidator(ValidationType.URL, false);
}
}
}
addNewRule() {
const rule: DescriptionTemplateRuleEditorModel = new DescriptionTemplateRuleEditorModel();
(<UntypedFormArray>this.form.get('visibilityRules')).push(rule.buildForm());
}
get canApplyVisibility(): boolean {
switch (this.fieldType) {
case DescriptionTemplateFieldType.TEXT_AREA:
case DescriptionTemplateFieldType.RICH_TEXT_AREA:
case DescriptionTemplateFieldType.UPLOAD:
case DescriptionTemplateFieldType.FREE_TEXT:
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
case DescriptionTemplateFieldType.RADIO_BOX:
case DescriptionTemplateFieldType.COMBO_BOX:
case DescriptionTemplateFieldType.CHECK_BOX:
case DescriptionTemplateFieldType.DATE_PICKER:
return true;
}
return false;
}
onInputTypeChange() {
const x = this.fieldType;
const field: DescriptionTemplateFieldPersist = this.form.getRawValue();
field.defaultValue = undefined;
if (!this.canApplyVisibility) {
field.visibilityRules = [];
}
switch (x) {
case DescriptionTemplateFieldType.BOOLEAN_DECISION: {
const data: DescriptionTemplateBooleanDecisionData = {
label: '',
fieldType: DescriptionTemplateFieldType.BOOLEAN_DECISION,
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.CHECK_BOX: {
const data: DescriptionTemplateCheckBoxData = {
label: '',
fieldType: DescriptionTemplateFieldType.CHECK_BOX,
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.COMBO_BOX: {
const firstOption = { label: '', value: '' } as DescriptionTemplateComboBoxOption;
const data: DescriptionTemplateWordListData = {
label: '',
multiList: false,
options: [firstOption],
fieldType: DescriptionTemplateFieldType.WORD_LIST
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.AUTO_COMPLETE: {
const data: DescriptionTemplateAutoCompleteData = {
autoCompleteSingleDataList: [],
multiAutoComplete: false,
label: '',
fieldType: DescriptionTemplateFieldType.AUTO_COMPLETE
}
field.data = data;
break;
} case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES: {
const data: DescriptionTemplateDmpAutoCompleteData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DMPS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.FREE_TEXT: {
const data: DescriptionTemplateFreeTextData = {
label: '',
fieldType: DescriptionTemplateFieldType.FREE_TEXT
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RADIO_BOX: {
const data: DescriptionTemplateRadioBoxData = {
label: '',
options: [],
fieldType: DescriptionTemplateFieldType.RADIO_BOX
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TEXT_AREA: {
const data: DescriptionTemplateTextAreaData = {
label: '',
fieldType: DescriptionTemplateFieldType.TEXT_AREA
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RICH_TEXT_AREA: {
const data: DescriptionTemplateRichTextAreaData = {
label: '',
fieldType: DescriptionTemplateFieldType.RICH_TEXT_AREA
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.UPLOAD: {
const data: DescriptionTemplateUploadData = {
label: '',
types: [],
maxFileSizeInMB: this.configurationService.maxFileSizeInMB,
fieldType: DescriptionTemplateFieldType.UPLOAD
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATE_PICKER: {
const data: DescriptionTemplateDatePickerData = {
label: '',
fieldType: DescriptionTemplateFieldType.DATE_PICKER
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.EXTERNAL_DATASETS: {
const data: DescriptionTemplateExternalDatasetData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.EXTERNAL_DATASETS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATA_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.PUB_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.JOURNAL_REPOSITORIES: {
const data: DescriptionTemplateDataRepositoryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.DATA_REPOSITORIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TAXONOMIES: {
const data: DescriptionTemplateTaxonomyData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.TAXONOMIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.LICENSES: {
const data: DescriptionTemplateLicenseData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.LICENSES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.PUBLICATIONS: {
const data: DescriptionTemplatePublicationData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.PUBLICATIONS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.REGISTRIES: {
const data: DescriptionTemplateRegistryData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.REGISTRIES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.SERVICES: {
const data: DescriptionTemplateServiceData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.SERVICES
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.TAGS: {
const data: DescriptionTemplateTagData = {
label: '',
fieldType: DescriptionTemplateFieldType.TAGS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.RESEARCHERS: {
const data: DescriptionTemplateResearcherAutoCompleteData = {
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_RESEARCHERS
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.ORGANIZATIONS: {
const data: DescriptionTemplateOrganizationData = {
// autoCompleteSingleDataList: [], //TODO maybe remove
label: '',
multiAutoComplete: false,
fieldType: DescriptionTemplateFieldType.ORGANIZATIONS
};
field.data = data;
break;
}
case DescriptionTemplateFieldType.DATASET_IDENTIFIER: {
const data: DescriptionTemplateDatasetIdentifierData = {
label: '',
fieldType: DescriptionTemplateFieldType.DATASET_IDENTIFIER
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.CURRENCY: {
const data: DescriptionTemplateCurrencyData = {
label: '',
fieldType: DescriptionTemplateFieldType.CURRENCY
}
field.data = data;
break;
}
case DescriptionTemplateFieldType.VALIDATION: {
const data: DescriptionTemplateValidationData = {
label: '',
fieldType: DescriptionTemplateFieldType.VALIDATION
}
field.data = data;
break;
}
}
const form = (new DescriptionTemplateFieldEditorModel).fromModel(field).buildForm();
const fields = this.form.parent as UntypedFormArray;
let index = -1;
fields.controls.forEach((control, i) => {
if (this.form.get('id').value === control.get('id').value) {
index = i
}
});
if (index >= 0) {
fields.removeAt(index);
fields.insert(index, form);
this.form = form;
}
// setTimeout(() => { //TODO
// this.showPreview = true;
// });
}
toggleRequired(event: MatSlideToggleChange) {
this.setValidator(ValidationType.Required, event.checked);
}
toggleURL(event: MatSlideToggleChange) {
this.setValidator(ValidationType.URL, event.checked);
}
private setValidator(validationType: ValidationType, add: boolean) {
let validationsControl = this.form.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
if (add) {
if (!validations.includes(validationType)) {
validations.push(validationType);
validationsControl.updateValueAndValidity();
}
} else {
validationsControl.setValue(validations.filter(validator => validator != validationType));
validationsControl.updateValueAndValidity();
}
this.form.markAsDirty();//deactivate guard
}
get isRequired() {
let validationsControl = this.form.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
return validations.includes(ValidationType.Required);
}
get isURL() {
let validationsControl = this.form.get('validations') as UntypedFormControl;
let validations: Array<ValidationType> = validationsControl.value;
return validations.includes(ValidationType.URL);
}
onDelete() {
this.delete.emit();
}
}

View File

@ -0,0 +1,29 @@
export enum ViewStyleType{
TextArea = "textarea",
RichTextArea = "richTextarea",
Upload = "upload",
Table = "table",
BooleanDecision = "booleanDecision",
CheckBox = "checkBox",
FreeText = "freetext",
RadioBox = "radiobox",
DatePicker = "datePicker",
InternalDmpEntities = "internalDmpEntities",
ExternalDatasets = "externalDatasets",
DataRepositories = "dataRepositories",
PubRepositories = "pubRepositories",
JournalRepositories = "journalRepositories",
Taxonomies = "taxonomies",
Licenses = "licenses",
Publications = "publications",
Registries = "registries",
Services = "services",
Tags = "tags",
Researchers = "researchers",
Organizations = "organizations",
DatasetIdentifier = "datasetIdentifier",
Currency = "currency",
Validation = 'validation',
Select ="selection",
Other ="other"
}

View File

@ -0,0 +1,3 @@
<app-dataset-description [form]="formGroup" [visibilityRules]="visibilityRules" *ngIf="formGroup">
</app-dataset-description>

View File

@ -0,0 +1,28 @@
import { Component, Input, OnInit} from '@angular/core';
import { Rule } from '@app/core/model/dataset-profile-definition/rule';
import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service';
@Component({
selector: 'app-final-preview-component',
templateUrl: './final-preview.component.html',
styleUrls: ['./final-preview.component.scss'],
providers:[VisibilityRulesService]
})
export class FinalPreviewComponent implements OnInit {
@Input() formGroup = null;
@Input() visibilityRules:Rule[] = [];
constructor(private visibilityRulesService: VisibilityRulesService){
}
ngOnInit(): void {
this.visibilityRulesService.buildVisibilityRules(this.visibilityRules, this.formGroup);
}
}

View File

@ -0,0 +1,13 @@
<mat-card *ngFor="let pageControl of form['controls']; let i=index;" class="page-card">
<mat-card-title class="page-card-title">{{'DATASET-PROFILE-EDITOR.STEPS.PAGES.PAGE-PREFIX' | translate}} {{i + 1}}</mat-card-title>
<div class="row">
<mat-form-field class="col">
<input matInput type="text" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.PAGES.PAGE-INPUT-TITLE' | translate}}"
[formControl]="pageControl.get('title')" required>
<mat-error *ngIf="pageControl.get('title').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<button mat-icon-button type="button" class="col-auto" (click)="removePage(i)" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
</mat-card>

View File

@ -0,0 +1,7 @@
.page-card {
margin-bottom: 1em;
.page-card-title {
text-align: center;
}
}

View File

@ -0,0 +1,17 @@
import { Component, Input } from '@angular/core';
import { UntypedFormArray } from '@angular/forms';
@Component({
selector: 'app-dataset-profile-editor-page-component',
templateUrl: './dataset-profile-editor-page.component.html',
styleUrls: ['./dataset-profile-editor-page.component.scss']
})
export class DatasetProfileEditorPageComponent {
@Input() form: UntypedFormArray;
@Input() viewOnly: boolean;
removePage(index) {
(<UntypedFormArray>this.form).removeAt(index);
}
}

View File

@ -0,0 +1,123 @@
<div id="topofcontainer"></div>
<div class="row" [id]="idprefix+form.get('id').value" *ngIf="form" [@fade-in-fast]>
<div class="col-12">
<div class="row fieldset">
<!-- SECTION INFO -->
<div class="col-9 p-0" style="margin-bottom:2em;">
<mat-card style="padding: 2em;">
<mat-card-content>
<app-description-template-editor-section-component [form]="form" [viewOnly]="viewOnly">
</app-description-template-editor-section-component>
</mat-card-content>
</mat-card>
<div class="row justify-content-center mt-4 mb-2">
<div class="col-auto add-question" (click)="addFieldSetAfter(-9999,0)" *ngIf="!viewOnly">
<img src="/assets/images/editor/icons/add_input_set.svg" class="question-icon mr-2"
alt="Add Question icon">
<span>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.NEW-INPUT-SET' | translate}}</span>
</div>
</div>
</div>
<div class="col-2 col-xl-auto ml-4" *ngIf="!selectedFieldSetId && !viewOnly">
<div class="row bg-white actions-list">
<nav>
<label class="action-list-label">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.GENERAL-TOOLS' |
translate}}</label>
<ul class="list-unstyled">
<li class="mli">
<div class="action-list-item" (click)="onAddFieldSet()">
<!-- <mat-icon class="action-list-icon">folder</mat-icon> -->
<img src="/assets/images/editor/icons/add_input_set.svg" class="input_icon"
alt="Add Question icon">
<span
class="action-list-text">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.NEW-INPUT-SET'
| translate}}</span>
</div>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<!-- FIELDSET INFO -->
<div class="col-12" dragula="FIELDSETS" [(dragulaModel)]="form.get('fieldSets').controls">
<div style="margin-bottom: 2em; position: relative;" class="row fieldset"
*ngFor="let fieldset of form.get('fieldSets')?.controls ; let i=index"
[id]="dragula_prefix+fieldset.get('id').value">
<div [id]="idprefix+fieldset.get('id').value" style="position: absolute; top: -7em; visibility: hidden;">
</div>
<div class="col-9 p-0">
<mat-card (click)="selectedFieldSetId = fieldset.get('id').value"
[ngClass]="{'field-container-active': fieldset.get('id').value === selectedFieldSetId}">
<mat-card-content>
<mat-card-header *ngIf="(fieldset.get('id').value === selectedFieldSetId) && !viewOnly">
<mat-icon class="handle"
style="display:inline-block; margin: 0px auto; cursor: grab;transform: rotate(90deg); opacity: 0.3;">drag_indicator</mat-icon>
</mat-card-header>
<app-description-template-editor-composite-field-component [form]="fieldset"
[viewOnly]="viewOnly" [numbering]="numbering + '.'+ (i+1)"
[hasFocus]="fieldset.get('id').value === selectedFieldSetId"
[datasetProfileId]="datasetProfileId">
</app-description-template-editor-composite-field-component>
</mat-card-content>
</mat-card>
</div>
<div class="col-2 col-xl-auto ml-4" *ngIf="selectedFieldSetId === fieldset.get('id').value &&(!viewOnly)">
<div class="row bg-white actions-list stick-list">
<nav *ngIf="!viewOnly">
<label class="action-list-label">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.GENERAL-TOOLS' |
translate}}</label>
<ul class="list-unstyled">
<li class="mli">
<div class="action-list-item" (click)="onAddFieldSet()">
<!-- <mat-icon class="action-list-icon">folder</mat-icon> -->
<img src="/assets/images/editor/icons/add_input_set.svg" class="input_icon"
alt="Add Question icon">
<span
class="action-list-text">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.NEW-INPUT-SET'
| translate}}</span>
</div>
</li>
<li class="mli">
<div class="action-list-item" (click)="onCloneFieldSet(fieldset)">
<!-- <mat-icon class="action-list-icon">file_copy</mat-icon> -->
<img src="/assets/images/editor/icons/clone.svg" class="input_icon"
alt="Clone icon">
<span class="action-list-text">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.CLONE' |
translate}}</span>
</div>
</li>
<li class="mli">
<div class="action-list-item" (click)="onRemoveFieldSet(selectedFieldSetId)">
<mat-icon class="action-list-icon">delete</mat-icon>
<span class="action-list-text">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.DELETE' |
translate}}</span>
</div>
</li>
</ul>
</nav>
</div>
</div>
<div class="col-9">
<div class="row justify-content-center mt-4 mb-2">
<div class="col-auto add-question" (click)="addFieldSetAfter(fieldset.get('ordinal').value, i)"
*ngIf="!viewOnly">
<img src="/assets/images/editor/icons/add_input_set.svg" class="question-icon mr-2"
alt="Add Question icon">
<span>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.NEW-INPUT-SET' | translate}}</span>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,80 @@
$blue-color : var(--primary-color);
$blue-color-light: #5cf7f2;
.field-container-active{
border-radius: .3em;
border-left: 0.3em solid $blue-color;
}
.fieldset-actions-list li{
cursor: pointer;
}
.fieldset{
.add-question{
cursor: pointer;
visibility: hidden;
transition-property: visibility;
transition-delay: 20ms;
transition-timing-function: ease;
transition-duration: 200ms;
}
}
.fieldset:hover{
.add-question{
visibility: visible;
}
}
.question-icon{
width: 20px;
}
.stick-list{
position: sticky;
top: 7em;
}
.actions-list{
// border: 1px solid $blue-color;
// box-shadow: 0px 3px 12px var(--primary-color)99;
border-radius: 4px;
// padding-top: 1rem;
padding: 1em 0.9em;
padding-bottom: 3em;
min-width: 166px;
box-shadow: 0px 2px 1px -1px rgb(0 0 0 / 20%), 0px 1px 1px 0px rgb(0 0 0 / 14%), 0px 1px 3px 0px rgb(0 0 0 / 12%);
.mat-list-item-content{
padding: 0px;
}
.action-list-item{
display: flex;
align-items: center;
cursor: pointer;
.action-list-icon{
font-size: 1.2em;
// padding-right: 1em;
width: 14px;
margin-right: 0.5em;
margin-left: -.09em;
height: auto;
color: var(--primary-color);;
}
.input_icon{
width: 14px;
margin-right: .5em;
}
.action-list-text{
font-size: 0.9em;
}
}
.action-list-label{
color: #212121;
font-size: small;
opacity: 0.6;
}
.list-unstyled{
margin-bottom: 0.2rem;
}
}

View File

@ -0,0 +1,250 @@
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { Guid } from '@common/types/guid';
import { isNullOrUndefined } from '@swimlane/ngx-datatable';
import { DragulaService } from 'ng2-dragula';
import { Subject, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { GENERAL_ANIMATIONS } from '../../animations/animations';
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateFieldSetEditorModel } from '../../description-template-editor.model';
import { ToCEntry, ToCEntryType } from '../../table-of-contents/description-template-table-of-contents-entry';
@Component({
selector: 'app-description-template-editor-section-fieldset-component',
templateUrl: './description-template-editor-section-fieldset.component.html',
styleUrls: ['./description-template-editor-section-fieldset.component.scss'],
animations: [GENERAL_ANIMATIONS]
})
export class DescriptionTemplateEditorSectionFieldSetComponent implements OnInit, OnChanges, OnDestroy {
@Input() viewOnly: boolean;
@Input() tocentry: ToCEntry;
@Input() datasetProfileId?: string;
@Output() selectedEntryId = new EventEmitter<Guid>();
@Output() dataNeedsRefresh = new EventEmitter<void>();
@Output() removeFieldSet = new EventEmitter<string>();
@Output() addNewFieldSet = new EventEmitter<UntypedFormGroup>();
@Output() cloneFieldSet = new EventEmitter<UntypedFormGroup>();
idprefix = "id";
readonly dragula_prefix = "dragulaid";
private subs = new Subscription();
private FIELDSETS = 'FIELDSETS';
private initializer = new Subject<void>();
private scroller = new Subject<string>();
// private $selectedFieldsetId = new Subject<string>();
constructor(
private dragulaService: DragulaService,
private myElement: ElementRef
) {
if (this.dragulaService.find(this.FIELDSETS)) {
this.dragulaService.destroy(this.FIELDSETS);
}
this.dragulaService.createGroup(this.FIELDSETS, {
moves: (el, container, handle) => {
// if(this.viewOnly) return false; //uncomment if want to unable drag n drop in viewonly mode
if (el.id != (this.dragula_prefix + this.tocentry.id)) return false;
if (handle.className && handle.classList.contains('handle')) return true;
return false;
}
});
this.subs.add(this.dragulaService.drop(this.FIELDSETS).subscribe(obs => {
(this.form.get('fieldSets') as UntypedFormArray).controls.forEach((e, i) => {
e.get('ordinal').setValue(i);
});
// obs.
this.dataNeedsRefresh.emit();
return;
}));
const initializerSub = this.initializer
.pipe(
debounceTime(100)
)
.subscribe(() => {
this.initialize();
});
this.subs.add(initializerSub);
this.subs.add(
this.scroller
.pipe(debounceTime(700))
.subscribe(id => {
if (isNullOrUndefined(id)) {
this._scrollOnTop();
return;
}
this._scrollToElement(id);
})
);
}
ngOnDestroy() {
// console.log('elemement destroyed -->');
this.subs.unsubscribe();
}
ngOnChanges(changes: SimpleChanges): void {
this.initializer.next();
}
form;
numbering;
private _selectedFieldSetId: Guid = null;
get selectedFieldSetId() {
return this._selectedFieldSetId;
}
set selectedFieldSetId(id: Guid) {
if (id === this._selectedFieldSetId) return;
this._selectedFieldSetId = id;
this.selectedEntryId.emit(id);
}
// private _findParentSection():FormGroup{
// const parent = this.form.parent;
// return parent;
// }
private initialize() {
if (this.tocentry.type === ToCEntryType.Section) {
this.form = this.tocentry.form;
this.numbering = this.tocentry.numbering;
this._selectedFieldSetId = null;
// this.scroller.next(null);
this._scrollOnTop(true);
} else if (this.tocentry.type === ToCEntryType.FieldSet) {
this.form = this.tocentry.form.parent.parent;
const numberingArray = this.tocentry.numbering.split('.');
if (numberingArray.length) {
numberingArray.splice(numberingArray.length - 1);
this.numbering = numberingArray.join('.');
} else {
// console.warn('!not found numbering');
}
this._selectedFieldSetId = Guid.parse(this.tocentry.id);
// this._scrollToElement(this.selectedFieldSetId);
this.scroller.next(this.tocentry.id);
} else {//scroll on top
// this._scrollOnTop();
this.scroller.next(null);
}
}
private _scrollToElement(id: string) {
let el = this.myElement.nativeElement.querySelector("#" + this.idprefix + id);
if (el) {
el.scrollIntoView({ behavior: "smooth", block: 'start' });
}
}
private _scrollOnTop(instant?: boolean) {
const el = this.myElement.nativeElement.querySelector('#topofcontainer');
if (el) {
if (instant) {
el.scrollIntoView({ block: 'end' });
} else {
el.scrollIntoView({ behavior: 'smooth', block: 'end' });
}
}
}
ngOnInit() {
}
onRemoveFieldSet(fieldsetId: string) {
this.removeFieldSet.emit(fieldsetId);
}
onCloneFieldSet(fieldset: UntypedFormGroup) {
this.cloneFieldSet.emit(fieldset);
}
onAddFieldSet() {
// this.addNewFieldSet.emit(this.form);
try {
const length = (this.form.get('fieldSets') as UntypedFormArray).length;
if (length === 0) {
this.addFieldSetAfter(-9999, 0);
return;
}
else {
const lastElement = (this.form.get('fieldSets') as UntypedFormArray).at(length - 1);
this.addFieldSetAfter(lastElement.get('ordinal').value, length - 1);
}
} catch { }
}
addFieldSetAfter(afterOrdinal: number, afterIndex: number): void {
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel();
field.id = Guid.create();
field.ordinal = 0;//first filed in the fields list
const fieldForm = field.buildForm();
//give fieldset id and ordinal
const fieldSet: DescriptionTemplateFieldSetEditorModel = new DescriptionTemplateFieldSetEditorModel();
const fieldSetId = Guid.create();
fieldSet.id = fieldSetId;
fieldSet.ordinal = afterOrdinal < 0 ? 0 : afterOrdinal;
const parentArray = this.form.get('fieldSets') as UntypedFormArray;
parentArray.controls.forEach(fieldset => {
const ordinalControl = fieldset.get('ordinal');
const ordinalValue = ordinalControl.value;
if (ordinalValue > afterOrdinal) {
ordinalControl.setValue(ordinalValue + 1);
}
});
const fieldsetForm = fieldSet.buildForm();
(fieldsetForm.get('fields') as UntypedFormArray).push(fieldForm);
const index = afterOrdinal < 0 ? 0 : afterIndex + 1;
parentArray.insert(index, fieldsetForm);
this.dataNeedsRefresh.emit();
// this.selectedFieldSetId = fieldSetId;
setTimeout(() => {
this.selectedFieldSetId = fieldSetId;
}, 200);
}
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry {
if (!tocentries) {
return null;
}
let tocEntryFound = tocentries.find(entry => entry.id === id);
if (tocEntryFound) {
return tocEntryFound;
}
for (let entry of tocentries) {
const result = this._findTocEntryById(id, entry.subEntries);
if (result) {
tocEntryFound = result;
break;
}
}
return tocEntryFound ? tocEntryFound : null;
}
}

View File

@ -0,0 +1,17 @@
<div [formGroup]="form" class="row description-template-editor">
<div class="heading col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.SECTION-INFO.SECTION-NAME' | translate}} *</div>
<div class="hint col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.SECTION-INFO.SECTION-NAME-HINT' | translate}}</div>
<mat-form-field class="col-12">
<input matInput type="text" [placeholder]="('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate)+ ' '+ ('DESCRIPTION-TEMPLATE-EDITOR.STEPS.SECTION-INFO.SECTION' | translate)"
formControlName="title">
<mat-error >{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<div class="heading col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.SECTION-INFO.SECTION-DESCRIPTION' | translate}} </div>
<div class="hint col-12">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.SECTION-INFO.SECTION-DESCRIPTION-HINT' | translate}}</div>
<div class="col-12">
<rich-text-editor-component [parentFormGroup]="form" [controlName]="'description'"
[placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.SECTION.FIELDS.DESCRIPTION'">
</rich-text-editor-component>
</div>
</div>

View File

@ -0,0 +1,31 @@
.description-template-editor {
.field-card {
margin-bottom: 1em;
}
}
.deleteBtn{
margin-right:2em;
}
.heading {
text-align: left;
font-weight: 700;
font-size: 18px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
// margin-top: 1.625rem;
margin-bottom: 0.625rem;
}
.hint {
text-align: left;
font-weight: 400;
font-size: 16px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-bottom: 0.125rem;
}

View File

@ -0,0 +1,75 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid';
import { DescriptionTemplateFieldEditorModel, DescriptionTemplateFieldSetEditorModel, DescriptionTemplateSectionEditorModel } from '../../description-template-editor.model';
@Component({
selector: 'app-description-template-editor-section-component',
templateUrl: './description-template-editor-section.component.html',
styleUrls: ['./description-template-editor-section.component.scss']
})
export class DescriptionTemplateEditorSectionComponent extends BaseComponent implements OnInit {
@Input() form: UntypedFormGroup;
@Input() indexPath: string;
@Input() viewOnly: boolean;
@Output() fieldsetAdded = new EventEmitter<String>(); //returns the id of the fieldset added
constructor() { super(); }
ngOnInit() {
}
addField() {
const fieldSet: DescriptionTemplateFieldSetEditorModel = new DescriptionTemplateFieldSetEditorModel();
fieldSet.ordinal = (this.form.get('fieldSets') as UntypedFormArray).length;
const field: DescriptionTemplateFieldEditorModel = new DescriptionTemplateFieldEditorModel();
field.id = Guid.create();
field.ordinal = 0;//first field in fields
fieldSet.fields.push(field);
fieldSet.id = Guid.create();
const fieldsetsArray = this.form.get('fieldSets') as UntypedFormArray;
fieldsetsArray.push(fieldSet.buildForm());
const fieldSetForm = fieldsetsArray.at(fieldsetsArray.length - 1);
//emit id inserted
if (fieldSetForm) {
const id: string = fieldSetForm.get('id').value;
this.fieldsetAdded.emit(id);
}
}
addSectioninSection() {
const section: DescriptionTemplateSectionEditorModel = new DescriptionTemplateSectionEditorModel();
//this.dataModel.sections.push(section);
(<UntypedFormArray>this.form.get('sections')).push(section.buildForm());
}
DeleteSectionInSection(index) {
//this.dataModel.sections.splice(index, 1);
(<UntypedFormArray>this.form.get('sections')).removeAt(index);
}
deleteFieldSet(index) {
//this.dataModel.fieldSets.splice(index, 1);
(<UntypedFormArray>this.form.get('fieldSets')).removeAt(index);
}
keepPageSelectionValid(pagesJson: Array<any>) {
const selectedPage = this.form.get('page').value as String;
// const pages: Array<PageEditorModel> = JsonSerializer.fromJSONArray(pagesJson, Page);
if (pagesJson.find(elem => elem.id === selectedPage) === undefined) {
this.form.get('page').reset();
}
}
getFieldTile(formGroup: UntypedFormGroup, index: number) {
if (formGroup.get('title') && formGroup.get('title').value && formGroup.get('title').value.length > 0) { return formGroup.get('title').value; }
return "Field " + (index + 1);
}
}

View File

@ -0,0 +1,40 @@
<div class="row" *ngFor="let ruleFormGroup of form['controls'] let i=index;" [formGroup]="ruleFormGroup">
<span class="col-auto align-self-center">{{i + 1}}</span>
<app-description-template-editor-default-value-component class="col align-self-center" [fieldType]="fieldTypeForCheck" [form]="ruleFormGroup" [formArrayOptions]="formArrayOptionsForCheck" placeHolder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.RULE-IF'| translate}}" required="true"></app-description-template-editor-default-value-component>
<!-- SELECTION -->
<mat-form-field class="col align-self-center">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.RULE-THEN'| translate}}</mat-label>
<mat-select formControlName="target" (openedChange)="computeOptions($event)">
<!-- SHOW FIELDSETS -->
<mat-optgroup [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.FIELDSETS' | translate">
<mat-option *ngFor="let option of fieldSetOptions" [value]="option.id" style="line-height: normal;" [disabled]="parentIds.includes(option.id) || hiddenBy.includes(option.id)" [matTooltip]="getToolTipMessage(option.id)" [matTooltipShowDelay]="700">
<span>
{{option.label? option.label:'<'+ ('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) + '>' }} </span> <br>
<small>
{{option.id}}
</small>
</mat-option>
</mat-optgroup>
<!-- SHOW FIELDS -->
<mat-optgroup [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.FIELDS.FIELDS' | translate">
<mat-option *ngFor="let option of fieldOptions" [value]="option.id" style="line-height: normal;" [disabled]="parentIds.includes(option.id) ||hiddenBy.includes(option.id)" [matTooltip]="getToolTipMessage(option.id)" [matTooltipShowDelay]="700">
<span>
{{option.label? option.label:'<'+ ('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) + '>' }} </span> <br>
<small>
{{option.id}}
</small>
</mat-option>
</mat-optgroup>
</mat-select>
<mat-error>{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<div class="col-auto align-self-center"><button mat-icon-button type="button" (click)="deleteRule(i);" [disabled]="viewOnly">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>

View File

@ -0,0 +1,211 @@
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
import { DescriptionTemplateRule } from '@app/core/model/description-template/description-template';
import { TranslateService } from '@ngx-translate/core';
import { ToCEntryType } from '../../table-of-contents/description-template-table-of-contents-entry';
@Component({
selector: 'app-description-template-editor-visibility-rule-component',
templateUrl: './description-template-editor-visibility-rule.component.html',
styleUrls: ['./description-template-editor-visibility-rule.component.scss']
})
export class DescriptionTemplateEditorRuleComponent implements OnInit {
@Input() form: UntypedFormArray;
@Input() fieldTypeForCheck: DescriptionTemplateFieldType;
@Input() formControlForCheck: UntypedFormControl;
@Input() formArrayOptionsForCheck: UntypedFormArray;
@Input() viewOnly: boolean;
options: OptionItem[];
sectionOptions: OptionItem[];
fieldSetOptions: OptionItem[];
fieldOptions: OptionItem[];
parentIds: string[] = [];
hiddenBy: string[] = [];
constructor(private language: TranslateService) {
}
targetValidation() {
//TODO
}
deleteRule(index) {
this.form.removeAt(index);
this.form.markAsDirty();//deactivate guard
}
ngOnInit(): void {
this._computeOptions();
}
private _computeOptions() {
this.options = this.getOptions();
this.sectionOptions = [];
this.fieldOptions = [];
this.fieldSetOptions = [];
this.options.forEach(option => {
switch (option.type) {
case ToCEntryType.Field:
this.fieldOptions.push(option);
break;
case ToCEntryType.FieldSet:
this.fieldSetOptions.push(option);
break;
case ToCEntryType.Section:
this.sectionOptions.push(option);
break;
default:
break;
}
});
//remove options to hide if given fieldset is already hidden by option
this.fieldOptions.forEach(e => this._buildHiddenBy(e));
this.fieldSetOptions.forEach(e => this._buildHiddenBy(e));
this.parentIds = this.computeParentIds();
this.hiddenBy = this.computeHiddenBy();
}
computeOptions(isOpened: boolean) {
if (isOpened) {
this._computeOptions();
}
}
private _buildHiddenBy(fo: OptionItem) {
try {
this.fieldOptions.forEach(foption => {
const rules = (foption.form.get('visible').get('rules') as UntypedFormArray).controls.map(c => (c as UntypedFormGroup).getRawValue()) as DescriptionTemplateRule[]
const targets = rules.map(rule => rule.target);
targets.forEach(target => {
if (fo.parentsIds.includes(target) && !fo.hiddenBy.includes(foption.id)) {
fo.hiddenBy.push(...foption.parentsIds);
}
})
});
} catch {
console.log('error');
}
}
getOptions(): OptionItem[] {
const rootForm = this.form.root;
if (rootForm) {
// const parentSections = rootForm.get('sections') as FormArray;
const result: OptionItem[] = [];
const sections = rootForm.get('sections') as UntypedFormArray;
if (sections) {
sections.controls.forEach(section => {
const subResult = this.buildOptions(section as UntypedFormGroup, ToCEntryType.Section, []);
result.push(...subResult);
});
}
//return options
return result;
}
//nothing found
return [];
}
private buildOptions(form: UntypedFormGroup, type: ToCEntryType, parentIds: string[]): OptionItem[] {
const sections = form.get('sections') as UntypedFormArray;
const fieldSets = form.get('fieldSets') as UntypedFormArray;
const fields = form.get('fields') as UntypedFormArray;
const result: OptionItem[] = [];
// parentIds.push(form.get('id').value);
const currentOptionItem: OptionItem = {
id: form.get('id').value,
type: type,
label: type === ToCEntryType.Field ? form.get('data').get('label').value : form.get('title').value,
// parentsIds: [form.get('id').value]
parentsIds: [...parentIds, form.get('id').value],
form: form,
hiddenBy: []
}
result.push(currentOptionItem);
if (sections) {
sections.controls.forEach(section => {
result.push(...this.buildOptions(section as UntypedFormGroup, ToCEntryType.Section, currentOptionItem.parentsIds));
});
}
if (fieldSets) {
fieldSets.controls.forEach(fieldset => {
result.push(...this.buildOptions(fieldset as UntypedFormGroup, ToCEntryType.FieldSet, currentOptionItem.parentsIds));
});
}
if (fields) {
fields.controls.forEach(field => {
result.push(...this.buildOptions(field as UntypedFormGroup, ToCEntryType.Field, currentOptionItem.parentsIds)); //TODO NA TO DOUME
});
}
return result;
}
computeParentIds(): string[] {
if (!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt => opt.id === this.formControlForCheck.get('id').value);
if (current) {
return current.parentsIds;
}
return [];
}
computeHiddenBy(): string[] {
if (!this.formControlForCheck.get('id')) return [];
const current = this.options.find(opt => opt.id === this.formControlForCheck.get('id').value);
if (current) {
return current.hiddenBy;
}
return [];
}
getToolTipMessage(id: string) {
if (this.parentIds.includes(id)) {
// return 'Cannot hide element that contain the field';
return this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.HINTS.ELEMENT-CHILD-OF-TARGET');
} else if (this.hiddenBy.includes(id)) {
return this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.RULE.HINTS.ELEMENT-HIDDEN-FROM-ELEMENT');
}
return '';
}
}
interface OptionItem {
id: string,
label: string,
type: ToCEntryType,
parentsIds: string[],
form: UntypedFormGroup,
hiddenBy: string[]
}

View File

@ -0,0 +1,64 @@
import { AbstractControl, UntypedFormArray, ValidationErrors, ValidatorFn } from "@angular/forms";
export class EditorCustomValidators {
static atLeastOneElementListValidator(arrayToCheck): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const fa = control.get(arrayToCheck) as UntypedFormArray;
if (!fa || fa.length === 0) {
return { [EditorCustomValidatorsEnum.emptyArray]: true };
}
return null;
}
}
static pagesHaveAtLeastOneSection(pagesArrayName: string, sectionsArrayName: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const pages = control.get(pagesArrayName) as UntypedFormArray;
const sections = control.get(sectionsArrayName) as UntypedFormArray;
const pageIdsArray = pages.controls.map(page => page.get('id').value);
const sectionsPageIds = sections.controls.map(section => section.get('page').value);
let invalidMessage = null;
pageIdsArray.forEach(pageId => {
if (!sectionsPageIds.includes(pageId)) {
invalidMessage = { [EditorCustomValidatorsEnum.atLeastOneSectionInPage]: true };
}
})
return invalidMessage;
}
}
static sectionHasAtLeastOneChildOf(fieldsetsArrayName, sectionsArrayName): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const fieldsets = control.get(fieldsetsArrayName) as UntypedFormArray;
const sections = control.get(sectionsArrayName) as UntypedFormArray;
if ((fieldsets && fieldsets.length) || (sections && sections.length)) {
return null;
}
return { [EditorCustomValidatorsEnum.sectionMustHaveOneChild]: true };
}
}
}
export enum EditorCustomValidatorsEnum {
sectionMustHaveOneChild = "sectionMustHaveOneChild",
atLeastOneSectionInPage = 'atLeastOneSectionInPage',
emptyArray = "emptyArray"
}

View File

@ -1,16 +1,16 @@
<div class="container-fluid description-template-editor">
<div id="header-outer-wrapper">
<div class="container-fluid description-template-editor" id="main-content">
<div id="header-outer-wrapper" *ngIf="formGroup">
<div class="row">
<div class="col-12 d-flex" id="title-column">
<div style="padding-left: 2em;">
<h3 *ngIf="isNew && !isClone && !isNewVersion">{{'DATASET-PROFILE-EDITOR.TITLE.NEW-PROFILE' | translate}}</h3>
<h3 *ngIf="isNew && !isClone && !isNewVersion">{{'DESCRIPTION-TEMPLATE-EDITOR.TITLE.NEW-PROFILE' | translate}}</h3>
<h3 *ngIf="isNew && isClone">
<span *ngIf="isClone">{{'DATASET-PROFILE-EDITOR.TITLE.NEW-PROFILE-CLONE' | translate}}</span>
<span *ngIf="isClone">{{'DESCRIPTION-TEMPLATE-EDITOR.TITLE.NEW-PROFILE-CLONE' | translate}}</span>
{{formGroup.get('label').value}}
</h3>
<h3 *ngIf="isNew && isNewVersion">
<span *ngIf="isNewVersion">{{'DATASET-PROFILE-EDITOR.TITLE.NEW-PROFILE-VERSION' | translate}}</span>
<span *ngIf="isNewVersion">{{'DESCRIPTION-TEMPLATE-EDITOR.TITLE.NEW-PROFILE-VERSION' | translate}}</span>
{{formGroup.get('label').value}}
</h3>
@ -20,6 +20,8 @@
</div>
</div>
<!-- {{formGroup?.value | json}} -->
<div class="row stepper-navigation-outer-wrapper">
@ -54,27 +56,27 @@
<mat-horizontal-stepper [linear]="true" #stepper class="stepper" (selectionChange)="onMatStepperSelectionChange($event)" style="padding-left: 8px; padding-right: 15px;">
<!-- IMPORTANT TO BE !INVALID (WHEN THE TEMPLATE IS FINALIZED THE CONTORLS ARE DISABLED) -->
<mat-step [label]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate" [completed]="(!formGroup.get('label').invalid && !formGroup.get('description').invalid && !formGroup.get('language').invalid)">
<!-- <ng-template matStepLabel>{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate}}
<mat-step [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate" [completed]="(!formGroup.get('label').invalid && !formGroup.get('description').invalid && !formGroup.get('language').invalid)">
<!-- <ng-template matStepLabel>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.TITLE' | translate}}
</ng-template> -->
<div class="col-9">
<div class="col">
<div class="col-12">
<div class="heading">1.1 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME'| translate}} *</div>
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME-HINT'| translate}}</div>
<div class="heading">1.1 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME'| translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NAME-HINT'| translate}}</div>
<mat-form-field class="full-width basic-info-input">
<input matInput [formControl]="formGroup.get('label')" placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-TITLE' | translate}}">
<input matInput [formControl]="formGroup.get('label')" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.DATASET-TITLE' | translate}}">
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' |
translate}}
</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<div class="heading">1.2 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION'| translate}} *</div>
<div class="heading">1.2 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION'| translate}} *</div>
<!-- <div class="hint">{{'DMP-EDITOR.MAIN-INFO.HINT' | translate}}</div> -->
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-HINT'| translate}}</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-HINT'| translate}}</div>
<div class="full-width basic-info-input">
<rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'description'" [placeholder]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER'" [wrapperClasses]="(formGroup.get('description').touched && formGroup.get('description').hasError('required')) ? 'required' : ''" [editable]="formGroup.controls['description'].status !== 'DISABLED'">
<rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'description'" [placeholder]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER'" [wrapperClasses]="(formGroup.get('description').touched && formGroup.get('description').hasError('required')) ? 'required' : ''" [editable]="formGroup.controls['description'].status !== 'DISABLED'">
</rich-text-editor-component>
<div [class]="(formGroup.get('description').touched && formGroup.get('description').hasError('required')) ? 'visible' : 'invisible'" class="mat-form-field formGroup-field-subscript-wrapper">
<mat-error>
@ -85,20 +87,22 @@
</div>
<div class="col-12">
<div class="heading">1.3 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-TYPE'| translate}} *</div>
<mat-form-field class="w-100">
<mat-label>{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-SELECT-TYPE' | translate}}</mat-label>
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('type')" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-SELECT-TYPE' | translate}}" [configuration]="descriptionTemplateTypeService.singleAutocompleteConfiguration">
<div class="heading">1.3 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-TYPE'| translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-TYPE-HINT'| translate}}</div>
<mat-form-field class="full-width basic-info-input">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-SELECT-TYPE' | translate}}</mat-label>
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('type')" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-SELECT-TYPE' | translate}}" [configuration]="descriptionTemplateTypeService.singleAutocompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<!-- <div class="heading">1.4 {{'DMP-EDITOR.FIELDS.LANGUAGE' | translate}}</div> -->
<div class="heading">1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *</div>
<div class="heading">1.4 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE-HINT'| translate}}</div>
<mat-form-field class="full-width basic-info-input">
<!-- <input matInput formControlName="description" placeholder="{{'DATASET-PROFILE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required> -->
<mat-select [formControl]="formGroup.get('language')" placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-SELECT-LANGUAGE'| translate}}">
<!-- <input matInput formControlName="description" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.FIELDS.DATASET-DESCRIPTION' | translate}}" required> -->
<mat-select [formControl]="formGroup.get('language')" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-SELECT-LANGUAGE'| translate}}">
<mat-option *ngFor="let lang of availableLanguages" [value]="lang.code">
{{ lang.name }}
</mat-option>
@ -108,48 +112,54 @@
</mat-error>
</mat-form-field>
</div>
<!-- <div class="col-12">
<div class="heading">1.5 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div>
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS-HINT'| translate}}</div>
<div class="full-width basic-info-input">
<table class="col-12 user-table">
<thead class="user-table-header">
<tr>
<th>{{'USERS.LISTING.NAME' | translate}}</th>
<th>{{'USERS.LISTING.EMAIL' | translate}}</th>
<th></th>
</tr>
</thead>
<tbody class="user-table-body">
<tr *ngFor="let user of userChipList" class="user-table-row">
<td>{{user.name}}</td>
<td >{{user.email}}</td>
<td>
<button mat-button class="delete-btn" (click)="verifyAndRemoveUser(user)" [matTooltip]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-REMOVE-USER'| translate"><mat-icon>person_remove</mat-icon></button>
</td>
</tr>
<tr *ngIf="!userChipList || !userChipList.length">
<td style="text-align: end; line-height: 3em;" colspan="2" >
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}}
</td>
</tr>
</tbody>
</table>
</div>
</div> -->
<div class="col-12">
<div class="heading">1.5 {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS-HINT'| translate}}</div>
<div class="full-width basic-info-input">
<table class="col-12 user-table">
<thead class="user-table-header">
<tr>
<th>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.USERS.NAME' | translate}}</th>
<th>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.USERS.ROLE' | translate}}</th>
<th></th>
</tr>
</thead>
<tbody class="user-table-body">
<tr *ngFor="let user of formGroup?.get('users')?.controls; let i=index;" class="user-table-row">
<td>{{usersMap.get(user?.get('userId')?.value)?.name}}</td>
<td>{{enumUtils.toUserDescriptionTemplateRoleString(user?.get('role')?.value)}}</td>
<td>
<button mat-button class="delete-btn" (click)="verifyAndRemoveUser(user)" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-REMOVE-USER'| translate"><mat-icon>person_remove</mat-icon></button>
</td>
</tr>
<tr *ngIf="formGroup.get('users')?.controls?.length === 0">
<td style="text-align: end; line-height: 3em;" colspan="2">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-NO-USERS-YET' | translate}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- <div class="col-12">
<div class="row justify-content-end">
<div class="col d-flex justify-content-end" style="overflow: hidden;">
<div style="min-width: 20em;max-width: 25em;" [@add-new-user-field]="inputUserState">
<mat-form-field>
<input matInput #email placeholder="{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}" (focus)="onUserFieldFocus()" (blur)="onUserFieldBlur()" (keyup.enter)="addUser(email)">
</mat-form-field>
</div>
<div class="col-12">
<div class="row justify-content-end">
<div class="col d-flex justify-content-end" style="overflow: hidden;">
<div style="min-width: 20em;max-width: 25em;">
<!-- <mat-form-field>
<input matInput #email placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}" (focus)="onUserFieldFocus()" (blur)="onUserFieldBlur()" (keyup.enter)="addUser(email)">
</mat-form-field> -->
<mat-form-field class="full-width basic-info-input">
<mat-label>{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS' | translate}}</mat-label>
<app-single-auto-complete [required]="false" [formControl]="userFormControl" (optionSelected)="addUser($event)" placeholder="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS' | translate}}" [configuration]="userService.singleAutocompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
<div class="col-auto">
<button mat-mini-fab color="primary" (click)="addUser(email)" (focus)="onUserButtonFocus()" (blur)="onUserButtonBlur()" [matTooltip]="'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate" [disabled]="userFormDisabled">
<!-- <div class="col-auto">
<button mat-mini-fab color="primary" (click)="addUser(email)" (focus)="onUserButtonFocus()" (blur)="onUserButtonBlur()" [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-VALIDATE-AND-ADD-USER'| translate" [disabled]="userFormDisabled">
<ng-container *ngIf="inputUserState === 'untriggered' else triggericon">
<mat-icon>add</mat-icon>
</ng-container>
@ -157,20 +167,20 @@
<mat-icon>person_add</mat-icon>
</ng-template>
</button>
</div>
</div>
</div> -->
</div> -->
</div>
</div>
</div>
<!-- <div class="col-12">
<button mat-button class="full-width" (click)="addPage()"
[disabled]="viewOnly">{{'DATASET-PROFILE-EDITOR.ACTIONS.NEXT' | translate}}</button>
[disabled]="viewOnly">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.NEXT' | translate}}</button>
</div> -->
</div>
</mat-step>
<mat-step [label]="'DATASET-PROFILE-EDITOR.STEPS.FORM.TITLE' | translate" [completed]="formGroup.valid">
<mat-step [label]="'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TITLE' | translate" [completed]="formGroup.valid">
<div class="row">
<!-- TABLE -->
@ -190,22 +200,22 @@
<div class="row">
<div class="col">
<!-- <div class="col-12" *ngIf="selectedTocEntry">
<div class="col-12" *ngIf="selectedTocEntry">
<div class="col-12 content-displayer" *ngIf="selectedTocEntry.type === tocEntryEnumValues.Page" [@fade-in-fast]>
<formGroup [formGroup]="selectedTocEntry.formGroup" class="page-infos">
<formGroup [formGroup]="selectedTocEntry.form" class="page-infos">
<div class="row">
<div class="col-12">
<div class="heading">{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME' | translate}} *</div>
<div class="hint">{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME-HINT' | translate}}</div>
<div class="heading">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME' | translate}} *</div>
<div class="hint">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.PAGE-NAME-HINT' | translate}}</div>
<mat-form-field>
<input type="text" matInput formControlName="title" [placeholder]="('DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) +' '+ ('DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.PAGE' |translate)">
<input type="text" matInput formControlName="title" [placeholder]="('DESCRIPTION-TEMPLATE-EDITOR.STEPS.GENERAL-INFO.UNTITLED' | translate) +' '+ ('DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.PAGE' |translate)">
<mat-error>{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12" *ngIf="!viewOnly && (!selectedTocEntry?.subEntries?.length)">
<button class="create-section-btn" (click)="addNewEntry({parent:selectedTocEntry, childType: tocEntryEnumValues.Section})">{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.CREATE-SECTION' | translate}}</button>
<button class="create-section-btn" (click)="addNewEntry({parent:selectedTocEntry, childType: tocEntryEnumValues.Section})">{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.CREATE-SECTION' | translate}}</button>
</div>
</div>
</formGroup>
@ -218,34 +228,34 @@
</div>
</div> -->
</div>
<!-- <div class="content-displayer row justify-content-center" *ngIf="!numOfPages" style="min-height: 30em;">
<div class="content-displayer row justify-content-center" *ngIf="!numOfPages" style="min-height: 30em;">
<div class="col-auto align-self-center">
<div class="row w-100 justify-content-center">
<div class="col-auto">
{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.NOTHING-HERE-HINT'| translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.NOTHING-HERE-HINT'| translate}}
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto d-flex aling-contents-center">
{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-START'| translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-START'| translate}}
<mat-icon color="accent" style="font-size: 1.5em; text-align: center; width: 1.5em;">add</mat-icon>
<strong style="cursor: pointer;" (click)="addNewEntry({childType: tocEntryEnumValues.Page,parent: null})">
{{'DATASET-PROFILE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-END'| translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.PAGE-INFO.ACTIONS.START-CREATING-PAGE-END'| translate}}
</strong>
</div>
</div>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
</mat-step>
<mat-step [label]="'DATASET-PROFILE-EDITOR.ACTIONS.PREVIEW-AND-FINALIZE' | translate">
<mat-step [label]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.PREVIEW-AND-FINALIZE' | translate">
<ng-container *ngIf="formGroup">
<div class="col-9">
<div class="col">
@ -262,7 +272,7 @@
</mat-horizontal-stepper>
<a class="scroll-on-top d-flex flex-column align-items-center" (click)="scrollOnTop()" [@scroll-on-top-btn] [matTooltip]="'DATASET-PROFILE-EDITOR.ACTIONS.BACK-TO-TOP'| translate">
<a class="scroll-on-top d-flex flex-column align-items-center" (click)="scrollOnTop()" [@scroll-on-top-btn] [matTooltip]="'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.BACK-TO-TOP'| translate">
<mat-icon>
arrow_upward
</mat-icon>
@ -288,9 +298,10 @@
<ng-template #actions>
<div>
<button mat-raised-button class="template_action_btn mr-3" (click)="discardChanges()">{{'DATASET-WIZARD.ACTIONS.CLOSE' | translate}}</button>
<button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1" [disabled]="!formGroup.valid" mat-raised-button class="template_action_btn save-btn" type="button">
<!-- <button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1" [disabled]="!formGroup.valid" mat-raised-button class="template_action_btn save-btn" type="button"> -->
<button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1" mat-raised-button class="template_action_btn save-btn" type="button">
<span class="d-flex flex-row row">
<span (click)="onSubmit()" class="col">{{'DATASET-PROFILE-EDITOR.ACTIONS.SAVE' |translate}}</span>
<span (click)="save(); formSubmit()" class="col">{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE' |translate}}</span>
<mat-divider [vertical]="true"></mat-divider>
<span class="align-items-center justify-content-center col-4 d-flex" (click)="$event.stopPropagation();" [matMenuTriggerFor]="menuSave">
<mat-icon>expand_more</mat-icon>
@ -298,21 +309,21 @@
</span>
</button>
<mat-menu #menuSave="matMenu">
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit(true)" type="button">{{ 'DATASET-PROFILE-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit()" type="button">{{ 'DATASET-PROFILE-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit(true)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="onSubmit()" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
</mat-menu>
<button *ngIf="formGroup.disabled || formGroup.get('status').value==1" [@finalize_btn] mat-raised-button class="template_action_btn save-btn" [disabled]="!formGroup.valid" (click)="updateAndFinalize()">
{{'DATASET-PROFILE-EDITOR.ACTIONS.UPDATE' |translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE' |translate}}
<mat-icon (click)="$event.stopPropagation();" style="width: 14px;" [matMenuTriggerFor]="menuUpdate">expand_more</mat-icon>
</button>
<mat-menu #menuUpdate="matMenu">
<button [disabled]="!formGroup.valid" mat-menu-item (click)="updateAndFinalize(true)" type="button">{{ 'DATASET-PROFILE-EDITOR.ACTIONS.UPDATE-AND-CLOSE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="updateAndFinalize()" type="button">{{ 'DATASET-PROFILE-EDITOR.ACTIONS.UPDATE-AND-CONTINUE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="updateAndFinalize(true)" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE-AND-CLOSE' | translate }}</button>
<button [disabled]="!formGroup.valid" mat-menu-item (click)="updateAndFinalize()" type="button">{{ 'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.UPDATE-AND-CONTINUE' | translate }}</button>
</mat-menu>
<button *ngIf="!formGroup.disabled && formGroup.get('status').value!=1 && steps?.length-1 === stepper?.selectedIndex" [@finalize_btn] mat-button class="finalize-btn ml-3" [disabled]="!formGroup.valid" [class.invisible]="steps?.length-1 !== stepper?.selectedIndex" (click)="updateAndFinalize(true)">
{{'DATASET-PROFILE-EDITOR.ACTIONS.FINALIZE' |translate}}
{{'DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.FINALIZE' |translate}}
</button>
</div>
</ng-template>

View File

@ -1,44 +1,94 @@
.description-template-editor {
margin-top: 1.3rem;
margin-left: 1em;
margin-right: 3em;
//margin-top: 1.3rem;
.remove {
background-color: white;
color: black;
}
.add {
background-color: white;
color: #009700;
}
}
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background, .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background {
background-color: var(--primary-color-3);
// background-color: #0070c0;
}
::ng-deep .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background {
background-color: #b0b0b0;
}
.finalize-btn {
border-radius: 30px;
border: 1px solid var(--primary-color);
background: transparent;
padding-left: 2em;
padding-right: 2em;
box-shadow: 0px 3px 6px #1E202029;
color: var(--primary-color);
&:disabled{
background-color: #CBCBCB;
color: #FFF;
border: 0px;
.full-width {
width: 100%;
}
}
.action-btn {
.deleteBtn{
margin-right:2em;
}
// REFACTORED CSS
.stepper{
background-color: transparent;
min-height: 500px;
}
.content-displayer{
background-color: #fff;
border-radius: 7px;
box-shadow: 0px 1px 2px #bfbfbf;
padding: 0em;
// padding-top: 0em;
overflow: visible;
// min-height: 30em;
}
.heading {
text-align: left;
font-weight: 700;
font-size: 18px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
// margin-top: 1.625rem;
margin-bottom: 0.625rem;
}
.hint {
text-align: left;
font-weight: 400;
font-size: 16px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-bottom: 0.125rem;
}
//TO CHECK
:host ::ng-deep .mat-horizontal-content-container {
overflow: visible;
// padding: 0px;
}
:host ::ng-deep .mat-form-field-outline{
background-color: #ffffff4f;
}
:host ::ng-deep .mat-horizontal-stepper-header-container {
display: none !important;
}
#progress{
position: absolute;
height: 100%;
width: 100%;
clip-path: polygon(0 0, 0 0, 0 0, 0 0);
transition-property: clip-path;
transition-duration: 600ms;
transition-timing-function: ease-out;
transition-delay: 50ms;
box-shadow: 0px 1px 2px #bfbfbf;
background-color: var(--secondary-color);
}
#progress-container{
box-shadow: 1px 1px 6px #00000029;;
// border-radius: .3em;
}
// .import-btn {
// background: #ffffff 0% 0% no-repeat padding-box;
// border-radius: 30px;
// // color: var(--primary-color);
// // border: 1px solid var(--primary-color);
// padding-left: 2em;
// padding-right: 2em;
// color: #000;
// border: 1px solid #000;
// }
.navigate-btn {
border-radius: 30px;
background-color: var(--secondary-color);
border: 1px solid transparent;
@ -50,67 +100,287 @@
transition-duration: 200ms;
transition-delay: 50ms;
transition-timing-function: ease-in-out;
&:disabled{
}
.navigate-btn-disabled{
background-color: #CBCBCB;
color: #FFF;
}
.create-section-btn {
border-radius: 30px;
background-color: var(--secondary-color);
border: 1px solid transparent;
padding-left: 1em;
padding-right: 1em;
box-shadow: 0px 3px 6px #1E202029;
line-height: 1.7em;
}
$blue-color : var(--primary-color);
$blue-color-light: #5cf7f2;
.finalize-btn {
border-radius: 30px;
border: 1px solid var(--primary-color);
background: transparent;
padding-left: 2em;
padding-right: 2em;
box-shadow: 0px 3px 6px #1E202029;
color: var(--primary-color);
}
.template_action_btn{
border-radius: 30px;
border: 1px solid var(--primary-color);
background: transparent;
//padding-left: 2em;
//padding-right: 2em;
height: 2.5em;
min-width: 110px;
width: auto;
box-shadow: 0px 3px 6px #1E202029;
color: var(--primary-color);
flex: 0 0 auto;
&.save-btn{
background-color: var(--secondary-color);
border: 1px solid transparent;
//padding-left: 2em;
//padding-right: 2em;
box-shadow: 0px 3px 6px #1E202029;
color: #212121;
transition-property: background-color, color;
transition-duration: 200ms;
transition-delay: 50ms;
transition-timing-function: ease-in-out;
}
&:disabled{
background-color: #CBCBCB;
color: #FFF;
border: 0px;
}
}
.dlt-section-btn {
margin: 0;
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
.stepper-title-label{
cursor: pointer;
transition-property: color, opacity;
transition-duration: 200ms;
transition-delay: 50ms;
transition-timing-function: ease-in-out;
color: #212121;
font-size: 0.9em;
}
.section-input {
position: relative;
.stepper-title-label-locked{
color: #DEDEDE;
}
.section-input .arrows {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
.stepper-title-label-completed{
opacity: 0.5;
}
.page-infos{
padding: 2em;
}
.mat-subheader{
padding: 0px;
}
.action-list-item{
display: flex;
align-items: center;
cursor: pointer;
.action-list-icon{
font-size: 1.2em;
// padding-right: 1em;
// width: 14px;
// margin-right: 0.5em;
// margin-left: -.09em;
// height: auto;
color: var(--primary-color);
}
.action-list-text{
font-size: 1em;
color: var(--primary-color);
}
//for the acitons list toolbar
// .mat-list-item.mat-list-item-with-avatar{
// padding-left: 0em;
// }
.actions-list{
// border: 1px solid $blue-color;
box-shadow: 0px 3px 12px var(--primary-color)99;
border-radius: 4px;
// padding-top: 1rem;
padding: 1em 0.9em;
min-width: 166px;
.mat-list-item-content{
padding: 0px;
}
.action-list-item{
display: flex;
align-items: center;
cursor: pointer;
.action-list-icon{
font-size: 1.2em;
// padding-right: 1em;
width: 14px;
margin-right: 0.5em;
margin-left: -.09em;
height: auto;
color: var(--primary-color);;
}
.input_icon{
width: 14px;
margin-right: .5em;
}
.action-list-text{
font-size: 0.9em;
}
}
.action-list-label{
color: #212121;
font-size: small;
opacity: 0.6;
}
.list-unstyled{
margin-bottom: 0.2rem;
}
}
.field-delete{
align-items: center;
// .mli{
// height: auto;
// }
:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}
.basic-info-input{
margin-top: 2em;
margin-bottom: 2em;
}
.delete-btn {
// background-color: rgba(255, 0, 0, 0.76);
// color: white;
}
.email-input {
border-color: black;
border-style: solid;
border-width: thin;
border-radius: 4px;
margin-right: 5px;
background-color: white;
padding-top: 10px;
padding-bottom: 10px;
}
.user-table {
// border: thin solid rgb(179, 173, 173);
// border: 1px solid rgba(0, 0, 0, 0.12);
background-color: white;
border-radius: 4px;
padding-bottom: 1em;
box-shadow: -1px 1px 11px -3px #00000017;
}
.user-table-header {
text-align: center;
display: revert;
background-color: rgb(243 245 248);
// background-color: #129d9811;
}
.user-table-header th {
padding-top: 10px;
padding-bottom: 10px;
// border: thin solid darkgray;
}
.user-table-row {
// display: revert;
background-color: #fafafa;
td{
padding-top: .5em;
padding-bottom: .5em;
}
&:hover{
background-color: #eef5f6;
}
border-top:1px solid rgba(0, 0, 0, 0.12);
}
.user-table-row:nth-child(even) {
// background-color: silver;
}
.user-table-body{
text-align: center;
}
.scroll-on-top{
position: fixed;
bottom: 20em;
right: 2em;
color: var(--primary-color) !important;
cursor: pointer;
font-size: 1rem;
font-weight: 400;
}
.floating-btn {
position: fixed;
bottom: 2em;
right: 2em;
}
.progress-min-height {
min-height: 35px;
}
#stepper-navigation-wrapper{
z-index: 99;
width: 100%;
#stepper-navigation{
background-color: #f4f4f4;
z-index: 99;
}
}
.actions-template{
align-self:flex-end;
display: flex;
cursor: pointer;
.field-delete-icon{
font-size: 1.2em;
width: 14px;
color: var(--primary-color);
}
.field-delete-text{
font-size: 1em;
margin-left: 0.5em;
color: var(--primary-color);
}
}
justify-content: space-between;
width: 100%;
padding-left: 15px;
padding-right: 15px;
}
.stepper-navigation-outer-wrapper{
padding: 2em;
margin-bottom: 1em;
//background: #f4f4f4;
//position: sticky;
//top: 0.01em;
//z-index: 9999;
}
#header-outer-wrapper {
padding-top: 1.3rem;
background: #f4f4f4;
position: sticky;
top: 0.01em;
z-index: 9999;
}
#title-column{
justify-content: space-between;
align-items: baseline;
padding-right: 15px;
}
.side-actions{
display: flex;
height: 40vh;
position: sticky;
top: 2em;
}

View File

@ -1,22 +1,23 @@
import { Component, OnInit, QueryList, ViewChild } from '@angular/core';
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { FormArray, FormControl, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BehaviorSubject } from 'rxjs';
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { CdkStep, StepperSelectionEvent } from '@angular/cdk/stepper';
import { DatePipe } from '@angular/common';
import { MatInput } from '@angular/material/input';
import { MatStepper } from '@angular/material/stepper';
import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type';
import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style';
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { DescriptionTemplatePersist } from '@app/core/model/description-template/description-template-persist';
import { LanguageInfo } from '@app/core/model/language-info';
import { User } from '@app/core/model/user/user';
import { AuthService } from '@app/core/services/auth/auth.service';
import { LanguageInfoService } from '@app/core/services/culture/language-info-service';
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
@ -24,6 +25,7 @@ import { DescriptionTemplateService } from '@app/core/services/description-templ
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { LoggingService } from '@app/core/services/logging/logging-service';
import { MatomoService } from '@app/core/services/matomo/matomo-service';
import { UserService } from '@app/core/services/user/user.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
import { BaseEditor } from '@common/base/base-editor';
@ -33,12 +35,14 @@ import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/
import { FilterService } from '@common/modules/text-filter/filter-service';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators';
import { combineLatest } from 'rxjs';
import { debounceTime, filter, map, takeUntil } from 'rxjs/operators';
import { GENERAL_ANIMATIONS, STEPPER_ANIMATIONS } from './animations/animations';
import { DescriptionTemplateEditorModel, DescriptionTemplateFieldEditorModel, DescriptionTemplateFieldSetEditorModel, DescriptionTemplatePageEditorModel, DescriptionTemplateSectionEditorModel } from './description-template-editor.model';
import { DescriptionTemplateEditorModel, DescriptionTemplateFieldEditorModel, DescriptionTemplateFieldSetEditorModel, DescriptionTemplatePageEditorModel, DescriptionTemplateSectionEditorModel, UserDescriptionTemplateEditorModel } from './description-template-editor.model';
import { DescriptionTemplateEditorResolver } from './description-template-editor.resolver';
import { DescriptionTemplateEditorService } from './description-template-editor.service';
import { NewEntryType, ToCEntry, ToCEntryType } from './table-of-contents/description-template-table-of-contents-entry';
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
@Component({
@ -55,6 +59,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
isNew = true;
isDeleted = false;
formGroup: UntypedFormGroup = null;
item: DescriptionTemplate;
showInactiveDetails = false;
availableLanguages: LanguageInfo[] = this.languageInfoService.getLanguageInfoValues();
@ -65,6 +70,10 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
toCEntries: ToCEntry[];
selectedTocEntry: ToCEntry;
colorizeInvalid: boolean = false;
tocEntryEnumValues = ToCEntryType;
usersMap: Map<Guid, User> = new Map<Guid, User>();
userFormControl = new FormControl();
// selectedSystemFields: Array<DescriptionTemplateSystemFieldType> = [];
@ -122,7 +131,8 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
private fileUtils: FileUtils,
private matomoService: MatomoService,
private dmpService: DmpService,
private languageInfoService: LanguageInfoService
private languageInfoService: LanguageInfoService,
public userService: UserService
) {
super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService);
}
@ -144,6 +154,9 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
prepareForm(data: DescriptionTemplate) {
try {
this.editorModel = data ? new DescriptionTemplateEditorModel().fromModel(data) : new DescriptionTemplateEditorModel();
this.item = data;
// Add user info to Map, to present them.
(this.item?.users ?? []).forEach(obj => {this.usersMap.set(obj.user.id, obj.user); });
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
this.buildForm();
@ -153,6 +166,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
this._initializeToCEntries();
} catch (error) {
console.error(error);
this.logger.error('Could not parse descriptionTemplate item: ' + data + error);
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
}
@ -233,6 +247,43 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
this.formService.validateAllFormFields(this.formGroup);
}
//
//
// Description Template User
//
//
addUser(user: User) {
console.log(user);
const newUser: UserDescriptionTemplateEditorModel = new UserDescriptionTemplateEditorModel();
newUser.userId = user.id;
newUser.role = UserDescriptionTemplateRole.Owner;
this.usersMap.set(user.id, user);
(this.formGroup.get('users') as FormArray).push(newUser.buildForm());
this.userFormControl.reset();
}
removeUser(index: number) {
(this.formGroup.get('users') as FormArray).controls.splice(index, 1);
this.formGroup.get('users').updateValueAndValidity();
}
verifyAndRemoveUser(index: number){
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
restoreFocus: false,
data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
isDeleteConfirmation: true
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(approve => {
if (approve) {
this.removeUser(index);
}
});
}
//
//
// Stepper
@ -327,9 +378,9 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
const occurences = fieldSetHavingInvalidVisibilityRules.map(record => record.numbering).join(' , ');
this.dialog.open(ConfirmationDialogComponent, {
data: {
message: this.language.instant('DATASET-PROFILE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.MESSAGE-START') + occurences + this.language.instant('DATASET-PROFILE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.MESSAGE-END'),
confirmButton: this.language.instant('DATASET-PROFILE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.CONFIRM-YES'),
cancelButton: this.language.instant('DATASET-PROFILE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.CONFIRM-NO')
message: this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.MESSAGE-START') + occurences + this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.MESSAGE-END'),
confirmButton: this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.CONFIRM-YES'),
cancelButton: this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.CONFIRM-NO')
},
maxWidth: '30em'
})
@ -337,7 +388,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
.subscribe(confirm => {
if (confirm) {
this.removeFieldSetVisibilityRules(fieldSetHavingInvalidVisibilityRules);
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-PROFILE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.REMOVE-SUCCESS'), SnackBarNotificationLevel.Success);
this.uiNotificationService.snackBarNotification(this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ERRORS.INVALID-VISIBILITY-RULES.REMOVE-SUCCESS'), SnackBarNotificationLevel.Success);
} else {
console.log('User not confirmed');
@ -352,8 +403,6 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
if (this.selectedTocEntry) {
this.selectedTocEntry = this._findTocEntryById(this.selectedTocEntry.id, this.toCEntries);
}
// this.updateOrdinals(this.toCEntries);
// this._updateNumbering(this.toCEntries);
return this.toCEntries;
}
@ -383,7 +432,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
const result: ToCEntry[] = [];
//build parent pages
(this.formGroup.get('pages') as UntypedFormArray).controls.forEach((pageElement, i) => {
(this.formGroup.get('definition').get('pages') as UntypedFormArray).controls.forEach((pageElement, i) => {
result.push({
id: pageElement.get('id').value,
label: pageElement.get('title').value,
@ -395,7 +444,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
});
// build first level sections
(this.formGroup.get('sections') as UntypedFormArray).controls.forEach((sectionElement, i) => {
(this.formGroup.get('definition').get('sections') as UntypedFormArray).controls.forEach((sectionElement, i) => {
const currentSectionPageId = sectionElement.get('page').value;
const pageToAdd = result.filter(x => x.id == currentSectionPageId)[0];
if (pageToAdd.subEntries == null) pageToAdd.subEntries = [];
@ -514,9 +563,10 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
//define entry type
switch (tce.childType) {
case ToCEntryType.Page:
const pagesArray = (this.formGroup.get('pages') as UntypedFormArray);
const pagesArray = (this.formGroup.get('definition').get('pages') as UntypedFormArray);
const page: DescriptionTemplatePageEditorModel = new DescriptionTemplatePageEditorModel();
page.id = Guid.create();
if (isNaN(pagesArray.length)) { page.ordinal = 0; } else { page.ordinal = pagesArray.length; }
const pageForm = page.buildForm();
// this.dataModel.pages.push(page);
@ -534,7 +584,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
let sectionsArray: UntypedFormArray;
if (parent.type === ToCEntryType.Page) {//FIRST LEVEL SECTION
sectionsArray = this.formGroup.get('sections') as UntypedFormArray;
sectionsArray = this.formGroup.get('definition').get('sections') as UntypedFormArray;
section.page = parent.id;
@ -649,7 +699,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
//define entry type
switch (tce.type) {
case ToCEntryType.Page:
const pages = this.formGroup.get('pages') as UntypedFormArray;
const pages = this.formGroup.get('definition').get('pages') as UntypedFormArray;
let pageIndex = -1;
//get the index
@ -668,7 +718,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
pages.removeAt(pageIndex);
//clean up sections of removed page
const sections = (this.formGroup.get('sections') as UntypedFormArray);
const sections = (this.formGroup.get('definition').get('sections') as UntypedFormArray);
const sectionsIndexToBeRemoved = [];
@ -700,7 +750,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
let index = -1;
const sections = (this.formGroup.get('sections') as UntypedFormArray);
const sections = (this.formGroup.get('definition').get('sections') as UntypedFormArray);
for (let i = 0; i < sections.length; i++) {
@ -716,7 +766,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
if (index >= 0) { //section found
const sections = (this.formGroup.get('sections') as UntypedFormArray);
const sections = (this.formGroup.get('definition').get('sections') as UntypedFormArray);
//remove section
this._updateSelectedItem(tce);
@ -801,7 +851,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
} else {
//if first level section
const firstLevelSections = (this.formGroup.get('sections') as UntypedFormArray);
const firstLevelSections = (this.formGroup.get('definition').get('sections') as UntypedFormArray);
let isFirstLevel: boolean = false;
firstLevelSections.controls.forEach(section => {
if (section.get('id').value === tce.id) {
@ -926,33 +976,33 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
//
//
private hasInvalidVisibilityRule(field: UntypedFormGroup): boolean {
const renderStyle = field.get('viewStyle').get('renderStyle').value;
if (renderStyle && ![
DatasetProfileFieldViewStyle.TextArea,
DatasetProfileFieldViewStyle.RichTextArea,
DatasetProfileFieldViewStyle.Upload,
DatasetProfileFieldViewStyle.FreeText,
DatasetProfileFieldViewStyle.BooleanDecision,
DatasetProfileFieldViewStyle.RadioBox,
DatasetProfileFieldViewStyle.CheckBox,
DatasetProfileFieldViewStyle.DatePicker,
DatasetProfileFieldViewStyle.ComboBox,
].includes(renderStyle)) {
if (((renderStyle === DatasetProfileFieldViewStyle) && (field.get('data').get('type').value === DatasetProfileComboBoxType.WordList))) {
return false;
}
try {
if (field.get('visible').get('rules').value.length) {
return true;
}
return false;
// const renderStyle = field.get('viewStyle').get('renderStyle').value;
// if (renderStyle && ![
// DatasetProfileFieldViewStyle.TextArea,
// DatasetProfileFieldViewStyle.RichTextArea,
// DatasetProfileFieldViewStyle.Upload,
// DatasetProfileFieldViewStyle.FreeText,
// DatasetProfileFieldViewStyle.BooleanDecision,
// DatasetProfileFieldViewStyle.RadioBox,
// DatasetProfileFieldViewStyle.CheckBox,
// DatasetProfileFieldViewStyle.DatePicker,
// DatasetProfileFieldViewStyle.ComboBox,
// ].includes(renderStyle)) {
// if (((renderStyle === DatasetProfileFieldViewStyle) && (field.get('data').get('type').value === DatasetProfileComboBoxType.WordList))) {
// return false;
// }
// try {
// if (field.get('visible').get('rules').value.length) {
// return true;
// }
// return false;
} catch {
return false;
}
} else {
return false;
}
// } catch {
// return false;
// }
// } else {
return false;
// }
}
private removeFieldSetVisibilityRules(fieldsets: ToCEntry[]) {
@ -986,16 +1036,37 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
try {
const topPage = document.getElementById('main-content');
topPage.scrollIntoView({ behavior: 'smooth' });
} catch {
} catch (e) {
console.log(e);
console.log('coulnd not scroll');
}
}
get numOfPages(){
return (<UntypedFormArray>this.formGroup.get('pages'))?.length;
}
checkFormValidation() {
this.colorizeInvalid = true;
// this.printMyErrors(this.form);
}
get progressStyle() {
// return {'transform': 'translateX('+this.barPercentage+'%) skewX(-25deg)'}
const diff = 3;
return {
'clip-path': `polygon(0 0, ${Math.round(this.barPercentage + diff)}% 0, ${Math.round(this.barPercentage)}% 100%, 0 100%)`
}
}
get barPercentage() {
if (!this.stepper || !this.steps) {
return 0;
}
const selectedIndex = this.stepper.selectedIndex + 1;
return (selectedIndex / this.stepper.steps.length) * 100;
}
// //
// //
// // Sections

View File

@ -1,8 +1,11 @@
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { DescriptionTemplateFieldAutocompleteType } from "@app/core/common/enum/description-template-field-autocomplete-type";
import { DescriptionTemplateFieldType } from "@app/core/common/enum/description-template-field-type";
import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/description-template-field-validation-type";
import { DescriptionTemplateStatus } from "@app/core/common/enum/description-template-status";
import { UserDescriptionTemplateRole } from "@app/core/common/enum/user-description-template-role";
import { DescriptionTemplate, DescriptionTemplateDefinition, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateRule, DescriptionTemplateSection } from "@app/core/model/description-template/description-template";
import { DescriptionTemplateBaseFieldDataPersist, DescriptionTemplateDefinitionPersist, DescriptionTemplateFieldPersist, DescriptionTemplateFieldSetPersist, DescriptionTemplateMultiplicityPersist, DescriptionTemplatePagePersist, DescriptionTemplatePersist, DescriptionTemplateRulePersist, DescriptionTemplateSectionPersist } from "@app/core/model/description-template/description-template-persist";
import { DescriptionTemplateAuthAutoCompleteDataPersist, DescriptionTemplateAutoCompleteDataPersist, DescriptionTemplateAutoCompleteSingleDataPersist, DescriptionTemplateBaseFieldDataPersist, DescriptionTemplateComboBoxOptionPersist, DescriptionTemplateDefinitionPersist, DescriptionTemplateFieldPersist, DescriptionTemplateFieldSetPersist, DescriptionTemplateMultiplicityPersist, DescriptionTemplatePagePersist, DescriptionTemplatePersist, DescriptionTemplatePlaceholderAndMultiplicityDataPersist, DescriptionTemplateRadioBoxDataPersist, DescriptionTemplateRadioBoxOptionPersist, DescriptionTemplateRulePersist, DescriptionTemplateSectionPersist, DescriptionTemplateUploadDataPersist, DescriptionTemplateUploadOptionPersist, DescriptionTemplateWordListDataPersist, UserDescriptionTemplatePersist } from "@app/core/model/description-template/description-template-persist";
import { BaseEditorModel } from "@common/base/base-form-editor-model";
import { BackendErrorValidator } from "@common/forms/validation/custom-validator";
import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model";
@ -15,7 +18,8 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
language: string;
type: Guid;
status: DescriptionTemplateStatus = DescriptionTemplateStatus.Draft;
definition: DescriptionTemplateDefinitionEditorModel;
definition: DescriptionTemplateDefinitionEditorModel = new DescriptionTemplateDefinitionEditorModel();
users: UserDescriptionTemplateEditorModel[] = [];
permissions: string[];
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
@ -30,6 +34,7 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
this.status = item.status;
this.description = item.description;
this.definition = new DescriptionTemplateDefinitionEditorModel().fromModel(item.definition);
if (item.users) { item.users.map(x => this.users.push(new UserDescriptionTemplateEditorModel().fromModel(x))); }
}
return this;
}
@ -47,6 +52,15 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
definition: this.definition.buildForm({
rootPath: `definition.`
}),
users: this.formBuilder.array(
(this.users ?? []).map(
(item, index) => new UserDescriptionTemplateEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `users[${index}].`
}), context.getValidation('users')
)
),
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators]
});
}
@ -61,6 +75,7 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'type')] });
baseValidationArray.push({ key: 'type', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'type')] });
baseValidationArray.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
baseValidationArray.push({ key: 'users', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'users')] });
baseValidationArray.push({ key: 'hash', validators: [] });
baseContext.validation = baseValidationArray;
@ -68,6 +83,60 @@ export class DescriptionTemplateEditorModel extends BaseEditorModel implements D
}
}
export class UserDescriptionTemplateEditorModel implements UserDescriptionTemplatePersist {
userId?: Guid;
role?: UserDescriptionTemplateRole;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
public fromModel(item: UserDescriptionTemplatePersist): UserDescriptionTemplateEditorModel {
if (item) {
this.userId = item.userId;
this.role = item.role;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = UserDescriptionTemplateEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
userId: [{ value: this.userId, disabled: disabled }, context.getValidation('userId').validators],
role: [{ value: this.role, disabled: disabled }, context.getValidation('role').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'userId', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}userId`)] });
baseValidationArray.push({ key: 'role', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}role`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
export class DescriptionTemplateDefinitionEditorModel implements DescriptionTemplateDefinitionPersist {
pages: DescriptionTemplatePageEditorModel[] = [];
sections: DescriptionTemplateSectionEditorModel[] = [];
@ -199,8 +268,8 @@ export class DescriptionTemplatePageEditorModel implements DescriptionTemplatePa
export class DescriptionTemplateSectionEditorModel implements DescriptionTemplateSectionPersist {
id: Guid;
ordinal: number;
defaultVisibility: boolean;
multiplicity: boolean;
defaultVisibility: boolean = false; // TODO: check if used and remove
multiplicity: boolean = false;
page: string;
title: string;
description: string;
@ -280,8 +349,8 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}id`)] });
baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] });
baseValidationArray.push({ key: 'defaultVisibility', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}defaultVisibility`)] });
baseValidationArray.push({ key: 'multiplicity', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}multiplicity`)] });
baseValidationArray.push({ key: 'defaultVisibility', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}defaultVisibility`)] });
baseValidationArray.push({ key: 'multiplicity', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}multiplicity`)] });
baseValidationArray.push({ key: 'page', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}page`)] });
baseValidationArray.push({ key: 'title', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}title`)] });
baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}description`)] });
@ -297,13 +366,13 @@ export class DescriptionTemplateSectionEditorModel implements DescriptionTemplat
export class DescriptionTemplateFieldSetEditorModel implements DescriptionTemplateFieldSetPersist {
id: Guid;
ordinal: number;
numbering: string;
numbering: string = "0"; // Check if used and remove
title: string;
description: string;
extendedDescription: string;
additionalInformation: string;
multiplicity: DescriptionTemplateMultiplicityEditorModel;
hasCommentField: boolean;
multiplicity: DescriptionTemplateMultiplicityEditorModel = new DescriptionTemplateMultiplicityEditorModel();
hasCommentField: boolean = false;
fields: DescriptionTemplateFieldEditorModel[] = [];
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
@ -441,7 +510,7 @@ export class DescriptionTemplateMultiplicityEditorModel implements DescriptionTe
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'min', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}min`)] });
baseValidationArray.push({ key: 'max', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}max`)] });
baseValidationArray.push({ key: 'max', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}max`)] });
baseValidationArray.push({ key: 'placeholder', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}placeholder`)] });
baseValidationArray.push({ key: 'tableView', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}tableView`)] });
@ -450,15 +519,20 @@ export class DescriptionTemplateMultiplicityEditorModel implements DescriptionTe
}
}
//
//
// Field Editor Model
//
//
export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateFieldPersist {
id: Guid;
ordinal: number;
schematics: string[];
defaultValue: string;
visibilityRules: DescriptionTemplateRuleEditorModel[] = [];
validations: DescriptionTemplateFieldValidationType[];
includeInExport: boolean;
data: DescriptionTemplateBaseFieldDataPersist;
validations: DescriptionTemplateFieldValidationType[] = [];
includeInExport: boolean = false;
data: DescriptionTemplateBaseFieldEditorModel = new DescriptionTemplateBaseFieldEditorModel();
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
@ -475,7 +549,7 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF
this.validations = item.validations;
this.includeInExport = item.includeInExport;
//this.data = new DescriptionTemplateBaseFieldDataEditorModel().fromModel(item.data);
this.data = this.getFieldEditorModel(item.data.fieldType).fromModel(item.data);
if (item.visibilityRules) { item.visibilityRules.map(x => this.visibilityRules.push(new DescriptionTemplateRuleEditorModel().fromModel(x))); }
}
return this;
@ -501,9 +575,9 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF
defaultValue: [{ value: this.defaultValue, disabled: disabled }, context.getValidation('defaultValue').validators],
validations: [{ value: this.validations, disabled: disabled }, context.getValidation('validations').validators],
includeInExport: [{ value: this.includeInExport, disabled: disabled }, context.getValidation('includeInExport').validators],
// data: this.data.buildForm({
// rootPath: `data.`
// }),
data: this.data.buildForm({
rootPath: `data.`
}),
visibilityRules: this.formBuilder.array(
(this.visibilityRules ?? []).map(
(item, index) => new DescriptionTemplateRuleEditorModel(
@ -535,6 +609,684 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF
baseContext.validation = baseValidationArray;
return baseContext;
}
private getFieldEditorModel(fieldType: DescriptionTemplateFieldType): DescriptionTemplateBaseFieldEditorModel {
switch (fieldType) {
case DescriptionTemplateFieldType.AUTO_COMPLETE:
return new DescriptionTemplateAutoCompleteFieldEditorModel();
case DescriptionTemplateFieldType.RADIO_BOX:
return new DescriptionTemplateRadioBoxFieldEditorModel();
case DescriptionTemplateFieldType.WORD_LIST:
return new DescriptionTemplateRadioBoxFieldEditorModel();
case DescriptionTemplateFieldType.BOOLEAN_DECISION:
case DescriptionTemplateFieldType.CHECK_BOX:
case DescriptionTemplateFieldType.FREE_TEXT:
case DescriptionTemplateFieldType.TEXT_AREA:
case DescriptionTemplateFieldType.RICH_TEXT_AREA:
case DescriptionTemplateFieldType.DATE_PICKER:
case DescriptionTemplateFieldType.TAGS:
case DescriptionTemplateFieldType.DATASET_IDENTIFIER:
case DescriptionTemplateFieldType.CURRENCY:
case DescriptionTemplateFieldType.VALIDATION:
return new DescriptionTemplateBaseFieldEditorModel();
case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_RESEARCHERS:
case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DMPS:
case DescriptionTemplateFieldType.INTERNAL_DMP_ENTRIES_DATASETS:
case DescriptionTemplateFieldType.EXTERNAL_DATASETS:
case DescriptionTemplateFieldType.DATA_REPOSITORIES:
case DescriptionTemplateFieldType.JOURNAL_REPOSITORIES:
case DescriptionTemplateFieldType.PUB_REPOSITORIES:
case DescriptionTemplateFieldType.LICENSES:
case DescriptionTemplateFieldType.TAXONOMIES:
case DescriptionTemplateFieldType.PUBLICATIONS:
case DescriptionTemplateFieldType.REGISTRIES:
case DescriptionTemplateFieldType.SERVICES:
case DescriptionTemplateFieldType.RESEARCHERS:
case DescriptionTemplateFieldType.ORGANIZATIONS:
return new DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel();
case DescriptionTemplateFieldType.UPLOAD:
return new DescriptionTemplateUploadFieldEditorModel();
}
}
}
export class DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplateBaseFieldDataPersist {
label: string;
fieldType: DescriptionTemplateFieldType;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(item: DescriptionTemplateBaseFieldDataPersist): DescriptionTemplateBaseFieldEditorModel {
if (item) {
this.label = item.label;
this.fieldType = item.fieldType;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateBaseFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
fieldType: [{ value: this.fieldType, disabled: disabled }, context.getValidation('fieldType').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'label', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] });
baseValidationArray.push({ key: 'fieldType', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}fieldType`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
export class DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel extends DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplatePlaceholderAndMultiplicityDataPersist {
multiAutoComplete: boolean;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { super(validationErrorModel); }
fromModel(item: DescriptionTemplatePlaceholderAndMultiplicityDataPersist): DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel {
if (item) {
super.fromModel(item);
this.multiAutoComplete = item.multiAutoComplete;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplatePlaceholderAndMultiplicityFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
const formGroup = super.buildForm({ context, disabled, rootPath });
formGroup.setControl('multiAutoComplete', new FormControl({ value: this.multiAutoComplete, disabled: disabled }, context.getValidation('multiAutoComplete').validators));
return formGroup;
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = super.createValidationContext({ rootPath, validationErrorModel });
baseContext.validation.push({ key: 'multiAutoComplete', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}multiAutoComplete`)] });
return baseContext;
}
}
//
//
// Autocomplete Field
//
//
export class DescriptionTemplateAutoCompleteFieldEditorModel extends DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplateAutoCompleteDataPersist {
multiAutoComplete: boolean;
autoCompleteSingleDataList: DescriptionTemplateAutoCompleteSingleDataEditorModel[] = [];
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { super(validationErrorModel); }
fromModel(item: DescriptionTemplateAutoCompleteDataPersist): DescriptionTemplateAutoCompleteFieldEditorModel {
if (item) {
super.fromModel(item);
this.multiAutoComplete = item.multiAutoComplete;
if (item.autoCompleteSingleDataList) { item.autoCompleteSingleDataList.map(x => this.autoCompleteSingleDataList.push(new DescriptionTemplateAutoCompleteSingleDataEditorModel().fromModel(x))); }
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateAutoCompleteFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
const formGroup = super.buildForm({ context, disabled, rootPath });
formGroup.setControl('multiAutoComplete', new FormControl({ value: this.multiAutoComplete, disabled: disabled }, context.getValidation('multiAutoComplete').validators));
formGroup.setControl('autoCompleteSingleDataList', this.formBuilder.array(
(this.autoCompleteSingleDataList ?? []).map(
(item, index) => new DescriptionTemplateAutoCompleteSingleDataEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `autoCompleteSingleDataList[${index}].`
}), context.getValidation('autoCompleteSingleDataList')
)));
return formGroup;
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = super.createValidationContext({ rootPath, validationErrorModel });
baseContext.validation.push({ key: 'multiAutoComplete', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}multiAutoComplete`)] });
baseContext.validation.push({ key: 'autoCompleteSingleDataList', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}autoCompleteSingleDataList`)] });
return baseContext;
}
}
export class DescriptionTemplateAutoCompleteSingleDataEditorModel implements DescriptionTemplateAutoCompleteSingleDataPersist {
autocompleteType: DescriptionTemplateFieldAutocompleteType;
url: string;
autoCompleteOptions: DescriptionTemplateComboBoxOptionEditorModel = new DescriptionTemplateComboBoxOptionEditorModel();
optionsRoot: string;
hasAuth: boolean;
auth: DescriptionTemplateAuthAutoCompleteDataEditorModel = new DescriptionTemplateAuthAutoCompleteDataEditorModel();
method: string;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(item: DescriptionTemplateAutoCompleteSingleDataPersist): DescriptionTemplateAutoCompleteSingleDataEditorModel {
if (item) {
this.autocompleteType = item.autocompleteType;
this.url = item.url;
this.autoCompleteOptions = new DescriptionTemplateComboBoxOptionEditorModel().fromModel(item.autoCompleteOptions);
this.optionsRoot = item.optionsRoot;
this.hasAuth = item.hasAuth;
this.auth = new DescriptionTemplateAuthAutoCompleteDataEditorModel().fromModel(item.auth);
this.method = item.method;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateAutoCompleteSingleDataEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
autocompleteType: [{ value: this.autocompleteType, disabled: disabled }, context.getValidation('autocompleteType').validators],
url: [{ value: this.url, disabled: disabled }, context.getValidation('url').validators],
optionsRoot: [{ value: this.optionsRoot, disabled: disabled }, context.getValidation('optionsRoot').validators],
hasAuth: [{ value: this.hasAuth, disabled: disabled }, context.getValidation('hasAuth').validators],
method: [{ value: this.method, disabled: disabled }, context.getValidation('method').validators],
autoCompleteOptions: this.autoCompleteOptions.buildForm({
rootPath: `autoCompleteOptions.`
}),
auth: this.auth.buildForm({
rootPath: `auth.`
}),
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'autocompleteType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}autocompleteType`)] });
baseValidationArray.push({ key: 'url', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}url`)] });
baseValidationArray.push({ key: 'optionsRoot', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}optionsRoot`)] });
baseValidationArray.push({ key: 'hasAuth', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}hasAuth`)] });
baseValidationArray.push({ key: 'method', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}method`)] });
baseValidationArray.push({ key: 'extendedDescription', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}extendedDescription`)] });
baseValidationArray.push({ key: 'additionalInformation', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}additionalInformation`)] });
baseValidationArray.push({ key: 'hasCommentField', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}hasCommentField`)] });
baseValidationArray.push({ key: 'fields', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fields`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
export class DescriptionTemplateComboBoxOptionEditorModel implements DescriptionTemplateComboBoxOptionPersist {
label: string;
value: string;
source: string;
uri: string;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(item: DescriptionTemplateComboBoxOptionPersist): DescriptionTemplateComboBoxOptionEditorModel {
if (item) {
this.label = item.label;
this.value = item.value;
this.source = item.source;
this.uri = item.uri;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateComboBoxOptionEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators],
source: [{ value: this.source, disabled: disabled }, context.getValidation('source').validators],
uri: [{ value: this.uri, disabled: disabled }, context.getValidation('uri').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'label', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] });
baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] });
baseValidationArray.push({ key: 'source', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}source`)] });
baseValidationArray.push({ key: 'uri', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}uri`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
export class DescriptionTemplateAuthAutoCompleteDataEditorModel implements DescriptionTemplateAuthAutoCompleteDataPersist {
url: string;
method: string;
body: string;
path: string;
type: string;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(item: DescriptionTemplateAuthAutoCompleteDataPersist): DescriptionTemplateAuthAutoCompleteDataEditorModel {
if (item) {
this.url = item.url;
this.method = item.method;
this.body = item.body;
this.path = item.path;
this.type = item.type;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateAuthAutoCompleteDataEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
url: [{ value: this.url, disabled: disabled }, context.getValidation('url').validators],
method: [{ value: this.method, disabled: disabled }, context.getValidation('method').validators],
body: [{ value: this.body, disabled: disabled }, context.getValidation('body').validators],
path: [{ value: this.path, disabled: disabled }, context.getValidation('path').validators],
type: [{ value: this.type, disabled: disabled }, context.getValidation('type').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'url', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}url`)] });
baseValidationArray.push({ key: 'method', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}method`)] });
baseValidationArray.push({ key: 'body', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}body`)] });
baseValidationArray.push({ key: 'path', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}path`)] });
baseValidationArray.push({ key: 'type', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}type`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
//
//
// Radiobox Field
//
//
export class DescriptionTemplateRadioBoxFieldEditorModel extends DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplateRadioBoxDataPersist {
options: DescriptionTemplateRadioBoxDataEditorModel[] = [];
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { super(validationErrorModel); }
fromModel(item: DescriptionTemplateRadioBoxDataPersist): DescriptionTemplateRadioBoxFieldEditorModel {
if (item) {
super.fromModel(item);
if (item.options) { item.options.map(x => this.options.push(new DescriptionTemplateRadioBoxDataEditorModel().fromModel(x))); }
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateRadioBoxFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
const formGroup = super.buildForm({ context, disabled, rootPath });
formGroup.setControl('options', this.formBuilder.array(
(this.options ?? []).map(
(item, index) => new DescriptionTemplateRadioBoxDataEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `options[${index}].`
}), context.getValidation('options')
)));
return formGroup;
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = super.createValidationContext({ rootPath, validationErrorModel });
baseContext.validation.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}options`)] });
return baseContext;
}
}
export class DescriptionTemplateRadioBoxDataEditorModel implements DescriptionTemplateRadioBoxOptionPersist {
label: string;
value: string;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(item: DescriptionTemplateRadioBoxOptionPersist): DescriptionTemplateRadioBoxDataEditorModel {
if (item) {
this.label = item.label;
this.value = item.value;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateRadioBoxDataEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'label', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] });
baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
//
//
// Wordlist Field
//
//
export class DescriptionTemplateWordListFieldEditorModel extends DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplateWordListDataPersist {
options: DescriptionTemplateComboBoxOptionEditorModel[] = [];
multiList: boolean;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { super(validationErrorModel); }
fromModel(item: DescriptionTemplateWordListDataPersist): DescriptionTemplateWordListFieldEditorModel {
if (item) {
super.fromModel(item);
this.multiList = item.multiList;
if (item.options) { item.options.map(x => this.options.push(new DescriptionTemplateComboBoxOptionEditorModel().fromModel(x))); }
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateWordListFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
const formGroup = super.buildForm({ context, disabled, rootPath });
formGroup.setControl('multiList', new FormControl({ value: this.multiList, disabled: disabled }, context.getValidation('multiList').validators));
formGroup.setControl('options', this.formBuilder.array(
(this.options ?? []).map(
(item, index) => new DescriptionTemplateComboBoxOptionEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `options[${index}].`
}), context.getValidation('options')
)));
return formGroup;
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = super.createValidationContext({ rootPath, validationErrorModel });
baseContext.validation.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}options`)] });
baseContext.validation.push({ key: 'multiList', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}multiList`)] });
return baseContext;
}
}
//
//
// Upload Field
//
//
export class DescriptionTemplateUploadFieldEditorModel extends DescriptionTemplateBaseFieldEditorModel implements DescriptionTemplateUploadDataPersist {
types: DescriptionTemplateUploadOptionEditorModel[] = [];
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { super(validationErrorModel); }
fromModel(item: DescriptionTemplateUploadDataPersist): DescriptionTemplateUploadFieldEditorModel {
if (item) {
super.fromModel(item);
if (item.types) { item.types.map(x => this.types.push(new DescriptionTemplateUploadOptionEditorModel().fromModel(x))); }
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateUploadFieldEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
const formGroup = super.buildForm({ context, disabled, rootPath });
formGroup.setControl('types', this.formBuilder.array(
(this.types ?? []).map(
(item, index) => new DescriptionTemplateUploadOptionEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `types[${index}].`
}), context.getValidation('types')
)));
return formGroup;
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = super.createValidationContext({ rootPath, validationErrorModel });
baseContext.validation.push({ key: 'types', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}types`)] });
return baseContext;
}
}
export class DescriptionTemplateUploadOptionEditorModel implements DescriptionTemplateUploadOptionPersist {
label: string;
value: string;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { }
fromModel(item: DescriptionTemplateUploadOptionPersist): DescriptionTemplateUploadOptionEditorModel {
if (item) {
this.label = item.label;
this.value = item.value;
}
return this;
}
buildForm(params?: {
context?: ValidationContext,
disabled?: boolean,
rootPath?: string
}): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) {
context = DescriptionTemplateUploadOptionEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel,
rootPath
});
}
return this.formBuilder.group({
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators],
});
}
static createValidationContext(params: {
rootPath?: string,
validationErrorModel: ValidationErrorModel
}): ValidationContext {
const { rootPath = '', validationErrorModel } = params;
const baseContext: ValidationContext = new ValidationContext();
const baseValidationArray: Validation[] = new Array<Validation>();
baseValidationArray.push({ key: 'label', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] });
baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] });
baseContext.validation = baseValidationArray;
return baseContext;
}
}
export class DescriptionTemplateRuleEditorModel implements DescriptionTemplateRulePersist {
@ -588,68 +1340,4 @@ export class DescriptionTemplateRuleEditorModel implements DescriptionTemplateRu
baseContext.validation = baseValidationArray;
return baseContext;
}
}
// export class DescriptionTemplatesInSectionEditorModel implements DescriptionTemplatesInSectionPersist {
// id: Guid;
// descriptionTemplateId: Guid;
// label: string;
// minMultiplicity: number;
// maxMultiplicity: number;
// protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
// constructor(
// public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
// ) { }
// fromModel(item: DescriptionTemplatesInSection): DescriptionTemplatesInSectionEditorModel {
// this.id = item.id;
// this.descriptionTemplateId = item.descriptionTemplateId;
// this.label = item.label;
// this.minMultiplicity = item.minMultiplicity;
// this.maxMultiplicity = item.maxMultiplicity;
// return this;
// }
// buildForm(params?: {
// context?: ValidationContext,
// disabled?: boolean,
// rootPath?: string
// }): UntypedFormGroup {
// let { context = null, disabled = false, rootPath } = params ?? {}
// if (context == null) {
// context = DescriptionTemplatesInSectionEditorModel.createValidationContext({
// validationErrorModel: this.validationErrorModel,
// rootPath
// });
// }
// return this.formBuilder.group({
// id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators],
// descriptionTemplateId: [{ value: this.descriptionTemplateId, disabled: disabled }, context.getValidation('descriptionTemplateId').validators],
// label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
// minMultiplicity: [{ value: this.minMultiplicity, disabled: disabled }, context.getValidation('minMultiplicity').validators],
// maxMultiplicity: [{ value: this.maxMultiplicity, disabled: disabled }, context.getValidation('maxMultiplicity').validators],
// });
// }
// static createValidationContext(params: {
// rootPath?: string,
// validationErrorModel: ValidationErrorModel
// }): ValidationContext {
// const { rootPath = '', validationErrorModel } = params;
// const baseContext: ValidationContext = new ValidationContext();
// const baseValidationArray: Validation[] = new Array<Validation>();
// baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}id`)] });
// baseValidationArray.push({ key: 'descriptionTemplateId', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}descriptionTemplateId`)] });
// baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}label`)] });
// baseValidationArray.push({ key: 'minMultiplicity', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}minMultiplicity`)] });
// baseValidationArray.push({ key: 'maxMultiplicity', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}maxMultiplicity`)] });
// baseContext.validation = baseValidationArray;
// return baseContext;
// }
// }
}

View File

@ -65,6 +65,7 @@ export class DescriptionTemplateEditorResolver extends BaseEditorResolver {
[nameof<DescriptionTemplate>(x => x.definition), nameof<DescriptionTemplateDefinition>(x => x.sections), nameof<DescriptionTemplateSection>(x => x.fieldSets), nameof<DescriptionTemplateFieldSet>(x => x.fields), nameof<DescriptionTemplateField>(x => x.visibilityRules), nameof<DescriptionTemplateRule>(x => x.target)].join('.'),
[nameof<DescriptionTemplate>(x => x.definition), nameof<DescriptionTemplateDefinition>(x => x.sections), nameof<DescriptionTemplateSection>(x => x.fieldSets), nameof<DescriptionTemplateFieldSet>(x => x.fields), nameof<DescriptionTemplateField>(x => x.visibilityRules), nameof<DescriptionTemplateRule>(x => x.value)].join('.'),
[nameof<DescriptionTemplate>(x => x.definition), nameof<DescriptionTemplateDefinition>(x => x.sections), nameof<DescriptionTemplateSection>(x => x.fieldSets), nameof<DescriptionTemplateFieldSet>(x => x.fields), nameof<DescriptionTemplateField>(x => x.data), nameof<DescriptionTemplateBaseFieldData>(x => x.label)].join('.'),
[nameof<DescriptionTemplate>(x => x.definition), nameof<DescriptionTemplateDefinition>(x => x.sections), nameof<DescriptionTemplateSection>(x => x.fieldSets), nameof<DescriptionTemplateFieldSet>(x => x.fields), nameof<DescriptionTemplateField>(x => x.data), nameof<DescriptionTemplateBaseFieldData>(x => x.fieldType)].join('.'),
nameof<DescriptionTemplate>(x => x.createdAt),
nameof<DescriptionTemplate>(x => x.hash),

View File

@ -136,7 +136,7 @@
<!-- <div *ngIf="links && !viewOnly && !(parentLink?.subEntriesType == tocEntryType.Page) " > -->
<ng-container *ngIf="selectedItemInLinks && (link.type != tocEntryType.Page) && isLast && (!viewOnly)">
<button class="mat-button add-new-entry" style="padding-left: 0px;" (click)="createNewEntry({childType:link.type,parent:parentLink})">
<button mat-button class="add-new-entry" style="padding-left: 0px;" (click)="createNewEntry({childType:link.type,parent:parentLink})">
<!-- <mat-icon>add</mat-icon> -->
<ng-container [ngSwitch]="link.type">
<ng-container *ngSwitchCase="tocEntryType.Section">
@ -181,13 +181,13 @@
<div class="ml-3">
<!-- Give option to generate fieldset (only if parent is section) -->
<button *ngIf="parentLink.type == tocEntryType.Section" class="mat-button" style="padding-left: 0px;" (click)="createNewEntry({childType:tocEntryType.FieldSet,parent:parentLink})">
<button *ngIf="parentLink.type == tocEntryType.Section" mat-button style="padding-left: 0px;" (click)="createNewEntry({childType:tocEntryType.FieldSet,parent:parentLink})">
<img src="/assets/images/editor/icons/add_input_set.svg" alt="" style="margin-left: -0.2em;" class="add-input-icon">
{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.TOOLKIT.NEW-INPUT-SET' | translate}}
</button>
<!-- Give option to generate section -->
<button class="mat-button" style="padding-left: 0px; display: block;" (click)="createNewEntry({childType:tocEntryType.Section,parent:parentLink})">
<button mat-button style="padding-left: 0px; display: block;" (click)="createNewEntry({childType:tocEntryType.Section,parent:parentLink})">
<!-- <mat-icon>add</mat-icon> -->
<!-- Subsection + -->
@ -231,7 +231,7 @@
<!-- Only for the page -->
<!-- style="margin-left: -0.5em;" -->
<div *ngIf="parentLink?.subEntriesType == tocEntryType.Page && !viewOnly" >
<button class="mat-button mt-2" (click)="createNewEntry({childType:parentLink.subEntriesType,parent:parentLink})" style="padding-left:0px">
<button mat-button class="mt-2" (click)="createNewEntry({childType:parentLink.subEntriesType,parent:parentLink})" style="padding-left:0px">
<!-- <mat-icon>add</mat-icon> -->
<div class="d-flex" style="align-items: center;" >
<mat-icon color="accent" style="font-size: 1.6em;margin-left: -0.3em;">add</mat-icon>

View File

@ -16,7 +16,7 @@
</div>
<div class="col-auto">
<button mat-raised-button class="create-btn" *ngIf="authService.hasPermission(authService.permissionEnum.EditDescriptionTemplateType)" [routerLink]="['/description-template/new']">
<button mat-raised-button class="create-btn" *ngIf="authService.hasPermission(authService.permissionEnum.EditDescriptionTemplate)" [routerLink]="['/description-templates/new']">
<mat-icon>add</mat-icon>
{{'DESCRIPTION-TEMPLATE-LISTING.CREATE-DESCRIPTION-TEMPLATE' | translate}}
</button>

View File

@ -3,7 +3,6 @@
<div class="row justify-content-between align-items-center">
<div class="col">
<!-- <h3 *ngIf="isNew">{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.NEW' | translate}}</h3> -->
<app-navigation-breadcrumb />
</div>
@ -33,7 +32,6 @@
<mat-card appearance="outlined">
<mat-card-header>
<mat-card-title *ngIf="isNew">{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.NEW' | translate}}</mat-card-title>
<!-- <mat-card-title *ngIf="!isNew">{{formGroup.get('name').value}}</mat-card-title> -->
</mat-card-header>
<mat-card-content>
<form (ngSubmit)="formSubmit()" [formGroup]="formGroup" *ngIf="formGroup">
@ -57,43 +55,4 @@
</mat-card-content>
</mat-card>
</div>
</div>
<!-- <div class="main-content">
<div class="container-fluid description-type-editor">
<div class="row align-items-center mb-4" *ngIf="formGroup">
<div class="col-auto">
<h3>{{'DESCRIPTION-TYPE-EDITOR.NEW' | translate}}</h3>
</div>
</div>
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
<mat-card style="padding: 2em;">
<mat-card-content>
<div class="row" style="gap:1em">
<mat-form-field class="col-lg-6">
<input matInput placeholder="{{'DESCRIPTION-TYPE-EDITOR.FIELDS.LABEL' | translate}}" type="text" name="name" formControlName="name"
required>
<mat-error *ngIf="formGroup.get('name').hasError('backendError')">
{{formGroup.get('name').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('name').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="row mt-4">
<div class="col-auto">
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.CANCEL' | translate}}</button>
</div>
<div class="col"></div>
<div class="col-auto">
<button mat-button *ngIf="formGroup.get('status').value!=1" class="action-btn" (click)="finalize()"
[disabled]="!this.isFormValid()" type="button">{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
<button mat-button class="action-btn ml-3" type="submit" [disabled]="!this.isFormValid() || viewOnly">
{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.SAVE' | translate}}
</button>
</div>
</div>
</mat-card-content>
</mat-card>
</form>
</div>
</div> -->
</div>

View File

@ -62,7 +62,6 @@ export class DmpBlueprintEditorModel extends BaseEditorModel implements DmpBluep
export class DmpBlueprintDefinitionEditorModel implements DmpBlueprintDefinitionPersist {
sections: DmpBlueprintDefinitionSectionEditorModel[] = [];
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
constructor(
@ -95,7 +94,7 @@ export class DmpBlueprintDefinitionEditorModel implements DmpBlueprintDefinition
(item, index) => new DmpBlueprintDefinitionSectionEditorModel(
this.validationErrorModel
).fromModel(item).buildForm({
rootPath: `sections[${index}].`
rootPath: `${rootPath}sections[${index}].`
}), context.getValidation('sections')
)
),

View File

@ -3,7 +3,7 @@ import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormContr
import { AppRole } from '@app/core/common/enum/app-role';
import { UserListingModel } from '@app/core/model/user/user-listing';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { UserService } from '@app/core/services/user/user.service';
import { UserServiceOld } from '@app/core/services/user/user.service-old';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
@ -23,7 +23,7 @@ export class UserRoleEditorComponent extends BaseComponent implements OnInit {
constructor(
private language: TranslateService,
private userService: UserService,
private userService: UserServiceOld,
private formBuilder: UntypedFormBuilder,
private enumUtils: EnumUtils,
private uiNotificationService: UiNotificationService

View File

@ -15,7 +15,7 @@ import { catchError, map, startWith, switchMap, takeUntil } from 'rxjs/operators
import { DataTableRequest } from '../../../../core/model/data-table/data-table-request';
import { UserListingModel } from '../../../../core/model/user/user-listing';
import { UserCriteria } from '../../../../core/query/user/user-criteria';
import { UserService } from '../../../../core/services/user/user.service';
import { UserServiceOld } from '../../../../core/services/user/user.service-old';
import { SnackBarNotificationComponent } from '../../../../library/notification/snack-bar/snack-bar-notification.component';
// import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item';
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
@ -26,7 +26,7 @@ export class UsersDataSource extends DataSource<UserListingModel> {
totalCount = 0;
constructor(
private _service: UserService,
private _service: UserServiceOld,
private _paginator: MatPaginator,
private _sort: MatSort,
private _languageService: TranslateService,
@ -108,7 +108,7 @@ export class UserListingComponent extends BaseComponent implements OnInit, After
displayedColumns: String[] = ['avatar', 'name', 'email', 'lastloggedin', 'roles'];
constructor(
private userService: UserService,
private userService: UserServiceOld,
private languageService: TranslateService,
public snackBar: MatSnackBar,
private httpClient: HttpClient,

View File

@ -16,7 +16,7 @@ import { DatasetService } from '@app/core/services/dataset/dataset.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { GrantService } from '@app/core/services/grant/grant.service';
import { SearchBarService } from '@app/core/services/search-bar/search-bar.service';
import { UserService } from '@app/core/services/user/user.service';
import { UserServiceOld } from '@app/core/services/user/user.service-old';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { BaseComponent } from '@common/base/base.component';
import { Observable, of as observableOf } from 'rxjs';
@ -80,7 +80,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
private dashboardService: DashboardService,
private searchBarService: SearchBarService,
private authentication: AuthService,
private userService: UserService,
private userService: UserServiceOld,
private dialog: MatDialog,
private language: TranslateService,
private uiNotificationService: UiNotificationService,

View File

@ -138,10 +138,6 @@
<button mat-menu-item (click)="deleteDatasetClicked(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}
</button>
<!-- <button mat-menu-item *ngIf="needsUpdate(activity)" class="menu-item" (click)="openUpdateDatasetProfileDialogue(activity.id);">
<mat-icon>update</mat-icon>
{{ 'DATASET-WIZARD.ACTIONS.UPDATE-DATASET-PROFILE' | translate }}
</button> -->
</mat-menu>
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(activity)">

View File

@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { RecentActivityType } from '@app/core/common/enum/recent-activity-type';
import { UserService } from '@app/core/services/user/user.service';
import { UserServiceOld } from '@app/core/services/user/user.service-old';
import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from 'rxjs/operators';
@ -19,7 +19,7 @@ export class RecentActivityComponent extends BaseComponent implements OnInit {
constructor(
private router: Router,
private userService: UserService
private userService: UserServiceOld
) { super(); }
ngOnInit() {

View File

@ -145,10 +145,6 @@
<button mat-menu-item (click)="deleteDatasetClicked(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}
</button>
<!-- <button mat-menu-item *ngIf="needsUpdate(activity)" class="menu-item" (click)="openUpdateDatasetProfileDialogue(activity.id);">
<mat-icon>update</mat-icon>
{{ 'DATASET-WIZARD.ACTIONS.UPDATE-DATASET-PROFILE' | translate }}
</button> -->
</mat-menu>
<mat-menu #exportMenu="matMenu" xPosition="before">

Some files were not shown because too many files have changed in this diff Show More