Merge branch 'Development' of https://gitlab.eudat.eu/dmp/OpenAIRE-EUDAT-DMP-service-pilot into Development
This commit is contained in:
commit
6c6cc061fc
|
@ -13,7 +13,7 @@ import java.util.UUID;
|
|||
*/
|
||||
@Entity
|
||||
@Table(name = "\"Content\"")
|
||||
public class Content implements DataEntity<Content, UUID> {
|
||||
public class Content implements DataEntity<Content, UUID> { //IGNORE ME
|
||||
|
||||
public enum ParentType {
|
||||
GRANT(0);
|
||||
|
|
|
@ -135,34 +135,35 @@ public class WordBuilder {
|
|||
private void createPages(List<DatasetProfilePage> datasetProfilePages, XWPFDocument mainDocumentPart, Boolean createListing, VisibilityRuleService visibilityRuleService) {
|
||||
datasetProfilePages.forEach(item -> {
|
||||
try {
|
||||
createSections(item.getSections(), mainDocumentPart, ParagraphStyle.HEADER4, 0, createListing, visibilityRuleService);
|
||||
createSections(item.getSections(), mainDocumentPart, ParagraphStyle.HEADER4, 0, createListing, visibilityRuleService, item.getOrdinal() + 1, null);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createSections(List<Section> sections, XWPFDocument mainDocumentPart, ParagraphStyle style, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) {
|
||||
private void createSections(List<Section> sections, XWPFDocument mainDocumentPart, ParagraphStyle style, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, Integer page, String sectionString) {
|
||||
if (createListing) this.addListing(mainDocumentPart, indent, false, true);
|
||||
sections.forEach(section -> {
|
||||
String tempSectionString = sectionString != null ? sectionString + "." + (section.getOrdinal() + 1) : "" + (section.getOrdinal() + 1);
|
||||
if (visibilityRuleService.isElementVisible(section.getId())) {
|
||||
if (!createListing) {
|
||||
XWPFParagraph paragraph = addParagraphContent(section.getNumbering() + " " + section.getTitle(), mainDocumentPart, style, numId);
|
||||
XWPFParagraph paragraph = addParagraphContent(page + "." + tempSectionString + " " + section.getTitle(), mainDocumentPart, style, numId);
|
||||
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
|
||||
number.setVal(BigInteger.valueOf(indent));
|
||||
}
|
||||
createSections(section.getSections(), mainDocumentPart, ParagraphStyle.HEADER5, 1, createListing, visibilityRuleService);
|
||||
createCompositeFields(section.getCompositeFields(), mainDocumentPart, 2, createListing, visibilityRuleService);
|
||||
createSections(section.getSections(), mainDocumentPart, ParagraphStyle.HEADER5, 1, createListing, visibilityRuleService, page, tempSectionString);
|
||||
createCompositeFields(section.getCompositeFields(), mainDocumentPart, 2, createListing, visibilityRuleService, page, tempSectionString);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createCompositeFields(List<FieldSet> compositeFields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) {
|
||||
private void createCompositeFields(List<FieldSet> compositeFields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, Integer page, String section) {
|
||||
if (createListing) this.addListing(mainDocumentPart, indent, true, true);
|
||||
compositeFields.forEach(compositeField -> {
|
||||
if (visibilityRuleService.isElementVisible(compositeField.getId()) && hasVisibleFields(compositeField, visibilityRuleService)) {
|
||||
if (compositeField.getTitle() != null && !compositeField.getTitle().isEmpty() && !createListing) {
|
||||
XWPFParagraph paragraph = addParagraphContent(compositeField.getNumbering() + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER6, numId);
|
||||
XWPFParagraph paragraph = addParagraphContent(page + "." + section + "." + (compositeField.getOrdinal() +1) + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER6, numId);
|
||||
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
|
||||
number.setVal(BigInteger.valueOf(indent));
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.json.JSONObject;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -239,6 +240,18 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
|
|||
} catch (JsonProcessingException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
} else if (this.value instanceof Collection) {
|
||||
Collection valueCollection = (Collection) this.value;
|
||||
StringBuilder valueBuilder = new StringBuilder();
|
||||
valueBuilder.append("[");
|
||||
for (int i = 0; i < valueCollection.size(); i++) {
|
||||
valueBuilder.append("\"").append(valueCollection.toArray()[i]).append("\"");
|
||||
if (i < valueCollection.size() - 1) {
|
||||
valueBuilder.append(", ");
|
||||
}
|
||||
}
|
||||
valueBuilder.append("]");
|
||||
fieldValues.put(this.id, valueBuilder.toString());
|
||||
} else {
|
||||
fieldValues.put(this.id, this.value.toString());
|
||||
}
|
||||
|
|
|
@ -17,16 +17,16 @@
|
|||
<div *ngSwitchCase="datasetProfileFieldViewStyleEnum.ComboBox" class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-12" *ngIf="form.get('data').value.type === datasetProfileComboBoxTypeEnum.Autocomplete">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="multipleAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="singleAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
|
@ -45,46 +45,46 @@
|
|||
<div *ngSwitchCase="datasetProfileFieldViewStyleEnum.InternalDmpEntities" class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-12" *ngIf="form.get('data').value.type === this.datasetProfileInternalDmpEntitiesTypeEnum.Researchers">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="multipleAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="singleAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-12" *ngIf="form.get('data').value.type === this.datasetProfileInternalDmpEntitiesTypeEnum.Datasets">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="multipleAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="singleAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-12" *ngIf="form.get('data').value.type === this.datasetProfileInternalDmpEntitiesTypeEnum.Dmps">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="multipleAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="singleAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
|
@ -138,18 +138,18 @@
|
|||
<div *ngSwitchCase="datasetProfileFieldViewStyleEnum.ExternalDatasets" class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-12">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="externalDatasetAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="externalDatasetAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
@ -158,16 +158,16 @@
|
|||
<div *ngSwitchCase="datasetProfileFieldViewStyleEnum.DataRepositories" class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-12">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="dataRepositoriesAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="dataRepositoriesAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
|
@ -178,16 +178,16 @@
|
|||
<div *ngSwitchCase="datasetProfileFieldViewStyleEnum.Registries" class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-12">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="registriesAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="registriesAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
|
@ -198,16 +198,16 @@
|
|||
<div *ngSwitchCase="datasetProfileFieldViewStyleEnum.Services" class="col-12">
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-12">
|
||||
<div *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<ng-container *ngIf="form.get('data').value.multiAutoComplete">
|
||||
<app-multiple-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="servicesAutoCompleteConfiguration">
|
||||
</app-multiple-auto-complete>
|
||||
</div>
|
||||
<div *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!(form.get('data').value.multiAutoComplete)">
|
||||
<app-single-auto-complete placeholder="{{ form.get('data').value.label | translate }}" [formControl]="form.get('value')"
|
||||
[configuration]="servicesAutoCompleteConfiguration" [required]="form.get('validationRequired').value">
|
||||
</app-single-auto-complete>
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-error *ngIf="form.get('value').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}
|
||||
</mat-error>
|
||||
<mat-hint>{{ "TYPES.DATASET-PROFILE-COMBO-BOX-TYPE.EXTERNAL-SOURCE-HINT" | translate }}</mat-hint>
|
||||
|
|
|
@ -106,7 +106,9 @@ export class FormFieldComponent extends BaseComponent implements OnInit {
|
|||
if (this.form.get('data').value.multiList) {
|
||||
const originalValue = <string>this.form.get('value').value;
|
||||
if (originalValue !== null && typeof originalValue === 'string') {
|
||||
let values = (<string>this.form.get('value').value).slice(1, -1).split(', ');
|
||||
let values = (<string>this.form.get('value').value).slice(1, -1).split(', ').filter((value) => !value.includes('"'));
|
||||
let specialValue = (<string>this.form.get('value').value).split('"').filter((value) => !value.startsWith('[') && !value.endsWith(']') && !values.includes(value) && value !== ', ');
|
||||
specialValue.forEach(value => values.push(value));
|
||||
if (!originalValue.startsWith('[') && !originalValue.endsWith(']')) {
|
||||
values = undefined;
|
||||
values = [originalValue];
|
||||
|
@ -385,8 +387,8 @@ export class FormFieldComponent extends BaseComponent implements OnInit {
|
|||
|
||||
parseTags() {
|
||||
try{
|
||||
|
||||
|
||||
|
||||
|
||||
let stringValue = this.form.get('value').value;
|
||||
if (typeof stringValue === 'string') {
|
||||
stringValue = (<string>stringValue).replace(new RegExp('{', 'g'), '{"').replace(new RegExp('=', 'g'), '":"').replace(new RegExp(',', 'g'), '",').replace(new RegExp(', ', 'g'), ', "').replace(new RegExp('}', 'g'), '"}');
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[ngStyle]="calculateStyle(entry)"
|
||||
[ngClass]="calculateClass(entry)"
|
||||
>
|
||||
<span [class.text-danger]="showErrors && entry.form.invalid && ( (entry.type === tocEntryTypeEnum.FieldSet) || entry.type !== tocEntryTypeEnum.FieldSet && !expandChildren[idx]) ">
|
||||
<span [class.text-danger]="showErrors && entry.form.invalid && ( entry.type === tocEntryTypeEnum.FieldSet || (entry.type !== tocEntryTypeEnum.FieldSet && !expandChildren[idx])) && invalidChildsVisible(entry) ">
|
||||
{{entry.numbering}}. {{entry.label}}
|
||||
</span>
|
||||
<!-- <mat-icon style="transform: translateY(3px);" class="text-danger"
|
||||
|
@ -34,7 +34,9 @@
|
|||
[selected]="selected"
|
||||
[TOCENTRY_ID_PREFIX]="TOCENTRY_ID_PREFIX"
|
||||
[showErrors]="showErrors"
|
||||
[hiddenEntries]="hiddenEntries">
|
||||
[hiddenEntries]="hiddenEntries"
|
||||
[visibilityRulesService]="visibilityRulesService"
|
||||
>
|
||||
|
||||
</table-of-contents-internal>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
import { DOCUMENT } from '@angular/common';
|
||||
import { Component, EventEmitter, Inject, OnInit, Output, Input } from '@angular/core';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { interval, Subject, Subscription } from 'rxjs';
|
||||
import { distinctUntilChanged } from 'rxjs/operators';
|
||||
import { type } from 'os';
|
||||
import { SimpleChanges } from '@angular/core';
|
||||
import { FormArray } from '@angular/forms';
|
||||
import { ToCEntry, ToCEntryType } from '../../dataset-description.component';
|
||||
import { VisibilityRulesService } from '../../visibility-rules/visibility-rules.service';
|
||||
import { Rule } from '@app/core/model/dataset-profile-definition/rule';
|
||||
|
||||
@Component({
|
||||
selector: 'table-of-contents-internal',
|
||||
|
@ -26,11 +21,9 @@ export class TableOfContentsInternal implements OnInit {
|
|||
@Input() TOCENTRY_ID_PREFIX="";
|
||||
@Input() showErrors: boolean = false;
|
||||
@Input() hiddenEntries: string[] =[];
|
||||
@Input() visibilityRulesService: VisibilityRulesService;
|
||||
|
||||
|
||||
constructor(public visibilityRulesService: VisibilityRulesService){
|
||||
|
||||
|
||||
constructor(){
|
||||
}
|
||||
ngOnInit(): void {
|
||||
// console.log('component created');
|
||||
|
@ -140,4 +133,29 @@ export class TableOfContentsInternal implements OnInit {
|
|||
|
||||
return tocEntryFound? tocEntryFound: null;
|
||||
}
|
||||
public invalidChildsVisible(entry: ToCEntry):boolean {
|
||||
if(!entry || !this.visibilityRulesService){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(entry.type!= this.tocEntryTypeEnum.FieldSet){
|
||||
return entry.subEntries.some(_ => this.invalidChildsVisible(_));
|
||||
}
|
||||
if(entry.type === this.tocEntryTypeEnum.FieldSet){
|
||||
const fieldsArray = entry.form.get('fields') as FormArray;
|
||||
|
||||
const hasError = !fieldsArray.controls.every(field=>{//every invalid field should be invisible
|
||||
if(field.invalid){
|
||||
const id = field.get('id').value;
|
||||
const isVisible = this.visibilityRulesService.checkElementVisibility(id);
|
||||
if(isVisible){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return hasError;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
(entrySelected)="onToCentrySelected($event)"
|
||||
[selected]="tocentrySelected"
|
||||
[hiddenEntries]="hiddenEntries"
|
||||
|
||||
[visibilityRulesService]="visibilityRulesService"
|
||||
>
|
||||
|
||||
</table-of-contents-internal>
|
||||
|
|
Loading…
Reference in New Issue