add fixed contact/help button

This commit is contained in:
Alex Martzios 2022-10-12 15:31:34 +03:00
parent dc1f947d7a
commit 6380311b1e
8 changed files with 142 additions and 24 deletions

View File

@ -10,24 +10,26 @@ const routes: Routes = [
{path: 'mail-preferences', loadChildren: () => import('./userEmailPreferences/mailPrefs.module').then(m => m.LibMailPrefsModule)}, {path: 'mail-preferences', loadChildren: () => import('./userEmailPreferences/mailPrefs.module').then(m => m.LibMailPrefsModule)},
{path: 'sdgs', loadChildren: () => import('./sdg/sdg.module').then(m => m.SdgModule)}, {path: 'sdgs', loadChildren: () => import('./sdg/sdg.module').then(m => m.SdgModule)},
{path: 'fields-of-science', loadChildren: () => import('./fos/fos.module').then(m => m.FosModule), data: {extraOffset: 100}}, {path: 'fields-of-science', loadChildren: () => import('./fos/fos.module').then(m => m.FosModule), data: {extraOffset: 100}},
{path: 'contact-us', loadChildren: () => import('./contact/contact.module').then(m => m.ContactModule)}, {path: 'contact-us', loadChildren: () => import('./contact/contact.module').then(m => m.ContactModule), data: {hasQuickContact: false}},
// ORCID Pages // ORCID Pages
{path: 'orcid', loadChildren: () => import('./orcid/orcid.module').then(m => m.LibOrcidModule)}, {path: 'orcid', loadChildren: () => import('./orcid/orcid.module').then(m => m.LibOrcidModule)},
{path: 'my-orcid-links', loadChildren: () => import('./orcid/my-orcid-links/myOrcidLinks.module').then(m => m.LibMyOrcidLinksModule)}, {path: 'my-orcid-links', loadChildren: () => import('./orcid/my-orcid-links/myOrcidLinks.module').then(m => m.LibMyOrcidLinksModule)},
// Landing Pages // Landing Pages
{path: 'search/result', loadChildren: () => import('./landingPages/result/libResult.module').then(m => m.LibResultModule)}, {path: 'search/result', loadChildren: () => import('./landingPages/result/libResult.module').then(m => m.LibResultModule), data: {hasQuickContact: false}},
{path: 'search/publication', loadChildren: () => import('./landingPages/publication/libPublication.module').then(m => m.LibPublicationModule)}, {path: 'search/publication', loadChildren: () => import('./landingPages/publication/libPublication.module').then(m => m.LibPublicationModule), data: {hasQuickContact: false}},
{path: 'search/dataset', loadChildren: () => import('./landingPages/dataset/libDataset.module').then(m => m.LibDatasetModule)}, {path: 'search/dataset', loadChildren: () => import('./landingPages/dataset/libDataset.module').then(m => m.LibDatasetModule), data: {hasQuickContact: false}},
{path: 'search/software', loadChildren: () => import('./landingPages/software/libSoftware.module').then(m => m.LibSoftwareModule)}, {path: 'search/software', loadChildren: () => import('./landingPages/software/libSoftware.module').then(m => m.LibSoftwareModule), data: {hasQuickContact: false}},
{path: 'search/other', loadChildren: () => import('./landingPages/orp/libOrp.module').then(m => m.LibOrpModule)}, {path: 'search/other', loadChildren: () => import('./landingPages/orp/libOrp.module').then(m => m.LibOrpModule), data: {hasQuickContact: false}},
{path: 'search/project', loadChildren: () => import('./landingPages/project/libProject.module').then(m => m.LibProjectModule)}, {path: 'search/project', loadChildren: () => import('./landingPages/project/libProject.module').then(m => m.LibProjectModule), data: {hasQuickContact: false}},
{ {
path: 'search/dataprovider', path: 'search/dataprovider',
loadChildren: () => import('././landingPages/dataProvider/libDataProvider.module').then(m => m.LibDataProviderModule) loadChildren: () => import('././landingPages/dataProvider/libDataProvider.module').then(m => m.LibDataProviderModule),
data: {hasQuickContact: false}
}, },
{ {
path: 'search/organization', path: 'search/organization',
loadChildren: () => import('./landingPages/organization/libOrganization.module').then(m => m.LibOrganizationModule) loadChildren: () => import('./landingPages/organization/libOrganization.module').then(m => m.LibOrganizationModule),
data: {hasQuickContact: false}
}, },
{ {
path: 'project-report', path: 'project-report',

View File

@ -1,10 +1,8 @@
import {Component} from '@angular/core'; import {ChangeDetectorRef, Component, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import {EnvProperties} from './openaireLibrary/utils/properties/env-properties'; import {EnvProperties} from './openaireLibrary/utils/properties/env-properties';
import {MenuItem} from './openaireLibrary/sharedComponents/menu'; import {MenuItem} from './openaireLibrary/sharedComponents/menu';
import {EnvironmentSpecificService} from './openaireLibrary/utils/properties/environment-specific.service'; import {EnvironmentSpecificService} from './openaireLibrary/utils/properties/environment-specific.service';
import {Session, User} from './openaireLibrary/login/utils/helper.class'; import {Session, User} from './openaireLibrary/login/utils/helper.class';
import {UserManagementService} from "./openaireLibrary/services/user-management.service"; import {UserManagementService} from "./openaireLibrary/services/user-management.service";
import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service"; import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service";
@ -15,6 +13,14 @@ import {properties} from "../environments/environment";
import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll"; import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll";
import {SEOService} from "./openaireLibrary/sharedComponents/SEO/SEO.service"; import {SEOService} from "./openaireLibrary/sharedComponents/SEO/SEO.service";
import {OpenaireEntities} from "./openaireLibrary/utils/properties/searchFields"; import {OpenaireEntities} from "./openaireLibrary/utils/properties/searchFields";
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {QuickContactComponent} from './openaireLibrary/sharedComponents/quick-contact/quick-contact.component';
import {EmailService} from './openaireLibrary/utils/email/email.service';
import {Composer} from "./openaireLibrary/utils/email/composer";
import {AlertModal} from './openaireLibrary/utils/modal/alert';
import {NotificationHandler} from "./openaireLibrary/utils/notification-handler";
import {QuickContactService} from './openaireLibrary/sharedComponents/quick-contact/quick-contact.service';
import {LayoutService} from './openaireLibrary/dashboard/sharedComponents/sidebar/layout.service';
@Component({ @Component({
//changeDetection: ChangeDetectionStrategy.Default, //changeDetection: ChangeDetectionStrategy.Default,
@ -46,6 +52,9 @@ import {OpenaireEntities} from "./openaireLibrary/utils/properties/searchFields"
</span></a> </span></a>
</cookie-law> </cookie-law>
<bottom id="bottom" *ngIf="isClient && properties" [properties]="properties"></bottom> <bottom id="bottom" *ngIf="isClient && properties" [properties]="properties"></bottom>
<quick-contact #quickContact *ngIf="showQuickContact && contactForm" (sendEmitter)="send($event)"
[contactForm]="contactForm" [sending]="sending" [contact]="'Help'"></quick-contact>
<modal-alert #modal [overflowBody]="false"></modal-alert>
` `
}) })
export class AppComponent { export class AppComponent {
@ -56,17 +65,29 @@ export class AppComponent {
properties: EnvProperties = properties; properties: EnvProperties = properties;
user: User; user: User;
header: Header; header: Header;
public showQuickContact: boolean;
public contactForm: FormGroup;
public sending: boolean = false;
@ViewChild('quickContact') quickContact: QuickContactComponent;
@ViewChild('modal') modal: AlertModal;
subscriptions = []; subscriptions = [];
constructor(private route: ActivatedRoute, private propertiesService: EnvironmentSpecificService, constructor(private route: ActivatedRoute, private propertiesService: EnvironmentSpecificService,
private router: Router, private userManagementService: UserManagementService, private smoothScroll: SmoothScroll, private router: Router, private userManagementService: UserManagementService, private smoothScroll: SmoothScroll,
private configurationService: ConfigurationService, private _meta: Meta, private seoService: SEOService,) { private configurationService: ConfigurationService, private _meta: Meta, private seoService: SEOService,
private emailService: EmailService, private fb: FormBuilder, private quickContactService: QuickContactService,
private layoutService: LayoutService, private cdr: ChangeDetectorRef) {
} }
ngOnInit() { ngOnInit() {
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
this.isClient = true; this.isClient = true;
} }
this.subscriptions.push(this.layoutService.hasQuickContact.subscribe(hasQuickContact => {
this.showQuickContact = hasQuickContact;
this.cdr.detectChanges();
}));
this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity); this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity);
this.feedbackmail = this.properties.feedbackmail; this.feedbackmail = this.properties.feedbackmail;
if (this.properties.environment == "production" || this.properties.environment == "development") { if (this.properties.environment == "production" || this.properties.environment == "development") {
@ -88,6 +109,10 @@ export class AppComponent {
position: 'left', position: 'left',
badge: true badge: true
}; };
this.reset();
}));
this.subscriptions.push(this.quickContactService.isDisplayed.subscribe(display => {
this.showQuickContact = display;
})); }));
} }
@ -138,7 +163,6 @@ export class AppComponent {
new MenuItem("", "Registries", "", "/search/entity-registries", false, ["datasource"], ["/search/entity-registries"], {}), new MenuItem("", "Registries", "", "/search/entity-registries", false, ["datasource"], ["/search/entity-registries"], {}),
new MenuItem("", "Browse all", "", "/search/find/dataproviders", false, ["datasource"], ["/search/find/dataproviders"], {})] new MenuItem("", "Browse all", "", "/search/find/dataproviders", false, ["datasource"], ["/search/find/dataproviders"], {})]
), ),
new MenuItem("contact", "Contact us", "", "/contact-us", false, [], ["/contact-us"], {}),
]; ];
if (Session.isPortalAdministrator(this.user)) { if (Session.isPortalAdministrator(this.user)) {
this.userMenuItems.push(new MenuItem("", "Manage all links", "", "/claims", false, [], ["/claims"], {})); this.userMenuItems.push(new MenuItem("", "Manage all links", "", "/claims", false, [], ["/claims"], {}));
@ -150,6 +174,66 @@ export class AppComponent {
if (this.user) { if (this.user) {
this.userMenuItems.push(new MenuItem("", "User information", "", "/user-info", false, [], [], {})); this.userMenuItems.push(new MenuItem("", "User information", "", "/user-info", false, [], [], {}));
} }
}
public send(event) {
if (event.valid === true) {
this.sendMail(this.properties.admins);
}
}
private sendMail(admins: string[]) {
this.sending = true;
this.subscriptions.push(this.emailService.contact(this.properties,
Composer.composeEmailForExplore(this.contactForm.value, admins),
this.contactForm.value.recaptcha).subscribe(
res => {
if (res) {
this.sending = false;
this.reset();
this.modalOpen();
} else {
this.handleError('Email <b>sent failed!</b> Please try again.');
}
},
error => {
this.handleError('Email <b>sent failed!</b> Please try again.', error);
}
));
}
public reset() {
if (this.quickContact) {
this.quickContact.close();
}
this.contactForm = this.fb.group({
name: this.fb.control('', Validators.required),
surname: this.fb.control('', Validators.required),
email: this.fb.control('', [Validators.required, Validators.email]),
affiliation: this.fb.control(''),
message: this.fb.control('', Validators.required),
recaptcha: this.fb.control('', Validators.required),
});
}
public modalOpen() {
this.modal.okButton = true;
this.modal.alertTitle = 'Your request has been successfully submitted';
this.modal.message = 'Our team will respond to your submission soon.';
this.modal.cancelButton = false;
this.modal.okButtonLeft = false;
this.modal.okButtonText = 'OK';
this.modal.open();
}
handleError(message: string, error = null) {
if (error) {
console.error(error);
}
this.sending = false;
this.quickContact.close();
NotificationHandler.rise(message, 'danger');
this.contactForm.get('recaptcha').setValue('');
} }
} }

View File

@ -17,6 +17,8 @@ import {Schema2jsonldModule} from "./openaireLibrary/sharedComponents/schema2jso
import {CacheInterceptorService} from "./openaireLibrary/cache-interceptor.service"; import {CacheInterceptorService} from "./openaireLibrary/cache-interceptor.service";
import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service"; import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service";
import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service"; import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service";
import {QuickContactModule} from './openaireLibrary/sharedComponents/quick-contact/quick-contact.module';
import {AlertModalModule} from './openaireLibrary/utils/modal/alertModal.module';
@NgModule({ @NgModule({
imports: [ imports: [
@ -29,7 +31,10 @@ import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.servi
BrowserModule.withServerTransition({ appId: 'explore' }), BrowserModule.withServerTransition({ appId: 'explore' }),
AppRoutingModule, AppRoutingModule,
BrowserTransferStateModule, BrowserTransferStateModule,
BrowserAnimationsModule, PageURLResolverModule, Schema2jsonldModule BrowserAnimationsModule, PageURLResolverModule,
Schema2jsonldModule,
QuickContactModule,
AlertModalModule
], ],
declarations: [AppComponent, OpenaireErrorPageComponent], declarations: [AppComponent, OpenaireErrorPageComponent],
exports: [AppComponent], exports: [AppComponent],

View File

@ -46,7 +46,7 @@
<ng-container> <ng-container>
<div class="uk-margin-top uk-padding-small"> <div class="uk-margin-top uk-padding-small">
<div id="parentContainer" class="uk-grid uk-grid-large" uk-grid> <div id="parentContainer" class="uk-grid uk-grid-large" uk-grid>
<div class="uk-width-1-4"> <div class="uk-width-1-4@m">
<div class="uk-sticky" uk-sticky="bottom: !#parentContainer; offset: 200;"> <div class="uk-sticky" uk-sticky="bottom: !#parentContainer; offset: 200;">
<ul *ngIf="!keyword" class="uk-tab uk-tab-left"> <ul *ngIf="!keyword" class="uk-tab uk-tab-left">
<li *ngFor="let item of fos; index as i" [class.uk-active]="activeSection === item.id" <li *ngFor="let item of fos; index as i" [class.uk-active]="activeSection === item.id"
@ -62,7 +62,7 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="uk-width-expand"> <div class="uk-width-expand@m">
<ng-container *ngIf="!keyword"> <ng-container *ngIf="!keyword">
<div [id]="item.id" *ngFor="let item of fos; index as i"> <div [id]="item.id" *ngFor="let item of fos; index as i">
<div class="uk-text-capitalize"> <div class="uk-text-capitalize">

View File

@ -324,7 +324,7 @@
</div> </div>
</div> </div>
<div class="uk-section"> <div #contact class="uk-section">
<div class="uk-container uk-container-large uk-margin-large-bottom uk-text-center"> <div class="uk-container uk-container-large uk-margin-large-bottom uk-text-center">
<h3 class="uk-h2 uk-margin-remove"> <h3 class="uk-h2 uk-margin-remove">
Need more information? Need more information?

View File

@ -19,7 +19,6 @@ import {SearchProjectsService} from '../openaireLibrary/services/searchProjects.
import {SearchOrganizationsService} from '../openaireLibrary/services/searchOrganizations.service'; import {SearchOrganizationsService} from '../openaireLibrary/services/searchOrganizations.service';
import {RefineFieldResultsService} from '../openaireLibrary/services/refineFieldResults.service'; import {RefineFieldResultsService} from '../openaireLibrary/services/refineFieldResults.service';
import {OpenaireEntities, SearchFields} from '../openaireLibrary/utils/properties/searchFields'; import {OpenaireEntities, SearchFields} from '../openaireLibrary/utils/properties/searchFields';
import {RouterHelper} from '../openaireLibrary/utils/routerHelper.class'; import {RouterHelper} from '../openaireLibrary/utils/routerHelper.class';
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties'; import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes'; import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
@ -32,6 +31,7 @@ import {properties} from "../../environments/environment";
import {Numbers, NumbersComponent} from "../openaireLibrary/sharedComponents/numbers/numbers.component"; import {Numbers, NumbersComponent} from "../openaireLibrary/sharedComponents/numbers/numbers.component";
import {StringUtils} from "../openaireLibrary/utils/string-utils.class"; import {StringUtils} from "../openaireLibrary/utils/string-utils.class";
import {NumberUtils} from '../openaireLibrary/utils/number-utils.class'; import {NumberUtils} from '../openaireLibrary/utils/number-utils.class';
import {QuickContactService} from '../openaireLibrary/sharedComponents/quick-contact/quick-contact.service';
@Component({ @Component({
selector: 'home', selector: 'home',
@ -138,7 +138,8 @@ export class HomeComponent implements OnInit, OnDestroy, AfterViewInit {
properties: EnvProperties = properties; properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities; public openaireEntities = OpenaireEntities;
public readMore: boolean = false; public readMore: boolean = false;
public showQuickContact: boolean;
@ViewChild('contact') contact: ElementRef;
subscriptions: any[] = []; subscriptions: any[] = [];
@ViewChildren('scrolling_element') elements: QueryList<ElementRef>; @ViewChildren('scrolling_element') elements: QueryList<ElementRef>;
@ -195,7 +196,8 @@ export class HomeComponent implements OnInit, OnDestroy, AfterViewInit {
private location: Location, private _piwikService: PiwikService, private location: Location, private _piwikService: PiwikService,
private config: ConfigurationService, private _meta: Meta, private _title: Title, private seoService: SEOService, private config: ConfigurationService, private _meta: Meta, private _title: Title, private seoService: SEOService,
private helper: HelperService, private helper: HelperService,
private cdr: ChangeDetectorRef private cdr: ChangeDetectorRef,
private quickContactService: QuickContactService
) { ) {
let description = "OpenAIRE Explore: Over 100M of research deduplicated, 170K research software, 11M research data. One of the largest open scholarly records collection worldwide."; let description = "OpenAIRE Explore: Over 100M of research deduplicated, 170K research software, 11M research data. One of the largest open scholarly records collection worldwide.";
let title = "OpenAIRE | Find and Share research"; let title = "OpenAIRE | Find and Share research";
@ -304,11 +306,28 @@ export class HomeComponent implements OnInit, OnDestroy, AfterViewInit {
ngAfterViewInit() { ngAfterViewInit() {
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
this.createObserver(); this.createObservers();
} }
} }
createObserver() { createObservers() {
let options = {
root: null,
rootMargin: '200px',
threshold: 1.0
};
let intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting && this.showQuickContact) {
this.showQuickContact = false;
this.quickContactService.setDisplay(this.showQuickContact);
} else if (!entry.isIntersecting && !this.showQuickContact) {
this.showQuickContact = true;
this.quickContactService.setDisplay(this.showQuickContact);
}
});
}, options);
intersectionObserver.observe(this.contact.nativeElement);
let mutationObserver = new MutationObserver(entries => { let mutationObserver = new MutationObserver(entries => {
entries.forEach(entry => { entries.forEach(entry => {
if (entry.attributeName === 'style') { if (entry.attributeName === 'style') {
@ -327,6 +346,7 @@ export class HomeComponent implements OnInit, OnDestroy, AfterViewInit {
this.elements.forEach(element => { this.elements.forEach(element => {
mutationObserver.observe(element.nativeElement, {attributes: true}); mutationObserver.observe(element.nativeElement, {attributes: true});
}); });
this.subscriptions.push(intersectionObserver);
this.subscriptions.push(mutationObserver); this.subscriptions.push(mutationObserver);
} }

@ -1 +1 @@
Subproject commit 09706515ba1feb0d44c02485bee9782f63a5978f Subproject commit 427e9105140fabb99f59693c94bc3b70db159901

View File

@ -3,6 +3,13 @@
/* Button */ /* Button */
@button-primary-background: @explore-color; @button-primary-background: @explore-color;
@inverse-button-primary-background: @explore-color; @inverse-button-primary-background: @explore-color;
@button-secondary-border: @explore-color;
@button-secondary-color: @explore-color;
@button-secondary-hover-background: @global-secondary-background;
@button-secondary-hover-background-gradient: none;
@button-secondary-active-background: @global-secondary-background;
@button-secondary-active-background-gradient: none;
/* Background */ /* Background */
@background-primary-background: @explore-color; @background-primary-background: @explore-color;