diff options
13 files changed, 179 insertions, 108 deletions
diff --git a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/controller/WidgetsCatalogController.java b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/controller/WidgetsCatalogController.java index 1896a4f8..e6c1c0ac 100644 --- a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/controller/WidgetsCatalogController.java +++ b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/controller/WidgetsCatalogController.java @@ -163,13 +163,14 @@ public class WidgetsCatalogController { try { //check the zip file structure first respond = storageService.checkZipFile(file); + logger.debug("Check file validity"+respond.isValid()+respond.getError()); if(respond.isValid()){ //update the widget catalog WidgetCatalog newWidget = new ObjectMapper().readValue(widget, WidgetCatalog.class); widgetCatalogService.updateWidgetCatalog(widgetId, newWidget); logger.debug("WidgetsCatalogController.saveWidgetCatalog: updating widget with widgetId={}", widgetId); //update the widget zip file - storageService.update(file, newWidget, widgetId); + storageService.updateJsFile(file, newWidget, widgetId); } } catch (Exception e) { logger.error("Exception occurred while performing WidgetsCatalogController.saveWidgetCatalog in widget microservices. Details:", e); diff --git a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/StorageService.java b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/StorageService.java index fbd0f963..d8b56422 100644 --- a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/StorageService.java +++ b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/StorageService.java @@ -30,5 +30,7 @@ public interface StorageService { void update(MultipartFile file, WidgetCatalog newWidget, long widgetId); + void updateJsFile(MultipartFile file, WidgetCatalog newWidget, long widgetId); + byte[] getWidgetCatalogContent(long widgetId) throws Exception; } diff --git a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/StorageServiceImpl.java b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/StorageServiceImpl.java index 7a35ba4e..3bb41b6b 100644 --- a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/StorageServiceImpl.java +++ b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/StorageServiceImpl.java @@ -73,7 +73,7 @@ public class StorageServiceImpl implements StorageService { Criteria criteria = session.createCriteria(WidgetFile.class); criteria.add(Restrictions.eq("widgetId", widgetId)); List<WidgetFile> widgetFiles = criteria.list(); - session.flush(); + //session.flush(); session.close(); if (widgetFiles.size() > 0) widgetFile = widgetFiles.get(0); @@ -148,7 +148,7 @@ public class StorageServiceImpl implements StorageService { logger.error("StorageServiceImpl.save: Failed to store file " + file.getOriginalFilename(), e); throw new StorageException("Failed to store file " + file.getOriginalFilename(), e); } - saveHelper(newWidget, widgetId, map); + saveJsHelper(newWidget, widgetId, map); } @Override @@ -167,7 +167,7 @@ public class StorageServiceImpl implements StorageService { throw new StorageException("Failed to store file " + file.getName(), e); } - saveHelper(newWidget, widgetId, map); + saveJsHelper(newWidget, widgetId, map); } /** @@ -259,6 +259,90 @@ public class StorageServiceImpl implements StorageService { widgetId); } + + /** + * Helper method to UnZip File + * + * @param file + */ + private Map<String, byte[]> unZipFile(MultipartFile file) { + UnzipUtil unzipper = new UnzipUtil(); + Map<String, byte[]> map; + File convFile; + try { + if (file.isEmpty()) { + logger.error("StorageServiceImpl.update: Failed to store empty file " + file.getOriginalFilename()); + throw new StorageException("Failed to store empty file " + file.getOriginalFilename()); + } + String fileLocation = file.getOriginalFilename(); + logger.debug("StorageServiceImpl.update: store the widget to:" + fileLocation); + convFile = new File(fileLocation); + try(FileOutputStream fos = new FileOutputStream(convFile)){ + fos.write(file.getBytes()); + } + map = unzipper.unzip_db(fileLocation, ".", "tempWidgets"); + convFile.delete(); + return map; + } catch (IOException e) { + logger.error("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), e); + throw new StorageException("StorageServiceImpl.update: Failed to store file " + file.getOriginalFilename(), + e); + } + } + + /** + * Helper method for saving widget file (controller.js) to ep_widget_catalog_files table in database + * + * @param newWidget + * @param widgetId + * @param map + */ + private void saveJsHelper(WidgetCatalog newWidget, long widgetId, Map<String, byte[]> map) { + + logger.debug("Going to save controller.js " + newWidget); + WidgetFile widgetFile = new WidgetFile(); + widgetFile.setName(newWidget.getName()); + widgetFile.setWidgetId(widgetId); + final byte[] controllerLoc = map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION); + if (controllerLoc == null || controllerLoc.length == 0) + throw new IllegalArgumentException( + "Map is missing required key " + WidgetConstant.WIDGET_CONTROLLER_LOCATION); + String javascript = new String(controllerLoc); + + widgetFile.setController(javascript.getBytes()); + Session session = sessionFactory.openSession(); + session.save(widgetFile); + session.flush(); + session.close(); + logger.debug( + "StorageServiceImpl.save: saved controller.js file to the database for widget {}", + widgetId); + + } + + @Override + public void updateJsFile(MultipartFile file, WidgetCatalog newWidget, long widgetId) { + Map<String, byte[]> map; + map = unZipFile(file); + //Get existing widget file from DB + WidgetFile widgetFile = getWidgetFile(widgetId); + + String javascript = new String(map.get(WidgetConstant.WIDGET_CONTROLLER_LOCATION)); + widgetFile.setController(javascript.getBytes()); + Session session = sessionFactory.openSession(); + Transaction tx = session.beginTransaction(); + session.update(widgetFile); + tx.commit(); + session.flush(); + session.close(); + logger.debug( + "StorageServiceImpl.save: updated controller.js file to the database for widget {}", + widgetId); + } + + + + @Override public void update(MultipartFile file, WidgetCatalog newWidget, long widgetId) { @@ -424,53 +508,14 @@ public class StorageServiceImpl implements StorageService { public byte[] getWidgetCatalogContent(long widgetId) throws Exception { WidgetCatalog widget = widgetCatalogService.getWidgetCatalog(widgetId); - String namespace = "Portal" + widgetId + "Widget"; - String controllerName = "Portal" + widgetId + "Ctrl"; - String cssName = "portal" + widgetId + "-css-ready"; - - String styles = getWidgetCSS(widgetId).replaceAll(cssName, widget.getName() + "-css-ready"); File f = File.createTempFile("temp", ".zip"); try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f))){ - ZipEntry e = new ZipEntry(widget.getName() + "/styles/styles.css"); - out.putNextEntry(new ZipEntry(widget.getName() + "/")); - out.putNextEntry(new ZipEntry(widget.getName() + "/styles/")); - out.putNextEntry(e); - byte[] data = styles.getBytes(); - out.write(data, 0, data.length); - - String widgetData = namespace + "=" + namespace + "||{};" + "var res = " + namespace + ".widgetData;"; - String javascript = getWidgetController(widgetId).replace(widgetData, "").replace(namespace + ".controller =", - ""); - - String functionHeader = javascript.substring(javascript.indexOf("function"), javascript.indexOf(")") + 1); - javascript = javascript.replaceFirst(controllerName, widget.getName() + "Ctrl"); - String functionParam = functionHeader.substring(functionHeader.indexOf("(") + 1, functionHeader.indexOf(")")); - StringBuilder injectStr = new StringBuilder().append("["); - List<String> paramList = Arrays.asList(functionParam.split(",")); - for (int i = 0; i < paramList.size(); i++) { - if (i == paramList.size() - 1) - injectStr.append("'" + paramList.get(i).trim() + "'];"); - else - injectStr.append("'" + paramList.get(i).trim() + "',"); - } - javascript = javascript.replace(";" + namespace + ".controller.$inject = " + injectStr.toString(), ""); + String javascript = getWidgetController(widgetId); - e = new ZipEntry(widget.getName() + "/js/controller.js"); + ZipEntry e = new ZipEntry(widget.getName() + "/js/controller.js"); out.putNextEntry(new ZipEntry(widget.getName() + "/js/")); out.putNextEntry(e); - data = javascript.getBytes(); - out.write(data, 0, data.length); - - String html = getWidgetMarkup(widgetId).replaceFirst(controllerName, widget.getName() + "Ctrl"); - - // new - // String(map.get(WidgetConstant.WIDGET_MARKUP_LOCATION)).replaceFirst(functionName, - // controllerName);; - - e = new ZipEntry(widget.getName() + "/markup/markup.html"); - out.putNextEntry(new ZipEntry(widget.getName() + "/markup/")); - out.putNextEntry(e); - data = html.getBytes(); + byte[] data = javascript.getBytes(); out.write(data, 0, data.length); out.closeEntry(); byte[] result = Files.readAllBytes(Paths.get(f.getPath())); diff --git a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/WidgetCatalogServiceImpl.java b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/WidgetCatalogServiceImpl.java index 4554ab51..d71356fb 100644 --- a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/WidgetCatalogServiceImpl.java +++ b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/service/impl/WidgetCatalogServiceImpl.java @@ -148,9 +148,7 @@ public class WidgetCatalogServiceImpl implements WidgetCatalogService { @Override public WidgetCatalog getWidgetCatalog(Long widgetCatalogId) { Session session = sessionFactory.getCurrentSession(); - Transaction tx = session.beginTransaction(); WidgetCatalog widget = (WidgetCatalog) session.get(WidgetCatalog.class, widgetCatalogId); - tx.commit(); logger.debug("WidgetCatalogServiceImpl.getWidgetCatalog: getting widget={}", widget); return widget; } diff --git a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/utils/UnzipUtil.java b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/utils/UnzipUtil.java index f20ed1b5..164a6983 100644 --- a/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/utils/UnzipUtil.java +++ b/ecomp-portal-widget-ms/widget-ms/src/main/java/org/onap/portalapp/widget/utils/UnzipUtil.java @@ -51,8 +51,7 @@ public class UnzipUtil { ZipEntry entry = zipIn.getNextEntry(); Map<String, byte[]> map = new HashMap<>(); - String[] requiredKeys = { WidgetConstant.WIDGET_CONTROLLER_LOCATION, WidgetConstant.WIDGET_MARKUP_LOCATION, - WidgetConstant.WIDGET_STYLE_LOCATION }; + String[] requiredKeys = { WidgetConstant.WIDGET_CONTROLLER_LOCATION }; for (String k : requiredKeys) map.put(k, null); diff --git a/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html index 65ccf1dc..db0b6afd 100644 --- a/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html +++ b/portal-FE-common/src/app/layout/components/tabbar/tabbar.component.html @@ -35,6 +35,17 @@ --> + <style> + .apps-tab { + position: absolute; + width: 100%; + height: 100%; + top: 100px; + left: 5px; + background-color: white; + } + </style> + <div style="display: flex; flex-direction:column"> <mat-tab-group [selectedIndex]="selected.value" (selectedIndexChange)="selected.setValue($event)" @@ -79,19 +90,15 @@ </mat-tab-group> - - - - - <div *ngFor="let tab of tabs; let index = index" - [style.display]='tab.active? "inline" : "none"' - [style.position]='tab.active? "static" : "absolute"' - [style.height]='tab.active? "calc(100vh)" : "calc(0vh)"'> - - <iframe id="tabframe-{{tab.label.split(' ').join('-')}}-{{index}}" scrolling='yes' frameBorder='0' width='100%' - scrolling='yes' frameBorder='0' width='100%' height='90%' [src]='tab.url'></iframe> - - </div> - - - </div> + <div class="apps-tab" *ngFor="let tab of tabs; let index = index" + [style.display]='"inline"' + [style.position]='"absolute"' + [style.height]='"calc(100vh)"' + [style.z-index]="tab.active? 1 : 0" + [style.opacity]="tab.active? 1 : 0" + > + <iframe id="tabframe-{{tab.label.split(' ').join('-')}}-{{index}}" scrolling='yes' frameBorder='0' + scrolling='yes' frameBorder='0' width='100%' height='90%' [src]='tab.url'> + </iframe> + </div> +</div> diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html index d898563b..54df2d12 100644 --- a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.html @@ -40,7 +40,7 @@ <h1 class="heading-page">Edit Functional Menu</h1> </div> <div id="jqTree"></div> - <div class="functional-admin-button-container"> + <!-- <div class="functional-admin-button-container"> <button id="regenrate-functionalmenu-btn" class="btn btn-alt btn-small" (click)="regenerateFunctionalMenuAncestors()">Regenerate Menu @@ -48,5 +48,5 @@ <div class="regenerate-functionalmenu-btn-txt"> <span class="n16r">Click when you are done with your changes.</span> </div> - </div> + </div> --> </div> diff --git a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts index d3b5a164..c231061d 100644 --- a/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts +++ b/portal-FE-common/src/app/pages/functional-menu/functional-menu.component.ts @@ -151,43 +151,42 @@ export class FunctionalMenuComponent implements OnInit { * @param ngbModal */ buildTree(treedataarray,ngbModal: NgbModal , _self){ - //console.log("treedataarray>>>>",treedataarray); - // $(function() { - // $('#jqTree').tree('loadData', treedataarray); - // $('#jqTree').tree({ - // data: treedataarray, - // autoOpen: false, - // dragAndDrop: true, - // onCreateLi: function(node, $li) { - // ////console.log("node >>",node); - // } - // }).on( - // 'tree.contextmenu', - // function(event:any) { - // // The clicked node is 'event.node' - // var node = event.node; - // openMenuDetailsModal(node, "view"); - // } - // ); + console.log("treedataarray>>>>",treedataarray); + $(function() { + (<any>$('#jqTree')).tree('loadData', treedataarray); + (<any>$('#jqTree')).tree({ + data: treedataarray, + autoOpen: false, + dragAndDrop: true, + onCreateLi: function(node, $li) { + ////console.log("node >>",node); + } + }).on( + 'tree.contextmenu', + function(event:any) { + // The clicked node is 'event.node' + var node = event.node; + openMenuDetailsModal(node, "view"); + } + ); - // var openMenuDetailsModal = function(node: any, actionName: string ){ - // const modalRef = ngbModal.open(FunctionalMenuDialogComponent, { size: 'lg' }); - // modalRef.componentInstance.title = 'Functional Menu ',actionName; - // if(node != 'undefined' && node){ - // modalRef.componentInstance.nodedata = node; - // modalRef.componentInstance.operationName = actionName; - // }else{ - // modalRef.componentInstance.nodedata = {}; - // } - // modalRef.componentInstance.passEntry.subscribe((receivedEntry: any) => { - // //console.log("receivedEntry>>>>",receivedEntry); - // ngbModal.dismissAll(); - // if(receivedEntry.httpStatusCode===200){ - // _self.getFunctionalMenu(); - // } - // }); - // } - // }); - // } + var openMenuDetailsModal = function(node: any, actionName: string ){ + const modalRef = ngbModal.open(FunctionalMenuDialogComponent, { size: 'lg' }); + modalRef.componentInstance.title = 'Functional Menu ',actionName; + if(node != 'undefined' && node){ + modalRef.componentInstance.nodedata = node; + modalRef.componentInstance.operationName = actionName; + }else{ + modalRef.componentInstance.nodedata = {}; + } + modalRef.componentInstance.passEntry.subscribe((receivedEntry: any) => { + //console.log("receivedEntry>>>>",receivedEntry); + ngbModal.dismissAll(); + if(receivedEntry.httpStatusCode===200){ + _self.getFunctionalMenu(); + } + }); + } + }); } } diff --git a/portal-FE-common/src/app/pages/web-analytics/web-analytics.component.scss b/portal-FE-common/src/app/pages/web-analytics/web-analytics.component.scss index c72d11e5..7e68e1ae 100644 --- a/portal-FE-common/src/app/pages/web-analytics/web-analytics.component.scss +++ b/portal-FE-common/src/app/pages/web-analytics/web-analytics.component.scss @@ -44,6 +44,11 @@ padding-bottom: 15px; padding-right: 40px; font-weight: bold; + white-space: nowrap; +} + +td.mat-cell, td.mat-footer-cell, th.mat-header-cell { + padding-right: 45px; } .ion-md-trash{ diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html index 6d0c5446..f68d8798 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html +++ b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.html @@ -252,10 +252,10 @@ <span style="flex: 9">Upload Image</span> <app-information-tooltip style="flex: 1;" - [textMessage]="'Image file must be smaller than 1MB'"> + [textMessage]="'Image file(.png or.jpg or.jpeg with dimension 200X200 pixel) must be smaller than 1MB.'"> </app-information-tooltip> </div> - <input type="file" id="input-app-image-upload" + <input #inputAppImageUpload type="file" id="input-app-image-upload" class="input-file-field input-app-image-upload-ht" accept="image/*" [(ngModel)]="applicationObj.originalImage" name="appImage" image-upload="applicationObj.originalImage" image-upload-resize-max-height="300" @@ -284,7 +284,10 @@ <div class="property" *ngIf="!(applicationObj.applicationType == '3')"> <div class="property-label preview"> <span class="left-label">Preview</span> - <span class="remove" (click)="removeImage()">Remove</span> + <span *ngIf="(applicationObj.imageLink && applicationObj.imageLink.indexOf('default_app_image.gif') == -1 + ||applicationObj.thumbnail && applicationObj.thumbnail.indexOf('default_app_image.gif') == -1 + ||emptyImgForPreview && emptyImgForPreview.indexOf('default_app_image.gif') == -1)" + class="remove" (click)="removeImage()">Remove</span> </div> <img id="image-app-preview" class="image-preview" src="{{applicationObj.imageLink || applicationObj.thumbnail || emptyImgForPreview}}" /> diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts index 1b15f801..852e9706 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts +++ b/portal-FE-os/src/app/pages/application-onboarding/application-details-dialog/application-details-dialog.component.ts @@ -75,6 +75,7 @@ export class ApplicationDetailsDialogComponent implements OnInit { @Input() action: any; @Output() passEntry: EventEmitter<any> = new EventEmitter(); @ViewChild('applicationName') applicationNameElement: ElementRef; + @ViewChild('inputAppImageUpload') inputAppImageUpload: ElementRef; newAppModel = { 'id': null, @@ -200,6 +201,7 @@ export class ApplicationDetailsDialogComponent implements OnInit { this.applicationObj.imageUrl = null; this.applicationObj.imageLink = null; this.emptyImgForPreview = '../../../assets/images/default_app_image.gif'; + this.inputAppImageUpload.nativeElement.value = ""; } }, (resut) => { return; diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html index 19f5d8ae..47722471 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html +++ b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.html @@ -51,6 +51,7 @@ </button> <div class="apps-table"> + <span class="ecomp-spinner" *ngIf="showEcompSpinner"></span> <!-- Applications Table goes here--> <table mat-table [dataSource]="dataSource" matSort> <!-- Thumbnail Column --> diff --git a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts index 5903d654..83cbfa0e 100644 --- a/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts +++ b/portal-FE-os/src/app/pages/application-onboarding/application-onboarding.component.ts @@ -66,6 +66,7 @@ export class ApplicationOnboardingComponent implements OnInit { dataSource = new MatTableDataSource(this.appsList); @ViewChild(MatSort) sort: MatSort; @ViewChild(MatPaginator) paginator: MatPaginator; + showEcompSpinner:boolean = false; constructor(public applicationsService: ApplicationsService, public ngbModal: NgbModal) { } @@ -77,11 +78,13 @@ export class ApplicationOnboardingComponent implements OnInit { getOnboardingApps(){ //console.log("getOnboardingApps called"); + this.showEcompSpinner = true; this.applicationsService.getOnboardingApps() .subscribe(_data => { this.result = _data; if (this.result == null || this.result == 'undefined') { console.log('WidgetOnboardingService::getOnboardingWidgets Failed: Result or result.data is null'); + this.showEcompSpinner = false; }else { this.appsList = _data; for (var i = 0; i < this.appsList.length; i++) { @@ -94,11 +97,14 @@ export class ApplicationOnboardingComponent implements OnInit { } } this.populateTableData(this.appsList); + this.showEcompSpinner = false; } }, error =>{ console.log(error); + this.showEcompSpinner = false; this.openConfirmationModal('Error', error.message); }); + this.showEcompSpinner = false; } applyFilter(filterValue: string) { @@ -143,13 +149,16 @@ export class ApplicationOnboardingComponent implements OnInit { console.log('ApplicationOnboardingCtrl::deleteApplication: No apllication or ID... cannot delete'); return; } + this.showEcompSpinner = true; this.appsList.splice(this.appsList.indexOf(application), 1); this.applicationsService.deleteOnboardingApp(application.id) .subscribe( data => { this.result = data; this.getOnboardingApps(); + this.showEcompSpinner = false; }, error => { console.log(error); + this.showEcompSpinner = false; if(error && error.status == 405){ this.openConfirmationModal('', 'Application : ' + application.appName+ ' can not be deleted as it is associsted with one of the Microservices.'); }else{ |