[main | DONE | CHANGED]: Added sepatare modules & routing modules for each component | Updated Single record validator to look the same as oai pmh validator & changed endpoint from "/validate" to "/validateRecord" | Deleted single-record-validator.component.less, oaipmh-validator.component.less, oaipmh-analysis.component.less | Created AnalysisComponent (<app-analysis>) to be commonly called by SingleRecordValidatorComponent and OaipmhAnalysisComponent & created SettingsComponent (<app-settings>) to be commonly called by SingleRecordValidatorComponent and OaipmhValidatorComponent.
This commit is contained in:
parent
e08b72eec2
commit
39e1e7acd2
|
@ -1,36 +1,35 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { SingleRecordValidatorComponent } from "./pages/single-record-validator/single-record-validator.component";
|
||||
import {OaipmhValidatorComponent} from "./pages/oaipmh-validator/validation-settings/oaipmh-validator.component";
|
||||
import {OaipmhHistoryComponent} from "./pages/oaipmh-validator/validation-history/oaipmh-history.component";
|
||||
import {OaipmhAnalysisComponent} from "./pages/oaipmh-validator/validation-analysis/oaipmh-analysis.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
pathMatch: 'full',
|
||||
redirectTo: 'single-record-validate'
|
||||
redirectTo: 'oaipmh'
|
||||
},
|
||||
{
|
||||
path: 'single-record-validate',
|
||||
component: SingleRecordValidatorComponent
|
||||
},
|
||||
loadChildren: () => import('./pages/single-record-validator/single-record-validator.module').then(m => m.SingleRecordValidatorModule)},
|
||||
{
|
||||
path: 'oaipmh-analysis',
|
||||
component: OaipmhAnalysisComponent
|
||||
loadChildren: () => import('./pages/oaipmh-validator/validation-analysis/oaipmh-analysis.module').then(m => m.OaipmhAnalysisModule)
|
||||
},
|
||||
{
|
||||
path: 'oaipmh-history',
|
||||
component: OaipmhHistoryComponent
|
||||
loadChildren: () => import('./pages/oaipmh-validator/validation-history/oaipmh-history.module').then(m => m.OaipmhHistoryModule)
|
||||
},
|
||||
{
|
||||
path: 'oaipmh',
|
||||
component: OaipmhValidatorComponent
|
||||
loadChildren: () => import('./pages/oaipmh-validator/validation-settings/oaipmh-validator.module').then(m => m.OaipmhValidatorModule)
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
imports: [RouterModule.forRoot(routes,
|
||||
{
|
||||
onSameUrlNavigation: "reload"
|
||||
}
|
||||
)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
|
|
|
@ -5,39 +5,38 @@ import { AppRoutingModule } from './app-routing.module';
|
|||
import { AppComponent } from './app.component';
|
||||
import { TopmenuComponent } from './shared/topmenu/topmenu.component';
|
||||
import { SidebarComponent } from './shared/sidebar/sidebar.component';
|
||||
import { SingleRecordValidatorComponent } from './pages/single-record-validator/single-record-validator.component';
|
||||
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
||||
import {HttpClientModule} from "@angular/common/http";
|
||||
import {OaipmhValidatorComponent} from "./pages/oaipmh-validator/validation-settings/oaipmh-validator.component";
|
||||
import {OaipmhHistoryComponent} from "./pages/oaipmh-validator/validation-history/oaipmh-history.component";
|
||||
import {OaipmhAnalysisComponent} from "./pages/oaipmh-validator/validation-analysis/oaipmh-analysis.component";
|
||||
import {InputModule} from "./openaire-library/sharedComponents/input/input.module";
|
||||
import {AlertModalModule} from "./openaire-library/utils/modal/alertModal.module";
|
||||
import {IconsModule} from "./openaire-library/utils/icons/icons.module";
|
||||
import {BreadcrumbsModule} from "./openaire-library/utils/breadcrumbs/breadcrumbs.module";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {SingleRecordValidatorModule} from "./pages/single-record-validator/single-record-validator.module";
|
||||
import {AnalysisModule} from "./pages/shared/analysis/analysis.module";
|
||||
import {SettingsModule} from "./pages/shared/settings/settings.module";
|
||||
import {OaipmhValidatorModule} from "./pages/oaipmh-validator/validation-settings/oaipmh-validator.module";
|
||||
import {OaipmhHistoryModule} from "./pages/oaipmh-validator/validation-history/oaipmh-history.module";
|
||||
import {OaipmhAnalysisModule} from "./pages/oaipmh-validator/validation-analysis/oaipmh-analysis.module";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TopmenuComponent,
|
||||
SidebarComponent,
|
||||
SingleRecordValidatorComponent,
|
||||
OaipmhValidatorComponent,
|
||||
OaipmhHistoryComponent,
|
||||
OaipmhAnalysisComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
HttpClientModule,
|
||||
InputModule,
|
||||
AlertModalModule,
|
||||
IconsModule,
|
||||
BreadcrumbsModule
|
||||
SingleRecordValidatorModule,
|
||||
OaipmhValidatorModule,
|
||||
OaipmhHistoryModule,
|
||||
OaipmhAnalysisModule,
|
||||
AnalysisModule,
|
||||
SettingsModule
|
||||
],
|
||||
providers: [],
|
||||
exports: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export class JobResult {
|
||||
id: string;
|
||||
xml?: string;
|
||||
baseUrl: string;
|
||||
set: string;
|
||||
numberOfRecords: number;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { PreviousRouteRecorder } from "../../../openaire-library/utils/piwik/previousRouteRecorder.guard";
|
||||
import { OaipmhAnalysisComponent } from "./oaipmh-analysis.component";
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([{ path: '', component: OaipmhAnalysisComponent, canDeactivate: [PreviousRouteRecorder] }])
|
||||
]
|
||||
})
|
||||
export class OaipmhAnalysisRoutingModule { }
|
|
@ -1,301 +1,4 @@
|
|||
<ng-template #rules_analysis let-rules=rules>
|
||||
<div *ngIf="rules?.length == 0" class="uk-margin-medium-top uk-text-center">No rules available</div>
|
||||
<table *ngIf="rules?.length > 0" class="uk-margin-medium-top uk-table uk-table-middle uk-table-divider uk-table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="uk-width-auto uk-width-2-6@xl">Rule Name</th>
|
||||
<th class="uk-text-center uk-width-auto uk-width-1-6@xl">FAIR Principles</th>
|
||||
<!-- <th class="uk-text-center">Rule Weight</th>-->
|
||||
<!-- <th class="uk-text-center"># Of Records</th>-->
|
||||
<th class="uk-text-center uk-width-auto uk-width-1-6@xl">Success Rate</th>
|
||||
<th class="uk-text-center uk-width-small uk-width-1-6@xl">Status</th>
|
||||
<th class="uk-text-center uk-width-small uk-width-1-6@xl">Issues</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="uk-text-small">
|
||||
<tr *ngFor="let ruleResult of rules">
|
||||
<td>
|
||||
<div>
|
||||
<span *ngIf="!ruleResult.ruleName">[No title available]</span>
|
||||
<span *ngIf="ruleResult.ruleName">
|
||||
<a *ngIf="ruleResult.link" class="custom-external uk-link-text" [href]="ruleResult.link" target="_blank">{{ruleResult.ruleName}}</a>
|
||||
<span *ngIf="!ruleResult.link">{{ruleResult.ruleName}}</span>
|
||||
</span>
|
||||
<span *ngIf="ruleResult.requirement_level">
|
||||
<span> (</span>
|
||||
<ng-container *ngIf="requirementLevelMapping.has(ruleResult.requirement_level)">{{requirementLevelMapping.get(ruleResult.requirement_level)}}</ng-container>
|
||||
<ng-container *ngIf="!requirementLevelMapping.has(ruleResult.requirement_level)">{{ruleResult.requirement_level}}</ng-container>
|
||||
<span>)</span>
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="ruleResult.description" class="uk-text-small uk-text-meta">{{ruleResult.description}}</div>
|
||||
</td>
|
||||
<td class="uk-text-center uk-text-normal">
|
||||
<!-- <span uk-tooltip="Findable">F</span>-->
|
||||
<!-- <span>, </span>-->
|
||||
<!-- <span uk-tooltip="Accessible">A</span>-->
|
||||
<!-- <span>, </span>-->
|
||||
<!-- <span uk-tooltip="Interoperable">I</span>-->
|
||||
<!-- <span>, </span>-->
|
||||
<!-- <span uk-tooltip="Reusable">R</span>-->
|
||||
<span *ngIf="ruleResult.fair_principles" [attr.uk-tooltip]="ruleResult.fair_principles_tooltip">{{ruleResult.fair_principles}}</span>
|
||||
<span *ngIf="!ruleResult.fair_principles">-</span>
|
||||
</td>
|
||||
<!-- <td class="uk-text-center">{{(ruleResult.rule_weight != undefined && ruleResult.rule_weight != null) ? ruleResult.rule_weight : '-'}}</td>-->
|
||||
<!-- <td class="uk-text-center">{{ruleResult.passed_records | number}}/{{(ruleResult.passed_records+ruleResult.failed_records) | number}}</td>-->
|
||||
<td>
|
||||
<div class="uk-text-xsmall">{{ruleResult.passed_records | number}}/{{jobResult.numberOfRecords | number}}</div>
|
||||
<div class="uk-text-center">
|
||||
<progress class="analysis-progress uk-progress uk-margin-remove-bottom" [value]="ruleResult.passed_records*100/jobResult.numberOfRecords" max="100"></progress>
|
||||
<div class="uk-text-center uk-text-xsmall uk-text-bolder uk-text-primary"
|
||||
style="position:relative; top: -18px; mix-blend-mode: color-burn">
|
||||
{{ruleResult.passed_records*100/jobResult.numberOfRecords}}%
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="uk-text-center">
|
||||
<span class="uk-label" [ngClass]="ruleResult.rule_status == Status.SUCCESS ? 'uk-label-success' : 'uk-label-danger'">{{ruleResult.rule_status}}</span>
|
||||
</td>
|
||||
<td class="uk-text-center">
|
||||
<a *ngIf="ruleResult.has_warnings" class="uk-text-warning" (click)="getWarnings(ruleResult)">Warnings</a>
|
||||
<div *ngIf="ruleResult.has_warnings && (ruleResult.has_errors || ruleResult.internal_error)">&</div>
|
||||
<a *ngIf="ruleResult.has_errors || ruleResult.internal_error" class="uk-text-danger" (click)="getErrors(ruleResult)">Errors</a>
|
||||
<!-- <div *ngIf="ruleResult.internal_error" class="uk-text-danger">error</div>-->
|
||||
<div *ngIf="!ruleResult.has_warnings && !ruleResult.has_errors && !ruleResult.internal_error">
|
||||
<icon class="uk-text-success" name="check" ratio="1"></icon>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ng-template>
|
||||
|
||||
<div id="page_content">
|
||||
<div id="page_content_header">
|
||||
<div class="analysis uk-grid uk-margin-remove-left" uk-grid>
|
||||
<div class="uk-width-expand uk-container uk-container-large">
|
||||
<div id="analysis-center-content" class="uk-width-expand uk-section uk-section-small uk-container uk-container-large">
|
||||
<!-- <div class="uk-section uk-section-small">-->
|
||||
<breadcrumbs [breadcrumbs]="breadcrumbs"></breadcrumbs>
|
||||
|
||||
<div class="uk-margin-large-top">
|
||||
<h1 class="uk-h5">Validation Result Analysis</h1>
|
||||
<hr>
|
||||
|
||||
<div *ngIf="!validationResult || validationResult.size == 0" class="uk-alert uk-alert-primary">
|
||||
No validated metadata record yet
|
||||
</div>
|
||||
<div *ngIf="validationResult?.size > 0">
|
||||
<ul uk-tab>
|
||||
<li *ngFor="let result of getKeys(validationResult)" class="uk-width-auto@l uk-width-medium">
|
||||
<a><span class="uk-text-truncate" [attr.uk-tooltip]="result">{{result}}</span></a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="uk-switcher uk-margin">
|
||||
<li *ngFor="let result of getValues(validationResult)">
|
||||
<ul class="uk-subnav uk-subnav-pill-alt uk-margin" uk-switcher>
|
||||
<li class="uk-active"><a>All Rules ({{result.analysisResult.length | number}})</a></li>
|
||||
<li><a>Successful ({{result.successfulAnalysisResult.length | number}})</a></li>
|
||||
<li><a>Warnings ({{result.warningAnalysisResult.length | number}})</a></li>
|
||||
<li><a>Failed ({{result.failedAnalysisResult.length | number}})</a></li>
|
||||
</ul>
|
||||
<ul class="uk-switcher uk-margin">
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.analysisResult}"></ng-container>
|
||||
</li>
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.successfulAnalysisResult}"></ng-container>
|
||||
</li>
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.warningAnalysisResult}"></ng-container>
|
||||
</li>
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.failedAnalysisResult}"></ng-container>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- <h6>Validation Result Analysis</h6>-->
|
||||
</div>
|
||||
|
||||
<modal-alert #warningsModal large="true" (alertOutput)="warningsModalOpen=false" classTitle="uk-border-bottom">
|
||||
<div *ngIf="warningsModalOpen" class="uk-modal-body uk-height-min-medium uk-width-expand">
|
||||
<div *ngIf="warnings.length == 0">No warnings available</div>
|
||||
<div *ngIf="warnings.length > 0">
|
||||
<div class="uk-h6">Warnings list ({{warnings.length | number}} warning<span *ngIf="warnings.length > 1">s</span>)</div>
|
||||
<ul uk-accordion class="uk-accordion">
|
||||
<li *ngFor="let message of warnings" class="accordion-warning uk-padding-small">
|
||||
<a class="uk-accordion-title">
|
||||
<div class="uk-flex uk-flex-top">
|
||||
<icon class="uk-text-warning" [flex]="true" name="warning" ratio="2"></icon>
|
||||
<div class="uk-margin-left">
|
||||
<div class="uk-text-warning uk-text-default">{{message.records.length | number}} Records - {{message.description}}</div>
|
||||
<div class="uk-text-normal uk-text-xsmall uk-margin-small-top uk-flex">
|
||||
<div class="uk-text-italic uk-text-meta">Try:</div>
|
||||
<div class="uk-margin-small-left">
|
||||
<div class="uk-text-truncate">
|
||||
1. Lorem ipsum
|
||||
</div>
|
||||
<div class="uk-text-truncate">
|
||||
2. Lorem ipsum
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="uk-accordion-content">
|
||||
<hr>
|
||||
<div *ngFor="let record of message.records" class="uk-margin-medium-left">
|
||||
<!-- {Base OAI-PMH url}?verb=GetRecord&metadataPrefix={the metadata prefix for each rule*}&identifier={oai identifier, which you have}-->
|
||||
<!-- *-->
|
||||
<a [href]="jobResult.baseUrl + '?verb=GetRecord&metadataPrefix=' + guidelinesLabelToPrefix.get(jobResult.guidelines) + '&identifier=' + record" target="_blank" class="uk-margin-left">{{record}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</modal-alert>
|
||||
|
||||
<modal-alert #errorsModal large="true" (alertOutput)="errorsModalOpen=false" classTitle="uk-border-bottom">
|
||||
<div *ngIf="errorsModalOpen" class="uk-modal-body uk-height-min-medium uk-width-expand">
|
||||
<div *ngIf="errors.length == 0 && !internal_error">No errors available</div>
|
||||
<div *ngIf="internal_error" [class.uk-margin-medium-bottom]="errors.length > 0">
|
||||
<div class="uk-h6">Internal error</div>
|
||||
<div class="uk-alert uk-alert-danger">{{internal_error}}</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="errors.length > 0">
|
||||
<div class="uk-h6">Errors list ({{errors.length | number}} error<span *ngIf="errors.length > 1">s</span>)</div>
|
||||
<ul uk-accordion class="uk-accordion">
|
||||
<li *ngFor="let message of errors" class="accordion-danger uk-padding-small">
|
||||
<a class="uk-accordion-title">
|
||||
<div class="uk-flex uk-flex-top">
|
||||
<icon class="uk-text-danger" [flex]="true" name="cancel" ratio="2"></icon>
|
||||
<div class="uk-margin-left">
|
||||
<div class="uk-text-danger uk-text-default">{{message.records.length | number}} Records - {{message.description}}</div>
|
||||
<div class="uk-text-normal uk-text-xsmall uk-margin-small-top uk-flex">
|
||||
<div class="uk-text-italic uk-text-meta">Try:</div>
|
||||
<div class="uk-margin-small-left">
|
||||
<div class="uk-text-truncate">
|
||||
1. Lorem ipsum
|
||||
</div>
|
||||
<div class="uk-text-truncate">
|
||||
2. Lorem ipsum
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="uk-accordion-content">
|
||||
<hr>
|
||||
<div *ngFor="let record of message.records" class="uk-margin-medium-left">
|
||||
<a [href]="jobResult.baseUrl + '?verb=GetRecord&metadataPrefix=' + guidelinesLabelToPrefix.get(jobResult.guidelines) + '&identifier=' + record" target="_blank" class="uk-margin-left">{{record}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- <div *ngIf="currentRule.internal_error">Internal error: {{currentRule.internal_error}}</div>-->
|
||||
</div>
|
||||
</modal-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="jobResult" id="analysis-right-sidebar" class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-text-small">
|
||||
<div class="uk-sticky" uk-sticky="end: true" [attr.offset]="offset">
|
||||
<div class="uk-overflow-auto uk-height-1-1 uk-padding">
|
||||
<div class="uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="link" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Base url</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.baseUrl}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="jobResult.set" class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="workspaces" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Set</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.set}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="gavel" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Guidelines</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.guidelines}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-top">
|
||||
<icon name="today" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Started</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.startDate | date: 'yyyy-MM-dd, HH:mm:ss'}}</div>
|
||||
<div class="uk-text-meta uk-text-xsmall uk-margin-small-top"><span *ngIf="!jobResult.endDate">Not yet </span>Ended</div>
|
||||
<div *ngIf="jobResult.endDate" class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.endDate | date: 'yyyy-MM-dd, HH:mm:ss'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="schedule" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Duration</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default" [title]="jobResult.progress" [attr.uk-tooltip]="!jobResult.endDate ? 'cls: uk-active' : 'cls: uk-invisible'">
|
||||
<span *ngIf="jobDuration.years">{{jobDuration.years}} years</span>
|
||||
<span *ngIf="jobDuration.years && (jobDuration.months || jobDuration.days || jobDuration.hours || jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.months">{{jobDuration.months}} months</span>
|
||||
<span *ngIf="jobDuration.months && (jobDuration.days || jobDuration.hours || jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.days">{{jobDuration.days}} days</span>
|
||||
<span *ngIf="jobDuration.days && (jobDuration.hours || jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.hours">{{jobDuration.hours}} hours</span>
|
||||
<span *ngIf="jobDuration.hours && (jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.minutes">{{jobDuration.minutes}} minutes</span>
|
||||
<span *ngIf="jobDuration.minutes && jobDuration.seconds"> & </span>
|
||||
<span *ngIf="jobDuration.seconds">{{jobDuration.seconds}} seconds</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <hr class="uk-margin-medium-top uk-margin-medium-bottom">-->
|
||||
<!-- <div class="uk-flex uk-flex-middle">-->
|
||||
<!-- <div class="uk-progress-circle" [attr.percentage]="jobResult.score" [style]="'--percentage: '+jobResult.score"></div>-->
|
||||
<!-- <div class="uk-margin-left uk-width-expand">-->
|
||||
<!-- <div>Validation Score</div>-->
|
||||
<!-- <div class="uk-text-left uk-width-1-1">-->
|
||||
<!-- <a class="uk-display-inline-block uk-width-auto uk-button uk-button-text uk-text-normal uk-text-xsmall" target="_blank" [href]="">-->
|
||||
<!-- <div class="uk-text-truncate">Guidelines Compliance</div>-->
|
||||
<!-- </a>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-analysis [breadcrumbs]="breadcrumbs" [single]="false" [jobResult]="jobResult"
|
||||
[jobDuration]="jobDuration" [validationResult]="validationResult"
|
||||
[(warnings)]="warnings" [(errors)]="errors" [(internal_error)]="internal_error"
|
||||
(getWarningsClicked)="getWarnings($event)" (getErrorsClicked)="getErrors($event)"></app-analysis>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {ChangeDetectorRef, Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {UntypedFormGroup} from "@angular/forms";
|
||||
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
|
||||
import {OaipmhValidatorService} from "../../../services/oaipmh-validator.service";
|
||||
import {Subscriber} from "rxjs";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
|
@ -7,71 +6,31 @@ import {RulePerJob, Status} from "../../entities/RulePerJob";
|
|||
import {Issue} from "../../entities/Issue";
|
||||
import {JobResult} from "../../entities/JobResult";
|
||||
import {Breadcrumb} from "../../../openaire-library/utils/breadcrumbs/breadcrumbs.component";
|
||||
|
||||
export class Duration {
|
||||
years: number;
|
||||
months: number;
|
||||
days: number;
|
||||
hours: number;
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
}
|
||||
import {Duration} from "../../shared/analysis/analysis.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-oaipmh-analysis',
|
||||
templateUrl: './oaipmh-analysis.component.html',
|
||||
styleUrls: ['./oaipmh-analysis.component.less']
|
||||
templateUrl: './oaipmh-analysis.component.html'
|
||||
})
|
||||
|
||||
export class OaipmhAnalysisComponent implements OnInit {
|
||||
public form: UntypedFormGroup;
|
||||
public jobResult: JobResult = null;
|
||||
public jobDuration: Duration = null;
|
||||
public validationResult: Map<string, { "analysisResult": RulePerJob[], "successfulAnalysisResult": RulePerJob[], "warningAnalysisResult": RulePerJob[], "failedAnalysisResult": RulePerJob[] }>;
|
||||
// public analysisResult: RulePerJob[] = [];
|
||||
// public successfulAnalysisResult: RulePerJob[] = [];
|
||||
// public warningAnalysisResult: RulePerJob[] = [];
|
||||
// public failedAnalysisResult: RulePerJob[] = [];
|
||||
public warningsModalOpen: boolean = false;
|
||||
public errorsModalOpen: boolean = false;
|
||||
public warnings: Issue[];
|
||||
public errors: Issue[];
|
||||
public internal_error: string;
|
||||
@ViewChild('warningsModal') warningsModal;
|
||||
@ViewChild('errorsModal') errorsModal;
|
||||
|
||||
public offset: number;
|
||||
|
||||
public jobId: string = "";
|
||||
public breadcrumbs: Breadcrumb[] = [{name: 'home', route: '/'}, {name: 'Validator\'s History', route: '/oaipmh-history'}, {name: 'Result for ...'}];
|
||||
|
||||
subscriptions = [];
|
||||
|
||||
public guidelinesLabelToPrefix: Map<string, string> = new Map([
|
||||
['OpenAIRE Guidelines for Literature Repositories Profile v4', 'oai_openaire'],
|
||||
['OpenAIRE Guidelines for Literature Repositories Profile v3', 'oai_dc'],
|
||||
['OpenAIRE Guidelines for Data Archives Profile v2', 'oai_datacite'],
|
||||
['OpenAIRE FAIR Guidelines for Data Repositories Profile', 'oai_datacite']
|
||||
]);
|
||||
|
||||
public requirementLevelMapping: Map<string, string> = new Map([
|
||||
["MANDATORY", "M"],
|
||||
["MANDATORY_IF_APPLICABLE", "MA"],
|
||||
["RECOMMENDED", "R"],
|
||||
["OPTIONAL", "O"]
|
||||
]);
|
||||
|
||||
|
||||
constructor(private route: ActivatedRoute, private cdr: ChangeDetectorRef, private validator: OaipmhValidatorService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscriptions.push(this.route.queryParams.subscribe(params => {
|
||||
this.jobId = params['jobId'];
|
||||
|
||||
// this.validationResult = new Map<string, {"analysisResult": RulePerJob[], "successfulAnalysisResult": RulePerJob[], "warningAnalysisResult": RulePerJob[], "failedAnalysisResult": RulePerJob[] }>;
|
||||
// this.analysisResult = [];
|
||||
// this.successfulAnalysisResult = [];
|
||||
// this.warningAnalysisResult = [];
|
||||
// this.failedAnalysisResult = [];
|
||||
this.jobResult = null;
|
||||
if(this.jobId) {
|
||||
this.getAnalysis();
|
||||
|
@ -80,16 +39,6 @@ export class OaipmhAnalysisComponent implements OnInit {
|
|||
}));
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (typeof document !== 'undefined') {
|
||||
if (document.getElementById("main-menu")) {
|
||||
this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
|
||||
} else {
|
||||
this.offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach(subscription => {
|
||||
if (subscription instanceof Subscriber) {
|
||||
|
@ -98,7 +47,6 @@ export class OaipmhAnalysisComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
public getAnalysis() {
|
||||
this.subscriptions.push(this.validator.getAnalysis(this.jobId).subscribe(
|
||||
(result: RulePerJob[]) => {
|
||||
|
@ -156,31 +104,11 @@ export class OaipmhAnalysisComponent implements OnInit {
|
|||
));
|
||||
}
|
||||
|
||||
public openWarningsModal(rule: RulePerJob) {
|
||||
this.warningsModalOpen = true;
|
||||
this.warningsModal.cancelButton = false;
|
||||
this.warningsModal.okButton = false;
|
||||
this.warningsModal.alertTitle = rule.ruleName;
|
||||
this.warningsModal.open();
|
||||
}
|
||||
|
||||
public openErrorsModal(rule: RulePerJob) {
|
||||
this.errorsModalOpen = true;
|
||||
this.errorsModal.cancelButton = false;
|
||||
this.errorsModal.okButton = false;
|
||||
this.errorsModal.alertTitle = rule.ruleName;
|
||||
this.errorsModal.open();
|
||||
}
|
||||
|
||||
getWarnings(rule: RulePerJob) {
|
||||
this.warnings = [];
|
||||
this.openWarningsModal(rule);
|
||||
this.warningsModalOpen = true;
|
||||
this.subscriptions.push(this.validator.getWarnings(this.jobId, rule.ruleName).subscribe(
|
||||
result => {
|
||||
this.warnings = result;
|
||||
console.log(result);
|
||||
// this.result = result;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -188,14 +116,10 @@ export class OaipmhAnalysisComponent implements OnInit {
|
|||
getErrors(rule: RulePerJob) {
|
||||
this.internal_error = rule.internal_error;
|
||||
this.errors = [];
|
||||
this.openErrorsModal(rule);
|
||||
this.errorsModalOpen = true;
|
||||
|
||||
if(rule.has_errors) {
|
||||
this.subscriptions.push(this.validator.getErrors(this.jobId, rule.ruleName).subscribe(
|
||||
result => {
|
||||
this.errors = result;
|
||||
console.log(result);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -220,13 +144,5 @@ export class OaipmhAnalysisComponent implements OnInit {
|
|||
));
|
||||
}
|
||||
|
||||
public getKeys(map) {
|
||||
return Array.from(map.keys());
|
||||
}
|
||||
|
||||
public getValues(map) {
|
||||
return Array.from(map.values());
|
||||
}
|
||||
|
||||
protected readonly Status = Status;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {OaipmhAnalysisRoutingModule} from "./oaipmh-analysis-routing.module";
|
||||
import {OaipmhAnalysisComponent} from "./oaipmh-analysis.component";
|
||||
import {AnalysisModule} from "../../shared/analysis/analysis.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule, RouterModule,
|
||||
OaipmhAnalysisRoutingModule, AnalysisModule
|
||||
],
|
||||
declarations: [
|
||||
OaipmhAnalysisComponent
|
||||
],
|
||||
providers: [],
|
||||
exports: [
|
||||
OaipmhAnalysisComponent
|
||||
]
|
||||
})
|
||||
export class OaipmhAnalysisModule {}
|
|
@ -0,0 +1,10 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { PreviousRouteRecorder } from "../../../openaire-library/utils/piwik/previousRouteRecorder.guard";
|
||||
import { OaipmhHistoryComponent } from "./oaipmh-history.component";
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([{ path: '', component: OaipmhHistoryComponent, canDeactivate: [PreviousRouteRecorder] }])
|
||||
]
|
||||
})
|
||||
export class OaipmhHistoryRoutingModule { }
|
|
@ -0,0 +1,22 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {OaipmhHistoryRoutingModule} from "./oaipmh-history-routing.module";
|
||||
import {OaipmhHistoryComponent} from "./oaipmh-history.component";
|
||||
import {BreadcrumbsModule} from "../../../openaire-library/utils/breadcrumbs/breadcrumbs.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule, RouterModule,
|
||||
OaipmhHistoryRoutingModule,
|
||||
BreadcrumbsModule
|
||||
],
|
||||
declarations: [
|
||||
OaipmhHistoryComponent
|
||||
],
|
||||
providers: [],
|
||||
exports: [
|
||||
OaipmhHistoryComponent
|
||||
]
|
||||
})
|
||||
export class OaipmhHistoryModule {}
|
|
@ -0,0 +1,10 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { PreviousRouteRecorder } from "../../../openaire-library/utils/piwik/previousRouteRecorder.guard";
|
||||
import { OaipmhValidatorComponent } from "./oaipmh-validator.component";
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([{ path: '', component: OaipmhValidatorComponent, canDeactivate: [PreviousRouteRecorder] }])
|
||||
]
|
||||
})
|
||||
export class OaipmhValidatorRoutingModule { }
|
|
@ -1,232 +1 @@
|
|||
<div>
|
||||
<!-- uk-blur-background-->
|
||||
<div class="">
|
||||
<div class="uk-grid uk-margin-remove-left" uk-grid>
|
||||
<!-- <div id="landing-center-content" class="uk-width-expand uk-padding-remove uk-background-default">-->
|
||||
<!-- <div class="uk-section uk-width-expand" [formGroup]="form">-->
|
||||
<div id="center-content" class="uk-width-2-3 uk-width-3-4@l" [formGroup]="form">
|
||||
<div class="uk-section uk-container uk-container-large">
|
||||
<div class="uk-margin-large-bottom">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">1.</span> Select a data source (repository or journal)</h6>
|
||||
<div input class="uk-width-xlarge uk-margin-xsmall-left uk-margin-medium-top" inputClass="flat x-small" [formInput]="form.get('url')"
|
||||
placeholder="Give the URL from one of your registered repositories" type="URL" (valueChange)="getSets()"></div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-large-bottom">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">2.</span> Select guidelines</h6>
|
||||
<div class="uk-margin-medium-top">
|
||||
<div *ngFor="let option of options" class="uk-margin-xsmall-left uk-margin-small-bottom">
|
||||
<input [id]="option.value" type="radio" [value]="option.value" name="guidelines" formControlName="guidelines">
|
||||
<label [for]="option.value" class="uk-margin-xsmall-left">{{option.label}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-large-bottom">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">3.</span> Define the number of records to validate</h6>
|
||||
<!-- <div class="uk-disabled uk-text-muted uk-margin-xsmall-left uk-margin-medium-top uk-margin-small-bottom">-->
|
||||
<!-- <input id="all" type="radio" name="recordsNum" value="-1" formControlName="recordsNum">-->
|
||||
<!-- <label for="all" class="uk-margin-xsmall-left">All</label>-->
|
||||
<!-- </div>-->
|
||||
<div class="uk-flex uk-flex-middle uk-margin-xsmall-left">
|
||||
<!-- <input #customRecordsNum id="custom" type="radio" name="recordsNum" [value]="recordsNum" formControlName="recordsNum">-->
|
||||
<!-- <label for="custom" class="uk-margin-xsmall-left uk-margin-right">-->
|
||||
<!-- Custom-->
|
||||
<!-- </label>-->
|
||||
<span class="uk-flex-inline uk-flex-middle">
|
||||
<icon class="clickable" name="remove_circle_outline" flex="true" ratio="0.9" type="outlined"
|
||||
[ngClass]="recordsNum <= 10 ? 'uk-disabled uk-text-muted' : ''" (click)="updateRecordsNum(false)"></icon>
|
||||
<span class="uk-margin-small-left uk-margin-small-right">{{recordsNum}}</span>
|
||||
<icon class="clickable" name="add_circle_outline" flex="true" ratio="0.9" type="outlined"
|
||||
[ngClass]="recordsNum >= 100 ? 'uk-disabled uk-text-muted' : ''" (click)="updateRecordsNum(true)"></icon>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div [disabled]="loadingSets || sets.length == 1" input type="select" placeholder="Select validation set" inputClass="flat x-small"
|
||||
[options]="sets" [formInput]="form.get('set')" class="uk-width-large uk-margin-medium-top uk-margin-xsmall-left"></div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-medium-top uk-margin-xsmall-left">
|
||||
<button class="uk-button uk-flex uk-flex-middle uk-flex-wrap"
|
||||
[class.uk-button-primary]="form.valid" [class.uk-disabled]="!form.valid"
|
||||
(click)="validate();">
|
||||
<span>Start Validation</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div id="right-sidebar" class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-background-primary">-->
|
||||
<!-- <div class="uk-sticky" uk-sticky [attr.offset]="offset">-->
|
||||
<!-- <div class="uk-overflow-auto uk-height-1-1">-->
|
||||
<!-- <div class="uk-h5 uk-light uk-text-center">Help</div>-->
|
||||
<!-- <div class="uk-card uk-card-default">-->
|
||||
<!-- <div class="uk-card-body">test body</div>-->
|
||||
<!-- <div class="uk-card-footer">Dismiss Help</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div id="right-sidebar" *ngIf="help"
|
||||
class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-text-small uk-visible@m uk-background-primary">
|
||||
<div class="uk-sticky" uk-sticky="end: true" [attr.offset]="offset">
|
||||
<div #right_sidebar class="uk-height-1-1">
|
||||
<div class="uk-height-1-1">
|
||||
<div #right_sidebar_header class="uk-section uk-section-small">
|
||||
<div class="uk-h5 uk-light uk-text-center">Help</div>
|
||||
</div>
|
||||
<div class="uk-card uk-card-default" [style]="'height: ' + right_sidebar_card_height + 'px;'">
|
||||
<div class="uk-overflow-auto uk-padding-remove-horizontal" [style]="'height: ' + right_sidebar_body_height + 'px;'">
|
||||
<div class="uk-card-body">
|
||||
<ul uk-accordion>
|
||||
<li class="uk-open">
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
1
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Data source</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>
|
||||
Select from the list, or enter the base OAI URL of the repository/ journal.
|
||||
The repository's/ journal's published sets are exposed in a later stage and you may select one for the compatibility tests.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
2
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Guidelines</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>You may apply two types of compatibility tests on your repository:</p>
|
||||
<ul>
|
||||
<li>Content: specific to the content/ format of the dc fields</li>
|
||||
<li>Usage: specific to the implementation of OAI-PMH</li>
|
||||
</ul>
|
||||
<p>You may select from a predefined set of rules (OpenAIRE for Literature Repositories, OpenAIRE for Data Archives) or customize them according to your needs.</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
3
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Parameters</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>
|
||||
...
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a #right_sidebar_footer uk-sticky="end: true" class="uk-sticky uk-card-footer uk-button-link uk-text-center" (click)="help=false">Dismiss Help</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="!help" class="quick-contact uk-align-right uk-padding uk-padding-remove-vertical">
|
||||
<button class="uk-button uk-box-shadow-default uk-box-shadow-default-hover uk-button-secondary uk-flex uk-flex-middle"
|
||||
(click)="openHelp();">
|
||||
<icon name="lightbulb" [flex]="true"></icon>
|
||||
<span class="uk-margin-small-left">help</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--<div id="tm-main" class="uk-visible@m landing uk-section uk-padding-remove tm-middle">-->
|
||||
<!-- <div class="tm-main">-->
|
||||
<!-- <div class="publication">-->
|
||||
<!-- <div class="uk-grid uk-margin-remove-left" uk-grid>-->
|
||||
<!-- <div id="center-content" class="uk-width-expand uk-padding-remove uk-background-default">-->
|
||||
<!-- <div class="uk-heading-2xlarge">-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- <ng-container >-->
|
||||
<!-- <div id="right-sidebar" class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-text-small uk-visible@m">-->
|
||||
<!-- <div class="uk-sticky" uk-sticky="bottom: true" [attr.offset]="offset">-->
|
||||
<!-- <div class="uk-overflow-auto uk-height-1-1">-->
|
||||
<!-- test-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </ng-container>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!--</div>-->
|
||||
|
||||
|
||||
<!--<div id="tm-main" class="uk-visible@m landing uk-section uk-padding-remove tm-middle">-->
|
||||
<!-- <div class="tm-main">-->
|
||||
<!-- <div class="">-->
|
||||
<!-- <div class="uk-grid uk-margin-remove-left" uk-grid>-->
|
||||
<!-- <div id="center-content" class="uk-width-2-3 uk-width-3-4@l">-->
|
||||
<!-- <div class="uk-heading-2xlarge">-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- <div>test</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div id="right-sidebar" class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-background-primary">-->
|
||||
<!-- <div class="uk-sticky" uk-sticky [attr.offset]="offset">-->
|
||||
<!-- <div class="uk-overflow-auto uk-height-1-1">-->
|
||||
<!-- <div class="uk-h5 uk-light uk-text-center">Help</div>-->
|
||||
<!-- <div class="uk-card uk-card-default">-->
|
||||
<!-- <div class="uk-card-body">test body</div>-->
|
||||
<!-- <div class="uk-card-footer">Dismiss Help</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!--</div>-->
|
||||
<app-settings [single]="false" [sets]="sets" (getSetsClicked)="getSets($event)" (validationClicked)="validate($event)"></app-settings>
|
||||
|
|
|
@ -1,67 +1,29 @@
|
|||
import {ChangeDetectorRef, Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
|
||||
import {Router} from "@angular/router";
|
||||
import {Subscriber} from "rxjs";
|
||||
import {OaipmhValidatorService} from "../../../services/oaipmh-validator.service";
|
||||
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
|
||||
import {Option} from "../../../openaire-library/sharedComponents/input/input.component";
|
||||
import {StringUtils} from "../../../openaire-library/utils/string-utils.class";
|
||||
import {JobResult} from "../../entities/JobResult";
|
||||
import {Router} from "@angular/router";
|
||||
import {Subscriber} from "rxjs";
|
||||
|
||||
declare var UIkit: any;
|
||||
|
||||
@Component({
|
||||
selector: 'app-oaipmh-validator',
|
||||
templateUrl: './oaipmh-validator.component.html',
|
||||
styleUrls: ['./oaipmh-validator.component.less']
|
||||
templateUrl: './oaipmh-validator.component.html'
|
||||
})
|
||||
|
||||
export class OaipmhValidatorComponent implements OnInit {
|
||||
@ViewChild("right_sidebar") right_sidebar;
|
||||
@ViewChild("right_sidebar_header") right_sidebar_header;
|
||||
@ViewChild("right_sidebar_footer") right_sidebar_footer;
|
||||
|
||||
public options: Option[] = [
|
||||
{label: 'OpenAIRE Guidelines for Data Archives Profile v2 & OpenAIRE FAIR Guidelines for Data Repositories Profile', value: 'OpenAIRE Guidelines for Data Archives Profile v2'},
|
||||
{label: 'OpenAIRE Guidelines for Literature Repositories Profile v3', value: 'OpenAIRE Guidelines for Literature Repositories Profile v3'},
|
||||
{label: 'OpenAIRE Guidelines for Literature Repositories Profile v4 & OpenAIRE FAIR Guidelines for Literature Profile', value: 'OpenAIRE Guidelines for Literature Repositories Profile v4'},
|
||||
{label: 'OpenAIRE FAIR Guidelines for Data Repositories Profile', value: 'OpenAIRE FAIR Guidelines for Data Repositories Profile'}
|
||||
];
|
||||
@ViewChild('customRecordsNum') customRecordsNum;
|
||||
public form: UntypedFormGroup;
|
||||
public sets: Option[] = [{label: 'All sets', value: 'all'}];
|
||||
public recordsNum: number = 10;
|
||||
public loadingSets: boolean = false;
|
||||
|
||||
public offset: number = 0;
|
||||
public help: boolean = false;
|
||||
|
||||
public right_sidebar_body_height: number = 0;
|
||||
public right_sidebar_card_height: number = 0;
|
||||
|
||||
subscriptions = [];
|
||||
|
||||
constructor(private fb: UntypedFormBuilder, private router: Router,
|
||||
constructor(private router: Router,
|
||||
private cdr: ChangeDetectorRef,
|
||||
private validator: OaipmhValidatorService) {
|
||||
this.form = this.fb.group({
|
||||
url: this.fb.control("", [Validators.required, StringUtils.urlValidator()]),//[Validators.required/*, Validators.email*/]),
|
||||
guidelines: this.fb.control("", Validators.required),
|
||||
recordsNum: this.fb.control(this.recordsNum, Validators.required),
|
||||
set: this.fb.control('all', Validators.required)
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (typeof document !== 'undefined') {
|
||||
if(document.getElementById("main-menu")) {
|
||||
this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
|
||||
} else {
|
||||
this.offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach(subscription => {
|
||||
if (subscription instanceof Subscriber) {
|
||||
|
@ -70,51 +32,27 @@ export class OaipmhValidatorComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
openHelp() {
|
||||
this.help = true;
|
||||
this.cdr.detectChanges();
|
||||
if (typeof document !== 'undefined') {
|
||||
console.log(this.right_sidebar.nativeElement.offsetHeight);
|
||||
console.log(this.right_sidebar_header.nativeElement.offsetHeight);
|
||||
console.log(this.right_sidebar_footer.nativeElement.offsetHeight);
|
||||
this.right_sidebar_card_height = this.right_sidebar.nativeElement.offsetHeight - this.right_sidebar_header.nativeElement.offsetHeight + 1;
|
||||
this.right_sidebar_body_height = this.right_sidebar_card_height - this.right_sidebar_footer.nativeElement.offsetHeight;
|
||||
}
|
||||
}
|
||||
|
||||
updateRecordsNum(increase: boolean = true) {
|
||||
this.recordsNum = this.recordsNum + (increase ? 10 : -10);
|
||||
this.form.get('recordsNum').setValue(this.recordsNum);
|
||||
if(this.customRecordsNum) {
|
||||
this.customRecordsNum.nativeElement.checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
getSets() {
|
||||
this.loadingSets = true;
|
||||
getSets(form) {
|
||||
let options: Option[] = [{label: 'All sets', value: 'all'}];
|
||||
if(this.form.get('setName')) {
|
||||
this.form.get('setName').setValue('all');
|
||||
if(form.get('setName')) {
|
||||
form.get('setName').setValue('all');
|
||||
}
|
||||
if(this.form.get('url') && this.form.get('url').value && StringUtils.isValidUrl(this.form.get('url').value)) {
|
||||
this.subscriptions.push(this.validator.getSets(this.form.get('url').value).subscribe(sets => {
|
||||
if(form.get('url') && form.get('url').value && StringUtils.isValidUrl(form.get('url').value)) {
|
||||
this.subscriptions.push(this.validator.getSets(form.get('url').value).subscribe(sets => {
|
||||
for(let set of sets) {
|
||||
options.push({label: set['setName'], value: set['setSpec']});
|
||||
}
|
||||
this.sets = options;
|
||||
this.loadingSets = false;
|
||||
}, error => {
|
||||
this.sets = options;
|
||||
this.loadingSets = false;
|
||||
}));
|
||||
} else {
|
||||
this.sets = options;
|
||||
this.loadingSets = false;
|
||||
}
|
||||
}
|
||||
|
||||
validate() {
|
||||
this.subscriptions.push(this.validator.validate(this.form.get('guidelines').value, this.form.get('url').value, this.form.get('recordsNum').value, this.form.get('set').value).subscribe(
|
||||
validate(form) {
|
||||
this.subscriptions.push(this.validator.validate(form.get('guidelines').value, form.get('url').value, form.get('recordsNum').value, form.get('set').value).subscribe(
|
||||
(result: JobResult) => {
|
||||
this.router.navigate(['/oaipmh-history'], {
|
||||
queryParams: { 'jobId': result.id }
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {OaipmhValidatorRoutingModule} from "./oaipmh-validator-routing.module";
|
||||
import {OaipmhValidatorComponent} from "./oaipmh-validator.component";
|
||||
import {SettingsModule} from "../../shared/settings/settings.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule, RouterModule,
|
||||
OaipmhValidatorRoutingModule, SettingsModule
|
||||
],
|
||||
declarations: [
|
||||
OaipmhValidatorComponent
|
||||
],
|
||||
providers: [],
|
||||
exports: [
|
||||
OaipmhValidatorComponent
|
||||
]
|
||||
})
|
||||
export class OaipmhValidatorModule {}
|
|
@ -0,0 +1,299 @@
|
|||
<ng-template #rules_analysis let-rules=rules>
|
||||
<div *ngIf="rules?.length == 0" class="uk-margin-medium-top uk-text-center">No rules available</div>
|
||||
<table *ngIf="rules?.length > 0" class="uk-margin-medium-top uk-table uk-table-middle uk-table-divider uk-table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="uk-width-auto uk-width-2-6@xl">Rule Name</th>
|
||||
<th class="uk-text-center uk-width-auto uk-width-1-6@xl">FAIR Principles</th>
|
||||
<th *ngIf="!single" class="uk-text-center uk-width-auto uk-width-1-6@xl">Success Rate</th>
|
||||
<th class="uk-text-center uk-width-small uk-width-1-6@xl">Status</th>
|
||||
<th class="uk-text-center uk-width-small uk-width-1-6@xl">Issues</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="uk-text-small">
|
||||
<tr *ngFor="let ruleResult of rules">
|
||||
<td>
|
||||
<div>
|
||||
<span *ngIf="!ruleResult.ruleName">[No title available]</span>
|
||||
<span *ngIf="ruleResult.ruleName">
|
||||
<a *ngIf="ruleResult.link" class="custom-external uk-link-text" [href]="ruleResult.link" target="_blank">{{ruleResult.ruleName}}</a>
|
||||
<span *ngIf="!ruleResult.link">{{ruleResult.ruleName}}</span>
|
||||
</span>
|
||||
<span *ngIf="ruleResult.requirement_level">
|
||||
<span> (</span>
|
||||
<ng-container *ngIf="requirementLevelMapping.has(ruleResult.requirement_level)">{{requirementLevelMapping.get(ruleResult.requirement_level)}}</ng-container>
|
||||
<ng-container *ngIf="!requirementLevelMapping.has(ruleResult.requirement_level)">{{ruleResult.requirement_level}}</ng-container>
|
||||
<span>)</span>
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="ruleResult.description" class="uk-text-small uk-text-meta">{{ruleResult.description}}</div>
|
||||
</td>
|
||||
<td class="uk-text-center uk-text-normal">
|
||||
<span *ngIf="ruleResult.fair_principles" [attr.uk-tooltip]="ruleResult.fair_principles_tooltip">{{ruleResult.fair_principles}}</span>
|
||||
<span *ngIf="!ruleResult.fair_principles">-</span>
|
||||
</td>
|
||||
<!-- <td class="uk-text-center">{{(ruleResult.rule_weight != undefined && ruleResult.rule_weight != null) ? ruleResult.rule_weight : '-'}}</td>-->
|
||||
<!-- <td class="uk-text-center">{{ruleResult.passed_records | number}}/{{(ruleResult.passed_records+ruleResult.failed_records) | number}}</td>-->
|
||||
<td *ngIf="!single">
|
||||
<div class="uk-text-xsmall">{{ruleResult.passed_records | number}}/{{jobResult.numberOfRecords | number}}</div>
|
||||
<div class="uk-text-center">
|
||||
<progress class="analysis-progress uk-progress uk-margin-remove-bottom" [value]="ruleResult.passed_records*100/jobResult.numberOfRecords" max="100"></progress>
|
||||
<div class="uk-text-center uk-text-xsmall uk-text-bolder uk-text-primary"
|
||||
style="position:relative; top: -18px; mix-blend-mode: color-burn">
|
||||
{{ruleResult.passed_records*100/jobResult.numberOfRecords}}%
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="uk-text-center">
|
||||
<span class="uk-label" [ngClass]="ruleResult.rule_status == Status.SUCCESS ? 'uk-label-success' : 'uk-label-danger'">{{ruleResult.rule_status}}</span>
|
||||
</td>
|
||||
<td class="uk-text-center">
|
||||
<a *ngIf="ruleResult.has_warnings" class="uk-text-warning" (click)="getWarnings(ruleResult)">Warnings</a>
|
||||
<div *ngIf="ruleResult.has_warnings && (ruleResult.has_errors || ruleResult.internal_error)">&</div>
|
||||
<a *ngIf="ruleResult.has_errors || ruleResult.internal_error" class="uk-text-danger" (click)="getErrors(ruleResult)">Errors</a>
|
||||
<!-- <div *ngIf="ruleResult.internal_error" class="uk-text-danger">error</div>-->
|
||||
<div *ngIf="!ruleResult.has_warnings && !ruleResult.has_errors && !ruleResult.internal_error">
|
||||
<icon class="uk-text-success" name="check" ratio="1"></icon>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ng-template>
|
||||
|
||||
<div id="page_content">
|
||||
<div id="page_content_header">
|
||||
<div class="analysis uk-grid uk-margin-remove-left" uk-grid>
|
||||
<div class="uk-width-expand uk-container uk-container-large">
|
||||
<div id="analysis-center-content" class="uk-width-expand uk-section uk-section-small uk-container uk-container-large">
|
||||
<breadcrumbs [breadcrumbs]="breadcrumbs"></breadcrumbs>
|
||||
|
||||
<div class="uk-margin-large-top">
|
||||
<h1 class="uk-h5">Validation Result Analysis</h1>
|
||||
<hr>
|
||||
|
||||
<div *ngIf="!validationResult || validationResult.size == 0" class="uk-alert uk-alert-primary">
|
||||
No validated metadata record yet
|
||||
</div>
|
||||
<div *ngIf="validationResult?.size > 0">
|
||||
<ul uk-tab>
|
||||
<li *ngFor="let result of getKeys(validationResult)" class="uk-width-auto@l uk-width-medium">
|
||||
<a><span class="uk-text-truncate" [attr.uk-tooltip]="result">{{result}}</span></a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="uk-switcher uk-margin">
|
||||
<li *ngFor="let result of getValues(validationResult)">
|
||||
<ul class="uk-subnav uk-subnav-pill-alt uk-margin" uk-switcher>
|
||||
<li class="uk-active"><a>All Rules ({{result.analysisResult.length | number}})</a></li>
|
||||
<li><a>Successful ({{result.successfulAnalysisResult.length | number}})</a></li>
|
||||
<li><a>Warnings ({{result.warningAnalysisResult.length | number}})</a></li>
|
||||
<li><a>Failed ({{result.failedAnalysisResult.length | number}})</a></li>
|
||||
</ul>
|
||||
<ul class="uk-switcher uk-margin">
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.analysisResult}"></ng-container>
|
||||
</li>
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.successfulAnalysisResult}"></ng-container>
|
||||
</li>
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.warningAnalysisResult}"></ng-container>
|
||||
</li>
|
||||
<li>
|
||||
<ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.failedAnalysisResult}"></ng-container>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- <h6>Validation Result Analysis</h6>-->
|
||||
</div>
|
||||
|
||||
<modal-alert #warningsModal large="true" (alertOutput)="warningsModalOpen=false" classTitle="uk-border-bottom">
|
||||
<div *ngIf="warningsModalOpen" class="uk-modal-body uk-height-min-medium uk-width-expand">
|
||||
<div *ngIf="warnings.length == 0">No warnings available</div>
|
||||
<div *ngIf="warnings.length > 0">
|
||||
<div class="uk-h6">Warnings list ({{warnings.length | number}} warning<span *ngIf="warnings.length > 1">s</span>)</div>
|
||||
<ul uk-accordion class="uk-accordion">
|
||||
<li *ngFor="let message of warnings" class="accordion-warning uk-padding-small">
|
||||
<div [class]="message.records ? 'uk-link uk-accordion-title' : 'uk-text-emphasis'">
|
||||
<div class="uk-flex uk-flex-top">
|
||||
<icon class="uk-text-warning" [flex]="true" name="warning" ratio="2"></icon>
|
||||
<div class="uk-margin-left">
|
||||
<div class="uk-text-warning uk-text-bold uk-text-default"><ng-container *ngIf="message.records">{{message.records.length | number}} Records - </ng-container>{{message.description}}</div>
|
||||
<div class="uk-text-normal uk-text-xsmall uk-margin-small-top uk-flex">
|
||||
<div class="uk-text-italic uk-text-meta">Try:</div>
|
||||
<div class="uk-margin-small-left">
|
||||
<div class="uk-text-truncate">
|
||||
1. Lorem ipsum
|
||||
</div>
|
||||
<div class="uk-text-truncate">
|
||||
2. Lorem ipsum
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="message.records" class="uk-accordion-content">
|
||||
<hr>
|
||||
<div *ngFor="let record of message.records" class="uk-margin-medium-left">
|
||||
<!-- {Base OAI-PMH url}?verb=GetRecord&metadataPrefix={the metadata prefix for each rule*}&identifier={oai identifier, which you have}-->
|
||||
<!-- *-->
|
||||
<a [href]="jobResult.baseUrl + '?verb=GetRecord&metadataPrefix=' + guidelinesLabelToPrefix.get(jobResult.guidelines) + '&identifier=' + record" target="_blank" class="uk-margin-left">{{record}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</modal-alert>
|
||||
|
||||
<modal-alert #errorsModal large="true" (alertOutput)="errorsModalOpen=false" classTitle="uk-border-bottom">
|
||||
<div *ngIf="errorsModalOpen" class="uk-modal-body uk-height-min-medium uk-width-expand">
|
||||
<div *ngIf="errors.length == 0 && !internal_error">No errors available</div>
|
||||
<div *ngIf="internal_error" [class.uk-margin-medium-bottom]="errors.length > 0">
|
||||
<div class="uk-h6">Internal error</div>
|
||||
<div class="uk-alert uk-alert-danger">{{internal_error}}</div>
|
||||
</div>
|
||||
<div *ngIf="errors.length > 0">
|
||||
<div class="uk-h6">Errors list ({{errors.length | number}} error<span *ngIf="errors.length > 1">s</span>)</div>
|
||||
<ul uk-accordion class="uk-accordion">
|
||||
<li *ngFor="let message of errors" class="accordion-danger uk-padding-small">
|
||||
<div [class]="message.records ? 'uk-link uk-accordion-title' : 'uk-text-emphasis'">
|
||||
<div class="uk-flex uk-flex-top">
|
||||
<icon class="uk-text-danger" [flex]="true" name="cancel" ratio="2"></icon>
|
||||
<div class="uk-margin-left">
|
||||
<div class="uk-text-danger uk-text-bold uk-text-default"><ng-container *ngIf="message.records">{{message.records.length | number}} Records - </ng-container>{{message.description}}</div>
|
||||
<div class="uk-text-normal uk-text-xsmall uk-margin-small-top uk-flex">
|
||||
<div class="uk-text-italic uk-text-meta">Try:</div>
|
||||
<div class="uk-margin-small-left">
|
||||
<div class="uk-text-truncate">
|
||||
1. Lorem ipsum
|
||||
</div>
|
||||
<div class="uk-text-truncate">
|
||||
2. Lorem ipsum
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="message.records" class="uk-accordion-content">
|
||||
<hr>
|
||||
<div *ngFor="let record of message.records" class="uk-margin-medium-left">
|
||||
<a [href]="jobResult.baseUrl + '?verb=GetRecord&metadataPrefix=' + guidelinesLabelToPrefix.get(jobResult.guidelines) + '&identifier=' + record" target="_blank" class="uk-margin-left">{{record}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- <div *ngIf="currentRule.internal_error">Internal error: {{currentRule.internal_error}}</div>-->
|
||||
</div>
|
||||
</modal-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="jobResult" id="analysis-right-sidebar" class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-text-small">
|
||||
<div class="uk-sticky" uk-sticky="end: true" [attr.offset]="offset">
|
||||
<div class="uk-overflow-auto uk-height-1-1 uk-padding">
|
||||
<div *ngIf="jobResult.baseUrl" class="uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="link" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Base url</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.baseUrl}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="jobResult.xml" class="uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="code" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Xml metadata record</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default multi-line-ellipsis lines-3">
|
||||
<p>{{jobResult.xml}}</p>
|
||||
</div>
|
||||
<a class="uk-link" (click)="openXmlModal()">View xml record</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal-alert #xmlModal large="true" (alertOutput)="xmlModalOpen=false" classTitle="uk-border-bottom">
|
||||
<div *ngIf="xmlModalOpen" class="uk-modal-body uk-height-min-medium uk-width-expand">
|
||||
<pre>{{jobResult.xml}}</pre>
|
||||
</div>
|
||||
</modal-alert>
|
||||
</div>
|
||||
|
||||
<div *ngIf="jobResult.set" class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="workspaces" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Set</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.set}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="gavel" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Guidelines</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.guidelines}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-top">
|
||||
<icon name="today" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Started</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.startDate | date: 'yyyy-MM-dd, HH:mm:ss'}}</div>
|
||||
<div class="uk-text-meta uk-text-xsmall uk-margin-small-top"><span *ngIf="!jobResult.endDate">Not yet </span>Ended</div>
|
||||
<div *ngIf="jobResult.endDate" class="uk-text-primary uk-text-bold uk-text-default">{{jobResult.endDate | date: 'yyyy-MM-dd, HH:mm:ss'}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="hasDuration" class="uk-margin-top uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-card-small">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon name="schedule" ratio="1.2" class="uk-text-background"></icon>
|
||||
<div class="uk-margin-left uk-width-expand uk-text-break">
|
||||
<div class="uk-text-meta uk-text-xsmall">Duration</div>
|
||||
<div class="uk-text-primary uk-text-bold uk-text-default" [title]="jobResult.progress" [attr.uk-tooltip]="!jobResult.endDate ? 'cls: uk-active' : 'cls: uk-invisible'">
|
||||
<span *ngIf="jobDuration.years">{{jobDuration.years}} years</span>
|
||||
<span *ngIf="jobDuration.years && (jobDuration.months || jobDuration.days || jobDuration.hours || jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.months">{{jobDuration.months}} months</span>
|
||||
<span *ngIf="jobDuration.months && (jobDuration.days || jobDuration.hours || jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.days">{{jobDuration.days}} days</span>
|
||||
<span *ngIf="jobDuration.days && (jobDuration.hours || jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.hours">{{jobDuration.hours}} hours</span>
|
||||
<span *ngIf="jobDuration.hours && (jobDuration.minutes || jobDuration.seconds)"> & </span>
|
||||
<span *ngIf="jobDuration.minutes">{{jobDuration.minutes}} minutes</span>
|
||||
<span *ngIf="jobDuration.minutes && jobDuration.seconds"> & </span>
|
||||
<span *ngIf="jobDuration.seconds">{{jobDuration.seconds}} seconds</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,132 @@
|
|||
import {Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
|
||||
import {JobResult} from "../../entities/JobResult";
|
||||
import {RulePerJob, Status} from "../../entities/RulePerJob";
|
||||
import {Issue} from "../../entities/Issue";
|
||||
import {Breadcrumb} from "../../../openaire-library/utils/breadcrumbs/breadcrumbs.component";
|
||||
|
||||
export class Duration {
|
||||
years: number;
|
||||
months: number;
|
||||
days: number;
|
||||
hours: number;
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-analysis',
|
||||
templateUrl: './analysis.component.html',
|
||||
styleUrls: ['./analysis.component.less']
|
||||
})
|
||||
export class AnalysisComponent {
|
||||
@Input() single: boolean = true;
|
||||
@Input() jobResult: JobResult = null;
|
||||
@Input() jobDuration: Duration = null;
|
||||
@Input() validationResult: Map<string, { "analysisResult": RulePerJob[], "successfulAnalysisResult": RulePerJob[], "warningAnalysisResult": RulePerJob[], "failedAnalysisResult": RulePerJob[] }>;
|
||||
@Input() breadcrumbs: Breadcrumb[];
|
||||
|
||||
@Input() warnings: Issue[];
|
||||
@Input() errors: Issue[];
|
||||
@Input() internal_error: string;
|
||||
@Output() warningsChange = new EventEmitter();
|
||||
@Output() errorsChange = new EventEmitter();
|
||||
@Output() internal_errorChange = new EventEmitter();
|
||||
@Output() getWarningsClicked = new EventEmitter();
|
||||
@Output() getErrorsClicked = new EventEmitter();
|
||||
|
||||
public warningsModalOpen: boolean = false;
|
||||
public errorsModalOpen: boolean = false;
|
||||
public xmlModalOpen: boolean = false;
|
||||
|
||||
@ViewChild('warningsModal') warningsModal;
|
||||
@ViewChild('errorsModal') errorsModal;
|
||||
@ViewChild('xmlModal') xmlModal;
|
||||
|
||||
public offset: number;
|
||||
|
||||
public guidelinesLabelToPrefix: Map<string, string> = new Map([
|
||||
['OpenAIRE Guidelines for Literature Repositories Profile v4', 'oai_openaire'],
|
||||
['OpenAIRE Guidelines for Literature Repositories Profile v3', 'oai_dc'],
|
||||
['OpenAIRE Guidelines for Data Archives Profile v2', 'oai_datacite'],
|
||||
['OpenAIRE FAIR Guidelines for Data Repositories Profile', 'oai_datacite']
|
||||
]);
|
||||
|
||||
public requirementLevelMapping: Map<string, string> = new Map([
|
||||
["MANDATORY", "M"],
|
||||
["MANDATORY_IF_APPLICABLE", "MA"],
|
||||
["RECOMMENDED", "R"],
|
||||
["OPTIONAL", "O"]
|
||||
]);
|
||||
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (typeof document !== 'undefined') {
|
||||
if (document.getElementById("main-menu")) {
|
||||
this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
|
||||
} else {
|
||||
this.offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public openWarningsModal(rule: RulePerJob) {
|
||||
this.warningsModalOpen = true;
|
||||
this.warningsModal.cancelButton = false;
|
||||
this.warningsModal.okButton = false;
|
||||
this.warningsModal.alertTitle = rule.ruleName;
|
||||
this.warningsModal.open();
|
||||
}
|
||||
|
||||
public openErrorsModal(rule: RulePerJob) {
|
||||
this.errorsModalOpen = true;
|
||||
this.errorsModal.cancelButton = false;
|
||||
this.errorsModal.okButton = false;
|
||||
this.errorsModal.alertTitle = rule.ruleName;
|
||||
this.errorsModal.open();
|
||||
}
|
||||
|
||||
public openXmlModal() {
|
||||
this.xmlModalOpen = true;
|
||||
this.xmlModal.cancelButton = false;
|
||||
this.xmlModal.okButton = false;
|
||||
this.xmlModal.alertTitle = "Xml metadata record";
|
||||
this.xmlModal.open();
|
||||
}
|
||||
|
||||
public getWarnings(rule: RulePerJob) {
|
||||
this.warnings = [];
|
||||
this.warningsChange.emit([]);
|
||||
this.openWarningsModal(rule);
|
||||
this.warningsModalOpen = true;
|
||||
this.getWarningsClicked.emit(rule);
|
||||
}
|
||||
|
||||
public getErrors(rule: RulePerJob) {
|
||||
this.errors = [];
|
||||
this.errorsChange.emit([]);
|
||||
this.internal_error = "";
|
||||
this.internal_errorChange.emit("");
|
||||
this.openErrorsModal(rule);
|
||||
this.errorsModalOpen = true;
|
||||
this.getErrorsClicked.emit(rule);
|
||||
}
|
||||
|
||||
public get hasDuration() {
|
||||
if(this.jobDuration && (this.jobDuration.years || this.jobDuration.months || this.jobDuration.days || this.jobDuration.hours || this.jobDuration.minutes || this.jobDuration.seconds)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public getKeys(map) {
|
||||
return Array.from(map.keys());
|
||||
}
|
||||
|
||||
public getValues(map) {
|
||||
return Array.from(map.values());
|
||||
}
|
||||
|
||||
protected readonly Status = Status;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {InputModule} from "../../../openaire-library/sharedComponents/input/input.module";
|
||||
import {AnalysisComponent} from "./analysis.component";
|
||||
import {BreadcrumbsModule} from "../../../openaire-library/utils/breadcrumbs/breadcrumbs.module";
|
||||
import {AlertModalModule} from "../../../openaire-library/utils/modal/alertModal.module";
|
||||
import {IconsModule} from "../../../openaire-library/utils/icons/icons.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule, FormsModule, RouterModule,
|
||||
ReactiveFormsModule, InputModule, BreadcrumbsModule,
|
||||
AlertModalModule, IconsModule,
|
||||
],
|
||||
declarations: [
|
||||
AnalysisComponent
|
||||
],
|
||||
providers: [],
|
||||
exports: [
|
||||
AnalysisComponent
|
||||
]
|
||||
})
|
||||
export class AnalysisModule {}
|
|
@ -0,0 +1,195 @@
|
|||
<div>
|
||||
<div class="">
|
||||
<div class="uk-grid uk-margin-remove-left" uk-grid>
|
||||
<div id="center-content" class="uk-width-2-3 uk-width-3-4@l" [formGroup]="form">
|
||||
<div class="uk-section uk-container uk-container-large">
|
||||
<div class="uk-margin-large-bottom">
|
||||
<ng-container *ngIf="!single">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">1.</span> Select a data source (repository or journal)</h6>
|
||||
<div input class="uk-width-xlarge uk-margin-xsmall-left uk-margin-medium-top" inputClass="flat x-small" [formInput]="form.get('url')"
|
||||
placeholder="Give the URL from one of your registered repositories" type="URL" (valueChange)="getSets()"></div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="single">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">1.</span> Metadata record</h6>
|
||||
<div input class="uk-width-xxlarge uk-margin-xsmall-left uk-margin-medium-top" [formInput]="form.get('xml')"
|
||||
placeholder="Paste your xml here" type="textarea" [rows]="15"></div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-large-bottom">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">2.</span> Select guidelines</h6>
|
||||
<div class="uk-margin-medium-top">
|
||||
<div *ngFor="let option of options" class="uk-margin-xsmall-left uk-margin-small-bottom">
|
||||
<input [id]="option.value" type="radio" [value]="option.value" name="guidelines" formControlName="guidelines">
|
||||
<label [for]="option.value" class="uk-margin-xsmall-left">{{option.label}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!single" class="uk-margin-large-bottom">
|
||||
<h6><span class="uk-text-secondary uk-margin-right">3.</span> Define the number of records to validate</h6>
|
||||
<!-- <div class="uk-disabled uk-text-muted uk-margin-xsmall-left uk-margin-medium-top uk-margin-small-bottom">-->
|
||||
<!-- <input id="all" type="radio" name="recordsNum" value="-1" formControlName="recordsNum">-->
|
||||
<!-- <label for="all" class="uk-margin-xsmall-left">All</label>-->
|
||||
<!-- </div>-->
|
||||
<div class="uk-flex uk-flex-middle uk-margin-xsmall-left">
|
||||
<!-- <input #customRecordsNum id="custom" type="radio" name="recordsNum" [value]="recordsNum" formControlName="recordsNum">-->
|
||||
<!-- <label for="custom" class="uk-margin-xsmall-left uk-margin-right">-->
|
||||
<!-- Custom-->
|
||||
<!-- </label>-->
|
||||
<span class="uk-flex-inline uk-flex-middle">
|
||||
<icon class="clickable" name="remove_circle_outline" flex="true" ratio="0.9" type="outlined"
|
||||
[ngClass]="recordsNum <= 10 ? 'uk-disabled uk-text-muted' : ''" (click)="updateRecordsNum(false)"></icon>
|
||||
<span class="uk-margin-small-left uk-margin-small-right">{{recordsNum}}</span>
|
||||
<icon class="clickable" name="add_circle_outline" flex="true" ratio="0.9" type="outlined"
|
||||
[ngClass]="recordsNum >= 100 ? 'uk-disabled uk-text-muted' : ''" (click)="updateRecordsNum(true)"></icon>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div [disabled]="!sets || sets.length <= 1" input type="select" placeholder="Select validation set" inputClass="flat x-small"
|
||||
[options]="sets" [formInput]="form.get('set')" class="uk-width-large uk-margin-medium-top uk-margin-xsmall-left"></div>
|
||||
</div>
|
||||
|
||||
<div class="uk-margin-medium-top uk-margin-xsmall-left">
|
||||
<button class="uk-button uk-flex uk-flex-middle uk-flex-wrap"
|
||||
[class.uk-button-primary]="form.valid" [class.uk-disabled]="!form.valid"
|
||||
(click)="validate();">
|
||||
<span>Start Validation</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="right-sidebar" *ngIf="help"
|
||||
class="uk-width-1-3 uk-width-1-4@l uk-padding-remove uk-text-small uk-visible@m uk-background-primary">
|
||||
<div class="uk-sticky" uk-sticky="end: true" [attr.offset]="offset">
|
||||
<div #right_sidebar class="uk-height-1-1">
|
||||
<div class="uk-height-1-1">
|
||||
<div #right_sidebar_header class="uk-section uk-section-small">
|
||||
<div class="uk-h5 uk-light uk-text-center">Help</div>
|
||||
</div>
|
||||
<div class="uk-card uk-card-default" [style]="'height: ' + right_sidebar_card_height + 'px;'">
|
||||
<div class="uk-overflow-auto uk-padding-remove-horizontal" [style]="'height: ' + right_sidebar_body_height + 'px;'">
|
||||
<div class="uk-card-body">
|
||||
<ul uk-accordion>
|
||||
<ng-container *ngIf="single">
|
||||
<li class="uk-open">
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
1
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Guidelines</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>You may apply two types of compatibility tests on your repository:</p>
|
||||
<ul>
|
||||
<li>Content: specific to the content/ format of the dc fields</li>
|
||||
<li>Usage: specific to the implementation of OAI-PMH</li>
|
||||
</ul>
|
||||
<p>You may select from a predefined set of rules (OpenAIRE for Literature Repositories, OpenAIRE for Data Archives) or customize them according to your needs.</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
2
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Paste xml metadata record</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>Paste your xml metadata record, which will be validated according to the selected guidelines.</p>
|
||||
</div>
|
||||
</li>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!single">
|
||||
<li class="uk-open">
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
1
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Data source</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>
|
||||
Select from the list, or enter the base OAI URL of the repository/ journal.
|
||||
The repository's/ journal's published sets are exposed in a later stage and you may select one for the compatibility tests.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
2
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Guidelines</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>You may apply two types of compatibility tests on your repository:</p>
|
||||
<ul>
|
||||
<li>Content: specific to the content/ format of the dc fields</li>
|
||||
<li>Usage: specific to the implementation of OAI-PMH</li>
|
||||
</ul>
|
||||
<p>You may select from a predefined set of rules (OpenAIRE for Literature Repositories, OpenAIRE for Data Archives) or customize them according to your needs.</p>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="uk-accordion-title uk-text-small uk-padding-small uk-padding-remove-vertical" href="#">
|
||||
<span class="accordion-title-num">
|
||||
<svg height="27" width="27">
|
||||
<circle cx="13" cy="13" r="13" stroke-width="1"></circle>
|
||||
<text x="50%" y="50%" text-anchor="middle" dy=".2em" font-size="12" font-weight="200">
|
||||
3
|
||||
</text>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="uk-margin-small-left">Select Parameters</span>
|
||||
</a>
|
||||
<div class="uk-accordion-content uk-text-small uk-padding-small uk-padding-remove-vertical">
|
||||
<p>
|
||||
...
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ng-container>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a #right_sidebar_footer uk-sticky="end: true" class="uk-sticky uk-card-footer uk-button-link uk-text-center" (click)="help=false">Dismiss Help</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="!help" class="quick-contact uk-align-right uk-padding uk-padding-remove-vertical">
|
||||
<button class="uk-button uk-box-shadow-default uk-box-shadow-default-hover uk-button-secondary uk-flex uk-flex-middle"
|
||||
(click)="openHelp();">
|
||||
<icon name="lightbulb" [flex]="true"></icon>
|
||||
<span class="uk-margin-small-left">help</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,94 @@
|
|||
import {ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
|
||||
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
|
||||
import {Router} from "@angular/router";
|
||||
import {Option} from "../../../openaire-library/sharedComponents/input/input.component";
|
||||
import {StringUtils} from "../../../openaire-library/utils/string-utils.class";
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
templateUrl: './settings.component.html',
|
||||
styleUrls: ['./settings.component.less']
|
||||
})
|
||||
export class SettingsComponent implements OnInit {
|
||||
@Input() single: boolean = true;
|
||||
@Input() sets: Option[] = [{label: 'All sets', value: 'all'}];
|
||||
@Output() validationClicked = new EventEmitter();
|
||||
@Output() getSetsClicked = new EventEmitter();
|
||||
|
||||
@ViewChild("right_sidebar") right_sidebar;
|
||||
@ViewChild("right_sidebar_header") right_sidebar_header;
|
||||
@ViewChild("right_sidebar_footer") right_sidebar_footer;
|
||||
|
||||
public right_sidebar_body_height: number = 0;
|
||||
public right_sidebar_card_height: number = 0;
|
||||
public offset: number = 0;
|
||||
public help: boolean = false;
|
||||
|
||||
public form: UntypedFormGroup;
|
||||
public recordsNum: number = 10;
|
||||
@ViewChild('customRecordsNum') customRecordsNum;
|
||||
|
||||
public options: Option[] = [
|
||||
{label: 'OpenAIRE Guidelines for Data Archives Profile v2 & OpenAIRE FAIR Guidelines for Data Repositories Profile', value: 'OpenAIRE Guidelines for Data Archives Profile v2'},
|
||||
{label: 'OpenAIRE Guidelines for Literature Repositories Profile v3', value: 'OpenAIRE Guidelines for Literature Repositories Profile v3'},
|
||||
{label: 'OpenAIRE Guidelines for Literature Repositories Profile v4 & OpenAIRE FAIR Guidelines for Literature Profile', value: 'OpenAIRE Guidelines for Literature Repositories Profile v4'},
|
||||
{label: 'OpenAIRE FAIR Guidelines for Data Repositories Profile', value: 'OpenAIRE FAIR Guidelines for Data Repositories Profile'}
|
||||
];
|
||||
|
||||
constructor(private fb: UntypedFormBuilder, private router: Router,
|
||||
private cdr: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if(this.single) {
|
||||
this.form = this.fb.group({
|
||||
guidelines: this.fb.control("", Validators.required),
|
||||
xml: this.fb.control('', Validators.required)
|
||||
});
|
||||
} else {
|
||||
this.form = this.fb.group({
|
||||
url: this.fb.control("", [Validators.required, StringUtils.urlValidator()]),//[Validators.required/*, Validators.email*/]),
|
||||
guidelines: this.fb.control("", Validators.required),
|
||||
recordsNum: this.fb.control(this.recordsNum, Validators.required),
|
||||
set: this.fb.control('all', Validators.required)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (typeof document !== 'undefined') {
|
||||
if(document.getElementById("main-menu")) {
|
||||
this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
|
||||
} else {
|
||||
this.offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {}
|
||||
|
||||
openHelp() {
|
||||
this.help = true;
|
||||
this.cdr.detectChanges();
|
||||
if (typeof document !== 'undefined') {
|
||||
this.right_sidebar_card_height = this.right_sidebar.nativeElement.offsetHeight - this.right_sidebar_header.nativeElement.offsetHeight + 1;
|
||||
this.right_sidebar_body_height = this.right_sidebar_card_height - this.right_sidebar_footer.nativeElement.offsetHeight;
|
||||
}
|
||||
}
|
||||
|
||||
updateRecordsNum(increase: boolean = true) {
|
||||
this.recordsNum = this.recordsNum + (increase ? 10 : -10);
|
||||
this.form.get('recordsNum').setValue(this.recordsNum);
|
||||
if(this.customRecordsNum) {
|
||||
this.customRecordsNum.nativeElement.checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
getSets() {
|
||||
this.getSetsClicked.emit(this.form);
|
||||
}
|
||||
|
||||
validate() {
|
||||
this.validationClicked.emit(this.form);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {InputModule} from "../../../openaire-library/sharedComponents/input/input.module";
|
||||
import {SettingsComponent} from "./settings.component";
|
||||
import {BreadcrumbsModule} from "../../../openaire-library/utils/breadcrumbs/breadcrumbs.module";
|
||||
import {IconsModule} from "../../../openaire-library/utils/icons/icons.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule, FormsModule, RouterModule,
|
||||
ReactiveFormsModule, InputModule, BreadcrumbsModule,
|
||||
IconsModule
|
||||
],
|
||||
declarations: [
|
||||
SettingsComponent
|
||||
],
|
||||
providers: [],
|
||||
exports: [
|
||||
SettingsComponent
|
||||
]
|
||||
})
|
||||
export class SettingsModule {}
|
|
@ -0,0 +1,10 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import {PreviousRouteRecorder} from "../../openaire-library/utils/piwik/previousRouteRecorder.guard";
|
||||
import { SingleRecordValidatorComponent } from "./single-record-validator.component";
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([{ path: '', component: SingleRecordValidatorComponent, canDeactivate: [PreviousRouteRecorder] }])
|
||||
]
|
||||
})
|
||||
export class SingleRecordValidatorRoutingModule { }
|
|
@ -1,154 +1,6 @@
|
|||
<ng-template #rules_analysis let-rules=rules>
|
||||
<table class="uk-table uk-table-striped">
|
||||
<thead>
|
||||
<tr class="uk-child-width-1-3">
|
||||
<th>Rule Name</th>
|
||||
<th class="uk-text-center">Score</th>
|
||||
<th class="uk-text-center">Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let ruleResult of rules">
|
||||
<td>
|
||||
<div>{{ruleResult.name ? ruleResult.name : '-'}}</div>
|
||||
<div *ngIf="ruleResult.description" class="uk-text-small uk-text-meta">{{ruleResult.description}}</div>
|
||||
</td>
|
||||
<td class="uk-text-center">{{(ruleResult.score != undefined && ruleResult.score != null) ? ruleResult.score : '-'}}</td>
|
||||
<td class="uk-text-center">
|
||||
<ng-container *ngIf="!ruleResult.status">-</ng-container>
|
||||
<ng-container *ngIf="ruleResult.status">
|
||||
<div *ngIf="(!ruleResult.errors || ruleResult.errors.length == 0) &&
|
||||
(!ruleResult.warnings || ruleResult.warnings.length == 0) &&
|
||||
(!ruleResult.internalError)" class="uk-text-success">{{ruleResult.status}}</div>
|
||||
<a *ngIf="ruleResult.warnings?.length > 0 || ruleResult.errors?.length > 0 || ruleResult.internalError" (click)="openMessagesModal(ruleResult)">
|
||||
<div *ngIf="ruleResult.warnings?.length > 0" class="uk-text-warning">warnings</div>
|
||||
<div *ngIf="ruleResult.errors?.length > 0" class="uk-text-danger">errors</div>
|
||||
<div *ngIf="ruleResult.internalError" class="uk-text-danger">error</div>
|
||||
</a>
|
||||
</ng-container>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ng-template>
|
||||
<app-settings *ngIf="!viewResults" (validationClicked)="validate($event)"></app-settings>
|
||||
|
||||
<div id="page_content">
|
||||
<div id="page_content_header" class="uk-blur-background" offset="65">
|
||||
<div class="uk-container uk-container-large">
|
||||
<div class="uk-section" [formGroup]="form">
|
||||
<ng-container *ngIf="!viewResults">
|
||||
<h6>1. Select guidelines (*)</h6>
|
||||
<div *ngFor="let option of options">
|
||||
<input [id]="option.value" type="radio" [value]="option.value" name="guidelines" formControlName="guidelines">
|
||||
<label [for]="option.value"> {{option.label}}</label>
|
||||
</div>
|
||||
|
||||
<h6>2. Paste metadata record (*)</h6>
|
||||
<div input class="uk-width-1-1 uk-margin-top" [formInput]="form.get('xml')" placeholder="Paste your xml here" type="textarea" [rows]="15"></div>
|
||||
|
||||
<!-- <ngx-dropzone #drop class="" (change)="fileChangeEvent($event, true)"-->
|
||||
<!-- [multiple]="false" [accept]="xml">-->
|
||||
<!-- <ngx-dropzone-preview *ngIf="form.value.value && form.value.value.name" class="file-preview"-->
|
||||
<!-- [removable]="true" (removed)="onRemove()">-->
|
||||
<!-- <ngx-dropzone-label class="file-label">{{ form.value.value.name }}</ngx-dropzone-label>-->
|
||||
<!-- </ngx-dropzone-preview>-->
|
||||
<!-- </ngx-dropzone>-->
|
||||
<!-- <button *ngIf="!form.value.value || filesToUpload" mat-button (click)="drop.showFileSelector()" type="button" class="attach-file-btn"-->
|
||||
<!-- [disabled]="!!form.value.value">-->
|
||||
<!-- <mat-icon class="mr-2">upload</mat-icon>-->
|
||||
<!-- <mat-label>{{ (form.get('data').value.label | translate)}}</mat-label>-->
|
||||
<!-- </button>-->
|
||||
|
||||
<div class="uk-margin-medium-top">
|
||||
<button class="uk-button uk-flex uk-flex-middle uk-flex-wrap"
|
||||
[class.uk-button-primary]="form.valid" [class.uk-disabled]="!form.valid"
|
||||
(click)="validate(); viewResults=true">
|
||||
<span class="uk-margin-small-left">Start Validation</span>
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="viewResults">
|
||||
<button class="uk-button uk-button-link uk-flex uk-flex-middle uk-margin-bottom" (click)="viewResults = false">
|
||||
<icon name="west" [flex]="true"></icon>
|
||||
<span class="uk-margin-small-left">Back</span>
|
||||
</button>
|
||||
|
||||
<div *ngIf="!result" class="uk-alert uk-alert-primary">
|
||||
No validated metadata record yet
|
||||
</div>
|
||||
|
||||
<div *ngIf="result">
|
||||
<h6>Validator's History</h6>
|
||||
<table class="uk-table uk-table-striped">
|
||||
<thead>
|
||||
<tr class="uk-child-width-1-4">
|
||||
<th *ngIf="result.validationScore">Validation Score</th>
|
||||
<th *ngIf="result.fairScore" class="uk-text-center">Fair Score</th>
|
||||
<th class="uk-text-center">Guidelines</th>
|
||||
<th class="uk-text-center">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td *ngIf="result.validationScore" [class.uk-text-center]="!result.validationScore">{{result.validationScore ? result.validationScore : '-'}}</td>
|
||||
<td *ngIf="result.fairScore" class="uk-text-center">{{result.fairScore ? result.fairScore : '-'}}</td>
|
||||
<td class="uk-text-center">{{currentGuideline?.label}}</td>
|
||||
<td class="uk-flex uk-flex-center">
|
||||
<a class="uk-button-link uk-flex uk-flex-middle uk-flex-center" (click)="validationAnalysis=!validationAnalysis">
|
||||
<icon name="visibility" flex="true" class="uk-margin-small-right"></icon>
|
||||
<ng-container *ngIf="!validationAnalysis">View Results</ng-container>
|
||||
<ng-container *ngIf="validationAnalysis">Hide Results</ng-container>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div *ngIf="result && validationAnalysis" class="uk-margin-large-top">
|
||||
<ul uk-tab>
|
||||
<li *ngIf="result.validationScore"><a>Validation Result Analysis</a></li>
|
||||
<li *ngIf="result.fairScore"><a>Fair Validation Result Analysis</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="uk-switcher uk-margin">
|
||||
<li *ngIf="result.validationScore"><ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.rules}"></ng-container></li>
|
||||
<li *ngIf="result.fairScore"><ng-container *ngTemplateOutlet="rules_analysis; context: {rules: result.fairRules}"></ng-container></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- <h6>Validation Result Analysis</h6>-->
|
||||
</div>
|
||||
|
||||
<modal-alert #modal large="true" (alertOutput)="modalOpen=false">
|
||||
<div *ngIf="modalOpen" class="uk-modal-body uk-height-min-medium uk-width-expand">
|
||||
<div *ngIf="currentRule.warnings?.length > 0" class="uk-margin-bottom">
|
||||
<span class="uk-text-warning">Warnings</span>
|
||||
<div *ngFor="let message of currentRule.warnings">{{message}}</div>
|
||||
</div>
|
||||
<div *ngIf="currentRule.errors?.length > 0" class="uk-margin-bottom">
|
||||
<span class="uk-text-danger">Errors</span>
|
||||
<div *ngFor="let message of currentRule.errors">{{message}}</div>
|
||||
</div>
|
||||
<div *ngIf="currentRule.internalError">Internal error: {{currentRule.internalError}}</div>
|
||||
</div>
|
||||
</modal-alert>
|
||||
|
||||
<!-- <div class="uk-margin-top uk-section-muted uk-padding-small">-->
|
||||
<!-- Comments-->
|
||||
<!-- <ul class="uk-list uk-list-bullet">-->
|
||||
<!-- <li>returns success, not warning status</li>-->
|
||||
<!-- <li>what is the score?</li>-->
|
||||
<!-- <li>do we have rule weight?</li>-->
|
||||
<!-- <li>no description or user friendly name provided</li>-->
|
||||
<!-- <li>errors/ warning not user friendly</li>-->
|
||||
<!-- <li>can return errors & warnings</li>-->
|
||||
<!-- <li>on errors, only the 1st one is returned (this is what comments in code say)</li>-->
|
||||
<!-- </ul>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-analysis *ngIf="viewResults" [breadcrumbs]="breadcrumbs" [single]="true" [jobResult]="jobResult"
|
||||
[jobDuration]="jobDuration" [validationResult]="validationResult"
|
||||
[(warnings)]="warnings" [(errors)]="errors" [(internal_error)]="internal_error"
|
||||
(getWarningsClicked)="getWarnings($event)" (getErrorsClicked)="getErrors($event)"></app-analysis>
|
||||
|
|
|
@ -1,42 +1,62 @@
|
|||
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
|
||||
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
|
||||
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
|
||||
import {SingleRecordValidatorService} from "../../services/single-record-validator.service";
|
||||
import {RuleInfo} from "../entities/RuleInfo";
|
||||
import {XmlValidationResponse} from "../entities/XmlValidationResponse";
|
||||
import {Option} from "../../openaire-library/sharedComponents/input/input.component";
|
||||
import {RulePerJob, Status} from "../entities/RulePerJob";
|
||||
import {JobResult, Progress} from "../entities/JobResult";
|
||||
import {Breadcrumb} from "../../openaire-library/utils/breadcrumbs/breadcrumbs.component";
|
||||
import {Issue} from "../entities/Issue";
|
||||
import {Subscriber} from "rxjs";
|
||||
import {NavigationEnd, Router} from "@angular/router";
|
||||
import {Duration} from "../shared/analysis/analysis.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-single-record-validator',
|
||||
templateUrl: './single-record-validator.component.html',
|
||||
styleUrls: ['./single-record-validator.component.less']
|
||||
templateUrl: './single-record-validator.component.html'
|
||||
})
|
||||
|
||||
export class SingleRecordValidatorComponent implements OnInit {
|
||||
public options: Option[] = [
|
||||
{label: 'Data Archive Guidelines V2 Profile & FAIR Data Guidelines Profile', value: 'dataArchiveGuidelinesV2Profile'},
|
||||
{label: 'Literature Guidelines V3 Profile', value: 'literatureGuidelinesV3Profile'},
|
||||
{label: 'Literature Guidelines V4 Profile', value: 'literatureGuidelinesV4Profile'},
|
||||
{label: 'FAIR Data Guidelines Profile', value: 'fairDataGuidelinesProfile'}
|
||||
{label: 'OpenAIRE Guidelines for Data Archives Profile v2 & OpenAIRE FAIR Guidelines for Data Repositories Profile', value: 'OpenAIRE Guidelines for Data Archives Profile v2'},
|
||||
{label: 'OpenAIRE Guidelines for Literature Repositories Profile v3', value: 'OpenAIRE Guidelines for Literature Repositories Profile v3'},
|
||||
{label: 'OpenAIRE Guidelines for Literature Repositories Profile v4 & OpenAIRE FAIR Guidelines for Literature Profile', value: 'OpenAIRE Guidelines for Literature Repositories Profile v4'},
|
||||
{label: 'OpenAIRE FAIR Guidelines for Data Repositories Profile', value: 'OpenAIRE FAIR Guidelines for Data Repositories Profile'}
|
||||
];
|
||||
|
||||
public breadcrumbs: Breadcrumb[] = [{name: 'Single Record Validation', route: '/single-record-validate'}, {name: 'Result for ...'}];
|
||||
|
||||
public form: UntypedFormGroup;
|
||||
public result: XmlValidationResponse
|
||||
public modalOpen: boolean = false;
|
||||
public currentRule: RuleInfo;
|
||||
@ViewChild('modal') modal;
|
||||
public result: RulePerJob[];
|
||||
public jobResult: JobResult = null;
|
||||
public jobDuration: Duration = null;
|
||||
|
||||
public validationResult: Map<string, { "analysisResult": RulePerJob[], "successfulAnalysisResult": RulePerJob[], "warningAnalysisResult": RulePerJob[], "failedAnalysisResult": RulePerJob[] }>;
|
||||
|
||||
public viewResults: boolean = false;
|
||||
public validationAnalysis: boolean = true;
|
||||
|
||||
subscriptions = [];
|
||||
|
||||
constructor(private fb: UntypedFormBuilder, private validator: SingleRecordValidatorService) {
|
||||
this.form = this.fb.group({
|
||||
guidelines: this.fb.control("", Validators.required),
|
||||
xml: this.fb.control('', Validators.required)
|
||||
});
|
||||
}
|
||||
public warningsPerRule: Map<string, Issue[]>;
|
||||
public errorsPerRule: Map<string, Issue[]>;
|
||||
public warnings: Issue[];
|
||||
public errors: Issue[];
|
||||
public internal_error: string;
|
||||
|
||||
ngOnInit(): void {}
|
||||
constructor(private _router: Router, private fb: UntypedFormBuilder, private cdr: ChangeDetectorRef,
|
||||
private validator: SingleRecordValidatorService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscriptions.push(this._router.events.subscribe((event) => {
|
||||
if (event instanceof NavigationEnd) {
|
||||
// do some logic again when same url is clicked
|
||||
this.viewResults = false;
|
||||
this.result = [];
|
||||
this.jobResult = null;
|
||||
this.jobDuration = null;
|
||||
this.validationResult = null;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach(subscription => {
|
||||
|
@ -46,27 +66,106 @@ export class SingleRecordValidatorComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
public validate() {
|
||||
this.subscriptions.push(this.validator.validateRecord(this.form.get('xml')?.getRawValue(), this.form.get('guidelines')?.getRawValue()).subscribe(
|
||||
public validate(form) {
|
||||
this.viewResults = true;
|
||||
this.jobResult = new JobResult();
|
||||
this.jobResult.startDate = new Date();
|
||||
this.jobResult.progress = Progress.IN_PROGRESS;
|
||||
this.jobResult.guidelines = form.get("guidelines").getRawValue();
|
||||
this.jobResult.xml = form.get("xml").getRawValue();
|
||||
|
||||
this.subscriptions.push(this.validator.validateRecord(form.get('xml')?.getRawValue(), form.get('guidelines')?.getRawValue()).subscribe(
|
||||
result => {
|
||||
this.result = result;
|
||||
this.jobResult.endDate = new Date();
|
||||
this.jobResult.numberOfRecords = 1;
|
||||
this.jobResult.recordsTested = 1;
|
||||
this.jobResult.progress = Progress.COMPLETED;
|
||||
|
||||
this.jobDuration = new Duration();
|
||||
const msBetweenDates = this.jobResult.endDate.getTime() - this.jobResult.startDate.getTime();
|
||||
this.jobDuration.seconds = Math.ceil(msBetweenDates / 1000 % 60);
|
||||
this.jobDuration.minutes = Math.floor(msBetweenDates / 1000 / 60 % 60);
|
||||
this.jobDuration.hours = Math.floor(msBetweenDates / 1000 / 60 / 60 % 24);
|
||||
this.jobDuration.days = Math.floor(msBetweenDates / 1000 / 60 / 60 / 24);
|
||||
this.jobDuration.months = Math.floor(this.jobDuration.days / 31);
|
||||
this.jobDuration.years = Math.floor(this.jobDuration.months / 12);
|
||||
|
||||
this.result = result.summaryResults;
|
||||
let validationResult: Map<string, { "analysisResult": RulePerJob[], "successfulAnalysisResult": RulePerJob[], "warningAnalysisResult": RulePerJob[], "failedAnalysisResult": RulePerJob[] }> =
|
||||
new Map<string, {"analysisResult": RulePerJob[], "successfulAnalysisResult": RulePerJob[], "warningAnalysisResult": RulePerJob[], "failedAnalysisResult": RulePerJob[] }>;
|
||||
|
||||
for(let rulePerJob of result.summaryResults) {
|
||||
if(rulePerJob.fair_principles) {
|
||||
if(rulePerJob.fair_principles.includes("F")) {
|
||||
rulePerJob.fair_principles_tooltip = "Findable";
|
||||
}
|
||||
if(rulePerJob.fair_principles.includes("F") &&
|
||||
(rulePerJob.fair_principles.includes("A") || rulePerJob.fair_principles.includes("I") || rulePerJob.fair_principles.includes("R"))) {
|
||||
rulePerJob.fair_principles_tooltip += ", ";
|
||||
}
|
||||
if(rulePerJob.fair_principles.includes("A")) {
|
||||
rulePerJob.fair_principles_tooltip += "Accessible";
|
||||
}
|
||||
if(rulePerJob.fair_principles.includes("A") &&
|
||||
(rulePerJob.fair_principles.includes("I") || rulePerJob.fair_principles.includes("R"))) {
|
||||
rulePerJob.fair_principles_tooltip += ", ";
|
||||
}
|
||||
if(rulePerJob.fair_principles.includes("I")) {
|
||||
rulePerJob.fair_principles_tooltip += "Interoperable";
|
||||
}
|
||||
if(rulePerJob.fair_principles.includes("I") && rulePerJob.fair_principles.includes("R")) {
|
||||
rulePerJob.fair_principles_tooltip += ", ";
|
||||
}
|
||||
if(rulePerJob.fair_principles.includes("R")) {
|
||||
rulePerJob.fair_principles_tooltip += "Reusable";
|
||||
}
|
||||
}
|
||||
|
||||
if(rulePerJob.issues) {
|
||||
for(let issue of rulePerJob.issues) {
|
||||
if(issue.issueType == "WARNING") {
|
||||
if(this.warningsPerRule == null) {
|
||||
this.warningsPerRule = new Map<string, Issue[]>();
|
||||
}
|
||||
if(!this.warningsPerRule.has(issue.ruleName)) {
|
||||
this.warningsPerRule.set(issue.ruleName, new Array<Issue>());
|
||||
}
|
||||
this.warningsPerRule.get(issue.ruleName).push({description: issue.issueText, records: null});
|
||||
} else if(issue.issueType == "ERROR") {
|
||||
if(this.errorsPerRule == null) {
|
||||
this.errorsPerRule = new Map<string, Issue[]>();
|
||||
}
|
||||
if(!this.errorsPerRule.has(issue.ruleName)) {
|
||||
this.errorsPerRule.set(issue.ruleName, new Array<Issue>());
|
||||
}
|
||||
this.errorsPerRule.get(issue.ruleName).push({description: issue.issueText, records: null});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!validationResult.has(rulePerJob.guidelines)) {
|
||||
validationResult.set(rulePerJob.guidelines, {analysisResult: [], successfulAnalysisResult: [], warningAnalysisResult: [], failedAnalysisResult: []});
|
||||
}
|
||||
|
||||
validationResult.get(rulePerJob.guidelines).analysisResult.push(rulePerJob);
|
||||
|
||||
if(rulePerJob.rule_status == Status.FAILURE || rulePerJob.rule_status == Status.ERROR) {
|
||||
validationResult.get(rulePerJob.guidelines).failedAnalysisResult.push(rulePerJob);
|
||||
} else {
|
||||
if(rulePerJob.has_warnings || rulePerJob.has_errors || rulePerJob.internal_error) {
|
||||
validationResult.get(rulePerJob.guidelines).warningAnalysisResult.push(rulePerJob);
|
||||
} else {
|
||||
validationResult.get(rulePerJob.guidelines).successfulAnalysisResult.push(rulePerJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.validationResult = validationResult;
|
||||
// this.cdr.detectChanges();
|
||||
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
public openMessagesModal(rule: RuleInfo) {
|
||||
this.modalOpen = true;
|
||||
this.currentRule = rule;
|
||||
this.modal.cancelButton = false;
|
||||
this.modal.okButton = false;
|
||||
this.modal.alertTitle = "Warnings & Errors";
|
||||
this.modal.open();
|
||||
}
|
||||
|
||||
public get currentGuideline() {
|
||||
return this.options.find(option => this.form.get("guidelines").getRawValue() == option.value);
|
||||
}
|
||||
|
||||
// fileChangeEvent(fileInput: any, dropped: boolean = false) {
|
||||
// if(this.form.value.value) {
|
||||
// this.onRemove(false);
|
||||
|
@ -127,4 +226,23 @@ export class SingleRecordValidatorComponent implements OnInit {
|
|||
// this.form.get("value").patchValue(null);
|
||||
// }
|
||||
|
||||
getWarnings(rule: RulePerJob) {
|
||||
this.warnings = [];
|
||||
if(this.warningsPerRule == null) {
|
||||
this.warnings = [];
|
||||
} else {
|
||||
this.warnings = [...this.warningsPerRule.get(rule.ruleName)];
|
||||
}
|
||||
}
|
||||
|
||||
getErrors(rule: RulePerJob) {
|
||||
this.internal_error = rule.internal_error;
|
||||
|
||||
this.errors = [];
|
||||
if(this.errorsPerRule == null) {
|
||||
this.errors = [];
|
||||
} else {
|
||||
this.errors = [...this.errorsPerRule.get(rule.ruleName)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {SingleRecordValidatorRoutingModule} from "./single-record-validator-routing.module";
|
||||
import {SingleRecordValidatorComponent} from "./single-record-validator.component";
|
||||
import {SingleRecordValidatorService} from "../../services/single-record-validator.service";
|
||||
import {AnalysisModule} from "../shared/analysis/analysis.module";
|
||||
import {SettingsModule} from "../shared/settings/settings.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule, RouterModule,
|
||||
SingleRecordValidatorRoutingModule, AnalysisModule, SettingsModule
|
||||
],
|
||||
declarations: [
|
||||
SingleRecordValidatorComponent
|
||||
],
|
||||
providers: [
|
||||
SingleRecordValidatorService
|
||||
],
|
||||
exports: [
|
||||
SingleRecordValidatorComponent
|
||||
]
|
||||
})
|
||||
export class SingleRecordValidatorModule {}
|
|
@ -6,6 +6,7 @@ import {map} from "rxjs";
|
|||
@Injectable({
|
||||
providedIn: "root"
|
||||
})
|
||||
|
||||
export class OaipmhValidatorService {
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
|
|
@ -11,7 +11,7 @@ export class SingleRecordValidatorService {
|
|||
constructor(private http: HttpClient) {}
|
||||
|
||||
validateRecord(xml: string, guidelinesName: string): Observable<any> {
|
||||
let url = environment.validatorAPI + "validate?guidelines="+guidelinesName;
|
||||
let url = environment.validatorAPI + "validateRecord?guidelines="+guidelinesName;
|
||||
let headers = new HttpHeaders({'Content-Type': 'application/json', 'accept': 'application/json'});
|
||||
return this.http.post<any>(url, xml, {headers: headers});
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
<a routerLink="/oaipmh-history">History [demo]</a>
|
||||
</li>
|
||||
<li class="uk-parent">
|
||||
<a routerLink="/oaipmh-analysis" [queryParams]="{jobId: 825}">Analysis [demo]</a>
|
||||
<a routerLink="/oaipmh-analysis" [queryParams]="{jobId: 2094}">Analysis [demo]</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue