Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring
# Conflicts: # dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.html
This commit is contained in:
commit
63a8820681
|
@ -95,6 +95,10 @@ public class Dmp {
|
|||
|
||||
public static final String _dmpUsers = "dmpUsers";
|
||||
|
||||
private List<Description> descriptions;
|
||||
|
||||
public static final String _descriptions = "descriptions";
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -262,4 +266,12 @@ public class Dmp {
|
|||
public void setVersionStatus(DmpVersionStatus versionStatus) {
|
||||
this.versionStatus = versionStatus;
|
||||
}
|
||||
|
||||
public List<Description> getDescriptions() {
|
||||
return descriptions;
|
||||
}
|
||||
|
||||
public void setDescriptions(List<Description> descriptions) {
|
||||
this.descriptions = descriptions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,7 @@ import eu.eudat.authorization.AuthorizationFlags;
|
|||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.data.DmpEntity;
|
||||
import eu.eudat.model.*;
|
||||
import eu.eudat.query.DmpBlueprintQuery;
|
||||
import eu.eudat.query.DmpReferenceQuery;
|
||||
import eu.eudat.query.DmpUserQuery;
|
||||
import eu.eudat.query.UserQuery;
|
||||
import eu.eudat.query.*;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
|
@ -69,6 +66,9 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
|
|||
FieldSet blueprintFields = fields.extractPrefixed(this.asPrefix(Dmp._blueprint));
|
||||
Map<UUID, DmpBlueprint> blueprintItemsMap = this.collectDmpBlueprints(blueprintFields, data);
|
||||
|
||||
FieldSet descriptionsFields = fields.extractPrefixed(this.asPrefix(Dmp._descriptions));
|
||||
Map<UUID, List<Description>> descriptionsMap = this.collectDmpDescriptions(descriptionsFields, data);
|
||||
|
||||
for (DmpEntity d : data) {
|
||||
Dmp m = new Dmp();
|
||||
if (fields.hasField(this.asIndexer(Dmp._id))) m.setId(d.getId());
|
||||
|
@ -91,6 +91,7 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
|
|||
if (!blueprintFields.isEmpty() && blueprintItemsMap != null && blueprintItemsMap.containsKey(d.getBlueprintId())) m.setBlueprint(blueprintItemsMap.get(d.getBlueprintId()));
|
||||
if (dmpReferencesMap != null && !dmpReferencesMap.isEmpty() && dmpReferencesMap.containsKey(d.getId())) m.setDmpReferences(dmpReferencesMap.get(d.getId()));
|
||||
if (dmpUsersMap != null && !dmpUsersMap.isEmpty() && dmpUsersMap.containsKey(d.getId())) m.setDmpUsers(dmpUsersMap.get(d.getId()));
|
||||
if (descriptionsMap != null && !descriptionsMap.isEmpty() && descriptionsMap.containsKey(d.getId())) m.setDescriptions(descriptionsMap.get(d.getId()));
|
||||
|
||||
models.add(m);
|
||||
}
|
||||
|
@ -196,4 +197,23 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
|
|||
return itemMap;
|
||||
}
|
||||
|
||||
private Map<UUID, List<Description>> collectDmpDescriptions(FieldSet fields, List<DmpEntity> data) throws MyApplicationException {
|
||||
if (fields.isEmpty() || data.isEmpty()) return null;
|
||||
this.logger.debug("checking related - {}", Description.class.getSimpleName());
|
||||
|
||||
Map<UUID, List<Description>> itemMap;
|
||||
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(this.asIndexer(Description._dmp, Dmp._id));
|
||||
DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).authorize(this.authorize).ids(data.stream().map(DmpEntity::getId).distinct().collect(Collectors.toList()));
|
||||
DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(this.authorize).dmpSubQuery(dmpQuery);
|
||||
itemMap = this.builderFactory.builder(DescriptionBuilder.class).authorize(this.authorize).asMasterKey(query, clone, x -> x.getDmp().getId());
|
||||
|
||||
if (!fields.hasField(this.asIndexer(Description._dmp, Dmp._id))) {
|
||||
itemMap.values().stream().flatMap(List::stream).filter(x -> x != null && x.getDmp() != null).peek(x -> {
|
||||
x.getDmp().setId(null);
|
||||
});
|
||||
}
|
||||
|
||||
return itemMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ const appRoutes: Routes = [
|
|||
}
|
||||
},
|
||||
{
|
||||
path: 'datasets',
|
||||
loadChildren: () => import('./ui/dataset/dataset.module').then(m => m.DatasetModule),
|
||||
path: 'descriptions',
|
||||
loadChildren: () => import('./ui/description/description.module').then(m => m.DescriptionModule),
|
||||
data: {
|
||||
breadcrumb: true,
|
||||
title: 'GENERAL.TITLES.DESCRIPTIONS'
|
||||
|
|
|
@ -225,10 +225,10 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
// }
|
||||
|
||||
initializeServices() {
|
||||
this.translate.setDefaultLang(this.configurationService.defaultLanguage || 'en');
|
||||
this.translate.setDefaultLang(this.language.getDefaultLanguagesCode());
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileCulture() ? this.cultureService.cultureSelected(this.authentication.getUserProfileCulture()) : this.cultureService.cultureSelected(this.configurationService.defaultCulture);
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileTimezone() ? this.timezoneService.timezoneSelected(this.authentication.getUserProfileTimezone()) : this.timezoneService.timezoneSelected(this.configurationService.defaultTimezone);
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileLanguage() ? this.language.changeLanguage(this.authentication.getUserProfileLanguage()) : (this.configurationService.defaultLanguage || 'en');
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileLanguage() ? this.language.changeLanguage(this.authentication.getUserProfileLanguage()) : (this.language.getDefaultLanguagesCode());
|
||||
}
|
||||
|
||||
toggleNavbar(event) {
|
||||
|
|
|
@ -20,31 +20,31 @@ import { ReloadHelperComponent } from '@app/ui/misc/reload-helper/reload-helper.
|
|||
import { NavbarModule } from '@app/ui/navbar/navbar.module';
|
||||
import { SidebarModule } from '@app/ui/sidebar/sidebar.module';
|
||||
import { MomentUtcDateAdapter } from '@common/date/moment-utc-date-adapter';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { CommonHttpModule } from '@common/http/common-http.module';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
|
||||
import { DragulaModule } from 'ng2-dragula';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { NgcCookieConsentConfig, NgcCookieConsentModule } from 'ngx-cookieconsent';
|
||||
import { MatomoInitializationMode, NgxMatomoModule } from 'ngx-matomo-client';
|
||||
import { from } from 'rxjs';
|
||||
import { AuthService } from './core/services/auth/auth.service';
|
||||
import { ConfigurationService } from './core/services/configuration/configuration.service';
|
||||
import { CultureService } from './core/services/culture/culture-service';
|
||||
import { LanguageHttpService } from './core/services/language/language.http.service';
|
||||
import { LanguageService } from './core/services/language/language.service';
|
||||
import { TranslateServerLoader } from './core/services/language/server.loader';
|
||||
import { MatomoService } from './core/services/matomo/matomo-service';
|
||||
import { GuidedTourModule } from './library/guided-tour/guided-tour.module';
|
||||
import { Oauth2DialogModule } from './ui/misc/oauth2-dialog/oauth2-dialog.module';
|
||||
import { OpenDMPCustomTranslationCompiler } from './utilities/translate/opendmp-custom-translation-compiler';
|
||||
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { from } from 'rxjs';
|
||||
import { AuthService } from './core/services/auth/auth.service';
|
||||
|
||||
// AoT requires an exported function for factories
|
||||
export function HttpLoaderFactory(http: HttpClient, appConfig: ConfigurationService) {
|
||||
return new TranslateServerLoader(http, appConfig);
|
||||
//GK: In case we want the original translation provider uncomment the line below.
|
||||
//return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
|
||||
export function HttpLoaderFactory(languageHttpService: LanguageHttpService) {
|
||||
return new TranslateServerLoader(languageHttpService);
|
||||
}
|
||||
|
||||
const cookieConfig: NgcCookieConsentConfig = {
|
||||
|
@ -82,8 +82,10 @@ const appearance: MatFormFieldDefaultOptions = {
|
|||
// appearance: 'standard'
|
||||
};
|
||||
|
||||
export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService) {
|
||||
return () => appConfig.loadConfiguration().then(x => keycloak.init({
|
||||
export function InstallationConfigurationFactory(appConfig: ConfigurationService, keycloak: KeycloakService, authService: AuthService, languageService: LanguageService) {
|
||||
return () => appConfig.loadConfiguration().then(() => {
|
||||
return languageService.loadAvailableLanguages().toPromise();
|
||||
}).then(x => keycloak.init({
|
||||
config: {
|
||||
url: appConfig.keycloak.address,
|
||||
realm: appConfig.keycloak.realm,
|
||||
|
@ -108,7 +110,7 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
|
|||
]
|
||||
};
|
||||
const tokenPromise = keycloak.getToken();
|
||||
return authService.prepareAuthRequest(from(tokenPromise), {params}).toPromise().catch(error => authService.onAuthenticateError(error));
|
||||
return authService.prepareAuthRequest(from(tokenPromise), { params }).toPromise().catch(error => authService.onAuthenticateError(error));
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -126,7 +128,7 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
|
|||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient, ConfigurationService]
|
||||
deps: [LanguageHttpService]
|
||||
}
|
||||
}),
|
||||
HttpClientModule,
|
||||
|
@ -161,7 +163,7 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
|
|||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: InstallationConfigurationFactory,
|
||||
deps: [ConfigurationService, KeycloakService, AuthService],
|
||||
deps: [ConfigurationService, KeycloakService, AuthService, LanguageService],
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export enum DescriptionStatus {
|
||||
Draft = 0,
|
||||
Finalized = 1
|
||||
Finalized = 1,
|
||||
Canceled = 2
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export enum DmpAccessType {
|
||||
Public = 0,
|
||||
Restricted = 1
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export enum DmpUserRole {
|
||||
Owner = 0,
|
||||
User = 1
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export enum DmpVersionStatus {
|
||||
Current = 0,
|
||||
Previous = 1
|
||||
}
|
|
@ -17,7 +17,7 @@ import { DepositRepositoriesService } from './services/deposit-repositories/depo
|
|||
import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service';
|
||||
import { DmpBlueprintService } from './services/dmp/dmp-blueprint.service';
|
||||
import { DmpInvitationService } from './services/dmp/dmp-invitation.service';
|
||||
import { DmpService } from './services/dmp/dmp.service';
|
||||
import { DmpService, DmpServiceNew } from './services/dmp/dmp.service';
|
||||
import { EmailConfirmationService } from './services/email-confirmation/email-confirmation.service';
|
||||
import { ExternalDataRepositoryService } from './services/external-sources/data-repository/extternal-data-repository.service';
|
||||
import { ExternalDatasetService } from './services/external-sources/dataset/external-dataset.service';
|
||||
|
@ -61,7 +61,8 @@ import { UserSettingsService } from './services/user-settings/user-settings.serv
|
|||
import { UserService } from './services/user/user.service';
|
||||
import { FileUtils } from './services/utilities/file-utils.service';
|
||||
import { QueryParamsService } from './services/utilities/query-params.service';
|
||||
import { LanguageV2Service } from './services/language/language-v2.service';
|
||||
import { LanguageHttpService } from './services/language/language.http.service';
|
||||
import { DescriptionService } from './services/description/description.service';
|
||||
//
|
||||
//
|
||||
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
||||
|
@ -142,7 +143,9 @@ export class CoreServiceModule {
|
|||
ReferenceTypeService,
|
||||
TenantService,
|
||||
UserService,
|
||||
LanguageV2Service
|
||||
LanguageHttpService,
|
||||
DmpServiceNew,
|
||||
DescriptionService
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,35 +3,71 @@ import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
|
|||
import { Guid } from "@common/types/guid";
|
||||
import { Dmp } from "../dmp/dmp";
|
||||
import { DescriptionTemplate } from "../description-template/description-template";
|
||||
import { DescriptionReference } from "./description-reference";
|
||||
import { User } from "../user/user";
|
||||
import { Reference, ReferencePersist } from "../reference/reference";
|
||||
import { Tag } from "../tag/tag";
|
||||
|
||||
|
||||
|
||||
export interface Description extends BaseEntity {
|
||||
label: string;
|
||||
properties: PropertyDefinition;
|
||||
status: DescriptionStatus;
|
||||
description?: String;
|
||||
dmp: Dmp;
|
||||
uri: String;
|
||||
status: DescriptionStatus
|
||||
createdBy: User;
|
||||
finalizedAt: Date;
|
||||
dmpSectionIndex?: number;
|
||||
template: DescriptionTemplate;
|
||||
descriptionReferences: DescriptionReference[];
|
||||
descriptionTags: DescriptionTag[];
|
||||
template: DescriptionTemplate;
|
||||
dmp: Dmp;
|
||||
}
|
||||
|
||||
export interface PublicDescription extends BaseEntity {
|
||||
}
|
||||
|
||||
export interface PropertyDefinition {
|
||||
fields?: DescriptionField[];
|
||||
}
|
||||
|
||||
// registries?: RegistryModel[];
|
||||
// services?: ServiceModel[];
|
||||
// dataRepositories?: DataRepositoryModel[];
|
||||
// tags?: TagModel[];
|
||||
// externalDatasets?: ExternalDatasetModel[];
|
||||
// isProfileLatestVersion?: Boolean;
|
||||
// modified?: Date;
|
||||
export interface DescriptionField {
|
||||
key?: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface DescriptionReference extends BaseEntity {
|
||||
description?: Description;
|
||||
reference?: Reference;
|
||||
}
|
||||
|
||||
export interface DescriptionTag extends BaseEntity {
|
||||
description?: Description;
|
||||
tag?: Tag;
|
||||
}
|
||||
|
||||
//
|
||||
// Persist
|
||||
//
|
||||
export interface DescriptionPersist extends BaseEntityPersist {
|
||||
|
||||
label: string;
|
||||
dmpId: Guid;
|
||||
dmpDescriptionTemplateId: Guid;
|
||||
descriptionTemplateId: Guid;
|
||||
status: DescriptionStatus;
|
||||
description: string;
|
||||
properties: PropertyDefinitionPersist;
|
||||
tags: string[];
|
||||
references: DescriptionReferencePersist[];
|
||||
}
|
||||
|
||||
export interface PropertyDefinitionPersist{
|
||||
fields: DescriptionFieldPersist[];
|
||||
}
|
||||
|
||||
export interface DescriptionFieldPersist {
|
||||
key?: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface DescriptionReferencePersist extends BaseEntity {
|
||||
reference?: ReferencePersist;
|
||||
}
|
|
@ -10,12 +10,3 @@ export interface DmpReference extends BaseEntity {
|
|||
reference?: Reference;
|
||||
data: String;
|
||||
}
|
||||
|
||||
//
|
||||
// Persist
|
||||
//
|
||||
export interface DmpPersist extends BaseEntityPersist {
|
||||
dmpId: Guid;
|
||||
referenceId: Guid;
|
||||
data: String;
|
||||
}
|
|
@ -5,16 +5,20 @@ import { GrantListingModel } from "../grant/grant-listing";
|
|||
import { OrganizationModel } from "../organisation/organization";
|
||||
import { ProjectModel } from "../project/project";
|
||||
import { ResearcherModel } from "../researcher/researcher";
|
||||
import { UserModel } from "../user/user";
|
||||
import { User, UserModel } from "../user/user";
|
||||
import { UserInfoListingModel } from "../user/user-info-listing";
|
||||
import { DmpDatasetProfile } from "./dmp-dataset-profile/dmp-dataset-profile";
|
||||
import { DmpDynamicField } from "./dmp-dynamic-field";
|
||||
import { DmpExtraField } from "./dmp-extra-field";
|
||||
import { BaseEntity, BaseEntityPersist } from '@common/base/base-entity.model';
|
||||
import { Description } from '../description/description';
|
||||
import { DmpReference } from '../reference/reference';
|
||||
import { DmpReference, ReferencePersist } from '../reference/reference';
|
||||
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
|
||||
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
|
||||
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
|
||||
import { Guid } from '@common/types/guid';
|
||||
|
||||
export interface DmpModel {
|
||||
export interface DmpModel { //TODO: Delete
|
||||
id: string;
|
||||
label: string;
|
||||
groupId: String;
|
||||
|
@ -49,21 +53,25 @@ export interface DmpBlueprint {
|
|||
|
||||
export interface Dmp extends BaseEntity {
|
||||
label: string;
|
||||
description: String;
|
||||
version: number;
|
||||
status: DmpStatus;
|
||||
versionStatus: DmpVersionStatus;
|
||||
properties: string;
|
||||
groupId: String;
|
||||
|
||||
|
||||
description: String;
|
||||
finalizedAt: Date;
|
||||
publishedAt: Date;
|
||||
creator: User;
|
||||
accessType: DmpAccessType;
|
||||
blueprint: DmpBlueprint;
|
||||
dmpDescriptions: Description[];
|
||||
dmpReferences: DmpReference
|
||||
|
||||
|
||||
lockable: boolean;
|
||||
language: String;
|
||||
publicAfter: Date;
|
||||
dmpReferences: DmpReference[];
|
||||
dmpUsers: DmpUser[];
|
||||
descriptions: Description[];
|
||||
|
||||
|
||||
// TODO: delete
|
||||
// grant: GrantListingModel;
|
||||
// project: ProjectModel;
|
||||
// funder: FunderModel;
|
||||
|
@ -85,13 +93,53 @@ export interface Dmp extends BaseEntity {
|
|||
// language: String;
|
||||
}
|
||||
|
||||
export interface DmpUser extends BaseEntity {
|
||||
dmp: Dmp;
|
||||
user: User;
|
||||
role: DmpUserRole;
|
||||
}
|
||||
|
||||
//
|
||||
// Persist
|
||||
//
|
||||
export interface DmpPersist extends BaseEntityPersist {
|
||||
label: string;
|
||||
description: String;
|
||||
version: number;
|
||||
status: DmpStatus;
|
||||
groupId: String;
|
||||
properties: string;
|
||||
description: String;
|
||||
language: String;
|
||||
blueprint: DmpBlueprint;
|
||||
accessType: DmpAccessType;
|
||||
references: DmpReferencePersist[];
|
||||
descriptionTemplates: DmpDescriptionTemplatePersist[];
|
||||
}
|
||||
|
||||
export interface DmpReferencePersist extends BaseEntityPersist {
|
||||
reference: ReferencePersist;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface DmpDescriptionTemplatePersist extends BaseEntityPersist {
|
||||
descriptionTemplateGroupId: Guid;
|
||||
sectionId: Guid;
|
||||
}
|
||||
|
||||
export interface CloneDmpPersist {
|
||||
id: Guid;
|
||||
label: string;
|
||||
description: String;
|
||||
descriptions: Guid[];
|
||||
}
|
||||
|
||||
export interface NewVersionDmpPersist {
|
||||
id: Guid;
|
||||
label: string;
|
||||
description: String;
|
||||
blueprintId: Guid;
|
||||
descriptions: Guid[];
|
||||
}
|
||||
|
||||
export interface DmpUserPersist {
|
||||
user: Guid;
|
||||
role: DmpUserRole;
|
||||
}
|
|
@ -1,4 +1,12 @@
|
|||
export interface TagModel {
|
||||
import { BaseEntity } from "@common/base/base-entity.model";
|
||||
import { User } from "../user/user";
|
||||
|
||||
export interface TagModel { //TODO: old entity, delete
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Tag extends BaseEntity {
|
||||
label?: string;
|
||||
createdBy?: User;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { Lookup } from '@common/model/lookup';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { IsActive } from '../common/enum/is-active.enum';
|
||||
import { DescriptionStatus } from '../common/enum/description-status';
|
||||
import { DmpLookup } from './dmp.lookup';
|
||||
|
||||
export class DescriptionLookup extends Lookup implements DescriptionFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
createdAfter: Date;
|
||||
createdBefore: Date;
|
||||
finalizedAfter: Date;
|
||||
finalizedBefore: Date;
|
||||
dmpSubQuery: DmpLookup;
|
||||
isActive: IsActive[];
|
||||
statuses: DescriptionStatus[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export interface DescriptionFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
createdAfter: Date;
|
||||
createdBefore: Date;
|
||||
finalizedAfter: Date;
|
||||
finalizedBefore: Date;
|
||||
dmpSubQuery: DmpLookup;
|
||||
isActive: IsActive[];
|
||||
statuses: DescriptionStatus[];
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import { Lookup } from '@common/model/lookup';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { IsActive } from '../common/enum/is-active.enum';
|
||||
import { DmpStatus } from '../common/enum/dmp-status';
|
||||
import { DmpVersionStatus } from '../common/enum/dmp-version-status';
|
||||
import { DmpAccessType } from '../common/enum/dmp-access-type';
|
||||
|
||||
export class DmpLookup extends Lookup implements DmpFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
versionStatuses: DmpVersionStatus[];
|
||||
statuses: DmpStatus[];
|
||||
accessTypes: DmpAccessType[];
|
||||
versions: Number[]
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export interface DmpFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
versionStatuses: DmpVersionStatus[];
|
||||
statuses: DmpStatus[];
|
||||
accessTypes: DmpAccessType[];
|
||||
versions: Number[]
|
||||
}
|
|
@ -47,16 +47,6 @@ export class ConfigurationService extends BaseComponent {
|
|||
return this._defaultTimezone || 'UTC';
|
||||
}
|
||||
|
||||
private _defaultLanguage: string;
|
||||
get defaultLanguage(): string {
|
||||
return this._defaultLanguage;
|
||||
}
|
||||
|
||||
private _availableLanguages: any[] = [];
|
||||
get availableLanguages(): any[] {
|
||||
return this._availableLanguages;
|
||||
}
|
||||
|
||||
private _logging: Logging;
|
||||
get logging(): Logging {
|
||||
return this._logging;
|
||||
|
@ -161,8 +151,6 @@ export class ConfigurationService extends BaseComponent {
|
|||
this._defaultCulture = config.defaultCulture;
|
||||
this._defaultBlueprintId = config.defaultBlueprintId;
|
||||
this._defaultTimezone = config.defaultTimezone;
|
||||
this._defaultLanguage = config.defaultLanguage;
|
||||
this._availableLanguages = config.availableLanguages;
|
||||
this._keycloak = KeycloakConfiguration.parseValue(config.keycloak);
|
||||
this._logging = Logging.parseValue(config.logging);
|
||||
this._lockInterval = config.lockInterval;
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { Description, DescriptionPersist, PublicDescription } from '@app/core/model/description/description';
|
||||
import { DescriptionLookup } from '@app/core/query/description.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 { 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 { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionService {
|
||||
|
||||
private headers = new HttpHeaders();
|
||||
|
||||
constructor(private http: BaseHttpV2Service, private httpClient: HttpClient, private configurationService: ConfigurationService, private filterService: FilterService) {
|
||||
}
|
||||
|
||||
private get apiBase(): string { return `${this.configurationService.server}description`; }
|
||||
|
||||
query(q: DescriptionLookup): Observable<QueryResult<Description>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http.post<QueryResult<Description>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
publicQuery(q: DescriptionLookup): Observable<QueryResult<PublicDescription>> {
|
||||
const url = `${this.apiBase}/public/query`;
|
||||
return this.http.post<QueryResult<PublicDescription>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
getSingle(id: Guid, reqFields: string[] = []): Observable<Description> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.get<Description>(url, options).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
getPublicSingle(id: Guid, reqFields: string[] = []): Observable<Description> {
|
||||
const url = `${this.apiBase}/public/${id}`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.get<Description>(url, options).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
persist(item: DescriptionPersist): Observable<Description> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
return this.http
|
||||
.post<Description>(url, item).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<Description> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
|
||||
return this.http
|
||||
.delete<Description>(url).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
//
|
||||
// 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: Description) => item.label,
|
||||
titleFn: (item: Description) => item.label,
|
||||
valueAssign: (item: Description) => item.id,
|
||||
};
|
||||
|
||||
// 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: Description) => item.label,
|
||||
titleFn: (item: Description) => item.label,
|
||||
valueAssign: (item: Description) => item.id,
|
||||
};
|
||||
|
||||
private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): DescriptionLookup {
|
||||
const lookup: DescriptionLookup = new DescriptionLookup();
|
||||
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<Description>(x => x.id),
|
||||
nameof<Description>(x => x.label)
|
||||
]
|
||||
};
|
||||
lookup.order = { items: [nameof<Description>(x => x.label)] };
|
||||
if (like) { lookup.like = this.filterService.transformLike(like); }
|
||||
return lookup;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,17 @@
|
|||
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
|
||||
import { VersionListingModel } from '@app/core/model/version/version-listing.model';
|
||||
import { DmpLookup } from '@app/core/query/dmp.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 { 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 { BaseHttpParams } from '../../../../common/http/base-http-params';
|
||||
import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type';
|
||||
import { DynamicFieldGrantCriteria } from '../../../models/dynamic-field-grant/DynamicFieldGrantCriteria';
|
||||
|
@ -10,17 +20,152 @@ import { DataTableRequest } from '../../model/data-table/data-table-request';
|
|||
import { DatasetListingModel } from '../../model/dataset/dataset-listing';
|
||||
import { DatasetProfileModel } from '../../model/dataset/dataset-profile';
|
||||
import { DatasetsToBeFinalized } from '../../model/dataset/datasets-toBeFinalized';
|
||||
import { DmpModel } from '../../model/dmp/dmp';
|
||||
import { CloneDmpPersist, Dmp, DmpModel, DmpPersist, DmpUser, DmpUserPersist, NewVersionDmpPersist } from '../../model/dmp/dmp';
|
||||
import { DmpListingModel } from '../../model/dmp/dmp-listing';
|
||||
import { DmpOverviewModel } from '../../model/dmp/dmp-overview';
|
||||
import { DatasetProfileCriteria } from '../../query/dataset-profile/dataset-profile-criteria';
|
||||
import { DmpCriteria } from '../../query/dmp/dmp-criteria';
|
||||
import { ExploreDmpCriteriaModel } from '../../query/explore-dmp/explore-dmp-criteria';
|
||||
import { RequestItem } from '../../query/request-item';
|
||||
import { BaseHttpService } from '../http/base-http.service';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
|
||||
import { VersionListingModel } from '@app/core/model/version/version-listing.model';
|
||||
import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||
import { BaseHttpService } from '../http/base-http.service';
|
||||
|
||||
@Injectable()
|
||||
export class DmpServiceNew {
|
||||
|
||||
private headers = new HttpHeaders();
|
||||
|
||||
constructor(private http: BaseHttpV2Service, private httpClient: HttpClient, private configurationService: ConfigurationService, private filterService: FilterService) {
|
||||
}
|
||||
|
||||
private get apiBase(): string { return `${this.configurationService.server}dmp`; }
|
||||
|
||||
query(q: DmpLookup): Observable<QueryResult<Dmp>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http.post<QueryResult<Dmp>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
getSingle(id: Guid, reqFields: string[] = []): Observable<Dmp> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.get<Dmp>(url, options).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
persist(item: DmpPersist): Observable<Dmp> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
return this.http
|
||||
.post<Dmp>(url, item).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<Dmp> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
|
||||
return this.http
|
||||
.delete<Dmp>(url).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
clone(item: CloneDmpPersist, reqFields: string[] = []): Observable<Dmp> {
|
||||
const url = `${this.apiBase}/clone`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.post<Dmp>(url, item).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
newVersion(item: NewVersionDmpPersist, reqFields: string[] = []): Observable<Dmp> {
|
||||
const url = `${this.apiBase}/new-version`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.get<Dmp>(url, options).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
assignUsers(id: Guid, items: DmpUserPersist[], reqFields: string[] = []): Observable<DmpUser> {
|
||||
const url = `${this.apiBase}/${id}/assign-users`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.post<DmpUser>(url, items).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
downloadXML(id: Guid): Observable<HttpResponse<Blob>> {
|
||||
const url = `${this.apiBase}/xml/export/${id}`;
|
||||
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 });
|
||||
}
|
||||
|
||||
uploadFile(file: FileList, labelSent: string, reqFields: string[] = []): Observable<DataTableData<Dmp>> {
|
||||
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 });
|
||||
}
|
||||
|
||||
//
|
||||
// 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: Dmp) => item.label,
|
||||
titleFn: (item: Dmp) => item.label,
|
||||
valueAssign: (item: Dmp) => item.id,
|
||||
};
|
||||
|
||||
// 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: Dmp) => item.label,
|
||||
titleFn: (item: Dmp) => item.label,
|
||||
valueAssign: (item: Dmp) => item.id,
|
||||
};
|
||||
|
||||
private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): DmpLookup {
|
||||
const lookup: DmpLookup = new DmpLookup();
|
||||
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<Dmp>(x => x.id),
|
||||
nameof<Dmp>(x => x.label)
|
||||
]
|
||||
};
|
||||
lookup.order = { items: [nameof<Dmp>(x => x.label)] };
|
||||
if (like) { lookup.like = this.filterService.transformLike(like); }
|
||||
return lookup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Pre refactor TODO: delete
|
||||
//
|
||||
//
|
||||
|
||||
@Injectable()
|
||||
export class DmpService {
|
||||
|
|
|
@ -15,7 +15,7 @@ import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
|||
import { HttpResponse } from '@angular/common/http';
|
||||
|
||||
@Injectable()
|
||||
export class LanguageV2Service {
|
||||
export class LanguageHttpService {
|
||||
|
||||
constructor(private http: BaseHttpV2Service, private configurationService: ConfigurationService, private filterService: FilterService) {
|
||||
}
|
|
@ -1,26 +1,20 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BaseService } from '@common/base/base.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { environment } from 'environments/environment';
|
||||
import { Observable } from 'rxjs';
|
||||
import { HttpResponse, HttpClient } from '@angular/common/http';
|
||||
import { BaseHttpService } from '../http/base-http.service';
|
||||
import { Language } from '@app/models/language/Language';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { LanguageHttpService } from './language.http.service';
|
||||
|
||||
@Injectable()
|
||||
export class LanguageService {
|
||||
export class LanguageService extends BaseService {
|
||||
private currentLanguage: string;
|
||||
private get apiBase(): string { return `${this.configurationService.server}language`; }
|
||||
private availableLanguageCodes: string[];
|
||||
|
||||
constructor(
|
||||
private translate: TranslateService,
|
||||
private http: HttpClient,
|
||||
private baseHttp: BaseHttpService,
|
||||
private configurationService: ConfigurationService
|
||||
private languageHttpService: LanguageHttpService
|
||||
) {
|
||||
this.currentLanguage = this.configurationService.defaultLanguage || 'en';
|
||||
super();
|
||||
}
|
||||
|
||||
public changeLanguage(lang: string) {
|
||||
|
@ -29,31 +23,28 @@ export class LanguageService {
|
|||
}
|
||||
|
||||
public getCurrentLanguage() {
|
||||
if (this.currentLanguage == null) throw new Error("languages not loaded");
|
||||
return this.currentLanguage;
|
||||
}
|
||||
|
||||
public getCurrentLanguageJSON(): Observable<HttpResponse<Blob>> {
|
||||
const params = new BaseHttpParams();
|
||||
// params.interceptorContext = {
|
||||
// excludedInterceptors: [
|
||||
// InterceptorType.AuthToken,
|
||||
// ]
|
||||
// };
|
||||
return this.http.get(`${this.apiBase}/${this.currentLanguage}`, { params: params, responseType: 'blob', observe: 'response' });
|
||||
public loadAvailableLanguages(): Observable<string[]> {
|
||||
return this.languageHttpService.queryAvailableCodes(this.languageHttpService.buildAutocompleteLookup())
|
||||
.pipe(takeUntil(this._destroyed)).pipe(
|
||||
map((data) => {
|
||||
this.availableLanguageCodes = data.items;
|
||||
if (this.availableLanguageCodes.length > 0) this.currentLanguage = this.availableLanguageCodes[0];
|
||||
return this.availableLanguageCodes;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public updateLanguage(json: string): Observable<String> {
|
||||
return this.baseHttp.post<string>(`${this.apiBase}/update/${this.currentLanguage}`, json);
|
||||
public getDefaultLanguagesCode() {
|
||||
if (this.availableLanguageCodes == null || this.availableLanguageCodes.length == 0) throw new Error("languages not loaded");
|
||||
return this.availableLanguageCodes[0];
|
||||
}
|
||||
|
||||
public getCurrentLanguageName() {
|
||||
let result: string = '';
|
||||
this.configurationService.availableLanguages.forEach(language => {
|
||||
if (language.value === this.currentLanguage) {
|
||||
result = this.translate.instant(language.label);
|
||||
public getAvailableLanguagesCodes() {
|
||||
if (this.availableLanguageCodes == null) throw new Error("languages not loaded");
|
||||
return this.availableLanguageCodes;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,23 +5,23 @@ import { HttpClient } from '@angular/common/http';
|
|||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { LanguageHttpService } from './language.http.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { Language } from '@app/core/model/language/language';
|
||||
|
||||
export class TranslateServerLoader implements TranslateLoader{
|
||||
private get apiBase(): string { return `${this.configurationService.server}language`; }
|
||||
export class TranslateServerLoader implements TranslateLoader {
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private configurationService: ConfigurationService
|
||||
private languageHttpService: LanguageHttpService
|
||||
) {
|
||||
|
||||
}
|
||||
getTranslation(lang: string): Observable<any> {
|
||||
const params = new BaseHttpParams();
|
||||
// params.interceptorContext = {
|
||||
// excludedInterceptors: [
|
||||
// InterceptorType.AuthToken,
|
||||
// ]
|
||||
// };
|
||||
return this.http.get(`${this.apiBase}/${lang}`, { params: params });
|
||||
return this.languageHttpService.getSingleWithCode(lang, [
|
||||
...nameof<Language>(x => x.id),
|
||||
nameof<Language>(x => x.code),
|
||||
nameof<Language>(x => x.payload),
|
||||
]).pipe(map(x => JSON.parse(x.payload)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import { map, takeUntil } from 'rxjs/operators';
|
|||
import { LanguageEditorResolver } from './language-editor.resolver';
|
||||
import { LanguageEditorService } from './language-editor.service';
|
||||
import { LanguageEditorModel } from './language-editor.model';
|
||||
import { LanguageV2Service } from '@app/core/services/language/language-v2.service';
|
||||
import { LanguageHttpService } from '@app/core/services/language/language.http.service';
|
||||
|
||||
|
||||
@Component({
|
||||
|
@ -76,7 +76,7 @@ export class LanguageEditorComponent extends BaseEditor<LanguageEditorModel, Lan
|
|||
// Rest dependencies. Inject any other needed deps here:
|
||||
public authService: AuthService,
|
||||
public enumUtils: EnumUtils,
|
||||
private languageV2Service: LanguageV2Service,
|
||||
private languageV2Service: LanguageHttpService,
|
||||
private logger: LoggingService,
|
||||
private languageEditorService: LanguageEditorService,
|
||||
private fileUtils: FileUtils,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { Language } from '@app/core/model/language/language';
|
||||
import { LanguageV2Service } from '@app/core/services/language/language-v2.service';
|
||||
import { LanguageHttpService } from '@app/core/services/language/language.http.service';
|
||||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
|
||||
import { Guid } from '@common/types/guid';
|
||||
|
@ -11,7 +11,7 @@ import { nameof } from 'ts-simple-nameof';
|
|||
@Injectable()
|
||||
export class LanguageEditorResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(private languageV2Service: LanguageV2Service, private breadcrumbService: BreadcrumbService) {
|
||||
constructor(private languageV2Service: LanguageHttpService, private breadcrumbService: BreadcrumbService) {
|
||||
super();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|||
import { Language } from '@app/core/model/language/language';
|
||||
import { LanguageLookup } from '@app/core/query/language.lookup';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { LanguageV2Service } from '@app/core/services/language/language-v2.service';
|
||||
import { LanguageHttpService } from '@app/core/services/language/language.http.service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||
|
@ -52,7 +52,7 @@ export class LanguageListingComponent extends BaseListingComponent<Language, Lan
|
|||
protected uiNotificationService: UiNotificationService,
|
||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||
protected queryParamsService: QueryParamsService,
|
||||
private languageV2Service: LanguageV2Service,
|
||||
private languageV2Service: LanguageHttpService,
|
||||
public authService: AuthService,
|
||||
private pipeService: PipeService,
|
||||
public enumUtils: EnumUtils,
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<div class="dataset-copy-dialog">
|
||||
<div mat-dialog-title class="row d-flex flex-row">
|
||||
<div mat-dialog-title class="col-auto">{{'DATASET-WIZARD.DIALOGUE.TITLE' | translate}}</div>
|
||||
<div class="col-auto ml-auto close-btn" (click)="close()"><mat-icon class="close-icon">close</mat-icon></div>
|
||||
</div>
|
||||
<div mat-dialog-content class="confirmation-message">
|
||||
<mat-form-field class="col-12">
|
||||
<app-single-auto-complete [formControl]="data.formControl" placeholder="{{'DATASET-WIZARD.DIALOGUE.DMP-SEARCH.PLACEHOLDER' | translate}}" [configuration]="dmpAutoCompleteConfiguration">
|
||||
</app-single-auto-complete>
|
||||
</mat-form-field>
|
||||
<!-- <mat-error *ngIf="data.formControl.hasError('incorrect')">{{getErrorMessage()}}</mat-error> -->
|
||||
</div>
|
||||
<div mat-dialog-actions class="row">
|
||||
<div class="col-auto ml-auto"><button mat-button class="cancel-btn" type="button" (click)="cancel()">{{ data.cancelButton }}</button></div>
|
||||
<div class="col-auto"><button mat-button class="confirm-btn" type="button" (click)="confirm()">{{ data.confirmButton }}</button></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,50 @@
|
|||
.confirmation-message {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dataset-copy-dialog {
|
||||
margin-bottom: 1.125rem;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
border: 1px solid #b5b5b5;
|
||||
border-radius: 30px;
|
||||
min-width: 101px;
|
||||
height: 43px;
|
||||
color: #212121;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
border: 1px solid var(--primary-color);
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
min-width: 101px;
|
||||
height: 43px;
|
||||
color: var(--primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.confirm-btn:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
cursor: pointer;
|
||||
// margin-right: 20px;
|
||||
padding: .4rem;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.close-icon:hover {
|
||||
background-color: #ECECED !important;
|
||||
border-radius: 50%;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
import { map, filter } from 'rxjs/operators';
|
||||
import { Component } from "@angular/core";
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog";
|
||||
import { SingleAutoCompleteConfiguration } from "../../../../library/auto-complete/single/single-auto-complete-configuration";
|
||||
import { Observable } from "rxjs";
|
||||
import { DataTableRequest } from "../../../../core/model/data-table/data-table-request";
|
||||
import { DmpCriteria } from "../../../../core/query/dmp/dmp-criteria";
|
||||
import { DmpListingModel } from "../../../../core/model/dmp/dmp-listing";
|
||||
import { DmpService } from "../../../../core/services/dmp/dmp.service";
|
||||
import { Inject } from "@angular/core";
|
||||
import { DmpModel } from "../../../../core/model/dmp/dmp";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
|
||||
@Component({
|
||||
selector: 'dataset-copy-dialogue-component',
|
||||
templateUrl: 'dataset-copy-dialogue.component.html',
|
||||
styleUrls: ['./dataset-copy-dialogue.component.scss'],
|
||||
})
|
||||
export class DatasetCopyDialogueComponent {
|
||||
|
||||
dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
|
||||
dmpModel: DmpModel;
|
||||
datasetDescriptionTemplateLabel: String;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<DatasetCopyDialogueComponent>,
|
||||
public dmpService: DmpService,
|
||||
public language: TranslateService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.dmpAutoCompleteConfiguration = {
|
||||
filterFn: this.searchDmp.bind(this),
|
||||
initialItems: (extraData) => this.searchDmp(''),
|
||||
displayFn: (item) => item['label'],
|
||||
titleFn: (item) => item['label'],
|
||||
};
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.dialogRef.close(this.data);
|
||||
}
|
||||
|
||||
confirm() {
|
||||
this.datasetProfileValidate().subscribe(x => {
|
||||
if (this.data.datasetProfileExist) {
|
||||
this.dialogRef.close(this.data);
|
||||
}
|
||||
else if (!this.data.datasetProfileExist) {
|
||||
this.data.formControl.setErrors({ 'incorrect': true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
searchDmp(query: string): Observable<DmpListingModel[]> {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
dmpDataTableRequest.criteria = new DmpCriteria();
|
||||
dmpDataTableRequest.criteria.like = query;
|
||||
dmpDataTableRequest.criteria.datasetTemplates = [this.data.datasetProfileId];
|
||||
return this.dmpService.getPaged(dmpDataTableRequest, "profiles").pipe(map(x => x.data));
|
||||
}
|
||||
|
||||
datasetProfileValidate() {
|
||||
return this.dmpService.getSingle(this.data.formControl.value.id).pipe(map(result => result as DmpModel),
|
||||
map(result => {
|
||||
this.dmpModel = result
|
||||
this.dmpModel.profiles.forEach((element) => {
|
||||
if (element.id == this.data.datasetProfileId) {
|
||||
this.data.datasetProfileExist = true;
|
||||
}
|
||||
})
|
||||
}));
|
||||
}
|
||||
|
||||
getErrorMessage() {
|
||||
return this.language.instant('DATASET-WIZARD.DIALOGUE.ERROR-MESSAGE');
|
||||
}
|
||||
|
||||
hasValidDatasetProfile() {
|
||||
if (this.data.datasetProfileExist) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
|
||||
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { DatasetCopyDialogueComponent } from './dataset-copy-dialogue.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
AutoCompleteModule
|
||||
],
|
||||
declarations: [
|
||||
DatasetCopyDialogueComponent
|
||||
]
|
||||
})
|
||||
export class DatasetCopyDialogModule { }
|
|
@ -0,0 +1,107 @@
|
|||
<form class="dataset-editor" *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<div class="col-12 intro">
|
||||
<p>{{'DATASET-EDITOR.TITLE.INTRO' | translate}}</p>
|
||||
<span>{{'DATASET-EDITOR.TITLE.INTRO-TIP' | translate}}</span>
|
||||
</div>
|
||||
<div class="col-12 card">
|
||||
<!-- Title Field -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="heading">1.1 {{'DATASET-EDITOR.FIELDS.TITLE' | translate}}*</div>
|
||||
<!-- <span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span> -->
|
||||
<!-- <a class="dmp-link dmp-tour-{{ formGroup.get('id').value + 1 }}" (click)="restartTour(formGroup.get('id').value + 1)">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span> -->
|
||||
<div class="title-form">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.TITLE' | translate}}" type="text" name="label" formControlName="label" required>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('backendError')"> {{formGroup.get('label').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Description field -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="heading">1.2 {{'DATASET-EDITOR.FIELDS.DESCRIPTION' | translate}}</div>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.DESCRIPTION' | translate}}</span>
|
||||
<!-- <span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span>
|
||||
<a class="dmp-link dmp-tour-{{ formGroup.get('id').value + 2 }}" (click)="restartTour(formGroup.get('id').value + 2)">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a>
|
||||
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span> -->
|
||||
<div class="description-form">
|
||||
<rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'description'"
|
||||
[placeholder]="'DMP-EDITOR.PLACEHOLDER.DESCRIPTION'"
|
||||
[wrapperClasses]="'full-width editor ' +
|
||||
((formGroup.get('description').touched && (formGroup.get('description').hasError('required') || formGroup.get('description').hasError('backendError'))) ? 'required' : '')"
|
||||
[editable]="!formGroup.get('description').disabled">
|
||||
</rich-text-editor-component>
|
||||
<div [class]="(formGroup.get('description').touched && (formGroup.get('description').hasError('required') || formGroup.get('description').hasError('backendError'))) ? 'visible' : 'invisible'" class="mat-form-field form-field-subscript-wrapper">
|
||||
<mat-error *ngIf="formGroup.get('description').hasError('backendError')">{{formGroup.get('description').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Uri field -->
|
||||
<!-- <div class="row">
|
||||
<div class="col-12">
|
||||
<div class="heading">1.3 {{'DATASET-EDITOR.FIELDS.EXTERNAL-LINK' | translate}}</div>
|
||||
<span class="hint"></span>
|
||||
<div class="uri-form">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.PLACEHOLDER.EXTERNAL-LINK' | translate}}" type="text" name="uri" formControlName="uri">
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('backendError')">{{formGroup.get('uri').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- External Fields -->
|
||||
<app-dataset-external-references-editor-component [formGroup]="formGroup" [viewOnly]="viewOnly"></app-dataset-external-references-editor-component>
|
||||
<!-- Template Field -->
|
||||
<div class="heading">1.4 {{'DATASET-EDITOR.FIELDS.PROFILE' | translate}}*</div>
|
||||
<div class="profile-form">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="{{'DATASET-WIZARD.FIRST-STEP.PROFILE'| translate}}" [required]="true" [compareWith]="compareWith" formControlName="profile">
|
||||
<mat-option *ngFor="let profile of availableProfiles" [value]="profile">
|
||||
<div (click)="checkMinMax($event, profile)">
|
||||
{{profile.label}}
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="formGroup.get('profile').hasError('backendError')">{{formGroup.get('profile').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<!-- <div class="container-fluid">
|
||||
<div class="row dataset-editor" [formGroup]="formGroup">
|
||||
<div class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-sm-12 col-md-6">
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.NAME' | translate}}" type="text" name="label" formControlName="label" required>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('backendError')">{{formGroup.get('label').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row" *ngIf="showUri">
|
||||
<mat-form-field class="col-sm-12 col-md-6">
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.URI' | translate}}" type="text" name="uri" formControlName="uri">
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('backendError')">{{formGroup.get('uri').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-form-field class="col-sm-12 col-md-6">
|
||||
<textarea matInput class="description-area" placeholder="{{'DATASET-EDITOR.FIELDS.DESCRIPTION' | translate}}" formControlName="description"></textarea>
|
||||
<mat-error *ngIf="formGroup.get('description').hasError('backendError')">{{formGroup.get('description').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
|
@ -0,0 +1,117 @@
|
|||
.dataset-editor {
|
||||
.intro {
|
||||
text-align: left;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
opacity: 1;
|
||||
margin: 3rem 0rem 3rem 0rem;
|
||||
}
|
||||
|
||||
.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: 2.125rem;
|
||||
}
|
||||
|
||||
.title-form,
|
||||
.description-form,
|
||||
.profile-form {
|
||||
text-align: left;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.15px;
|
||||
color: #7d7d7d;
|
||||
opacity: 1;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
// textarea::placeholder {
|
||||
// font-style: oblique;
|
||||
// }
|
||||
|
||||
.input-btn {
|
||||
border: none;
|
||||
color: #aaaaaa;
|
||||
background-color: #ffffff00;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.input-btn :hover {
|
||||
color: var(--primary-color-3) !important;
|
||||
}
|
||||
|
||||
.dmp-link {
|
||||
color: #3fafac;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dmp-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .title-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
::ng-deep .description-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
::ng-deep .uri-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
::ng-deep .tags-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
::ng-deep .profile-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
::ng-deep .title-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
font-size: 1rem;
|
||||
padding: 0.6em 0 1em 0 !important;
|
||||
}
|
||||
|
||||
::ng-deep .description-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
// font-size: 1rem;
|
||||
padding: 0.6em 0 1em 0 !important;
|
||||
}
|
||||
|
||||
::ng-deep .uri-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
font-size: 1rem;
|
||||
padding: 0.6em 0 1em 0 !important;
|
||||
}
|
||||
|
||||
::ng-deep .tags-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
font-size: 1rem;
|
||||
padding: 0.6em 0 1em 0 !important;
|
||||
}
|
||||
|
||||
::ng-deep .profile-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
font-size: 1rem;
|
||||
padding: 0.6em 0 1em 0 !important;
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
|
||||
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dataset-editor-component',
|
||||
templateUrl: 'dataset-editor.component.html',
|
||||
styleUrls: ['./dataset-editor.component.scss']
|
||||
})
|
||||
export class DatasetEditorComponent extends BaseComponent {
|
||||
|
||||
@Input() formGroup: UntypedFormGroup;
|
||||
// @Input() formGroup: FormGroup = null;
|
||||
@Input() availableProfiles: DatasetProfileModel[];
|
||||
@Input() dmpId: string;
|
||||
showUri: boolean = false;
|
||||
dmpText: string = null;
|
||||
viewOnly = false;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private dmpBlueprintService: DmpBlueprintService,
|
||||
private dialog: MatDialog,
|
||||
private guidedTourService: GuidedTourService,
|
||||
private language: TranslateService
|
||||
) { super(); }
|
||||
|
||||
public dashboardTourDmp: GuidedTour = {
|
||||
tourId: 'only-dmp-tour',
|
||||
useOrb: true,
|
||||
steps: [
|
||||
{
|
||||
title: this.dmpText,
|
||||
content: 'Step 1',
|
||||
orientation: Orientation.Bottom,
|
||||
highlightPadding: 3,
|
||||
isStepUnique: true,
|
||||
customTopOffset: 8
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
checkMinMax(event, profile: DatasetProfileModel) {
|
||||
event.stopPropagation();
|
||||
const dmpSectionIndex = this.formGroup.get('dmpSectionIndex').value;
|
||||
const blueprintId = this.formGroup.get('dmp').value.profile.id;
|
||||
this.dmpBlueprintService.getSingle(blueprintId,
|
||||
[
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.description)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
||||
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.dataType)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.systemFieldType)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'),
|
||||
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.id)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateId)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||
]
|
||||
)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
const section = result.definition.sections[dmpSectionIndex];
|
||||
if(section.hasTemplates){
|
||||
const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id));
|
||||
if (foundTemplate !== undefined) {
|
||||
let count = 0;
|
||||
if(this.formGroup.get('dmp').value.datasets != null){
|
||||
for(let dataset of this.formGroup.get('dmp').value.datasets){
|
||||
if(dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count === foundTemplate.maxMultiplicity){
|
||||
this.dialog.open(PopupNotificationDialogComponent, {
|
||||
data: {
|
||||
title: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.TITLE'),
|
||||
message: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.MESSAGE')
|
||||
}, maxWidth: '30em'
|
||||
});
|
||||
}
|
||||
else{
|
||||
this.formGroup.get('profile').setValue(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.formGroup.get('profile').setValue(profile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.formGroup.get('profile').setValue(profile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getDmpText(): string {
|
||||
return this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
|
||||
this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
||||
this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' +
|
||||
this.language.instant('DMP-LISTING.GET-IDEA');
|
||||
}
|
||||
|
||||
setDashboardTourDmp(label: string): void {
|
||||
this.dashboardTourDmp.steps[0].title = this.getDmpText();
|
||||
this.dashboardTourDmp.steps[0].selector = '.dmp-tour-' + label;
|
||||
}
|
||||
|
||||
public restartTour(label: string): void {
|
||||
this.setDashboardTourDmp(label);
|
||||
this.guidedTourService.startTour(this.dashboardTourDmp);
|
||||
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.router.navigate(['/datasets']);
|
||||
}
|
||||
|
||||
public compareWith(object1: any, object2: any) {
|
||||
return object1 && object2 && object1.id === object2.id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,382 @@
|
|||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { ExternalDatasetType } from '@app/core/common/enum/external-dataset-type';
|
||||
import { DataRepositoryModel } from '@app/core/model/data-repository/data-repository';
|
||||
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||
import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard';
|
||||
import { DmpModel } from '@app/core/model/dmp/dmp';
|
||||
import { ExternalDatasetModel } from '@app/core/model/external-dataset/external-dataset';
|
||||
import { RegistryModel } from '@app/core/model/registry/registry';
|
||||
import { ServiceModel } from '@app/core/model/service/service';
|
||||
import { TagModel } from '@app/core/model/tag/tag';
|
||||
import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model';
|
||||
import { BackendErrorValidator } from '@common/forms/validation/custom-validator';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { ValidationContext } from '@common/forms/validation/validation-context';
|
||||
|
||||
export class DatasetWizardEditorModel {
|
||||
public id: string;
|
||||
public label: string;
|
||||
public profile: DatasetProfileModel;
|
||||
public uri: String;
|
||||
public status: number;
|
||||
public description: String;
|
||||
public services: ExternalServiceEditorModel[] = [];
|
||||
public registries: ExternalRegistryEditorModel[] = [];
|
||||
public dataRepositories: ExternalDataRepositoryEditorModel[] = [];
|
||||
public tags: ExternalTagEditorModel[] = [];
|
||||
public externalDatasets: ExternalDatasetEditorModel[] = [];
|
||||
public dmp: DmpModel;
|
||||
public dmpSectionIndex: number;
|
||||
public datasetProfileDefinition: DatasetDescriptionFormEditorModel;
|
||||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
|
||||
public isProfileLatestVersion: Boolean;
|
||||
public modified: Date;
|
||||
|
||||
fromModel(item: DatasetWizardModel): DatasetWizardEditorModel {
|
||||
this.id = item.id;
|
||||
this.label = item.label;
|
||||
this.profile = item.profile;
|
||||
this.uri = item.uri;
|
||||
this.status = item.status;
|
||||
this.description = item.description;
|
||||
if (item.services) { this.services = item.services.map(x => new ExternalServiceEditorModel().fromModel(x)); }
|
||||
if (item.registries) { this.registries = item.registries.map(x => new ExternalRegistryEditorModel().fromModel(x)); }
|
||||
if (item.dataRepositories) { this.dataRepositories = item.dataRepositories.map(x => new ExternalDataRepositoryEditorModel().fromModel(x)); }
|
||||
if (item.externalDatasets) { this.externalDatasets = item.externalDatasets.map(x => new ExternalDatasetEditorModel().fromModel(x)); }
|
||||
this.dmp = item.dmp;
|
||||
this.dmpSectionIndex = item.dmpSectionIndex;
|
||||
if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); }
|
||||
if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); }
|
||||
this.isProfileLatestVersion = item.isProfileLatestVersion;
|
||||
this.modified = new Date(item.modified);
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
if (context == null) { context = this.createValidationContext(); }
|
||||
const formBuilder = new UntypedFormBuilder();
|
||||
const formGroup = formBuilder.group({
|
||||
id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators],
|
||||
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators],
|
||||
uri: [{ value: this.uri, disabled: disabled }, context.getValidation('uri').validators],
|
||||
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
|
||||
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
|
||||
dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators],
|
||||
dmpSectionIndex: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators],
|
||||
//externalDatasets: [{ value: this.externalDatasets, disabled: disabled }, context.getValidation('externalDatasets').validators],
|
||||
tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators],
|
||||
//registries: [{ value: this.registries, disabled: disabled }, context.getValidation('registries').validators],
|
||||
//dataRepositories: [{ value: this.dataRepositories, disabled: disabled }, context.getValidation('dataRepositories').validators],
|
||||
//services: [{ value: this.services, disabled: disabled }, context.getValidation('services').validators],
|
||||
profile: [{ value: this.profile, disabled: disabled }, context.getValidation('profile').validators],
|
||||
modified: [{value: this.modified, disabled: disabled}, context.getValidation('modified').validators]
|
||||
});
|
||||
|
||||
const externalDatasetsFormArray = new Array<UntypedFormGroup>();
|
||||
//if (this.externalDatasets && this.externalDatasets.length > 0) {
|
||||
this.externalDatasets.forEach(item => {
|
||||
externalDatasetsFormArray.push(item.buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
|
||||
});
|
||||
// } else {
|
||||
// //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
|
||||
// }
|
||||
formGroup.addControl('externalDatasets', formBuilder.array(externalDatasetsFormArray));
|
||||
|
||||
// const tagsFormArray = new Array<FormGroup>();
|
||||
// if (this.tags && this.tags.length > 0) {
|
||||
// this.tags.forEach(item => {
|
||||
// tagsFormArray.push(item.buildForm(context.getValidation('tags').descendantValidations, disabled));
|
||||
// });
|
||||
// } else {
|
||||
// //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
|
||||
// }
|
||||
// formGroup.addControl('tags', formBuilder.array(tagsFormArray));
|
||||
|
||||
const registriesFormArray = new Array<UntypedFormGroup>();
|
||||
//if (this.registries && this.registries.length > 0) {
|
||||
this.registries.forEach(item => {
|
||||
registriesFormArray.push(item.buildForm(context.getValidation('registries').descendantValidations, disabled));
|
||||
});
|
||||
// } else {
|
||||
// //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
|
||||
// }
|
||||
formGroup.addControl('registries', formBuilder.array(registriesFormArray));
|
||||
|
||||
const dataRepositoriesFormArray = new Array<UntypedFormGroup>();
|
||||
//if (this.dataRepositories && this.dataRepositories.length > 0) {
|
||||
this.dataRepositories.forEach(item => {
|
||||
dataRepositoriesFormArray.push(item.buildForm(context.getValidation('dataRepositories').descendantValidations, disabled));
|
||||
});
|
||||
// } else {
|
||||
// //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
|
||||
// }
|
||||
formGroup.addControl('dataRepositories', formBuilder.array(dataRepositoriesFormArray));
|
||||
|
||||
const servicesFormArray = new Array<UntypedFormGroup>();
|
||||
// if (this.services && this.services.length > 0) {
|
||||
this.services.forEach(item => {
|
||||
servicesFormArray.push(item.buildForm(context.getValidation('services').descendantValidations, disabled));
|
||||
});
|
||||
// } else {
|
||||
// //externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
|
||||
// }
|
||||
formGroup.addControl('services', formBuilder.array(servicesFormArray));
|
||||
|
||||
// const tagsFormArray = new Array<FormGroup>();
|
||||
// this.tags.forEach(item => {
|
||||
// tagsFormArray.push(item.buildForm(context.getValidation('tags').descendantValidations, disabled));
|
||||
// });
|
||||
// formGroup.addControl('tags', formBuilder.array(tagsFormArray));
|
||||
|
||||
if (this.datasetProfileDefinition) { formGroup.addControl('datasetProfileDefinition', this.datasetProfileDefinition.buildForm()); }
|
||||
// formGroup.addControl('profile', this.profile.buildForm());
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] });
|
||||
baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] });
|
||||
baseContext.validation.push({ key: 'profile', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'profile')] });
|
||||
baseContext.validation.push({ key: 'uri', validators: [BackendErrorValidator(this.validationErrorModel, 'uri')] });
|
||||
baseContext.validation.push({ key: 'status', validators: [BackendErrorValidator(this.validationErrorModel, 'status')] });
|
||||
baseContext.validation.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] });
|
||||
baseContext.validation.push({ key: 'services', validators: [BackendErrorValidator(this.validationErrorModel, 'services')] });
|
||||
baseContext.validation.push({ key: 'registries', validators: [BackendErrorValidator(this.validationErrorModel, 'registries')] });
|
||||
baseContext.validation.push({ key: 'dataRepositories', validators: [BackendErrorValidator(this.validationErrorModel, 'dataRepositories')] });
|
||||
baseContext.validation.push({ key: 'externalDatasets', validators: [BackendErrorValidator(this.validationErrorModel, 'externalDatasets')] });
|
||||
baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] });
|
||||
baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] });
|
||||
baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] });
|
||||
baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] });
|
||||
baseContext.validation.push({ key: 'modified', validators: []});
|
||||
return baseContext;
|
||||
}
|
||||
}
|
||||
|
||||
export class ExternalTagEditorModel {
|
||||
public abbreviation: String;
|
||||
public definition: String;
|
||||
public id: String;
|
||||
public name: String;
|
||||
public reference: String;
|
||||
public uri: String;
|
||||
|
||||
constructor(id?: String, name?: String) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
fromModel(item: TagModel): ExternalTagEditorModel {
|
||||
this.id = item.id;
|
||||
this.name = item.name;
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
return new UntypedFormBuilder().group({
|
||||
id: [this.id],
|
||||
name: [this.name]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ExternalServiceEditorModel {
|
||||
public id: String;
|
||||
public abbreviation: String;
|
||||
public definition: String;
|
||||
public uri: String;
|
||||
public label: String;
|
||||
public reference: String;
|
||||
public source: String;
|
||||
|
||||
constructor(abbreviation?: String, definition?: String, id?: String, label?: String, reference?: String, uri?: String, source?: String) {
|
||||
this.id = id;
|
||||
this.abbreviation = abbreviation;
|
||||
this.definition = definition;
|
||||
this.uri = uri;
|
||||
this.label = label;
|
||||
this.reference = reference;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
fromModel(item: ServiceModel): ExternalServiceEditorModel {
|
||||
this.id = item.id;
|
||||
this.abbreviation = item.abbreviation;
|
||||
this.definition = item.definition;
|
||||
this.uri = item.uri;
|
||||
this.label = item.label;
|
||||
this.reference = item.reference;
|
||||
this.source = item.source;
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
return new UntypedFormBuilder().group({
|
||||
id: [this.id],
|
||||
abbreviation: [this.abbreviation],
|
||||
label: [this.label, Validators.required],
|
||||
reference: [this.reference],
|
||||
uri: [this.uri, Validators.required],
|
||||
definition: [this.definition],
|
||||
source: [this.source]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ExternalRegistryEditorModel {
|
||||
public abbreviation: String;
|
||||
public definition: String;
|
||||
public id: String;
|
||||
public label: String;
|
||||
public reference: String;
|
||||
public uri: String;
|
||||
public source: String
|
||||
|
||||
constructor(abbreviation?: String, definition?: String, id?: String, label?: String, reference?: String, uri?: String, source?: String) {
|
||||
this.abbreviation = abbreviation;
|
||||
this.definition = definition;
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
this.reference = reference;
|
||||
this.uri = uri;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
fromModel(item: RegistryModel): ExternalRegistryEditorModel {
|
||||
this.abbreviation = item.abbreviation;
|
||||
this.definition = item.definition;
|
||||
this.id = item.id;
|
||||
this.label = item.label;
|
||||
this.reference = item.pid ? item.pid : item.reference;
|
||||
this.uri = item.uri;
|
||||
this.source = item.source
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
return new UntypedFormBuilder().group({
|
||||
id: [this.id],
|
||||
abbreviation: [this.abbreviation],
|
||||
label: [this.label, Validators.required],
|
||||
reference: [this.reference],
|
||||
uri: [this.uri, Validators.required],
|
||||
definition: [this.definition],
|
||||
source: [this.source]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ExternalDatasetEditorModel {
|
||||
|
||||
public abbreviation: String;
|
||||
public id: String;
|
||||
public name: String;
|
||||
public reference: String;
|
||||
public type: ExternalDatasetType;
|
||||
public info: String;
|
||||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
|
||||
public source: String;
|
||||
|
||||
constructor(id?: string, abbreviation?: string, name?: string, reference?: string, source?: String, info?: string, type?: ExternalDatasetType) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.abbreviation = abbreviation;
|
||||
this.reference = reference;
|
||||
this.info = info;
|
||||
this.type = type;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
fromModel(item: ExternalDatasetModel): ExternalDatasetEditorModel {
|
||||
this.abbreviation = item.abbreviation;
|
||||
this.id = item.id;
|
||||
this.name = item.name;
|
||||
this.reference = item.reference;
|
||||
this.type = item.type;
|
||||
this.info = item.info;
|
||||
this.source = item.source;
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
return new UntypedFormBuilder().group({
|
||||
id: [this.id],
|
||||
abbreviation: [this.abbreviation],
|
||||
name: [this.name, Validators.required],
|
||||
reference: [this.reference],
|
||||
type: [this.type],
|
||||
info: [this.info],
|
||||
source: [this.source]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ExternalDataRepositoryEditorModel {
|
||||
public id: string;
|
||||
public name: string;
|
||||
public abbreviation: string;
|
||||
public uri: string;
|
||||
public reference: string;
|
||||
public info: string;
|
||||
public created: Date;
|
||||
public modified: Date;
|
||||
public source: string;
|
||||
|
||||
constructor(id?: string, name?: string, abbreviation?: string, uri?: string, reference?: string, source?: string) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.abbreviation = abbreviation;
|
||||
this.uri = uri;
|
||||
this.reference = reference;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
fromModel(item: DataRepositoryModel): ExternalDataRepositoryEditorModel {
|
||||
this.id = item.id;
|
||||
this.name = item.name;
|
||||
this.abbreviation = item.abbreviation;
|
||||
this.uri = item.uri;
|
||||
this.info = item.info;
|
||||
this.reference = item.pid;
|
||||
this.source = item.source;
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
return new UntypedFormBuilder().group({
|
||||
id: [this.id],
|
||||
name: [this.name, [Validators.required]],
|
||||
abbreviation: [this.abbreviation],
|
||||
uri: [this.uri, [Validators.required]],
|
||||
info: [this.info],
|
||||
reference: [this.reference],
|
||||
source: [this.source]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// export class TagModel implements Serializable<TagModel> {
|
||||
|
||||
// public id: string;
|
||||
// public name: string;
|
||||
|
||||
// constructor(id?: string, name?: string) {
|
||||
// this.id = id;
|
||||
// this.name = name;
|
||||
// }
|
||||
|
||||
// fromJSONObject(item: any): TagModel {
|
||||
// this.id = item.id;
|
||||
// this.name = item.name;
|
||||
// return this;
|
||||
// }
|
||||
|
||||
// buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup {
|
||||
// return new FormBuilder().group({
|
||||
// id: [this.id],
|
||||
// name: [this.name]
|
||||
// });
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,288 @@
|
|||
<div class="main-content">
|
||||
<div class="container-fluid dataset-wizard">
|
||||
<form *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<!-- <form *ngIf="formGroup" [formGroup]="formGroup" (ngSubmit)="formSubmit()"> -->
|
||||
<!-- Dataset Header -->
|
||||
<div class="fixed-editor-header">
|
||||
<div class="card dataset-editor-header">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col info">
|
||||
<ng-container *ngIf="!viewOnly else viewOnlyTemplate">
|
||||
<div *ngIf="isNew" class="dataset-title">{{'DMP-EDITOR.TITLE.ADD-DATASET' | translate}}</div>
|
||||
<div *ngIf="!isNew" class="dataset-title">{{'DMP-EDITOR.TITLE.EDIT-DESCRIPTION' | translate}}</div>
|
||||
<div class="dataset-subtitle">{{ formGroup.get('label').value }} <span *ngIf="isDirty()" class="dataset-changes">({{'DMP-EDITOR.CHANGES' | translate}})</span></div>
|
||||
</ng-container>
|
||||
<ng-template #viewOnlyTemplate>
|
||||
<div class="dataset-title">{{'DMP-EDITOR.TITLE.PREVIEW-DATASET' | translate}}</div>
|
||||
</ng-template>
|
||||
<div class="d-flex flex-direction-row dmp-info">
|
||||
<div class="col-auto dataset-to-dmp">{{'DATASET-LISTING.TOOLTIP.TO-DMP' | translate}}</div>
|
||||
<div class="dmp-title p-0">: {{ formGroup.get('dmp').value.label }}</div>
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<a [routerLink]="['/overview/' + formGroup.get('dmp').value.id]" target="_blank" class="pointer open-in-new-icon">
|
||||
<mat-icon class="size-18">open_in_new</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<button *ngIf="formGroup.get('id').value" [disabled]="isDirty()" [matTooltipDisabled]="!isDirty()"
|
||||
mat-raised-button class="dataset-export-btn" type="button"
|
||||
[matMenuTriggerFor]="exportMenu" (click)="$event.stopPropagation();"
|
||||
[matTooltip]="'DATASET-EDITOR.ACTIONS.DISABLED-EXPORT' | translate">
|
||||
{{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}
|
||||
<mat-icon [disabled]="isDirty()" style="width: 14px;">expand_more</mat-icon>
|
||||
</button>
|
||||
<mat-menu #exportMenu="matMenu" xPosition="before">
|
||||
<button mat-menu-item (click)="downloadPDF(formGroup.get('id').value)">
|
||||
<i class="fa fa-file-pdf-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadDOCX(formGroup.get('id').value)">
|
||||
<i class="fa fa-file-word-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadXML(formGroup.get('id').value)">
|
||||
<i class="fa fa-file-code-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<mat-divider *ngIf="formGroup.get('id').value && (!viewOnly || (!lockStatus && !viewOnly) || lockStatus || (hasReversableStatus() && !lockStatus))"
|
||||
[vertical]="true" class="ml-2 mr-2"></mat-divider>
|
||||
|
||||
<div *ngIf="isDirty() && !viewOnly" class="col-auto d-flex align-items-center pr-0">
|
||||
<button [disabled]="saving" type="button" mat-raised-button class="dataset-discard-btn" (click)="discardChanges()">
|
||||
{{'DMP-EDITOR.ACTIONS.DISCARD' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<button [disabled]="saving" *ngIf="!lockStatus && !viewOnly" mat-raised-button
|
||||
class="dataset-save-btn mr-2" type="button">
|
||||
<span class="d-flex flex-row row">
|
||||
<span (click)="!saving?save():null" class="col">{{ 'DATASET-WIZARD.ACTIONS.SAVE' | translate }}</span>
|
||||
<mat-divider [vertical]="true"></mat-divider>
|
||||
<span *ngIf="!saving" class="align-items-center justify-content-center col-4 d-flex"
|
||||
(click)="$event.stopPropagation();" [matMenuTriggerFor]="menu">
|
||||
<mat-icon >expand_more</mat-icon>
|
||||
</span>
|
||||
<span *ngIf="saving" class="align-items-center justify-content-center col-4 d-flex">
|
||||
<mat-icon >expand_more</mat-icon>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button [disabled]="saving" mat-menu-item (click)="save(saveAnd.close)" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
|
||||
<button [disabled]="saving" mat-menu-item (click)="save(saveAnd.addNew)" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-ADD' | translate }}</button>
|
||||
<button [disabled]="saving" mat-menu-item (click)="save()" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
|
||||
</mat-menu>
|
||||
|
||||
<button [disabled]="saving" *ngIf="!lockStatus && !viewOnly" mat-raised-button class="dataset-save-btn mr-2" type="button" (click)="saveFinalize()">{{ 'DATASET-WIZARD.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<!-- <button *ngIf="!lockStatus && !viewOnly" mat-raised-button class="dataset-save-btn mr-2" (click)="save()" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE' | translate }}</button>
|
||||
<button *ngIf="!lockStatus && !viewOnly" mat-raised-button class="dataset-save-btn mr-2" (click)="save(saveAnd.close)" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
|
||||
<button *ngIf="!lockStatus && !viewOnly" mat-raised-button class="dataset-save-btn mr-2" (click)="save(saveAnd.addNew)">{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-ADD' | translate }}</button> -->
|
||||
<button [disabled]="saving" *ngIf="lockStatus" mat-raised-button disabled class="dataset-save-btn cursor-default" type="button">{{ 'DMP-OVERVIEW.LOCKED' | translate}}</button>
|
||||
<button [disabled]="saving" *ngIf="hasReversableStatus() && !lockStatus" mat-raised-button class="dataset-save-btn mr-2" (click)="reverse()" type="button">{{ 'DATASET-WIZARD.ACTIONS.REVERSE' | translate }}</button>
|
||||
<!-- <button *ngIf="!lockStatus" mat-raised-button class="dataset-save-btn mr-2" (click)="touchForm()" type="button">{{ 'DATASET-WIZARD.ACTIONS.VALIDATE' | translate }}</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row editor-content">
|
||||
<div class="col-auto dataset-stepper">
|
||||
<div class="stepper-back d-flex flex-direction-row">
|
||||
<div class="d-flex align-items-center pr-2 back-to-dmp" (click)="backToDmp(formGroup.get('dmp').value.id)">
|
||||
<mat-icon class="back-icon pointer">chevron_left</mat-icon>
|
||||
<span class="pointer">{{'DATASET-WIZARD.ACTIONS.BACK-TO' | translate}}</span>
|
||||
</div>
|
||||
<div class="col-auto dmp-label ml-3">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
|
||||
</div>
|
||||
<div class="stepper-title">{{'DMP-EDITOR.STEPPER.USER-GUIDE' | translate}}</div>
|
||||
<div class="stepper-options" id="stepper-options">
|
||||
<div class="col stepper-list">
|
||||
<div (click)="table0fContents.onToCentrySelected()" *ngIf="!datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0, 'text-danger':hintErrors}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (2)</div>
|
||||
<div (click)="table0fContents.onToCentrySelected()" *ngIf="datasetInfoValid()" class="main-info" [ngClass]="{'active': this.step === 0}">0. {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (<mat-icon class="done-icon">done</mat-icon>)</div>
|
||||
<div class="row toc-pane-container" #boundary>
|
||||
<div #spacer></div>
|
||||
<table-of-contents [visibilityRulesService]="visRulesService" [selectedFieldsetId]="fieldsetIdWithFocus" #table0fContents
|
||||
[showErrors]="showtocentriesErrors" [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [hasFocus]="step > 0"
|
||||
[formGroup]="formGroup" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [links]="links"
|
||||
[boundary]="boundary" [spacer]="spacer" [isActive]="step !== 0" stickyThing (stepFound)="onStepFound($event)"
|
||||
(currentLinks)="getLinks($event)" (entrySelected)="changeStep($event.entry, $event.execute)"
|
||||
[visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value"></table-of-contents>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stepper-actions">
|
||||
<div mat-raised-button type="button" class="col-auto previous stepper-btn mr-2" [ngClass]="{'previous-disabled': this.step === 0}" (click)="previousStep()">
|
||||
<span class="material-icons">chevron_left</span>
|
||||
<div>{{'DMP-EDITOR.STEPPER.PREVIOUS' | translate}}</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="this.step < this.maxStep" mat-raised-button type="button" class="col-auto stepper-btn dataset-next ml-auto" (click)="nextStep()">
|
||||
<div>{{'DMP-EDITOR.STEPPER.NEXT' | translate}}</div>
|
||||
<span class="material-icons">chevron_right</span>
|
||||
</div>
|
||||
<div *ngIf="!formGroup.get('profile').value" mat-raised-button type="button" class="col-auto stepper-btn dataset-next next-disabled ml-auto">
|
||||
<div>{{'DMP-EDITOR.STEPPER.NEXT' | translate}}</div>
|
||||
<span class="material-icons">chevron_right</span>
|
||||
</div>
|
||||
<button [disabled]="saving" (click)="save(saveAnd.addNew)" *ngIf="(step === maxStep) && !lockStatus && formGroup.get('profile').value && !viewOnly" mat-raised-button type="button" class="col-auto stepper-btn add-dataset-btn ml-auto">
|
||||
{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-ADD' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto pr-0">
|
||||
<app-form-progress-indication class="col-12" *ngIf="formGroup && !viewOnly" [formGroup]="formGroup" [isDatasetEditor]="true"></app-form-progress-indication>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto form" id="dataset-editor-form">
|
||||
<app-dataset-editor-component [hidden]="this.step !== 0" [formGroup]="formGroup" [dmpId]="formGroup.get('dmp').value.id" [availableProfiles]="availableDescriptionTemplates" (formChanged)="formChanged()"></app-dataset-editor-component>
|
||||
<app-dataset-description (visibilityRulesInstance)="visRulesService = $event" [TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX" [hidden]="this.step === 0" *ngIf="formGroup && formGroup.get('datasetProfileDefinition')" [form]="this.formGroup.get('datasetProfileDefinition')" [visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value" [datasetProfileId]="formGroup.get('profile').value" [linkToScroll]="linkToScroll" (fieldsetFocusChange)="fieldsetIdWithFocus = $event"></app-dataset-description>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <mat-slide-toggle [(ngModel)]="showtocentriesErrors">
|
||||
|
||||
</mat-slide-toggle> -->
|
||||
|
||||
<!-- <div class="row">
|
||||
<div class="col-12">
|
||||
<button (click)="printForm()">Print form</button>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button (click)="printFormValue()">Print form value</button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- <div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<div class="card dataset-wizard">
|
||||
<div class="row card-header card-header-plain d-flex">
|
||||
<div class="col-12 card-desc d-flex flex-column justify-content-center">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center flex-wrap-nowrap">
|
||||
<h4 *ngIf="!isNew" class="card-title">{{datasetWizardModel?.label}}
|
||||
<span *ngIf="this.formGroup && this.formGroup.dirty"> -
|
||||
{{ 'GENERAL.STATUSES.EDIT' | translate }}</span>
|
||||
</h4>
|
||||
<div *ngIf="isNew" class="card-desc new-dataset d-flex flex-column justify-content-center">
|
||||
<h4 class="card-title">{{ 'DATASET-WIZARD.TITLE.NEW' | translate }}</h4>
|
||||
</div>
|
||||
|
||||
<div *ngIf="datasetWizardModel && !isNew" class="ml-auto">
|
||||
<button mat-icon-button [matMenuTriggerFor]="actionsMenu" class="more-icon" *ngIf="!publicMode" (click)="$event.stopImmediatePropagation();">
|
||||
<mat-icon class="more-horiz">more_horiz</mat-icon>
|
||||
</button>
|
||||
<mat-menu #actionsMenu="matMenu">
|
||||
<button mat-menu-item (click)="openDmpSearchDialogue()" class="menu-item">
|
||||
<mat-icon>file_copy</mat-icon>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}
|
||||
</button>
|
||||
<button mat-menu-item *ngIf="!viewOnly && !isCopy" (click)="openConfirm(formGroup.get('label').value, formGroup.get('id').value)" class="menu-item">
|
||||
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto d-flex flex-wrap p-2" *ngIf="datasetWizardModel && !isNew">
|
||||
<button mat-raised-button [matMenuTriggerFor]="exportMenu" color="primary" class="lightblue-btn ml-2 export-btn">
|
||||
{{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }} <mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
<mat-menu #exportMenu="matMenu" xPosition="before">
|
||||
<button mat-menu-item (click)="downloadPDF()">
|
||||
<i class="fa fa-file-pdf-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadDOCX()">
|
||||
<i class="fa fa-file-word-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadXML()">
|
||||
<i class="fa fa-file-code-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form *ngIf="formGroup">
|
||||
<div class="d-flex flex-column">
|
||||
<mat-tab-group class="mt-3">
|
||||
<mat-tab>
|
||||
<ng-template mat-tab-label class="tab-label">
|
||||
<i class="material-icons-outlined mr-2">view_agenda</i>
|
||||
{{'DATASET-PROFILE-EDITOR.STEPS.PAGES.DATASET-DETAILS' | translate}}
|
||||
</ng-template>
|
||||
<form *ngIf="formGroup" [formGroup]="formGroup" class="p-3">
|
||||
<mat-form-field class="col-md-6">
|
||||
<app-single-auto-complete [required]="true" [formControl]="formGroup.get('dmp')" placeholder="{{'DATASET-EDITOR.FIELDS.DMP' | translate}}" [configuration]="dmpAutoCompleteConfiguration">
|
||||
</app-single-auto-complete>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-6">
|
||||
<mat-select placeholder=" {{'DATASET-WIZARD.FIRST-STEP.PROFILE'| translate}}" [required]="true" formControlName="profile">
|
||||
<mat-option *ngFor="let profile of availableProfiles" [value]="profile">
|
||||
{{profile.label}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="formGroup.get('profile').hasError('backendError')">
|
||||
{{formGroup.get('profile').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
<app-dataset-editor-component [formGroup]="formGroup"></app-dataset-editor-component>
|
||||
</form>
|
||||
</mat-tab>
|
||||
<mat-tab>
|
||||
<ng-template mat-tab-label>
|
||||
<mat-icon class="mr-2">work_outline</mat-icon>
|
||||
{{'DATASET-PROFILE-EDITOR.STEPS.PAGES.EXTERNAL-REFERENCES' | translate}}
|
||||
</ng-template>
|
||||
<form *ngIf="formGroup" [formGroup]="formGroup" class="p-3">
|
||||
<app-dataset-external-references-editor-component [formGroup]="formGroup" [viewOnly]="viewOnly"></app-dataset-external-references-editor-component>
|
||||
</form>
|
||||
</mat-tab>
|
||||
<mat-tab [disabled]="isNew && (formGroup.get('profile').disabled || !(formGroup.get('profile').valid))">
|
||||
<ng-template mat-tab-label>
|
||||
<div class="d-flex">
|
||||
<mat-icon class="mr-2">library_books</mat-icon>
|
||||
{{'DATASET-PROFILE-EDITOR.STEPS.PAGES.DESCRIPTION' | translate}}
|
||||
</div>
|
||||
</ng-template>
|
||||
<div class="col">
|
||||
<div class="row toc-pane-container" #boundary>
|
||||
<div class="col-md-8 h-100 ">
|
||||
<app-dataset-description-form class="w-100 h-100" *ngIf="formGroup && datasetWizardModel && datasetWizardModel.datasetProfileDefinition" [form]="this.formGroup.get('datasetProfileDefinition')" [visibilityRules]="datasetWizardModel.datasetProfileDefinition.rules" [datasetProfileId]="formGroup.get('profile').value" [linkToScroll]="linkToScroll">
|
||||
</app-dataset-description-form>
|
||||
</div>
|
||||
<div #spacer></div>
|
||||
<div class="col-md-4">
|
||||
<table-of-contents class="toc-pane-container" [boundary]="boundary" [spacer]="spacer" stickyThing (stepFound)="onStepFound($event)"></table-of-contents>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
|
||||
<div class="actions">
|
||||
<mat-icon *ngIf="hasNotReversableStatus() || lockStatus" color="accent" class="align-self-center mr-1">info_outlined</mat-icon>
|
||||
<div *ngIf="hasNotReversableStatus()" class="align-self-center mr-3">{{'DATASET-WIZARD.ACTIONS.INFO' | translate}}</div>
|
||||
<div *ngIf="lockStatus" class="align-self-center mr-3">{{'DATASET-WIZARD.ACTIONS.LOCK' | translate}}</div>
|
||||
<button mat-raised-button (click)="cancel()" type="button" class="cancelButton" color="primary">
|
||||
{{'DMP-EDITOR.ACTIONS.CANCEL' | translate}}
|
||||
</button>
|
||||
<button *ngIf="(datasetWizardModel.status == 0 || isNew) && !lockStatus" mat-raised-button class="saveButton" color="primary" (click)="save();" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE' | translate }}</button>
|
||||
<button *ngIf="(datasetWizardModel.status == 0 || isNew) && !lockStatus" mat-raised-button class="finalizeButton" color="primary" (click)="saveFinalize();" type="button">{{ 'DATASET-WIZARD.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<div class="fill-space"></div>
|
||||
<button *ngIf="hasReversableStatus() && !lockStatus" mat-raised-button class="reverseButton" color="primary" (click)="reverse()" type="button">{{ 'DATASET-WIZARD.ACTIONS.REVERSE' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
|
@ -0,0 +1,524 @@
|
|||
.main-content {
|
||||
height: 100vh !important;
|
||||
margin-top: -80px;
|
||||
}
|
||||
|
||||
.dataset-wizard {
|
||||
.toc-pane-container {
|
||||
&.is-sticky ~ .nav-spacer {
|
||||
height: 500px; // the container size }
|
||||
// height: calc(100vh - 100px); // the container size }
|
||||
}
|
||||
}
|
||||
|
||||
.step-container {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.external-item-card {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.external-item-action-row,
|
||||
.description-action-row {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.deleteButton,
|
||||
.reverseButton {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.cancelButton {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.saveButton {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.saveAndFinalizeButton {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.finalizeButton {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.export-btn {
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.downloadPDF {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.downloadXML {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.downloadDOCX {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.updateDatasetProfile {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
// .actions > button {
|
||||
// background-color: #0070c0;
|
||||
// color: #ffffff;
|
||||
// text-transform: uppercase;
|
||||
// }
|
||||
|
||||
.more-horiz {
|
||||
font-size: 28px;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.more-icon :hover {
|
||||
color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
.new-dataset {
|
||||
height: 3.5em;
|
||||
}
|
||||
|
||||
.fixed-editor-header {
|
||||
// position: fixed;
|
||||
// width: calc(100% - 310px);
|
||||
z-index: 3;
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
.dataset-editor-header {
|
||||
height: 113px;
|
||||
background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box;
|
||||
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #00000029;
|
||||
padding: 0.6rem;
|
||||
margin: 30px 0px 0px 0px;
|
||||
border-radius: 4px;
|
||||
opacity: 1;
|
||||
|
||||
.info {
|
||||
flex: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.dataset-title {
|
||||
text-align: left;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: left;
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dataset-subtitle {
|
||||
text-align: left;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
opacity: 0.9;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.discard-btn {
|
||||
background: transparent;
|
||||
border: 1px solid #ffffff;
|
||||
color: white;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
width: 110px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
width: auto;
|
||||
min-width: 110px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.dataset-discard-btn {
|
||||
border: 1px solid #212121;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
background-color: transparent;
|
||||
font-weight: 700;
|
||||
width: 110px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dataset-save-btn, .dataset-export-btn {
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
width: auto;
|
||||
min-width: 110px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dataset-to-dmp {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.dmp-info {
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
.dmp-label {
|
||||
min-width: 67px;
|
||||
height: 37px;
|
||||
background: var(--primary-color) 0% 0% no-repeat padding-box;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
opacity: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dmp-title {
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: 1rem;
|
||||
color: #212121;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.open-in-new-icon {
|
||||
color: #434343;
|
||||
opacity: 0.75;
|
||||
}
|
||||
.open-in-new-icon:hover {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.dataset-stepper {
|
||||
position: fixed;
|
||||
// height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 246px);
|
||||
// max-width: 366px;
|
||||
}
|
||||
|
||||
.stepper-options {
|
||||
height: calc(100vh - 600px);
|
||||
overflow-y: auto;
|
||||
.main-info {
|
||||
padding-left: .2rem;
|
||||
color: #21212194;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
.main-info:hover {
|
||||
background-color: #ececec;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.stepper-back {
|
||||
margin-top: 3.125rem;
|
||||
padding-left: 0.5rem;
|
||||
font-size: 0.875rem;
|
||||
letter-spacing: 0px;
|
||||
color: #848484;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.stepper-title {
|
||||
text-align: left;
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
opacity: 0.6;
|
||||
margin: 2.875rem 0rem 2.25rem 0rem;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.stepper-list {
|
||||
.toc-pane-container {
|
||||
// padding-left: 0.2rem;
|
||||
// overflow-x: hidden;
|
||||
span {
|
||||
text-align: left;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
padding: 0.3rem 0.1rem;
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
max-width: 290px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stepper-list span:hover {
|
||||
background-color: #ececec;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.stepper-list .active {
|
||||
color: #212121;
|
||||
font-weight: 700;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.stepper-list .active-dataset {
|
||||
color: #212121;
|
||||
font-weight: 700;
|
||||
opacity: 1;
|
||||
.label {
|
||||
width: 100%;
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
background-color: var(--secondary-color);
|
||||
color: #5d5d5d;
|
||||
border-radius: 4px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
justify-content: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 0.625rem;
|
||||
padding-right: 0.625rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.back-to-dmp:hover {
|
||||
background: #ececec;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.editor-content {
|
||||
.form {
|
||||
// position: relative;
|
||||
// left: 362px;
|
||||
// width: calc(100% - 366px);
|
||||
|
||||
position: relative;
|
||||
left: 362px;
|
||||
width: calc(100% - 366px);
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 218px);
|
||||
}
|
||||
}
|
||||
|
||||
form {
|
||||
height: calc(100vh - 124px);
|
||||
margin-top: 6rem;
|
||||
}
|
||||
|
||||
.stepper-actions {
|
||||
display: flex;
|
||||
padding-left: 1rem;
|
||||
margin-top: auto;
|
||||
margin-bottom: 0.5rem;
|
||||
// margin-top: 5rem;
|
||||
// flex-grow: 8;
|
||||
}
|
||||
|
||||
.stepper-btn {
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
width: 154px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.previous {
|
||||
color: #212121;
|
||||
background: #f5f5f5 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
border: 2px solid #212121;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.add-dataset-btn {
|
||||
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
font-weight: 500;
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.next {
|
||||
background: var(--primary-color) 0% 0% no-repeat padding-box;
|
||||
color: white;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
font-weight: 400;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dataset-next {
|
||||
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||
color: #212121;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.previous-disabled {
|
||||
border: 1px solid #b5b5b5;
|
||||
color: #b5b5b5 !important;
|
||||
cursor: auto !important;
|
||||
}
|
||||
|
||||
.next-disabled {
|
||||
background: #cbcbcb 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
color: white;
|
||||
cursor: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
mat-icon.size-18 {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
width: 248px;
|
||||
}
|
||||
|
||||
.toc-pane-container {
|
||||
&.is-sticky ~ .nav-spacer {
|
||||
height: 500px; // the container size }
|
||||
// height: calc(100vh - 100px); // the container size }
|
||||
}
|
||||
}
|
||||
|
||||
.is-sticky {
|
||||
margin-top: 70px !important;
|
||||
}
|
||||
|
||||
.done-icon {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
font-size: 16px !important;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
// ::ng-deep .mat-tab-labels {
|
||||
// justify-content: space-between;
|
||||
// }
|
||||
|
||||
// ::ng-deep .mat-tab-label-content {
|
||||
// text-transform: uppercase;
|
||||
// }
|
||||
|
||||
// ::ng-deep .mat-ink-bar {
|
||||
// background-color: var(--primary-color-3) !important;
|
||||
// // background-color: #0070c0 !important;
|
||||
// }
|
||||
|
||||
// @media (max-width: 768px) {
|
||||
// .main-content {
|
||||
// padding: 30px 0px;
|
||||
// }
|
||||
|
||||
// ::ng-deep .mat-expansion-panel-header {
|
||||
// min-height: 48px;
|
||||
// height: auto !important;
|
||||
// }
|
||||
|
||||
// ::ng-deep .mat-expansion-panel-body {
|
||||
// padding: 0 0px 16px !important;
|
||||
// }
|
||||
|
||||
// ::ng-deep .mat-vertical-content {
|
||||
// padding: 0 14px 24px 14px !important;
|
||||
// }
|
||||
// }
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,489 @@
|
|||
<form *ngIf="formGroup" [formGroup]="formGroup" class="dataset-external-references-editor">
|
||||
<!-- Tags -->
|
||||
<div class="pt-2">
|
||||
<div class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">1.3 {{'DATASET-EDITOR.FIELDS.TAGS' | translate}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tags-form">
|
||||
<mat-form-field appearance="outline">
|
||||
<app-multiple-auto-complete [configuration]="tagsAutoCompleteConfiguration" [formControl]="formGroup.get('tags')" placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}" [separatorKeysCodes]="separatorKeysCodes"></app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Data Repositories -->
|
||||
<!-- <div class="pt-2">
|
||||
<div class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">1.5 {{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto d-flex align-items-center" *ngIf='!viewOnly'>
|
||||
<button class="col-auto" mat-raised-button (click)="addDataRepository()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('dataRepositories') && dataRepositoriesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.dataRepositories" placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}" [parentTemplate]='dataRepositoriesTemplate' [formArray]="formGroup.get('dataRepositories')" [autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration" (onItemChange)="dataRepositoriesOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
<ng-template #dataRepositoriesTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<span class="col">
|
||||
{{i+1}}) {{suggestion.get('name').value}}
|
||||
</span>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.LABEL' | translate}}" type="text" name="name" [formControl]="suggestion.get('name')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.URI' | translate}}" type="text" name="uri" [formControl]="suggestion.get('uri')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES-INFO' | translate}}" type="text" name="info" [formControl]="suggestion.get('info')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateDataRepository(suggestion)" type="button">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly'>
|
||||
<button mat-icon-button (click)="callback(i)">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div> -->
|
||||
<!-- External Datasets -->
|
||||
<!-- <div class="pt-2">
|
||||
<div class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">1.6 {{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto d-flex align-items-center" *ngIf='!viewOnly'><button mat-raised-button (click)="addExternalDataset()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<span class="hint">{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS-DESCRIPTION' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('externalDatasets') && externalDatasetsTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.externalDatasets" placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}" [parentTemplate]='externalDatasetsTemplate' [formArray]="formGroup.get('externalDatasets')" [autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration" (onItemChange)="externalDatasetsOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
|
||||
<ng-template #externalDatasetsTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('name').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.LABEL' | translate}}" type="text" name="name" [formControl]="suggestion.get('name')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASET-INFO' | translate}}" type="text" name="info" [formControl]="suggestion.get('info')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="{{'DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-DATASET-TYPE' | translate}}" [formControl]="suggestion.get('type')" required>
|
||||
<mat-option [value]="0">{{'TYPES.EXTERNAL-DATASET-TYPE.SOURCE' | translate}}</mat-option>
|
||||
<mat-option [value]="1">{{'TYPES.EXTERNAL-DATASET-TYPE.OUTPUT' | translate}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="suggestion.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateExternalDataset(suggestion)" type="button">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div> -->
|
||||
<!-- Registries -->
|
||||
<!-- <div class="pt-2">
|
||||
<div class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">1.7 {{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto d-flex align-items-center" *ngIf='!viewOnly'><button mat-raised-button (click)="addRegistry()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('registries') && registriesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.registries" placeholder="{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}" [parentTemplate]='registriesTemplate' [formArray]="formGroup.get('registries')" [autoCompleteConfiguration]="registriesAutoCompleteConfiguration" (onItemChange)="registriesOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
|
||||
<ng-template #registriesTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('label').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.LABEL' | translate}}" type="text" name="label" [formControl]="suggestion.get('label')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.URI' | translate}}" type="text" name="uri" [formControl]="suggestion.get('uri')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateRegistry(suggestion)" type="button">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div> -->
|
||||
<!-- Services -->
|
||||
<!-- <div class="pt-2">
|
||||
<div class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">1.8 {{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto d-flex align-items-center" *ngIf='!viewOnly'>
|
||||
<button mat-raised-button (click)="addService()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('services') && servicesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.services" placeholder="{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}" [parentTemplate]='servicesTemplate' [formArray]="formGroup.get('services')" [autoCompleteConfiguration]="servicesAutoCompleteConfiguration" (onItemChange)="servicesOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
|
||||
<ng-template #servicesTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('label').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.LABEL' | translate}}" type="text" name="label" [formControl]="suggestion.get('label')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.URI' | translate}}" type="text" name="uri" [formControl]="suggestion.get('uri')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateRegistry(suggestion)" type="button">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div> -->
|
||||
</form>
|
||||
|
||||
<!-- <form *ngIf="formGroup" [formGroup]="formGroup" class="dataset-external-references-editor">
|
||||
<mat-card class="col-12 external-item-card">
|
||||
<div class="row">
|
||||
<div class="col-12 row">
|
||||
<h4 class="col-auto">{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto" *ngIf='!viewOnly'>
|
||||
<button class="col-auto" mat-raised-button color="primary" (click)="addDataRepository()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('dataRepositories') && dataRepositoriesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.dataRepositories" placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}" [parentTemplate]='dataRepositoriesTemplate' [formArray]="formGroup.get('dataRepositories')" [autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration" (onItemChange)="dataRepositoriesOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
<ng-template #dataRepositoriesTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<span class="col">
|
||||
{{i+1}}) {{suggestion.get('name').value}}
|
||||
</span>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.LABEL' | translate}}" type="text" name="name" [formControl]="suggestion.get('name')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.URI' | translate}}" type="text" name="uri" [formControl]="suggestion.get('uri')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES-INFO' | translate}}" type="text" name="info" [formControl]="suggestion.get('info')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateDataRepository(suggestion)" type="button" color="primary">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly'>
|
||||
<button mat-icon-button (click)="callback(i)">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-card>
|
||||
<mat-card class="col-12 external-item-card">
|
||||
<div class="row">
|
||||
<div class="col-12 row">
|
||||
<h4 class="col-auto">{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto" *ngIf='!viewOnly'><button mat-raised-button color="primary" (click)="addExternalDataset()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<span>{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS-DESCRIPTION' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('externalDatasets') && externalDatasetsTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.externalDatasets" placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}" [parentTemplate]='externalDatasetsTemplate' [formArray]="formGroup.get('externalDatasets')" [autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration" (onItemChange)="externalDatasetsOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
|
||||
<ng-template #externalDatasetsTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('name').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.LABEL' | translate}}" type="text" name="name" [formControl]="suggestion.get('name')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASET-INFO' | translate}}" type="text" name="info" [formControl]="suggestion.get('info')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<mat-form-field>
|
||||
<mat-select placeholder="{{'DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-DATASET-TYPE' | translate}}" [formControl]="suggestion.get('type')" required>
|
||||
<mat-option [value]="0">{{'TYPES.EXTERNAL-DATASET-TYPE.SOURCE' | translate}}</mat-option>
|
||||
<mat-option [value]="1">{{'TYPES.EXTERNAL-DATASET-TYPE.OUTPUT' | translate}}</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="suggestion.get('type').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateExternalDataset(suggestion)" type="button" color="primary">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="col-12 external-item-card">
|
||||
<div class="row">
|
||||
<div class="col-12 row">
|
||||
<h4 class="col-auto">{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto" *ngIf='!viewOnly'><button mat-raised-button color="primary" (click)="addRegistry()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('registries') && registriesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.registries" placeholder="{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}" [parentTemplate]='registriesTemplate' [formArray]="formGroup.get('registries')" [autoCompleteConfiguration]="registriesAutoCompleteConfiguration" (onItemChange)="registriesOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
|
||||
<ng-template #registriesTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('label').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.LABEL' | translate}}" type="text" name="label" [formControl]="suggestion.get('label')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.URI' | translate}}" type="text" name="uri" [formControl]="suggestion.get('uri')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateRegistry(suggestion)" type="button" color="primary">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="col-12 external-item-card">
|
||||
<div class="row">
|
||||
<div class="col-12 row">
|
||||
<h4 class="col-auto">{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}</h4>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto" *ngIf='!viewOnly'>
|
||||
<button mat-raised-button color="primary" (click)="addService()">
|
||||
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-external-item-listing class="col-12" *ngIf="formGroup.get('services') && servicesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.services" placeholder="{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}" [parentTemplate]='servicesTemplate' [formArray]="formGroup.get('services')" [autoCompleteConfiguration]="servicesAutoCompleteConfiguration" (onItemChange)="servicesOnItemChange($event)">
|
||||
</app-external-item-listing>
|
||||
|
||||
<ng-template #servicesTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('label').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.LABEL' | translate}}" type="text" name="label" [formControl]="suggestion.get('label')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.ABBREVIATION' | translate}}" type="text" name="abbreviation" [formControl]="suggestion.get('abbreviation')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isInternal(suggestion)">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.URI' | translate}}" type="text" name="uri" [formControl]="suggestion.get('uri')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf='!viewOnly && isInternal(suggestion)'>
|
||||
<button mat-raised-button (click)="updateRegistry(suggestion)" type="button" color="primary">
|
||||
{{ 'DATASET-EDITOR.ACTIONS.UPDATE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="col-12 external-item-card">
|
||||
<div class="row">
|
||||
<div class="col-12 row">
|
||||
<h4 class="col-auto">{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}</h4>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <app-external-item-listing *ngIf="formGroup.get('tags') && tagsTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.tags" placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}" [parentTemplate]='tagsTemplate' [formArray]="formGroup.get('tags')" [autoCompleteConfiguration]="tagsAutoCompleteConfiguration" (onItemChange)="tagsOnItemChange($event)">
|
||||
</app-external-item-listing> -->
|
||||
<!-- <mat-form-field>
|
||||
<mat-chip-list #chipList [disabled]="viewOnly">
|
||||
<mat-chip *ngFor="let tag of formGroup.get('tags').value"
|
||||
[removable]="true" (removed)="removeTag(tag)">
|
||||
{{tag.name}}
|
||||
<mat-icon matChipRemove *ngIf="!viewOnly">cancel</mat-icon>
|
||||
</mat-chip>
|
||||
<input matInput [disabled]="viewOnly" placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}"
|
||||
[matChipInputFor]="chipList"
|
||||
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
||||
[matChipInputAddOnBlur]="true"
|
||||
(matChipInputTokenEnd)="addTag($event)">
|
||||
</mat-chip-list>
|
||||
</mat-form-field>
|
||||
|
||||
<ng-template #tagsTemplate let-suggestion let-i="index" let-callback="function">
|
||||
<div class="col-12 row align-items-center">
|
||||
<div class="col">
|
||||
<p>
|
||||
{{i+1}}) {{suggestion.get('name').value}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-card>
|
||||
</form> -->
|
|
@ -0,0 +1,35 @@
|
|||
.dataset-external-references-editor {
|
||||
.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: 2.125rem;
|
||||
}
|
||||
|
||||
.external-item-card {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
::ng-deep .tags-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
::ng-deep .tags-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
font-size: 1rem;
|
||||
padding: 0.6em 0 1em 0 !important;
|
||||
}
|
|
@ -0,0 +1,341 @@
|
|||
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
|
||||
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item';
|
||||
import { ExternalSourcesConfiguration } from '@app/core/model/external-sources/external-sources-configuration';
|
||||
import { DataRepositoryCriteria } from '@app/core/query/data-repository/data-repository-criteria';
|
||||
import { ExternalDatasetCriteria } from '@app/core/query/external-dataset/external-dataset-criteria';
|
||||
import { RegistryCriteria } from '@app/core/query/registry/registry-criteria';
|
||||
import { RequestItem } from '@app/core/query/request-item';
|
||||
import { ServiceCriteria } from '@app/core/query/service/service-criteria';
|
||||
import { TagCriteria } from '@app/core/query/tag/tag-criteria';
|
||||
import { ExternalSourcesConfigurationService } from '@app/core/services/external-sources/external-sources-configuration.service';
|
||||
import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service';
|
||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||
import { ExternalDataRepositoryEditorModel, ExternalDatasetEditorModel, ExternalRegistryEditorModel, ExternalServiceEditorModel, ExternalTagEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
|
||||
import { DatasetExternalDataRepositoryDialogEditorComponent } from '@app/ui/dataset/dataset-wizard/external-references/editors/data-repository/dataset-external-data-repository-dialog-editor.component';
|
||||
import { DatasetExternalDatasetDialogEditorComponent } from '@app/ui/dataset/dataset-wizard/external-references/editors/external-dataset/dataset-external-dataset-dialog-editor.component';
|
||||
import { DatasetExternalRegistryDialogEditorComponent } from '@app/ui/dataset/dataset-wizard/external-references/editors/registry/dataset-external-registry-dialog-editor.component';
|
||||
import { DatasetExternalServiceDialogEditorComponent } from '@app/ui/dataset/dataset-wizard/external-references/editors/service/dataset-external-service-dialog-editor.component';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { takeUntil, map } from 'rxjs/operators';
|
||||
import { ENTER, COMMA } from '@angular/cdk/keycodes';
|
||||
import { MatChipInputEvent } from '@angular/material/chips';
|
||||
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
|
||||
import { ExternalDataRepositoryService } from '@app/core/services/external-sources/data-repository/extternal-data-repository.service';
|
||||
import { ExternalDatasetService } from '@app/core/services/external-sources/dataset/external-dataset.service';
|
||||
import { ExternalRegistryService } from '@app/core/services/external-sources/registry/external-registry.service';
|
||||
import { ExternalServiceService } from '@app/core/services/external-sources/service/external-service.service';
|
||||
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dataset-external-references-editor-component',
|
||||
templateUrl: 'dataset-external-references-editor.component.html',
|
||||
styleUrls: ['./dataset-external-references-editor.component.scss']
|
||||
})
|
||||
export class DatasetExternalReferencesEditorComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@Input() formGroup: UntypedFormGroup = null;
|
||||
@Input() viewOnly = false;
|
||||
@Output() formChanged: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
public filteringTagsAsync = false;
|
||||
public filteredTags: ExternalSourceItemModel[];
|
||||
|
||||
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
|
||||
|
||||
externalDatasetAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
|
||||
filterFn: this.searchDatasetExternalDatasets.bind(this),
|
||||
initialItems: (type) => this.searchDatasetExternalDatasets('', type),//.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1),
|
||||
displayFn: (item) => item ? item.name : null,
|
||||
titleFn: (item) => item ? item.name : null,
|
||||
subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')
|
||||
};
|
||||
|
||||
registriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
|
||||
filterFn: this.searchDatasetExternalRegistries.bind(this),
|
||||
initialItems: (type) => this.searchDatasetExternalRegistries('', type),
|
||||
displayFn: (item) => item ? item.name : null,
|
||||
titleFn: (item) => item ? item.name : null,
|
||||
subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')
|
||||
};
|
||||
|
||||
dataRepositoriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
|
||||
filterFn: this.searchDatasetExternalDataRepositories.bind(this),
|
||||
initialItems: (type) => this.searchDatasetExternalDataRepositories('', type),
|
||||
displayFn: (item) => item ? item.name : null,
|
||||
titleFn: (item) => item ? item.name : null,
|
||||
subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')
|
||||
};
|
||||
|
||||
servicesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
|
||||
filterFn: this.searchDatasetExternalServices.bind(this),
|
||||
initialItems: (type) => this.searchDatasetExternalServices('', type),
|
||||
displayFn: (item) => item ? item.label : null,
|
||||
titleFn: (item) => item ? item.label : null,
|
||||
subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')
|
||||
};
|
||||
|
||||
tagsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
filterFn: this.filterTags.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterTags('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => this.showTag(item),
|
||||
titleFn: (item) => item['name'],
|
||||
valueAssign: (item) => this.addTag(item)
|
||||
};
|
||||
|
||||
externalSourcesConfiguration: ExternalSourcesConfiguration;
|
||||
|
||||
// new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetRepository.bind(this.externalSourcesService),
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private router: Router,
|
||||
private language: TranslateService,
|
||||
private externalSourcesService: ExternalSourcesService,
|
||||
private externalSourcesConfigurationService: ExternalSourcesConfigurationService,
|
||||
private externalDataRepositoryService: ExternalDataRepositoryService,
|
||||
private externalDatasetService: ExternalDatasetService,
|
||||
private externalRegistryService: ExternalRegistryService,
|
||||
private externalServiceService: ExternalServiceService,
|
||||
) { super(); }
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
this.externalSourcesConfigurationService.getExternalSourcesConfiguration()
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
this.externalSourcesConfiguration = result;
|
||||
this.externalSourcesConfiguration.dataRepositories.push({ key: '', label: 'All' });
|
||||
this.externalSourcesConfiguration.externalDatasets.push({ key: '', label: 'All' });
|
||||
this.externalSourcesConfiguration.registries.push({ key: '', label: 'All' });
|
||||
this.externalSourcesConfiguration.services.push({ key: '', label: 'All' });
|
||||
if (!isNullOrUndefined(this.externalSourcesConfiguration.tags)) {
|
||||
this.externalSourcesConfiguration.tags.push({ key: '', label: 'All' });
|
||||
} else {
|
||||
this.externalSourcesConfiguration.tags = [{ key: '', label: 'All' }];
|
||||
}
|
||||
});
|
||||
|
||||
this.formGroup.valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(val => {
|
||||
this.formChanged.emit(val);
|
||||
});
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.router.navigate(['/datasets']);
|
||||
}
|
||||
|
||||
externalDatasetsOnItemChange(event) {
|
||||
const externalDatasetModel = new ExternalDatasetEditorModel(event.id, event.abbreviation, event.name, event.pid ? event.pid : event.reference, event.source);
|
||||
(<UntypedFormArray>this.formGroup.get('externalDatasets')).push(externalDatasetModel.buildForm());
|
||||
}
|
||||
|
||||
registriesOnItemChange(event) {
|
||||
const registryModel = new ExternalRegistryEditorModel(event.abbreviation, event.definition, event.id, event.name, event.pid ? event.pid : event.reference, event.uri, event.source);
|
||||
(<UntypedFormArray>this.formGroup.get('registries')).push(registryModel.buildForm());
|
||||
}
|
||||
|
||||
servicesOnItemChange(event) {
|
||||
const serviceModel = new ExternalServiceEditorModel(event.abbreviation, event.definition, event.id, event.label, event.reference, event.uri);
|
||||
(<UntypedFormArray>this.formGroup.get('services')).push(serviceModel.buildForm());
|
||||
}
|
||||
|
||||
tagsOnItemChange(event) {
|
||||
const tagModel = new ExternalTagEditorModel(event.id, event.name);
|
||||
(<UntypedFormArray>this.formGroup.get('tags')).push(tagModel.buildForm());
|
||||
}
|
||||
|
||||
|
||||
dataRepositoriesOnItemChange(event) {
|
||||
const dataRepositoryModel = new ExternalDataRepositoryEditorModel(event.id, event.name, event.abbreviation, event.uri, event.pid, event.source);
|
||||
(<UntypedFormArray>this.formGroup.get('dataRepositories')).push(dataRepositoryModel.buildForm());
|
||||
}
|
||||
|
||||
addDataRepository() {
|
||||
const dialogRef = this.dialog.open(DatasetExternalDataRepositoryDialogEditorComponent, {
|
||||
width: '500px',
|
||||
restoreFocus: false,
|
||||
data: {}
|
||||
});
|
||||
dialogRef.afterClosed()
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (!result) { return; }
|
||||
const dataRepositoryModel = new ExternalDataRepositoryEditorModel(result.id, result.name, result.abbreviation, result.uri, result.pid, result.source);
|
||||
(<UntypedFormArray>this.formGroup.get('dataRepositories')).push(dataRepositoryModel.buildForm());
|
||||
});
|
||||
}
|
||||
|
||||
addRegistry() {
|
||||
const dialogRef = this.dialog.open(DatasetExternalRegistryDialogEditorComponent, {
|
||||
width: '500px',
|
||||
restoreFocus: false,
|
||||
data: {}
|
||||
});
|
||||
dialogRef.afterClosed()
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (!result) { return; }
|
||||
const registryModel = new ExternalRegistryEditorModel(result.abbreviation, result.definition, result.id, result.label, result.reference, result.uri, result.source);
|
||||
(<UntypedFormArray>this.formGroup.get('registries')).push(registryModel.buildForm());
|
||||
});
|
||||
}
|
||||
|
||||
addExternalDataset() {
|
||||
const dialogRef = this.dialog.open(DatasetExternalDatasetDialogEditorComponent, {
|
||||
width: '500px',
|
||||
restoreFocus: false,
|
||||
data: {}
|
||||
});
|
||||
dialogRef.afterClosed()
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (!result) { return; }
|
||||
const externalDatasetModel = new ExternalDatasetEditorModel(result.id, result.abbreviation, result.name, result.reference, result.source);
|
||||
(<UntypedFormArray>this.formGroup.get('externalDatasets')).push(externalDatasetModel.buildForm());
|
||||
});
|
||||
}
|
||||
|
||||
addService() {
|
||||
const dialogRef = this.dialog.open(DatasetExternalServiceDialogEditorComponent, {
|
||||
width: '500px',
|
||||
restoreFocus: false,
|
||||
data: {}
|
||||
});
|
||||
dialogRef.afterClosed()
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (!result) { return; }
|
||||
const serviceModel = new ExternalServiceEditorModel(result.abbreviation, result.definition, result.id, result.label, result.reference, result.uri, result.source);
|
||||
(<UntypedFormArray>this.formGroup.get('services')).push(serviceModel.buildForm());
|
||||
});
|
||||
}
|
||||
|
||||
searchDatasetExternalDatasets(query: string, type: string): Observable<ExternalSourceItemModel[]> {
|
||||
const requestItem: RequestItem<ExternalDatasetCriteria> = new RequestItem();
|
||||
requestItem.criteria = new ExternalDatasetCriteria();
|
||||
requestItem.criteria.like = query;
|
||||
requestItem.criteria.type = type;
|
||||
return this.externalSourcesService.searchDatasetSExternalDatasetservice(requestItem);
|
||||
}
|
||||
|
||||
searchDatasetExternalDataRepositories(query: string, type: string): Observable<ExternalSourceItemModel[]> {
|
||||
const requestItem: RequestItem<DataRepositoryCriteria> = new RequestItem();
|
||||
requestItem.criteria = new DataRepositoryCriteria();
|
||||
requestItem.criteria.like = query;
|
||||
requestItem.criteria.type = type;
|
||||
return this.externalSourcesService.searchDatasetRepository(requestItem);
|
||||
}
|
||||
|
||||
searchDatasetExternalRegistries(query: string, type: string): Observable<ExternalSourceItemModel[]> {
|
||||
const requestItem: RequestItem<RegistryCriteria> = new RequestItem();
|
||||
requestItem.criteria = new RegistryCriteria();
|
||||
requestItem.criteria.like = query;
|
||||
requestItem.criteria.type = type;
|
||||
return this.externalSourcesService.searchDatasetRegistry(requestItem);
|
||||
}
|
||||
|
||||
searchDatasetExternalServices(query: string, type: string): Observable<ExternalSourceItemModel[]> {
|
||||
const requestItem: RequestItem<ServiceCriteria> = new RequestItem();
|
||||
requestItem.criteria = new ServiceCriteria();
|
||||
requestItem.criteria.like = query;
|
||||
requestItem.criteria.type = type;
|
||||
return this.externalSourcesService.searchDatasetService(requestItem);
|
||||
}
|
||||
|
||||
searchDatasetTags(query: string, type: string): Observable<ExternalSourceItemModel[]> {
|
||||
const requestItem: RequestItem<TagCriteria> = new RequestItem();
|
||||
requestItem.criteria = new TagCriteria();
|
||||
requestItem.criteria.like = query;
|
||||
requestItem.criteria.type = type;
|
||||
return this.externalSourcesService.searchDatasetTags(requestItem);
|
||||
}
|
||||
|
||||
removeTag(tag: any) {
|
||||
(<UntypedFormArray>this.formGroup.get('tags')).removeAt(((<UntypedFormArray>this.formGroup.get('tags')).value as any[]).indexOf(tag));
|
||||
}
|
||||
|
||||
addTag(ev: any) {
|
||||
let item: ExternalTagEditorModel;
|
||||
//this.filteredTags = this.formGroup.get('tags').value;
|
||||
if (typeof ev === 'string') {
|
||||
item = new ExternalTagEditorModel('', ev);
|
||||
} else {
|
||||
item = ev;
|
||||
}
|
||||
if (item.name !== '' ) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
isInternal(element: any): boolean {
|
||||
if (element.get('source') == null) {
|
||||
// console.log(element);
|
||||
}
|
||||
return element.get('source').value === 'Internal';
|
||||
}
|
||||
|
||||
updateDataRepository(dataRepository: UntypedFormGroup) {
|
||||
this.externalDataRepositoryService.create(dataRepository.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(result) => {
|
||||
dataRepository.setValue(result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateExternalDataset(externalDataset: UntypedFormGroup) {
|
||||
this.externalDatasetService.create(externalDataset.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(result) => {
|
||||
externalDataset.setValue(result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateRegistry(registry: UntypedFormGroup) {
|
||||
this.externalRegistryService.create(registry.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(result) => {
|
||||
registry.setValue(result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateService(service: UntypedFormGroup) {
|
||||
this.externalServiceService.create(service.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(result) => {
|
||||
service.setValue(result);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
filterTags(value: string): Observable<ExternalSourceItemModel[]> {
|
||||
this.filteringTagsAsync = true;
|
||||
|
||||
const requestItem: RequestItem<TagCriteria> = new RequestItem();
|
||||
const criteria: TagCriteria = new TagCriteria();
|
||||
criteria.like = value;
|
||||
requestItem.criteria = criteria;
|
||||
return this.externalSourcesService.searchDatasetTags(requestItem);
|
||||
}
|
||||
|
||||
showTag(ev: any) {
|
||||
if (typeof ev === 'string') {
|
||||
return ev;
|
||||
} else {
|
||||
return ev.name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<form *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<div class="row d-flex flex-row">
|
||||
<div mat-dialog-title class="col-auto">
|
||||
{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.TITLE' | translate}}
|
||||
</div>
|
||||
<div class="col-auto ml-auto close-btn" (click)="close()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div mat-dialog-content class="row">
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="name" placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.LABEL' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="abbreviation" placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.ABBREVIATION' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('abbreviation').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="uri" placeholder="{{'DATASET-REFERENCED-MODELS.DATA-REPOSITORY.URI' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="row">
|
||||
<div class="ml-auto col-auto"><button mat-raised-button type="button" mat-dialog-close>Cancel</button></div>
|
||||
<div class="col-auto"><button mat-raised-button color="primary" (click)="send()" type="button">Save</button></div>
|
||||
</div>
|
||||
</form>
|
|
@ -0,0 +1,3 @@
|
|||
.close-btn {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ExternalDataRepositoryService } from '@app/core/services/external-sources/data-repository/extternal-data-repository.service';
|
||||
import { ExternalDataRepositoryEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'dataset-external-data-repository-dialog-editor.component.html',
|
||||
styleUrls: ['./dataset-external-data-repository-dialog-editor.component.scss']
|
||||
})
|
||||
export class DatasetExternalDataRepositoryDialogEditorComponent extends BaseComponent implements OnInit {
|
||||
public formGroup: UntypedFormGroup;
|
||||
|
||||
constructor(
|
||||
private externalDataRepositoryService: ExternalDataRepositoryService,
|
||||
public dialogRef: MatDialogRef<DatasetExternalDataRepositoryDialogEditorComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private formService: FormService
|
||||
) { super(); }
|
||||
|
||||
ngOnInit(): void {
|
||||
const datarepo = new ExternalDataRepositoryEditorModel();
|
||||
this.formGroup = datarepo.buildForm();
|
||||
}
|
||||
|
||||
send(value: any) {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.formGroup.valid) { return; }
|
||||
this.externalDataRepositoryService.create(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(item) => this.dialogRef.close(item)
|
||||
);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<form *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<div class="row d-flex flex-row">
|
||||
<div mat-dialog-title class="col-auto">
|
||||
{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.TITLE' | translate}}
|
||||
</div>
|
||||
<div class="col-auto ml-auto close-btn" (click)="close()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div mat-dialog-content class="row">
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="name" placeholder="{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.LABEL' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="abbreviation" placeholder="{{'DATASET-REFERENCED-MODELS.EXTERNAL-DATASET.ABBREVIATION' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('abbreviation').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="row">
|
||||
<div class="ml-auto col-auto"><button mat-raised-button mat-dialog-close type="button">Cancel</button></div>
|
||||
<div class="col-auto"><button mat-raised-button color="primary" (click)="send()" type="button">Save</button></div>
|
||||
</div>
|
||||
</form>
|
|
@ -0,0 +1,3 @@
|
|||
.close-btn {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ExternalDatasetService } from '@app/core/services/external-sources/dataset/external-dataset.service';
|
||||
import { ExternalDatasetEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'dataset-external-dataset-dialog-editor.component.html',
|
||||
styleUrls: ['./dataset-external-dataset-dialog-editor.component.scss']
|
||||
})
|
||||
export class DatasetExternalDatasetDialogEditorComponent extends BaseComponent implements OnInit {
|
||||
public formGroup: UntypedFormGroup;
|
||||
|
||||
constructor(
|
||||
private externalDatasetService: ExternalDatasetService,
|
||||
public dialogRef: MatDialogRef<DatasetExternalDatasetDialogEditorComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private formService: FormService
|
||||
) { super(); }
|
||||
|
||||
ngOnInit(): void {
|
||||
const externalDatasetModel = new ExternalDatasetEditorModel();
|
||||
this.formGroup = externalDatasetModel.buildForm();
|
||||
}
|
||||
|
||||
send(value: any) {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.formGroup.valid) { return; }
|
||||
this.externalDatasetService.create(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(item) => this.dialogRef.close(item)
|
||||
);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<form *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<div class="row d-flex flex-row">
|
||||
<div mat-dialog-title class="col-auto">
|
||||
{{'DATASET-REFERENCED-MODELS.REGISTRY.TITLE' | translate}}
|
||||
</div>
|
||||
<div class="col-auto ml-auto close-btn" (click)="close()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div mat-dialog-content class="row">
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="label" placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.LABEL' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="abbreviation" placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.ABBREVIATION' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('abbreviation').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="uri" placeholder="{{'DATASET-REFERENCED-MODELS.REGISTRY.URI' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="row">
|
||||
<div class="ml-auto col-auto"><button mat-raised-button mat-dialog-close type="button">Cancel</button></div>
|
||||
<div class="col-auto"><button mat-raised-button color="primary" (click)="send()" type="button">Save</button></div>
|
||||
</div>
|
||||
</form>
|
|
@ -0,0 +1,3 @@
|
|||
.close-btn {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ExternalRegistryService } from '@app/core/services/external-sources/registry/external-registry.service';
|
||||
import { ExternalRegistryEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'dataset-external-registry-dialog-editor.component.html',
|
||||
styleUrls: ['./dataset-external-registry-dialog-editor.component.scss']
|
||||
})
|
||||
export class DatasetExternalRegistryDialogEditorComponent extends BaseComponent implements OnInit {
|
||||
public formGroup: UntypedFormGroup;
|
||||
|
||||
constructor(
|
||||
private externalRegistryService: ExternalRegistryService,
|
||||
public dialogRef: MatDialogRef<DatasetExternalRegistryDialogEditorComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private formService: FormService
|
||||
) { super(); }
|
||||
|
||||
ngOnInit(): void {
|
||||
const registryModel = new ExternalRegistryEditorModel();
|
||||
this.formGroup = registryModel.buildForm();
|
||||
}
|
||||
|
||||
send(value: any) {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.formGroup.valid) { return; }
|
||||
this.externalRegistryService.create(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(item) => this.dialogRef.close(item)
|
||||
);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<form *ngIf="formGroup" [formGroup]="formGroup">
|
||||
<div class="row d-flex flex-row">
|
||||
<div mat-dialog-title class="col-auto">
|
||||
{{'DATASET-REFERENCED-MODELS.SERVICES.TITLE' | translate}}
|
||||
</div>
|
||||
<div class="col-auto ml-auto close-btn" (click)="close()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div mat-dialog-content class="row">
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="label" placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.LABEL' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="abbreviation" placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.ABBREVIATION' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('abbreviation').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-auto">
|
||||
<input matInput formControlName="uri" placeholder="{{'DATASET-REFERENCED-MODELS.SERVICES.URI' | translate}}" required>
|
||||
<mat-error *ngIf="formGroup.get('uri').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div mat-dialog-actions class="row">
|
||||
<div class="ml-auto col-auto"><button mat-raised-button mat-dialog-close type="button">Cancel</button></div>
|
||||
<div class="col-auto"><button mat-raised-button color="primary" (click)="send()" type="button">Save</button></div>
|
||||
</div>
|
||||
</form>
|
|
@ -0,0 +1,3 @@
|
|||
.close-btn {
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { ExternalServiceService } from '@app/core/services/external-sources/service/external-service.service';
|
||||
import { ExternalServiceEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'dataset-external-service-dialog-editor.component.html',
|
||||
styleUrls: ['./dataset-external-service-dialog-editor.component.scss']
|
||||
})
|
||||
export class DatasetExternalServiceDialogEditorComponent extends BaseComponent implements OnInit {
|
||||
public formGroup: UntypedFormGroup;
|
||||
|
||||
constructor(
|
||||
private externalServiceService: ExternalServiceService,
|
||||
public dialogRef: MatDialogRef<DatasetExternalServiceDialogEditorComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private formService: FormService
|
||||
) { super(); }
|
||||
|
||||
ngOnInit(): void {
|
||||
const serviceModel = new ExternalServiceEditorModel();
|
||||
this.formGroup = serviceModel.buildForm();
|
||||
}
|
||||
|
||||
send() {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.formGroup.valid) { return; }
|
||||
this.externalServiceService.create(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
(item) => this.dialogRef.close(item)
|
||||
);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<div class="template-container">
|
||||
<div mat-dialog-title class="row d-flex m-0 header">
|
||||
<span class="template-title align-self-center">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.TITLE' | translate}}</span>
|
||||
<span class="ml-auto align-self-center" (click)="closeDialog()"><mat-icon
|
||||
class="close-icon">close</mat-icon></span>
|
||||
</div>
|
||||
<div *ngIf="progressIndication" class="progress-bar">
|
||||
<mat-progress-bar color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
</div>
|
||||
<div mat-dialog-content *ngIf="prefillForm" [formGroup]="prefillForm" class="definition-content">
|
||||
<div class="row d-flex align-items-center justify-content-center">
|
||||
<div class="pb-4 pl-4 pr-4">
|
||||
{{'DATASET-CREATE-WIZARD.PREFILL-STEP.HINT' | translate}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row d-flex align-items-center justify-content-center" [class.pb-4]="isPrefilled">
|
||||
<button mat-raised-button type="button" class="empty-btn"
|
||||
(click)="closeDialog()">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.MANUALLY' | translate}}</button>
|
||||
<div class="ml-2 mr-2">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.OR' | translate}}</div>
|
||||
<button mat-raised-button type="button" class="prefill-btn"
|
||||
(click)="isPrefilled = true">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.PREFILL' | translate}}</button>
|
||||
</div>
|
||||
<div *ngIf="isPrefilled" class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.PROFILE' | translate}}</h4>
|
||||
</div>
|
||||
<mat-form-field class="col-md-12">
|
||||
<mat-select placeholder="{{'DATASET-CREATE-WIZARD.PREFILL-STEP.PROFILE'| translate}}" [required]="true" [compareWith]="compareWith" formControlName="profile">
|
||||
<mat-option *ngFor="let profile of data.availableProfiles" [value]="profile">
|
||||
<div (click)="checkMinMax($event, profile)">
|
||||
{{profile.label}}
|
||||
</div>
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="prefillForm.get('profile').hasError('backendError')">{{prefillForm.get('profile').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div *ngIf="isPrefilled" class="row">
|
||||
<div class="col-12 pl-0 pr-0 pb-2 d-flex flex-row">
|
||||
<h4 class="col-auto heading">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.PREFILLED-DATASET' | translate}}</h4>
|
||||
</div>
|
||||
<mat-form-field class="col-md-12">
|
||||
<app-single-auto-complete [required]="true" [formControl]="prefillForm.get('prefill')"
|
||||
placeholder="{{'DATASET-CREATE-WIZARD.PREFILL-STEP.SEARCH' | translate}}"
|
||||
[configuration]="prefillAutoCompleteConfiguration">
|
||||
</app-single-auto-complete>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div *ngIf="isPrefilled">
|
||||
<div class="col-auto d-flex pb-4 pt-2">
|
||||
<button mat-raised-button type="button" class="prefill-btn ml-auto" [disabled]="prefillForm.invalid"
|
||||
(click)="next()">{{'DATASET-CREATE-WIZARD.PREFILL-STEP.NEXT' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,57 @@
|
|||
.template-container {
|
||||
.header {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: var(--secondary-color);
|
||||
color: #212121;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.template-title {
|
||||
margin-left: 37px;
|
||||
white-space: nowrap;
|
||||
width: 480px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
cursor: pointer;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.close-icon:hover {
|
||||
background-color: #fefefe6e !important;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.definition-content {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.empty-btn, .prefill-btn {
|
||||
background: var(--secondary-color) 0 0 no-repeat padding-box;
|
||||
border: 1px solid var(--secondary-color);
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
min-width: 101px;
|
||||
height: 43px;
|
||||
color: #212121;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.prefill-btn:disabled {
|
||||
background: #a1a1a1 0 0 no-repeat padding-box;
|
||||
border: 1px solid #a1a1a1;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.empty-btn {
|
||||
background: #ffffff 0 0 no-repeat padding-box;
|
||||
border: 1px solid #a1a1a1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from "@angular/material/dialog";
|
||||
import { DatasetProfileModel } from "@app/core/model/dataset/dataset-profile";
|
||||
import { Prefilling } from "@app/core/model/dataset/prefilling";
|
||||
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from "@app/core/model/dmp-blueprint/dmp-blueprint";
|
||||
import { DmpBlueprintService } from "@app/core/services/dmp/dmp-blueprint.service";
|
||||
import { PrefillingService } from "@app/core/services/prefilling.service";
|
||||
import { ProgressIndicationService } from "@app/core/services/progress-indication/progress-indication-service";
|
||||
import { SingleAutoCompleteConfiguration } from "@app/library/auto-complete/single/single-auto-complete-configuration";
|
||||
import { PopupNotificationDialogComponent } from "@app/library/notification/popup/popup-notification.component";
|
||||
import { BaseComponent } from "@common/base/base.component";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { map, takeUntil } from "rxjs/operators";
|
||||
import { nameof } from "ts-simple-nameof";
|
||||
|
||||
@Component({
|
||||
selector: 'prefill-dataset-component',
|
||||
templateUrl: 'prefill-dataset.component.html',
|
||||
styleUrls: ['prefill-dataset.component.scss']
|
||||
})
|
||||
export class PrefillDatasetComponent extends BaseComponent implements OnInit {
|
||||
|
||||
progressIndication = false;
|
||||
prefillAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
|
||||
isPrefilled: boolean = false;
|
||||
prefillForm: UntypedFormGroup;
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<PrefillDatasetComponent>,
|
||||
private prefillingService: PrefillingService,
|
||||
private dmpBlueprintService: DmpBlueprintService,
|
||||
private dialog: MatDialog,
|
||||
private language: TranslateService,
|
||||
private progressIndicationService: ProgressIndicationService,
|
||||
private fb: UntypedFormBuilder,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.progressIndicationService.getProgressIndicationObservable().pipe(takeUntil(this._destroyed)).subscribe(x => {
|
||||
setTimeout(() => { this.progressIndication = x; });
|
||||
});
|
||||
this.prefillForm = this.fb.group({
|
||||
type: this.fb.control(false),
|
||||
profile: this.fb.control('', Validators.required),
|
||||
prefill: this.fb.control(null, Validators.required)
|
||||
})
|
||||
if (this.data.availableProfiles && this.data.availableProfiles.length === 1) {
|
||||
this.addProfileIfUsedLessThanMax(this.data.availableProfiles[0]);
|
||||
}
|
||||
this.prefillAutoCompleteConfiguration = {
|
||||
filterFn: this.searchDatasets.bind(this),
|
||||
loadDataOnStart: false,
|
||||
displayFn: (item) => (item['name'].length > 60) ? (item['name'].substr(0, 60) + "...") : item['name'],
|
||||
titleFn: (item) => item['name'],
|
||||
subtitleFn: (item) => item['pid']
|
||||
};
|
||||
}
|
||||
|
||||
addProfileIfUsedLessThanMax(profile: DatasetProfileModel) {
|
||||
const dmpSectionIndex = this.data.datasetFormGroup.get('dmpSectionIndex').value;
|
||||
const blueprintId = this.data.datasetFormGroup.get('dmp').value.profile.id;
|
||||
this.dmpBlueprintService.getSingle(blueprintId, this.getBlueprintDefinitionFields())
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
const section = result.definition.sections[dmpSectionIndex];
|
||||
if (section.hasTemplates) {
|
||||
const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id));
|
||||
if (foundTemplate !== undefined) {
|
||||
let count = 0;
|
||||
if (this.data.datasetFormGroup.get('dmp').value.datasets != null) {
|
||||
for (let dataset of this.data.datasetFormGroup.get('dmp').value.datasets) {
|
||||
if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count < foundTemplate.maxMultiplicity) {
|
||||
this.prefillForm.get('profile').patchValue(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.prefillForm.get('profile').patchValue(profile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.prefillForm.get('profile').patchValue(profile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
checkMinMax(event, profile: DatasetProfileModel) {
|
||||
event.stopPropagation();
|
||||
const dmpSectionIndex = this.data.datasetFormGroup.get('dmpSectionIndex').value;
|
||||
const blueprintId = this.data.datasetFormGroup.get('dmp').value.profile.id;
|
||||
this.dmpBlueprintService.getSingle(blueprintId, this.getBlueprintDefinitionFields())
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
const section = result.definition.sections[dmpSectionIndex];
|
||||
if (section.hasTemplates) {
|
||||
const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id));
|
||||
if (foundTemplate !== undefined) {
|
||||
let count = 0;
|
||||
if (this.data.datasetFormGroup.get('dmp').value.datasets != null) {
|
||||
for (let dataset of this.data.datasetFormGroup.get('dmp').value.datasets) {
|
||||
if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count === foundTemplate.maxMultiplicity) {
|
||||
this.dialog.open(PopupNotificationDialogComponent, {
|
||||
data: {
|
||||
title: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.TITLE'),
|
||||
message: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.MESSAGE')
|
||||
}, maxWidth: '30em'
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.prefillForm.get('profile').setValue(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.prefillForm.get('profile').setValue(profile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.prefillForm.get('profile').setValue(profile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getBlueprintDefinitionFields() {
|
||||
return [
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.description)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
||||
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.dataType)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.systemFieldType)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'),
|
||||
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.id)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateId)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
||||
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||
]
|
||||
}
|
||||
|
||||
public compareWith(object1: any, object2: any) {
|
||||
return object1 && object2 && object1.id === object2.id;
|
||||
}
|
||||
|
||||
searchDatasets(query: string): Observable<Prefilling[]> {
|
||||
return this.prefillingService.getPrefillingList(query).pipe(map(prefilling => prefilling.sort((a, b) => {
|
||||
if (a.name > b.name) {
|
||||
return 1;
|
||||
} else if (a.name < b.name) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.isPrefilled) {
|
||||
if (this.prefillForm.get('prefill').value.data == null) {
|
||||
this.prefillingService.getPrefillingDataset(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => {
|
||||
wizard.profile = this.prefillForm.get('profile').value;
|
||||
this.closeDialog(wizard);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.prefillingService.getPrefillingDatasetUsingData(this.prefillForm.get('prefill').value.data, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => {
|
||||
wizard.profile = this.prefillForm.get('profile').value;
|
||||
this.closeDialog(wizard);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.closeDialog();
|
||||
}
|
||||
}
|
||||
|
||||
closeDialog(result = null): void {
|
||||
this.dialogRef.close(result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { FormattingModule } from '@app/core/formatting.module';
|
||||
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
|
||||
import { ExportMethodDialogModule } from '@app/library/export-method-dialog/export-method-dialog.module';
|
||||
import { RichTextEditorModule } from "@app/library/rich-text-editor/rich-text-editor.module";
|
||||
import { UrlListingModule } from '@app/library/url-listing/url-listing.module';
|
||||
// import { DescriptionEditorComponent } from '@app/ui/description/description-wizard/description-editor/description-editor.component';
|
||||
// import { DescriptionWizardComponent } from '@app/ui/description/description-wizard/description-wizard.component';
|
||||
// import { DescriptionExternalReferencesEditorComponent } from '@app/ui/description/description-wizard/external-references/description-external-references-editor.component';
|
||||
// import { DescriptionExternalDataRepositoryDialogEditorComponent } from '@app/ui/description/description-wizard/external-references/editors/data-repository/description-external-data-repository-dialog-editor.component';
|
||||
// import { DescriptionExternalDescriptionDialogEditorComponent } from '@app/ui/description/description-wizard/external-references/editors/external-description/description-external-description-dialog-editor.component';
|
||||
// import { DescriptionExternalRegistryDialogEditorComponent } from '@app/ui/description/description-wizard/external-references/editors/registry/description-external-registry-dialog-editor.component';
|
||||
// import { DescriptionExternalServiceDialogEditorComponent } from '@app/ui/description/description-wizard/external-references/editors/service/description-external-service-dialog-editor.component';
|
||||
// import { PrefillDescriptionComponent } from "@app/ui/description/description-wizard/prefill-description/prefill-description.component";
|
||||
import { DescriptionRoutingModule } from '@app/ui/description/description.routing';
|
||||
// import { DescriptionCriteriaComponent } from '@app/ui/description/listing/criteria/description-criteria.component';
|
||||
// import { DescriptionUploadDialogue } from '@app/ui/description/listing/criteria/description-upload-dialogue/description-upload-dialogue.component';
|
||||
import { DescriptionListingComponent } from '@app/ui/description/listing/description-listing.component';
|
||||
import { DescriptionListingItemComponent } from '@app/ui/description/listing/listing-item/description-listing-item.component';
|
||||
// import { DescriptionDescriptionFormModule } from '@app/ui/misc/description-description-form/description-description-form.module';
|
||||
// import { TableOfContentsModule } from '@app/ui/misc/description-description-form/tableOfContentsMaterial/table-of-contents.module';
|
||||
import { ExternalSourcesModule } from '@app/ui/misc/external-sources/external-sources.module';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { FormValidationErrorsDialogModule } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.module';
|
||||
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { AngularStickyThingsModule } from '@w11k/angular-sticky-things';
|
||||
// import { FormProgressIndicationModule } from '../misc/description-description-form/components/form-progress-indication/form-progress-indication.module';
|
||||
// import { DescriptionCopyDialogModule } from './description-wizard/description-copy-dialogue/description-copy-dialogue.module';
|
||||
// import { DescriptionCriteriaDialogComponent } from './listing/criteria/description-criteria-dialogue/description-criteria-dialog.component';
|
||||
// import { DescriptionOverviewModule } from './overview/description-overview.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
UrlListingModule,
|
||||
FormattingModule,
|
||||
ConfirmationDialogModule,
|
||||
AutoCompleteModule,
|
||||
ExternalSourcesModule,
|
||||
ExportMethodDialogModule,
|
||||
// DescriptionDescriptionFormModule,
|
||||
// TableOfContentsModule,
|
||||
AngularStickyThingsModule,
|
||||
DescriptionRoutingModule,
|
||||
FormValidationErrorsDialogModule,
|
||||
// DescriptionCopyDialogModule,
|
||||
// DescriptionOverviewModule,
|
||||
// FormProgressIndicationModule,
|
||||
RichTextEditorModule
|
||||
],
|
||||
declarations: [
|
||||
DescriptionListingComponent,
|
||||
// DescriptionCriteriaComponent,
|
||||
// DescriptionWizardComponent,
|
||||
// DescriptionEditorComponent,
|
||||
// DescriptionExternalReferencesEditorComponent,
|
||||
// DescriptionExternalDataRepositoryDialogEditorComponent,
|
||||
// DescriptionExternalDescriptionDialogEditorComponent,
|
||||
// DescriptionExternalRegistryDialogEditorComponent,
|
||||
// DescriptionExternalServiceDialogEditorComponent,
|
||||
// DescriptionUploadDialogue,
|
||||
DescriptionListingItemComponent,
|
||||
// DescriptionCriteriaDialogComponent,
|
||||
// PrefillDescriptionComponent
|
||||
],
|
||||
exports: [
|
||||
// DescriptionExternalReferencesEditorComponent,
|
||||
// DescriptionExternalDataRepositoryDialogEditorComponent,
|
||||
// DescriptionExternalDescriptionDialogEditorComponent,
|
||||
// DescriptionExternalRegistryDialogEditorComponent,
|
||||
// DescriptionExternalServiceDialogEditorComponent,
|
||||
// DescriptionEditorComponent,
|
||||
// DescriptionDescriptionFormModule
|
||||
]
|
||||
})
|
||||
export class DescriptionModule { }
|
|
@ -0,0 +1,129 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard';
|
||||
import { AuthGuard } from '../../core/auth-guard.service';
|
||||
// import { DescriptionWizardComponent } from './description-wizard/description-wizard.component';
|
||||
import { DescriptionListingComponent } from './listing/description-listing.component';
|
||||
// import { DescriptionOverviewComponent } from './overview/description-overview.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DescriptionListingComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
data: {
|
||||
breadcrumb: true
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'dmp/:dmpId',
|
||||
component: DescriptionListingComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
breadcrumb: true
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: 'new/:dmpId/:dmpSectionIndex',
|
||||
// component: DescriptionWizardComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-NEW'
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
// {
|
||||
// path: 'edit/:id',
|
||||
// component: DescriptionWizardComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// public: false,
|
||||
// title: 'GENERAL.TITLES.DATASET-EDIT'
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
// {
|
||||
// path: 'edit/:id/finalize',
|
||||
// component: DescriptionWizardComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// public: false,
|
||||
// title: 'GENERAL.TITLES.DATASET-EDIT',
|
||||
// finalize: true
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
// {
|
||||
// path: 'publicEdit/:publicId',
|
||||
// component: DescriptionWizardComponent,
|
||||
// //canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// public: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-PUBLIC-EDIT'
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
// {
|
||||
// path: 'new',
|
||||
// component: DescriptionWizardComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-NEW'
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
{
|
||||
path: 'dmp/:dmpId',
|
||||
component: DescriptionListingComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
breadcrumb: true
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: 'copy/:id',
|
||||
// component: DescriptionWizardComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-COPY'
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
// {
|
||||
// path: 'profileupdate/:updateId',
|
||||
// component: DescriptionWizardComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-UPDATE'
|
||||
// },
|
||||
// canDeactivate:[CanDeactivateGuard]
|
||||
// },
|
||||
// {
|
||||
// path: 'overview/:id',
|
||||
// component: DescriptionOverviewComponent,
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-OVERVIEW'
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// path: 'publicOverview/:publicId',
|
||||
// component: DescriptionOverviewComponent,
|
||||
// data: {
|
||||
// breadcrumb: true,
|
||||
// title: 'GENERAL.TITLES.DATASET-OVERVIEW'
|
||||
// },
|
||||
// }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DescriptionRoutingModule { }
|
|
@ -0,0 +1,2 @@
|
|||
<a class="col-auto d-flex pointer" (click)="onClose()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a>
|
||||
<app-dataset-criteria-component [isPublic]="data.isPublic" [status]="data.status" [criteriaFormGroup]="data.formGroup" (filtersChanged)="onFiltersChanged($event)"></app-dataset-criteria-component>
|
|
@ -0,0 +1,20 @@
|
|||
.clear-icon {
|
||||
cursor: pointer;
|
||||
color: #212121;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
.clear-icon:hover {
|
||||
background-color: #ececec !important;
|
||||
border-radius: 50%;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-form-field-wrapper {
|
||||
background-color: white !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
padding: 0.3rem 0rem 0.6rem 0rem !important;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, Inject, OnInit, ViewChild } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { DatasetCriteriaComponent } from '../dataset-criteria.component';
|
||||
|
||||
@Component({
|
||||
selector: 'dataset-criteria-dialog-component',
|
||||
templateUrl: './dataset-criteria-dialog.component.html',
|
||||
styleUrls: ['./dataset-criteria-dialog.component.scss']
|
||||
})
|
||||
|
||||
export class DatasetCriteriaDialogComponent implements OnInit {
|
||||
|
||||
@ViewChild(DatasetCriteriaComponent, { static: true }) criteria: DatasetCriteriaComponent;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<DatasetCriteriaDialogComponent>,
|
||||
private httpClient: HttpClient,
|
||||
private matomoService: MatomoService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { isPublic: boolean, status: Number, criteria: DatasetCriteria, formGroup: UntypedFormGroup, updateDataFn: Function }
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.matomoService.trackPageView('Dataset Criteria');
|
||||
this.criteria.setCriteria(this.data.criteria);
|
||||
}
|
||||
|
||||
onNoClick(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onClose(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onFiltersChanged(event) {
|
||||
this.data.updateDataFn(this.criteria);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
<div class="dmp-criteria">
|
||||
<div class="filters">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-10">
|
||||
<h6 class="criteria-title">{{'CRITERIA.FILTERS'| translate}}</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<!-- Search Filter-->
|
||||
<!-- <mat-form-field class="col-11 search">
|
||||
<input matInput placeholder="{{'CRITERIA.GRANTS.LIKE'| translate}}" name="grantCriteriaLike"
|
||||
[formControl]="formGroup.get('like')">
|
||||
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">
|
||||
{{formGroup.get('like').getError('backendError').message}}</mat-error>
|
||||
<mat-icon matSuffix class="style-icon">search</mat-icon>
|
||||
</mat-form-field> -->
|
||||
<!-- End of Search Filter -->
|
||||
|
||||
<!-- Status Filter-->
|
||||
<div class="col-10" *ngIf="!isPublic">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.STATUS'| translate}}</h6>
|
||||
<mat-radio-group aria-label="Select an option" [formControl]="formGroup.get('status')">
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="null" [checked]="!formGroup.get('status').value">{{ 'TYPES.DATASET-STATUS.ANY' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="0">{{ 'TYPES.DATASET-STATUS.DRAFT' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="1">{{ 'TYPES.DATASET-STATUS.FINALISED' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
</mat-radio-group>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Status Filter-->
|
||||
|
||||
<!-- Grant Status -->
|
||||
<div class="col-10" *ngIf="isPublic">
|
||||
<h6 class="category-title">{{ 'FACET-SEARCH.GRANT-STATUS.TITLE' | translate }}</h6>
|
||||
<mat-radio-group [formControl]="formGroup.get('grantStatus')">
|
||||
<mat-list-item>
|
||||
<mat-radio-button checked value="null" [checked]="!formGroup.get('grantStatus').value">{{ 'FACET-SEARCH.GRANT-STATUS.OPTIONS.ANY' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="0">{{ 'FACET-SEARCH.GRANT-STATUS.OPTIONS.ACTIVE' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="1">{{ 'FACET-SEARCH.GRANT-STATUS.OPTIONS.INACTIVE' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
</mat-radio-group>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Grant Status -->
|
||||
|
||||
<!-- Related Dataset Templates Filters -->
|
||||
<div class="col-10">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.RELATED-DATASET-TEMPLATES' | translate}}</h6>
|
||||
<mat-form-field class="mb-4">
|
||||
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-DATASET-TEMPLATES' | translate }}</mat-label>
|
||||
<app-multiple-auto-complete [formControl]="formGroup.get('datasetTemplates')" [configuration]="datasetTemplateAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Related Dataset Templates Filters -->
|
||||
|
||||
<!-- Related DMP Filters -->
|
||||
<div class="col-10">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.RELATED-DMP' | translate}}</h6>
|
||||
<mat-form-field class="mb-4">
|
||||
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-DMP' | translate }}</mat-label>
|
||||
<app-multiple-auto-complete [formControl]="formGroup.get('groupIds')" [configuration]="dmpAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Related DMP Filters -->
|
||||
|
||||
<!-- All Versions Filter-->
|
||||
<div class="col-10" *ngIf="!isPublic">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.ALL-VERSIONS'| translate}}</h6>
|
||||
<mat-slide-toggle [formControl]="formGroup.get('allVersions')"></mat-slide-toggle>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of All Versions Filter-->
|
||||
|
||||
<!-- Related Grant Filters -->
|
||||
<div class="col-10">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.RELATED-GRANT' | translate}}</h6>
|
||||
<mat-form-field class="mb-4">
|
||||
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-GRANTS' | translate }}</mat-label>
|
||||
<app-multiple-auto-complete [formControl]="formGroup.get('grants')" [configuration]="grantAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Related Grants Filters -->
|
||||
|
||||
<!-- Related Collaborators Filters -->
|
||||
<div class="col-10" *ngIf="!isPublic">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.RELATED-COLLABORATORS' | translate}}</h6>
|
||||
<mat-form-field class="mb-4">
|
||||
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-COLLABORATORS' | translate }}</mat-label>
|
||||
<app-multiple-auto-complete [formControl]="formGroup.get('collaborators')" [configuration]="collaboratorsAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Related Collaborators Filters -->
|
||||
|
||||
<!-- Role Filter -->
|
||||
<div class="col-10" *ngIf="isAuthenticated()">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.ROLE' | translate }}</h6>
|
||||
<mat-radio-group aria-label="Select an option" [formControl]="formGroup.get('role')">
|
||||
<mat-list-item>
|
||||
<mat-radio-button checked value="null" [checked]="!formGroup.get('role').value">{{ 'TYPES.DATASET-ROLE.ANY' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="0">{{ 'TYPES.DATASET-ROLE.OWNER' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<mat-radio-button value="1">{{ 'TYPES.DATASET-ROLE.MEMBER' | translate }}</mat-radio-button>
|
||||
</mat-list-item>
|
||||
</mat-radio-group>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Role Filter -->
|
||||
|
||||
<!-- Related Organization Filter -->
|
||||
<div class="col-10">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.ORGANIZATION' | translate }}</h6>
|
||||
<mat-form-field class="mb-4">
|
||||
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-ORGANIZATIONS' | translate}}</mat-label>
|
||||
<app-multiple-auto-complete [formControl]="formGroup.get('organisations')" [configuration]="organisationAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- End of Related Organization Filter -->
|
||||
|
||||
<!-- Tags Filter -->
|
||||
<div class="col-10">
|
||||
<h6 class="category-title">{{'CRITERIA.DATA-SETS.TAGS' | translate }}</h6>
|
||||
<mat-form-field class="mb-4">
|
||||
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-TAGS' | translate}}</mat-label>
|
||||
<app-multiple-auto-complete [formControl]="formGroup.get('tags')" [configuration]="tagsAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<!-- End of Tags Filter -->
|
||||
|
||||
<!-- Import Button -->
|
||||
<!-- <div class="col-10 import">
|
||||
<button class="importButton" mat-raised-button color="primary" (click)="fileSave($event)"
|
||||
type="button col-auto">
|
||||
{{'DMP-UPLOAD.ACTIONS.IMPORT' | translate}}
|
||||
</button>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <form class="dataset-criteria">
|
||||
<mat-card class="mat-card">
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
<h4>{{'CRITERIA.FILTERS'| translate}}</h4>
|
||||
</mat-card-title>
|
||||
<div class="col"></div>
|
||||
<button class="importButton" mat-raised-button color="primary" (click)="fileImport($event)" type="button col-auto">
|
||||
{{'DATASET-UPLOAD.ACTIONS.IMPORT' | translate}}
|
||||
</button>
|
||||
</mat-card-header>
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-3">
|
||||
<input matInput placeholder=" {{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="datasetCriteriaName" [(ngModel)]="criteria.like"
|
||||
(ngModelChange)="controlModified()">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-md-3">
|
||||
<app-multiple-auto-complete placeholder="{{'CRITERIA.DMP.LIKE'| translate}}" name="dmpCriteriaName" [(ngModel)]="criteria.dmpIds"
|
||||
(ngModelChange)="controlModified()" [configuration]="dmpAutoCompleteConfiguration"></app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-md-3">
|
||||
<mat-select placeholder=" {{'CRITERIA.DATA-SETS.STATUS'| translate}}" name="datasetCriteriastatus" [(ngModel)]="criteria.status"
|
||||
(ngModelChange)="controlModified()">
|
||||
<mat-option [value]="null">{{'CRITERIA.DATA-SETS.NONE'| translate}}</mat-option>
|
||||
<mat-option [value]="statuses.Draft">{{enumUtils.toDatasetStatusString(statuses.Draft)}}</mat-option>
|
||||
<mat-option [value]="statuses.Finalized">{{enumUtils.toDatasetStatusString(statuses.Finalized)}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-3">
|
||||
<app-multiple-auto-complete name="datasetCriteriaTags" [(ngModel)]="criteria.tags" (ngModelChange)="controlModified()" placeholder="{{'CRITERIA.DATA-SETS.TAGS' | translate}}"
|
||||
[configuration]="tagsAutoCompleteConfiguration"></app-multiple-auto-complete>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</mat-card>
|
||||
</form> -->
|
|
@ -0,0 +1,56 @@
|
|||
.search ::ng-deep.mat-form-field-infix {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
color: black;
|
||||
// color: #089dbb;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 12px;
|
||||
text-transform: none;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.import {
|
||||
margin: 10px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
// border: 1px solid #e4e4e4;
|
||||
// border-radius: 5px;
|
||||
}
|
||||
|
||||
.criteria-title {
|
||||
color: black;
|
||||
font-weight: 500;
|
||||
text-transform: none;
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 1.5em;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.filters-title {
|
||||
width: 93px;
|
||||
// color: #089dbb;
|
||||
color: var(--primary-color-2);
|
||||
background-color: white;
|
||||
padding: 0px 20px;
|
||||
margin-top: -10px;
|
||||
margin-left: 20px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.style-icon {
|
||||
color: #adadad;
|
||||
}
|
||||
|
||||
::ng-deep .search-form .mat-form-field-wrapper {
|
||||
background-color: white !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
padding: 0.3rem 0rem 0.6rem 0rem !important;
|
||||
}
|
|
@ -0,0 +1,339 @@
|
|||
|
||||
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
|
||||
import { DataTableData } from '@app/core/model/data-table/data-table-data';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
|
||||
import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item';
|
||||
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
|
||||
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
|
||||
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
|
||||
import { GrantCriteria } from '@app/core/query/grant/grant-criteria';
|
||||
import { OrganisationCriteria } from '@app/core/query/organisation/organisation-criteria';
|
||||
import { RequestItem } from '@app/core/query/request-item';
|
||||
import { TagCriteria } from '@app/core/query/tag/tag-criteria';
|
||||
import { UserCriteria } from '@app/core/query/user/user-criteria';
|
||||
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
|
||||
import { DatasetService } from '@app/core/services/dataset/dataset.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service';
|
||||
import { GrantService } from '@app/core/services/grant/grant.service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { OrganisationService } from '@app/core/services/organisation/organisation.service';
|
||||
import { UserServiceOld } from '@app/core/services/user/user.service-old';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||
import { DatasetUploadDialogue } from '@app/ui/dataset/listing/criteria/dataset-upload-dialogue/dataset-upload-dialogue.component';
|
||||
import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
|
||||
import { ExploreDmpCriteriaModel } from '@app/core/query/explore-dmp/explore-dmp-criteria';
|
||||
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dataset-criteria-component',
|
||||
templateUrl: './dataset-criteria.component.html',
|
||||
styleUrls: ['./dataset-criteria.component.scss']
|
||||
})
|
||||
export class DatasetCriteriaComponent extends BaseCriteriaComponent implements OnInit {
|
||||
|
||||
@Input() dmpSearchEnabled;
|
||||
@Input() status;
|
||||
@Input() isPublic: boolean;
|
||||
@Input() criteriaFormGroup: UntypedFormGroup;
|
||||
@Output() filtersChanged: EventEmitter<any> = new EventEmitter();
|
||||
public criteria: any;
|
||||
public filteringTagsAsync = false;
|
||||
public filteredTags: ExternalSourceItemModel[];
|
||||
statuses = DatasetStatus;
|
||||
|
||||
options: UntypedFormGroup;
|
||||
|
||||
public formGroup = new UntypedFormBuilder().group({
|
||||
like: new UntypedFormControl(),
|
||||
groupIds: new UntypedFormControl(),
|
||||
grants: new UntypedFormControl(),
|
||||
status: new UntypedFormControl(),
|
||||
role: new UntypedFormControl(),
|
||||
organisations: new UntypedFormControl(),
|
||||
collaborators: new UntypedFormControl(),
|
||||
datasetTemplates: new UntypedFormControl(),
|
||||
tags: new UntypedFormControl(),
|
||||
allVersions: new UntypedFormControl(),
|
||||
grantStatus: new UntypedFormControl()
|
||||
});
|
||||
|
||||
tagsAutoCompleteConfiguration = {
|
||||
filterFn: this.filterTags.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterTags('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => item['name'],
|
||||
titleFn: (item) => item['name']
|
||||
};
|
||||
|
||||
datasetTemplateAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
filterFn: this.filterDatasetTemplate.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterDatasetTemplate('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => item['label'],
|
||||
titleFn: (item) => item['label'],
|
||||
subtitleFn: (item) => item['description']
|
||||
};
|
||||
|
||||
dmpAutoCompleteConfiguration = {
|
||||
filterFn: (x, excluded) => this.filterDmps(x).pipe(map(x => x.data)),
|
||||
initialItems: (extraData) => this.filterDmps('').pipe(map(x => x.data)),
|
||||
displayFn: (item) => item['label'],
|
||||
titleFn: (item) => item['label']
|
||||
};
|
||||
|
||||
collaboratorsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
filterFn: this.filterCollaborators.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterCollaborators('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => item['name'],
|
||||
titleFn: (item) => item['name']
|
||||
};
|
||||
|
||||
grantAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
filterFn: this.filterGrant.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterGrant('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => item['label'],
|
||||
titleFn: (item) => item['label']
|
||||
};
|
||||
|
||||
organisationAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
|
||||
filterFn: this.filterOrganisations.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => item['name'],
|
||||
titleFn: (item) => item['name']
|
||||
}
|
||||
|
||||
constructor(
|
||||
private externalSourcesService: ExternalSourcesService,
|
||||
public enumUtils: EnumUtils,
|
||||
public dmpService: DmpService,
|
||||
public datasetWizardService: DatasetWizardService,
|
||||
private dialog: MatDialog,
|
||||
private snackBar: MatSnackBar,
|
||||
private uiNotificationService: UiNotificationService,
|
||||
private router: Router,
|
||||
private language: TranslateService,
|
||||
public grantService: GrantService,
|
||||
private organisationService: OrganisationService,
|
||||
private userService: UserServiceOld,
|
||||
private datasetService: DatasetService,
|
||||
fb: UntypedFormBuilder,
|
||||
private authService: AuthService
|
||||
|
||||
) {
|
||||
super(new ValidationErrorModel());
|
||||
// this.options = fb.group({
|
||||
// status: new FormControl(),
|
||||
// floatLabel: 'auto',
|
||||
// });
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
|
||||
// This if is just for passing label on chips of dialog
|
||||
if (this.formGroup && this.criteriaFormGroup) {
|
||||
this.formGroup.get('datasetTemplates').setValue(this.criteriaFormGroup.get('datasetTemplates').value);
|
||||
this.formGroup.get('groupIds').setValue(this.criteriaFormGroup.get('groupIds').value);
|
||||
this.formGroup.get('grants').setValue(this.criteriaFormGroup.get('grants').value);
|
||||
this.formGroup.get('collaborators').setValue(this.criteriaFormGroup.get('collaborators').value);
|
||||
this.formGroup.get('organisations').setValue(this.criteriaFormGroup.get('organisations').value);
|
||||
this.formGroup.get('tags').setValue(this.criteriaFormGroup.get('tags').value);
|
||||
|
||||
}
|
||||
|
||||
this.formGroup.get('like').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('groupIds').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('grants').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('status').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('role').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('organisations').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('collaborators').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('datasetTemplates').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('allVersions').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('tags').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('grantStatus').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => this.controlModified());
|
||||
// if (this.criteria == null) { this.criteria = {}; }
|
||||
// this.formGroup.patchValue({'status': this.status !== undefined ? this.status : 'null'});
|
||||
}
|
||||
|
||||
setCriteria(criteria: DatasetCriteria): void {
|
||||
this.formGroup.get('like').patchValue(criteria.like);
|
||||
this.formGroup.get('groupIds').patchValue(criteria.groupIds);
|
||||
this.formGroup.get('grants').patchValue(criteria.grants);
|
||||
this.formGroup.get('status').patchValue(criteria.status);
|
||||
this.formGroup.get('role').patchValue(criteria.role);
|
||||
this.formGroup.get('collaborators').patchValue(criteria.collaborators);
|
||||
this.formGroup.get('datasetTemplates').patchValue(criteria.datasetTemplates);
|
||||
this.formGroup.get('allVersions').patchValue(criteria.allVersions);
|
||||
this.formGroup.get('tags').patchValue(criteria.tags);
|
||||
this.formGroup.get('grantStatus').patchValue(criteria.grantStatus);
|
||||
// this.criteria = criteria;
|
||||
}
|
||||
|
||||
controlModified(): void {
|
||||
this.clearErrorModel();
|
||||
this.filtersChanged.emit();
|
||||
if (this.refreshCallback != null &&
|
||||
(this.formGroup.get('like').value == null || this.formGroup.get('like').value.length === 0 || this.formGroup.get('like').value.length > 2)
|
||||
) {
|
||||
setTimeout(() => this.refreshCallback(true));
|
||||
}
|
||||
// if (this.refreshCallback != null &&
|
||||
// (this.criteria.like == null || this.criteria.like.length === 0 || this.criteria.like.length > 2)
|
||||
// ) {
|
||||
// this.refreshCallback();
|
||||
// }
|
||||
}
|
||||
|
||||
filterTags(value: string): Observable<ExternalSourceItemModel[]> {
|
||||
this.filteredTags = undefined;
|
||||
this.filteringTagsAsync = true;
|
||||
|
||||
const requestItem: RequestItem<TagCriteria> = new RequestItem();
|
||||
const criteria: TagCriteria = new TagCriteria();
|
||||
criteria.like = value;
|
||||
requestItem.criteria = criteria;
|
||||
return this.externalSourcesService.searchDatasetTags(requestItem);
|
||||
}
|
||||
|
||||
filterDatasetTemplate(query: string): Observable<any[]> {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
const datasetTemplateRequestItem: DataTableRequest<DatasetProfileCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
datasetTemplateRequestItem.criteria = new DatasetProfileCriteria();
|
||||
datasetTemplateRequestItem.criteria.like = query;
|
||||
if (this.isPublic) {
|
||||
return this.datasetService.getDatasetProfiles(datasetTemplateRequestItem);
|
||||
} else {
|
||||
return this.datasetService.getDatasetProfilesUsedPaged(datasetTemplateRequestItem).pipe(map(x => x.data));
|
||||
}
|
||||
}
|
||||
|
||||
filterDmps(value: string): Observable<DataTableData<DmpListingModel>> {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
|
||||
// if (this.isPublic) {
|
||||
// const dmpDataTableRequest: DataTableRequest<ExploreDmpCriteriaModel> = new DataTableRequest(0, null, { fields: fields });
|
||||
// dmpDataTableRequest.criteria = new ExploreDmpCriteriaModel();
|
||||
// dmpDataTableRequest.criteria.like = value;
|
||||
// return this.dmpService.getPublicPaged(dmpDataTableRequest, "autocomplete");
|
||||
// } else {
|
||||
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
dmpDataTableRequest.criteria = new DmpCriteria();
|
||||
dmpDataTableRequest.criteria.like = value;
|
||||
if (this.isPublic) {
|
||||
dmpDataTableRequest.criteria.isPublic = true;
|
||||
dmpDataTableRequest.criteria.onlyPublic = true;
|
||||
}
|
||||
return this.dmpService.getPaged(dmpDataTableRequest, "autocomplete");
|
||||
// }
|
||||
}
|
||||
|
||||
filterGrant(query: string) {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
const grantRequestItem: DataTableRequest<GrantCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
grantRequestItem.criteria = new GrantCriteria();
|
||||
grantRequestItem.criteria.like = query;
|
||||
if (this.isPublic) {
|
||||
return this.grantService.getPublicPaged(grantRequestItem).pipe(map(x => x.data));
|
||||
} else {
|
||||
return this.grantService.getPaged(grantRequestItem, "autocomplete").pipe(map(x => x.data));
|
||||
}
|
||||
}
|
||||
|
||||
filterOrganisations(value: string) {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
const dataTableRequest: DataTableRequest<OrganisationCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
dataTableRequest.criteria = new OrganisationCriteria();
|
||||
dataTableRequest.criteria.labelLike = value;
|
||||
if (this.isPublic) {
|
||||
return this.organisationService.searchPublicOrganisations(dataTableRequest).pipe(map(x => x.data));
|
||||
} else {
|
||||
return this.organisationService.searchInternalOrganisations(dataTableRequest).pipe(map(x => x.data));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
filterCollaborators(query: string) {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
const collaboratorsRequestItem: DataTableRequest<UserCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
collaboratorsRequestItem.criteria = new UserCriteria();
|
||||
collaboratorsRequestItem.criteria.collaboratorLike = query;
|
||||
return this.userService.getCollaboratorsPaged(collaboratorsRequestItem).pipe(map(x => x.data));
|
||||
}
|
||||
|
||||
fileImport(event) {
|
||||
const dialogRef = this.dialog.open(DatasetUploadDialogue, {
|
||||
data: {
|
||||
fileList: FileList,
|
||||
success: Boolean,
|
||||
datasetTitle: String,
|
||||
dmpId: String,
|
||||
datasetProfileId: String,
|
||||
dmpSearchEnabled: this.dmpSearchEnabled,
|
||||
criteria: this.criteria
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result && result.success) {
|
||||
this.datasetWizardService.uploadXml(result.fileList, result.datasetTitle, result.dmpId, result.datasetProfileId)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-UPLOAD.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success);
|
||||
this.router.navigate(['/plans']);
|
||||
}
|
||||
|
||||
onCallbackError(error: any) {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Success);
|
||||
}
|
||||
|
||||
isAuthenticated(): boolean {
|
||||
return this.authService.currentAccountIsAuthenticated();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<div class="confirmation-dialog">
|
||||
<div class="row">
|
||||
<div class="confirmation-message col align-self-center">
|
||||
<h4>{{'DATASET-UPLOAD.TITLE' | translate}}</h4>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button class="col-auto" (click)="fileInput.click()" type="button">
|
||||
<mat-icon color="primary">attach_file</mat-icon>
|
||||
</button>
|
||||
<input class="hidden" #fileInput type="file" (change)="uploadFile($event)" accept="text/xml">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-form-field class="col-12">
|
||||
<input class="uploadInput" [(ngModel)]="datasetTitle" [disabled]="disableDatasetName()" matInput placeholder="{{'DATASET-UPLOAD.PLACEHOLDER' | translate}}"
|
||||
name="uploadFileInput">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-12">
|
||||
<app-single-auto-complete [required]="true" [(ngModel)]="dmp" (ngModelChange)="controlModified()" placeholder="{{'CRITERIA.DMP.LIKE' | translate}}"
|
||||
[configuration]="dmpAutoCompleteConfiguration" [disabled]="disableDmpSearch()">
|
||||
</app-single-auto-complete>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-md-12">
|
||||
<mat-select placeholder=" {{'DATASET-UPLOAD.DATASET-PROFILE.SELECT'| translate}}" [required]="true" [(value)]="datasetProfile"
|
||||
[disabled]="disableDatasetProfile()">
|
||||
<mat-option *ngFor="let datasetProfile of availableProfiles" [value]="datasetProfile">
|
||||
{{datasetProfile.label}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button type="button" (click)="cancel()">{{'DATASET-UPLOAD.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button color="primary" type="button" (click)="confirm()" [disabled]="disableButton()">{{'DATASET-UPLOAD.ACTIONS.IMPORT' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,21 @@
|
|||
.confirmation-dialog {
|
||||
.confirmation-message {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.uploadButton {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.col-md-6 {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin: -4px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DataTableData } from '@app/core/model/data-table/data-table-data';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||
import { DmpModel } from '@app/core/model/dmp/dmp';
|
||||
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
|
||||
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
|
||||
import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria';
|
||||
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
|
||||
import { RequestItem } from '@app/core/query/request-item';
|
||||
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'dataset-upload-dialogue',
|
||||
templateUrl: './dataset-upload-dialogue.component.html',
|
||||
styleUrls: ['./dataset-upload-dialogue.component.scss']
|
||||
})
|
||||
export class DatasetUploadDialogue extends BaseCriteriaComponent implements OnInit {
|
||||
|
||||
public dialogueCriteria: any;
|
||||
datasetTitle: string;
|
||||
dmp: DmpModel;
|
||||
datasetProfile: DatasetProfileModel;
|
||||
availableProfiles: DatasetProfileModel[] = [];
|
||||
|
||||
dmpAutoCompleteConfiguration = {
|
||||
filterFn: (x, excluded) => this.filterDmps(x).pipe(map(x => x.data)),
|
||||
initialItems: (extraData) => this.filterDmps('').pipe(map(x => x.data)),
|
||||
displayFn: (item) => item['label'],
|
||||
titleFn: (item) => item['label']
|
||||
};
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<DatasetUploadDialogue>,
|
||||
public dmpService: DmpService,
|
||||
private datasetWizardService: DatasetWizardService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
) { super(new ValidationErrorModel()); }
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
if (this.dialogueCriteria == null) { this.dialogueCriteria = {}; }
|
||||
if (!this.data.dmpSearchEnabled) {
|
||||
this.dialogueCriteria = this.data.criteria;
|
||||
this.dmp = this.dialogueCriteria.dmpIds[0];
|
||||
this.loadDatasetProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.data.success = false;
|
||||
this.dialogRef.close(this.data)
|
||||
}
|
||||
|
||||
confirm() {
|
||||
this.data.success = true;
|
||||
this.data.datasetTitle = this.datasetTitle;
|
||||
this.data.dmpId = this.dmp.id;
|
||||
this.data.datasetProfileId = this.datasetProfile.id;
|
||||
this.dialogRef.close(this.data);
|
||||
}
|
||||
|
||||
uploadFile(event) {
|
||||
const fileList: FileList = event.target.files
|
||||
this.data.fileList = fileList;
|
||||
if (this.data.fileList.length > 0) {
|
||||
this.datasetTitle = fileList.item(0).name;
|
||||
}
|
||||
}
|
||||
|
||||
filterDmps(value: string): Observable<DataTableData<DmpListingModel>> {
|
||||
const fields: Array<string> = new Array<string>();
|
||||
fields.push('asc');
|
||||
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||
dmpDataTableRequest.criteria = new DmpCriteria();
|
||||
dmpDataTableRequest.criteria.like = value;
|
||||
return this.dmpService.getPaged(dmpDataTableRequest, "autocomplete");
|
||||
}
|
||||
|
||||
controlModified(): void {
|
||||
this.loadDatasetProfiles();
|
||||
if (!this.dmp) {
|
||||
this.availableProfiles = [];
|
||||
}
|
||||
this.clearErrorModel();
|
||||
if (this.refreshCallback != null &&
|
||||
(this.dialogueCriteria.like == null || this.dialogueCriteria.like.length === 0 || this.dialogueCriteria.like.length > 2)
|
||||
) {
|
||||
this.refreshCallback();
|
||||
}
|
||||
}
|
||||
|
||||
loadDatasetProfiles() {
|
||||
const datasetProfileRequestItem: RequestItem<DatasetProfileCriteria> = new RequestItem();
|
||||
datasetProfileRequestItem.criteria = new DatasetProfileCriteria();
|
||||
if (this.dmp) {
|
||||
datasetProfileRequestItem.criteria.id = this.dmp.id;
|
||||
}
|
||||
if (datasetProfileRequestItem.criteria.id) {
|
||||
this.datasetWizardService.getAvailableProfiles(datasetProfileRequestItem)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(items => {
|
||||
this.availableProfiles = items;
|
||||
if (this.availableProfiles.length === 1) {
|
||||
this.datasetProfile = this.availableProfiles[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setCriteriaDialogue(criteria: DatasetCriteria): void {
|
||||
this.dialogueCriteria = criteria;
|
||||
}
|
||||
|
||||
disableButton() {
|
||||
if (!(this.data.fileList.length > 0) || !this.dmp) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
disableDatasetName() {
|
||||
if (!(this.data.fileList.length > 0)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
disableDmpSearch() {
|
||||
if (!(this.data.fileList.length > 0) || !this.data.dmpSearchEnabled) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
disableDatasetProfile() {
|
||||
if (!this.dmp || (!this.data.dmpSearchEnabled && !(this.data.fileList.length > 0)) || (!this.data.dmpSearchEnabled && this.availableProfiles.length === 1)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<div class="main-content listing-main-container h-100">
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex flex-direction-row">
|
||||
<div *ngIf="hasListingItems && listingItems && listingItems.length === 0 && !hasLikeCriteria()" class="card mt-0">
|
||||
<!-- <div class="card mt-0" [style.display]="isVisible ? 'block' : 'none'"> -->
|
||||
<!-- <a class="col-auto d-flex" (click)="closeCard()"><span class="ml-auto pt-3 material-icons clear-icon">clear</span></a> -->
|
||||
<div class="card-content info-text mb-0">
|
||||
<p>{{'DATASET-LISTING.TEXT-INFO' | translate}} <u class="pointer" [routerLink]="['/explore']">{{'DATASET-LISTING.LINK-PUBLIC-DATASETS' | translate}}</u> {{'DATASET-LISTING.TEXT-INFO-REST' | translate}}</p>
|
||||
<p class="mt-4 pt-2">{{'DATASET-LISTING.TEXT-INFO-PAR' | translate}}
|
||||
<div class="d-flex">
|
||||
<button mat-raised-button class="add-description align-self-center yellow-btn" (click)="addNewDescription()">
|
||||
{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}
|
||||
</button>
|
||||
<img class="col-auto ml-auto laptop-img" src="../../../assets/images/dashboard-popup.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p *ngIf="listingItems && listingItems.length > 0 || this.lookup.like" class="col-auto header-title">{{(isPublic ? 'GENERAL.TITLES.EXPLORE' : 'GENERAL.TITLES.DESCRIPTIONS') | translate}}</p>
|
||||
<div *ngIf="listingItems && listingItems.length > 0 && !isPublic || this.lookup.like" class="ml-auto">
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button class="add-description align-self-center yellow-btn" (click)="addNewDescription()">
|
||||
{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="listingItems && listingItems.length > 0 || this.lookup.like" class="filter-btn" [style.right]="dialog.getDialogById('filters') ? '446px' : '0px'" [style.width]="scrollbar ? '57px' : '37px'" (click)="openFiltersDialog()">
|
||||
<button mat-raised-button class="p-0">
|
||||
<mat-icon class="mr-4">filter_alt</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="listing row pb-2">
|
||||
<div *ngIf="listingItems && listingItems.length > 0 || this.lookup.like" class="col-md-12">
|
||||
<div class="d-flex flex-direction-row pt-4">
|
||||
<!-- Sort by -->
|
||||
<span class="d-flex align-items-center">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
|
||||
<mat-form-field class="sort-form col-auto pr-0">
|
||||
<mat-select placeholder="{{'CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
|
||||
<mat-option *ngIf="!isPublic" [value]="order.MODIFIED">{{enumUtils.toRecentActivityOrderString(order.MODIFIED)}}</mat-option>
|
||||
<mat-option *ngIf="isPublic" [value]="order.DATASETPUBLISHED">{{enumUtils.toRecentActivityOrderString(order.DATASETPUBLISHED)}}</mat-option>
|
||||
<mat-option [value]="order.LABEL">{{enumUtils.toRecentActivityOrderString(order.LABEL)}}</mat-option>
|
||||
<mat-option *ngIf="!isPublic" [value]="order.STATUS">{{enumUtils.toRecentActivityOrderString(order.STATUS)}}</mat-option>
|
||||
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<!-- End of Sort by -->
|
||||
<div class="d-flex flex-row ml-auto">
|
||||
<!-- Guided Tour -->
|
||||
<div *ngIf="!isPublic" class="center-content" (click)="restartTour()">
|
||||
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}
|
||||
</div>
|
||||
<!-- End of Guided Tour -->
|
||||
<!-- Search Filter-->
|
||||
<mat-form-field class="search-form ml-auto col-auto" floatLabel="never">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<input matInput placeholder="{{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
|
||||
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
|
||||
</mat-form-field>
|
||||
<!-- End of Search Filter -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12 col-md-9">
|
||||
<div *ngFor="let item of listingItems; let i = index">
|
||||
<app-description-listing-item-component [isPublic]="isPublic" [description]="item" [showDivider]="i != (listingItems.length - 1)"></app-description-listing-item-component>
|
||||
</div>
|
||||
<div *ngIf="listingItems && listingItems.length > 0 && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center">
|
||||
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="hasListingItems && listingItems && listingItems.length === 0 && this.lookup.like !== ''" class="col-md-12 d-flex justify-content-center pt-4 mt-4 mb-4 pb-4">
|
||||
<span class="empty-list">{{'DATASET-LISTING.EMPTY-LIST' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,265 @@
|
|||
@import "node_modules/bootstrap/scss/functions";
|
||||
@import "node_modules/bootstrap/scss/variables";
|
||||
@import "node_modules/bootstrap/scss/mixins/_breakpoints";
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
.lightblue-btn {
|
||||
font-size: 12px;
|
||||
}
|
||||
::ng-deep .mat-paginator-container {
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
.header-image {
|
||||
background: url("/assets/images/new-dashboard-bg.png") no-repeat;
|
||||
background-size: cover;
|
||||
margin-top: 70px;
|
||||
min-height: 15em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
text-align: left;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 300;
|
||||
color: #212121;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.header-text-container {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
padding-left: 5em;
|
||||
padding-right: 10em;
|
||||
padding-top: 2em;
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
.explore-dmp-content {
|
||||
padding: 30px 15px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
background-color: #f5f5f5;
|
||||
padding-top: 4.68rem;
|
||||
padding-bottom: 3rem;
|
||||
padding-left: 3rem;
|
||||
padding-right: 3rem;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #00000029;
|
||||
border-radius: 4px;
|
||||
// width: 987px;
|
||||
margin-bottom: 3.75rem;
|
||||
/* height: 407px; */
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
text-align: left;
|
||||
font: Bold 20px/30px Roboto;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
padding-left: 40px;
|
||||
/* padding-top: 40px; */
|
||||
padding-right: 55px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
text-align: left;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
padding-left: 40px;
|
||||
padding-top: 36px;
|
||||
// padding-bottom: 36px;
|
||||
padding-right: 55px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.clear-icon {
|
||||
cursor: pointer;
|
||||
color: #212121;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
.clear-icon:hover {
|
||||
background-color: #ececec !important;
|
||||
border-radius: 50%;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
.normal-btn {
|
||||
min-width: 162px;
|
||||
max-width: 256px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
background: var(--primary-color) 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
border-radius: 30px;
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
opacity: 1;
|
||||
line-height: 1;
|
||||
font-size: 0.87rem;
|
||||
padding: 0.62rem 1.87rem;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.yellow-btn {
|
||||
min-width: 162px;
|
||||
max-width: 256px;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
border: none;
|
||||
color: #000000;
|
||||
opacity: 1;
|
||||
line-height: 1;
|
||||
font-size: 0.87rem;
|
||||
padding: 0.62rem 1.87rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
text-align: left;
|
||||
font-weight: 300;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
z-index: 100;
|
||||
width: 37px;
|
||||
}
|
||||
|
||||
.filter-btn button {
|
||||
color: white;
|
||||
background-color: var(--primary-color-2);
|
||||
width: 37px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.center-content {
|
||||
width: 100%;
|
||||
min-width: 10rem;
|
||||
margin: auto;
|
||||
padding: 0 15px;
|
||||
text-align: right;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.02rem;
|
||||
color: #2d72d6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
// font-size: 12px;
|
||||
text-align: left;
|
||||
width: 20rem;
|
||||
}
|
||||
|
||||
.search-form mat-icon {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
font-size: 1.25rem;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.pointer:hover {
|
||||
color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
::ng-deep .search-form .mat-form-field-wrapper {
|
||||
background-color: white !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
::ng-deep .sort-form .mat-form-field-wrapper {
|
||||
background-color: white !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||
padding: 0.3rem 0rem 0.6rem 0rem !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-paginator-container {
|
||||
flex-direction: row-reverse !important;
|
||||
justify-content: space-between !important;
|
||||
background-color: #f6f6f6;
|
||||
height: 30px;
|
||||
min-height: 30px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-paginator-page-size {
|
||||
height: 43px;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-icon-button {
|
||||
height: 30px !important;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-paginator-range-label {
|
||||
margin: 15px 32px 0 24px !important;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-paginator-range-actions {
|
||||
width: auto !important;
|
||||
min-width: 55% !important;
|
||||
min-height: 43px !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
:host ::ng-deep .mat-paginator-navigation-previous {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
::ng-deep .mat-ripple-element {
|
||||
background-color: #2e74b649 !important;
|
||||
}
|
||||
|
||||
::ng-deep .mat-radio-container {
|
||||
border-radius: 1em;
|
||||
background: white;
|
||||
}
|
||||
|
||||
::ng-deep .mat-radio-button .mat-radio-outer-circle {
|
||||
border: 1px solid #aaaaaa;
|
||||
}
|
||||
|
||||
::ng-deep .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle {
|
||||
border-color: #777777;
|
||||
// border-color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle {
|
||||
// color: var(--primary-color-3);
|
||||
// background-color: var(--primary-color-3);
|
||||
color: #777777;
|
||||
background-color: #777777;
|
||||
}
|
||||
|
||||
.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element {
|
||||
background-color: #2e74b649;
|
||||
}
|
|
@ -0,0 +1,321 @@
|
|||
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { Description } from '@app/core/model/description/description';
|
||||
import { DescriptionLookup } from '@app/core/query/description.lookup';
|
||||
import { DmpLookup } from '@app/core/query/dmp.lookup';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
|
||||
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
|
||||
import { StartNewDmpDialogComponent } from '@app/ui/dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component';
|
||||
// import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent';
|
||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-listing-component',
|
||||
templateUrl: 'description-listing.component.html',
|
||||
styleUrls: ['./description-listing.component.scss']
|
||||
})
|
||||
export class DescriptionListingComponent extends BaseComponent implements OnInit {//IBreadCrumbComponent
|
||||
|
||||
@ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
// @ViewChild(DescriptionCriteriaComponent, { static: true }) criteria: DescriptionCriteriaComponent;
|
||||
|
||||
// breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
|
||||
titlePrefix: String;
|
||||
dmpId: string;
|
||||
status: Number;
|
||||
totalCount: number;
|
||||
dmpSearchEnabled = true;
|
||||
listingItems: Description[] = [];
|
||||
hasListingItems = null;
|
||||
|
||||
isPublic: boolean = false;
|
||||
public isVisible = true
|
||||
|
||||
pageSize: number = 5;
|
||||
lookup: DescriptionLookup = new DescriptionLookup();
|
||||
criteriaFormGroup: UntypedFormGroup;
|
||||
public formGroup = new UntypedFormBuilder().group({
|
||||
like: new UntypedFormControl(),
|
||||
order: new UntypedFormControl()
|
||||
});
|
||||
|
||||
scrollbar: boolean;
|
||||
order = RecentActivityOrder;
|
||||
dmpText: string;
|
||||
descriptionText: string;
|
||||
|
||||
constructor(
|
||||
private descriptionService: DescriptionService,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
public dialog: MatDialog,
|
||||
private dmpService: DmpService,
|
||||
private language: TranslateService,
|
||||
private authService: AuthService,
|
||||
public enumUtils: EnumUtils,
|
||||
private authentication: AuthService,
|
||||
private guidedTourService: GuidedTourService,
|
||||
private httpClient: HttpClient,
|
||||
private matomoService: MatomoService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.matomoService.trackPageView('Descriptions');
|
||||
this.isPublic = this.router.url === '/explore';
|
||||
if (this.isPublic) {
|
||||
this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED);
|
||||
} else {
|
||||
this.formGroup.get('order').setValue(this.order.MODIFIED);
|
||||
}
|
||||
if (!this.isPublic && !this.authService.currentAccountIsAuthenticated()) {
|
||||
this.router.navigateByUrl("/explore");
|
||||
}
|
||||
this.route.params
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(async (params: Params) => {
|
||||
const queryParams = this.route.snapshot.queryParams;
|
||||
this.dmpId = queryParams['dmpId'];
|
||||
this.status = queryParams['status'];
|
||||
|
||||
this.lookup.page = { size: this.pageSize, offset: 0 };
|
||||
this.lookup.order = { items: ['-' + nameof<Description>(x => x.updatedAt)] };
|
||||
if (this.dmpId != null && Guid.isGuid(this.dmpId)) {
|
||||
this.dmpSearchEnabled = false;
|
||||
//const dmp = await this.dmpService.getSingle(this.dmpId).toPromise();
|
||||
this.lookup.dmpSubQuery = new DmpLookup();
|
||||
this.lookup.dmpSubQuery.ids = [Guid.parse(this.dmpId)];
|
||||
this.refresh(this.lookup);
|
||||
if (params['dmpLabel'] !== undefined) {
|
||||
this.titlePrefix = 'for ' + params['dmpLabel'];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.status != null && this.status == DescriptionStatus.Draft) { //TODO: chack if actually used
|
||||
this.lookup.statuses = [DescriptionStatus.Draft]
|
||||
}
|
||||
this.refresh(this.lookup);
|
||||
});
|
||||
|
||||
this.formGroup.get('like').valueChanges
|
||||
.pipe(takeUntil(this._destroyed), debounceTime(500))
|
||||
.subscribe(x => this.controlModified());
|
||||
this.formGroup.get('order').valueChanges
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(x => {
|
||||
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '' : "-") + this.formGroup.get('order').value];
|
||||
this.lookup.order = { items: fields };
|
||||
this.lookup.page = { size: this.pageSize, offset: 0 };
|
||||
this.refresh(this.lookup);
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterContentChecked(): void {
|
||||
this.scrollbar = this.hasScrollbar();
|
||||
}
|
||||
|
||||
public dashboardTour: GuidedTour = {
|
||||
tourId: 'dmp-description-tour',
|
||||
useOrb: true,
|
||||
steps: [
|
||||
{
|
||||
selector: '.dmp-tour',
|
||||
content: 'Step 1',
|
||||
orientation: Orientation.Right,
|
||||
isStepUnique: false
|
||||
},
|
||||
{
|
||||
selector: '.description-tour',
|
||||
content: 'Step 2',
|
||||
orientation: Orientation.Right,
|
||||
isStepUnique: false
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
public isAuthenticated(): boolean {
|
||||
return this.authService.currentAccountIsAuthenticated();
|
||||
}
|
||||
|
||||
controlModified(): void {
|
||||
|
||||
this.lookup.like = this.formGroup.get("like").value;
|
||||
this.lookup.page = { size: this.pageSize, offset: 0 };
|
||||
this.refresh(this.lookup);
|
||||
}
|
||||
|
||||
refresh(lookup: DescriptionLookup) {
|
||||
lookup.project = {
|
||||
fields: [
|
||||
nameof<Description>(x => x.id),
|
||||
nameof<Description>(x => x.label),
|
||||
]
|
||||
};
|
||||
this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (!result) { return []; }
|
||||
// if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
|
||||
this.totalCount = result.count;
|
||||
if (lookup?.page?.offset === 0) this.listingItems = [];
|
||||
this.listingItems = result.items;
|
||||
this.hasListingItems = true;
|
||||
});
|
||||
}
|
||||
|
||||
openFiltersDialog(): void {
|
||||
//TODO: Add filters dialog
|
||||
|
||||
// const dialogRef = this.dialog.open(DescriptionCriteriaDialogComponent, {
|
||||
// width: '456px',
|
||||
// height: '100%',
|
||||
// id: 'filters',
|
||||
// restoreFocus: false,
|
||||
// data: {
|
||||
// isPublic: this.isPublic,
|
||||
// status: this.status,
|
||||
// criteria: this.criteria,
|
||||
// formGroup: this.criteriaFormGroup,
|
||||
// // criteria: this.grantId ? this.criteria : this.getDefaultCriteria(),
|
||||
// updateDataFn: this.updateDataFn.bind(this)
|
||||
// },
|
||||
// position: { right: '0px;' },
|
||||
// panelClass: 'dialog-side-panel'
|
||||
// });
|
||||
|
||||
// dialogRef.afterClosed().subscribe(result => {
|
||||
// });
|
||||
}
|
||||
|
||||
// updateDataFn(criteria: DescriptionCriteriaComponent): void {
|
||||
// this.criteriaFormGroup = criteria.formGroup;
|
||||
// this.toDescriptionCriteria(criteria);
|
||||
// this.refresh();
|
||||
// }
|
||||
|
||||
// toDescriptionCriteria(criteria: DescriptionCriteriaComponent) {
|
||||
// let formGroup = criteria.formGroup;
|
||||
// this.criteria = {
|
||||
// like: formGroup.get("like").value,
|
||||
// status: formGroup.get("status").value,
|
||||
// allVersions: formGroup.get("allVersions").value,
|
||||
// role: formGroup.get("role").value
|
||||
// }
|
||||
// if (formGroup.get("tags") && formGroup.get("tags").value) {
|
||||
// this.criteria.tags = formGroup.get("tags").value.map(x => (<ExternalTagEditorModel>x));
|
||||
// }
|
||||
// if (formGroup.get("collaborators") && formGroup.get("collaborators").value) {
|
||||
// this.criteria.collaborators = formGroup.get("collaborators").value.map(x => x.id);
|
||||
// }
|
||||
// if (formGroup.get("dmpIds") && formGroup.get("dmpIds").value) {
|
||||
// this.criteria.dmpIds = formGroup.get("dmpIds").value.map(x => x.id);
|
||||
// }
|
||||
// if (formGroup.get("groupIds") && formGroup.get("groupIds").value) {
|
||||
// this.criteria.groupIds = formGroup.get("groupIds").value.map(x => x.groupId);
|
||||
// }
|
||||
// if (formGroup.get("grants") && formGroup.get("grants").value) {
|
||||
// this.criteria.grants = formGroup.get("grants").value.map(x => x.id);
|
||||
// }
|
||||
// if (formGroup.get("organisations") && formGroup.get("organisations").value) {
|
||||
// this.criteria.organisations = formGroup.get("organisations").value.map(x => x.id);
|
||||
// }
|
||||
// if (formGroup.get("descriptionTemplates") && formGroup.get("descriptionTemplates").value) {
|
||||
// this.criteria.descriptionTemplates = formGroup.get("descriptionTemplates").value.map(x => x.id)
|
||||
// }
|
||||
// if (formGroup.get("grantStatus") && formGroup.get("grantStatus").value) {
|
||||
// this.criteria.grantStatus = formGroup.get("grantStatus").value;
|
||||
// }
|
||||
// this.criteria.isPublic = this.isPublic;
|
||||
// }
|
||||
|
||||
|
||||
hasScrollbar(): boolean {
|
||||
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
|
||||
}
|
||||
|
||||
public restartTour(): void {
|
||||
this.setDashboardTourDmpText();
|
||||
this.setDashboardTourDescriptionText();
|
||||
this.guidedTourService.startTour(this.dashboardTour);
|
||||
}
|
||||
|
||||
public setDashboardTourDmpText(): void {
|
||||
this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
|
||||
this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
||||
this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' +
|
||||
this.language.instant('DMP-LISTING.GET-IDEA');
|
||||
this.dashboardTour.steps[0].title = this.dmpText;
|
||||
}
|
||||
|
||||
public setDashboardTourDescriptionText(): void {
|
||||
this.descriptionText = this.language.instant('DATASET-LISTING.TEXT-INFO') +
|
||||
this.language.instant('DATASET-LISTING.LINK-PUBLIC-DATASETS') + ' ' +
|
||||
this.language.instant('DATASET-LISTING.TEXT-INFO-REST') + '\n\n' +
|
||||
this.language.instant('DATASET-LISTING.TEXT-INFO-PAR');
|
||||
this.dashboardTour.steps[1].title = this.descriptionText;
|
||||
}
|
||||
|
||||
openNewDmpDialog() {
|
||||
if (this.dialog.openDialogs.length > 0) {
|
||||
this.dialog.closeAll();
|
||||
}
|
||||
else {
|
||||
const dialogRef = this.dialog.open(StartNewDmpDialogComponent, {
|
||||
disableClose: false,
|
||||
data: {
|
||||
isDialog: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
addNewDescription() {
|
||||
//TODO: Add new description dialog
|
||||
|
||||
// const dialogRef = this.dialog.open(StartNewDescriptionDialogComponent, {
|
||||
// disableClose: false,
|
||||
// restoreFocus: false,
|
||||
// data: {
|
||||
// startNewDmp: false,
|
||||
// formGroup: new DescriptionWizardEditorModel().buildForm()
|
||||
// }
|
||||
// });
|
||||
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (result) {
|
||||
// if (result.startNewDmp) {
|
||||
// this.openNewDmpDialog();
|
||||
// } else {
|
||||
// this.router.navigate(['/plans', 'edit', result.formGroup.get('dmp').value.id]);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
hasLikeCriteria(): boolean {
|
||||
return this.lookup.like !== undefined && this.lookup.like !== null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<div class="description-card">
|
||||
<a [routerLink]="getItemLink()" class="pointer">
|
||||
<div class="d-flex flex-direction-row">
|
||||
<div class="col-auto description-label">{{'DATASET-LISTING.DESCRIPTION' | translate}}</div>
|
||||
<div *ngIf="!isPublic" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{description.modified | dateTimeCultureFormatter: "d MMMM y"}}</div>
|
||||
<div *ngIf="isPublic" class="col-auto ml-auto edited-date">{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{description.dmpPublishedAt | dateTimeCultureFormatter: "d MMMM y"}}</div>
|
||||
</div>
|
||||
<div *ngIf="description.status === 1" class="col-auto description-title">{{description.label}}</div>
|
||||
<div *ngIf="description.status === 0" class="col-auto description-title-draft">{{description.label}}</div>
|
||||
<div class="description-subtitle">
|
||||
<span *ngIf="isUserDescriptionRelated()" class="col-auto">{{ roleDisplay(description.users) }}</span>
|
||||
<span *ngIf="isUserDescriptionRelated()">.</span>
|
||||
<!-- <span class="col-auto" *ngIf="description.status === 1 && description.public === true"><span class="material-icons icon-align">public</span>{{'DATASET-LISTING.STATES.PUBLIC' | translate}}</span> -->
|
||||
<!-- <span *ngIf="description.status === 1 && description.public === false" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(description.status) }}</span> -->
|
||||
<span *ngIf="description.status === 0" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(description.status) }}</span>
|
||||
<span>.</span>
|
||||
<!-- <span class="col">{{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{description.grant}}</span> -->
|
||||
</div>
|
||||
<div class="d-flex flex-direction-row pt-3 pb-3">
|
||||
<div class="col-auto description-subtitle pr-0">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}
|
||||
<div class="col-auto dmp-label ml-3">{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}</div>
|
||||
</div>
|
||||
<div class="col dmp-title">{{description.dmp}}</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="description-card-actions">
|
||||
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DATASET-LISTING.ACTIONS.EXPORT' | translate}}</a>
|
||||
<a class="col-auto border-right pointer" *ngIf="isUserOwner" (click)="openShareDialog(description.dmpId, description.dmp)"><span class="material-icons icon-align pr-2">group_add</span>{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
|
||||
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="openDmpSearchDialogue(description)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}</a>
|
||||
<a class="col-auto border-right pointer" *ngIf="isAuthenticated() && isUserDescriptionRelated()" (click)="deleteClicked(description.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}</a>
|
||||
</div>
|
||||
<mat-menu #actionsMenu="matMenu">
|
||||
<button *ngIf="isAuthenticated()" mat-menu-item (click)="openDmpSearchDialogue(description)" class="menu-item">
|
||||
<mat-icon>file_copy</mat-icon>{{'DATASET-WIZARD.ACTIONS.COPY-DESCRIPTION' | translate}}
|
||||
</button>
|
||||
<button *ngIf="isUserDescriptionRelated()" mat-menu-item (click)="deleteClicked(description.id)" class="menu-item">
|
||||
<mat-icon>delete</mat-icon>{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
|
||||
<mat-menu #exportMenu="matMenu" xPosition="before">
|
||||
<button mat-menu-item (click)="downloadPDF(description)">
|
||||
<i class="fa fa-file-pdf-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadDOCX(description)">
|
||||
<i class="fa fa-file-word-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadXML(description)">
|
||||
<i class="fa fa-file-code-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
|
@ -0,0 +1,261 @@
|
|||
.gray-container {
|
||||
letter-spacing: 5px;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
.container-header {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-top: 0px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.container-header p {
|
||||
letter-spacing: 5px;
|
||||
color: #aaaaaa;
|
||||
padding-top: 10px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.container-header :hover {
|
||||
color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
h4 {
|
||||
display: inline;
|
||||
padding-left: 1em;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
h4 > span {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.title h4 {
|
||||
padding-left: 30px;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
.about-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.links :hover {
|
||||
color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
.about-item .length {
|
||||
color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
.about-item .title {
|
||||
margin: 2px 10px;
|
||||
// text-transform: uppercase;
|
||||
}
|
||||
|
||||
.about-item p {
|
||||
margin-left: auto;
|
||||
margin-bottom: 0px;
|
||||
padding-top: 7px;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.storage :hover {
|
||||
color: var(--primary-color-3);
|
||||
}
|
||||
|
||||
.draft-bookmark {
|
||||
color: #e7e6e6;
|
||||
}
|
||||
|
||||
.finalized-bookmark {
|
||||
color: #08bd63;
|
||||
}
|
||||
|
||||
.dmp-card,
|
||||
.description-card {
|
||||
min-width: 712px;
|
||||
/* min-height: 308px; */
|
||||
background: #ffffff 0% 0% no-repeat padding-box;
|
||||
box-shadow: 0px 3px 6px #0000001a;
|
||||
border-radius: 4px;
|
||||
opacity: 1;
|
||||
margin-top: 2.43rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.remove-border-bottom ::ng-deep .mat-tab-header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
background: #fafafa 0% 0% no-repeat padding-box;
|
||||
border: 1px solid #d1d1d1;
|
||||
border-radius: 4px;
|
||||
opacity: 1;
|
||||
width: 347px;
|
||||
height: 56px;
|
||||
font-family: Arial, FontAwesome;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.edited-date {
|
||||
text-align: left;
|
||||
font-weight: 300;
|
||||
font-family: "Roboto", sans-serif;
|
||||
line-height: 2.4;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.dmp-label {
|
||||
background: var(--primary-color) 0% 0% no-repeat padding-box;
|
||||
border-radius: 4px 0px;
|
||||
opacity: 1;
|
||||
min-width: 67px;
|
||||
height: 37px;
|
||||
color: #ffffff;
|
||||
line-height: 2.4;
|
||||
}
|
||||
|
||||
.description-label {
|
||||
width: auto;
|
||||
height: 37px;
|
||||
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||
border-radius: 4px 0px;
|
||||
text-align: left;
|
||||
line-height: 2.8;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0px;
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.dmp-title,
|
||||
.description-title {
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: 1rem;
|
||||
// opacity: 0.81;
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.55rem;
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.description-subtitle,
|
||||
.dmp-subtitle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
text-align: left;
|
||||
font-weight: 400;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: 0.875rem;
|
||||
opacity: 1;
|
||||
align-items: center;
|
||||
color: #848484;
|
||||
}
|
||||
|
||||
.dmp-title-draft,
|
||||
.description-title-draft {
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: 1rem;
|
||||
// opacity: 0.81;
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.55rem;
|
||||
color: #f16868;
|
||||
}
|
||||
|
||||
.icon-align {
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
// line-height: .9em;
|
||||
// padding-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.dmp-subtitle,
|
||||
.description-subtitle {
|
||||
|
||||
.icon-align {
|
||||
display: inline-flex;
|
||||
vertical-align: top;
|
||||
margin-right: .2rem;
|
||||
line-height: .95em;
|
||||
}
|
||||
}
|
||||
|
||||
.description-card-actions,
|
||||
.dmp-card-actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border-top: 1px solid #dbdbdb;
|
||||
line-height: 4;
|
||||
color: #848484;
|
||||
}
|
||||
|
||||
.description-card-actions a,
|
||||
.dmp-card-actions a {
|
||||
color: #848484 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.description-card-actions a:hover,
|
||||
.dmp-card-actions a:hover {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
.dmp-description-descriptions-title {
|
||||
color: #000000;
|
||||
opacity: 0.6;
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 0.8rem;
|
||||
}
|
||||
|
||||
.dmp-description-descriptions-name {
|
||||
color: #000000;
|
||||
opacity: 0.6;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.show-more {
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.show-more:hover {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
.btn-load-more {
|
||||
border: 2px solid #212121;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
min-width: 132px;
|
||||
width: auto;
|
||||
height: 40px;
|
||||
margin-top: 4.125rem;
|
||||
}
|
||||
|
||||
.btn-load-more:hover {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.draft {
|
||||
color: #f16868;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::ng-deep .mat-menu-panel {
|
||||
max-width: 282px !important;
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
import { Location } from '@angular/common';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
import { Role } from '@app/core/common/enum/role';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { LockService } from '@app/core/services/lock/lock.service';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import * as FileSaver from 'file-saver';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { DescriptionStatus } from '../../../../core/common/enum/description-status';
|
||||
import { Description } from '@app/core/model/description/description';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { Guid } from '@common/types/guid';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-listing-item-component',
|
||||
templateUrl: './description-listing-item.component.html',
|
||||
styleUrls: ['./description-listing-item.component.scss']
|
||||
})
|
||||
export class DescriptionListingItemComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@Input() description: Description;
|
||||
@Input() showDivider: boolean = true;
|
||||
@Input() isPublic: boolean = false;
|
||||
@Output() onClick: EventEmitter<Description> = new EventEmitter();
|
||||
|
||||
isDraft: boolean;
|
||||
isDeleted: boolean;
|
||||
isUserOwner: boolean;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
public enumUtils: EnumUtils,
|
||||
private descriptionService: DescriptionService,
|
||||
public dialog: MatDialog,
|
||||
private language: TranslateService,
|
||||
private authService: AuthService,
|
||||
private uiNotificationService: UiNotificationService,
|
||||
private lockService: LockService,
|
||||
private location: Location,
|
||||
private httpClient: HttpClient,
|
||||
private matomoService: MatomoService,
|
||||
private fileUtils: FileUtils
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.matomoService.trackPageView('Description Listing Item');
|
||||
if (this.description.isActive === IsActive.Inactive) {
|
||||
this.isDeleted = true;
|
||||
} else if (this.description.status === DescriptionStatus.Draft) {
|
||||
this.isDraft = true;
|
||||
this.isDeleted = false;
|
||||
this.setIsUserOwner();
|
||||
} else {
|
||||
this.isDraft = false;
|
||||
this.isDeleted = false;
|
||||
this.setIsUserOwner();
|
||||
}
|
||||
}
|
||||
|
||||
setIsUserOwner() {
|
||||
if (this.description) {
|
||||
const principalId: string = this.authService.userId()?.toString();
|
||||
//TODO: add user to description objects
|
||||
//if (principalId) this.isUserOwner = !!this.description.users.find(x => (x.role === Role.Owner) && (principalId === x.id));
|
||||
}
|
||||
}
|
||||
|
||||
public isAuthenticated(): boolean {
|
||||
return this.authService.currentAccountIsAuthenticated();
|
||||
}
|
||||
|
||||
getItemLink(): string[] {
|
||||
// return this.isPublic ? [`/descriptions/publicEdit/${this.description.id}`] : [`/descriptions/edit/${this.description.id}`];
|
||||
return this.isPublic ? ['/descriptions/publicOverview/' + this.description.id] : ['/descriptions/overview/' + this.description.id];
|
||||
}
|
||||
|
||||
getDmpLink(): string[] {
|
||||
return this.isPublic ? [`/explore-plans/publicOverview/${this.description.dmp.id}`] : [`/plans/edit/${this.description.dmp.id}`];
|
||||
}
|
||||
|
||||
downloadPDF(description: Description): void {
|
||||
//TODO: add file transformer service
|
||||
// this.descriptionService.downloadPDF(description.id as string)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/pdf' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('descriptions', "pdf", description.id);
|
||||
// });
|
||||
}
|
||||
|
||||
downloadDOCX(description: Description): void {
|
||||
//TODO: add file transformer service
|
||||
// this.descriptionService.downloadDOCX(description.id as string)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/msword' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('descriptions', "docx", description.id);
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
downloadXML(description: Description): void {
|
||||
//TODO: add file transformer service
|
||||
// this.descriptionService.downloadXML(description.id as string)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/xml' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('descriptions', "xml", description.id);
|
||||
// });
|
||||
}
|
||||
|
||||
openShareDialog(dmpRowId: any, dmpRowName: any) {
|
||||
// TODO: This is a shared component. Put it in a seperate module.
|
||||
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
|
||||
// height: '250px',
|
||||
// width: '700px',
|
||||
autoFocus: false,
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
dmpId: dmpRowId,
|
||||
dmpName: dmpRowName
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openDmpSearchDialogue(description: Description) {
|
||||
// TODO: add this.
|
||||
// const formControl = new UntypedFormControl();
|
||||
// const dialogRef = this.dialog.open(DescriptionCopyDialogueComponent, {
|
||||
// width: '500px',
|
||||
// restoreFocus: false,
|
||||
// data: {
|
||||
// formControl: formControl,
|
||||
// descriptionId: description.id,
|
||||
// descriptionProfileId: description.profile.id,
|
||||
// descriptionProfileExist: false,
|
||||
// confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'),
|
||||
// cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL')
|
||||
// }
|
||||
// });
|
||||
|
||||
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(result => {
|
||||
// if (result && result.descriptionProfileExist) {
|
||||
// const newDmpId = result.formControl.value.id;
|
||||
// this.router.navigate(['/descriptions/copy/' + result.descriptionId], { queryParams: { newDmpId: newDmpId } });
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
deleteClicked(id: Guid) {
|
||||
this.lockService.checkLockStatus(id.toString()).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(lockStatus => {
|
||||
if (!lockStatus) {
|
||||
this.openDeleteDialog(id);
|
||||
} else {
|
||||
this.openLockedByUserDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openDeleteDialog(id: Guid): void {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '300px',
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
||||
isDeleteConfirmation: true
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.descriptionService.delete(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onDeleteCallbackSuccess(),
|
||||
error => this.onDeleteCallbackError(error)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
openLockedByUserDialog() {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '400px',
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK')
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reloadPage(): void {
|
||||
const path = this.location.path();
|
||||
this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => {
|
||||
this.router.navigate([path]);
|
||||
});
|
||||
}
|
||||
|
||||
onDeleteCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
|
||||
this.reloadPage();
|
||||
}
|
||||
|
||||
onDeleteCallbackError(error) {
|
||||
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
|
||||
roleDisplay(value: any) {
|
||||
const principalId: string = this.authService.userId()?.toString();
|
||||
let role: number;
|
||||
if (principalId) {
|
||||
value.forEach(element => {
|
||||
if (principalId === element.id) {
|
||||
role = element.role;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (role === 0) {
|
||||
return this.language.instant('DMP-LISTING.OWNER');
|
||||
}
|
||||
else if (role === 1) {
|
||||
return this.language.instant('DMP-LISTING.MEMBER');
|
||||
}
|
||||
else {
|
||||
return this.language.instant('DMP-LISTING.OWNER');
|
||||
}
|
||||
}
|
||||
|
||||
isUserDescriptionRelated() {
|
||||
//TODO: add user to description objects
|
||||
const principalId: string = this.authService.userId()?.toString();
|
||||
let isRelated: boolean = false;
|
||||
// if (this.description && principalId) {
|
||||
// this.description.users.forEach(element => {
|
||||
// if (element.id === principalId) {
|
||||
// isRelated = true;
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
return isRelated;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
<div class="main-content dataset-overview pl-5 pr-5">
|
||||
<div class="container-fluid pl-0 pr-0">
|
||||
<div *ngIf="dataset">
|
||||
<a class="row mb-2 pl-1" (click)="goBack()" role="button">
|
||||
<mat-icon class="back-icon pointer">chevron_left</mat-icon>
|
||||
<p class="label-txt pointer">{{'DMP-WIZARD.ACTIONS.BACK' | translate}}</p>
|
||||
</a>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-lg-8 pl-4">
|
||||
<div class="row">
|
||||
<span class="col-auto dataset-logo">{{ 'NAV-BAR.DESCRIPTION' | translate }}</span>
|
||||
<p class="col dataset-label p-0 ml-3 mb-0">{{ dataset.label }}</p>
|
||||
</div>
|
||||
<div class="row d-flex align-items-center mt-3 mb-4 label-txt">
|
||||
<div *ngIf="isUserDatasetRelated()" class="d-flex">
|
||||
<p class="ml-0 mb-0 label2-txt">
|
||||
{{ roleDisplayFromList(dataset.users) }}
|
||||
</p>
|
||||
</div>
|
||||
<span *ngIf="isUserDatasetRelated()" class="ml-2 mr-2">.</span>
|
||||
<!-- UNCOMMENT TO ADD PRIVATE ICON -->
|
||||
<!-- <span *ngIf="isUserDatasetRelated() && (dataset.public || !dataset.public || lockStatus)" class="ml-2 mr-2">.</span> -->
|
||||
<div *ngIf="dataset.public" class="d-flex flex-row">
|
||||
<mat-icon class="status-icon">public</mat-icon>
|
||||
{{'DMP-OVERVIEW.PUBLIC' | translate}}
|
||||
</div>
|
||||
<span *ngIf="dataset.public" class="ml-2 mr-2">.</span>
|
||||
<!-- UNCOMMENT TO ADD PRIVATE ICON -->
|
||||
<!-- <div *ngIf="!dataset.public" class="d-flex flex-row">
|
||||
<mat-icon class="status-icon">public_off</mat-icon>
|
||||
{{'DMP-OVERVIEW.PRIVATE' | translate}}
|
||||
</div>
|
||||
<span *ngIf="!dataset.public" class="ml-2 mr-2">.</span> -->
|
||||
<div *ngIf="lockStatus" class="d-flex flex-row">
|
||||
<mat-icon class="status-icon">lock_outline</mat-icon>
|
||||
{{'DMP-OVERVIEW.LOCKED' | translate}}
|
||||
</div>
|
||||
<span *ngIf="lockStatus" class="ml-2 mr-2">.</span>
|
||||
<div class="d-flex mr-2">{{'GENERAL.STATUSES.EDIT' | translate}} :
|
||||
<!-- {{dataset.modified | date:'longDate':'+0200': this.language.store.currentLang }} -->
|
||||
{{dataset.modified | dateTimeCultureFormatter: "d MMMM y"}}
|
||||
</div>
|
||||
<div class="d-flex ml-2 mr-4">
|
||||
<div *ngIf="dataset.status" class="d-flex flex-row uppercase">
|
||||
<mat-icon class="status-icon check-icon">check</mat-icon>
|
||||
{{'TYPES.DATASET-STATUS.FINALISED' | translate}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-4 pb-3">
|
||||
<button *ngIf="isDraftDataset(dataset) && !lockStatus" (click)="editClicked(dataset)" mat-mini-fab class="mr-3 actions-btn" matTooltip="{{'DMP-LISTING.ACTIONS.EDIT' | translate}}" matTooltipPosition="above">
|
||||
<mat-icon class="mat-mini-fab-icon">create</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isAuthenticated()" (click)="openDmpSearchDialogue()" mat-mini-fab class="mr-3 actions-btn" matTooltip="{{'DMP-LISTING.ACTIONS.CLONE' | translate}}" matTooltipPosition="above">
|
||||
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
|
||||
</button>
|
||||
<button *ngIf="isUserDatasetRelated() && !lockStatus" (click)="deleteClicked()" mat-mini-fab class="mr-3 actions-btn" matTooltip="{{'DMP-LISTING.ACTIONS.DELETE' | translate}}" matTooltipPosition="above">
|
||||
<mat-icon class="mat-mini-fab-icon">delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="row header">{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}}</div>
|
||||
<div class="row ">
|
||||
<button class="dmp-btn" (click)="dmpClicked(dataset.dmp)">
|
||||
<div class="dmp-btn-label">
|
||||
{{ this.dataset.dmp.label }}
|
||||
</div>
|
||||
<mat-icon>launch</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="dataset.grant">
|
||||
<div class="row header">{{'DMP-OVERVIEW.GRANT' | translate}}</div>
|
||||
<div class="row dataset-label">{{ dataset.grant.label }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row header">{{'DMP-OVERVIEW.RESEARCHERS' | translate}}</div>
|
||||
<div class="row">
|
||||
<div *ngFor="let researcher of researchers; let last = last">
|
||||
<span *ngIf="isOrcid(researcher.reference)">
|
||||
<a href="{{ getOrcidPathForResearcher(researcher.reference) }}" target="blank" class="researcher">
|
||||
<div class="id-btn"> </div>
|
||||
<div *ngIf="!last">{{ researcher.name }}, </div>
|
||||
<div *ngIf="last">{{ researcher.name }}</div>
|
||||
</a>
|
||||
</span>
|
||||
<span *ngIf="!isOrcid(researcher.reference)">
|
||||
<div *ngIf="!last">{{ researcher.name }}, </div>
|
||||
<div *ngIf="last">{{ researcher.name }}</div>
|
||||
</span>
|
||||
</div>
|
||||
<span *ngIf="!researchers || researchers.length === 0" class="material-icons">horizontal_rule</span>
|
||||
</div>
|
||||
|
||||
<div class="row header">{{'DATASET-LISTING.COLUMNS.DESCRIPTION' | translate}}</div>
|
||||
<div class="row" *ngIf="dataset.description">
|
||||
<p class="desc-txt" [innerHTML]="dataset.description"></p>
|
||||
</div>
|
||||
<div class="row" *ngIf="!dataset.description">
|
||||
<span class="material-icons">horizontal_rule</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 col-lg-4 p-0">
|
||||
<div class="frame mb-3 pt-4 pl-3 pr-5 pb-1">
|
||||
<div *ngIf="!dataset.status && isDraftDataset(dataset) && !lockStatus">
|
||||
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center" (click)="finalize(dataset)">
|
||||
<button mat-mini-fab class="finalize-btn">
|
||||
<mat-icon class="mat-mini-fab-icon check-icon">check</mat-icon>
|
||||
</button>
|
||||
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.FINALIZE' | translate }}</p>
|
||||
</div>
|
||||
<div class="row ml-0 mr-0 pl-4 d-flex align-items-center">
|
||||
<hr class="hr-line">
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="hasReversableStatus(dataset)" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="reverse(dataset)">
|
||||
<button mat-mini-fab class="frame-btn">
|
||||
<mat-icon class="mat-mini-fab-icon">unarchive</mat-icon>
|
||||
</button>
|
||||
<p class="mb-0 mr-0 pl-2 frame-txt">{{ 'DATASET-WIZARD.ACTIONS.REVERSE' | translate }}</p>
|
||||
</div>
|
||||
<div class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center">
|
||||
<button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu">
|
||||
<mat-icon class="mat-mini-fab-icon">open_in_new</mat-icon>
|
||||
</button>
|
||||
<p class="mb-0 mr-0 pl-2 frame-txt" [matMenuTriggerFor]="exportMenu">
|
||||
{{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}</p>
|
||||
</div>
|
||||
<!-- <div *ngIf="!dataset.public && showPublishButton(dataset) && isUserOwner" class="row ml-0 mr-0 pl-4 pb-3 d-flex align-items-center" (click)="publish(dataset.id)">
|
||||
<button mat-mini-fab class="frame-btn">
|
||||
<mat-icon class="mat-mini-fab-icon">public</mat-icon>
|
||||
</button>
|
||||
<p class="mb-0 pl-2 frame-txt">{{ 'DMP-LISTING.ACTIONS.MAKE-PUBLIC' | translate }}</p>
|
||||
</div> -->
|
||||
<mat-menu #exportMenu="matMenu" xPosition="before">
|
||||
<button mat-menu-item (click)="downloadPDF(dataset.id)">
|
||||
<i class="fa fa-file-pdf-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.PDF' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadDocx(dataset.id)">
|
||||
<i class="fa fa-file-word-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.DOC' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="downloadXml(dataset.id)">
|
||||
<i class="fa fa-file-code-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.XML' | translate}}</span>
|
||||
</button>
|
||||
<!-- GK: NO-->
|
||||
<!-- <button mat-menu-item (click)="downloadJson(dataset.id)">
|
||||
<i class="fa fa-file-o pr-2"></i>
|
||||
<span>{{'GENERAL.FILE-TYPES.JSON' | translate}}</span>
|
||||
</button> -->
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class="frame mb-3 pt-4 pl-3 pr-3 pb-1">
|
||||
<div class="row ml-0 mr-0 pl-4 pb-3">
|
||||
<p class="header">{{ 'DATASET-OVERVIEW.DESCRIPTION-AUTHORS' | translate }}</p>
|
||||
</div>
|
||||
<div class="row ml-0 mr-0 pl-4 ml-2 pb-3 d-flex align-items-center">
|
||||
<div *ngFor="let user of dataset.users" class="row authors">
|
||||
<div class="d-flex flex-row">
|
||||
<button class="account_btn mr-3 pl-0">
|
||||
<mat-icon class="account-icon">account_circle</mat-icon>
|
||||
</button>
|
||||
<div>
|
||||
<p class="authors-label">{{ user.name }}
|
||||
<span *ngIf="isUserAuthor(user.id)">
|
||||
({{ 'DMP-OVERVIEW.YOU' | translate }})</span>
|
||||
</p>
|
||||
<p class="authors-role">{{ roleDisplay(user) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button *ngIf="isUserOwner && !dataset.status && user.role" (click)="removeUserFromDmp(user)" class="remove-btn">{{ 'GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="isUserOwner" class="row mt-3 mb-3 d-flex align-items-center justify-content-center">
|
||||
<button mat-raised-button class="invite-btn" (click)="openShareDialog(dataset.dmp.id, dataset.dmp.label)">
|
||||
<mat-icon>group_add</mat-icon>
|
||||
{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,301 @@
|
|||
.container-fluid {
|
||||
margin: 2em 4em;
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.dataset-overview {
|
||||
// margin-top: 5rem;
|
||||
}
|
||||
|
||||
// ********ICONS********
|
||||
|
||||
.back-icon {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.mat-mini-fab {
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
color: #212121;
|
||||
background-color: var(--secondary-color);
|
||||
}
|
||||
|
||||
.mat-mini-fab-icon,
|
||||
.status-icon {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.actions-btn:hover,
|
||||
.finalize-btn:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
color: #a7a7a7;
|
||||
}
|
||||
|
||||
.check-icon {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.account-icon {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
// ********BUTTONS********
|
||||
|
||||
.version-btn {
|
||||
// width: 6.7em;
|
||||
height: 1.8em;
|
||||
border: 1px solid #707070;
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.id-btn {
|
||||
background: url("../../../../assets/images/NoPath.png") no-repeat center;
|
||||
width: 1em;
|
||||
margin-right: 0.3em;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.dmp-btn {
|
||||
width: 35em;
|
||||
min-height: 2.3em;
|
||||
background-color: var(--primary-color);
|
||||
border-radius: 4px;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.dmp-btn,
|
||||
.dmp-btn > mat-icon {
|
||||
color: #ffffff;
|
||||
// opacity: 0.8;
|
||||
}
|
||||
|
||||
.show-more-btn {
|
||||
width: 31.6em;
|
||||
padding: 0 1em;
|
||||
background-color: #ffffff00;
|
||||
color: var(--primary-color);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.frame-btn {
|
||||
border: 1px solid #212121;
|
||||
color: black;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.finalize-btn {
|
||||
// border: 1px solid var(--secondary-color);
|
||||
background: #f5db71;
|
||||
}
|
||||
|
||||
.frame-btn,
|
||||
.finalize-btn {
|
||||
box-shadow: 0px 2px 6px #00000029;
|
||||
}
|
||||
|
||||
.remove-btn {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
font-size: 0.875em;
|
||||
font-weight: bold;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.invite-btn {
|
||||
width: 9.4em;
|
||||
height: 2.9em;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 3px 6px #1e202029;
|
||||
border: 2px solid #212121;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.account_btn {
|
||||
background: white;
|
||||
color: #d5d5d5;
|
||||
border: none;
|
||||
height: 2.9em;
|
||||
}
|
||||
|
||||
// ********TEXT********
|
||||
|
||||
.dataset-logo {
|
||||
width: 6em;
|
||||
height: 2.6em;
|
||||
background: var(--secondary-color);
|
||||
border-radius: 4px;
|
||||
font-size: 0.875em;
|
||||
// color: #212121;
|
||||
// color: black;
|
||||
// opacity: 0.75;
|
||||
}
|
||||
|
||||
.label-txt {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.label2-txt {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.label-txt,
|
||||
.label2-txt {
|
||||
color: #848484;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.dataset-label {
|
||||
font-weight: bold;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.researcher {
|
||||
font-size: 0.875em;
|
||||
color: var(--primary-color);
|
||||
padding-right: 0.5em;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.header {
|
||||
opacity: 0.6;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.dataset-label,
|
||||
.header {
|
||||
font-size: 1.25em;
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.desc-txt {
|
||||
width: 48.25em;
|
||||
font-size: 1em;
|
||||
color: #212121;
|
||||
margin-bottom: 1.875em;
|
||||
}
|
||||
|
||||
.dmp-btn-label {
|
||||
margin-right: 1em;
|
||||
overflow: hidden;
|
||||
color: #ffffff;
|
||||
opacity: 0.8;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.doi-label {
|
||||
font-size: 1em;
|
||||
color: #212121;
|
||||
opacity: 0.6;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.doi-txt {
|
||||
font-size: 0.8em;
|
||||
letter-spacing: 0.009em;
|
||||
color: #7d7d7d;
|
||||
width: 12em;
|
||||
height: 1em;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.doi-panel {
|
||||
height: 3.5em;
|
||||
background: #fafafa;
|
||||
border: 1px solid #d1d1d1;
|
||||
border-radius: 4px;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.doi-link {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.frame {
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 1px 5px #00000026;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.frame-txt {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.frame-txt,
|
||||
.finalize-txt {
|
||||
font-size: 0.75em;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0px;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hr-line {
|
||||
border: 1px solid #dbdbdb;
|
||||
// width: 274px;
|
||||
// width: 17em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.authors {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.authors-label {
|
||||
font-size: 0.875em;
|
||||
color: #212121;
|
||||
height: 1.4em;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.authors-role {
|
||||
font-size: 0.875em;
|
||||
color: #a8a8a8;
|
||||
height: 1.4em;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
// ********CENTER ELEMENTS********
|
||||
|
||||
.mat-mini-fab,
|
||||
.mat-mini-fab-icon,
|
||||
.actions-btn,
|
||||
.status-icon,
|
||||
.dataset-logo,
|
||||
.frame-btn,
|
||||
.finalize-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dataset-label,
|
||||
.dmp-btn,
|
||||
.doi-panel,
|
||||
.researcher {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.show-more-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
|
@ -0,0 +1,549 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { DatasetOverviewModel } from '@app/core/model/dataset/dataset-overview';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
import { Location } from '@angular/common';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { DatasetStatus } from '@app/core/common/enum/dataset-status';
|
||||
import { DmpStatus } from '@app/core/common/enum/dmp-status';
|
||||
import { Role } from '@app/core/common/enum/role';
|
||||
import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard';
|
||||
import { DmpOverviewModel } from '@app/core/model/dmp/dmp-overview';
|
||||
import { ResearcherModel } from '@app/core/model/researcher/researcher';
|
||||
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service';
|
||||
import { DatasetService } from '@app/core/services/dataset/dataset.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { LockService } from '@app/core/services/lock/lock.service';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { UserServiceOld } from '@app/core/services/user/user.service-old';
|
||||
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
|
||||
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component';
|
||||
import { Oauth2DialogService } from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import * as FileSaver from 'file-saver';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { DatasetCopyDialogueComponent } from '../dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-dataset-overview',
|
||||
templateUrl: './dataset-overview.component.html',
|
||||
styleUrls: ['./dataset-overview.component.scss']
|
||||
})
|
||||
export class DatasetOverviewComponent extends BaseComponent implements OnInit {
|
||||
|
||||
dataset: DatasetOverviewModel;
|
||||
// datasetWizardEditorModel: DatasetWizardEditorModel;
|
||||
datasetWizardModel: DatasetWizardModel;
|
||||
isNew = true;
|
||||
isFinalized = false;
|
||||
isPublicView = true;
|
||||
hasPublishButton: boolean = true;
|
||||
// breadCrumbs: Observable<BreadcrumbItem[]> = observableOf();
|
||||
isUserOwner: boolean;
|
||||
expand = false;
|
||||
researchers: ResearcherModel[];
|
||||
users: UserInfoListingModel[];
|
||||
lockStatus: Boolean;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private datasetService: DatasetService,
|
||||
private translate: TranslateService,
|
||||
private authentication: AuthService,
|
||||
private dialog: MatDialog,
|
||||
private language: TranslateService,
|
||||
private uiNotificationService: UiNotificationService,
|
||||
private configurationService: ConfigurationService,
|
||||
private oauth2DialogService: Oauth2DialogService,
|
||||
private userService: UserServiceOld,
|
||||
private dmpService: DmpService,
|
||||
private location: Location,
|
||||
private datasetWizardService: DatasetWizardService,
|
||||
private lockService: LockService,
|
||||
private httpClient: HttpClient,
|
||||
private matomoService: MatomoService,
|
||||
private fileUtils: FileUtils
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.matomoService.trackPageView('Dataset Overview');
|
||||
// Gets dataset data using parameter id
|
||||
this.route.params
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe((params: Params) => {
|
||||
const itemId = params['id'];
|
||||
const publicId = params['publicId'];
|
||||
if (itemId != null) {
|
||||
this.isNew = false;
|
||||
this.isPublicView = false;
|
||||
this.datasetService.getOverviewSingle(itemId)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.dataset = data;
|
||||
this.researchers = this.dataset.dmp.researchers;
|
||||
this.users = this.dataset.dmp.users;
|
||||
this.checkLockStatus(this.dataset.id);
|
||||
this.setIsUserOwner();
|
||||
// const breadCrumbs = [];
|
||||
// breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DATASET-DESCRIPTIONS'), url: "/datasets" });
|
||||
// breadCrumbs.push({ parentComponentName: 'DatasetListingComponent', label: this.dataset.label, url: '/datasets/overview/' + this.dataset.id });
|
||||
// this.breadCrumbs = observableOf(breadCrumbs);
|
||||
}, (error: any) => {
|
||||
if (error.status === 404) {
|
||||
return this.onFetchingDeletedCallbackError('/datasets/');
|
||||
}
|
||||
if (error.status === 403) {
|
||||
return this.onFetchingForbiddenCallbackError('/datasets/');
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (publicId != null) {
|
||||
this.isNew = false;
|
||||
this.isFinalized = true;
|
||||
this.isPublicView = true;
|
||||
this.datasetService.getOverviewSinglePublic(publicId)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.dataset = data;
|
||||
this.researchers = this.dataset.dmp.researchers;
|
||||
this.users = this.dataset.dmp.users;
|
||||
// const breadCrumbs = [];
|
||||
// breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.PUBLIC DATASETS'), url: "/explore" });
|
||||
// breadCrumbs.push({ parentComponentName: 'DatasetListingComponent', label: this.dataset.label, url: '/datasets/publicOverview/' + this.dataset.id });
|
||||
// this.breadCrumbs = observableOf(breadCrumbs);
|
||||
}, (error: any) => {
|
||||
if (error.status === 404) {
|
||||
return this.onFetchingDeletedCallbackError('/explore');
|
||||
}
|
||||
if (error.status === 403) {
|
||||
return this.onFetchingForbiddenCallbackError('/explore');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
checkLockStatus(id: string) {
|
||||
this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(lockStatus => {
|
||||
this.lockStatus = lockStatus
|
||||
if (lockStatus) {
|
||||
this.dialog.open(PopupNotificationDialogComponent, {
|
||||
data: {
|
||||
title: this.language.instant('DATASET-OVERVIEW.LOCKED.TITLE'),
|
||||
message: this.language.instant('DATASET-OVERVIEW.LOCKED.MESSAGE')
|
||||
}, maxWidth: '30em'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onFetchingDeletedCallbackError(redirectRoot: string) {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-OVERVIEW.ERROR.DELETED-DATASET'), SnackBarNotificationLevel.Error);
|
||||
this.router.navigate([redirectRoot]);
|
||||
}
|
||||
|
||||
onFetchingForbiddenCallbackError(redirectRoot: string) {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-OVERVIEW.ERROR.FORBIDEN-DATASET'), SnackBarNotificationLevel.Error);
|
||||
this.router.navigate([redirectRoot]);
|
||||
}
|
||||
|
||||
goBack(): void {
|
||||
this.location.back();
|
||||
}
|
||||
|
||||
reloadPage(): void {
|
||||
const path = this.location.path();
|
||||
this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => this.router.navigate([path]));
|
||||
}
|
||||
|
||||
setIsUserOwner() {
|
||||
if (this.dataset) {
|
||||
const principalId: string = this.authentication.userId()?.toString();
|
||||
if (principalId) this.isUserOwner = !!this.dataset.users.find(x => (x.role === Role.Owner) && (principalId === x.id));
|
||||
}
|
||||
}
|
||||
|
||||
isUserAuthor(userId: string): boolean {
|
||||
if (this.isAuthenticated()) {
|
||||
const principalId: string = this.authentication.userId()?.toString();
|
||||
return userId === principalId;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
isUserDatasetRelated() {
|
||||
const principalId: string = this.authentication.userId()?.toString();
|
||||
let isRelated: boolean = false;
|
||||
if (this.dataset && principalId) {
|
||||
this.dataset.users.forEach(element => {
|
||||
if (element.id === principalId) {
|
||||
isRelated = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
return isRelated;
|
||||
}
|
||||
|
||||
roleDisplay(value: UserInfoListingModel) {
|
||||
if (value.role === Role.Owner) {
|
||||
return this.translate.instant('DMP-LISTING.OWNER');
|
||||
} else if (value.role === Role.Member) {
|
||||
return this.translate.instant('DMP-LISTING.MEMBER');
|
||||
} else {
|
||||
return this.translate.instant('DMP-LISTING.OWNER');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
roleDisplayFromList(value: UserInfoListingModel[]) {
|
||||
const principalId: string = this.authentication.userId()?.toString();
|
||||
let role: number;
|
||||
if (principalId) {
|
||||
value.forEach(element => {
|
||||
if (principalId === element.id) {
|
||||
role = element.role;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (role === Role.Owner) {
|
||||
return this.translate.instant('DMP-LISTING.OWNER');
|
||||
} else if (role === Role.Member) {
|
||||
return this.translate.instant('DMP-LISTING.MEMBER');
|
||||
} else {
|
||||
return this.translate.instant('DMP-LISTING.OWNER');
|
||||
}
|
||||
}
|
||||
|
||||
openShareDialog(rowId: any, rowName: any) {
|
||||
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
|
||||
autoFocus: false,
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
dmpId: rowId,
|
||||
dmpName: rowName
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public isAuthenticated(): boolean {
|
||||
return this.authentication.currentAccountIsAuthenticated();
|
||||
}
|
||||
|
||||
isDraftDataset(dataset: DatasetOverviewModel) {
|
||||
return dataset.status == DatasetStatus.Draft;
|
||||
}
|
||||
|
||||
isFinalizedDataset(dataset: DatasetOverviewModel) {
|
||||
return dataset.status == DatasetStatus.Finalized;
|
||||
}
|
||||
|
||||
editClicked(dataset: DatasetOverviewModel) {
|
||||
if (dataset.public) {
|
||||
this.router.navigate(['/datasets/publicEdit/', dataset.id]);
|
||||
// let url = this.router.createUrlTree(['/datasets/publicEdit/', dataset.id]);
|
||||
// window.open(url.toString(), '_blank');
|
||||
} else {
|
||||
this.router.navigate(['/datasets/edit/', dataset.id]);
|
||||
// let url = this.router.createUrlTree(['/datasets/edit/', dataset.id]);
|
||||
// let url = this.router.createUrlTree(['/plans/edit/', dataset.dmp.id], { queryParams: { dataset: dataset.id } });
|
||||
// window.open(url.toString(), '_blank');
|
||||
}
|
||||
}
|
||||
|
||||
deleteClicked() {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '300px',
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
||||
isDeleteConfirmation: true
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.datasetService.delete(this.dataset.id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => {
|
||||
this.onDeleteCallbackSuccess();
|
||||
},
|
||||
error => this.onDeleteCallbackError(error)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dmpClicked(dmp: DmpOverviewModel) {
|
||||
if (this.isPublicView) {
|
||||
this.router.navigate(['/explore-plans/publicOverview/' + dmp.id]);
|
||||
} else {
|
||||
this.router.navigate(['/plans/overview/' + dmp.id]);
|
||||
}
|
||||
}
|
||||
|
||||
onDeleteCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
|
||||
this.router.navigate(['/datasets']);
|
||||
}
|
||||
|
||||
onDeleteCallbackError(error) {
|
||||
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
|
||||
onUpdateCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||
this.reloadPage();
|
||||
}
|
||||
|
||||
onUpdateCallbackError(error) {
|
||||
this.uiNotificationService.snackBarNotification(error.error.message ? this.tryTranslate(error.error.message) : this.language.instant('DATASET-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
tryTranslate(errorMessage: string): string {
|
||||
return errorMessage.replace('Field value of', this.language.instant('Field value of'))
|
||||
.replace('must be filled', this.language.instant('must be filled'));
|
||||
}
|
||||
|
||||
public getOrcidPath(): string {
|
||||
return this.configurationService.orcidPath;
|
||||
}
|
||||
|
||||
isOrcid(reference: string) {
|
||||
const head = reference.split(':')[0];
|
||||
return head === 'orcid';
|
||||
}
|
||||
|
||||
getOrcidPathForResearcher(reference: string): string {
|
||||
const path = this.getOrcidPath();
|
||||
const userId = reference.split(':')[1];
|
||||
return path + userId;
|
||||
}
|
||||
|
||||
downloadPDF(id: string) {
|
||||
this.datasetService.downloadPDF(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/pdf' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('datasets', "pdf", id);
|
||||
});
|
||||
}
|
||||
|
||||
downloadDocx(id: string) {
|
||||
this.datasetService.downloadDocx(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/msword' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('datasets', "docx", id);
|
||||
});
|
||||
}
|
||||
|
||||
downloadXml(id: string) {
|
||||
this.datasetService.downloadXML(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/xml' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('datasets', "xml", id);
|
||||
});
|
||||
}
|
||||
|
||||
//GK: NO
|
||||
// downloadJson(id: string) {
|
||||
// this.datasetService.downloadJson(id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/json' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// })
|
||||
// }
|
||||
|
||||
openDmpSearchDialogue() {
|
||||
const formControl = new UntypedFormControl();
|
||||
const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, {
|
||||
width: '500px',
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
formControl: formControl,
|
||||
datasetId: this.dataset.id,
|
||||
datasetProfileId: this.dataset.datasetTemplate.id,
|
||||
datasetProfileExist: false,
|
||||
confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'),
|
||||
cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL')
|
||||
}
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (result && result.datasetProfileExist) {
|
||||
const newDmpId = result.formControl.value.id;
|
||||
this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } });
|
||||
// let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }])
|
||||
// window.open(url.toString(), '_blank')
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateUsers() {
|
||||
return this.dmpService.updateUsers(this.dataset.dmp.id, this.users).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => {
|
||||
this.onUpdateCallbackSuccess();
|
||||
},
|
||||
error => this.onUpdateCallbackError(error)
|
||||
);
|
||||
}
|
||||
|
||||
removeUserFromDmp(user: UserInfoListingModel) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.REMOVE'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
||||
isDeleteConfirmation: false
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
const index = this.users.findIndex(x => x.id === user.id);
|
||||
if (index > -1) {
|
||||
this.users.splice(index, 1);
|
||||
}
|
||||
this.updateUsers();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
showPublishButton(dataset: DatasetOverviewModel) {
|
||||
return this.isFinalizedDataset(dataset) && !dataset.public && this.hasPublishButton;
|
||||
}
|
||||
|
||||
// publish(id: String) {
|
||||
// const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
// maxWidth: '500px',
|
||||
// restoreFocus: false,
|
||||
// data: {
|
||||
// message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PUBLISH-ITEM'),
|
||||
// privacyPolicyNames: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PRIVACY-POLICY-NAMES'),
|
||||
// confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||
// cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
||||
// isDeleteConfirmation: false
|
||||
// }
|
||||
// });
|
||||
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (result) {
|
||||
// this.datasetService.publish(id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(() => {
|
||||
// this.hasPublishButton = false;
|
||||
// this.reloadPage();
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
finalize(dataset: DatasetOverviewModel) {
|
||||
|
||||
|
||||
this.dialog.open(ConfirmationDialogComponent, {
|
||||
data: {
|
||||
message: this.language.instant('DATASET-OVERVIEW.FINALISE-POPUP.MESSAGE'),
|
||||
confirmButton: this.language.instant('DATASET-OVERVIEW.FINALISE-POPUP.CONFIRM'),
|
||||
cancelButton: this.language.instant('DATASET-OVERVIEW.FINALISE-POPUP.CANCEL'),
|
||||
},
|
||||
maxWidth: '30em'
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(
|
||||
filter(x => x),
|
||||
takeUntil(this._destroyed)
|
||||
)
|
||||
.subscribe(_ => {
|
||||
this.router.navigate(['datasets', 'edit', dataset.id, 'finalize']);
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
// restoreFocus: false,
|
||||
// data: {
|
||||
// message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'),
|
||||
// confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'),
|
||||
// cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'),
|
||||
// isDeleteConfirmation: false
|
||||
// }
|
||||
// });
|
||||
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (result) {
|
||||
// this.datasetWizardService.getSingle(dataset.id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(data => {
|
||||
// this.datasetWizardModel = data;
|
||||
// this.datasetWizardModel.status = DatasetStatus.Finalized;
|
||||
// this.datasetWizardService.createDataset(this.datasetWizardModel)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(
|
||||
// data => this.onUpdateCallbackSuccess(),
|
||||
// error => this.onUpdateCallbackError(error)
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
hasReversableStatus(dataset: DatasetOverviewModel): boolean {
|
||||
return dataset.dmp.status == DmpStatus.Draft && dataset.status == DatasetStatus.Finalized
|
||||
}
|
||||
|
||||
reverse(dataset: DatasetOverviewModel) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.UNFINALIZE-ITEM'),
|
||||
confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'),
|
||||
cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'),
|
||||
isDeleteConfirmation: false
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.datasetWizardService.getSingle(dataset.id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.datasetWizardModel = data;
|
||||
this.datasetWizardModel.status = DatasetStatus.Draft;
|
||||
this.datasetWizardService.createDataset(this.datasetWizardModel)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
data => this.onUpdateCallbackSuccess(),
|
||||
error => this.onUpdateCallbackError(error)
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { FormattingModule } from '@app/core/formatting.module';
|
||||
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
|
||||
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
|
||||
import { ExportMethodDialogModule } from '@app/library/export-method-dialog/export-method-dialog.module';
|
||||
import { UrlListingModule } from '@app/library/url-listing/url-listing.module';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { DatasetOverviewComponent } from './dataset-overview.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
UrlListingModule,
|
||||
ConfirmationDialogModule,
|
||||
ExportMethodDialogModule,
|
||||
FormattingModule,
|
||||
AutoCompleteModule
|
||||
],
|
||||
declarations: [
|
||||
DatasetOverviewComponent
|
||||
]
|
||||
})
|
||||
export class DatasetOverviewModule { }
|
|
@ -8,11 +8,10 @@ import { MatSort } from '@angular/material/sort';
|
|||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { DmpListingModel } from '@app/core/model/dmp/dmp-listing';
|
||||
import { GrantListingModel } from '@app/core/model/grant/grant-listing';
|
||||
import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { DmpService, DmpServiceNew } from '@app/core/services/dmp/dmp.service';
|
||||
import { GrantService } from "@app/core/services/grant/grant.service";
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
|
@ -31,6 +30,9 @@ import { Observable, of as observableOf } from 'rxjs';
|
|||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||
import { DmpCriteriaDialogComponent } from './criteria/dmp-criteria-dialog.component';
|
||||
import { DmpUploadDialogue } from './upload-dialogue/dmp-upload-dialogue.component';
|
||||
import { DmpLookup } from '@app/core/query/dmp.lookup';
|
||||
import { Dmp } from '@app/core/model/dmp/dmp';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-listing-component',
|
||||
|
@ -49,7 +51,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
showGrant: boolean;
|
||||
titlePrefix: string;
|
||||
totalCount: number;
|
||||
listingItems: DmpListingModel[] = [];
|
||||
listingItems: Dmp[] = [];
|
||||
allVersions: boolean = false;
|
||||
groupLabel: string;
|
||||
isPublic: boolean = false;
|
||||
|
@ -73,6 +75,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
|
||||
constructor(
|
||||
private dmpService: DmpService,
|
||||
private dmpServiceNew: DmpServiceNew,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
public dialogAnimation: NgDialogAnimationService,
|
||||
|
@ -233,13 +236,6 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
}
|
||||
|
||||
public refresh(resetPages = false) {
|
||||
// if (this._paginator.pageSize === undefined) this._paginator.pageSize = 10;
|
||||
// if (resetPages) this._paginator.pageIndex = 0;
|
||||
// const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
|
||||
|
||||
// let fields: Array<string> = new Array();
|
||||
// if (this.sort && this.sort.active) { fields = this.sort.direction === 'asc' ? ['+' + this.sort.active] : ['-' + this.sort.active]; }
|
||||
// fields.push('-modified');
|
||||
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
|
||||
this.startIndex = 0;
|
||||
|
||||
|
@ -247,47 +243,81 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
this.setPublicCriteria();
|
||||
request.criteria = this.criteria;
|
||||
|
||||
this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (!result) { return []; }
|
||||
result.data.map(item => {
|
||||
item['datasets'].map(dmp => {
|
||||
dmp.url = 'datasets/edit/' + dmp.url;
|
||||
dmp.all = 'datasets/dmp/' + item.id;
|
||||
return dmp;
|
||||
});
|
||||
return item;
|
||||
});
|
||||
this.listingItems = result.data;
|
||||
let lookup: DmpLookup = new DmpLookup();
|
||||
lookup.project = {
|
||||
fields: [
|
||||
nameof<Dmp>(x => x.id),
|
||||
nameof<Dmp>(x => x.label),
|
||||
]
|
||||
};
|
||||
this.dmpServiceNew.query(lookup).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(result => {
|
||||
if (!result) { return; }
|
||||
// result.data.map(item => {
|
||||
// item['datasets'].map(dmp => {
|
||||
// dmp.url = 'datasets/edit/' + dmp.url;
|
||||
// dmp.all = 'datasets/dmp/' + item.id;
|
||||
// return dmp;
|
||||
// });
|
||||
// return item;
|
||||
// });
|
||||
this.listingItems = result.items;
|
||||
this.hasListingItems = true;
|
||||
if (!this.isPublic && this.listingItems.length === 0 && !this.hasCriteria() && !this.hasLikeCriteria()) {
|
||||
this.openTour();
|
||||
}
|
||||
this.totalCount = result.totalCount;
|
||||
this.totalCount = result.count;
|
||||
});
|
||||
|
||||
// const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
|
||||
// this.startIndex = 0;
|
||||
|
||||
// const request = new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields });
|
||||
// this.setPublicCriteria();
|
||||
// request.criteria = this.criteria;
|
||||
|
||||
// this.dmpService
|
||||
// this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (!result) { return []; }
|
||||
// result.data.map(item => {
|
||||
// item['datasets'].map(dmp => {
|
||||
// dmp.url = 'datasets/edit/' + dmp.url;
|
||||
// dmp.all = 'datasets/dmp/' + item.id;
|
||||
// return dmp;
|
||||
// });
|
||||
// return item;
|
||||
// });
|
||||
// this.listingItems = result.data;
|
||||
// this.hasListingItems = true;
|
||||
// if (!this.isPublic && this.listingItems.length === 0 && !this.hasCriteria() && !this.hasLikeCriteria()) {
|
||||
// this.openTour();
|
||||
// }
|
||||
// this.totalCount = result.totalCount;
|
||||
// });
|
||||
}
|
||||
|
||||
public loadMore() {
|
||||
this.startIndex = this.startIndex + this.pageSize;
|
||||
// const fields: Array<string> = ["-modified"];
|
||||
const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
|
||||
const request = new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields });
|
||||
this.setPublicCriteria();
|
||||
request.criteria = this.criteria;
|
||||
// this.startIndex = this.startIndex + this.pageSize;
|
||||
// // const fields: Array<string> = ["-modified"];
|
||||
// const fields: Array<string> = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value];
|
||||
// const request = new DataTableRequest<DmpCriteria>(this.startIndex, this.pageSize, { fields: fields });
|
||||
// this.setPublicCriteria();
|
||||
// request.criteria = this.criteria;
|
||||
|
||||
this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (!result) { return []; }
|
||||
result.data.map(item => {
|
||||
item['datasets'].map(dmp => {
|
||||
dmp.url = 'datasets/edit/' + dmp.url;
|
||||
dmp.all = 'datasets/dmp/' + item.id;
|
||||
return dmp;
|
||||
});
|
||||
return item;
|
||||
});
|
||||
// this.listingItems = this.listingItems.concat(result.data);
|
||||
this.listingItems = this.mergeTwoSortedLists(this.listingItems, result.data, this.formGroup.get('order').value);
|
||||
this.hasListingItems = true;
|
||||
});
|
||||
// this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (!result) { return []; }
|
||||
// result.data.map(item => {
|
||||
// item['datasets'].map(dmp => {
|
||||
// dmp.url = 'datasets/edit/' + dmp.url;
|
||||
// dmp.all = 'datasets/dmp/' + item.id;
|
||||
// return dmp;
|
||||
// });
|
||||
// return item;
|
||||
// });
|
||||
// // this.listingItems = this.listingItems.concat(result.data);
|
||||
// this.listingItems = this.mergeTwoSortedLists(this.listingItems, result.data, this.formGroup.get('order').value);
|
||||
// this.hasListingItems = true;
|
||||
// });
|
||||
}
|
||||
|
||||
pageThisEvent(event) {
|
||||
|
@ -315,7 +345,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
this.refresh();
|
||||
}
|
||||
|
||||
// rowClicked(dmp: DmpListingModel) {
|
||||
// rowClicked(dmp: Dmp) {
|
||||
// this.router.navigate(['/plans/overview/' + dmp.id]);
|
||||
// }
|
||||
|
||||
|
@ -464,62 +494,62 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
|
||||
}
|
||||
|
||||
private mergeTwoSortedLists(arr1: DmpListingModel[], arr2: DmpListingModel[], order: string): DmpListingModel[] {
|
||||
let merged = [];
|
||||
let index1 = 0;
|
||||
let index2 = 0;
|
||||
let current = 0;
|
||||
// private mergeTwoSortedLists(arr1: Dmp[], arr2: Dmp[], order: string): Dmp[] {
|
||||
// let merged = [];
|
||||
// let index1 = 0;
|
||||
// let index2 = 0;
|
||||
// let current = 0;
|
||||
|
||||
while (current < (arr1.length + arr2.length)) {
|
||||
// while (current < (arr1.length + arr2.length)) {
|
||||
|
||||
let isArr1Depleted = index1 >= arr1.length;
|
||||
let isArr2Depleted = index2 >= arr2.length;
|
||||
// let isArr1Depleted = index1 >= arr1.length;
|
||||
// let isArr2Depleted = index2 >= arr2.length;
|
||||
|
||||
if (order === 'modified') {
|
||||
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modifiedTime) > new Date(arr2[index2].modifiedTime)))) {
|
||||
merged[current] = arr1[index1];
|
||||
index1++;
|
||||
} else {
|
||||
merged[current] = arr2[index2];
|
||||
index2++;
|
||||
}
|
||||
} else if (order === 'created') {
|
||||
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].creationTime) > new Date(arr2[index2].creationTime)))) {
|
||||
merged[current] = arr1[index1];
|
||||
index1++;
|
||||
} else {
|
||||
merged[current] = arr2[index2];
|
||||
index2++;
|
||||
}
|
||||
} else if (order === 'label') {
|
||||
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label.localeCompare(arr2[index2].label)))) {
|
||||
merged[current] = arr1[index1];
|
||||
index1++;
|
||||
} else {
|
||||
merged[current] = arr2[index2];
|
||||
index2++;
|
||||
}
|
||||
} else if (order === 'status') {
|
||||
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) {
|
||||
merged[current] = arr1[index1];
|
||||
index1++;
|
||||
} else {
|
||||
merged[current] = arr2[index2];
|
||||
index2++;
|
||||
}
|
||||
} else if (order === "publishedAt") {
|
||||
if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].publishedAt) > new Date(arr2[index2].publishedAt)))) {
|
||||
merged[current] = arr1[index1];
|
||||
index1++;
|
||||
} else {
|
||||
merged[current] = arr2[index2];
|
||||
index2++;
|
||||
}
|
||||
}
|
||||
current++;
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
// if (order === 'modified') {
|
||||
// if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modifiedTime) > new Date(arr2[index2].modifiedTime)))) {
|
||||
// merged[current] = arr1[index1];
|
||||
// index1++;
|
||||
// } else {
|
||||
// merged[current] = arr2[index2];
|
||||
// index2++;
|
||||
// }
|
||||
// } else if (order === 'created') {
|
||||
// if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].creationTime) > new Date(arr2[index2].creationTime)))) {
|
||||
// merged[current] = arr1[index1];
|
||||
// index1++;
|
||||
// } else {
|
||||
// merged[current] = arr2[index2];
|
||||
// index2++;
|
||||
// }
|
||||
// } else if (order === 'label') {
|
||||
// if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label.localeCompare(arr2[index2].label)))) {
|
||||
// merged[current] = arr1[index1];
|
||||
// index1++;
|
||||
// } else {
|
||||
// merged[current] = arr2[index2];
|
||||
// index2++;
|
||||
// }
|
||||
// } else if (order === 'status') {
|
||||
// if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) {
|
||||
// merged[current] = arr1[index1];
|
||||
// index1++;
|
||||
// } else {
|
||||
// merged[current] = arr2[index2];
|
||||
// index2++;
|
||||
// }
|
||||
// } else if (order === "publishedAt") {
|
||||
// if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].publishedAt) > new Date(arr2[index2].publishedAt)))) {
|
||||
// merged[current] = arr1[index1];
|
||||
// index1++;
|
||||
// } else {
|
||||
// merged[current] = arr2[index2];
|
||||
// index2++;
|
||||
// }
|
||||
// }
|
||||
// current++;
|
||||
// }
|
||||
// return merged;
|
||||
// }
|
||||
|
||||
public setDashboardTourDmpText(): void {
|
||||
this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
|
||||
|
@ -547,69 +577,3 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
|||
return this.criteria.like !== undefined && this.criteria.like !== null;
|
||||
}
|
||||
}
|
||||
|
||||
// export class DmpDataSource extends DataSource<DmpListingModel> {
|
||||
|
||||
// totalCount = 0;
|
||||
|
||||
// constructor(
|
||||
// private _service: DmpService,
|
||||
// private _paginator: MatPaginator,
|
||||
// private _sort: MatSort,
|
||||
// private _criteria: DmpCriteriaComponent,
|
||||
// private itemId
|
||||
// ) {
|
||||
// super();
|
||||
// }
|
||||
|
||||
// connect(): Observable<DmpListingModel[]> {
|
||||
// const displayDataChanges = [
|
||||
// this._paginator.page
|
||||
// ];
|
||||
|
||||
// return Observable.merge(...displayDataChanges)
|
||||
// .startWith(null)
|
||||
// .switchMap(() => {
|
||||
// const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
|
||||
// let fields: Array<string> = new Array();
|
||||
// if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; }
|
||||
// const request = new DataTableRequest<DmpCriteria>(startIndex, this._paginator.pageSize, { fields: fields });
|
||||
// request.criteria = this._criteria.formGroup.value;
|
||||
// if (this.itemId) {
|
||||
// request.criteria.groupIds = [this.itemId];
|
||||
// request.criteria.allVersions = true;
|
||||
// }
|
||||
// return this._service.getPaged(request, "listing");
|
||||
// })
|
||||
// /*.catch((error: any) => {
|
||||
// this._snackBar.openFromComponent(SnackBarNotificationComponent, {
|
||||
// data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
|
||||
// duration: 3000,
|
||||
// extraClasses: ['snackbar-warning']
|
||||
// });
|
||||
// return Observable.of(null);
|
||||
// })*/
|
||||
// .map(result => {
|
||||
// result.data = result.data;
|
||||
// return result;
|
||||
// })
|
||||
// .map(result => {
|
||||
// return result;
|
||||
// })
|
||||
// .map(result => {
|
||||
// if (!result) { return []; }
|
||||
// if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
|
||||
// return result.data.map(item => {
|
||||
// item['datasets'].map(dmp => {
|
||||
// dmp.url = 'datasets/edit/' + dmp.url;
|
||||
// dmp.all = 'datasets/dmp/' + item.id;
|
||||
// return dmp;
|
||||
// });
|
||||
// return item;
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// disconnect() {
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -2,30 +2,30 @@
|
|||
<a [routerLink]="isPublic ? ['/explore-plans/publicOverview/' + dmp.id] : ['/plans/overview/' + dmp.id]" class="pointer">
|
||||
<div class="d-flex flex-direction-row">
|
||||
<div class="col-auto dmp-label">{{ 'DMP-LISTING.DMP' | translate }}</div>
|
||||
<div *ngIf="!isPublic" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.EDITED' | translate }}: {{ dmp.modifiedTime | dateTimeCultureFormatter: "d MMMM y" }}</div>
|
||||
<div *ngIf="!isPublic" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.EDITED' | translate }}: {{ dmp.updatedAt | dateTimeCultureFormatter: "d MMMM y" }}</div>
|
||||
<div *ngIf="isPublic" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ dmp.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}</div>
|
||||
</div>
|
||||
<div class="col-auto" [ngClass]="{'dmp-title': !isDraft, 'dmp-title-draft': isDraft}">{{dmp.label}}</div>
|
||||
<div class="dmp-subtitle">
|
||||
<span *ngIf="isUserDMPRelated()" class="col-auto">{{ roleDisplay(dmp.users) }}</span>
|
||||
<span *ngIf="isUserDMPRelated()">.</span>
|
||||
<span class="col-auto" *ngIf="dmp.status === 1 && dmp.public === true"><span class="material-icons icon-align">public</span>{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}}</span>
|
||||
<span *ngIf="dmp.status === 1 && dmp.public === false" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(dmp.status) }}</span>
|
||||
<span *ngIf="dmp.status === 0" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(dmp.status) }}</span>
|
||||
<span class="col-auto" *ngIf="dmp.status === dmpStatusEnum.Finalized && isPublic"><span class="material-icons icon-align">public</span>{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}}</span>
|
||||
<span *ngIf="dmp.status === dmpStatusEnum.Finalized && !isPublic" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(dmp.status) }}</span>
|
||||
<span *ngIf="dmp.status === dmpStatusEnum.Draft" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(dmp.status) }}</span>
|
||||
<span>.</span>
|
||||
<span class="col-auto">{{'DMP-LISTING.VERSION' | translate}} {{dmp.version}}</span>
|
||||
<span>.</span>
|
||||
<span class="col">{{ 'DMP-LISTING.GRANT' | translate }}: {{dmp.grant}}</span>
|
||||
<!-- <span class="col">{{ 'DMP-LISTING.GRANT' | translate }}: {{dmp.grant}}</span> -->
|
||||
</div>
|
||||
<div class="col-auto dmp-dataset-descriptions-title">{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ dmp.datasets.length }})
|
||||
<div class="col-auto dmp-dataset-descriptions-title">{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ dmp.descriptions.length }})
|
||||
</div>
|
||||
<div *ngFor="let dataset of dmp.datasets; let i = index; let last = last" [ngClass]="{'pb-3': i === dmp.datasets.length - 1}">
|
||||
<div *ngFor="let dataset of dmp.descriptions; let i = index; let last = last" [ngClass]="{'pb-3': i === dmp.descriptions.length - 1}">
|
||||
<div *ngIf="i < 3">
|
||||
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="!last && i !== 2">{{dataset.label}},</div>
|
||||
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="last || i == 2">{{dataset.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="dmp.datasets.length > 3" [routerLink]="isPublic ? ['/explore-plans/publicOverview/' + dmp.id] : ['/plans/overview/' + dmp.id]"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
|
||||
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="dmp.descriptions.length > 3" [routerLink]="isPublic ? ['/explore-plans/publicOverview/' + dmp.id] : ['/plans/overview/' + dmp.id]"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
|
||||
</a>
|
||||
<div class="dmp-card-actions">
|
||||
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DMP-LISTING.ACTIONS.EXPORT' | translate}}</a>
|
||||
|
@ -68,92 +68,3 @@
|
|||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
<!-- <div class="listing-item">
|
||||
<a [routerLink]="isPublic ? ['/explore-plans/publicOverview/' + dmp.id] : ['/plans/overview/' + dmp.id]">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-12 gray-container container-header">
|
||||
<p>{{dmp.grantAbbreviation}}</p>
|
||||
<button *ngIf="isDraft" mat-icon-button [matMenuTriggerFor]="actionsMenu" class="ml-auto" (click)="$event.preventDefault(); $event.stopPropagation();">
|
||||
<mat-icon class="more-horiz">more_horiz</mat-icon>
|
||||
</button>
|
||||
<mat-menu #actionsMenu="matMenu">
|
||||
<button mat-menu-item (click)="editClicked(dmp.id)" class="menu-item" *ngIf="!isPublic">
|
||||
<mat-icon>edit</mat-icon>{{ 'DMP-LISTING.ACTIONS.EDIT' | translate }}
|
||||
</button>
|
||||
<button mat-menu-item (click)="openShareDialog(dmp.id,dmp.label)" *ngIf="!isPublic">
|
||||
<mat-icon>share</mat-icon>{{'DMP-LISTING.ACTIONS.INVITE' | translate}}
|
||||
</button>
|
||||
<button mat-menu-item (click)="addDataset(dmp.id)" *ngIf="!isPublic">
|
||||
<mat-icon>add</mat-icon>{{'DMP-LISTING.ACTIONS.ADD-DATASET' | translate}}
|
||||
</button>
|
||||
<button mat-menu-item (click)="showDatasets(dmp.id, dmp.label)">
|
||||
<mat-icon>list</mat-icon>{{'DMP-LISTING.ACTIONS.DATASETS' | translate}}
|
||||
</button>
|
||||
<button mat-menu-item (click)="viewVersions(dmp.groupId, dmp.label)">
|
||||
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<mat-icon *ngIf="isDraft" matTooltip="{{'DMP-LISTING.TOOLTIP.DMP-STATUS.DRAFT' | translate}}" class="draft-icon">
|
||||
lock_open
|
||||
</mat-icon>
|
||||
<mat-icon *ngIf="isFinalized && !isPublished" matTooltip="{{'DMP-LISTING.TOOLTIP.DMP-STATUS.FINALIZED' | translate}}" class="lock-icon">
|
||||
lock
|
||||
</mat-icon>
|
||||
<div *ngIf="isPublished" class="outer-circle"><div class="inner-circle" matTooltip="{{'DMP-LISTING.TOOLTIP.DMP-STATUS.PUBLISHED' | translate}}"></div></div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row d-flex flex-wrap">
|
||||
<div class="col pl-0">
|
||||
<h4 class="title pl-0" *ngIf="isDraft">
|
||||
<span>{{ 'TYPES.DMP.DRAFT' | translate }}:</span> {{dmp.label}}
|
||||
</h4>
|
||||
<h4 class="title pl-0" *ngIf="!isDraft">{{dmp.label}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto pl-0">
|
||||
<p class="mt-1 description">{{dmp.description}}</p>
|
||||
</div>
|
||||
<div class="col-auto about-item ml-auto">
|
||||
<p>{{'DMP-LISTING.COLUMNS.VERSION' | translate}} : {{dmp.version}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto about-item pl-0" *ngIf="!isPublic">
|
||||
<mat-icon class="gray-icon pt-2" matTooltip="{{'DMP-LISTING.TOOLTIP.LEVEL-OF-ACCESS' | translate}}">
|
||||
settings
|
||||
</mat-icon>
|
||||
<h4 class="mt-1 ml-1 mr-3 p-1 role">{{roleDisplay(dmp.users).toUpperCase()}}</h4>
|
||||
</div>
|
||||
<div class="col-auto about-item" [ngClass]="isPublic ? 'pl-0' : ''">
|
||||
<a class="datasets-counter" [routerLink]="isPublic ? ['/explore-plans/publicEdit/' + dmp.id] : ['/plans/edit/' + dmp.id]" [queryParams]="{ tab: 'datasetDescriptions' }">
|
||||
<mat-icon class="gray-icon pt-2" matTooltip="{{'DMP-LISTING.TOOLTIP.INVOLVED-DATASETS' | translate}}">
|
||||
storage
|
||||
</mat-icon>
|
||||
<h4 class="mt-1 ml-1 mr-3 p-1">{{dmp.datasets.length}}</h4>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-auto about-item pt-2 pl-0">
|
||||
<mat-icon class="gray-icon" matTooltip="{{'DMP-LISTING.TOOLTIP.TEMPLATES-INVOLVED' | translate}}">assignment</mat-icon>
|
||||
<div *ngFor="let profile of dmp.associatedProfiles" class="pb-1">
|
||||
<div matTooltip="{{profile.label}}" class="chip ml-2 mr-2">{{profile.label}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto about-item ml-auto">
|
||||
<p *ngIf="isDraft">{{'DMP-BLUEPRINT-LISTING.COLUMNS.LAST-EDITED' | translate}} {{dmp.modifiedTime | date: "shortDate"}}</p>
|
||||
<p *ngIf="isFinalized && !isPublished">{{'TYPES.DMP.FINALISED' | translate}} {{dmp.finalizedAt | date: "shortDate"}}</p>
|
||||
<p *ngIf="isPublished">{{'DMP-BLUEPRINT-LISTING.COLUMNS.PUBLISHED' | translate}} {{dmp.publishedAt | date: "shortDate"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div> -->
|
||||
<!-- <mat-divider *ngIf="showDivider"></mat-divider> -->
|
||||
|
|
|
@ -8,7 +8,7 @@ import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blue
|
|||
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
|
||||
import { Role } from '@app/core/common/enum/role';
|
||||
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpModel } from '@app/core/model/dmp/dmp';
|
||||
import { Dmp, DmpModel } from '@app/core/model/dmp/dmp';
|
||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { LockService } from '@app/core/services/lock/lock.service';
|
||||
|
@ -25,7 +25,6 @@ import * as FileSaver from 'file-saver';
|
|||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { DmpStatus } from '../../../../core/common/enum/dmp-status';
|
||||
import { DmpListingModel } from '../../../../core/model/dmp/dmp-listing';
|
||||
import { AuthService } from '../../../../core/services/auth/auth.service';
|
||||
import { CloneDialogComponent } from '../../clone/clone-dialog/clone-dialog.component';
|
||||
import { DmpEditorModel } from '../../editor/dmp-editor.model';
|
||||
|
@ -34,6 +33,7 @@ import { FunderFormModel } from '../../editor/grant-tab/funder-form-model';
|
|||
import { GrantTabModel } from '../../editor/grant-tab/grant-tab-model';
|
||||
import { ProjectFormModel } from '../../editor/grant-tab/project-form-model';
|
||||
import { DmpInvitationDialogComponent } from '../../invitation/dmp-invitation-dialog.component';
|
||||
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-listing-item-component',
|
||||
|
@ -42,16 +42,17 @@ import { DmpInvitationDialogComponent } from '../../invitation/dmp-invitation-di
|
|||
})
|
||||
export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@Input() dmp: DmpListingModel;
|
||||
@Input() dmp: Dmp;
|
||||
@Input() showDivider: boolean = true;
|
||||
@Input() isPublic: boolean;
|
||||
@Output() onClick: EventEmitter<DmpListingModel> = new EventEmitter();
|
||||
@Output() onClick: EventEmitter<Dmp> = new EventEmitter();
|
||||
|
||||
isDraft: boolean;
|
||||
isFinalized: boolean;
|
||||
isPublished: boolean;
|
||||
dmpModel: DmpEditorModel;
|
||||
dmpFormGroup: UntypedFormGroup;
|
||||
dmpStatusEnum = DmpStatus;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
|
@ -81,7 +82,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
this.isDraft = false;
|
||||
this.isFinalized = true;
|
||||
this.isPublished = false;
|
||||
if (this.dmp.public == true) { this.isPublished = true }
|
||||
// if (this.dmp.public == true) { this.isPublished = true }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,29 +111,17 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
this.router.navigate(['/datasets/dmp/' + rowId, { dmpLabel: rowLabel }]);
|
||||
}
|
||||
|
||||
viewVersions(rowId: String, rowLabel: String, dmp: DmpListingModel) {
|
||||
if (dmp.public && !this.isUserOwner(dmp)) {
|
||||
let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]);
|
||||
window.open(url.toString(), '_blank');
|
||||
// this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
|
||||
} else {
|
||||
let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]);
|
||||
window.open(url.toString(), '_blank');
|
||||
// this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
|
||||
viewVersions(rowId: String, rowLabel: String, dmp: Dmp) {
|
||||
// if (dmp.public && !this.isUserOwner(dmp)) {
|
||||
// let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]);
|
||||
// window.open(url.toString(), '_blank');
|
||||
// // this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
|
||||
// } else {
|
||||
// let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]);
|
||||
// window.open(url.toString(), '_blank');
|
||||
// // this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } });
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// itemClicked() {
|
||||
// this.onClick.emit(this.dmp);
|
||||
// }
|
||||
|
||||
// grantClicked(grantId: String) {
|
||||
// this.router.navigate(['/grants/edit/' + grantId]);
|
||||
// }
|
||||
|
||||
// datasetClicked(dmpId: string) {
|
||||
// this.router.navigate(['/plans/edit/' + dmpId], { queryParams: { tab: "datasetDescriptions" } });
|
||||
// }
|
||||
|
||||
roleDisplay(value: any) {
|
||||
const principalId: string = this.authentication.userId()?.toString();
|
||||
|
@ -159,41 +148,41 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
const principalId: string = this.authentication.userId()?.toString();
|
||||
let isRelated: boolean = false;
|
||||
if (this.dmp && principalId) {
|
||||
this.dmp.users.forEach(element => {
|
||||
if (element.id === principalId) {
|
||||
isRelated = true;
|
||||
}
|
||||
})
|
||||
// this.dmp.users.forEach(element => {
|
||||
// if (element.id === principalId) {
|
||||
// isRelated = true;
|
||||
// }
|
||||
// })
|
||||
}
|
||||
return isRelated;
|
||||
}
|
||||
|
||||
cloneOrNewVersionClicked(dmp: DmpListingModel, isNewVersion: boolean) {
|
||||
this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.dmpModel = new DmpEditorModel();
|
||||
this.dmpModel.grant = new GrantTabModel();
|
||||
this.dmpModel.project = new ProjectFormModel();
|
||||
this.dmpModel.funder = new FunderFormModel();
|
||||
this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
|
||||
this.dmpModel.fromModel(data);
|
||||
this.dmpModel.status = DmpStatus.Draft;
|
||||
this.dmpFormGroup = this.dmpModel.buildForm();
|
||||
cloneOrNewVersionClicked(dmp: Dmp, isNewVersion: boolean) {
|
||||
// this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel))
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(data => {
|
||||
// this.dmpModel = new DmpEditorModel();
|
||||
// this.dmpModel.grant = new GrantTabModel();
|
||||
// this.dmpModel.project = new ProjectFormModel();
|
||||
// this.dmpModel.funder = new FunderFormModel();
|
||||
// this.dmpModel.extraProperties = new ExtraPropertiesFormModel();
|
||||
// this.dmpModel.fromModel(data);
|
||||
// this.dmpModel.status = DmpStatus.Draft;
|
||||
// this.dmpFormGroup = this.dmpModel.buildForm();
|
||||
|
||||
if (!isNullOrUndefined(this.dmpFormGroup.get('profile').value)) {
|
||||
this.getBlueprintDefinition(Guid.parse(this.dmpFormGroup.get('profile').value), result => {
|
||||
this.checkForGrant(result.definition);
|
||||
this.checkForFunder(result.definition);
|
||||
this.checkForProject(result.definition);
|
||||
});
|
||||
}
|
||||
// if (!isNullOrUndefined(this.dmpFormGroup.get('profile').value)) {
|
||||
// this.getBlueprintDefinition(Guid.parse(this.dmpFormGroup.get('profile').value), result => {
|
||||
// this.checkForGrant(result.definition);
|
||||
// this.checkForFunder(result.definition);
|
||||
// this.checkForProject(result.definition);
|
||||
// });
|
||||
// }
|
||||
|
||||
if (!isNewVersion) {
|
||||
this.dmpFormGroup.get('label').setValue(dmp.label + " New");
|
||||
}
|
||||
this.openCloneDialog(isNewVersion);
|
||||
});
|
||||
// if (!isNewVersion) {
|
||||
// this.dmpFormGroup.get('label').setValue(dmp.label + " New");
|
||||
// }
|
||||
// this.openCloneDialog(isNewVersion);
|
||||
// });
|
||||
}
|
||||
|
||||
private getBlueprintDefinition(blueprintId: Guid, successFunction) {
|
||||
|
@ -281,25 +270,25 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'),
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
if (!isNewVersion) {
|
||||
this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmp.id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCloneOrNewVersionCallbackSuccess(complete),
|
||||
error => this.onCloneOrNewVersionCallbackError(error)
|
||||
);
|
||||
} else if (isNewVersion) {
|
||||
this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmp.id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCloneOrNewVersionCallbackSuccess(complete),
|
||||
error => this.onCloneOrNewVersionCallbackError(error)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (result) {
|
||||
// if (!isNewVersion) {
|
||||
// this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmp.id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(
|
||||
// complete => this.onCloneOrNewVersionCallbackSuccess(complete),
|
||||
// error => this.onCloneOrNewVersionCallbackError(error)
|
||||
// );
|
||||
// } else if (isNewVersion) {
|
||||
// this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmp.id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(
|
||||
// complete => this.onCloneOrNewVersionCallbackSuccess(complete),
|
||||
// error => this.onCloneOrNewVersionCallbackError(error)
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
// newVersion(id: String, label: String) {
|
||||
|
@ -307,53 +296,53 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
// window.open(url.toString(), '_blank');
|
||||
// }
|
||||
|
||||
downloadXml(id: string) {
|
||||
this.dmpService.downloadXML(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/xml' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
downloadXml(id: Guid) {
|
||||
// this.dmpService.downloadXML(id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/xml' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('dmps', "xml", id);
|
||||
});
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('dmps', "xml", id);
|
||||
// });
|
||||
}
|
||||
|
||||
downloadDocx(id: string) {
|
||||
this.dmpService.downloadDocx(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/msword' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
downloadDocx(id: Guid) {
|
||||
// this.dmpService.downloadDocx(id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/msword' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('dmps', "docx", id);
|
||||
});
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('dmps', "docx", id);
|
||||
// });
|
||||
}
|
||||
|
||||
downloadPDF(id: string) {
|
||||
this.dmpService.downloadPDF(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/pdf' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
downloadPDF(id: Guid) {
|
||||
// this.dmpService.downloadPDF(id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/pdf' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('dmps', "pdf", id);
|
||||
});
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('dmps', "pdf", id);
|
||||
// });
|
||||
}
|
||||
|
||||
downloadJson(id: string) {
|
||||
this.dmpService.downloadJson(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/json' });
|
||||
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
FileSaver.saveAs(blob, filename);
|
||||
this.matomoService.trackDownload('dmps', "json", id);
|
||||
}, async error => {
|
||||
this.onExportCallbackError(error);
|
||||
});
|
||||
downloadJson(id: Guid) {
|
||||
// this.dmpService.downloadJson(id)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(response => {
|
||||
// const blob = new Blob([response.body], { type: 'application/json' });
|
||||
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
||||
// FileSaver.saveAs(blob, filename);
|
||||
// this.matomoService.trackDownload('dmps', "json", id);
|
||||
// }, async error => {
|
||||
// this.onExportCallbackError(error);
|
||||
// });
|
||||
}
|
||||
|
||||
async onExportCallbackError(error: any) {
|
||||
|
@ -406,7 +395,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
isDraftDmp(activity: DmpListingModel) {
|
||||
isDraftDmp(activity: Dmp) {
|
||||
return activity.status == DmpStatus.Draft;
|
||||
}
|
||||
|
||||
|
@ -440,8 +429,8 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit {
|
|||
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
|
||||
isUserOwner(activity: DmpListingModel): boolean {
|
||||
const principalId: string = this.authentication.userId()?.toString();
|
||||
if (principalId) return !!activity.users.find(x => (x.role === Role.Owner) && (principalId === x.id));
|
||||
isUserOwner(dmp: Dmp): boolean {
|
||||
const principalId: Guid = this.authentication.userId();
|
||||
if (principalId) return !!dmp.dmpUsers.find(x => (x.role === DmpUserRole.Owner) && (principalId === x.id));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<mat-button-toggle-group class="lang-menu" vertical (change)="onLanguageSelected($event)" [value]="this.getCurrentLanguage().value">
|
||||
<mat-button-toggle-group class="lang-menu" vertical (change)="onLanguageSelected($event)" [value]="this.getCurrentLanguage()">
|
||||
<div *ngFor="let lang of languages">
|
||||
<mat-button-toggle class="lang-button" [value]="lang.value">{{lang.label | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle class="lang-button" [value]="lang">{{'GENERAL.LANGUAGES.' + lang | translate}}</mat-button-toggle>
|
||||
</div>
|
||||
</mat-button-toggle-group>
|
||||
|
|
|
@ -6,6 +6,8 @@ import { UserServiceOld } from '@app/core/services/user/user.service-old';
|
|||
import { takeUntil } from 'rxjs/operators';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { MatButtonToggleChange } from '@angular/material/button-toggle';
|
||||
import { UserService } from '@app/core/services/user/user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-language',
|
||||
|
@ -15,47 +17,49 @@ import { ConfigurationService } from '@app/core/services/configuration/configura
|
|||
export class LanguageComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@Output() languageChange: EventEmitter<any> = new EventEmitter();
|
||||
languages = [];
|
||||
languages: string[] = [];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private authentication: AuthService,
|
||||
private languageService: LanguageService,
|
||||
private userService: UserServiceOld,
|
||||
private configurationService:ConfigurationService
|
||||
private userService: UserService,
|
||||
private languageService: LanguageService
|
||||
) {
|
||||
super();
|
||||
this.languages = this.configurationService.availableLanguages;
|
||||
this.languages = this.languageService.getAvailableLanguagesCodes();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.languageChange.emit(this.getCurrentLanguage().value)
|
||||
this.languageChange.emit(this.getCurrentLanguage())
|
||||
}
|
||||
|
||||
public isAuthenticated(): boolean {
|
||||
return this.authentication.currentAccountIsAuthenticated();
|
||||
}
|
||||
|
||||
public getCurrentLanguage(): any {
|
||||
const lang = this.languages.find(lang => lang.value === this.languageService.getCurrentLanguage());
|
||||
public getCurrentLanguage(): string {
|
||||
const lang = this.languages.find(lang => lang === this.languageService.getCurrentLanguage());
|
||||
return lang;
|
||||
}
|
||||
|
||||
onLanguageSelected(selectedLanguage: any) {
|
||||
onLanguageSelected(selectedLanguage: MatButtonToggleChange) {
|
||||
if (this.isAuthenticated()) {
|
||||
const langMap = new Map<string, string>();
|
||||
langMap.set('language', selectedLanguage.value);
|
||||
this.userService.updateUserSettings({ language: this.languages.find(lang => lang.value === selectedLanguage.value) })
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe((response) => {
|
||||
//TODO: refactor - save language selection to user profile
|
||||
// this.userService.updateUserSettings({ language: this.languages.find(lang => lang === selectedLanguage.value) })
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe((response) => {
|
||||
// this.languageService.changeLanguage(selectedLanguage.value);
|
||||
// this.authentication.refresh()
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(innerResponse => { this.router.navigateByUrl(this.router.url); });
|
||||
// },
|
||||
// error => {
|
||||
// console.log(error);
|
||||
// });
|
||||
this.languageService.changeLanguage(selectedLanguage.value);
|
||||
this.authentication.refresh()
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(innerResponse => { this.router.navigateByUrl(this.router.url); });
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
});
|
||||
this.router.navigateByUrl(this.router.url);
|
||||
} else {
|
||||
this.languageService.changeLanguage(selectedLanguage.value);
|
||||
this.router.navigateByUrl(this.router.url);
|
||||
|
|
|
@ -54,8 +54,8 @@ export class NavbarComponent extends BaseComponent implements OnInit {
|
|||
super();
|
||||
this.location = location;
|
||||
this.sidebarVisible = false;
|
||||
this.languages = this.configurationService.availableLanguages;
|
||||
this.selectedLanguage = this.configurationService.defaultLanguage || 'en';
|
||||
this.languages = this.languageService.getAvailableLanguagesCodes();
|
||||
this.selectedLanguage = this.languageService.getDefaultLanguagesCode();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
|
|
@ -4,32 +4,32 @@
|
|||
<div *ngIf="showItem(groupMenuItem);">
|
||||
<hr *ngIf="!firstGroup">
|
||||
<mat-list-item routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}" *ngFor="let groupMenuRoute of groupMenuItem.routes; let first = first" class="nav-item" [ngClass]="{'mt-4': first && firstGroup}">
|
||||
<a class="new-dmp nav-link nav-row" *ngIf="groupMenuRoute.path !== '/contact-support' && groupMenuRoute.path !== '/co-branding' && groupMenuRoute.path !== '/feedback' && groupMenuRoute.path !== '/datasets'" [routerLink]="[groupMenuRoute.path]" [ngClass]="{'dmp-tour': groupMenuRoute.path == '/plans'}">
|
||||
<i class="material-icons icon">{{ groupMenuRoute.icon }}</i>
|
||||
<i *ngIf="groupMenuRoute.path == '/plans'" class="material-icons icon-mask">person</i>
|
||||
<a class="new-dmp nav-link nav-row" *ngIf="groupMenuRoute.path !== '/contact-support' && groupMenuRoute.path !== '/co-branding' && groupMenuRoute.path !== '/feedback' && groupMenuRoute.path !== '/descriptions'" [routerLink]="[groupMenuRoute.path]" [ngClass]="{'dmp-tour': groupMenuRoute.path == '/plans'}">
|
||||
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
|
||||
<i *ngIf="groupMenuRoute.path == '/plans'" class="material-symbols-outlined icon-mask">person</i>
|
||||
<span [ngClass]="{'pl-0': groupMenuRoute.path == '/plans'}">{{groupMenuRoute.title | translate}}</span>
|
||||
</a>
|
||||
<a class="nav-link nav-row dataset-tour" *ngIf="groupMenuRoute.path === '/datasets'" [routerLink]="[groupMenuRoute.path]">
|
||||
<a class="nav-link nav-row dataset-tour" *ngIf="groupMenuRoute.path === '/descriptions'" [routerLink]="[groupMenuRoute.path]">
|
||||
<span class="inner-line"></span>
|
||||
<i class="material-icons icon">{{ groupMenuRoute.icon }}</i>
|
||||
<i class="material-icons icon-mask">person</i>
|
||||
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
|
||||
<i class="material-symbols-outlined icon-mask">person</i>
|
||||
<span class="pl-0">{{groupMenuRoute.title | translate}}</span>
|
||||
</a>
|
||||
<a class="nav-link nav-row" *ngIf="groupMenuRoute.path === '/co-branding'" href="/splash/resources/co-branding.html">
|
||||
<i class="material-icons icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}} <span class="material-icons icon-external">open_in_new</span></span>
|
||||
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}} <span class="material-symbols-outlined icon-external">open_in_new</span></span>
|
||||
</a>
|
||||
<a class="nav-link nav-row" *ngIf="groupMenuRoute.path === '/contact-support' && this.isAuthenticated()" [routerLink]="[groupMenuRoute.path]">
|
||||
<i class="material-icons icon">{{ groupMenuRoute.icon }}</i>
|
||||
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}}</span>
|
||||
</a>
|
||||
<a class="nav-link nav-row" *ngIf="groupMenuRoute.path === '/contact-support' && !this.isAuthenticated()" href="/splash/contact.html">
|
||||
<i class="material-icons icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}} <span class="material-icons icon-external">open_in_new</span></span>
|
||||
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}} <span class="material-symbols-outlined icon-external">open_in_new</span></span>
|
||||
</a>
|
||||
<a class="nav-link nav-row" *ngIf="groupMenuRoute.path === '/feedback'" (click)="openFeedback(groupMenuRoute)">
|
||||
<i class="material-icons icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}} <span class="material-icons icon-external">open_in_new</span></span>
|
||||
<i class="material-symbols-outlined icon">{{ groupMenuRoute.icon }}</i>
|
||||
<span>{{groupMenuRoute.title | translate}} <span class="material-symbols-outlined icon-external">open_in_new</span></span>
|
||||
</a>
|
||||
</mat-list-item>
|
||||
</div>
|
||||
|
|
|
@ -30,7 +30,7 @@ export const GENERAL_ROUTES: RouteInfo[] = [
|
|||
];
|
||||
export const DMP_ROUTES: RouteInfo[] = [
|
||||
{ path: '/plans', title: 'SIDE-BAR.MY-DMPS', icon: 'library_books' },
|
||||
{ path: '/datasets', title: 'SIDE-BAR.MY-DESCRIPTIONS', icon: 'dns' },
|
||||
{ path: '/descriptions', title: 'SIDE-BAR.MY-DESCRIPTIONS', icon: 'dns' },
|
||||
// { path: '/quick-wizard', title: 'SIDE-BAR.QUICK-WIZARD', icon: 'play_circle_outline' },
|
||||
// { path: '/plans/new', title: 'SIDE-BAR.ADD-EXPERT', icon: 'playlist_add' }
|
||||
];
|
||||
|
@ -51,18 +51,18 @@ export const PUBLIC_ROUTES: RouteInfo[] = [
|
|||
|
||||
export const ADMIN_ROUTES: RouteInfo[] = [
|
||||
{ path: '/dmp-blueprints', title: 'SIDE-BAR.DMP-BLUEPRINTS', icon: 'library_books' },
|
||||
{ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'library_books' },
|
||||
{ path: '/description-template-type', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'library_books' },
|
||||
{ path: '/references', title: 'SIDE-BAR.REFERENCES', icon: 'library_books' },
|
||||
{ path: '/reference-type', title: 'SIDE-BAR.REFERENCE-TYPES', icon: 'library_books' },
|
||||
{ path: '/tenants', title: 'SIDE-BAR.TENANTS', icon: 'library_books' },
|
||||
{ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'description' },
|
||||
{ path: '/description-template-type', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'stack' },
|
||||
{ path: '/references', title: 'SIDE-BAR.REFERENCES', icon: 'dataset_linked' },
|
||||
{ path: '/reference-type', title: 'SIDE-BAR.REFERENCE-TYPES', icon: 'add_link' },
|
||||
{ path: '/tenants', title: 'SIDE-BAR.TENANTS', icon: 'tenancy' },
|
||||
{ path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' },
|
||||
{ path: '/languages', title: 'SIDE-BAR.LANGUAGES', icon: 'language' },
|
||||
{ path: '/supportive-material', title: 'SIDE-BAR.SUPPORTIVE-MATERIAL', icon: 'import_contacts' }
|
||||
];
|
||||
|
||||
export const DATASET_TEMPLATE_ROUTES: RouteInfo[] = [
|
||||
{ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'library_books' }
|
||||
{ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'description' }
|
||||
];
|
||||
|
||||
export const INFO_ROUTES: RouteInfo[] = [
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
<div class="supportive-material-editor">
|
||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()">
|
||||
<div>
|
||||
<mat-card class="col-md-8 offset-md-2">
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{'SUPPORTIVE-MATERIAL-EDITOR.TITLE' | translate}}</mat-card-title>
|
||||
</mat-card-header>
|
||||
<div>
|
||||
<div class ="material">
|
||||
<mat-form-field>
|
||||
<mat-card class="col-md-8 offset-md-2 p-3">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'SUPPORTIVE-MATERIAL-EDITOR.FIELDS.MATERIAL-TYPE' | translate}}</mat-label>
|
||||
<mat-select (selectionChange)="selectedMaterialChanged($event.value)" name="type" [formControl]="formGroup.get('type')" required>
|
||||
<mat-option *ngFor="let type of supportiveMaterialTypeEnum" [value]="type">
|
||||
|
@ -18,10 +15,10 @@
|
|||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class ="lang">
|
||||
<mat-form-field>
|
||||
<div class="col">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>{{'SUPPORTIVE-MATERIAL-EDITOR.FIELDS.LANGUAGE' | translate}}</mat-label>
|
||||
<mat-select (selectionChange)="selectedLangChanged($event.value)" name= "languageCode" [formControl]="formGroup.get('languageCode')">
|
||||
<mat-select (selectionChange)="selectedLangChanged($event.value)" name="languageCode" [formControl]="formGroup.get('languageCode')">
|
||||
<mat-option *ngFor="let languageCode of availableLanguageCodes" [value]="languageCode">
|
||||
{{languageCode}}
|
||||
</mat-option>
|
||||
|
@ -31,9 +28,9 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <mat-card-title><div>{{selectedMaterial.name | translate}}</div></mat-card-title> -->
|
||||
<mat-card-content *ngIf="formGroup.get('type').value>=0 && formGroup.get('languageCode').value">
|
||||
<editor [init]="{
|
||||
<div class="row" *ngIf="formGroup.get('type').value != null && formGroup.get('languageCode').value">
|
||||
<div class="col">
|
||||
<editor class="w-100" [init]="{
|
||||
base_url: '/tinymce',
|
||||
suffix: '.min',
|
||||
height: 800,
|
||||
|
@ -53,7 +50,8 @@
|
|||
alignleft aligncenter alignright alignjustify | \
|
||||
bullist numlist outdent indent | code codesample | searchreplace | preview | removeformat | help'
|
||||
}" [formControl]="formGroup.get('payload')"></editor>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
<button mat-fab class="mat-fab-bottom-right save-btn" matTooltip="{{'SUPPORTIVE-MATERIAL-EDITOR.ACTIONS.SAVE' | translate}}" type="submit">
|
||||
<mat-icon class="mat-24">save</mat-icon>
|
||||
|
|
|
@ -30,7 +30,7 @@ import { SupportiveMaterialEditorResolver } from './supportive-material-editor.r
|
|||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { LanguageV2Service } from '@app/core/services/language/language-v2.service';
|
||||
import { LanguageHttpService } from '@app/core/services/language/language.http.service';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { Language } from '@app/core/model/language/language';
|
||||
import { LanguageLookup } from '@app/core/query/language.lookup';
|
||||
|
@ -69,7 +69,7 @@ export class SupportiveMaterialEditorComponent extends BaseEditor<SupportiveMate
|
|||
public enumUtils: EnumUtils,
|
||||
private supportiveMaterialService: SupportiveMaterialService,
|
||||
private languageService: LanguageService,
|
||||
private languageV2Service: LanguageV2Service,
|
||||
private languageV2Service: LanguageHttpService,
|
||||
private logger: LoggingService,
|
||||
private supportiveMaterialEditorService: SupportiveMaterialEditorService,
|
||||
private fileUtils: FileUtils,
|
||||
|
|
|
@ -85,7 +85,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
private matomoService: MatomoService
|
||||
) {
|
||||
super();
|
||||
this.languages = this.configurationService.availableLanguages;
|
||||
this.languages = this.languageService.getAvailableLanguagesCodes();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -99,7 +99,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
|
|||
//result['additionalinfo'] = JSON.parse(result['additionalinfo']);
|
||||
|
||||
this.userProfileEditorModel = new UserProfileEditorModel().fromModel(result);
|
||||
this.formGroup = this.userProfileEditorModel.buildForm(this.configurationService.availableLanguages);
|
||||
this.formGroup = this.userProfileEditorModel.buildForm(this.languageService.getAvailableLanguagesCodes());
|
||||
// this.formGroup = new FormBuilder().group({
|
||||
// language: new FormControl(result['language'] ? availableLanguages.filter(x => x.value === result['language']['value']).pop() : '', [Validators.required]),
|
||||
// timezone: new FormControl(result['timezone'], [Validators.required]),
|
||||
|
|
|
@ -7,49 +7,6 @@
|
|||
"Url": "localhost:5000/"
|
||||
},
|
||||
"defaultCulture": "en-US",
|
||||
"defaultLanguage": "en",
|
||||
"availableLanguages": [
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.ENGLISH",
|
||||
"value": "en"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.GREEK",
|
||||
"value": "gr"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.SPANISH",
|
||||
"value": "es"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.GERMAN",
|
||||
"value": "de"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.TURKISH",
|
||||
"value": "tr"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.SLOVAK",
|
||||
"value": "sk"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.SERBIAN",
|
||||
"value": "sr"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.PORTUGUESE",
|
||||
"value": "pt"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.CROATIAN",
|
||||
"value": "hr"
|
||||
},
|
||||
{
|
||||
"label": "GENERAL.LANGUAGES.POLISH",
|
||||
"value": "pl"
|
||||
}
|
||||
],
|
||||
"defaultBlueprintId": "86635178-36a6-484f-9057-a934e4eeecd5",
|
||||
"keycloak": {
|
||||
"enabled": true,
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Dokument"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Englisch",
|
||||
"GREEK": "Griechisch",
|
||||
"SPANISH": "Spanisch",
|
||||
"GERMAN": "German",
|
||||
"TURKISH": "Turkish",
|
||||
"SLOVAK": "Slovak",
|
||||
"SERBIAN": "Serbian",
|
||||
"PORTUGUESE": "Portuguese",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "Englisch",
|
||||
"gr": "Griechisch",
|
||||
"es": "Spanisch",
|
||||
"de": "German",
|
||||
"tr": "Turkish",
|
||||
"sk": "Slovak",
|
||||
"sr": "Serbian",
|
||||
"pt": "Portuguese",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -183,16 +183,16 @@
|
|||
"DOC": "Document"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "English",
|
||||
"GREEK": "Greek",
|
||||
"SPANISH": "Spanish",
|
||||
"GERMAN": "German",
|
||||
"TURKISH": "Turkish",
|
||||
"SLOVAK": "Slovak",
|
||||
"SERBIAN": "Serbian",
|
||||
"PORTUGUESE": "Portuguese",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "English",
|
||||
"gr": "Greek",
|
||||
"es": "Spanish",
|
||||
"de": "German",
|
||||
"tr": "Turkish",
|
||||
"sk": "Slovak",
|
||||
"sr": "Serbian",
|
||||
"pt": "Portuguese",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"HYBRID-LISTING": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Documento"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Inglés",
|
||||
"GREEK": "Griego",
|
||||
"SPANISH": "Español",
|
||||
"GERMAN": "Alemán",
|
||||
"TURKISH": "Turco",
|
||||
"SLOVAK": "Eslovaco",
|
||||
"SERBIAN": "Serbio",
|
||||
"PORTUGUESE": "Portugués",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "Inglés",
|
||||
"gr": "Griego",
|
||||
"es": "Español",
|
||||
"de": "Alemán",
|
||||
"tr": "Turco",
|
||||
"sk": "Eslovaco",
|
||||
"sr": "Serbio",
|
||||
"pt": "Portugués",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Document"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Αγγλικά",
|
||||
"GREEK": "Ελληνικά",
|
||||
"SPANISH": "Ισπανικά",
|
||||
"GERMAN": "Γερμανικά",
|
||||
"TURKISH": "Τούρκικα",
|
||||
"SLOVAK": "Σλοβάκικα",
|
||||
"SERBIAN": "Σερβικά",
|
||||
"PORTUGUESE": "Πορτογαλικά",
|
||||
"CROATIAN": "Κροατικά",
|
||||
"POLISH": "Πολωνικά"
|
||||
"en": "Αγγλικά",
|
||||
"gr": "Ελληνικά",
|
||||
"es": "Ισπανικά",
|
||||
"de": "Γερμανικά",
|
||||
"tr": "Τούρκικα",
|
||||
"sk": "Σλοβάκικα",
|
||||
"sr": "Σερβικά",
|
||||
"pt": "Πορτογαλικά",
|
||||
"hr": "Κροατικά",
|
||||
"pl": "Πολωνικά"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "DOCX"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Engleski",
|
||||
"GREEK": "Grčki",
|
||||
"SPANISH": "Španjolski",
|
||||
"GERMAN": "Njemački",
|
||||
"TURKISH": "Turski",
|
||||
"SLOVAK": "Slovački",
|
||||
"SERBIAN": "Srpski",
|
||||
"PORTUGUESE": "Portugalski",
|
||||
"CROATIAN": "Hrvatski",
|
||||
"POLISH": "Poljski"
|
||||
"en": "Engleski",
|
||||
"gr": "Grčki",
|
||||
"es": "Španjolski",
|
||||
"de": "Njemački",
|
||||
"tr": "Turski",
|
||||
"sk": "Slovački",
|
||||
"sr": "Srpski",
|
||||
"pt": "Portugalski",
|
||||
"hr": "Hrvatski",
|
||||
"pl": "Poljski"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Dokument"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Angielski",
|
||||
"GREEK": "Grecki",
|
||||
"SPANISH": "Hiszpański",
|
||||
"GERMAN": "Niemiecki",
|
||||
"TURKISH": "Turecki",
|
||||
"SLOVAK": "Słowacki",
|
||||
"SERBIAN": "Serbski",
|
||||
"PORTUGUESE": "Portugalski",
|
||||
"CROATIAN": "Chorwacki",
|
||||
"POLISH": "Polski"
|
||||
"en": "Angielski",
|
||||
"gr": "Grecki",
|
||||
"es": "Hiszpański",
|
||||
"de": "Niemiecki",
|
||||
"tr": "Turecki",
|
||||
"sk": "Słowacki",
|
||||
"sr": "Serbski",
|
||||
"pt": "Portugalski",
|
||||
"hr": "Chorwacki",
|
||||
"pl": "Polski"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "DOCX"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Inglês",
|
||||
"GREEK": "Grego",
|
||||
"SPANISH": "Espanhol",
|
||||
"GERMAN": "Alemão",
|
||||
"TURKISH": "Turco",
|
||||
"SLOVAK": "Eslovaco",
|
||||
"SERBIAN": "Sérvio",
|
||||
"PORTUGUESE": "Português",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "Inglês",
|
||||
"gr": "Grego",
|
||||
"es": "Espanhol",
|
||||
"de": "Alemão",
|
||||
"tr": "Turco",
|
||||
"sk": "Eslovaco",
|
||||
"sr": "Sérvio",
|
||||
"pt": "Português",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Dokument"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "Angličtina",
|
||||
"GREEK": "Gréčtina",
|
||||
"SPANISH": "Španielčtina",
|
||||
"GERMAN": "Nemečina",
|
||||
"TURKISH": "Turečtina",
|
||||
"SLOVAK": "Slovenčina",
|
||||
"SERBIAN": "Serbian",
|
||||
"PORTUGUESE": "Portuguese",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "Angličtina",
|
||||
"gr": "Gréčtina",
|
||||
"es": "Španielčtina",
|
||||
"de": "Nemečina",
|
||||
"tr": "Turečtina",
|
||||
"sk": "Slovenčina",
|
||||
"sr": "Serbian",
|
||||
"pt": "Portuguese",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Dokument"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "engleski",
|
||||
"GREEK": "grčki",
|
||||
"SPANISH": "španski",
|
||||
"GERMAN": "nemački",
|
||||
"TURKISH": "turski",
|
||||
"SLOVAK": "slovački",
|
||||
"SERBIAN": "Serbian",
|
||||
"PORTUGUESE": "Portuguese",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "engleski",
|
||||
"gr": "grčki",
|
||||
"es": "španski",
|
||||
"de": "nemački",
|
||||
"tr": "turski",
|
||||
"sk": "slovački",
|
||||
"sr": "Serbian",
|
||||
"pt": "Portuguese",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -182,16 +182,16 @@
|
|||
"DOC": "Belge"
|
||||
},
|
||||
"LANGUAGES": {
|
||||
"ENGLISH": "İngilizce",
|
||||
"GREEK": "Yunanca",
|
||||
"SPANISH": "İspanyolca",
|
||||
"GERMAN": "Almanca",
|
||||
"TURKISH": "Türkçe",
|
||||
"SLOVAK": "Slovakça",
|
||||
"SERBIAN": "Sırpça",
|
||||
"PORTUGUESE": "Portekizce",
|
||||
"CROATIAN": "Croatian",
|
||||
"POLISH": "Polish"
|
||||
"en": "İngilizce",
|
||||
"gr": "Yunanca",
|
||||
"es": "İspanyolca",
|
||||
"de": "Almanca",
|
||||
"tr": "Türkçe",
|
||||
"sk": "Slovakça",
|
||||
"sr": "Sırpça",
|
||||
"pt": "Portekizce",
|
||||
"hr": "Croatian",
|
||||
"pl": "Polish"
|
||||
}
|
||||
},
|
||||
"COOKIE": {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<script type="text/javascript" src="//platform.linkedin.com/in.js"></script>
|
||||
<!-- Fonts and icons -->
|
||||
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto:400,500,700,300|Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone' rel='stylesheet' type='text/css'>
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto:400,500,700,300|Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Symbols+Outlined' rel='stylesheet' type='text/css'>
|
||||
<!-- Hammer.js -->
|
||||
|
||||
</head>
|
||||
|
|
Loading…
Reference in New Issue