[Admin tool| Trunk]

Customization:
	lattest changes in customization
	include upload/download options


git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-admin-portal/trunk@57995 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
argiro.kokogiannaki 2020-01-20 14:33:36 +00:00
parent 81c6123d53
commit bcbc0c7b19
7 changed files with 187 additions and 54 deletions

View File

@ -93,6 +93,6 @@
"widgetLink" : "https://beta.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=",
"claimsInformationLink": "https://beta.openaire.eu/linking",
"lastIndexUpdate": "2019-05-16",
"lastIndexUpdate": "2019-11-01",
"indexInfoAPI": "http://beta.services.openaire.eu/openaire/info/"
}

View File

@ -40,7 +40,7 @@ export class AppComponent implements OnInit {
constructor(private route: ActivatedRoute,
private propertiesService: EnvironmentSpecificService,
private _communitiesService: CommunitiesService,
private router: Router,
public router: Router,
private userManagementService: UserManagementService) {
this.router.events.forEach((event) => {
if (event instanceof NavigationStart) {
@ -242,13 +242,11 @@ export class AppComponent implements OnInit {
'/organizations', false, [], [], {communityId: this.communityId}),
items: []
});
if(this.properties.environment == 'development') {
community.items.push({
rootItem: new MenuItem('layout', 'Customize Layout', '/customize-layout',
'/customize-layout', false, [], [], {communityId: this.communityId}),
items: []
});
}
community.items.push({
rootItem: new MenuItem('layout', 'Customize Layout', '/customize-layout',
'/customize-layout', false, [], [], {communityId: this.communityId}),
items: []
});
/*community.items.push({
rootItem: new MenuItem('communityLayout', 'Community Layout', '/community-layout',
'/community-layout', false, [], [], {communityId: this.communityId}),

View File

@ -8,12 +8,8 @@ import {Component, EventEmitter, Input, OnInit, Output,} from '@angular/core';
<div class="uk-grid uk-flex uk-flex-middle uk-remove-margin">
<div class="uk-width-2-3"> {{label}}:</div>
<div class="uk-width-1-3 uk-padding-remove-left">
<button [(colorPicker)]="color" [style.background]="color"
id="color" class="uk-margin-small-left uk-icon-button"
(colorPickerChange)="color=$event; colorChanged();">
</button>
<!--<input class="uk-margin-small-left uk-width-small " color-picker [colorPicker]="color" [style.background]="color"
(colorPickerChange)="color=$event; colorChanged();"/>-->
<input class="uk-margin-small-left uk-width-small " color-picker [colorPicker]="color" [style.background]="color"
(colorPickerChange)="color=$event; colorChanged();"/>
</div>
</div>
</div>

View File

@ -9,17 +9,19 @@
<span> Reset</span>
</button>
<button class="uk-button uk-button-small uk-button-primary uk-float-right"
[disabled]="!hasChanges(draftCustomizationOptions, appliedCustomizationOptions)"
[title]="(hasChanges(draftCustomizationOptions, appliedCustomizationOptions)?'Apply changes to preview on the right':'No changes to apply')"
(click)="applyLayout();">Apply
</button>
</div>
</ng-template>
<div class="uk-grid uk-height-1-1" >
<div class="uk-grid uk-height-1-1">
<div class="uk-width-1-5 uk-background-muted customizationMenuPanel uk-padding-small ">
<div *ngIf="menuSelected == 'main'" class=" ">
<div class="uk-background-primary uk-padding-small uk-light">
<a class="uk-margin-right uk-link " (click)="exit();" >
<a class="uk-margin-right uk-link " (click)="exit();">
<span class="uk-icon"><svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="close"><path fill="none" stroke="#000" stroke-width="1.06"
d="M16,16 L4,4"></path><path fill="none" stroke="#000"
@ -28,6 +30,20 @@
</a>
<span> Customization</span>
</div>
<div class="uk-margin-small-top uk-alert uk-text-small uk-grid uk-margin-small-left uk-padding-small">
<div class="uk-padding-remove">Download the saved customization settings and upload a customization file:</div>
<div class="uk-width-1-2 uk-padding-remove"><a
(click)="downloadCustomization()" class="uk-link"
><span
uk-icon="icon: download; ratio:0.7"></span>Download </a>
</div>
<div class="js-upload uk-width-1-2 uk-text-right uk-float-right" uk-form-custom
>
<input id="exampleInputFile" class="uk-width-medium" type="file" (change)="fileChangeEvent($event)"/>
<span class="uk-link " style=""><span uk-icon="icon: upload; ratio:0.7"></span>Upload </span>
</div>
</div>
<div>{{errorMessage}}</div>
<div class="">
<div class="uk-h5 uk-margin-small-top">
Style
@ -56,7 +72,7 @@
</div>
<div class="uk-padding-small customizationMenuItems">
<a [href]="communityUrl" target="_blank">Community Page</a>
<a [href]="getCommunityUrl()" target="_blank">Community Page</a>
</div>
</div>
@ -74,7 +90,13 @@
<ng-container
*ngTemplateOutlet="applyResetButtons ; context: { }"></ng-container>
<div class="uk-alert uk-alert-primary uk-text-small uk-padding-small"> Tooltip ....</div>
<div class="uk-alert uk-text-small uk-padding-small">
<span class="uk-icon"><svg width="14" height="14" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="info"><path
d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle
fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg></span>
Set the banner background color and which fonts to be used (for dark or light background).
</div>
<div class="uk-padding-small customizationMenuItems uk-margin-small">
<ul uk-accordion>
<li class="uk-open">
@ -98,7 +120,7 @@
type="radio"/> for light background</label>
</div>
<div class="uk-margin-top uk-margin-small-bottom uk-text-bold">QUICK LOOK
<span class="uk-icon uk-link " (click)="resetButtons()">
<span class="uk-icon uk-link " (click)="resetBackgrounds()">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="refresh"><path fill="none" stroke="#000" stroke-width="1.1"
d="M17.08,11.15 C17.09,11.31 17.1,11.47 17.1,11.64 C17.1,15.53 13.94,18.69 10.05,18.69 C6.16,18.68 3,15.53 3,11.63 C3,7.74 6.16,4.58 10.05,4.58 C10.9,4.58 11.71,4.73 12.46,5"></path><polyline
@ -166,7 +188,13 @@
</div>
<ng-container
*ngTemplateOutlet="applyResetButtons ; context: { }"></ng-container>
<div class="uk-alert uk-alert-primary uk-text-small uk-padding-small"> Tooltip ....</div>
<div class="uk-alert uk-text-small uk-padding-small">
<span class="uk-icon"><svg width="14" height="14" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="info"><path
d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle
fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg></span>
Customize the banner fonts, and the links for dark and light background
</div>
<div class="uk-padding-small customizationMenuItems uk-margin-small">
<ul uk-accordion>
<li class="uk-open">
@ -183,8 +211,7 @@
(colorChange)=
" draftCustomizationOptions.panel.title.color = $event;" [addMargin]="true"></color>
<div class="uk-margin-top uk-margin-small-bottom uk-text-bold">QUICK LOOK
<span class="uk-icon uk-link " (click)="draftCustomizationOptions.panel.title =
copyObject(publishedCustomizationOptions.panel.title);">
<span class="uk-icon uk-link " (click)="resetFontsBig()">
<svg width="16" height="16" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="refresh"><path fill="none" stroke="#000" stroke-width="1.1"
d="M17.08,11.15 C17.09,11.31 17.1,11.47 17.1,11.64 C17.1,15.53 13.94,18.69 10.05,18.69 C6.16,18.68 3,15.53 3,11.63 C3,7.74 6.16,4.58 10.05,4.58 C10.9,4.58 11.71,4.73 12.46,5"></path><polyline
@ -325,7 +352,13 @@
</div>
<ng-container
*ngTemplateOutlet="applyResetButtons ; context: { }"></ng-container>
<div class="uk-alert uk-alert-primary uk-text-small uk-padding-small"> Tooltip ....</div>
<div class="uk-alert uk-text-small uk-padding-small">
<span class="uk-icon"><svg width="14" height="14" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="info"><path
d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle
fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg></span>
Customize the layout of dashboard elements.
</div>
<div class="uk-padding-small customizationMenuItems uk-margin-small">
<ul uk-accordion>
<li class="uk-open">
@ -377,8 +410,12 @@
</div>
<ng-container
*ngTemplateOutlet="applyResetButtons ; context: { }"></ng-container>
<div class="uk-alert uk-alert-primary uk-text-small uk-padding-small">Identity colors are used in several
points (e.g paging, accordions, tabs, etc) in your community RCD.<br> Hint: it can't be white!
<div class="uk-alert uk-text-small uk-padding-small">
<span class="uk-icon"><svg width="14" height="14" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="info"><path
d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle
fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg></span>
Identity colors are used in several spots in your community Dashboard. Check the <b>quick look</b> section!
</div>
<div class="uk-padding-small customizationMenuItems uk-margin-small">
<ul uk-accordion>
@ -492,7 +529,13 @@
</div>
<ng-container
*ngTemplateOutlet="applyResetButtons ; context: { }"></ng-container>
<div class="uk-alert uk-alert-primary uk-text-small uk-padding-small"> Tooltip ....</div>
<div class="uk-alert uk-text-small uk-padding-small">
<span class="uk-icon"><svg width="14" height="14" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
data-svg="info"><path
d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle
fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg></span>
Customize the buttons for dark and light backgrounds
</div>
<div class="uk-padding-small customizationMenuItems uk-margin-small">
<ul uk-accordion>
<li class="uk-open">
@ -605,24 +648,27 @@
</div>
<div *ngIf="successfulSaveMessage.length > 0" class="uk-alert uk-alert-primary">{{successfulSaveMessage}}</div>
<div *ngIf="errorMessage.length > 0" class="uk-alert uk-alert-danger">{{errorMessage}}</div>
<button class="uk-button uk-margin uk-button-primary uk-button-small uk-align-right"
[disabled]="!hasChanges(publishedCustomizationOptions, draftCustomizationOptions)"
[title]="(hasChanges(publishedCustomizationOptions, draftCustomizationOptions)?'Save changes':'No changes to save')"
(click)="saveLayout()">
Publish
</button>
</div>
<div class="uk-width-4-5 uk-padding-remove-left">
<iframe [src]="previewUrl" class="" width="100%" height="100%"></iframe>
<!-- sandbox="allow-scripts allow-same-origin" -->
<iframe *ngIf="previewUrl" [src]="previewUrl" class="" width="100%" height="100%" ></iframe>
</div>
</div>
<modal-alert #backAlert (alertOutput)="resetToAppliedOptions()" >
<div class="uk-text-bold uk-h5">If you leave that Page without applying or publishing, changes will be lost.</div>
<div> Are you sure that you want to proceed?</div>
</modal-alert>
<modal-alert #exitAlert (alertOutput)="exitCustomization()" >
<modal-alert #backAlert (alertOutput)="resetToAppliedOptions()">
<div class="uk-text-bold uk-h5">If you leave that Page without applying or publishing, changes will be lost.</div>
<div> Are you sure that you want to proceed?</div>
</modal-alert>
<modal-alert #exitAlert (alertOutput)="exitCustomization()">
<div class="uk-text-bold uk-h5">If you leave that Page without applying or publishing, changes will be lost.</div>
<div> Are you sure that you want to proceed?</div>
</modal-alert>

View File

@ -21,7 +21,6 @@ export class CustomizationComponent implements OnInit {
menuSelected = 'main';
color = 'white';
communityUrl = 'http://scoobydoo.di.uoa.gr:4200/?communityId=ee';
publishedCustomizationOptions: CustomizationOptions = null;
draftCustomizationOptions: CustomizationOptions = null;
appliedCustomizationOptions: CustomizationOptions = null;
@ -33,17 +32,14 @@ export class CustomizationComponent implements OnInit {
linkLightBackgroundPreview;
hoveredText;
public showLoading = true;
public updateErrorMessage = '';
public errorMessage = '';
public successfulSaveMessage = '';
public communityId = null;
public hasChanged = false;
public properties: EnvProperties = null;
private file: File = null;
private maxsize: number = 200 * 1024;
public enabled = true;
@ViewChild('backAlert') backAlert: AlertModal;
@ViewChild('exitAlert') exitAlert: AlertModal;
@ -67,25 +63,36 @@ export class CustomizationComponent implements OnInit {
this.route.queryParams.subscribe((params) => {
this.communityId = params['communityId'];
this.showLoading = true;
this.updateErrorMessage = '';
this.errorMessage = '';
this.successfulSaveMessage = '';
this.layoutService.getLayout(this.communityId, this.properties.adminToolsAPIURL + 'community/').subscribe(layout => {
this.publishedCustomizationOptions = layout;
this.publishedCustomizationOptions = (layout?layout:new CustomizationOptions());
this.initializeCustomizationOptions(true);
}, error => {
this.publishedCustomizationOptions = new CustomizationOptions();
this.initializeCustomizationOptions(true);
this.errorMessage = "An error occured fetching customizations options"
});
});
}
});
}
hasChanges(object1,object2):boolean{
return JSON.stringify(object1) != JSON.stringify(object2);
}
saveLayout() {
if (!Session.isLoggedIn()) {
this._router.navigate(['/user-info'], {
queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url}
});
}
this.layoutService.saveLayout(this.communityId, this.properties.adminToolsAPIURL + 'community/', this.draftCustomizationOptions).subscribe(layout => {
this.publishedCustomizationOptions = layout;
this.initializeCustomizationOptions(JSON.stringify(this.publishedCustomizationOptions) != this.previewCustomization);
this.successfulSaveMessage = "Customization Options saved!"
}, error => {
this.errorMessage = "An error occured on save"
});
}
@ -168,6 +175,8 @@ export class CustomizationComponent implements OnInit {
this.draftCustomizationOptions.links.darkBackground = this.copyObject(this.publishedCustomizationOptions.links.darkBackground);
this.appliedCustomizationOptions.links.darkBackground = this.copyObject(this.publishedCustomizationOptions.links.darkBackground);
this.linkDarkBackgroundPreview=this.changeFontsStyle(this.publishedCustomizationOptions.links.darkBackground, this.publishedCustomizationOptions.links.darkBackground.color);
}
resetFontsLinksLight() {
@ -176,6 +185,8 @@ export class CustomizationComponent implements OnInit {
this.appliedCustomizationOptions.panel.title = this.copyObject(this.publishedCustomizationOptions.panel.title);
this.appliedCustomizationOptions.links.lightBackground = this.copyObject(this.publishedCustomizationOptions.links.lightBackground);
this.linkLightBackgroundPreview=this.changeFontsStyle(this.publishedCustomizationOptions.links.lightBackground, this.publishedCustomizationOptions.links.lightBackground.color);
}
resetElements() {
@ -193,12 +204,16 @@ export class CustomizationComponent implements OnInit {
this.draftCustomizationOptions.buttons.darkBackground = this.copyObject(this.publishedCustomizationOptions.buttons.darkBackground);
this.appliedCustomizationOptions.buttons.darkBackground = this.copyObject(this.publishedCustomizationOptions.buttons.darkBackground);
this.buttonDarkBackgroundPreview=this.changeStyle(this.publishedCustomizationOptions.buttons.darkBackground);
}
resetButtonsLight() {
this.draftCustomizationOptions.buttons.lightBackground = this.copyObject(this.publishedCustomizationOptions.buttons.lightBackground);
this.appliedCustomizationOptions.buttons.lightBackground = this.copyObject(this.publishedCustomizationOptions.buttons.lightBackground);
this.buttonLightBackgroundPreview=this.changeStyle(this.publishedCustomizationOptions.buttons.lightBackground);
}
resetIdentity() {
@ -263,10 +278,13 @@ export class CustomizationComponent implements OnInit {
getCommunityUrlSatinized(layout: string) {
return this.sanitizer.bypassSecurityTrustResourceUrl(this.getCommunityUrlNewLayout(layout));
}
getCommunityUrl() {
return 'https://'+ (this.properties.environment == 'production'?'':'beta.')+this.communityId+'.openaire.eu';
}
getCommunityUrlNewLayout(layout: string) {
this.previewCustomization = layout;
return this.communityUrl + '&layout=' + StringUtils.URIEncode(layout);
return this.getCommunityUrl()+'/?' + 'layout=' + StringUtils.URIEncode(layout);
}
copyObject(obj) {
@ -310,4 +328,79 @@ export class CustomizationComponent implements OnInit {
queryParams: {'communityId': this.communityId}
});
}
downloadCustomization(){
this.errorMessage = "";
let options= JSON.parse(JSON.stringify(this.publishedCustomizationOptions));
delete options['_id'];
console.info("Here!" +JSON.stringify(options));
if(typeof document !== 'undefined') {
let dataStr = JSON.stringify(options);
let dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
let exportFileDefaultName = 'layoutOptions.json';
let linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', exportFileDefaultName);
linkElement.click();
}
}
fileChangeEvent(fileInput: any) {
this.errorMessage = "";
let filesToUpload = <Array<File>>fileInput.target.files;
if (filesToUpload.length == 0) {
this.errorMessage = "There is no selected file to upload.";
return;
} else {
if (filesToUpload[0].name.indexOf(".json") == -1 ||
(filesToUpload[0].type != "application/json" )) {
this.errorMessage = "No valid file type. The required type is json "+filesToUpload[0].type;
return;
}
}
this.makeFileRequest(this.properties.utilsService + '/upload?type=json', [], filesToUpload).then((result) => {
let layout:CustomizationOptions = JSON.parse(result.toString());
if( layout && layout.panel && layout.links && layout.buttons && layout.box){
this.draftCustomizationOptions = layout;
//put the same id to not have any difference
if(this.publishedCustomizationOptions['_id']){
this.draftCustomizationOptions['_id'] = this.publishedCustomizationOptions['_id'];
}
}else{
this.errorMessage = "No valid file";
}
}, (error) => {
this.errorMessage = "No valid file";
});
}
makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
return new Promise((resolve, reject) => {
const formData: any = new FormData();
const xhr = new XMLHttpRequest();
for (let i = 0; i < files.length; i++) {
formData.append("uploads[]", files[i], files[i].name);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject(xhr.response);
}
}
}
xhr.open("POST", url, true);
xhr.send(formData);
});
}
}

View File

@ -14,8 +14,8 @@
</div>
<div>
<a routerLink="/community-edit-form" [queryParams]="{communityId: this.communityId}" class="uk-button uk-button-text">Community Profile</a><br>
<a routerLink="/organizations" [queryParams]="{communityId: this.communityId}" class="uk-button uk-button-text">Organizations</a>
<a *ngIf="properties.environment == 'development'" routerLink="/customize-layout"
<a routerLink="/organizations" [queryParams]="{communityId: this.communityId}" class="uk-button uk-button-text">Organizations</a><br>
<a routerLink="/customize-layout"
[queryParams]="{communityId: this.communityId}"
class="uk-button uk-button-text">Customize Layout</a>
</div>

View File

@ -27,13 +27,13 @@
<script src="assets/common-assets/common/jquery.js"></script>
<script src="assets/common-assets/common/uikit.min.js?v=1"></script>
<script src="assets/common-assets/common/uikit-icons.min.js?v=1"></script>
<script src="assets/common-assets/common/uikit.min.js?v=2"></script>
<script src="assets/common-assets/common/uikit-icons.min.js?v=2"></script>
<!-- stylesheets -->
<link rel="stylesheet" type="text/css" href="assets/common-assets/common/theme.css?v=1" />
<link rel="stylesheet" type="text/css" href="assets/common-assets/common/custom.css?v=1" />
<link rel="stylesheet" type="text/css" href="assets/common-assets/library.css?v=5" />
<link rel="stylesheet" type="text/css" href="assets/css/connect-custom.css?v=6" />
<link rel="stylesheet" type="text/css" href="assets/common-assets/common/theme.css?v=2" />
<link rel="stylesheet" type="text/css" href="assets/common-assets/common/custom.css?v=2" />
<link rel="stylesheet" type="text/css" href="assets/common-assets/library.css?v=6" />
<link rel="stylesheet" type="text/css" href="assets/css/connect-custom.css?v=7" />