some minor changes

parent df535bda
#Sun May 30 15:06:06 CEST 2021
gradle.version=6.7
#Fri Feb 17 18:28:47 CET 2023
gradle.version=7.6
......@@ -7,6 +7,47 @@
"newProjectRoot": "projects",
"projects": {
"ipmworks-web": {
"i18n": {
"sourceLocale": "en",
"locales": {
"sr": {
"translation": "src/locale/messages.sr.xlf"
},
"it": {
"translation": "src/locale/messages.it.xlf"
},
"pt": {
"translation": "src/locale/messages.pt.xlf"
},
"pl": {
"translation": "src/locale/messages.pl.xlf"
},
"fi": {
"translation": "src/locale/messages.fi.xlf"
},
"fr": {
"translation": "src/locale/messages.fr.xlf"
},
"el": {
"translation": "src/locale/messages.el.xlf"
},
"sl": {
"translation": "src/locale/messages.sl.xlf"
},
"es": {
"translation": "src/locale/messages.es.xlf"
},
"nl": {
"translation": "src/locale/messages.nl.xlf"
},
"da": {
"translation": "src/locale/messages.da.xlf"
},
"de": {
"translation": "src/locale/messages.de.xlf"
}
}
},
"projectType": "application",
"schematics": {
"@schematics/angular:application": {
......@@ -20,6 +61,8 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"localize": true,
"aot": true,
"outputPath": "dist/ipmworks-web",
"index": "src/index.html",
"baseHref": "/toolbox/",
......@@ -35,7 +78,9 @@
"./node_modules/primeicons/primeicons.css",
"./node_modules/primeng/resources/themes/mdc-light-indigo/theme.css",
"./node_modules/primeng/resources/primeng.css",
"./node_modules/primeflex/primeflex.css"
"./node_modules/primeflex/primeflex.css",
"./node_modules/quill/dist/quill.core.css",
"./node_modules/quill/dist/quill.snow.css"
],
"scripts": []
},
......@@ -47,12 +92,12 @@
{
"type": "initial",
"maximumWarning": "10mb",
"maximumError": "5mb"
"maximumError": "10mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "5mb",
"maximumError": "4kb"
"maximumWarning": "10mb",
"maximumError": "10mb"
}
],
"fileReplacements": [
......
......@@ -10,8 +10,8 @@ repositories {
}
node {
version = '14.15.5'
npmVersion = '6.14.11'
version = '18.13.0'
npmVersion = '9.4.0'
download = true
}
......
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -22,19 +22,21 @@
"@ngxs/store": "^3.5.0",
"lazysizes": "^5.3.2",
"ng-lazyload-image": "^9.1.2",
"ngx-clipboard": "~15.1.0",
"primeflex": "~3.1.3",
"primeicons": "~5.0.0",
"primeng": "~13.2.1",
"quill": "^1.3.7",
"rxjs": "~6.6.0",
"tslib": "^2.1.0",
"zone.js": "~0.11.4",
"ngx-clipboard": "~15.1.0"
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "^13.2.6",
"@angular/cdk": "~13.2.6",
"@angular/cli": "~13.2.6",
"@angular/compiler-cli": "~13.2.6",
"@angular/localize": "~13.2.6",
"@types/jasmine": "~3.10.3",
"@types/node": "^14.0.0",
"jasmine-core": "~4.0.1",
......@@ -43,6 +45,7 @@
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"lite-server": "^2.6.1",
"typescript": "~4.4.2"
}
}
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {NgModule, OnInit} from '@angular/core';
import {ActivatedRoute, Router, RouterModule, Routes} from '@angular/router';
import {HomeComponent} from './component/home/home.component';
import {ResourceComponent} from "./component/resource/resource.component";
import {AddResourceComponent} from "./component/add-resource/add-resource.component";
......@@ -7,15 +7,20 @@ import {ApproveResourceComponent} from "./component/approve-resource/approve-res
import {LoginComponent} from "./component/login/login.component";
import {AuthGuard} from "./guard/auth.guard";
import {ChangePasswordComponent} from "./component/change-password/change-password.component";
import {HelpComponent} from "./component/help/help.component";
import {AppComponent} from "./app.component";
const routes: Routes = [
{path: '', component: HomeComponent, pathMatch: 'full'},
{path: 'export', component: HomeComponent, pathMatch: 'full',data:{header:"none"}},
{path: 'home', component: HomeComponent, pathMatch: 'full'},
{path:'resource/approve', component:ApproveResourceComponent, pathMatch:'full',canActivate:[AuthGuard]},
{path:'resource/add', component:AddResourceComponent, pathMatch:'full'},
{path:'resource/edit/:id',component:AddResourceComponent,pathMatch:'full',canActivate:[AuthGuard]},
{path:'resource/:id/:lang', component:ResourceComponent, pathMatch:'full'},
{path:'resource/:id', component:ResourceComponent, pathMatch:'full'},
{path:'login', component:LoginComponent, pathMatch:'full'},
{path:'help', component:HelpComponent, pathMatch:'full'},
{path:'changePassword/:token', component:ChangePasswordComponent, pathMatch:'full'}
......@@ -23,7 +28,9 @@ const routes: Routes = [
];
@NgModule({
imports: [RouterModule.forRoot(routes,{ onSameUrlNavigation: 'reload' })],
imports: [RouterModule.forRoot(routes,{onSameUrlNavigation: 'reload', scrollPositionRestoration: 'enabled'})],
exports: [RouterModule]
})
export class AppRoutingModule { }
export class AppRoutingModule{
}
<app-header-menu></app-header-menu>
<app-header-menu [hideheader]="hideheader"> </app-header-menu>
<div class="container-fluid py-4">
<router-outlet></router-outlet>
</div>
......
import {Component, OnDestroy, OnInit} from "@angular/core";
import {LogoutAction, UserState} from "./states/user.state";
import {filter, takeUntil} from "rxjs/operators";
import {NavigationEnd, Router} from "@angular/router";
import {MenuItem, MessageService, PrimeNGConfig} from "primeng/api";
import {Select, Store} from "@ngxs/store";
import {Observable, Subject} from "rxjs";
import {User} from "./model/user";
import {ActivatedRoute, NavigationEnd, Router} from "@angular/router";
@Component({
......@@ -14,9 +8,17 @@ import {User} from "./model/user";
styleUrls: ['./app.component.css']
})
export class AppComponent{
export class AppComponent implements OnInit{
title = 'ipmworks-web';
constructor(private primengConfig: PrimeNGConfig, private store: Store, private router: Router,private messageService: MessageService) {}
hideheader?:string
constructor(public router:Router,public route:ActivatedRoute) {
}
ngOnInit(): void {
this.router.events.subscribe(e => {
this.hideheader = this.route.root.firstChild?.snapshot.data['header'];
});
}
}
......
import { NgModule } from '@angular/core';
import {LOCALE_ID, NgModule} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
......@@ -13,7 +13,6 @@ import {CheckboxModule} from 'primeng/checkbox';
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {DataViewModule} from "primeng/dataview";
import {RatingModule} from "primeng/rating";
import {RouterModule} from "@angular/router";
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http";
import {MultiSelectModule} from 'primeng/multiselect';
import {DropdownModule} from "primeng/dropdown";
......@@ -21,8 +20,8 @@ import {InputTextModule} from "primeng/inputtext";
import {TooltipModule} from "primeng/tooltip";
import {CardModule} from "primeng/card";
import {TagModule} from "primeng/tag";
import { ResourceComponent } from './component/resource/resource.component';
import { AddResourceComponent } from './component/add-resource/add-resource.component';
import {ResourceComponent } from './component/resource/resource.component';
import {AddResourceComponent } from './component/add-resource/add-resource.component';
import {InputTextareaModule} from "primeng/inputtextarea";
import {RadioButtonModule} from "primeng/radiobutton";
import {FileUploadModule} from "primeng/fileupload";
......@@ -47,10 +46,19 @@ import {ImageModule} from "primeng/image";
import {ConfirmPopupModule} from 'primeng/confirmpopup';
import {ConfirmationService} from 'primeng/api';
import {ConfirmDialogModule} from "primeng/confirmdialog";
import {LAZYLOAD_IMAGE_HOOKS, LazyLoadImageModule, ScrollHooks} from 'ng-lazyload-image';
import { FooterComponent } from './component/footer/footer.component';
import { ChangePasswordComponent } from './component/change-password/change-password.component';
import { CheckPasswordDirective } from './validator/check-password.directive';
import {LazyLoadImageModule} from 'ng-lazyload-image';
import {FooterComponent } from './component/footer/footer.component';
import {ChangePasswordComponent } from './component/change-password/change-password.component';
import {CheckPasswordDirective } from './validator/check-password.directive';
import {BadgeModule} from "primeng/badge";
import {ClipboardModule } from 'ngx-clipboard';
import {AvatarModule} from 'primeng/avatar';
import {AvatarGroupModule} from 'primeng/avatargroup';
import {HelpComponent } from './component/help/help.component';
import {DividerModule} from 'primeng/divider';
import {ProgressSpinner, ProgressSpinnerModule} from "primeng/progressspinner";
import {TabViewModule} from 'primeng/tabview';
import {EditorModule} from "primeng/editor";
@NgModule({
declarations: [
......@@ -63,60 +71,67 @@ import { CheckPasswordDirective } from './validator/check-password.directive';
HeaderMenuComponent,
FooterComponent,
ChangePasswordComponent,
CheckPasswordDirective
],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
MenubarModule,
ButtonModule,
MenuModule,
AccordionModule,
SharedModule,
CheckboxModule,
FormsModule,
DataViewModule,
RatingModule,
RouterModule,
HttpClientModule,
MultiSelectModule,
DropdownModule,
InputTextModule,
TooltipModule,
CardModule,
TagModule,
InputTextModule,
CheckboxModule,
ButtonModule,
RadioButtonModule,
InputTextareaModule,
FileUploadModule,
ChipsModule,
MessagesModule,
MessageModule,
ToastModule,
PanelModule,
CascadeSelectModule,
DialogModule,
TableModule,
NgxsModule.forRoot([UserState], {developmentMode: !environment.production}),
NgxsStoragePluginModule.forRoot(),
ReactiveFormsModule,
ToastModule,
ImageModule,
ConfirmPopupModule,
ConfirmDialogModule,
LazyLoadImageModule
CheckPasswordDirective,
HelpComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
MenubarModule,
ButtonModule,
MenuModule,
AccordionModule,
SharedModule,
FormsModule,
DataViewModule,
RatingModule,
HttpClientModule,
MultiSelectModule,
DropdownModule,
InputTextModule,
TooltipModule,
CardModule,
TagModule,
InputTextModule,
CheckboxModule,
ButtonModule,
RadioButtonModule,
InputTextareaModule,
FileUploadModule,
ChipsModule,
MessagesModule,
MessageModule,
ToastModule,
PanelModule,
CascadeSelectModule,
DialogModule,
TableModule,
NgxsModule.forRoot([UserState], {developmentMode: !environment.production}),
NgxsStoragePluginModule.forRoot(),
ReactiveFormsModule,
ToastModule,
ImageModule,
ConfirmPopupModule,
ConfirmDialogModule,
LazyLoadImageModule,
BadgeModule,
ClipboardModule,
AvatarModule,
AvatarGroupModule,
DividerModule,
ProgressSpinnerModule,
TabViewModule,
EditorModule
],
providers: [MessageService,ConfirmationService,
{provide: LocationStrategy, useClass: HashLocationStrategy},
{
provide: LocationStrategy, useClass: HashLocationStrategy,
},{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}],
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
import { Component, OnInit } from '@angular/core';
import {Component, Inject, LOCALE_ID, OnInit} from '@angular/core';
import {ResourceType, Language, Region, Sector, Project, Resource, Pest, Crop} from "../../model/resource";
import {ResourceService} from "../../service/resource.service";
import {MessageService} from 'primeng/api';
import {ConfirmationService, MessageService} from 'primeng/api';
import {ActivatedRoute, Router} from "@angular/router";
import {FormControl} from "@angular/forms";
import {environment} from "../../../environments/environment";
......@@ -36,8 +36,10 @@ export class AddResourceComponent implements OnInit {
logo: any;
showOldLogo = true;
logoExist:boolean = false;
displayTerms = false;
termChecked = false;
constructor(private resourceService:ResourceService, private route: ActivatedRoute, private messageService: MessageService, private router: Router) { }
constructor(private resourceService:ResourceService, private route: ActivatedRoute, private messageService: MessageService, private router: Router, @Inject(LOCALE_ID) public locale: string, private confirmationService: ConfirmationService) { }
ngOnInit(): void {
this.resourceService.getAllSectors().subscribe((sectors: Sector[]) => {
......@@ -75,11 +77,9 @@ export class AddResourceComponent implements OnInit {
}
saveResource(){
this.resource.canEdit=true;
this.resourceService.saveResource(this.resource,this.edit).subscribe((data: Resource) => {
this.resource = data;
console.log(this.image)
console.log(this.logo)
this.resourceService.addFiles(this.image, this.logo, this.resourceContent, this.resource.idResource).subscribe(data => {
if(!this.edit){
this.messageService.add({severity: 'success', detail: 'Resource is saved, but need to be approved by administrator!'});
......@@ -156,4 +156,37 @@ export class AddResourceComponent implements OnInit {
this.logo=undefined;
this.showOldLogo = true;
}
showTerms(){
this.displayTerms = true;
}
delete(fileId?: String) {
this.confirmationService.confirm({
message: 'Are you sure that you want to delete resource?',
icon: 'pi pi-exclamation-triangle',
accept: () => {
// @ts-ignore
this.resourceService.deleteFile(fileId).subscribe(r => {
this.messageService.add({severity: 'success', detail: 'Resource has been deleted.'});
this.router.navigate(['/resource/edit/'+this.resource.idResource]);
}, error => {
this.messageService.add({severity: 'error', detail: 'Some error occurred!'});
}
);
}
});
}
downloadFile(fileName: any): void {
this.resourceService.downloadFile(fileName).subscribe((file: any) => {
const blob = new Blob([file], {type: file.type});
var url = window.URL.createObjectURL(blob);
/*const link = document.createElement('a');
link.href = this.url;
link.target="_blank";
link.download = fileName;*/
window.open(url,"_blank")
}, error => {
console.log(error)
});
}
}
<div class="card pt-6 pl-6 pr-6">
<p class="text-3xl"> Approve resources</p>
<p class="text-3xl" i18n> Approve resources</p>
<p-table [value]="resources" [paginator]="true" [rows]="10" >
<ng-template pTemplate="header">
<tr>
<th>Resource name</th>
<th>Resource type</th>
<th>Creation date</th>
<th i18n>Resource name</th>
<th i18n>Resource type</th>
<th i18n>Creation date</th>
<th i18n>How resource added</th>
<th></th>
</tr>
</ng-template>
......@@ -14,6 +15,7 @@
<td>{{resource.resourceName}}</td>
<td>{{resource.resourceType?.name}}</td>
<td>{{resource.creationDate| date:"d.M.yyyy, h:mm a"}}</td>
<td i18n>Manually</td>
<td>
<button pButton type="button" routerLink="/resource/{{resource.idResource}}" icon="pi pi-pencil"></button>
</td>
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -5,22 +5,22 @@
<div class="field">
<span class="p-float-label">
<input type="password" id="password" pInputText formControlName="password">
<label for="password">Enter new password...</label>
<label for="password" i18n="@@{new_password}">Enter new password...</label>
</span>
</div>
<div class="field">
<span class="p-float-label">
<input type="password" id="confirmedPassword" pInputText formControlName="confirmedPassword">
<label for="confirmedPassword">Retype password again...</label>
<label for="confirmedPassword" i18n="@@{retype_pass}">Retype password again...</label>
</span>
</div>
<div *ngIf="changeForm.errors?.['notSame'] && (changeForm.touched || changeForm.dirty)" class="text-xs p-error ">
<div *ngIf="changeForm.errors?.['notSame'] && (changeForm.touched || changeForm.dirty)" class="text-xs p-error " i18n="@@{pass_error}">
Passwords does not match!
</div>
</div>
<div class="field flex justify-content-center pt-4">
<p-button class="pr-4" type="submit" [disabled]="changeForm.invalid" (click)="changePassword()">Change password</p-button>
<p-button class="pr-4" type="submit" [disabled]="changeForm.invalid" (click)="changePassword()" i18n="@@{change_password}">Change password</p-button>
</div>
</form>
</div>
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -15,7 +15,7 @@
<img src="assets/EUFlag.png"/>
</div>
<div>
<p class="pl-5 pt-2 align-self-center">
<p class="pl-5 pt-2 align-self-center" i18n="@@{project_ack}">
This project has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No. 101000339.
</p>
</div>
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
@media only screen and (min-width: 60.0px) {
.flag{
width: 45px;
}
}
:host ::ng-deep .p-dropdown{
border:0px !important;
}
:host ::ng-deep .p-dropdown:not(.p-disabled).p-focus {
box-shadow: none;
}
:host ::ng-deep .p-menubar-end{
align-self: auto !important;
}
:host ::ng-deep .p-dropdown-trigger {
display: none !important;
}
<p-menubar [model]="items">
<p-menubar [model]="items" [ngStyle]="{'display': hideheader}">
<ng-template pTemplate="start">
<img src="assets/logo.jpg" height="97" class="pl-6 mr-8" routerLink="/home" alt="brand logo">
<a href="http://ipmworks.net">
<img src="assets/logo.jpg" height="97" class="pl-6 mr-8" alt="brand logo">
</a>
</ng-template>
<ng-template pTemplate="end">
<p-dropdown [options]="languages" [(ngModel)]="selectedLanguage" optionLabel="name" class="col-4" (onChange)="reloadTranslate($event)" appendTo="body">
<ng-template pTemplate="selectedItem">
<div *ngIf="selectedLanguage">
<img src="assets/languages/{{locale}}.png" class="flag pr-2"/>
</div>
</ng-template>
<ng-template let-language pTemplate="item">
<div class="flex">
<img src="assets/languages/{{language.code}}.png" class="flag pr-2"/>
<div>{{language.name}}</div>
</div>
</ng-template>
</p-dropdown>
</ng-template>
</p-menubar>
<p-toast></p-toast>
File mode changed from 100644 to 100755
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
import {MenuItem, MessageService, PrimeNGConfig} from "primeng/api";
import {Observable, Subject} from "rxjs";
import {User} from "../../model/user";
import {LogoutAction, UserState} from "../../states/user.state";
import {Select, Store} from "@ngxs/store";
import {NavigationEnd, Router, RouterEvent} from "@angular/router";
import {ActivatedRoute, NavigationEnd, Router, RouterEvent} from "@angular/router";
import {filter, takeUntil} from "rxjs/operators";
import { LOCALE_ID, Inject } from '@angular/core';
export class LanguageTrans{
public name?: string;
public code?:string;
}
@Component({
selector: 'app-header-menu',
templateUrl: './header-menu.component.html',
......@@ -19,49 +24,53 @@ export class HeaderMenuComponent implements OnInit,OnDestroy{
// @ts-ignore
public loggeduser: Observable<User> = this.store.select(UserState.userDetails);
logged?:boolean
selectedLanguage?:LanguageTrans;
languages :LanguageTrans[] = [];
constructor(private primengConfig: PrimeNGConfig, private store: Store, private router: Router,private messageService: MessageService) {}
@Input() hideheader?:string|null;
constructor(private route:ActivatedRoute,private primengConfig: PrimeNGConfig, private store: Store, private router: Router,private messageService: MessageService, @Inject(LOCALE_ID) public locale: string) {}
initialise() {
this.logged = this.isLogged();
// @ts-ignore
this.items = [
{
label: 'Home',
label: $localize `Home`,
routerLink:'/home',
styleClass:"pr-2 ",
},
{
label: 'Add resource',
label: $localize `Add resource`,
url:'#/resource/add',
styleClass:"pr-2",
target:"_blank"
},
{
label: 'Approve',
label: $localize `Approve`,
routerLink:'/resource/approve',
styleClass:"pr-2",
visible:this.isUserAdmin()
},
{
label: 'IPMWORKS Project',
label:$localize `IPMWORKS Project`,
url:'http://ipmworks.net',
styleClass:"pr-2",
target:"_blank"
},
{
label: 'Help and Support',
label: $localize`Help and Support`,
routerLink:'/help',
styleClass:"pr-2",
target:"_blank"
},
{
label: 'Logout',
label: $localize `Logout`,
command:(event) => {this.logout()},
styleClass:"pr-2",
visible:this.logged
},
{
label: 'Login',
label: $localize `Login`,
routerLink:'/login',
styleClass:"pr-2",
visible:!this.logged
......@@ -69,12 +78,38 @@ export class HeaderMenuComponent implements OnInit,OnDestroy{
]
}
ngOnInit(): void {
this.languages = [
{ name: $localize `Dutch`, code: "nl" },
{ name: $localize `Danish`, code: "da" },
{ name: $localize `English`, "code": "en" },
{ name: $localize `Finnish`, code: "fi" },
{ name: $localize `French`, code: "fr" },
{ name: $localize `German`, code: "de" },
{ name: $localize `Greek`, code: "el" },
{ name: $localize `Italian`, code: "it" },
{ name: $localize `Polish`, code: "pl" },
{ name: $localize `Portuguese`, code: "pt" },
{ name: $localize `Serbian`, "code": "sr" },
{ name: $localize `Slovenian`, code: "sl" },
{ name: $localize `Spanish`, code: "es" }
]
this.findSelectedLanguage();
this.router.events.pipe(filter((event) => event instanceof NavigationEnd),
takeUntil(this.destroyed)
).subscribe(() => {
this.router.routeReuseStrategy.shouldReuseRoute = function() { return false; };
this.initialise();
});
}
public findSelectedLanguage(){
console.log("locale:"+this.locale)
var selected = this.languages.filter(l=>l.code===this.locale);
if(selected.length !== 0){
this.selectedLanguage =this.languages.filter(l=>l.code===this.locale)[0];
}
}
public isUserAdmin() {
var admin = false;
......@@ -110,6 +145,11 @@ export class HeaderMenuComponent implements OnInit,OnDestroy{
this.router.navigate(['/home']);
this.messageService.add({severity:"success", detail:"Goodbye!"})
}
public reloadTranslate(event:any):void{
window.location.href= "/toolbox/"+this.selectedLanguage?.code;
}
}
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -34,3 +34,8 @@
padding:5px;
display: inline-block;
}
.hoverResource:hover{
background: rgba(63, 81, 181, 0.04);
cursor: pointer;
}
import {Component, OnDestroy, OnInit} from '@angular/core';
import {Component, Inject, LOCALE_ID, OnDestroy, OnInit} from '@angular/core';
import {
Crop,
Keyword,
......@@ -16,6 +16,7 @@ import {Message, MessageService} from "primeng/api";
import {environment} from "../../../environments/environment";
import {SearchModel} from "../../model/search-model";
import {NavigationEnd, Router} from "@angular/router";
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
......@@ -48,13 +49,14 @@ export class HomeComponent implements OnInit{
selectedPestType: string | undefined;
serachRunning= false;
searchTerm: string = "";
more= false;
more= true;
close = false;
imagePath = environment.baseUrl+"/resource/image";
imagePathRaw = environment.baseUrl+"/resource/image/raw";
searchModel:SearchModel = {};
constructor(private resourceService:ResourceService, private router:Router,private messageService: MessageService) {
loading:boolean = true;
counter:number = 0;
constructor(private resourceService:ResourceService, private router:Router,private messageService: MessageService, @Inject(LOCALE_ID) public locale: string) {
this.pageableResponse = {totalElements:0}
}
......@@ -121,7 +123,9 @@ export class HomeComponent implements OnInit{
this.totalElements = this.pageableResponse.totalElements;
}
public resetSearch(){
this.serachRunning=true;
this.router.navigate(['home']);
/*this.serachRunning=true;
this.resourceService.getAllResources().subscribe((resources: PageableResource) => {
// @ts-ignore
this.resources = resources.content;
......@@ -129,12 +133,46 @@ export class HomeComponent implements OnInit{
this.totalElements = resources.totalElements;
this.searchModel = {};
this.search = false;
this.serachRunning=false;
this.serachRunning=false;*/
});
//});
}
isEmptySearch(){
return JSON.stringify(this.searchModel) === '{}';
}
public getRegion(resource:Resource){
if (resource.regions !== undefined && resource.regions?.length >1){
return "EU"
}else if (resource.regions?.length ===1){
// if(this.locale !== 'en'){
// return Reflect.get(resource.regions[0],'name_'+this.locale)
// }else{
return resource.regions[0].name;
//}
}else{
return "EU"
}
}
public getResourceType(resource:Resource){
// if(this.locale !== 'en'){
// // @ts-ignore
// return Reflect.get(resource.resourceType,'name_'+this.locale)
// }else{
// @ts-ignore
return resource.resourceType.name;
// }
}
public getProject(resource:Resource){
if (resource.sectors == undefined|| resource.sectors.length==0 ){
return null;
}else{
return resource.project;
}
}
public getLang(){
if (this.searchModel.language !=undefined){
return this.searchModel.language[0].code;
}
return "";
}
}
......@@ -4,27 +4,27 @@
<div class="field">
<span class="p-float-label">
<input type="email" id="username" pInputText formControlName="username">
<label for="username">Username</label>
<label for="username" i18n="@@{username}">Username</label>
</span>
</div>
<div class="field">
<span class="p-float-label">
<input type="password" id="password" pInputText formControlName="password">
<label for="username">Password</label>
<label for="username" i18n="@@{password}">Password</label>
</span>
</div>
<div class="field flex justify-content-center pt-4">
<p-button class="pr-4" type="submit" (click)="signIn()">Login</p-button>
<p-button label="Forgot password?" (click)="displayDialog()" styleClass="p-button-link"></p-button>
<p-button class="pr-4" type="submit" (click)="signIn()" i18n="@@{login}">Login</p-button>
<p-button i18n-label="@@{forgot_password}" label="Forgot password?" (click)="displayDialog()" styleClass="p-button-link"></p-button>
</div>
</form>
</div>
</div>
<p-dialog [(visible)]="display" [breakpoints]="{'960px': '75vw', '640px': '100vw'}" [style]="{width: '50vw'} ">
<p>If you want to change your password, please enter your e-mail used to login. If we find email in our system, we will send you instructions to follow.</p>
<p i18n="@@{change_pass_instr}">If you want to change your password, please enter your e-mail used to login. If we find email in our system, we will send you instructions to follow.</p>
<input type="text" pInputText [(ngModel)]="email">
<div class="pt-4" >
<button type="button" pButton autofocus (click)="sendPasswordChange()" [disabled]="email.length == 0" > Send email</button>
<button type="button" pButton autofocus (click)="sendPasswordChange()" [disabled]="email.length == 0" i18n="@@{send_email}"> Send email</button>
</div>
</p-dialog>
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -27,3 +27,6 @@
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
.keep-format{
white-space: pre-wrap;
}
<div class="grid pt-6 pl-6 flex">
<div class="grid pt-6 pl-6 flex flex-wrap">
<div class="flex col-12 justify-content-center">
<p class="text-3xl">{{resource.resourceName}}
</p>
</div>
<div class="col-6 flex flex-column">
<div class="md:col-6 flex flex-column">
<div class="col-12 text-center">
<img [src]="imagePath+'/'+resourceId" class="imageSize" >
</div>
<div class="col-12">
<p-panel class="col-12 inline">
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}">Resource language</div><div class="my-0">{{resource.language?.name}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}">Resource origin</div> <div class="my-0 overflow-text"><a href="{{resource.resourceOrigin}}" target="_blank">{{resource.resourceOrigin}}</a></div></div>
<div class="flex align-items-center"> <div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}">Resource type</div><div class="my-0">{{resource.resourceType?.name}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}">Organization name</div><div class="my-0">{{resource.contactInstitution}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0"[ngStyle]="{color:'var(--surface-500)'}">Contact email</div><div class="my-0"></div>{{resource.contactEmail}}</div>
<div class="flex align-items-center"><div class="col-3 inline my-0"[ngStyle]="{color:'var(--surface-500)'}">Contact phone</div><div class="my-0">{{resource.contactPhone}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0"[ngStyle]="{color:'var(--surface-500)'}">Contact address</div><div class="my-0">{{resource.contactAddress}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}">Citation (DOI)</div><div class="overflow-text my-0">{{resource.citation}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{project}">Project</div><div class="my-0">{{resource.project}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{language}">Resource language</div><div class="my-0">{{resource.language?.name}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{resourceOrigin}">Resource origin</div> <div class="my-0 overflow-text"><a href="{{resource.resourceOrigin}}" target="_blank">{{resource.resourceOrigin}}</a></div></div>
<div class="flex align-items-center"> <div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{resourceType}">Resource type</div><div class="my-0">{{resource.resourceType?.name}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{contactInstitution}">Organization name</div><div class="my-0">{{resource.contactInstitution}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0"[ngStyle]="{color:'var(--surface-500)'}" i18n="@@{contactEmail}">Contact email</div><div class="my-0"></div>{{resource.contactEmail}}</div>
<div class="flex align-items-center"><div class="col-3 inline my-0"[ngStyle]="{color:'var(--surface-500)'}" i18n="@@{contactPhone}">Contact phone</div><div class="my-0">{{resource.contactPhone}}</div></div>
<div class="flex align-items-center"><div class="col-3 inline my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{citation}">Citation (DOI)</div><div class="overflow-text my-0">{{resource.citation}}</div></div>
</p-panel>
</div>
</div>
<div class="col-6 flex flex-column">
<p-panel header="Short summary" class="col-12 p-d-block">
<div class="flex"> {{resource.description}}</div>
<div class="md:col-6 flex flex-column">
<p-panel i18n-header="@@{short_summary}" header="Short summary" class="col-12 p-d-block">
<div *ngIf="resource.descriptionNative == undefined" class="flex keep-format" [innerHTML]="resource.description"></div>
<p-tabView *ngIf="resource.descriptionNative != undefined">
<p-tabPanel i18n-header="@@{tab_english}" header="English" >
<div class="flex keep-format"> {{resource.description}}</div>
</p-tabPanel>
<p-tabPanel i18n-header="@@{tab_native}}" header="Native">
<div class="flex keep-format"> {{resource.descriptionNative}}</div>
</p-tabPanel>
</p-tabView>
<div class="flex mt-5">
<div class="inline col-3 my-0"[ngStyle]="{color:'var(--surface-500)'}">Sectors</div>
<div class="inline col-3 my-0"[ngStyle]="{color:'var(--surface-500)'}" i18n="@@{sectors}">Sectors</div>
<div class="inline my-0" *ngFor="let sector of resource.sectors">
<img class="sector mx-2" [src]="'assets/sectors/'+sector.sectorIcon" pTooltip="{{sector.name}}">
</div>
</div>
<div class="flex flex-wrap">
<div class="inline col-3 my-0" [ngStyle]="{color:'var(--surface-500)'}">Regions</div>
<div class="inline col-3 my-0" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{regions}">Regions</div>
<div *ngFor="let region of resource.regions" class="inline my-0">
<p class=" my-0 py-2 mx-2" >{{region.name}}</p>
</div>
</div>
<div class="flex">
<div class="inline col-3" [ngStyle]="{color:'var(--surface-500)'}">Relevant pest(s)</div>
<div class="inline col-3" [ngStyle]="{color:'var(--surface-500)'}"i18n="@@{relevant_pests}">Relevant pest(s)</div>
<div class="col-9">
<div *ngFor="let pest of resource.pests" class="inline-flex pr-2 pb-2">
<p-badge severity="danger" value={{pest.commonName}}></p-badge>
......@@ -44,7 +52,7 @@
</div>
</div>
<div class="flex">
<div class="inline col-3" [ngStyle]="{color:'var(--surface-500)'}"> Relevant crop(s)</div>
<div class="inline col-3" [ngStyle]="{color:'var(--surface-500)'}" i18n="@@{relevant_crops}"> Relevant crop(s)</div>
<div class="col-9">
<div class="inline-flex pr-2 pb-2" *ngFor="let crop of resource.crops">
<p-badge severity="success" value={{crop.commonName}}></p-badge>
......@@ -54,10 +62,10 @@
</div>
</p-panel>
<p-panel class="col-12 p-d-block" header="Find out more" *ngIf="(resource.fileNames != undefined) || (resource.links != undefined)">
<div *ngFor="let file of resource.fileNames" >
<p-panel class="col-12 p-d-block" i18n-header="@@{find_more}" header="Find out more" *ngIf="(resource.files != undefined) || (resource.links != undefined)">
<div *ngFor="let file of resource.files" >
<i class="pi pi-file p-mr-2" style="font-size: 2rem"></i>
<button pButton type="button" label="{{file}}" class="p-button-link button-link" (click)="downloadFile(file)"></button>
<button pButton type="button" label="{{file.description}}" class="p-button-link button-link" (click)="downloadFile(file.description)"></button>
</div>
<div class="mt-2" *ngFor="let link of resource.links" >
<i class="pi pi-link p-mr-2" style="font-size: 2rem"></i>
......@@ -67,18 +75,19 @@
</div>
<div class="col-12 pt-3 flex justify-content-center">
<div class="pr-2">
<p-button label="Back to search" icon="pi pi-search" routerLink="/home" [loading]="false"></p-button>
<p-button label="Share" icon="pi pi-share-alt" class="ml-3"(click)=linkCopied(getPermLink(resource.idResource)) [loading]="false"></p-button>
<p-button i18n-label="@@{back_to_search}" label="Back to search" icon="pi pi-search" routerLink="/home" [loading]="false"></p-button>
<p-button i18n-label="@@{share}" label="Share" icon="pi pi-share-alt" class="ml-3"(click)=linkCopied(getPermLink(resource.idResource)) [loading]="false"></p-button>
<p-button i18n-label="@@{download}" label="Download" icon="pi pi-share-alt" class="ml-3"(click)=download(resource) [loading]="false"></p-button>
</div>
<div class="pr-2" *ngIf="!resource.approved && resource.canEdit && (loggeduser| async)?.roles?.includes('ADMIN')">
<p-button label="Approve" icon="pi pi-check" (onClick)="approve($event)" [loading]="false"></p-button>
<p-button i18n-label="@@{approve}" label="Approve" icon="pi pi-check" (onClick)="approve($event)" [loading]="false"></p-button>
</div>
<div class="pr-2" *ngIf="(loggeduser| async)?.roles?.includes('ADMIN') && resource.canEdit">
<p-button label="Edit" icon="pi pi-pencil" routerLink="/resource/edit/{{resourceId}}" [loading]="false"></p-button>
<p-button i18n-label="@@{edit}" label="Edit" icon="pi pi-pencil" routerLink="/resource/edit/{{resourceId}}" [loading]="false"></p-button>
</div>
<div *ngIf="(loggeduser| async)?.roles?.includes('ADMIN') && resource.canEdit">
<p-button label="Delete" icon="pi pi-trash" (onClick)="delete($event)" [loading]="false"></p-button>
<p-button i18n-label="@@{delete]" label="Delete" icon="pi pi-trash" (onClick)="delete($event)" [loading]="false"></p-button>
</div>
</div>
</div>
......@@ -86,7 +95,7 @@
<p-confirmDialog></p-confirmDialog>
<p-dialog id="shareModal" name="shareModal" header="Copy link to share" [(visible)]="displayModal" [style]="{width: '40vw'}">
<div class="field">
<label>Link</label>
<label i18n="@@{link}">Link</label>
<input id="link" type="text" [(ngModel)]="copiedLink" pInputText/>
</div>
......
File mode changed from 100644 to 100755
......@@ -8,6 +8,7 @@ import {Observable} from "rxjs";
import {User} from "../../model/user";
import {UserState} from "../../states/user.state";
import {Store} from "@ngxs/store";
import {HttpResponse} from "@angular/common/http";
@Component({
selector: 'app-resource',
......@@ -20,6 +21,7 @@ export class ResourceComponent implements OnInit {
filePath = environment.baseUrl+"/resource/file";
url:any;
resourceId = null;
lang = null;
displayModal=false;
copiedLink="";
// @ts-ignore
......@@ -32,7 +34,10 @@ export class ResourceComponent implements OnInit {
// @ts-ignore
this.resourceId = this.route.snapshot.paramMap.get('id');
// @ts-ignore
this.resourceService.getResource(this.resourceId).subscribe(data =>{
this.lang = this.route.snapshot.paramMap.get('lang');
// @ts-ignore
this.resourceService.getResource(this.resourceId,this.lang).subscribe(data =>{
this.resource =data;
});
......@@ -77,7 +82,7 @@ export class ResourceComponent implements OnInit {
this.resourceService.deleteResource(this.resourceId).subscribe(r =>{
this.messageService.add({severity:'success', detail:'Resource has been deleted.'});
this.router.navigate(['/home'])
},error =>{
},(error: { status: any; }) =>{
this.messageService.add({severity:'error', detail:'Some error occurred!'});
}
);
......@@ -99,4 +104,31 @@ export class ResourceComponent implements OnInit {
this.copiedLink=link;
this.displayModal=true;
}
download(resource:Resource) {
this.resourceService.download(resource).subscribe({
next: (data) => {
// @ts-ignore
if (resource.resourceName ==undefined){
resource.resourceName = "unknown"
}
this.downloadPDF(data as unknown as HttpResponse<any>, resource.resourceName)
},
error: () => {
this.messageService.add({severity:'error', detail:'Some error occurred!'});
}
});
}
private downloadPDF(resp: HttpResponse<any>,fileName:string) {
const content = resp.headers.get('Content-Type');
const blob = new Blob([resp.body], { type: resp.body.type });
const anchor = document.createElement('a');
anchor.href = window.URL.createObjectURL(blob);
anchor.download = fileName +'.pdf';
anchor.target = '_blank';
anchor.dataset.downloadurl = ['text/plain', anchor.download, anchor.href].join(':');
document.body.appendChild(anchor);
anchor.click();
document.body.removeChild(anchor);
}
}
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -4,15 +4,13 @@ export interface Resource {
description?: string;
descriptionNative?:string;
links?:string[];
fileNames?:string[];
files?:any[];
resourceOrigin?: string;
resourceType?: ResourceType;
sectors?: Sector[];
regions?: Region[];
crops?:Crop[];
pests?:Pest[];
//keywordsTemp?:string[];
//keywords?: Keyword[];
language?: Language;
project?: Project;
projectWeb?: string;
......@@ -20,7 +18,6 @@ export interface Resource {
contactInstitution?: string;
contactEmail?: string;
contactPhone?: string;
contactAddress?:string;
canEdit?:boolean;
citation?:string;
creationDate?:Date;
......@@ -47,13 +44,16 @@ export class ResourceType{
export class Sector{
public idSector!: string;
public name!: string;
public name_sr!: string;
public sectorIcon!:string;
}
export class Region{
public idRegion!: string;
public name!: string;
public code!:string;
}
export class Language{
public idLanguage!: string;
......
File mode changed from 100644 to 100755
......@@ -9,4 +9,5 @@ export class SearchModel {
pest?: Pest[];
crop?: Crop[];
language?: Language[];
title?:string;
}
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -34,8 +34,8 @@ export class ResourceService {
public getResourcesForApproval() {
return this._httpClient.get<Resource []>(`${AppConfig.ApiPaths.getResourcesForApproval}`);
}
public getResource(id:string) {
return this._httpClient.get<Resource>(`${AppConfig.ApiPaths.getResource}`+"/"+id);
public getResource(id:string, lang:string) {
return this._httpClient.get<Resource>(`${AppConfig.ApiPaths.getResource}`+"/"+id+"/"+lang);
}
public hasImage(id:string,type:string) {
return this._httpClient.get<boolean>(`${AppConfig.ApiPaths.hasImage}`+"/"+type+"/"+id);
......@@ -49,6 +49,7 @@ export class ResourceService {
public deleteFile(id:string) {
return this._httpClient.get<Resource>(`${AppConfig.ApiPaths.deleteFile}`+"/"+id);
}
public downloadFile(name: string) {
const httpOptions = {
responseType: 'blob' as 'json',
......@@ -130,6 +131,8 @@ export class ResourceService {
public getAllHelpFilesDesc() {
return this._httpClient.get<FileDesc[]>(`${AppConfig.ApiPaths.getAllHelpFilesDesc}`);
}
public download(resource:Resource){
return this._httpClient.post(`${AppConfig.ApiPaths.download}`,resource,{responseType: 'blob' as 'blob', observe: 'response'})
}
}
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment