summaryrefslogtreecommitdiffstats
path: root/ecomp-sdk/epsdk-app-overlay/src
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-sdk/epsdk-app-overlay/src')
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/defs/definitions.xml52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.editorconfig13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.gitignore39
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/README.md27
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/angular.json130
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/protractor.conf.js28
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/src/app.e2e-spec.ts4
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/package.json50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied-routing.module.ts53
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.html3
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.scss37
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.spec.ts62
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.ts52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.spec.ts50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.ts51
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts77
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app-routing.module.ts29
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.css17
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.html24
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.spec.ts49
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.ts37
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.module.ts106
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core-routing.module.ts10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.html33
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.scss75
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.spec.ts69
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.ts98
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.html34
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.scss229
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.spec.ts69
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.ts153
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard-routing.module.ts16
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.html1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.scss (renamed from ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/.gitkeep)0
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.spec.ts32
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.ts59
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.ts16
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.html5
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.scss68
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.spec.ts70
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.ts56
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.spec.ts50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.ts57
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.html12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.scss1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.ts19
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.html13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.scss1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.ts19
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.html12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.scss1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.ts19
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found-routing.module.ts53
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.html3
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.scss37
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.spec.ts62
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.ts52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.spec.ts50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.ts51
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.html0
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.scss0
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.module.ts15
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.spec.ts12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.ts98
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.html50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.scss66
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.ts65
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.module.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.html104
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.scss31
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.ts75
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.module.ts16
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-function.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.html67
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.scss20
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.ts103
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.module.ts16
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.html60
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.scss60
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.ts116
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.module.ts11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.html53
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.scss20
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.ts28
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.module.ts11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.html1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.scss0
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.spec.ts25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.ts15
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.module.ts46
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile-routing.module.ts10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report-routing.module.ts10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage-routing.module.ts10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error-routing.module.ts53
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.html3
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.scss37
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.spec.ts62
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.ts52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.spec.ts50
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.ts51
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/index.ts37
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.spec.ts12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.ts18
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/index.ts38
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.spec.ts49
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.ts60
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.spec.ts12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.ts65
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.ts24
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared-routing.module.ts10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.spec.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.ts13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/mockdata/get_usage_list.json3
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/browserslist11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.prod.ts22
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.ts28
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/favicon.icobin5430 -> 0 bytes
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/karma.conf.js31
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/main.ts31
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/ngwelcome.html156
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/polyfills.ts98
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles.css1
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_responsive.scss7
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_utils.scss3
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/app.scss11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_alert.scss51
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_badge.scss47
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_breadcrumb.scss38
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_button-group.scss166
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_buttons.scss147
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_card.scss270
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_carousel.scss191
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_close.scss34
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_code.scss56
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_custom-forms.scss282
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_dropdown.scss131
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_forms.scss333
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_functions.scss86
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_grid.scss52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_images.scss42
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_input-group.scss156
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_jumbotron.scss16
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_list-group.scss115
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_media.scss8
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_mixins.scss42
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_modal.scss168
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_nav.scss118
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_navbar.scss311
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_pagination.scss72
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_popover.scss183
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_print.scss110
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_progress.scss33
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_reboot.scss505
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_root.scss19
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tables.scss180
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tooltip.scss115
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_transitions.scss36
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_type.scss125
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_utilities.scss14
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_variables.scss874
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-grid.scss35
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-reboot.scss12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap.scss42
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_alert.scss13
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_background-variant.scss21
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_badge.scss12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_border-radius.scss35
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_box-shadow.scss5
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_breakpoints.scss121
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_buttons.scss101
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_caret.scss65
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_clearfix.scss7
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_float.scss11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_forms.scss133
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_gradients.scss45
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid-framework.scss69
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid.scss52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_hover.scss61
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_image.scss36
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_list-group.scss24
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_lists.scss7
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_nav-divider.scss10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_navbar-align.scss10
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_pagination.scss22
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_reset-text.scss17
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_resize.scss6
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_screen-reader.scss35
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_size.scss6
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_table-row.scss30
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-emphasis.scss14
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-hide.scss9
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-truncate.scss8
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_transition.scss9
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_visibility.scss7
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_align.scss8
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_background.scss19
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_borders.scss54
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_clearfix.scss3
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_display.scss56
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_embed.scss52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_flex.scss46
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_float.scss9
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_position.scss36
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_screenreaders.scss11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_sizing.scss12
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_spacing.scss51
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_text.scss52
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_visibility.scss11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/test.ts39
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.app.json11
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.spec.json18
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tslint.json17
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tsconfig.json25
-rw-r--r--ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tslint.json131
235 files changed, 10677 insertions, 1474 deletions
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/defs/definitions.xml b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/defs/definitions.xml
index 90ccf9b7..4e223b3f 100644
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/defs/definitions.xml
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/WEB-INF/fusion/defs/definitions.xml
@@ -57,13 +57,14 @@
<!-- <definition name="nbooktest"
template="app/fusion/notebook-integration/scripts/view-models/notebook-frame.html"/>
-
- <definition name="nbooktest"
- template="app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-frame.html"/>
+
+ <definition name="nbooktest"
+ template="app/fusion/scripts/DS2-view-models/ds2-samplePages/ngnotebook-frame.html"/>
-->
- <definition name="nbooktest"
- template="app/fusion/scripts/DS2-view-models/ds2-samplePages/ngnotebook-frame.html"/>
+
+ <definition name="nbooktest"
+ template="app/fusion/scripts/DS2-view-models/ds2-samplePages/notebook-frame.html"/>
<definition extends="ebz_template" name="broadcast_list">
<put-attribute name="body"
@@ -88,54 +89,61 @@
/>
<definition name="user_profile_list"
- template="/app/fusion/scripts/DS2-view-models/ds2-profile/profile.html" />
+ template="/app/fusion/scripts/DS2-view-models/ds2-profile/ngprofile.html" />
+
+
-->
<definition name="user_profile_list"
- template="/app/fusion/scripts/DS2-view-models/ds2-profile/ngprofile.html" />
+ template="/app/fusion/scripts/DS2-view-models/ds2-profile/profile.html" />
- <!-- <definition name="admin" template="/app/fusion/scripts/view-models/admin-page/admin.html"
- /> -->
+
<definition name="openCollaboration"
template="/app/fusion/scripts/DS2-view-models/ds2-admin/collaboration.html" />
- <!--
+
<definition name="workflows"
template="/app/fusion/scripts/DS2-view-models/DS2-workflows-page/workflow-landing.html" />
- -->
-
+
+ <!--
<definition name="workflows"
template="/app/fusion/scripts/DS2-view-models/DS2-workflows-page/ngworkflow-landing.html" />
-
+ -->
+
<definition name="report_dashboard"
template="/app/fusion/scripts/view-models/reportdashboard-page/src/report-dashboard.html" />
<definition name="ds2_sample"
template="/app/fusionapp/scripts/DS2-view-models/sampleDS2.html" />
- <!--
+
<definition name="admin"
template="/app/fusion/scripts/DS2-view-models/ds2-admin/admin.html" />
- -->
+ <!--
<definition name="admin"
template="/app/fusion/scripts/DS2-view-models/ds2-admin/ngadmin.html" />
+ -->
- <!--
+
<definition name="samplePage"
template="/app/fusion/scripts/DS2-view-models/ds2-samplePages/samplePage.html" />
- -->
+
+ <!--
<definition name="samplePage"
template="/app/fusion/scripts/DS2-view-models/ds2-samplePages/ngsamplePage.html" />
-
+ -->
+
<!--
<definition name="welcome"
template="/app/fusion/scripts/DS2-view-models/welcome.html" />
- -->
+
<definition name="welcome"
template="/app/ngapp/ngwelcome.html" />
+
+ -->
<definition name="bootstrap_sample"
template="/app/fusion/scripts/DS2-view-models/bootstrap-sample-page.html" />
@@ -157,12 +165,14 @@
<put-attribute name="viewName" value="report_import"></put-attribute>
</definition>
- <!--
+
<definition name="report"
template="/app/fusion/scripts/DS2-view-models/ds2-reports/all-reports.html" />
- -->
+
+ <!--
<definition name="report"
template="/app/fusion/scripts/DS2-view-models/ds2-reports/ngall-reports.html" />
+ -->
<definition extends="ebz_template" name="reportDS1">
<put-attribute name="body"
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.editorconfig b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.editorconfig
deleted file mode 100644
index 6e87a003..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.editorconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# Editor configuration, see http://editorconfig.org
-root = true
-
-[*]
-charset = utf-8
-indent_style = space
-indent_size = 2
-insert_final_newline = true
-trim_trailing_whitespace = true
-
-[*.md]
-max_line_length = off
-trim_trailing_whitespace = false
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.gitignore b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.gitignore
deleted file mode 100644
index ee5c9d83..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/.gitignore
+++ /dev/null
@@ -1,39 +0,0 @@
-# See http://help.github.com/ignore-files/ for more about ignoring files.
-
-# compiled output
-/dist
-/tmp
-/out-tsc
-
-# dependencies
-/node_modules
-
-# IDEs and editors
-/.idea
-.project
-.classpath
-.c9/
-*.launch
-.settings/
-*.sublime-workspace
-
-# IDE - VSCode
-.vscode/*
-!.vscode/settings.json
-!.vscode/tasks.json
-!.vscode/launch.json
-!.vscode/extensions.json
-
-# misc
-/.sass-cache
-/connect.lock
-/coverage
-/libpeerconnection.log
-npm-debug.log
-yarn-error.log
-testem.log
-/typings
-
-# System Files
-.DS_Store
-Thumbs.db
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/README.md b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/README.md
deleted file mode 100644
index 6b2fc4be..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/README.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# Ngapp
-
-This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.2.3.
-
-## Development server
-
-Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
-
-## Code scaffolding
-
-Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
-
-## Build
-
-Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
-
-## Running unit tests
-
-Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
-
-## Running end-to-end tests
-
-Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
-
-## Further help
-
-To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/angular.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/angular.json
deleted file mode 100644
index f3033b1f..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/angular.json
+++ /dev/null
@@ -1,130 +0,0 @@
-{
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
- "version": 1,
- "newProjectRoot": "projects",
- "projects": {
- "ngapp": {
- "root": "",
- "sourceRoot": "src",
- "projectType": "application",
- "prefix": "app",
- "schematics": {},
- "architect": {
- "build": {
- "builder": "@angular-devkit/build-angular:browser",
- "options": {
- "outputPath": "dist/ngapp",
- "index": "src/ngwelcome.html",
- "main": "src/main.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "src/tsconfig.app.json",
- "assets": [
- "src/favicon.ico",
- "src/assets",
- "src/static",
- "src/app/fusion",
- "src/app/fusionapp"
- ],
- "styles": [
- "src/styles.css"
- ],
- "scripts": []
- },
- "configurations": {
- "production": {
- "fileReplacements": [
- {
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
- }
- ],
- "optimization": true,
- "outputHashing": "all",
- "sourceMap": false,
- "extractCss": true,
- "namedChunks": false,
- "aot": true,
- "extractLicenses": true,
- "vendorChunk": false,
- "buildOptimizer": true
- }
- }
- },
- "serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
- "options": {
- "browserTarget": "ngapp:build"
- },
- "configurations": {
- "production": {
- "browserTarget": "ngapp:build:production"
- }
- }
- },
- "extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "ngapp:build"
- }
- },
- "test": {
- "builder": "@angular-devkit/build-angular:karma",
- "options": {
- "main": "src/test.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "src/tsconfig.spec.json",
- "karmaConfig": "src/karma.conf.js",
- "styles": [
- "src/styles.css"
- ],
- "scripts": [],
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ]
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": [
- "src/tsconfig.app.json",
- "src/tsconfig.spec.json"
- ],
- "exclude": [
- "**/node_modules/**"
- ]
- }
- }
- }
- },
- "ngapp-e2e": {
- "root": "e2e/",
- "projectType": "application",
- "architect": {
- "e2e": {
- "builder": "@angular-devkit/build-angular:protractor",
- "options": {
- "protractorConfig": "e2e/protractor.conf.js",
- "devServerTarget": "ngapp:serve"
- },
- "configurations": {
- "production": {
- "devServerTarget": "ngapp:serve:production"
- }
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": "e2e/tsconfig.e2e.json",
- "exclude": [
- "**/node_modules/**"
- ]
- }
- }
- }
- }
- },
- "defaultProject": "ngapp"
-} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/protractor.conf.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/protractor.conf.js
deleted file mode 100644
index 86776a39..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/protractor.conf.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Protractor configuration file, see link for more information
-// https://github.com/angular/protractor/blob/master/lib/config.ts
-
-const { SpecReporter } = require('jasmine-spec-reporter');
-
-exports.config = {
- allScriptsTimeout: 11000,
- specs: [
- './src/**/*.e2e-spec.ts'
- ],
- capabilities: {
- 'browserName': 'chrome'
- },
- directConnect: true,
- baseUrl: 'http://localhost:4200/',
- framework: 'jasmine',
- jasmineNodeOpts: {
- showColors: true,
- defaultTimeoutInterval: 30000,
- print: function() {}
- },
- onPrepare() {
- require('ts-node').register({
- project: require('path').join(__dirname, './tsconfig.e2e.json')
- });
- jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
- }
-}; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/src/app.e2e-spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/src/app.e2e-spec.ts
index b6f71fee..2646cc6b 100644
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/src/app.e2e-spec.ts
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/e2e/src/app.e2e-spec.ts
@@ -1,6 +1,6 @@
import { AppPage } from './app.po';
-describe('workspace-project App', () => {
+describe('App', () => {
let page: AppPage;
beforeEach(() => {
@@ -9,6 +9,6 @@ describe('workspace-project App', () => {
it('should display welcome message', () => {
page.navigateTo();
- expect(page.getParagraphText()).toEqual('Welcome to ngapp!');
+ expect(page.getParagraphText()).toEqual('SB Admin BS4 Angular7');
});
});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/package.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/package.json
deleted file mode 100644
index 25c22951..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/package.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "name": "ngapp",
- "version": "0.0.0",
- "scripts": {
- "ng": "ng",
- "start": "ng serve",
- "build": "ng build --prod --output-hashing none",
- "test": "ng test",
- "lint": "ng lint",
- "e2e": "ng e2e"
- },
- "private": true,
- "dependencies": {
- "@angular/animations": "^6.1.0",
- "@angular/common": "^6.1.0",
- "@angular/compiler": "^6.1.0",
- "@angular/core": "^6.1.0",
- "@angular/forms": "^6.1.0",
- "@angular/http": "^6.1.0",
- "@angular/platform-browser": "^6.1.0",
- "@angular/platform-browser-dynamic": "^6.1.0",
- "@angular/router": "^6.1.0",
- "@angular/upgrade": "^6.1.0",
- "core-js": "^2.5.4",
- "rxjs": "~6.2.0",
- "zone.js": "~0.8.26"
- },
- "devDependencies": {
- "@angular-devkit/build-angular": "~0.8.0",
- "@angular/cli": "~6.2.3",
- "@angular/compiler-cli": "^6.1.0",
- "@angular/language-service": "^6.1.0",
- "@types/angular": "^1.6.51",
- "@types/jasmine": "~2.8.8",
- "@types/jasminewd2": "~2.0.3",
- "@types/node": "~8.9.4",
- "codelyzer": "~4.3.0",
- "jasmine-core": "~2.99.1",
- "jasmine-spec-reporter": "~4.2.1",
- "karma": "~3.0.0",
- "karma-chrome-launcher": "~2.2.0",
- "karma-coverage-istanbul-reporter": "~2.0.1",
- "karma-jasmine": "~1.1.2",
- "karma-jasmine-html-reporter": "^0.2.2",
- "protractor": "~5.4.0",
- "ts-node": "~7.0.0",
- "tslint": "~5.11.0",
- "typescript": "~2.9.2"
- }
-}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied-routing.module.ts
new file mode 100644
index 00000000..aa6d5994
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied-routing.module.ts
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { AccessDeniedComponent } from './access-denied.component';
+
+const routes: Routes = [
+ {
+ path: '', component: AccessDeniedComponent
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class AccessDeniedRoutingModule {
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.html
new file mode 100644
index 00000000..ffaa7365
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.html
@@ -0,0 +1,3 @@
+<p>
+ access-denied works!
+</p>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.scss
new file mode 100644
index 00000000..8cacac55
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.scss
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.spec.ts
new file mode 100644
index 00000000..818a2750
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.spec.ts
@@ -0,0 +1,62 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AccessDeniedComponent } from './access-denied.component';
+
+describe('AccessDeniedComponent', () => {
+ let component: AccessDeniedComponent;
+ let fixture: ComponentFixture<AccessDeniedComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AccessDeniedComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AccessDeniedComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.ts
new file mode 100644
index 00000000..4b04dffc
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.component.ts
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-access-denied',
+ templateUrl: './access-denied.component.html',
+ styleUrls: ['./access-denied.component.scss']
+})
+export class AccessDeniedComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.spec.ts
new file mode 100644
index 00000000..a1f13ff7
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.spec.ts
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { AccessDeniedModule } from './access-denied.module';
+
+describe('AccessDeniedModule', () => {
+ let accessDeniedModule: AccessDeniedModule;
+
+ beforeEach(() => {
+ accessDeniedModule = new AccessDeniedModule();
+ });
+
+ it('should create an instance', () => {
+ expect(accessDeniedModule).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.ts
new file mode 100644
index 00000000..eee4e8f8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/access-denied/access-denied.module.ts
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { AccessDeniedRoutingModule } from './access-denied-routing.module';
+import { AccessDeniedComponent } from './access-denied.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ AccessDeniedRoutingModule
+ ],
+ declarations: [AccessDeniedComponent]
+})
+export class AccessDeniedModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts
deleted file mode 100644
index 5b0a501f..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin-routing.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class AdminRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.spec.ts
deleted file mode 100644
index ee0b4037..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { AdminModule } from './admin.module';
-
-describe('AdminModule', () => {
- let adminModule: AdminModule;
-
- beforeEach(() => {
- adminModule = new AdminModule();
- });
-
- it('should create an instance', () => {
- expect(adminModule).toBeTruthy();
- });
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts
deleted file mode 100644
index ab443337..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/admin/admin.module.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-
-import { CommonModule } from '@angular/common';
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule } from '@angular/core';
-import { AppRoutingModule } from '../app-routing.module';
-
-import { UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
-import { HttpClientModule } from '@angular/common/http';
-import { RouterModule, UrlHandlingStrategy } from '@angular/router';
-import { APP_BASE_HREF } from '@angular/common';
-
-export class CustomHandlingStrategy implements UrlHandlingStrategy {
- shouldProcessUrl(url) {
- console.log('url --->>> ' + url.toString());
- var str = "ng6";
- if (url.toString().search(str) == -1 )
- return false;
- else
- return true;
- }
-
- extract(url) { return url; }
- merge(url, whole) { return url; }
-}
-
-
-//declare var angular: any;
-
-/*
-declare var angular: angular.IAngularStatic;
-
-angular.module('abs')
- .directive(
- 'appusage',
- downgradeComponent({component: UsageComponent}) as angular.IDirectiveFactory
-);
-
-angular.module('abs')
- .directive(
- 'app-hello',
- downgradeComponent({component: HelloComponent}) as angular.IDirectiveFactory
-);
-*/
-
-@NgModule({
- declarations: [
- ],
- imports: [
- CommonModule,
- BrowserModule,
- AppRoutingModule,
- UpgradeModule,
- HttpClientModule,
- RouterModule,
- /*
- RouterModule.forRoot([
- {
- path: 'ng6/usage_list',
- component: UsageComponent
- }
- ],
- {
- useHash: true,
- enableTracing: true
- }
- )*/
- ],
-
- entryComponents: [
- ],
- providers: [
- { provide: UrlHandlingStrategy, useClass: CustomHandlingStrategy },
- { provide: APP_BASE_HREF, useValue: '/' + (window.location.pathname.split('/')[1] || '') }
- ]
-})
-
-export class AdminModule { } \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app-routing.module.ts
deleted file mode 100644
index e3dafc36..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app-routing.module.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forRoot(routes)],
- exports: [RouterModule]
-})
-export class AppRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.css
deleted file mode 100644
index 1aa77fb8..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.html
deleted file mode 100644
index adc96ffd..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!--The content below is only a placeholder and can be replaced.-->
-
-<!--
-<div style="text-align:center">
- <h1>
- Welcome to {{ title }}!
- </h1>
- <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
-</div>
-<h2>Here are some links to help you start: </h2>
-<ul>
- <li>
- <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
- </li>
- <li>
- <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
- </li>
- <li>
- <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
- </li>
-</ul>
--->
-
-<router-outlet></router-outlet> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.spec.ts
deleted file mode 100644
index aca0180f..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.spec.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { TestBed, async } from '@angular/core/testing';
-import { RouterTestingModule } from '@angular/router/testing';
-import { AppComponent } from './app.component';
-describe('AppComponent', () => {
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [
- RouterTestingModule
- ],
- declarations: [
- AppComponent
- ],
- }).compileComponents();
- }));
- it('should create the app', async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.debugElement.componentInstance;
- expect(app).toBeTruthy();
- }));
- it(`should have as title 'ngapp'`, async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- const app = fixture.debugElement.componentInstance;
- expect(app.title).toEqual('ngapp');
- }));
- it('should render title in a h1 tag', async(() => {
- const fixture = TestBed.createComponent(AppComponent);
- fixture.detectChanges();
- const compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('h1').textContent).toContain('Welcome to ngapp!');
- }));
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.ts
deleted file mode 100644
index 05aa60b5..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.component.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { Component } from '@angular/core';
-import { UpgradeModule } from "@angular/upgrade/static";
-
-@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
-})
-export class AppComponent {
- title = 'ngapp';
-
- constructor(private upgrade: UpgradeModule) {
- console.log('base href ==>> ' + window.location.pathname.split('/')[1]);
- }
-
- ngOnInit() {
- this.upgrade.bootstrap(document.body, ['abs']);
- }
-}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.module.ts
deleted file mode 100644
index 5c57be3f..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/app.module.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule } from '@angular/core';
-import { AppRoutingModule } from './app-routing.module';
-import { AppComponent} from './app.component';
-import { UpgradeModule, downgradeComponent} from '@angular/upgrade/static';
-import { RouterModule, UrlHandlingStrategy } from '@angular/router';
-import { APP_BASE_HREF } from '@angular/common';
-import { AdminModule } from './admin/admin.module';
-import { ProfileModule } from './profile/profile.module';
-
-import { SharedModule } from './shared/shared.module';
-import { SamplepageModule } from './samplepage/samplepage.module';
-import { ReportModule } from './report/report.module';
-import { CoreModule } from './core/core.module'
-
-
-export class CustomHandlingStrategy implements UrlHandlingStrategy {
- shouldProcessUrl(url) {
- console.log('url --->>> ' + url.toString());
- var str = "ng6";
- if (url.toString().search(str) == -1 )
- return false;
- else
- return true;
- }
-
- extract(url) { return url; }
- merge(url, whole) { return url; }
-}
-
-
-//declare var angular: any;
-
-/*
-declare var angular: angular.IAngularStatic;
-
-angular.module('abs')
- .directive(
- 'appusage',
- downgradeComponent({component: UsageComponent}) as angular.IDirectiveFactory
-);
-
-angular.module('abs')
- .directive(
- 'app-hello',
- downgradeComponent({component: HelloComponent}) as angular.IDirectiveFactory
-);
-*/
-
-@NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- AppRoutingModule,
- UpgradeModule,
- RouterModule,
- /*
- RouterModule.forRoot([
- {
- path: 'ng6/usage_list',
- component: UsageComponent
- }
- ],
- {
- useHash: true,
- enableTracing: true
- }
- ),*/
- AdminModule,
- ProfileModule,
- ReportModule,
- SharedModule,
- SamplepageModule,
- ReportModule,
- CoreModule
- ],
-
- entryComponents: [
- ],
- providers: [
- { provide: UrlHandlingStrategy, useClass: CustomHandlingStrategy },
- { provide: APP_BASE_HREF, useValue: '/' + (window.location.pathname.split('/')[1] || '') }
- ],
- bootstrap: [AppComponent]
-})
-export class AppModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core-routing.module.ts
deleted file mode 100644
index 405e5a0f..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core-routing.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class CoreRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.spec.ts
deleted file mode 100644
index d8fcf7e3..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { CoreModule } from './core.module';
-
-describe('CoreModule', () => {
- let coreModule: CoreModule;
-
- beforeEach(() => {
- coreModule = new CoreModule();
- });
-
- it('should create an instance', () => {
- expect(coreModule).toBeTruthy();
- });
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.ts
deleted file mode 100644
index 41729d40..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/core/core.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-import { CoreRoutingModule } from './core-routing.module';
-
-@NgModule({
- imports: [
- CommonModule,
- CoreRoutingModule
- ],
- declarations: []
-})
-export class CoreModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.html
new file mode 100644
index 00000000..85644522
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.html
@@ -0,0 +1,33 @@
+<nav class="navbar navbar-expand-lg fixed-top">
+ <a class="navbar-brand" href="#">Ecomp Portal SDK</a>
+ <button class="navbar-toggler" type="button" (click)="toggleSidebar()">
+ <i class="fa fa-bars" aria-hidden="true"></i>
+ </button>
+ <div class="collapse navbar-collapse">
+ <ul class="navbar-nav ml-auto">
+ <li class="nav-item dropdown" ngbDropdown>
+ <a href="javascript:void(0)" class="nav-link" ngbDropdownToggle>
+ <i class="fa fa-user"></i> {{userFirstName}} <b class="caret"></b>
+ </a>
+
+ <div class="dropdown-menu-right" ngbDropdownMenu>
+
+ {{userName}}
+
+ <br/>
+ <div ><span class="reg-userEmail-value-spn">
+ <div>Email:</div>{{userEmail}}</span></div>
+ <br/>
+ <div ><span class="reg-userEmail-value-spn">
+ <div>userId:</div>{{userId}}</span></div>
+ <br/>
+ <div id="reg-logout-div" style="padding-top: 8px">
+ <a href="logout.htm" id="allLogout" class="btn btn-primary">
+ Log out
+ </a>
+ </div>
+ </div>
+ </li>
+ </ul>
+ </div>
+</nav>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.scss
new file mode 100644
index 00000000..159a0aba
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.scss
@@ -0,0 +1,75 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+$topnav-background-color: #222;
+:host {
+ .navbar {
+ background-color: $topnav-background-color;
+ .navbar-brand {
+ color: #fff;
+ }
+ .nav-item > a {
+ color: #999;
+ &:hover {
+ color: #fff;
+ }
+ }
+ }
+ .messages {
+ width: 300px;
+ .media {
+ border-bottom: 1px solid #ddd;
+ padding: 5px 10px;
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+ .media-body {
+ h5 {
+ font-size: 13px;
+ font-weight: 600;
+ }
+ .small {
+ margin: 0;
+ }
+ .last {
+ font-size: 12px;
+ margin: 0;
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.spec.ts
new file mode 100644
index 00000000..cbab9b18
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.spec.ts
@@ -0,0 +1,69 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { TranslateModule } from '@ngx-translate/core';
+
+import { HeaderComponent } from './header.component';
+import { LayoutModule } from '../../layout.module';
+
+describe('HeaderComponent', () => {
+ let component: HeaderComponent;
+ let fixture: ComponentFixture<HeaderComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ LayoutModule,
+ RouterTestingModule,
+ TranslateModule.forRoot(),
+ ],
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HeaderComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.ts
new file mode 100644
index 00000000..10a9fc39
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/header/header.component.ts
@@ -0,0 +1,98 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Component, OnInit } from '@angular/core';
+import { Router, NavigationEnd } from '@angular/router';
+import { HeaderService } from '../../../shared/services/header/header.service';
+import { UserService } from 'src/app/shared/services/user/user.service';
+import { User } from 'src/app/shared/services/user/user';
+
+@Component({
+ selector: 'app-header',
+ templateUrl: './header.component.html',
+ styleUrls: ['./header.component.scss']
+})
+export class HeaderComponent implements OnInit {
+ public pushRightClass: string;
+ isAppCentralized;
+ userFirstName:string;
+ userEmail:string;
+ userId:string;
+ response:any;
+ userName;
+
+
+ constructor(public router: Router,public headerService: HeaderService) {
+
+ this.router.events.subscribe(val => {
+ if (
+ val instanceof NavigationEnd &&
+ window.innerWidth <= 992 &&
+ this.isToggled()
+ ) {
+ this.toggleSidebar();
+ }
+ });
+ }
+
+ ngOnInit() {
+ this.pushRightClass = 'push-right';
+ let result = this.headerService.getTopMenuItems();
+ result.subscribe(res => {
+ this.response = res;
+ this.userFirstName = this.response.firstName;
+ this.userEmail = this.response.email;
+ this.userId = this.response.userid;
+ this.userName = this.response.userName;
+ });
+ }
+
+
+ isToggled(): boolean {
+ const dom: Element = document.querySelector('body');
+ return dom.classList.contains(this.pushRightClass);
+ }
+
+ toggleSidebar() {
+ const dom: any = document.querySelector('body');
+ dom.classList.toggle(this.pushRightClass);
+ }
+
+ onLoggedout() {
+ localStorage.removeItem('isLoggedin');
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.html
new file mode 100644
index 00000000..45fd256f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.html
@@ -0,0 +1,34 @@
+<nav class="sidebar" [ngClass]="{sidebarPushRight: isActive, collapsed: collapsed}">
+ <div class="toggle-button" [ngClass]="{collapsed: collapsed}" (click)="toggleCollapsed()">
+ <i class="fa fa-angle-double-{{collapsed?'right':'left'}}"></i>&nbsp;
+ </div>
+<div class="list-group" *ngFor="let menu of menuData ; index as item">
+ <a href="{{menu.href}}" *ngIf="!(menu.menuItems.length > 0)" class="list-group-item">
+ <i class="fa fa-dashboard"></i>&nbsp;
+ <span>{{menu.name}}</span>
+ </a>
+ <div class="nested-menu" *ngIf="menu.menuItems.length > 0">
+ <a href="javascript:void(0)" class="list-group-item"
+ (click)="addExpandClass(menu.name)">
+ <i class="fa fa-plus"></i>&nbsp;
+ <span>{{menu.name}}</span>
+ </a>
+ <li class="nested" [class.expand]="showMenu === menu.name">
+ <ul class="submenu">
+ <li *ngFor="let menuItems of menu.menuItems">
+ <a href="{{menuItems.href}}" *ngIf="menuItems.href!==null else routerBlock">
+ <i class="fa fa-monument"></i>&nbsp;
+ <span>{{ menuItems.name }}</span>
+ </a>
+ <ng-template #routerBlock>
+ <a [routerLink]="[menuItems.router]">
+ <i class="fa fa-monument"></i>&nbsp;
+ <span>{{ menuItems.name }}</span>
+ </a>
+ </ng-template>
+ </li>
+ </ul>
+ </li>
+ </div>
+</div>
+</nav>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.scss
new file mode 100644
index 00000000..788b4f0d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.scss
@@ -0,0 +1,229 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+$topnav-background-color: #f2f2f2;
+.sidebar {
+ border-radius: 0;
+ position: fixed;
+ z-index: 1000;
+ top: 56px;
+ left: 235px;
+ width: 235px;
+ margin-left: -235px;
+ margin-bottom: 48px;
+ border: none;
+ border-radius: 0;
+ overflow-y: auto;
+ background-color: $topnav-background-color;
+ bottom: 0;
+ overflow-x: hidden;
+ padding-bottom: 40px;
+ white-space: nowrap;
+ -webkit-transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -ms-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ .list-group {
+ a.list-group-item {
+ background: $topnav-background-color;
+ border: 0;
+ border-top: 1px solid #999;
+ border-radius: 0;
+ color: #0568ae;
+ text-decoration: none;
+ .fa {
+ margin-right: 10px;
+ color: #000;
+ }
+ }
+ a:hover {
+ background: darken($topnav-background-color, 5%);
+ color: #fff;
+ }
+ a.router-link-active {
+ background: darken($topnav-background-color, 5%);
+ color: #fff;
+ }
+ .header-fields {
+ padding-top: 10px;
+
+ > .list-group-item:first-child {
+ border-top: 1px solid rgba(255, 255, 255, 0.2);
+ }
+ }
+ }
+ .sidebar-dropdown {
+ *:focus {
+ border-radius: none;
+ border: none;
+ }
+ .panel-title {
+ font-size: 1rem;
+ height: 50px;
+ margin-bottom: 0;
+ a {
+ color: #999;
+ text-decoration: none;
+ font-weight: 400;
+ background: $topnav-background-color;
+ span {
+ position: relative;
+ display: block;
+ padding: 0.75rem 1.5rem;
+ padding-top: 1rem;
+ }
+ }
+ a:hover,
+ a:focus {
+ color: #fff;
+ outline: none;
+ outline-offset: -2px;
+ }
+ }
+ .panel-title:hover {
+ background: darken($topnav-background-color, 5%);
+ }
+ .panel-collapse {
+ border-radious: 0;
+ border: none;
+ .panel-body {
+ .list-group-item {
+ border-radius: 0;
+ background-color: $topnav-background-color;
+ border: 0 solid transparent;
+ a {
+ color: #999;
+ }
+ a:hover {
+ color: #fff;
+ }
+ }
+ .list-group-item:hover {
+ background: darken($topnav-background-color, 5%);
+ }
+ }
+ }
+ }
+}
+
+.nested-menu {
+ .list-group-item {
+ cursor: pointer;
+ }
+ .nested {
+ list-style-type: none;
+ }
+ ul.submenu {
+ display: none;
+ height: 0;
+ }
+ & .expand {
+ ul.submenu {
+ display: block;
+ list-style-type: none;
+ height: auto;
+ li {
+ a {
+ color: #0568ae;
+ padding: 10px;
+ display: block;
+ }
+ }
+ }
+ }
+}
+@media screen and (max-width: 992px) {
+ .sidebar {
+ top: 54px;
+ left: 0px;
+ }
+}
+@media print {
+ .sidebar {
+ display: none !important;
+ }
+}
+@media (min-width: 992px) {
+ .header-fields {
+ display: none;
+ }
+}
+
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ -webkit-box-shadow: inset 0 0 0px rgba(255, 255, 255, 1);
+ border-radius: 3px;
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 3px;
+ -webkit-box-shadow: inset 0 0 3px rgba(255, 255, 255, 1);
+}
+
+.toggle-button {
+ position: fixed;
+ width: 236px;
+ cursor: pointer;
+ padding: 12px;
+ bottom: 0;
+ color: #000;;
+ background: #f2f2f2;
+ i {
+ font-size: 23px;
+ }
+ &:hover {
+ background: darken($topnav-background-color, 5%);
+ color: #fff;
+ }
+ border-top: 1px solid #999;
+ -webkit-transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -ms-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+}
+
+.collapsed {
+ width: 60px;
+ span {
+ display: none;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.spec.ts
new file mode 100644
index 00000000..8dbcb615
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.spec.ts
@@ -0,0 +1,69 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { TranslateModule } from '@ngx-translate/core';
+
+import { SidebarComponent } from './sidebar.component';
+import { LayoutModule } from '../../layout.module';
+
+describe('SidebarComponent', () => {
+ let component: SidebarComponent;
+ let fixture: ComponentFixture<SidebarComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ LayoutModule,
+ RouterTestingModule,
+ TranslateModule.forRoot(),
+ ],
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SidebarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.ts
new file mode 100644
index 00000000..988ebcc1
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/components/sidebar/sidebar.component.ts
@@ -0,0 +1,153 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Component, Output, EventEmitter, OnInit } from '@angular/core';
+import { Router, NavigationEnd } from '@angular/router';
+import { SidebarService} from '../../../shared/services/index'
+
+@Component({
+ selector: 'app-sidebar',
+ templateUrl: './sidebar.component.html',
+ styleUrls: ['./sidebar.component.scss']
+})
+export class SidebarComponent implements OnInit {
+ isActive: boolean;
+ collapsed: boolean;
+ showMenu: string;
+ pushRightClass: string;
+ result:any;
+ leftParentData;
+ leftChildData;
+ hash:string="#";
+ menuData:Array<object> = [];
+ page;
+
+ @Output() collapsedEvent = new EventEmitter<boolean>();
+
+ constructor(public router: Router, public sidebarService: SidebarService) {
+ this.router.events.subscribe(val => {
+ if (
+ val instanceof NavigationEnd &&
+ window.innerWidth <= 992 &&
+ this.isToggled()
+ ) {
+ this.toggleSidebar();
+ }
+ });
+ }
+
+ ngOnInit() {
+ this.isActive = false;
+ this.collapsed = false;
+ this.showMenu = '';
+ this.pushRightClass = 'push-right';
+ this.sidebarService.getLeftMenu()
+ .subscribe(data => {
+
+ this.result = data;
+ this.leftParentData = JSON.parse(this.result.data);
+ this.leftChildData = JSON.parse(this.result.data2);
+
+ for (var i = 0; i < this.leftParentData.length; i++) {
+ var parentItem={
+ name:null,
+ imageSrc:null,
+ href:null,
+ menuItems:[]
+ };
+
+ console.log(this.leftParentData[i].label);
+ parentItem.name = this.leftParentData[i].label;
+ parentItem.imageSrc = this.leftParentData[i].imageSrc;
+ // Add link to items with no subitems
+ if (this.leftChildData[i].length == 0)
+ parentItem.href = this.leftParentData[i].action;
+
+ for (var j = 0; j < this.leftChildData[i].length; j++) {
+
+ var childItem={
+ name:null,
+ href:null,
+ router:null
+ };
+ if (this.leftChildData[i][j].label != null && this.leftChildData[i][j].label.length > 0) {
+
+ childItem.name = this.leftChildData[i][j].label;
+ if(this.leftChildData[i][j].action.match('v2/*'))
+ childItem.router = '/'+ this.leftChildData[i][j].action;
+ else childItem.href = this.leftChildData[i][j].action;
+ parentItem.menuItems.push(childItem)
+ }
+ }
+ this.menuData.push(parentItem);
+ console.log(this.menuData);
+ }
+
+ });
+
+ }
+ eventCalled() {
+ this.isActive = !this.isActive;
+ }
+
+ addExpandClass(element: any) {
+ if (element === this.showMenu) {
+ this.showMenu = '0';
+ } else {
+ this.showMenu = element;
+ }
+ }
+
+ toggleCollapsed() {
+ this.collapsed = !this.collapsed;
+ this.collapsedEvent.emit(this.collapsed);
+ }
+
+ isToggled(): boolean {
+ const dom: Element = document.querySelector('body');
+ return dom.classList.contains(this.pushRightClass);
+ }
+
+ toggleSidebar() {
+ const dom: any = document.querySelector('body');
+ dom.classList.toggle(this.pushRightClass);
+ }
+
+ onLoggedout() {
+ localStorage.removeItem('isLoggedin');
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard-routing.module.ts
new file mode 100644
index 00000000..0b7389d0
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard-routing.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { DashboardComponent } from './dashboard.component';
+
+const routes: Routes = [
+ {
+ path: '', component: DashboardComponent
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class DashboardRoutingModule {
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.html
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.html
@@ -0,0 +1 @@
+
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/.gitkeep b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.scss
index e69de29b..e69de29b 100644
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/.gitkeep
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.scss
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.spec.ts
new file mode 100644
index 00000000..21423380
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.spec.ts
@@ -0,0 +1,32 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+import { DashboardComponent } from './dashboard.component';
+import { DashboardModule } from './dashboard.module';
+
+describe('DashboardComponent', () => {
+ let component: DashboardComponent;
+ let fixture: ComponentFixture<DashboardComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ DashboardModule,
+ RouterTestingModule,
+ BrowserAnimationsModule,
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(DashboardComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.ts
new file mode 100644
index 00000000..b16cf742
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.component.ts
@@ -0,0 +1,59 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-dashboard',
+ templateUrl: './dashboard.component.html',
+ styleUrls: ['./dashboard.component.scss']
+})
+export class DashboardComponent implements OnInit {
+ public alerts: Array<any> = [];
+ public sliders: Array<any> = [];
+
+ constructor() {
+ this.sliders.push(
+ {
+ imagePath: 'assets/images/slider1.jpg',
+ label: 'First slide label',
+ text:
+ 'Nulla vitae elit libero, a pharetra augue mollis interdum.'
+ },
+ {
+ imagePath: 'assets/images/slider2.jpg',
+ label: 'Second slide label',
+ text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
+ },
+ {
+ imagePath: 'assets/images/slider3.jpg',
+ label: 'Third slide label',
+ text:
+ 'Praesent commodo cursus magna, vel scelerisque nisl consectetur.'
+ }
+ );
+
+ this.alerts.push(
+ {
+ id: 1,
+ type: 'success',
+ message: `Lorem ipsum dolor sit amet, consectetur adipisicing elit.
+ Voluptates est animi quibusdam praesentium quam, et perspiciatis,
+ consectetur velit culpa molestias dignissimos
+ voluptatum veritatis quod aliquam! Rerum placeat necessitatibus, vitae dolorum`
+ },
+ {
+ id: 2,
+ type: 'warning',
+ message: `Lorem ipsum dolor sit amet, consectetur adipisicing elit.
+ Voluptates est animi quibusdam praesentium quam, et perspiciatis,
+ consectetur velit culpa molestias dignissimos
+ voluptatum veritatis quod aliquam! Rerum placeat necessitatibus, vitae dolorum`
+ }
+ );
+ }
+
+ ngOnInit() {}
+
+ public closeAlert(alert: any) {
+ const index: number = this.alerts.indexOf(alert);
+ this.alerts.splice(index, 1);
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.spec.ts
new file mode 100644
index 00000000..514b3f04
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.spec.ts
@@ -0,0 +1,13 @@
+import { DashboardModule } from './dashboard.module';
+
+describe('DashboardModule', () => {
+ let dashboardModule: DashboardModule;
+
+ beforeEach(() => {
+ dashboardModule = new DashboardModule();
+ });
+
+ it('should create an instance', () => {
+ expect(dashboardModule).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.ts
new file mode 100644
index 00000000..b8511952
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/dashboard/dashboard.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { DashboardRoutingModule } from './dashboard-routing.module';
+import { DashboardComponent } from './dashboard.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ DashboardRoutingModule
+ ],
+ declarations: [
+ DashboardComponent
+ ]
+})
+export class DashboardModule {}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.html
new file mode 100644
index 00000000..8fad35c8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.html
@@ -0,0 +1,5 @@
+<app-header></app-header>
+<app-sidebar (collapsedEvent)="receiveCollapsed($event)"></app-sidebar>
+<section class="main-container" [ngClass]="{collapsed: collapedSideBar}">
+ <router-outlet></router-outlet>
+</section>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.scss
new file mode 100644
index 00000000..561f493b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.scss
@@ -0,0 +1,68 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+* {
+ -webkit-transition: margin-left 0.2s ease-in-out;
+ -moz-transition: margin-left 0.2s ease-in-out;
+ -ms-transition: margin-left 0.2s ease-in-out;
+ -o-transition: margin-left 0.2s ease-in-out;
+ transition: margin-left 0.2s ease-in-out;
+}
+.main-container {
+ margin-top: 56px;
+ margin-left: 235px;
+ padding: 15px;
+ -ms-overflow-x: hidden;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ position: relative;
+ overflow: hidden;
+}
+.collapsed {
+ margin-left: 60px;
+}
+@media screen and (max-width: 992px) {
+ .main-container {
+ margin-left: 0px !important;
+ }
+}
+@media print {
+ .main-container {
+ margin-top: 0px !important;
+ margin-left: 0px !important;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.spec.ts
new file mode 100644
index 00000000..22f11b8d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.spec.ts
@@ -0,0 +1,70 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { TranslateModule } from '@ngx-translate/core';
+
+import { LayoutComponent } from './layout.component';
+import { LayoutModule } from './layout.module';
+
+describe('LayoutComponent', () => {
+ let component: LayoutComponent;
+ let fixture: ComponentFixture<LayoutComponent>;
+
+ beforeEach(
+ async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ LayoutModule,
+ RouterTestingModule,
+ TranslateModule.forRoot(),
+ ]
+ }).compileComponents();
+ })
+ );
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(LayoutComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.ts
new file mode 100644
index 00000000..ad361164
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.component.ts
@@ -0,0 +1,56 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-layout',
+ templateUrl: './layout.component.html',
+ styleUrls: ['./layout.component.scss']
+})
+export class LayoutComponent implements OnInit {
+
+ collapedSideBar: boolean;
+
+ constructor() {}
+
+ ngOnInit() {}
+
+ receiveCollapsed($event) {
+ this.collapedSideBar = $event;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.spec.ts
new file mode 100644
index 00000000..d11d3dd7
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.spec.ts
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { LayoutModule } from './layout.module';
+
+describe('LayoutModule', () => {
+ let layoutModule: LayoutModule;
+
+ beforeEach(() => {
+ layoutModule = new LayoutModule();
+ });
+
+ it('should create an instance', () => {
+ expect(layoutModule).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.ts
new file mode 100644
index 00000000..4f136074
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/layout/layout.module.ts
@@ -0,0 +1,57 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { TranslateModule } from '@ngx-translate/core';
+import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { LayoutRoutingModule } from './layout-routing.module';
+import { LayoutComponent } from './layout.component';
+import { SidebarComponent } from './components/sidebar/sidebar.component';
+import { HeaderComponent } from './components/header/header.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ LayoutRoutingModule,
+ TranslateModule,
+ NgbDropdownModule
+ ],
+ declarations: [LayoutComponent, SidebarComponent, HeaderComponent]
+})
+export class LayoutModule {}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.html
new file mode 100644
index 00000000..0b264171
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.html
@@ -0,0 +1,12 @@
+<div class="modal-header">
+ <h4 class="modal-title">Error</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+</div>
+<div class="modal-body">
+ <p>{{message}}</p>
+</div>
+<div class="modal-footer">
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close click')">Close</button>
+</div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.scss
new file mode 100644
index 00000000..d8f951bb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.scss
@@ -0,0 +1 @@
+@import '../../pages/pages.component'; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.spec.ts
new file mode 100644
index 00000000..36497beb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ErrorModalComponent } from './error-modal.component';
+
+describe('ErrorModalComponent', () => {
+ let component: ErrorModalComponent;
+ let fixture: ComponentFixture<ErrorModalComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ErrorModalComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ErrorModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.ts
new file mode 100644
index 00000000..7efb9929
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/error-modal/error-modal.component.ts
@@ -0,0 +1,19 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'app-error-modal',
+ templateUrl: './error-modal.component.html',
+ styleUrls: ['./error-modal.component.scss']
+})
+export class ErrorModalComponent implements OnInit {
+
+ @Input() message: string;
+
+ constructor(public activeModal: NgbActiveModal) { }
+
+
+ ngOnInit() {
+ }
+
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.html
new file mode 100644
index 00000000..425c0f19
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.html
@@ -0,0 +1,13 @@
+<div class="modal-header">
+ <h4 class="modal-title">{{title}}</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+</div>
+<div class="modal-body">
+ <p>{{message}}</p>
+</div>
+<div class="modal-footer">
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Ok')">Submit</button>
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close')">Close</button>
+</div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.scss
new file mode 100644
index 00000000..d8f951bb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.scss
@@ -0,0 +1 @@
+@import '../../pages/pages.component'; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.spec.ts
new file mode 100644
index 00000000..1cc043ac
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { InformationModalComponent } from './information-modal.component';
+
+describe('InformationModalComponent', () => {
+ let component: InformationModalComponent;
+ let fixture: ComponentFixture<InformationModalComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ InformationModalComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(InformationModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.ts
new file mode 100644
index 00000000..8f7242fd
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/information-modal/information-modal.component.ts
@@ -0,0 +1,19 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'app-information-modal',
+ templateUrl: './information-modal.component.html',
+ styleUrls: ['./information-modal.component.scss']
+})
+export class InformationModalComponent implements OnInit {
+
+ @Input() title: string;
+ @Input() message: string;
+
+ constructor(public activeModal: NgbActiveModal) { }
+
+ ngOnInit() {
+ }
+
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.html
new file mode 100644
index 00000000..fa38f60b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.html
@@ -0,0 +1,12 @@
+<div class="modal-header">
+ <h4 class="modal-title">Success</h4>
+ <button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
+ <span aria-hidden="true">&times;</span>
+ </button>
+</div>
+<div class="modal-body">
+ <p>{{message}}</p>
+</div>
+<div class="modal-footer">
+ <button type="button" class="btn btn-primary" (click)="activeModal.close('Close click')">Close</button>
+</div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.scss
new file mode 100644
index 00000000..d8f951bb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.scss
@@ -0,0 +1 @@
+@import '../../pages/pages.component'; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.spec.ts
new file mode 100644
index 00000000..911af135
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SuccessModalComponent } from './success-modal.component';
+
+describe('SuccessModalComponent', () => {
+ let component: SuccessModalComponent;
+ let fixture: ComponentFixture<SuccessModalComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ SuccessModalComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SuccessModalComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.ts
new file mode 100644
index 00000000..d1d1b918
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/modals/success-modal/success-modal.component.ts
@@ -0,0 +1,19 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'app-success-modal',
+ templateUrl: './success-modal.component.html',
+ styleUrls: ['./success-modal.component.scss']
+})
+export class SuccessModalComponent implements OnInit {
+
+ @Input() message;
+
+ constructor(public activeModal: NgbActiveModal) { }
+
+
+ ngOnInit() {
+ }
+
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found-routing.module.ts
new file mode 100644
index 00000000..d12702e9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found-routing.module.ts
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { NotFoundComponent } from './not-found.component';
+
+const routes: Routes = [
+ {
+ path: '', component: NotFoundComponent
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class NotFoundRoutingModule {
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.html
new file mode 100644
index 00000000..ff604933
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.html
@@ -0,0 +1,3 @@
+<p>
+ not-found works!
+</p>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.scss
new file mode 100644
index 00000000..8cacac55
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.scss
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.spec.ts
new file mode 100644
index 00000000..16736d80
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.spec.ts
@@ -0,0 +1,62 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NotFoundComponent } from './not-found.component';
+
+describe('NotFoundComponent', () => {
+ let component: NotFoundComponent;
+ let fixture: ComponentFixture<NotFoundComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ NotFoundComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NotFoundComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.ts
new file mode 100644
index 00000000..119180b2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.component.ts
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-not-found',
+ templateUrl: './not-found.component.html',
+ styleUrls: ['./not-found.component.scss']
+})
+export class NotFoundComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.spec.ts
new file mode 100644
index 00000000..8ec7fece
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.spec.ts
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NotFoundModule } from './not-found.module';
+
+describe('NotFoundModule', () => {
+ let notFoundModule: NotFoundModule;
+
+ beforeEach(() => {
+ notFoundModule = new NotFoundModule();
+ });
+
+ it('should create an instance', () => {
+ expect(notFoundModule).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.ts
new file mode 100644
index 00000000..eb0902df
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/not-found/not-found.module.ts
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { NotFoundRoutingModule } from './not-found-routing.module';
+import { NotFoundComponent } from './not-found.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ NotFoundRoutingModule
+ ],
+ declarations: [NotFoundComponent]
+})
+export class NotFoundModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.html
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.html
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.scss
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.scss
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.spec.ts
new file mode 100644
index 00000000..72e742ff
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AdminComponent } from './admin.component';
+
+describe('AdminComponent', () => {
+ let component: AdminComponent;
+ let fixture: ComponentFixture<AdminComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AdminComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AdminComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.ts
new file mode 100644
index 00000000..ad5498c6
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.component.ts
@@ -0,0 +1,13 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-admin',
+ templateUrl: './admin.component.html',
+ styleUrls: ['./admin.component.scss']
+})
+export class AdminComponent implements OnInit {
+ constructor() { }
+ ngOnInit() {
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.module.ts
new file mode 100644
index 00000000..0daf59b9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.module.ts
@@ -0,0 +1,15 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { AdminComponent } from './admin.component';
+import {AbsTablesModule} from 'abs-components-bc';
+import {AbsUtilitiesModule} from 'abs-components-bc';
+
+@NgModule({
+ declarations: [AdminComponent],
+ imports: [
+ CommonModule,
+ AbsTablesModule,
+ AbsUtilitiesModule
+ ]
+})
+export class AdminModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.spec.ts
new file mode 100644
index 00000000..27aad032
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { AdminService } from './admin.service';
+
+describe('AdminService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: AdminService = TestBed.get(AdminService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.ts
new file mode 100644
index 00000000..74d4b9b8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/admin.service.ts
@@ -0,0 +1,98 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { JsonPipe } from '@angular/common';
+import { environment } from '../../../environments/environment';
+
+@Injectable({
+ providedIn: 'root'
+})
+
+export class AdminService {
+
+ constructor(private http:HttpClient) { }
+
+ getRoleFunctionList(){
+ return this.http.get(environment.roleFunctionList,{ withCredentials: true });
+ }
+
+ saveRoleFunction(roleData:string){
+ return this.http.post(environment.addRoleFunction,roleData);
+ }
+
+ getUsageList()
+ {
+ return this.http.get(environment.usageList,{ withCredentials: true });
+
+ }
+
+ getCacheRegions(){
+ return this.http.get(environment.cachedRegions,{ withCredentials: true });
+
+ }
+
+ getRole(roleId){
+ return this.http.get(environment.getRole+'?role_id=' + roleId,{ withCredentials: true });
+
+ }
+ getFnMenuItems()
+ {
+ return this.http.get(environment.getFnMenuItems,{ withCredentials: true });
+ }
+
+ deleteRole(roleData:any){
+ return this.http.post(environment.deleteRole,JSON.stringify({role: roleData}),{ withCredentials: true });
+ }
+
+ deleteRoleFunction(roleFunc:any)
+ {
+ return this.http.post(environment.deleteRoleFunction,roleFunc,{ withCredentials: true });
+
+ }
+
+ deleteMenu(fnMenuItem:any){
+ return this.http.post(environment.deleteMenu,JSON.stringify({fnMenuItem: fnMenuItem}),{ withCredentials: true });
+ }
+
+ getCacheRegionDetails(cacheName:any){
+ return this.http.get(environment.getRegion+'?cacheName='+cacheName,{ withCredentials: true });
+
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.html
new file mode 100644
index 00000000..8aba64c9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.html
@@ -0,0 +1,50 @@
+<div id="page-content" style=" width: 100%">
+
+ <div>
+ <h1 class="heading-page" id="CacheRegions">Cache Regions</h1>
+ </div>
+
+ <div style="margin-right:20px; text-align:justify; text-align-last:auto;">
+ <p>
+ These are the regions which are currently defined in the cache. 'Items' and 'Bytes' refer to the elements currently in memory (not spooled).
+ You can clear all items for a region by clicking on the Clear icon next to the desired region below. You can also <a href="admin#/jcs_admin" ng-click="clearAllFuncPopUp();">clear all regions</a>
+ which empties the entire cache.</p>
+ </div>
+
+
+
+ <mat-accordion displayMode="flat" multi class="mat-table">
+ <section matSort class="mat-header-row">
+ <span class="mat-header-cell" >Cache Name</span>
+ <span class="mat-header-cell" ># of Items</span>
+ <span class="mat-header-cell" >Bytes</span>
+ <span class="mat-header-cell" >Status</span>
+ <span class="mat-header-cell" >Memory Hits</span>
+ <span class="mat-header-cell">Aux Hits</span>
+ <span class="mat-header-cell" >Not Expired MissesFound Misses</span>
+ <span class="mat-header-cell" >Expired Misses</span>
+ <span class="mat-header-cell" >Clear?</span>
+ <span class="mat-header-cell" >Items</span>
+
+ </section>
+
+ <mat-expansion-panel *ngFor="let item of regions">
+ <mat-expansion-panel-header >
+ <span class="mat-cell"><a href="javascript:;" (click)="showRegionDetails(item.cacheName)">{{item.cacheName}}</a></span>
+ <span class="mat-cell">{{item.byteCount}}</span>
+ <span class="mat-cell">{{item.status}}</span>
+ <span class="mat-cell">{{item.hitCountRam}}</span>
+ <span class="mat-cell">{{item.hitCountAux}}</span>
+ <span class="mat-cell">{{item.missCountNotFound}}</span>
+ <span class="mat-cell">{{item.missCountExpired}}</span>
+ <span class="mat-cell">{{item.hitCountRam}}</span>
+ <span class="mat-cell">clear</span>
+ <span class="mat-cell">delete</span>
+
+ </mat-expansion-panel-header>
+ <div><pre>{{item.items | json }}</pre></div>
+ </mat-expansion-panel>
+
+ </mat-accordion>
+
+ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.scss
new file mode 100644
index 00000000..34516bbf
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.scss
@@ -0,0 +1,66 @@
+table {
+ width: 100%;
+ }
+
+ .mat-form-field {
+ font-size: 14px;
+ width: 100%;
+ }
+
+ td, th {
+ width: 25%;
+ }
+
+
+ .mat-accordion .mat-header-row {
+ padding-left: 1.5rem;
+ padding-right: 2rem;
+ border-bottom: none;
+ }
+
+
+ //copied from https://github.com/angular/material2/blob/master/src/lib/table/table.scss
+ $mat-header-row-height: 56px;
+ $mat-row-height: 48px;
+ $mat-row-horizontal-padding: 24px;
+
+
+ .mat-header-row {
+ min-height: $mat-header-row-height;
+ }
+
+ .mat-row {
+ min-height: $mat-row-height;
+ }
+
+ .mat-row, .mat-header-row {
+ display: flex;
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ align-items: center;
+ padding: 0 $mat-row-horizontal-padding;
+ box-sizing: border-box;
+
+ // Workaround for https://goo.gl/pFmjJD in IE 11. Adds a pseudo
+ // element that will stretch the row the correct height. See:
+ // https://connect.microsoft.com/IE/feedback/details/802625
+ &::after {
+ display: inline-block;
+ min-height: inherit;
+ content: '';
+ }
+ }
+
+ .mat-cell, .mat-header-cell {
+ flex: 1;
+ overflow: hidden;
+ word-wrap: break-word;
+ }
+
+ .mat-expansion-panel {
+ margin: 0;
+ border-radius: 4px;
+ overflow: hidden;
+ transition: margin 225ms cubic-bezier(.4,0,.2,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);
+ }
+ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.spec.ts
new file mode 100644
index 00000000..e2550383
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CacheAdminComponent } from './cache-admin.component';
+
+describe('CacheAdminComponent', () => {
+ let component: CacheAdminComponent;
+ let fixture: ComponentFixture<CacheAdminComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ CacheAdminComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(CacheAdminComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.ts
new file mode 100644
index 00000000..d9f5ca80
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.component.ts
@@ -0,0 +1,65 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import { AdminService } from '../admin.service';
+import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
+import { SuccessModalComponent } from 'src/app/modals/success-modal/success-modal.component';
+
+
+@Component({
+ selector: 'app-cache-admin',
+ templateUrl: './cache-admin.component.html',
+ styleUrls: ['./cache-admin.component.scss']
+})
+export class CacheAdminComponent implements OnInit {
+
+ constructor(public adminService:AdminService,private ngModal: NgbModal) {
+
+ }
+
+ response: any;
+ regions:any;
+ message;any;
+
+ ngOnInit() {
+
+ let result = this.adminService.getCacheRegions();
+ result.subscribe(data => {
+ this.response = data;
+ this.regions = JSON.parse(this.response.data);
+ });
+
+ }
+
+
+ showRegionDetails(item: any) {
+ let response;
+
+ this.adminService.getCacheRegionDetails(item).subscribe(data => {
+ response = data;
+
+
+ let message = response.data;
+ let msgParsed = JSON.stringify(message);
+
+
+
+ if(message!=null && message!=''){
+ var status = response.status;
+ var htmlstring = message.toString();
+ var htmlStrReplace = htmlstring.replace(/['"]+/g, '');
+ var htmlStrReplaceSplit = htmlStrReplace.split('\n');
+ var dataStr = htmlStrReplace.replace(/\\n/g, "\n");
+ this.message = dataStr;
+
+ }
+
+
+
+ });
+ const modalRef = this.ngModal.open(SuccessModalComponent);
+ modalRef.componentInstance.message = this.message;
+
+
+ }
+
+}
+
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.module.ts
new file mode 100644
index 00000000..5974dd7b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/cache-admin/cache-admin.module.ts
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { CacheAdminComponent } from './cache-admin.component';
+import { MatFormField, MatFormFieldModule } from '@angular/material/form-field';
+
+@NgModule({
+ declarations: [CacheAdminComponent],
+ imports: [
+ CommonModule,
+ MatFormFieldModule
+ ]
+})
+export class CacheAdminModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.html
new file mode 100644
index 00000000..c98e476f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.html
@@ -0,0 +1,104 @@
+<div id="page-content">
+ <div>
+ <h1 class="heading-page" id="AdminMenuItems">Admin Menu Items</h1>
+ </div>
+ <div>
+ <button type="submit" ng-click="addNewFnMenuItemModalPopup();" class="btn btn-alt btn-small"
+ style="position: initial;">Add Menu Item</button>
+ </div>
+
+ <h3 class="heading-small">
+ Existing menu items
+ </h3>
+
+ <div ng-show="showLoader" class="span loader-container">
+ <i class="icon-primary-spinner" role="img" aria-label="Please wait while we load your content"></i>
+ </div>
+
+
+ <table mat-table [dataSource]="dataSource" matSort>
+ <ng-container matColumnDef="menuId">
+ <th mat-header-cell *matHeaderCellDef id="heading1"> Menu ID</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.id}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="label">
+ <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading2"> Label </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.label}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="paretId">
+ <th mat-header-cell *matHeaderCellDef id="heading3">ParentId </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.parentId}}</td>
+ </ng-container>
+
+ <ng-container matColumnDef="action">
+ <th mat-header-cell *matHeaderCellDef id="heading4"> Action </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.sortOrder}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="functionCd">
+ <th mat-header-cell *matHeaderCellDef id="heading6"> Function </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.functionCd}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="active">
+ <th mat-header-cell *matHeaderCellDef id="heading7"> Active</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.active ? 'Y' : 'N'}} </td>
+ </ng-container>
+ <ng-container matColumnDef="servlet">
+ <th mat-header-cell *matHeaderCellDef id="heading8"> Servlet</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.servlet}} </td>
+ </ng-container>
+ <ng-container matColumnDef="queryString">
+ <th mat-header-cell *matHeaderCellDef id="heading9"> Query String</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.queryString}} </td>
+ </ng-container>
+ <ng-container matColumnDef="externalUrl">
+ <th mat-header-cell *matHeaderCellDef id="heading10">External URL </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.externalUrl}} </td>
+ </ng-container>
+ <ng-container matColumnDef="target">
+ <th mat-header-cell *matHeaderCellDef id="heading11"> Target </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.target}} </td>
+ </ng-container>
+ <ng-container matColumnDef="menuSetCode">
+ <th mat-header-cell *matHeaderCellDef id="heading12"> Menu Set Code </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.menuSetCode}} </td>
+ </ng-container>
+ <ng-container matColumnDef="separator">
+ <th mat-header-cell *matHeaderCellDef id="heading13"> Separator </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.separator ? 'Y' : 'N'}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="imageSrc">
+ <th mat-header-cell *matHeaderCellDef id="heading14"> Image Source </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.imageSrc}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="Edit">
+ <th mat-header-cell *matHeaderCellDef id="heading15"> Edit</th>
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-role-edit"
+ (click)="editMenu(rowData)">
+ <i class="ion ion-md-create"></i>
+ </span>
+ </td>
+ </ng-container>
+
+ <ng-container matColumnDef="Delete">
+ <th mat-header-cell *matHeaderCellDef id="heading16"> Delete </th>
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-role-remove"
+ (click)="removeMenuItem(rowData)">
+ <i class="icon ion-md-trash"></i>
+ </span>
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="menuHeaders"></tr>
+ <tr mat-row *matRowDef="let rowData; columns: menuHeaders;">
+
+ </table>
+ <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
+ </div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.scss
new file mode 100644
index 00000000..a9b6308f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.scss
@@ -0,0 +1,31 @@
+table {
+ width: 100%;
+ }
+
+ .mat-form-field {
+ font-size: 14px;
+ width: 100%;
+ }
+
+ td, th {
+ width: 25%;
+ }
+ .mat-form-field[_ngcontent-c4] {
+ font-size: 14px;
+ width: 20%;
+ float: right;
+ }
+
+ /*td.mat-cell, td.mat-footer-cell{
+ padding: 0;
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ border-right-style: solid;
+ border-right-color: rgba(0,0,0,.12);
+ border-right-width: 1px;
+ }
+*/
+
+td[_ngcontent-c4], th[_ngcontent-c4] {
+ width: 7%;
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.spec.ts
new file mode 100644
index 00000000..9984ceee
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MenusComponent } from './menus.component';
+
+describe('MenusComponent', () => {
+ let component: MenusComponent;
+ let fixture: ComponentFixture<MenusComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ MenusComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(MenusComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.ts
new file mode 100644
index 00000000..3575486d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.component.ts
@@ -0,0 +1,75 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { AdminService } from '../admin.service';
+import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+
+@Component({
+ selector: 'app-menus',
+ templateUrl: './menus.component.html',
+ styleUrls: ['./menus.component.scss']
+})
+export class MenusComponent implements OnInit {
+
+ constructor(public adminService: AdminService,private ngModal: NgbModal) { }
+
+ menuHeaders = ["menuId","label","paretId","action","functionCd","active","servlet","queryString","externalUrl","target","menuSetCode","separator","imageSrc","Edit","Delete"];
+
+ response: any;
+ result: any;
+ functionalMenuRes:any;
+ tableData;
+ dataSource: MatTableDataSource<[]>;
+ closeResult: string;
+
+
+ @ViewChild(MatPaginator, {}) paginator: MatPaginator;
+ @ViewChild(MatSort, {}) sort: MatSort;
+
+ ngOnInit() {
+ this.getMenus();
+ }
+
+ getMenus(){
+ let response;
+ this.response = this.adminService.getFnMenuItems();
+ this.response.subscribe(data => {
+ response = data;
+ this.functionalMenuRes =JSON.parse(response.data);
+ this.tableData =this.functionalMenuRes.fnMenuItems;
+ this.dataSource = new MatTableDataSource(this.tableData);
+ this.dataSource.paginator = this.paginator;
+ this.dataSource.sort = this.sort;
+ });
+ }
+ removeMenuItem(item: any) {
+ const modalRef = this.ngModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = 'Confirmation';
+ let response;
+ modalRef.componentInstance.message = `Are you sure you want to delete ${item.label} ?`;
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.adminService.deleteMenu(item).subscribe(data => {
+ response = data;
+ this.getMenus();
+ })
+ }
+ }, (reason) => {
+ this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
+ });
+ }
+
+ private getDismissReason(reason: any): string {
+ if (reason === ModalDismissReasons.ESC) {
+ return 'by pressing ESC';
+ } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
+ return 'by clicking on a backdrop';
+ } else {
+ return `with: ${reason}`;
+ }
+
+}
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.module.ts
new file mode 100644
index 00000000..729437c2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/menus/menus.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { MenusComponent } from './menus.component';
+import { MaterialModule } from 'src/app/material-module';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatFormFieldModule } from '@angular/material/form-field';
+
+@NgModule({
+ declarations: [MenusComponent],
+ imports: [
+ CommonModule,FormsModule,ReactiveFormsModule,MatFormFieldModule
+ ],
+ exports: [MenusComponent],
+ bootstrap: [MenusComponent]
+})
+export class MenusModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-function.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-function.ts
new file mode 100644
index 00000000..9359561d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-function.ts
@@ -0,0 +1,13 @@
+export class RoleFunction {
+ public name:string;
+ public code:string;
+ public type:string;
+ public action:string;
+
+ constructor(roleFun:any){
+ this.name= roleFun.name;
+ this.code = roleFun.code;
+ this.type = roleFun.type;
+ this.action = roleFun.action;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.html
new file mode 100644
index 00000000..ea0503cb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.html
@@ -0,0 +1,67 @@
+
+
+<div id="page-content">
+ <h1 class="heading-page" id="roleFunction">Role Function</h1>
+ <span class= "heading-small" *ngIf="isAppCentralized=='true'"><b>Please go to portal to Manage Role Function.</b></span>
+
+ <div class="create" *ngIf="isAppCentralized=='false'" (click)="addRoleFuncPopUp(rowData);">
+ <button type="button" class="btn btn-primary">Create</button>
+
+ </div>
+ <mat-form-field>
+ <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Search">
+ </mat-form-field>
+
+
+
+
+ <table mat-table [dataSource]="dataSource" matSort>
+ <ng-container matColumnDef="name">
+ <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading1"> Name</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.name}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="code">
+ <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading2"> Code</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.code}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="type">
+ <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading3">Type </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.type}}</td>
+ </ng-container>
+
+ <ng-container matColumnDef="action">
+ <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading4"> Action</th>
+ <td mat-cell *matCellDef="let rowData" > {{rowData.action}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="edit">
+ <th mat-header-cell *matHeaderCellDef id="heading5"> {{roleFunctionHeaders[4]}} </th>
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-role-edit"
+ (click)="editRole(rowData)">
+ <i class="ion ion-md-create"></i>
+ </span>
+ </td>
+ </ng-container>
+
+ <ng-container matColumnDef="delete">
+ <th mat-header-cell *matHeaderCellDef id="heading6"> {{roleFunctionHeaders[5]}} </th>
+
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-role-remove"
+ (click)="delRoleFunction(rowData)">
+ <i class="icon ion-md-trash"></i>
+ </span>
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="roleFunctionHeaders"></tr>
+ <tr mat-row *matRowDef="let rowData; columns: roleFunctionHeaders;">
+
+ </table>
+ <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
+
+ </div>
+ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.scss
new file mode 100644
index 00000000..c9ab8db4
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.scss
@@ -0,0 +1,20 @@
+table {
+ width: 100%;
+ }
+
+ .mat-form-field {
+ font-size: 14px;
+ width: 100%;
+ }
+
+ td, th {
+ width: 25%;
+ }
+ .mat-form-field[_ngcontent-c4] {
+ font-size: 14px;
+ width: 20%;
+ float: right;
+ }
+td[_ngcontent-c4], th[_ngcontent-c4] {
+ width: 15%;
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.spec.ts
new file mode 100644
index 00000000..a03f2e71
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RoleFunctionsComponent } from './role-functions.component';
+
+describe('RoleFunctionsComponent', () => {
+ let component: RoleFunctionsComponent;
+ let fixture: ComponentFixture<RoleFunctionsComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ RoleFunctionsComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RoleFunctionsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.ts
new file mode 100644
index 00000000..c9893bf2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.component.ts
@@ -0,0 +1,103 @@
+import { Component, OnInit, Directive, Input, Output, EventEmitter, ViewChildren, QueryList, PipeTransform, ViewChild } from '@angular/core';
+import { AdminService } from '../admin.service';
+import {UserService} from '../../../shared/services/user/user.service'
+import { User } from 'src/app/shared/services/user/user';
+import { of, Observable } from 'rxjs';
+import { RoleFunction } from './role-function';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'app-role-functions',
+ templateUrl: './role-functions.component.html',
+ styleUrls: ['./role-functions.component.scss']
+})
+export class RoleFunctionsComponent implements OnInit {
+
+ tableData: Array<RoleFunction> = [];
+ response: any;
+ result: any;
+ function:RoleFunction;
+
+ isAppCentralized:any;
+ user: User;
+ closeResult: string;
+
+ roleFunctionHeaders = ["name","code","type","action","edit","delete"];
+ dataSource: MatTableDataSource<RoleFunction>;
+
+ constructor(public adminService: AdminService, public userService: UserService,private ngModal: NgbModal) { }
+
+ @ViewChild(MatPaginator, {}) paginator: MatPaginator;
+ @ViewChild(MatSort, {}) sort: MatSort;
+
+ ngOnInit() {
+ this.getRoleFunctions();
+ let result = this.userService.getFunctionalMenuStaticDetailSession();
+ let user;
+ result.subscribe(user => {
+ this.user = user;
+ this.isAppCentralized = this.user.isAppCentralized;
+ });
+ }
+
+ getRoleFunctions(){
+
+ let response;
+ this.response = this.adminService.getRoleFunctionList();
+ this.response.subscribe(data => {
+ response = data;
+ this.result = JSON.parse(response.data);
+ this.tableData = JSON.parse(this.result.availableRoleFunctions);
+ this.dataSource = new MatTableDataSource(this.tableData);
+ this.dataSource.paginator = this.paginator;
+ this.dataSource.sort = this.sort;
+
+ });
+
+ }
+
+ applyFilter(filterValue: string) {
+ this.dataSource.filter = filterValue.trim().toLowerCase();
+
+ if (this.dataSource.paginator) {
+ this.dataSource.paginator.firstPage();
+ }
+ }
+
+
+ delRoleFunction(item: any) {
+ const modalRef = this.ngModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = 'Confirmation';
+ let response;
+ modalRef.componentInstance.message = `Are you sure you want to delete ${item.name} ?`;
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.adminService.deleteRoleFunction(item).subscribe(data => {
+ response = data;
+ if(response ='SUCCESS')
+ {
+ this.getRoleFunctions();
+ }
+ })
+ }
+ }, (reason) => {
+ this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
+ });
+ }
+
+ private getDismissReason(reason: any): string {
+ if (reason === ModalDismissReasons.ESC) {
+ return 'by pressing ESC';
+ } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
+ return 'by clicking on a backdrop';
+ } else {
+ return `with: ${reason}`;
+ }
+
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.module.ts
new file mode 100644
index 00000000..3406f5bd
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/role-functions/role-functions.module.ts
@@ -0,0 +1,16 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { RoleFunctionsComponent } from './role-functions.component';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatTooltipModule } from '@angular/material/tooltip';
+
+@NgModule({
+ declarations: [RoleFunctionsComponent],
+ imports: [
+ CommonModule,FormsModule,ReactiveFormsModule,MatFormFieldModule,MatTooltipModule
+ ],
+ exports: [RoleFunctionsComponent],
+ bootstrap: [RoleFunctionsComponent]
+})
+export class RoleFunctionsModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.html
new file mode 100644
index 00000000..36440ead
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.html
@@ -0,0 +1,60 @@
+<div id="page-content">
+ <div>
+ <h1 class="heading-page" id="Roles">Roles</h1>
+ <span class= "heading-small" *ngIf="isAppCentralized=='true'"><b>Please go to portal to Manage Roles.</b></span>
+ </div>
+ <div>
+ <button type="button" (click)="window.location='admin#/role/0';" class="btn btn-primary" *ngIf="isAppCentralized=='false'">Add New Role</button>
+ </div>
+ <h2 class="heading-small"*ngIf="isAppCentralized=='false'">Click on a Role to view its details.</h2>
+
+ <span class="ecomp-spinner" *ngIf="showSpinner"></span>
+ <table mat-table [dataSource]="dataSource" matSort>
+ <ng-container matColumnDef="name">
+ <th mat-header-cell *matHeaderCellDef mat-sort-header id="heading1"> Name</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.name}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="priority">
+ <th mat-header-cell *matHeaderCellDef id="heading2"> Priority</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.priority}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="Edit">
+ <th mat-header-cell *matHeaderCellDef id="heading3">{{roleHeaders[2]}} </th>
+
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-role-edit"
+ (click)="editRole(rowData)">
+ <i class="ion ion-md-create"></i>
+ </span>
+ </td>
+
+ </ng-container>
+
+ <ng-container matColumnDef="Active?">
+ <th mat-header-cell *matHeaderCellDef id="heading4"> {{roleHeaders[3]}} </th>
+ <td mat-cell *matCellDef="let rowData">
+ <mat-slide-toggle class="example-margin" [color]="color" [checked]="checked" [disabled]="disabled">
+
+ </mat-slide-toggle>
+ </td>
+
+ </ng-container>
+
+ <ng-container matColumnDef="Delete?">
+ <th mat-header-cell *matHeaderCellDef id="heading6"> {{roleHeaders[4]}} </th>
+ <td id="rowheader_t1_{{i}}" mat-cell *matCellDef="let rowData; let i=index;">
+ <span class="icon-trash" id="{{i}}-button-role-remove"
+ (click)="delRoleConfirmPopUp(rowData)">
+ <i class="icon ion-md-trash"></i>
+ </span>
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="roleHeaders"></tr>
+ <tr mat-row *matRowDef="let rowData; columns: roleHeaders;">
+
+ </table>
+ <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
+ </div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.scss
new file mode 100644
index 00000000..036634bf
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.scss
@@ -0,0 +1,60 @@
+@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
+table {
+ width: 100%;
+ }
+
+ .mat-form-field {
+ font-size: 14px;
+ width: 100%;
+ }
+
+ td, th {
+ width: 25%;
+ }
+ .mat-form-field[_ngcontent-c4] {
+ font-size: 14px;
+ width: 20%;
+ float: right;
+ }
+
+ /*td.mat-cell, td.mat-footer-cell{
+ padding: 0;
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ border-right-style: solid;
+ border-right-color: rgba(0,0,0,.12);
+ border-right-width: 1px;
+ }
+*/
+
+td[_ngcontent-c4], th[_ngcontent-c4] {
+ width: 15%;
+}
+
+.example-h2 {
+ margin: 10px;
+}
+
+.example-section {
+ display: flex;
+ align-content: center;
+ align-items: center;
+ height: 60px;
+}
+
+.example-margin {
+ margin: 10px;
+}
+body {
+ font-family: Roboto, Arial, sans-serif;
+ margin: 0;
+}
+
+.basic-container {
+ padding: 30px;
+}
+
+.version-info {
+ font-size: 8pt;
+ float: right;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.spec.ts
new file mode 100644
index 00000000..60280487
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RolesComponent } from './roles.component';
+
+describe('RolesComponent', () => {
+ let component: RolesComponent;
+ let fixture: ComponentFixture<RolesComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ RolesComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(RolesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.ts
new file mode 100644
index 00000000..5c271b66
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.component.ts
@@ -0,0 +1,116 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { AdminService } from '../admin.service';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatSort } from '@angular/material/sort';
+import { MatPaginator } from '@angular/material/paginator';
+import { User } from 'src/app/shared/services/user/user';
+import { UserService } from 'src/app/shared/services/user/user.service';
+import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
+import { modelGroupProvider } from '@angular/forms/src/directives/ng_model_group';
+import { InformationModalComponent } from 'src/app/modals/information-modal/information-modal.component';
+
+
+@Component({
+ selector: 'app-roles',
+ templateUrl: './roles.component.html',
+ styleUrls: ['./roles.component.scss']
+})
+export class RolesComponent implements OnInit {
+ tableData: Array<object> = [];
+ roleHeaders: Array<string> = [];
+ constructor(public adminService:AdminService,public userService: UserService,private ngModal: NgbModal) { }
+roleId;
+response:any;
+result:any;
+roleInfo:any;
+roleData:any;
+ociavailableRoleFunctions;
+availableRoleFunctions;
+availableRoles;
+dataSource: MatTableDataSource<[]>;
+user:User;
+isAppCentralized;
+closeResult: string;
+showSpinner = true;
+
+ @ViewChild(MatPaginator, {}) paginator: MatPaginator;
+ @ViewChild(MatSort, {}) sort: MatSort;
+
+
+ ngOnInit() {
+ this.roleHeaders = ["name","priority","Edit","Active?","Delete?"];
+ this.showSpinner = false;
+ this.roleId=undefined;
+ this.getRole(this.roleId);
+ let result = this.userService.getFunctionalMenuStaticDetailSession();
+ let user;
+ result.subscribe(user => {
+ this.user = user;
+ this.isAppCentralized = this.user.isAppCentralized;
+ });
+
+
+ }
+
+ getRole(roleId:any)
+ {
+ this.response = this.adminService.getRole(this.roleId);
+ this.response.subscribe(data => {
+
+ this.result = data;
+ this.roleInfo = JSON.parse(this.result.data);
+ this.roleData =JSON.parse(this.roleInfo.role);
+
+ this.ociavailableRoleFunctions =JSON.parse(this.roleInfo.availableRoleFunctions);
+ this.availableRoleFunctions=[];
+
+ for( let availableFun of this.ociavailableRoleFunctions){
+ let availableRoleFunction = availableFun;
+ availableRoleFunction.selected = false;
+ for( let availableFunc of this.roleData.roleFunctions){
+ if(availableFun.code === availableFunc.code){
+ availableRoleFunction.selected = true;
+ }
+ }
+ this.availableRoleFunctions.push(availableRoleFunction);
+ }
+ this.availableRoles=JSON.parse(this.roleInfo.availableRoles);
+
+ this.dataSource = new MatTableDataSource(this.availableRoles);
+ this.dataSource.paginator = this.paginator;
+ this.dataSource.sort = this.sort;
+ });
+ }
+
+ delRoleConfirmPopUp(item: any) {
+ const modalRef = this.ngModal.open(InformationModalComponent);
+ modalRef.componentInstance.title = 'Confirmation';
+ let response;
+ modalRef.componentInstance.message = `Are you sure you want to delete ${item.name} ?`;
+ modalRef.result.then((result) => {
+ if (result === 'Ok') {
+ this.adminService.deleteRole(item).subscribe(data => {
+ this.showSpinner = true;
+ response = data;
+ this.availableRoles = response.availableRoles;
+ this.dataSource = new MatTableDataSource(this.availableRoles);
+ this.dataSource.paginator = this.paginator;
+ this.dataSource.sort = this.sort;
+ })
+ }
+ }, (reason) => {
+ this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
+ });
+ }
+
+ private getDismissReason(reason: any): string {
+ if (reason === ModalDismissReasons.ESC) {
+ return 'by pressing ESC';
+ } else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
+ return 'by clicking on a backdrop';
+ } else {
+ return `with: ${reason}`;
+ }
+
+}
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.module.ts
new file mode 100644
index 00000000..cf3547a3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/roles/roles.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { RolesComponent } from './roles.component';
+
+@NgModule({
+ declarations: [RolesComponent],
+ imports: [
+ CommonModule
+ ]
+})
+export class RolesModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.html
new file mode 100644
index 00000000..9321c0d2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.html
@@ -0,0 +1,53 @@
+<div id="page-content">
+ <div>
+ <h1 class="heading-page" id="Usage">Current Usage</h1>
+ </div>
+
+ <h3 class="heading-small">
+ The following table shows all current user sessions. Click the icon to end a user's session.
+ </h3>
+
+ <table mat-table [dataSource]="users" matSort>
+ <ng-container matColumnDef="userId">
+ <th mat-header-cell *matHeaderCellDef id="heading1"> User Id</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.id}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="userName">
+ <th mat-header-cell *matHeaderCellDef id="heading2"> User Name </th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.lastName}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="email">
+ <th mat-header-cell *matHeaderCellDef id="heading3">Email</th>
+ <td mat-cell *matCellDef="let rowData"> {{rowData.email}}</td>
+ </ng-container>
+
+ <ng-container matColumnDef="lastAccessTime">
+ <th mat-header-cell *matHeaderCellDef id="heading4"> Last Access Time (minutes)</th>
+ <td mat-cell *matCellDef="let rowData" > {{rowData.lastAccess}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="timeRemaining">
+ <th mat-header-cell *matHeaderCellDef id="heading5"> Time Remaining (minutes) </th>
+ <td mat-cell *matCellDef="let rowData" > {{rowData.remaining}} </td>
+ </ng-container>
+
+ <ng-container matColumnDef="userSession">
+ <th mat-header-cell *matHeaderCellDef id="heading6"> Expire User Session? </th>
+ <td mat-cell *matCellDef="let rowData">
+ <div>Current Session</div>
+ <div (click)="removeSession(user.sessionId);"
+ style="font-size:20px;text-align:center">
+ <a href="javascript:void(0)" *ngIf="rowData.delete=='yes'" class="icon-misc-trash" ></a>
+ </div>
+
+ </td>
+ </ng-container>
+
+ <tr mat-header-row *matHeaderRowDef="usageHeaders"></tr>
+ <tr mat-row *matRowDef="let rowData; columns: usageHeaders;">
+
+ </table>
+
+ </div> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.scss
new file mode 100644
index 00000000..c9ab8db4
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.scss
@@ -0,0 +1,20 @@
+table {
+ width: 100%;
+ }
+
+ .mat-form-field {
+ font-size: 14px;
+ width: 100%;
+ }
+
+ td, th {
+ width: 25%;
+ }
+ .mat-form-field[_ngcontent-c4] {
+ font-size: 14px;
+ width: 20%;
+ float: right;
+ }
+td[_ngcontent-c4], th[_ngcontent-c4] {
+ width: 15%;
+} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.spec.ts
new file mode 100644
index 00000000..40b7df06
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UsageComponent } from './usage.component';
+
+describe('UsageComponent', () => {
+ let component: UsageComponent;
+ let fixture: ComponentFixture<UsageComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ UsageComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(UsageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.ts
new file mode 100644
index 00000000..705bf475
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.component.ts
@@ -0,0 +1,28 @@
+import { Component, OnInit } from '@angular/core';
+import { AdminService } from '../admin.service';
+
+@Component({
+ selector: 'app-usage',
+ templateUrl: './usage.component.html',
+ styleUrls: ['./usage.component.scss']
+})
+export class UsageComponent implements OnInit {
+
+ response: any;
+ result: any;
+ users:any;
+
+ usageHeaders = ["userId","userName","email","lastAccessTime","timeRemaining","userSession"];
+
+ constructor(public adminService: AdminService) { }
+
+ ngOnInit() {
+ this.adminService.getUsageList()
+ .subscribe(data => {
+ this.response = data;
+ this.users = JSON.parse(this.response.data);
+
+ });
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.module.ts
new file mode 100644
index 00000000..c2105323
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/admin/usage/usage.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { UsageComponent } from './usage.component';
+
+@NgModule({
+ declarations: [UsageComponent],
+ imports: [
+ CommonModule
+ ]
+})
+export class UsageModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.html
new file mode 100644
index 00000000..90c6b646
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.html
@@ -0,0 +1 @@
+<router-outlet></router-outlet> \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.scss
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.scss
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.spec.ts
new file mode 100644
index 00000000..7a864aca
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PagesComponent } from './pages.component';
+
+describe('PagesComponent', () => {
+ let component: PagesComponent;
+ let fixture: ComponentFixture<PagesComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ PagesComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PagesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.ts
new file mode 100644
index 00000000..d8ad6cb6
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-pages',
+ templateUrl: './pages.component.html',
+ styleUrls: ['./pages.component.scss']
+})
+export class PagesComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.module.ts
new file mode 100644
index 00000000..94a06007
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/pages/pages.module.ts
@@ -0,0 +1,46 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { PagesComponent } from './pages.component';
+import { PagesRoutingModule } from './pages-routing.module';
+import { AdminComponent } from './admin/admin.component';
+import {AbsTablesModule} from 'abs-components-bc';
+import {AbsUtilitiesModule} from 'abs-components-bc'
+import { RoleFunctionsComponent } from './admin/role-functions/role-functions.component';
+import { UsageComponent } from './admin/usage/usage.component';
+import { CacheAdminComponent } from './admin/cache-admin/cache-admin.component';
+
+import { ReactiveFormsModule, FormsModule } from '@angular/forms';
+import { MaterialModule } from '../material-module';
+import { RolesComponent } from './admin/roles/roles.component';
+import { MenusComponent } from './admin/menus/menus.component';
+import { InformationModalComponent } from '../modals/information-modal/information-modal.component';
+import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { SuccessModalComponent } from '../modals/success-modal/success-modal.component';
+import { ErrorModalComponent } from '../modals/error-modal/error-modal.component';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { SearchComponent } from './ext/profile/search/search.component';
+import { SelfComponent } from './ext/profile/self/self.component';
+import { ImportusersComponent } from './ext/profile/importusers/importusers.component';
+
+
+@NgModule({
+ declarations: [PagesComponent, AdminComponent,RoleFunctionsComponent,UsageComponent,CacheAdminComponent,SearchComponent,RolesComponent,MenusComponent,InformationModalComponent,SelfComponent,ImportusersComponent,SuccessModalComponent,ErrorModalComponent],
+ imports: [
+ CommonModule,
+ PagesRoutingModule,
+ AbsTablesModule,
+ AbsTablesModule,
+ AbsUtilitiesModule,
+ MaterialModule,
+ ReactiveFormsModule,
+ NgbModule,
+ MatTooltipModule,
+ MatExpansionModule,
+ FormsModule,
+ MatFormFieldModule
+ ],
+ entryComponents:[InformationModalComponent,RolesComponent,SuccessModalComponent,ErrorModalComponent, SelfComponent]
+})
+export class PagesModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile-routing.module.ts
deleted file mode 100644
index 339de808..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile-routing.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class ProfileRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.spec.ts
deleted file mode 100644
index 0960501e..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ProfileModule } from './profile.module';
-
-describe('ProfileModule', () => {
- let profileModule: ProfileModule;
-
- beforeEach(() => {
- profileModule = new ProfileModule();
- });
-
- it('should create an instance', () => {
- expect(profileModule).toBeTruthy();
- });
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.ts
deleted file mode 100644
index dbb3875d..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/profile/profile.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-import { ProfileRoutingModule } from './profile-routing.module';
-
-@NgModule({
- imports: [
- CommonModule,
- ProfileRoutingModule
- ],
- declarations: []
-})
-export class ProfileModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report-routing.module.ts
deleted file mode 100644
index c5d8680d..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report-routing.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class ReportRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.spec.ts
deleted file mode 100644
index cfbd84ca..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ReportModule } from './report.module';
-
-describe('ReportModule', () => {
- let reportModule: ReportModule;
-
- beforeEach(() => {
- reportModule = new ReportModule();
- });
-
- it('should create an instance', () => {
- expect(reportModule).toBeTruthy();
- });
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.ts
deleted file mode 100644
index ed2ea4c5..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/report/report.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-import { ReportRoutingModule } from './report-routing.module';
-
-@NgModule({
- imports: [
- CommonModule,
- ReportRoutingModule
- ],
- declarations: []
-})
-export class ReportModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage-routing.module.ts
deleted file mode 100644
index 9a98dc38..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage-routing.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class SamplepageRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.spec.ts
deleted file mode 100644
index 856d8f3a..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { SamplepageModule } from './samplepage.module';
-
-describe('SamplepageModule', () => {
- let samplepageModule: SamplepageModule;
-
- beforeEach(() => {
- samplepageModule = new SamplepageModule();
- });
-
- it('should create an instance', () => {
- expect(samplepageModule).toBeTruthy();
- });
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.ts
deleted file mode 100644
index c1a065f1..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/samplepage/samplepage.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-import { SamplepageRoutingModule } from './samplepage-routing.module';
-
-@NgModule({
- imports: [
- CommonModule,
- SamplepageRoutingModule
- ],
- declarations: []
-})
-export class SamplepageModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error-routing.module.ts
new file mode 100644
index 00000000..9c7fd259
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error-routing.module.ts
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { ServerErrorComponent } from './server-error.component';
+
+const routes: Routes = [
+ {
+ path: '', component: ServerErrorComponent
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+export class ServerErrorRoutingModule {
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.html
new file mode 100644
index 00000000..afedf161
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.html
@@ -0,0 +1,3 @@
+<p>
+ server-error works!
+</p>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.scss
new file mode 100644
index 00000000..8cacac55
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.scss
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.spec.ts
new file mode 100644
index 00000000..df5f099f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.spec.ts
@@ -0,0 +1,62 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ServerErrorComponent } from './server-error.component';
+
+describe('ServerErrorComponent', () => {
+ let component: ServerErrorComponent;
+ let fixture: ComponentFixture<ServerErrorComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ServerErrorComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ServerErrorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.ts
new file mode 100644
index 00000000..81d9f11b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.component.ts
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-server-error',
+ templateUrl: './server-error.component.html',
+ styleUrls: ['./server-error.component.scss']
+})
+export class ServerErrorComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.spec.ts
new file mode 100644
index 00000000..279dbdcc
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.spec.ts
@@ -0,0 +1,50 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { ServerErrorModule } from './server-error.module';
+
+describe('ServerErrorModule', () => {
+ let serverErrorModule: ServerErrorModule;
+
+ beforeEach(() => {
+ serverErrorModule = new ServerErrorModule();
+ });
+
+ it('should create an instance', () => {
+ expect(serverErrorModule).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.ts
new file mode 100644
index 00000000..aebda428
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/server-error/server-error.module.ts
@@ -0,0 +1,51 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { ServerErrorRoutingModule } from './server-error-routing.module';
+import { ServerErrorComponent } from './server-error.component';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ ServerErrorRoutingModule
+ ],
+ declarations: [ServerErrorComponent]
+})
+export class ServerErrorModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/index.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/index.ts
new file mode 100644
index 00000000..8cacac55
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/index.ts
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */ \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.spec.ts
new file mode 100644
index 00000000..0c8b8b06
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { HeaderService } from './header.service';
+
+describe('HeaderService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: HeaderService = TestBed.get(HeaderService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.ts
new file mode 100644
index 00000000..cd33e303
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/header/header.service.ts
@@ -0,0 +1,18 @@
+import { Injectable } from '@angular/core';
+import { environment } from '../../../../environments/environment';
+import { HttpClient } from '@angular/common/http';
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class HeaderService {
+
+ constructor(private http:HttpClient) { }
+
+ getTopMenuItems()
+ {
+ return this.http.get(environment.getTopMenu,{ withCredentials: true });
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/index.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/index.ts
new file mode 100644
index 00000000..c161be12
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/index.ts
@@ -0,0 +1,38 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+export * from './sidebar/sidebar.service'; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.spec.ts
new file mode 100644
index 00000000..065e6e56
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.spec.ts
@@ -0,0 +1,49 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { TestBed } from '@angular/core/testing';
+
+import { SidebarService } from './sidebar.service';
+
+describe('SidenavService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: SidebarService = TestBed.get(SidebarService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.ts
new file mode 100644
index 00000000..cbb4cf26
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/sidebar/sidebar.service.ts
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START==========================================
+ * ONAP Portal SDK
+ * ===================================================================
+ * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+ * ===================================================================
+ *
+ * Unless otherwise specified, all software contained herein is licensed
+ * under the Apache License, Version 2.0 (the "License");
+ * you may not use this software except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ============LICENSE_END============================================
+ *
+ *
+ */
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { JsonPipe } from '@angular/common';
+import { environment } from '../../../../environments/environment';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class SidebarService {
+
+ resp:string;
+
+ constructor(private http:HttpClient) { }
+ getLeftMenu(){
+ return this.http.get(environment.getLeftMenu,{ withCredentials: true });
+
+ }
+
+ getPage(url:string){
+ return this.http.get(environment.baseUrl+url,{ withCredentials: true });
+ }
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.spec.ts
new file mode 100644
index 00000000..9e7fd1c3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.spec.ts
@@ -0,0 +1,12 @@
+import { TestBed } from '@angular/core/testing';
+
+import { UserService } from './user.service';
+
+describe('UserService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: UserService = TestBed.get(UserService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.ts
new file mode 100644
index 00000000..4c4a01c3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.service.ts
@@ -0,0 +1,65 @@
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { User } from './user';
+import { Observable } from 'rxjs/Observable';
+import 'rxjs/add/observable/of';
+import 'rxjs/add/operator/share';
+import 'rxjs/add/operator/map';
+import { environment } from '../../../../environments/environment';
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class UserService {
+ user: User;
+ response:any;
+ results: Observable<any>;
+ constructor(private http:HttpClient) { }
+data;
+observable;
+
+getFunctionalMenuStaticDetailSession2(){
+ return this.http.get(environment.getFunctionalMenuStaticDetail,{ withCredentials: true })
+ .subscribe((results: Object) => {
+ this.user = new User(results);
+ });
+}
+
+
+
+public getFunctionalMenuStaticDetailSession(): Observable<User> {
+ return this.http
+ .get(environment.getFunctionalMenuStaticDetail,{ withCredentials: true })
+ .map(response => {
+ return new User(response);
+ })
+ }
+
+
+getFunctionalMenuStaticDetailSession1() {
+ if (this.data) {
+ return Observable.of(this.data);
+ } else if (this.observable) {
+ return this.observable;
+ } else {
+ this.observable = this.http.get(environment.getFunctionalMenuStaticDetail, {
+ withCredentials: true,
+ observe: 'response'
+ })
+ .map(response => {
+ this.observable = null;
+ if (response.status === 400) {
+ return 'Request failed.';
+ } else if (response.status === 200) {
+ this.data = response.body;
+ return this.data;
+ }
+ })
+ .share();
+ return this.observable;
+
+ }
+}
+
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.ts
new file mode 100644
index 00000000..41239361
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/services/user/user.ts
@@ -0,0 +1,24 @@
+
+export class User{
+ public userName: string;
+ public firstName:string;
+ public userId:string;
+ public userEmail:any;
+ public portalUrl:any;
+ public getAccessUrl:any;
+ public isAppCentralized:any;
+ public contactUsLink:any;
+ public lastName : string;
+
+ constructor(userInfo:any){
+ this.contactUsLink= userInfo.contactUsLink;
+ this.userName = userInfo.userName;
+ this.userId = userInfo.userid;
+ this.userEmail = userInfo.email;
+ this.firstName = userInfo.firstName;
+ this.portalUrl = userInfo.portalUrl;
+ this.getAccessUrl = userInfo.getAccessUrl;
+ this.isAppCentralized = userInfo.isAppCentralized;
+ this.lastName = userInfo.lastName;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared-routing.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared-routing.module.ts
deleted file mode 100644
index 06ce37cd..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared-routing.module.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [];
-
-@NgModule({
- imports: [RouterModule.forChild(routes)],
- exports: [RouterModule]
-})
-export class SharedRoutingModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.spec.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.spec.ts
deleted file mode 100644
index 3ecb6260..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.spec.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { SharedModule } from './shared.module';
-
-describe('SharedModule', () => {
- let sharedModule: SharedModule;
-
- beforeEach(() => {
- sharedModule = new SharedModule();
- });
-
- it('should create an instance', () => {
- expect(sharedModule).toBeTruthy();
- });
-});
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.ts
deleted file mode 100644
index f9eea33e..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/app/shared/shared.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-
-import { SharedRoutingModule } from './shared-routing.module';
-
-@NgModule({
- imports: [
- CommonModule,
- SharedRoutingModule
- ],
- declarations: []
-})
-export class SharedModule { }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/mockdata/get_usage_list.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/mockdata/get_usage_list.json
deleted file mode 100644
index 648043b6..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/assets/mockdata/get_usage_list.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "data":"[{\"lastName\":\"User\",\"lastAccess\":\"0:34\",\"id\":1,\"sessionId\":\"00A71210A24BFB0BF44CB5DA77FE3125\",\"delete\":\"no\",\"email\":\"demo@email.com\",\"remaining\":\"29:26\"}]"
-} \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/browserslist b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/browserslist
deleted file mode 100644
index 37371cb0..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/browserslist
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
-# For additional information regarding the format and rule options, please see:
-# https://github.com/browserslist/browserslist#queries
-#
-# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
-
-> 0.5%
-last 2 versions
-Firefox ESR
-not dead
-not IE 9-11 \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.prod.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.prod.ts
deleted file mode 100644
index dc99c444..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.prod.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-export const environment = {
- production: true,
- baseUrl: ''
-}; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.ts
deleted file mode 100644
index 493f63e6..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/environments/environment.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-// The file contents for the current environment will overwrite these during build.
-// The build system defaults to the dev environment which uses `environment.ts`, but if you do
-// `ng build --env=prod` then `environment.prod.ts` will be used instead.
-// The list of which env maps to which file can be found in `.angular-cli.json`.
-
-export const environment = {
- production: false,
- baseUrl: 'http://localhost:8067/epsdk-app-os/'
-}; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/favicon.ico b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/favicon.ico
deleted file mode 100644
index 8081c7ce..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/karma.conf.js b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/karma.conf.js
deleted file mode 100644
index b6e00421..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/karma.conf.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Karma configuration file, see link for more information
-// https://karma-runner.github.io/1.0/config/configuration-file.html
-
-module.exports = function (config) {
- config.set({
- basePath: '',
- frameworks: ['jasmine', '@angular-devkit/build-angular'],
- plugins: [
- require('karma-jasmine'),
- require('karma-chrome-launcher'),
- require('karma-jasmine-html-reporter'),
- require('karma-coverage-istanbul-reporter'),
- require('@angular-devkit/build-angular/plugins/karma')
- ],
- client: {
- clearContext: false // leave Jasmine Spec Runner output visible in browser
- },
- coverageIstanbulReporter: {
- dir: require('path').join(__dirname, '../coverage'),
- reports: ['html', 'lcovonly'],
- fixWebpackSourcePaths: true
- },
- reporters: ['progress', 'kjhtml'],
- port: 9876,
- colors: true,
- logLevel: config.LOG_INFO,
- autoWatch: true,
- browsers: ['Chrome'],
- singleRun: false
- });
-}; \ No newline at end of file
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/main.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/main.ts
deleted file mode 100644
index 2c9e65f6..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/main.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { enableProdMode } from '@angular/core';
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-
-import { AppModule } from './app/app.module';
-import { environment } from './environments/environment';
-
-if (environment.production) {
- enableProdMode();
-}
-
-platformBrowserDynamic().bootstrapModule(AppModule)
- .catch(err => console.error(err));
-
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/ngwelcome.html b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/ngwelcome.html
deleted file mode 100644
index 71aa415a..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/ngwelcome.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>Welcome NG</title>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="icon" type="image/x-icon" href="favicon.ico">
-
- <!-- B2b Library -->
- <link rel="stylesheet" type="text/css" href="app/fusion/external/b2b/css/b2b-angular/b2b-angular.css">
- <link rel="stylesheet" type="text/css" href="app/fusion/external/b2b/css/b2b-angular/font_icons.css">
-
- <!-- icons in open source -->
- <link rel="stylesheet" type="text/css" href="app/fusion/external/ds2/css/digital-ng-library/ionicons.css">
- <link rel="stylesheet" type="text/css" href="app/fusion/external/ds2/css/digital-ng-library/ecomp-ionicons.css">
-
- <link rel="stylesheet" type="text/css" href="app/fusion/external/angular-bootstrap/ui-bootstrap-csp.css">
- <link rel="stylesheet" type="text/css" href="app/fusion/external/angular-gridster/dist/angular-gridster.min.css">
- <link rel="stylesheet" type="text/css" href="static/fusion/sample/css/scribble.css" />
- <link rel="stylesheet" type="text/css" href="static/fusion/sample/css/welcome.css" />
-
- <link rel="stylesheet" type="text/css" href="app/fusion/styles/ecomp.css">
-
- <!-- Common scripts -->
- <script src="app/fusion/external/angular-1.4.13/angular.min.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-messages.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-touch.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-sanitize.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-route.min.js"></script>
- <script src="app/fusion/external/angular-1.4.13/angular-cookies.min.js"></script>
- <script src="app/fusion/external/jquery/dist/jquery.min.js"></script>
- <script src="app/fusion/external/javascript-detect-element-resize/jquery.resize.js"></script>
- <script src="app/fusion/external/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
- <script src="app/fusion/external/angular-gridster/dist/angular-gridster.min.js"></script>
-
- <!-- EPSDK App scripts and common services -->
- <!-- B2b Library -->
- <script src="app/fusion/external/b2b/js/b2b-angular/b2b-library.min.js"></script>
- <script src="app/fusion/scripts/DS2-services/ds2-modal/modalService.js"></script>
- <script src="app/fusion/external/ds2/js/appDS2.js"></script>
-
- <script src="app/fusion/scripts/DS2-services/userInfoServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-services/headerServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-services/leftMenuServiceDS2.js"></script>
- <script src="app/fusion/scripts/DS2-services/manifestService.js"></script>
-
- <script src="app/fusion/scripts/DS2-directives/footer.js"></script>
- <script src="app/fusion/scripts/DS2-directives/ds2Header.js"></script>
- <script src="app/fusion/scripts/DS2-directives/ds2LeftMenu.js"></script>
- <script src="app/fusion/scripts/DS2-directives/b2b-leftnav-ext.js"></script>
- <script src= "app/fusion/scripts/DS2-services/userInfoServiceDS2.js"></script>
-
- <!-- Page specific items -->
- <script src="app/fusion/scripts/DS2-controllers/welcome-controller.js"></script>
- <script src="app/fusion/scripts/DS2-controllers/welcome-route.js"></script>
-
-<style>
- .controls {
- margin-bottom: 20px;
- }
- .page-header {
- margin-top: 20px;
- }
- ul {
- list-style: none;
- }
- .box {
- height: 100%;
- border: 1px solid #ccc;
- background-color: #fff;
- position: relative;
- overflow: hidden;
- }
- .box-header {
- background-color: #eee;
- padding: 0px 0px 0px 0px;
- /* border-bottom: 1px solid #ccc; */
- margin-bottom: -25px;
- cursor: move;
- position: relative;
- }
- .box-header h3 {
- margin-top: 0px;
- display: inline-block;
- }
- .box-content {
- padding: 10px;
- display:block;
- height: 100%;
- position: relative;
- overflow-x:auto;
- overflow-y:auto;
- }
- .box-header-btns {
- top: 15px;
- right: 10px;
- cursor: pointer;
- position: absolute;
- }
-
- .gridster {
- border: none;
- position:relative;
- }
-
- .box-content .box-content-frame{
-
- }
-
- .box table{
- border:none;
- display:block;
- }
-
- .box table tr{
- line-height:20px;
- }
-
- .box table th{
- border:none;
- line-height:20px;
- }
-
- /* .header-container{
- margin-top:-50px;
- } */
- /* .content-container{
- margin-top:50px;
- } */
- .menu-container{
- margin-top:0px
- }
-
- .handle-e {
- width:3px;
- }
-</style>
-
-<link rel="stylesheet" type="text/css" href="app/ngapp/styles.css">
-</head>
-<body class="appBody">
- <app-root></app-root>
- <!-- commented the header for now to avoid duplicate headers on portal -->
- <div ds2-Header class="header-container" ></div>
- <div ds2-menu id="menuContainer" class="menu-container"></div>
- <div ng-view id="rightContentProfile" class="content-container"></div>
- <div ds2-Footer class="footer-container"></div>
-
- <script type="text/javascript" src="app/ngapp/runtime.js"></script>
- <script type="text/javascript" src="app/ngapp/polyfills.js"></script>
- <script type="text/javascript" src="app/ngapp/main.js"></script>
-
- </body>
-
-</body>
-</html>
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/polyfills.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/polyfills.ts
deleted file mode 100644
index b012103c..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/polyfills.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This file includes polyfills needed by Angular and is loaded before the app.
- * You can add your own extra polyfills to this file.
- *
- * This file is divided into 2 sections:
- * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
- * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
- * file.
- *
- * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
- * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
- * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
- *
- * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
- */
-
-/***************************************************************************************************
- * BROWSER POLYFILLS
- */
-
-/** IE9, IE10 and IE11 requires all of the following polyfills. **/
- import 'core-js/es6/symbol';
- import 'core-js/es6/object';
- import 'core-js/es6/function';
- import 'core-js/es6/parse-int';
- import 'core-js/es6/parse-float';
- import 'core-js/es6/number';
- import 'core-js/es6/math';
- import 'core-js/es6/string';
- import 'core-js/es6/date';
- import 'core-js/es6/array';
- import 'core-js/es6/regexp';
- import 'core-js/es6/map';
- import 'core-js/es6/weak-map';
- import 'core-js/es6/set';
-
-/** IE10 and IE11 requires the following for NgClass support on SVG elements */
-// import 'classlist.js'; // Run `npm install --save classlist.js`.
-
-/** IE10 and IE11 requires the following for the Reflect API. */
-// import 'core-js/es6/reflect';
-
-
-/** Evergreen browsers require these. **/
-// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
-import 'core-js/es7/reflect';
-
-
-/**
- * Web Animations `@angular/platform-browser/animations`
- * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
- * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
- **/
-// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
-
-/**
- * By default, zone.js will patch all possible macroTask and DomEvents
- * user can disable parts of macroTask/DomEvents patch by setting following flags
- */
-
- // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
- // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
- // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
-
- /*
- * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
- * with the following flag, it will bypass `zone.js` patch for IE/Edge
- */
-// (window as any).__Zone_enable_cross_context_check = true;
-
-/***************************************************************************************************
- * Zone JS is required by default for Angular itself.
- */
-import 'zone.js/dist/zone'; // Included with Angular CLI.
-
-
-
-/***************************************************************************************************
- * APPLICATION IMPORTS
- */
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles.css b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles.css
deleted file mode 100644
index 90d4ee00..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles.css
+++ /dev/null
@@ -1 +0,0 @@
-/* You can add global styles to this file, and also import other style files */
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_responsive.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_responsive.scss
new file mode 100644
index 00000000..b56b3c65
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_responsive.scss
@@ -0,0 +1,7 @@
+@media screen and (max-width: 992px) {
+ .push-right {
+ .sidebar {
+ left: 235px !important;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_utils.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_utils.scss
new file mode 100644
index 00000000..2c47f5e2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/_utils.scss
@@ -0,0 +1,3 @@
+.fs-12 {
+ font-size: 12px;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/app.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/app.scss
new file mode 100644
index 00000000..8e1bc797
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/app.scss
@@ -0,0 +1,11 @@
+/* You can add global styles to this file, and also import other style files */
+@import "bootstrap/bootstrap";
+@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';
+@import "utils";
+@import "responsive";
+
+@media print {
+ .breadcrumb {
+ display: none !important;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_alert.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_alert.scss
new file mode 100644
index 00000000..c2d5c810
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_alert.scss
@@ -0,0 +1,51 @@
+//
+// Base styles
+//
+
+.alert {
+ position: relative;
+ padding: $alert-padding-y $alert-padding-x;
+ margin-bottom: $alert-margin-bottom;
+ border: $alert-border-width solid transparent;
+ @include border-radius($alert-border-radius);
+}
+
+// Headings for larger alerts
+.alert-heading {
+ // Specified to prevent conflicts of changing $headings-color
+ color: inherit;
+}
+
+// Provide class for links that match alerts
+.alert-link {
+ font-weight: $alert-link-font-weight;
+}
+
+
+// Dismissible alerts
+//
+// Expand the right padding and account for the close button's positioning.
+
+.alert-dismissible {
+ padding-right: ($close-font-size + $alert-padding-x * 2);
+
+ // Adjust close link position
+ .close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: $alert-padding-y $alert-padding-x;
+ color: inherit;
+ }
+}
+
+
+// Alternate styles
+//
+// Generate contextual modifier classes for colorizing the alert.
+
+@each $color, $value in $theme-colors {
+ .alert-#{$color} {
+ @include alert-variant(theme-color-level($color, -10), theme-color-level($color, -9), theme-color-level($color, 6));
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_badge.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_badge.scss
new file mode 100644
index 00000000..b87a1b00
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_badge.scss
@@ -0,0 +1,47 @@
+// Base class
+//
+// Requires one of the contextual, color modifier classes for `color` and
+// `background-color`.
+
+.badge {
+ display: inline-block;
+ padding: $badge-padding-y $badge-padding-x;
+ font-size: $badge-font-size;
+ font-weight: $badge-font-weight;
+ line-height: 1;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ @include border-radius($badge-border-radius);
+
+ // Empty badges collapse automatically
+ &:empty {
+ display: none;
+ }
+}
+
+// Quick fix for badges in buttons
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+// Pill badges
+//
+// Make them extra rounded with a modifier to replace v3's badges.
+
+.badge-pill {
+ padding-right: $badge-pill-padding-x;
+ padding-left: $badge-pill-padding-x;
+ @include border-radius($badge-pill-border-radius);
+}
+
+// Colors
+//
+// Contextual variations (linked badges get darker on :hover).
+
+@each $color, $value in $theme-colors {
+ .badge-#{$color} {
+ @include badge-variant($value);
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_breadcrumb.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_breadcrumb.scss
new file mode 100644
index 00000000..25b9d85a
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_breadcrumb.scss
@@ -0,0 +1,38 @@
+.breadcrumb {
+ display: flex;
+ flex-wrap: wrap;
+ padding: $breadcrumb-padding-y $breadcrumb-padding-x;
+ margin-bottom: $breadcrumb-margin-bottom;
+ list-style: none;
+ background-color: $breadcrumb-bg;
+ @include border-radius($border-radius);
+}
+
+.breadcrumb-item {
+ // The separator between breadcrumbs (by default, a forward-slash: "/")
+ + .breadcrumb-item::before {
+ display: inline-block; // Suppress underlining of the separator in modern browsers
+ padding-right: $breadcrumb-item-padding;
+ padding-left: $breadcrumb-item-padding;
+ color: $breadcrumb-divider-color;
+ content: "#{$breadcrumb-divider}";
+ }
+
+ // IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
+ // without `<ul>`s. The `::before` pseudo-element generates an element
+ // *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
+ //
+ // To trick IE into suppressing the underline, we give the pseudo-element an
+ // underline and then immediately remove it.
+ + .breadcrumb-item:hover::before {
+ text-decoration: underline;
+ }
+ // stylelint-disable-next-line no-duplicate-selectors
+ + .breadcrumb-item:hover::before {
+ text-decoration: none;
+ }
+
+ &.active {
+ color: $breadcrumb-active-color;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_button-group.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_button-group.scss
new file mode 100644
index 00000000..c1b82653
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_button-group.scss
@@ -0,0 +1,166 @@
+// stylelint-disable selector-no-qualifying-type
+
+// Make the div behave like a button
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-flex;
+ vertical-align: middle; // match .btn alignment given font-size hack above
+
+ > .btn {
+ position: relative;
+ flex: 0 1 auto;
+
+ // Bring the hover, focused, and "active" buttons to the front to overlay
+ // the borders properly
+ @include hover {
+ z-index: 1;
+ }
+ &:focus,
+ &:active,
+ &.active {
+ z-index: 1;
+ }
+ }
+
+ // Prevent double borders when buttons are next to each other
+ .btn + .btn,
+ .btn + .btn-group,
+ .btn-group + .btn,
+ .btn-group + .btn-group {
+ margin-left: -$btn-border-width;
+ }
+}
+
+// Optional: Group multiple button groups together for a toolbar
+.btn-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+
+ .input-group {
+ width: auto;
+ }
+}
+
+.btn-group {
+ > .btn:first-child {
+ margin-left: 0;
+ }
+
+ // Reset rounded corners
+ > .btn:not(:last-child):not(.dropdown-toggle),
+ > .btn-group:not(:last-child) > .btn {
+ @include border-right-radius(0);
+ }
+
+ > .btn:not(:first-child),
+ > .btn-group:not(:first-child) > .btn {
+ @include border-left-radius(0);
+ }
+}
+
+// Sizing
+//
+// Remix the default button sizing classes into new ones for easier manipulation.
+
+.btn-group-sm > .btn { @extend .btn-sm; }
+.btn-group-lg > .btn { @extend .btn-lg; }
+
+
+//
+// Split button dropdowns
+//
+
+.dropdown-toggle-split {
+ padding-right: $btn-padding-x * .75;
+ padding-left: $btn-padding-x * .75;
+
+ &::after {
+ margin-left: 0;
+ }
+}
+
+.btn-sm + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-sm * .75;
+ padding-left: $btn-padding-x-sm * .75;
+}
+
+.btn-lg + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-lg * .75;
+ padding-left: $btn-padding-x-lg * .75;
+}
+
+
+// The clickable button for toggling the menu
+// Set the same inset shadow as the :active state
+.btn-group.show .dropdown-toggle {
+ @include box-shadow($btn-active-box-shadow);
+
+ // Show no shadow for `.btn-link` since it has no other button styles.
+ &.btn-link {
+ @include box-shadow(none);
+ }
+}
+
+
+//
+// Vertical button groups
+//
+
+.btn-group-vertical {
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+
+ .btn,
+ .btn-group {
+ width: 100%;
+ }
+
+ > .btn + .btn,
+ > .btn + .btn-group,
+ > .btn-group + .btn,
+ > .btn-group + .btn-group {
+ margin-top: -$btn-border-width;
+ margin-left: 0;
+ }
+
+ // Reset rounded corners
+ > .btn:not(:last-child):not(.dropdown-toggle),
+ > .btn-group:not(:last-child) > .btn {
+ @include border-bottom-radius(0);
+ }
+
+ > .btn:not(:first-child),
+ > .btn-group:not(:first-child) > .btn {
+ @include border-top-radius(0);
+ }
+}
+
+
+// Checkbox and radio options
+//
+// In order to support the browser's form validation feedback, powered by the
+// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
+// `display: none;` or `visibility: hidden;` as that also hides the popover.
+// Simply visually hiding the inputs via `opacity` would leave them clickable in
+// certain cases which is prevented by using `clip` and `pointer-events`.
+// This way, we ensure a DOM element is visible to position the popover from.
+//
+// See https://github.com/twbs/bootstrap/pull/12794 and
+// https://github.com/twbs/bootstrap/pull/14559 for more information.
+
+.btn-group-toggle {
+ > .btn,
+ > .btn-group > .btn {
+ margin-bottom: 0; // Override default `<label>` value
+
+ input[type="radio"],
+ input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_buttons.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_buttons.scss
new file mode 100644
index 00000000..3a5f5ee8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_buttons.scss
@@ -0,0 +1,147 @@
+// stylelint-disable selector-no-qualifying-type
+
+//
+// Base styles
+//
+
+.btn {
+ display: inline-block;
+ font-weight: $btn-font-weight;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ user-select: none;
+ border: $btn-border-width solid transparent;
+ @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $btn-line-height, $btn-border-radius);
+ @include transition($btn-transition);
+
+ // Share hover and focus styles
+ @include hover-focus {
+ text-decoration: none;
+ }
+
+ &:focus,
+ &.focus {
+ outline: 0;
+ box-shadow: $btn-focus-box-shadow;
+ }
+
+ // Disabled comes first so active can properly restyle
+ &.disabled,
+ &:disabled {
+ opacity: $btn-disabled-opacity;
+ @include box-shadow(none);
+ }
+
+ // Opinionated: add "hand" cursor to non-disabled .btn elements
+ &:not([disabled]):not(.disabled) {
+ cursor: pointer;
+ }
+
+ &:not([disabled]):not(.disabled):active,
+ &:not([disabled]):not(.disabled).active {
+ background-image: none;
+ @include box-shadow($btn-active-box-shadow);
+
+ &:focus {
+ @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
+ }
+ }
+}
+
+// Future-proof disabling of clicks on `<a>` elements
+a.btn.disabled,
+fieldset[disabled] a.btn {
+ pointer-events: none;
+}
+
+
+//
+// Alternate buttons
+//
+
+@each $color, $value in $theme-colors {
+ .btn-#{$color} {
+ @include button-variant($value, $value);
+ }
+}
+
+@each $color, $value in $theme-colors {
+ .btn-outline-#{$color} {
+ @if $color == "light" {
+ @include button-outline-variant($value, $gray-900);
+ } @else {
+ @include button-outline-variant($value, $white);
+ }
+ }
+}
+
+
+//
+// Link buttons
+//
+
+// Make a button look and behave like a link
+.btn-link {
+ font-weight: $font-weight-normal;
+ color: $link-color;
+ background-color: transparent;
+
+ @include hover {
+ color: $link-hover-color;
+ text-decoration: $link-hover-decoration;
+ background-color: transparent;
+ border-color: transparent;
+ }
+
+ &:focus,
+ &.focus {
+ text-decoration: $link-hover-decoration;
+ border-color: transparent;
+ box-shadow: none;
+ }
+
+ &:disabled,
+ &.disabled {
+ color: $btn-link-disabled-color;
+ }
+
+ // No need for an active state here
+}
+
+
+//
+// Button Sizes
+//
+
+.btn-lg {
+ @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
+}
+
+.btn-sm {
+ @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
+}
+
+
+//
+// Block button
+//
+
+.btn-block {
+ display: block;
+ width: 100%;
+
+ // Vertically space out multiple block buttons
+ + .btn-block {
+ margin-top: $btn-block-spacing-y;
+ }
+}
+
+// Specificity overrides
+input[type="submit"],
+input[type="reset"],
+input[type="button"] {
+ &.btn-block {
+ width: 100%;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_card.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_card.scss
new file mode 100644
index 00000000..4c4845c0
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_card.scss
@@ -0,0 +1,270 @@
+//
+// Base styles
+//
+
+.card {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+ word-wrap: break-word;
+ background-color: $card-bg;
+ background-clip: border-box;
+ border: $card-border-width solid $card-border-color;
+ @include border-radius($card-border-radius);
+
+ > hr {
+ margin-right: 0;
+ margin-left: 0;
+ }
+
+ > .list-group:first-child {
+ .list-group-item:first-child {
+ @include border-top-radius($card-border-radius);
+ }
+ }
+
+ > .list-group:last-child {
+ .list-group-item:last-child {
+ @include border-bottom-radius($card-border-radius);
+ }
+ }
+}
+
+.card-body {
+ // Enable `flex-grow: 1` for decks and groups so that card blocks take up
+ // as much space as possible, ensuring footers are aligned to the bottom.
+ flex: 1 1 auto;
+ padding: $card-spacer-x;
+}
+
+.card-title {
+ margin-bottom: $card-spacer-y;
+}
+
+.card-subtitle {
+ margin-top: -($card-spacer-y / 2);
+ margin-bottom: 0;
+}
+
+.card-text:last-child {
+ margin-bottom: 0;
+}
+
+.card-link {
+ @include hover {
+ text-decoration: none;
+ }
+
+ + .card-link {
+ margin-left: $card-spacer-x;
+ }
+}
+
+//
+// Optional textual caps
+//
+
+.card-header {
+ padding: $card-spacer-y $card-spacer-x;
+ margin-bottom: 0; // Removes the default margin-bottom of <hN>
+ background-color: $card-cap-bg;
+ border-bottom: $card-border-width solid $card-border-color;
+
+ &:first-child {
+ @include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
+ }
+
+ + .list-group {
+ .list-group-item:first-child {
+ border-top: 0;
+ }
+ }
+}
+
+.card-footer {
+ padding: $card-spacer-y $card-spacer-x;
+ background-color: $card-cap-bg;
+ border-top: $card-border-width solid $card-border-color;
+
+ &:last-child {
+ @include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
+ }
+}
+
+
+//
+// Header navs
+//
+
+.card-header-tabs {
+ margin-right: -($card-spacer-x / 2);
+ margin-bottom: -$card-spacer-y;
+ margin-left: -($card-spacer-x / 2);
+ border-bottom: 0;
+}
+
+.card-header-pills {
+ margin-right: -($card-spacer-x / 2);
+ margin-left: -($card-spacer-x / 2);
+}
+
+// Card image
+.card-img-overlay {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: $card-img-overlay-padding;
+}
+
+.card-img {
+ width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
+ @include border-radius($card-inner-border-radius);
+}
+
+// Card image caps
+.card-img-top {
+ width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
+ @include border-top-radius($card-inner-border-radius);
+}
+
+.card-img-bottom {
+ width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
+ @include border-bottom-radius($card-inner-border-radius);
+}
+
+
+// Card deck
+
+.card-deck {
+ display: flex;
+ flex-direction: column;
+
+ .card {
+ margin-bottom: $card-deck-margin;
+ }
+
+ @include media-breakpoint-up(sm) {
+ flex-flow: row wrap;
+ margin-right: -$card-deck-margin;
+ margin-left: -$card-deck-margin;
+
+ .card {
+ display: flex;
+ // Flexbugs #4: https://github.com/philipwalton/flexbugs#4-flex-shorthand-declarations-with-unitless-flex-basis-values-are-ignored
+ flex: 1 0 0%;
+ flex-direction: column;
+ margin-right: $card-deck-margin;
+ margin-bottom: 0; // Override the default
+ margin-left: $card-deck-margin;
+ }
+ }
+}
+
+
+//
+// Card groups
+//
+
+.card-group {
+ display: flex;
+ flex-direction: column;
+
+ // The child selector allows nested `.card` within `.card-group`
+ // to display properly.
+ > .card {
+ margin-bottom: $card-group-margin;
+ }
+
+ @include media-breakpoint-up(sm) {
+ flex-flow: row wrap;
+ // The child selector allows nested `.card` within `.card-group`
+ // to display properly.
+ > .card {
+ // Flexbugs #4: https://github.com/philipwalton/flexbugs#4-flex-shorthand-declarations-with-unitless-flex-basis-values-are-ignored
+ flex: 1 0 0%;
+ margin-bottom: 0;
+
+ + .card {
+ margin-left: 0;
+ border-left: 0;
+ }
+
+ // Handle rounded corners
+ @if $enable-rounded {
+ &:first-child {
+ @include border-right-radius(0);
+
+ .card-img-top,
+ .card-header {
+ border-top-right-radius: 0;
+ }
+ .card-img-bottom,
+ .card-footer {
+ border-bottom-right-radius: 0;
+ }
+ }
+
+ &:last-child {
+ @include border-left-radius(0);
+
+ .card-img-top,
+ .card-header {
+ border-top-left-radius: 0;
+ }
+ .card-img-bottom,
+ .card-footer {
+ border-bottom-left-radius: 0;
+ }
+ }
+
+ &:only-child {
+ @include border-radius($card-border-radius);
+
+ .card-img-top,
+ .card-header {
+ @include border-top-radius($card-border-radius);
+ }
+ .card-img-bottom,
+ .card-footer {
+ @include border-bottom-radius($card-border-radius);
+ }
+ }
+
+ &:not(:first-child):not(:last-child):not(:only-child) {
+ @include border-radius(0);
+
+ .card-img-top,
+ .card-img-bottom,
+ .card-header,
+ .card-footer {
+ @include border-radius(0);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//
+// Columns
+//
+
+.card-columns {
+ .card {
+ margin-bottom: $card-columns-margin;
+ }
+
+ @include media-breakpoint-up(sm) {
+ column-count: $card-columns-count;
+ column-gap: $card-columns-gap;
+
+ .card {
+ display: inline-block; // Don't let them vertically span multiple columns
+ width: 100%; // Don't let their width change
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_carousel.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_carousel.scss
new file mode 100644
index 00000000..72a50344
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_carousel.scss
@@ -0,0 +1,191 @@
+// Wrapper for the slide container and indicators
+.carousel {
+ position: relative;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.carousel-item {
+ position: relative;
+ display: none;
+ align-items: center;
+ width: 100%;
+ @include transition($carousel-transition);
+ backface-visibility: hidden;
+ perspective: 1000px;
+}
+
+.carousel-item.active,
+.carousel-item-next,
+.carousel-item-prev {
+ display: block;
+}
+
+.carousel-item-next,
+.carousel-item-prev {
+ position: absolute;
+ top: 0;
+}
+
+// CSS3 transforms when supported by the browser
+.carousel-item-next.carousel-item-left,
+.carousel-item-prev.carousel-item-right {
+ transform: translateX(0);
+
+ @supports (transform-style: preserve-3d) {
+ transform: translate3d(0, 0, 0);
+ }
+}
+
+.carousel-item-next,
+.active.carousel-item-right {
+ transform: translateX(100%);
+
+ @supports (transform-style: preserve-3d) {
+ transform: translate3d(100%, 0, 0);
+ }
+}
+
+.carousel-item-prev,
+.active.carousel-item-left {
+ transform: translateX(-100%);
+
+ @supports (transform-style: preserve-3d) {
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+
+
+//
+// Left/right controls for nav
+//
+
+.carousel-control-prev,
+.carousel-control-next {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ // Use flex for alignment (1-3)
+ display: flex; // 1. allow flex styles
+ align-items: center; // 2. vertically center contents
+ justify-content: center; // 3. horizontally center contents
+ width: $carousel-control-width;
+ color: $carousel-control-color;
+ text-align: center;
+ opacity: $carousel-control-opacity;
+ // We can't have a transition here because WebKit cancels the carousel
+ // animation if you trip this while in the middle of another animation.
+
+ // Hover/focus state
+ @include hover-focus {
+ color: $carousel-control-color;
+ text-decoration: none;
+ outline: 0;
+ opacity: .9;
+ }
+}
+.carousel-control-prev {
+ left: 0;
+ @if $enable-gradients {
+ background: linear-gradient(90deg, rgba(0, 0, 0, .25), rgba(0, 0, 0, .001));
+ }
+}
+.carousel-control-next {
+ right: 0;
+ @if $enable-gradients {
+ background: linear-gradient(270deg, rgba(0, 0, 0, .25), rgba(0, 0, 0, .001));
+ }
+}
+
+// Icons for within
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+ display: inline-block;
+ width: $carousel-control-icon-width;
+ height: $carousel-control-icon-width;
+ background: transparent no-repeat center center;
+ background-size: 100% 100%;
+}
+.carousel-control-prev-icon {
+ background-image: $carousel-control-prev-icon-bg;
+}
+.carousel-control-next-icon {
+ background-image: $carousel-control-next-icon-bg;
+}
+
+
+// Optional indicator pips
+//
+// Add an ordered list with the following class and add a list item for each
+// slide your carousel holds.
+
+.carousel-indicators {
+ position: absolute;
+ right: 0;
+ bottom: 10px;
+ left: 0;
+ z-index: 15;
+ display: flex;
+ justify-content: center;
+ padding-left: 0; // override <ol> default
+ // Use the .carousel-control's width as margin so we don't overlay those
+ margin-right: $carousel-control-width;
+ margin-left: $carousel-control-width;
+ list-style: none;
+
+ li {
+ position: relative;
+ flex: 0 1 auto;
+ width: $carousel-indicator-width;
+ height: $carousel-indicator-height;
+ margin-right: $carousel-indicator-spacer;
+ margin-left: $carousel-indicator-spacer;
+ text-indent: -999px;
+ background-color: rgba($carousel-indicator-active-bg, .5);
+
+ // Use pseudo classes to increase the hit area by 10px on top and bottom.
+ &::before {
+ position: absolute;
+ top: -10px;
+ left: 0;
+ display: inline-block;
+ width: 100%;
+ height: 10px;
+ content: "";
+ }
+ &::after {
+ position: absolute;
+ bottom: -10px;
+ left: 0;
+ display: inline-block;
+ width: 100%;
+ height: 10px;
+ content: "";
+ }
+ }
+
+ .active {
+ background-color: $carousel-indicator-active-bg;
+ }
+}
+
+
+// Optional captions
+//
+//
+
+.carousel-caption {
+ position: absolute;
+ right: ((100% - $carousel-caption-width) / 2);
+ bottom: 20px;
+ left: ((100% - $carousel-caption-width) / 2);
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: $carousel-caption-color;
+ text-align: center;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_close.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_close.scss
new file mode 100644
index 00000000..f1763cc2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_close.scss
@@ -0,0 +1,34 @@
+.close {
+ float: right;
+ font-size: $close-font-size;
+ font-weight: $close-font-weight;
+ line-height: 1;
+ color: $close-color;
+ text-shadow: $close-text-shadow;
+ opacity: .5;
+
+ @include hover-focus {
+ color: $close-color;
+ text-decoration: none;
+ opacity: .75;
+ }
+
+ // Opinionated: add "hand" cursor to non-disabled .close elements
+ &:not([disabled]):not(.disabled) {
+ cursor: pointer;
+ }
+}
+
+// Additional properties for button version
+// iOS requires the button element instead of an anchor tag.
+// If you want the anchor version, it requires `href="#"`.
+// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
+
+// stylelint-disable property-no-vendor-prefix, selector-no-qualifying-type
+button.close {
+ padding: 0;
+ background-color: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+// stylelint-enable
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_code.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_code.scss
new file mode 100644
index 00000000..9de20fa0
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_code.scss
@@ -0,0 +1,56 @@
+// Inline and block code styles
+code,
+kbd,
+pre,
+samp {
+ font-family: $font-family-monospace;
+}
+
+// Inline code
+code {
+ font-size: $code-font-size;
+ color: $code-color;
+ word-break: break-word;
+
+ // Streamline the style when inside anchors to avoid broken underline and more
+ a > & {
+ color: inherit;
+ }
+}
+
+// User input typically entered via keyboard
+kbd {
+ padding: $kbd-padding-y $kbd-padding-x;
+ font-size: $kbd-font-size;
+ color: $kbd-color;
+ background-color: $kbd-bg;
+ @include border-radius($border-radius-sm);
+ @include box-shadow($kbd-box-shadow);
+
+ kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: $nested-kbd-font-weight;
+ @include box-shadow(none);
+ }
+}
+
+// Blocks of code
+pre {
+ display: block;
+ font-size: $code-font-size;
+ color: $pre-color;
+
+ // Account for some code outputs that place code tags in pre tags
+ code {
+ font-size: inherit;
+ color: inherit;
+ word-break: normal;
+ }
+}
+
+// Enable scrollable blocks of code
+.pre-scrollable {
+ max-height: $pre-scrollable-max-height;
+ overflow-y: scroll;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_custom-forms.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_custom-forms.scss
new file mode 100644
index 00000000..d99a86dc
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_custom-forms.scss
@@ -0,0 +1,282 @@
+// Embedded icons from Open Iconic.
+// Released under MIT and copyright 2014 Waybury.
+// https://useiconic.com/open
+
+
+// Checkboxes and radios
+//
+// Base class takes care of all the key behavioral aspects.
+
+.custom-control {
+ position: relative;
+ display: block;
+ min-height: (1rem * $line-height-base);
+ padding-left: $custom-control-gutter;
+}
+
+.custom-control-inline {
+ display: inline-flex;
+ margin-right: $custom-control-spacer-x;
+}
+
+.custom-control-input {
+ position: absolute;
+ z-index: -1; // Put the input behind the label so it doesn't overlay text
+ opacity: 0;
+
+ &:checked ~ .custom-control-label::before {
+ color: $custom-control-indicator-checked-color;
+ @include gradient-bg($custom-control-indicator-checked-bg);
+ @include box-shadow($custom-control-indicator-checked-box-shadow);
+ }
+
+ &:focus ~ .custom-control-label::before {
+ // the mixin is not used here to make sure there is feedback
+ box-shadow: $custom-control-indicator-focus-box-shadow;
+ }
+
+ &:active ~ .custom-control-label::before {
+ color: $custom-control-indicator-active-color;
+ background-color: $custom-control-indicator-active-bg;
+ @include box-shadow($custom-control-indicator-active-box-shadow);
+ }
+
+ &:disabled {
+ ~ .custom-control-label {
+ color: $custom-control-label-disabled-color;
+
+ &::before {
+ background-color: $custom-control-indicator-disabled-bg;
+ }
+ }
+ }
+}
+
+// Custom control indicators
+//
+// Build the custom controls out of psuedo-elements.
+
+.custom-control-label {
+ margin-bottom: 0;
+
+ // Background-color and (when enabled) gradient
+ &::before {
+ position: absolute;
+ top: (($line-height-base - $custom-control-indicator-size) / 2);
+ left: 0;
+ display: block;
+ width: $custom-control-indicator-size;
+ height: $custom-control-indicator-size;
+ pointer-events: none;
+ content: "";
+ user-select: none;
+ background-color: $custom-control-indicator-bg;
+ @include box-shadow($custom-control-indicator-box-shadow);
+ }
+
+ // Foreground (icon)
+ &::after {
+ position: absolute;
+ top: (($line-height-base - $custom-control-indicator-size) / 2);
+ left: 0;
+ display: block;
+ width: $custom-control-indicator-size;
+ height: $custom-control-indicator-size;
+ content: "";
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: $custom-control-indicator-bg-size;
+ }
+}
+
+
+// Checkboxes
+//
+// Tweak just a few things for checkboxes.
+
+.custom-checkbox {
+ .custom-control-label::before {
+ @include border-radius($custom-checkbox-indicator-border-radius);
+ }
+
+ .custom-control-input:checked ~ .custom-control-label {
+ &::before {
+ @include gradient-bg($custom-control-indicator-checked-bg);
+ }
+ &::after {
+ background-image: $custom-checkbox-indicator-icon-checked;
+ }
+ }
+
+ .custom-control-input:indeterminate ~ .custom-control-label {
+ &::before {
+ @include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
+ @include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
+ }
+ &::after {
+ background-image: $custom-checkbox-indicator-icon-indeterminate;
+ }
+ }
+}
+
+// Radios
+//
+// Tweak just a few things for radios.
+
+.custom-radio {
+ .custom-control-label::before {
+ border-radius: $custom-radio-indicator-border-radius;
+ }
+
+ .custom-control-input:checked ~ .custom-control-label {
+ &::before {
+ @include gradient-bg($custom-control-indicator-checked-bg);
+ }
+ &::after {
+ background-image: $custom-radio-indicator-icon-checked;
+ }
+ }
+}
+
+
+// Select
+//
+// Replaces the browser default select with a custom one, mostly pulled from
+// http://primercss.io.
+//
+
+.custom-select {
+ display: inline-block;
+ width: 100%;
+ height: $input-height;
+ padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
+ line-height: $custom-select-line-height;
+ color: $custom-select-color;
+ vertical-align: middle;
+ background: $custom-select-bg $custom-select-indicator no-repeat right $custom-select-padding-x center;
+ background-size: $custom-select-bg-size;
+ border: $custom-select-border-width solid $custom-select-border-color;
+ @if $enable-rounded {
+ border-radius: $custom-select-border-radius;
+ } @else {
+ border-radius: 0;
+ }
+ appearance: none;
+
+ &:focus {
+ border-color: $custom-select-focus-border-color;
+ outline: 0;
+ box-shadow: $custom-select-focus-box-shadow;
+
+ &::-ms-value {
+ // For visual consistency with other platforms/browsers,
+ // suppress the default white text on blue background highlight given to
+ // the selected option text when the (still closed) <select> receives focus
+ // in IE and (under certain conditions) Edge.
+ // See https://github.com/twbs/bootstrap/issues/19398.
+ color: $input-color;
+ background-color: $input-bg;
+ }
+ }
+
+ &[multiple],
+ &[size]:not([size="1"]) {
+ height: auto;
+ padding-right: $custom-select-padding-x;
+ background-image: none;
+ }
+
+ &:disabled {
+ color: $custom-select-disabled-color;
+ background-color: $custom-select-disabled-bg;
+ }
+
+ // Hides the default caret in IE11
+ &::-ms-expand {
+ opacity: 0;
+ }
+}
+
+.custom-select-sm {
+ height: $custom-select-height-sm;
+ padding-top: $custom-select-padding-y;
+ padding-bottom: $custom-select-padding-y;
+ font-size: $custom-select-font-size-sm;
+}
+
+.custom-select-lg {
+ height: $custom-select-height-lg;
+ padding-top: $custom-select-padding-y;
+ padding-bottom: $custom-select-padding-y;
+ font-size: $custom-select-font-size-lg;
+}
+
+
+// File
+//
+// Custom file input.
+
+.custom-file {
+ position: relative;
+ display: inline-block;
+ width: 100%;
+ height: $custom-file-height;
+ margin-bottom: 0;
+}
+
+.custom-file-input {
+ position: relative;
+ z-index: 2;
+ width: 100%;
+ height: $custom-file-height;
+ margin: 0;
+ opacity: 0;
+
+ &:focus ~ .custom-file-control {
+ border-color: $custom-file-focus-border-color;
+ box-shadow: $custom-file-focus-box-shadow;
+
+ &::before {
+ border-color: $custom-file-focus-border-color;
+ }
+ }
+
+ @each $lang, $value in $custom-file-text {
+ &:lang(#{$lang}) ~ .custom-file-label::after {
+ content: $value;
+ }
+ }
+}
+
+.custom-file-label {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 1;
+ height: $custom-file-height;
+ padding: $custom-file-padding-y $custom-file-padding-x;
+ line-height: $custom-file-line-height;
+ color: $custom-file-color;
+ background-color: $custom-file-bg;
+ border: $custom-file-border-width solid $custom-file-border-color;
+ @include border-radius($custom-file-border-radius);
+ @include box-shadow($custom-file-box-shadow);
+
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 3;
+ display: block;
+ height: calc(#{$custom-file-height} - #{$custom-file-border-width} * 2);
+ padding: $custom-file-padding-y $custom-file-padding-x;
+ line-height: $custom-file-line-height;
+ color: $custom-file-button-color;
+ content: "Browse";
+ @include gradient-bg($custom-file-button-bg);
+ border-left: $custom-file-border-width solid $custom-file-border-color;
+ @include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_dropdown.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_dropdown.scss
new file mode 100644
index 00000000..a9d4cfed
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_dropdown.scss
@@ -0,0 +1,131 @@
+// The dropdown wrapper (`<div>`)
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle {
+ // Generate the caret automatically
+ @include caret;
+}
+
+// The dropdown menu
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: $zindex-dropdown;
+ display: none; // none by default, but block on "open" of the menu
+ float: left;
+ min-width: $dropdown-min-width;
+ padding: $dropdown-padding-y 0;
+ margin: $dropdown-spacer 0 0; // override default ul
+ font-size: $font-size-base; // Redeclare because nesting can cause inheritance issues
+ color: $body-color;
+ text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
+ list-style: none;
+ background-color: $dropdown-bg;
+ background-clip: padding-box;
+ border: $dropdown-border-width solid $dropdown-border-color;
+ @include border-radius($dropdown-border-radius);
+ @include box-shadow($dropdown-box-shadow);
+}
+
+// Allow for dropdowns to go bottom up (aka, dropup-menu)
+// Just add .dropup after the standard .dropdown class and you're set.
+.dropup {
+ .dropdown-menu {
+ margin-top: 0;
+ margin-bottom: $dropdown-spacer;
+ }
+
+ .dropdown-toggle {
+ @include caret(up);
+ }
+}
+
+.dropright {
+ .dropdown-menu {
+ margin-top: 0;
+ margin-left: $dropdown-spacer;
+ }
+
+ .dropdown-toggle {
+ @include caret(right);
+ &::after {
+ vertical-align: 0;
+ }
+ }
+}
+
+.dropleft {
+ .dropdown-menu {
+ margin-top: 0;
+ margin-right: $dropdown-spacer;
+ }
+
+ .dropdown-toggle {
+ @include caret(left);
+ &::before {
+ vertical-align: 0;
+ }
+ }
+}
+
+// Dividers (basically an `<hr>`) within the dropdown
+.dropdown-divider {
+ @include nav-divider($dropdown-divider-bg);
+}
+
+// Links, buttons, and more within the dropdown menu
+//
+// `<button>`-specific styles are denoted with `// For <button>s`
+.dropdown-item {
+ display: block;
+ width: 100%; // For `<button>`s
+ padding: $dropdown-item-padding-y $dropdown-item-padding-x;
+ clear: both;
+ font-weight: $font-weight-normal;
+ color: $dropdown-link-color;
+ text-align: inherit; // For `<button>`s
+ white-space: nowrap; // prevent links from randomly breaking onto new lines
+ background-color: transparent; // For `<button>`s
+ border: 0; // For `<button>`s
+
+ @include hover-focus {
+ color: $dropdown-link-hover-color;
+ text-decoration: none;
+ @include gradient-bg($dropdown-link-hover-bg);
+ }
+
+ &.active,
+ &:active {
+ color: $dropdown-link-active-color;
+ text-decoration: none;
+ @include gradient-bg($dropdown-link-active-bg);
+ }
+
+ &.disabled,
+ &:disabled {
+ color: $dropdown-link-disabled-color;
+ background-color: transparent;
+ // Remove CSS gradients if they're enabled
+ @if $enable-gradients {
+ background-image: none;
+ }
+ }
+}
+
+.dropdown-menu.show {
+ display: block;
+}
+
+// Dropdown section headers
+.dropdown-header {
+ display: block;
+ padding: $dropdown-padding-y $dropdown-item-padding-x;
+ margin-bottom: 0; // for use with heading elements
+ font-size: $font-size-sm;
+ color: $dropdown-header-color;
+ white-space: nowrap; // as with > li > a
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_forms.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_forms.scss
new file mode 100644
index 00000000..b0954f8c
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_forms.scss
@@ -0,0 +1,333 @@
+// stylelint-disable selector-no-qualifying-type
+
+//
+// Textual form controls
+//
+
+.form-control {
+ display: block;
+ width: 100%;
+ padding: $input-padding-y $input-padding-x;
+ font-size: $font-size-base;
+ line-height: $input-line-height;
+ color: $input-color;
+ background-color: $input-bg;
+ background-clip: padding-box;
+ border: $input-border-width solid $input-border-color;
+
+ // Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
+ @if $enable-rounded {
+ // Manually use the if/else instead of the mixin to account for iOS override
+ border-radius: $input-border-radius;
+ } @else {
+ // Otherwise undo the iOS default
+ border-radius: 0;
+ }
+
+ @include box-shadow($input-box-shadow);
+ @include transition($input-transition);
+
+ // Unstyle the caret on `<select>`s in IE10+.
+ &::-ms-expand {
+ background-color: transparent;
+ border: 0;
+ }
+
+ // Customize the `:focus` state to imitate native WebKit styles.
+ @include form-control-focus();
+
+ // Placeholder
+ &::placeholder {
+ color: $input-placeholder-color;
+ // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
+ opacity: 1;
+ }
+
+ // Disabled and read-only inputs
+ //
+ // HTML5 says that controls under a fieldset > legend:first-child won't be
+ // disabled if the fieldset is disabled. Due to implementation difficulty, we
+ // don't honor that edge case; we style them as disabled anyway.
+ &:disabled,
+ &[readonly] {
+ background-color: $input-disabled-bg;
+ // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
+ opacity: 1;
+ }
+}
+
+select.form-control {
+ &:not([size]):not([multiple]) {
+ height: $input-height;
+ }
+
+ &:focus::-ms-value {
+ // Suppress the nested default white text on blue background highlight given to
+ // the selected option text when the (still closed) <select> receives focus
+ // in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
+ // match the appearance of the native widget.
+ // See https://github.com/twbs/bootstrap/issues/19398.
+ color: $input-color;
+ background-color: $input-bg;
+ }
+}
+
+// Make file inputs better match text inputs by forcing them to new lines.
+.form-control-file,
+.form-control-range {
+ display: block;
+ width: 100%;
+}
+
+
+//
+// Labels
+//
+
+// For use with horizontal and inline forms, when you need the label (or legend)
+// text to align with the form controls.
+.col-form-label {
+ padding-top: calc(#{$input-padding-y} + #{$input-border-width});
+ padding-bottom: calc(#{$input-padding-y} + #{$input-border-width});
+ margin-bottom: 0; // Override the `<label>/<legend>` default
+ font-size: inherit; // Override the `<legend>` default
+ line-height: $input-line-height;
+}
+
+.col-form-label-lg {
+ padding-top: calc(#{$input-padding-y-lg} + #{$input-border-width});
+ padding-bottom: calc(#{$input-padding-y-lg} + #{$input-border-width});
+ font-size: $font-size-lg;
+ line-height: $input-line-height-lg;
+}
+
+.col-form-label-sm {
+ padding-top: calc(#{$input-padding-y-sm} + #{$input-border-width});
+ padding-bottom: calc(#{$input-padding-y-sm} + #{$input-border-width});
+ font-size: $font-size-sm;
+ line-height: $input-line-height-sm;
+}
+
+
+// Readonly controls as plain text
+//
+// Apply class to a readonly input to make it appear like regular plain
+// text (without any border, background color, focus indicator)
+
+.form-control-plaintext {
+ display: block;
+ width: 100%;
+ padding-top: $input-padding-y;
+ padding-bottom: $input-padding-y;
+ margin-bottom: 0; // match inputs if this class comes on inputs with default margins
+ line-height: $input-line-height;
+ background-color: transparent;
+ border: solid transparent;
+ border-width: $input-border-width 0;
+
+ &.form-control-sm,
+ &.form-control-lg {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+
+// Form control sizing
+//
+// Build on `.form-control` with modifier classes to decrease or increase the
+// height and font-size of form controls.
+//
+// The `.form-group-* form-control` variations are sadly duplicated to avoid the
+// issue documented in https://github.com/twbs/bootstrap/issues/15074.
+
+.form-control-sm {
+ padding: $input-padding-y-sm $input-padding-x-sm;
+ font-size: $font-size-sm;
+ line-height: $input-line-height-sm;
+ @include border-radius($input-border-radius-sm);
+}
+
+select.form-control-sm {
+ &:not([size]):not([multiple]) {
+ height: $input-height-sm;
+ }
+}
+
+.form-control-lg {
+ padding: $input-padding-y-lg $input-padding-x-lg;
+ font-size: $font-size-lg;
+ line-height: $input-line-height-lg;
+ @include border-radius($input-border-radius-lg);
+}
+
+select.form-control-lg {
+ &:not([size]):not([multiple]) {
+ height: $input-height-lg;
+ }
+}
+
+
+// Form groups
+//
+// Designed to help with the organization and spacing of vertical forms. For
+// horizontal forms, use the predefined grid classes.
+
+.form-group {
+ margin-bottom: $form-group-margin-bottom;
+}
+
+.form-text {
+ display: block;
+ margin-top: $form-text-margin-top;
+}
+
+
+// Form grid
+//
+// Special replacement for our grid system's `.row` for tighter form layouts.
+
+.form-row {
+ display: flex;
+ flex-wrap: wrap;
+ margin-right: -5px;
+ margin-left: -5px;
+
+ > .col,
+ > [class*="col-"] {
+ padding-right: 5px;
+ padding-left: 5px;
+ }
+}
+
+
+// Checkboxes and radios
+//
+// Indent the labels to position radios/checkboxes as hanging controls.
+
+.form-check {
+ position: relative;
+ display: block;
+ padding-left: $form-check-input-gutter;
+}
+
+.form-check-input {
+ position: absolute;
+ margin-top: $form-check-input-margin-y;
+ margin-left: -$form-check-input-gutter;
+
+ &:disabled ~ .form-check-label {
+ color: $text-muted;
+ }
+}
+
+.form-check-label {
+ margin-bottom: 0; // Override default `<label>` bottom margin
+}
+
+.form-check-inline {
+ display: inline-flex;
+ align-items: center;
+ padding-left: 0; // Override base .form-check
+ margin-right: $form-check-inline-margin-x;
+
+ // Undo .form-check-input defaults and add some `margin-right`.
+ .form-check-input {
+ position: static;
+ margin-top: 0;
+ margin-right: $form-check-inline-input-margin-x;
+ margin-left: 0;
+ }
+}
+
+
+// Form validation
+//
+// Provide feedback to users when form field values are valid or invalid. Works
+// primarily for client-side validation via scoped `:invalid` and `:valid`
+// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
+// server side validation.
+
+@include form-validation-state("valid", $form-feedback-valid-color);
+@include form-validation-state("invalid", $form-feedback-invalid-color);
+
+// Inline forms
+//
+// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
+// forms begin stacked on extra small (mobile) devices and then go inline when
+// viewports reach <768px.
+//
+// Requires wrapping inputs and labels with `.form-group` for proper display of
+// default HTML form controls and our custom form controls (e.g., input groups).
+
+.form-inline {
+ display: flex;
+ flex-flow: row wrap;
+ align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
+
+ // Because we use flex, the initial sizing of checkboxes is collapsed and
+ // doesn't occupy the full-width (which is what we want for xs grid tier),
+ // so we force that here.
+ .form-check {
+ width: 100%;
+ }
+
+ // Kick in the inline
+ @include media-breakpoint-up(sm) {
+ label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 0;
+ }
+
+ // Inline-block all the things for "inline"
+ .form-group {
+ display: flex;
+ flex: 0 0 auto;
+ flex-flow: row wrap;
+ align-items: center;
+ margin-bottom: 0;
+ }
+
+ // Allow folks to *not* use `.form-group`
+ .form-control {
+ display: inline-block;
+ width: auto; // Prevent labels from stacking above inputs in `.form-group`
+ vertical-align: middle;
+ }
+
+ // Make static controls behave like regular ones
+ .form-control-plaintext {
+ display: inline-block;
+ }
+
+ .input-group {
+ width: auto;
+ }
+
+ // Remove default margin on radios/checkboxes that were used for stacking, and
+ // then undo the floating of radios and checkboxes to match.
+ .form-check {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: auto;
+ padding-left: 0;
+ }
+ .form-check-input {
+ position: relative;
+ margin-top: 0;
+ margin-right: $form-check-input-margin-x;
+ margin-left: 0;
+ }
+
+ .custom-control {
+ align-items: center;
+ justify-content: center;
+ }
+ .custom-control-label {
+ margin-bottom: 0;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_functions.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_functions.scss
new file mode 100644
index 00000000..1266d34b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_functions.scss
@@ -0,0 +1,86 @@
+// Bootstrap functions
+//
+// Utility mixins and functions for evalutating source code across our variables, maps, and mixins.
+
+// Ascending
+// Used to evaluate Sass maps like our grid breakpoints.
+@mixin _assert-ascending($map, $map-name) {
+ $prev-key: null;
+ $prev-num: null;
+ @each $key, $num in $map {
+ @if $prev-num == null {
+ // Do nothing
+ } @else if not comparable($prev-num, $num) {
+ @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ } @else if $prev-num >= $num {
+ @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ }
+ $prev-key: $key;
+ $prev-num: $num;
+ }
+}
+
+// Starts at zero
+// Another grid mixin that ensures the min-width of the lowest breakpoint starts at 0.
+@mixin _assert-starts-at-zero($map) {
+ $values: map-values($map);
+ $first-value: nth($values, 1);
+ @if $first-value != 0 {
+ @warn "First breakpoint in `$grid-breakpoints` must start at 0, but starts at #{$first-value}.";
+ }
+}
+
+// Replace `$search` with `$replace` in `$string`
+// Used on our SVG icon backgrounds for custom forms.
+//
+// @author Hugo Giraudel
+// @param {String} $string - Initial string
+// @param {String} $search - Substring to replace
+// @param {String} $replace ('') - New value
+// @return {String} - Updated string
+@function str-replace($string, $search, $replace: "") {
+ $index: str-index($string, $search);
+
+ @if $index {
+ @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
+ }
+
+ @return $string;
+}
+
+// Color contrast
+@function color-yiq($color) {
+ $r: red($color);
+ $g: green($color);
+ $b: blue($color);
+
+ $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
+
+ @if ($yiq >= $yiq-contrasted-threshold) {
+ @return $yiq-text-dark;
+ } @else {
+ @return $yiq-text-light;
+ }
+}
+
+// Retrieve color Sass maps
+@function color($key: "blue") {
+ @return map-get($colors, $key);
+}
+
+@function theme-color($key: "primary") {
+ @return map-get($theme-colors, $key);
+}
+
+@function gray($key: "100") {
+ @return map-get($grays, $key);
+}
+
+// Request a theme color level
+@function theme-color-level($color-name: "primary", $level: 0) {
+ $color: theme-color($color-name);
+ $color-base: if($level > 0, #000, #fff);
+ $level: abs($level);
+
+ @return mix($color-base, $color, $level * $theme-color-interval);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_grid.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_grid.scss
new file mode 100644
index 00000000..a2275153
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_grid.scss
@@ -0,0 +1,52 @@
+// Container widths
+//
+// Set the container width, and override it for fixed navbars in media queries.
+
+@if $enable-grid-classes {
+ .container {
+ @include make-container();
+ @include make-container-max-widths();
+ }
+}
+
+// Fluid container
+//
+// Utilizes the mixin meant for fixed width containers, but with 100% width for
+// fluid, full width layouts.
+
+@if $enable-grid-classes {
+ .container-fluid {
+ @include make-container();
+ }
+}
+
+// Row
+//
+// Rows contain and clear the floats of your columns.
+
+@if $enable-grid-classes {
+ .row {
+ @include make-row();
+ }
+
+ // Remove the negative margin from default .row, then the horizontal padding
+ // from all immediate children columns (to prevent runaway style inheritance).
+ .no-gutters {
+ margin-right: 0;
+ margin-left: 0;
+
+ > .col,
+ > [class*="col-"] {
+ padding-right: 0;
+ padding-left: 0;
+ }
+ }
+}
+
+// Columns
+//
+// Common styles for small and large grid columns
+
+@if $enable-grid-classes {
+ @include make-grid-columns();
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_images.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_images.scss
new file mode 100644
index 00000000..2bce02f6
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_images.scss
@@ -0,0 +1,42 @@
+// Responsive images (ensure images don't scale beyond their parents)
+//
+// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
+// We previously tried the "images are responsive by default" approach in Bootstrap v2,
+// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
+// which weren't expecting the images within themselves to be involuntarily resized.
+// See also https://github.com/twbs/bootstrap/issues/18178
+.img-fluid {
+ @include img-fluid;
+}
+
+
+// Image thumbnails
+.img-thumbnail {
+ padding: $thumbnail-padding;
+ background-color: $thumbnail-bg;
+ border: $thumbnail-border-width solid $thumbnail-border-color;
+ @include border-radius($thumbnail-border-radius);
+ @include box-shadow($thumbnail-box-shadow);
+
+ // Keep them at most 100% wide
+ @include img-fluid;
+}
+
+//
+// Figures
+//
+
+.figure {
+ // Ensures the caption's text aligns with the image.
+ display: inline-block;
+}
+
+.figure-img {
+ margin-bottom: ($spacer / 2);
+ line-height: 1;
+}
+
+.figure-caption {
+ font-size: $figure-caption-font-size;
+ color: $figure-caption-color;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_input-group.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_input-group.scss
new file mode 100644
index 00000000..7ef0267c
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_input-group.scss
@@ -0,0 +1,156 @@
+// stylelint-disable selector-no-qualifying-type
+
+//
+// Base styles
+//
+
+.input-group {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap; // For form validation feedback
+ align-items: stretch;
+ width: 100%;
+
+ .form-control,
+ .custom-select,
+ .custom-file {
+ position: relative; // For focus state's z-index
+ flex: 1 1 auto;
+ // Add width 1% and flex-basis auto to ensure that button will not wrap out
+ // the column. Applies to IE Edge+ and Firefox. Chrome does not require this.
+ width: 1%;
+ margin-bottom: 0;
+
+ // Bring the "active" form control to the top of surrounding elements
+ &:focus {
+ z-index: 3;
+ }
+
+ + .form-control {
+ margin-left: -$input-border-width;
+ }
+ }
+
+ .form-control,
+ .custom-select {
+ &:not(:last-child) { @include border-right-radius(0); }
+ &:not(:first-child) { @include border-left-radius(0); }
+ }
+
+ // Custom file inputs have more complex markup, thus requiring different
+ // border-radius overrides.
+ .custom-file {
+ display: flex;
+ align-items: center;
+
+ &:not(:last-child) .custom-file-control,
+ &:not(:last-child) .custom-file-control::before { @include border-right-radius(0); }
+ &:not(:first-child) .custom-file-control,
+ &:not(:first-child) .custom-file-control::before { @include border-left-radius(0); }
+ }
+}
+
+
+// Prepend and append
+//
+// While it requires one extra layer of HTML for each, dedicated prepend and
+// append elements allow us to 1) be less clever, 2) simplify our selectors, and
+// 3) support HTML5 form validation.
+
+.input-group-prepend,
+.input-group-append {
+ display: flex;
+ align-items: center;
+
+ // Ensure buttons are always above inputs for more visually pleasing borders.
+ // This isn't needed for `.input-group-text` since it shares the same border-color
+ // as our inputs.
+ .btn {
+ position: relative;
+ z-index: 2;
+ }
+
+ .btn + .btn,
+ .btn + .input-group-text,
+ .input-group-text + .input-group-text,
+ .input-group-text + .btn {
+ margin-left: -$input-border-width;
+ }
+}
+
+.input-group-prepend { margin-right: -$input-border-width; }
+.input-group-append { margin-left: -$input-border-width; }
+
+
+// Textual addons
+//
+// Serves as a catch-all element for any text or radio/checkbox input you wish
+// to prepend or append to an input.
+
+.input-group-text {
+ padding: $input-padding-y $input-padding-x;
+ margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
+ font-size: $font-size-base; // Match inputs
+ font-weight: $font-weight-normal;
+ line-height: $input-line-height;
+ color: $input-group-addon-color;
+ text-align: center;
+ white-space: nowrap;
+ background-color: $input-group-addon-bg;
+ border: $input-border-width solid $input-group-addon-border-color;
+ @include border-radius($input-border-radius);
+
+ // Nuke default margins from checkboxes and radios to vertically center within.
+ input[type="radio"],
+ input[type="checkbox"] {
+ margin-top: 0;
+ }
+}
+
+
+// Sizing
+//
+// Remix the default form control sizing classes into new ones for easier
+// manipulation.
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-prepend > .input-group-text,
+.input-group-lg > .input-group-append > .input-group-text,
+.input-group-lg > .input-group-prepend > .btn,
+.input-group-lg > .input-group-append > .btn {
+ @extend .form-control-lg;
+}
+
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-prepend > .input-group-text,
+.input-group-sm > .input-group-append > .input-group-text,
+.input-group-sm > .input-group-prepend > .btn,
+.input-group-sm > .input-group-append > .btn {
+ @extend .form-control-sm;
+}
+
+
+// Prepend and append rounded corners
+//
+// These rulesets must come after the sizing ones to properly override sm and lg
+// border-radius values when extending. They're more specific than we'd like
+// with the `.input-group >` part, but without it, we cannot override the sizing.
+
+
+.input-group > .input-group-prepend > .btn,
+.input-group > .input-group-prepend > .input-group-text,
+.input-group > .input-group-append:not(:last-child) > .btn,
+.input-group > .input-group-append:not(:last-child) > .input-group-text,
+.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
+ @include border-right-radius(0);
+}
+
+.input-group > .input-group-append > .btn,
+.input-group > .input-group-append > .input-group-text,
+.input-group > .input-group-prepend:not(:first-child) > .btn,
+.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
+.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
+.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
+ @include border-left-radius(0);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_jumbotron.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_jumbotron.scss
new file mode 100644
index 00000000..7966bba1
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_jumbotron.scss
@@ -0,0 +1,16 @@
+.jumbotron {
+ padding: $jumbotron-padding ($jumbotron-padding / 2);
+ margin-bottom: $jumbotron-padding;
+ background-color: $jumbotron-bg;
+ @include border-radius($border-radius-lg);
+
+ @include media-breakpoint-up(sm) {
+ padding: ($jumbotron-padding * 2) $jumbotron-padding;
+ }
+}
+
+.jumbotron-fluid {
+ padding-right: 0;
+ padding-left: 0;
+ @include border-radius(0);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_list-group.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_list-group.scss
new file mode 100644
index 00000000..9f145c1d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_list-group.scss
@@ -0,0 +1,115 @@
+// Base class
+//
+// Easily usable on <ul>, <ol>, or <div>.
+
+.list-group {
+ display: flex;
+ flex-direction: column;
+
+ // No need to set list-style: none; since .list-group-item is block level
+ padding-left: 0; // reset padding because ul and ol
+ margin-bottom: 0;
+}
+
+
+// Interactive list items
+//
+// Use anchor or button elements instead of `li`s or `div`s to create interactive
+// list items. Includes an extra `.active` modifier class for selected items.
+
+.list-group-item-action {
+ width: 100%; // For `<button>`s (anchors become 100% by default though)
+ color: $list-group-action-color;
+ text-align: inherit; // For `<button>`s (anchors inherit)
+
+ // Hover state
+ @include hover-focus {
+ color: $list-group-action-hover-color;
+ text-decoration: none;
+ background-color: $list-group-hover-bg;
+ }
+
+ &:active {
+ color: $list-group-action-active-color;
+ background-color: $list-group-action-active-bg;
+ }
+}
+
+
+// Individual list items
+//
+// Use on `li`s or `div`s within the `.list-group` parent.
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: $list-group-item-padding-y $list-group-item-padding-x;
+ // Place the border on the list items and negative margin up for better styling
+ margin-bottom: -$list-group-border-width;
+ background-color: $list-group-bg;
+ border: $list-group-border-width solid $list-group-border-color;
+
+ &:first-child {
+ @include border-top-radius($list-group-border-radius);
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ @include border-bottom-radius($list-group-border-radius);
+ }
+
+ @include hover-focus {
+ z-index: 1; // Place hover/active items above their siblings for proper border styling
+ text-decoration: none;
+ }
+
+ &.disabled,
+ &:disabled {
+ color: $list-group-disabled-color;
+ background-color: $list-group-disabled-bg;
+ }
+
+ // Include both here for `<a>`s and `<button>`s
+ &.active {
+ z-index: 2; // Place active items above their siblings for proper border styling
+ color: $list-group-active-color;
+ background-color: $list-group-active-bg;
+ border-color: $list-group-active-border-color;
+ }
+}
+
+
+// Flush list items
+//
+// Remove borders and border-radius to keep list group items edge-to-edge. Most
+// useful within other components (e.g., cards).
+
+.list-group-flush {
+ .list-group-item {
+ border-right: 0;
+ border-left: 0;
+ @include border-radius(0);
+ }
+
+ &:first-child {
+ .list-group-item:first-child {
+ border-top: 0;
+ }
+ }
+
+ &:last-child {
+ .list-group-item:last-child {
+ border-bottom: 0;
+ }
+ }
+}
+
+
+// Contextual variants
+//
+// Add modifier classes to change text and background color on individual items.
+// Organizationally, this must come after the `:hover` states.
+
+@each $color, $value in $theme-colors {
+ @include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_media.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_media.scss
new file mode 100644
index 00000000..b573052c
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_media.scss
@@ -0,0 +1,8 @@
+.media {
+ display: flex;
+ align-items: flex-start;
+}
+
+.media-body {
+ flex: 1;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_mixins.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_mixins.scss
new file mode 100644
index 00000000..d9a1774b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_mixins.scss
@@ -0,0 +1,42 @@
+// Toggles
+//
+// Used in conjunction with global variables to enable certain theme features.
+
+// Utilities
+@import "mixins/breakpoints";
+@import "mixins/hover";
+@import "mixins/image";
+@import "mixins/badge";
+@import "mixins/resize";
+@import "mixins/screen-reader";
+@import "mixins/size";
+@import "mixins/reset-text";
+@import "mixins/text-emphasis";
+@import "mixins/text-hide";
+@import "mixins/text-truncate";
+@import "mixins/visibility";
+
+// // Components
+@import "mixins/alert";
+@import "mixins/buttons";
+@import "mixins/caret";
+@import "mixins/pagination";
+@import "mixins/lists";
+@import "mixins/list-group";
+@import "mixins/nav-divider";
+@import "mixins/forms";
+@import "mixins/table-row";
+
+// // Skins
+@import "mixins/background-variant";
+@import "mixins/border-radius";
+@import "mixins/box-shadow";
+@import "mixins/gradients";
+@import "mixins/transition";
+
+// // Layout
+@import "mixins/clearfix";
+// @import "mixins/navbar-align";
+@import "mixins/grid-framework";
+@import "mixins/grid";
+@import "mixins/float";
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_modal.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_modal.scss
new file mode 100644
index 00000000..edda8366
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_modal.scss
@@ -0,0 +1,168 @@
+// .modal-open - body class for killing the scroll
+// .modal - container to scroll within
+// .modal-dialog - positioning shell for the actual modal
+// .modal-content - actual modal w/ bg and corners and stuff
+
+
+// Kill the scroll on the body
+.modal-open {
+ overflow: hidden;
+}
+
+// Container that the modal scrolls within
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-modal;
+ display: none;
+ overflow: hidden;
+ // Prevent Chrome on Windows from adding a focus outline. For details, see
+ // https://github.com/twbs/bootstrap/pull/10951.
+ outline: 0;
+ // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
+ // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
+ // See also https://github.com/twbs/bootstrap/issues/17695
+
+ .modal-open & {
+ overflow-x: hidden;
+ overflow-y: auto;
+ }
+}
+
+// Shell div to position the modal with bottom padding
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: $modal-dialog-margin;
+ // allow clicks to pass through for custom click handling to close modal
+ pointer-events: none;
+
+ // When fading in the modal, animate it to slide down
+ .modal.fade & {
+ @include transition($modal-transition);
+ transform: translate(0, -25%);
+ }
+ .modal.show & {
+ transform: translate(0, 0);
+ }
+}
+
+.modal-dialog-centered {
+ display: flex;
+ align-items: center;
+ min-height: calc(100% - (#{$modal-dialog-margin} * 2));
+}
+
+// Actual modal
+.modal-content {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
+ // counteract the pointer-events: none; in the .modal-dialog
+ pointer-events: auto;
+ background-color: $modal-content-bg;
+ background-clip: padding-box;
+ border: $modal-content-border-width solid $modal-content-border-color;
+ @include border-radius($border-radius-lg);
+ @include box-shadow($modal-content-box-shadow-xs);
+ // Remove focus outline from opened modal
+ outline: 0;
+}
+
+// Modal background
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-modal-backdrop;
+ background-color: $modal-backdrop-bg;
+
+ // Fade for backdrop
+ &.fade { opacity: 0; }
+ &.show { opacity: $modal-backdrop-opacity; }
+}
+
+// Modal header
+// Top section of the modal w/ title and dismiss
+.modal-header {
+ display: flex;
+ align-items: flex-start; // so the close btn always stays on the upper right corner
+ justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
+ padding: $modal-header-padding;
+ border-bottom: $modal-header-border-width solid $modal-header-border-color;
+ @include border-top-radius($border-radius-lg);
+
+ .close {
+ padding: $modal-header-padding;
+ // auto on the left force icon to the right even when there is no .modal-title
+ margin: (-$modal-header-padding) (-$modal-header-padding) (-$modal-header-padding) auto;
+ }
+}
+
+// Title text within header
+.modal-title {
+ margin-bottom: 0;
+ line-height: $modal-title-line-height;
+}
+
+// Modal body
+// Where all modal content resides (sibling of .modal-header and .modal-footer)
+.modal-body {
+ position: relative;
+ // Enable `flex-grow: 1` so that the body take up as much space as possible
+ // when should there be a fixed height on `.modal-dialog`.
+ flex: 1 1 auto;
+ padding: $modal-inner-padding;
+}
+
+// Footer (for actions)
+.modal-footer {
+ display: flex;
+ align-items: center; // vertically center
+ justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
+ padding: $modal-inner-padding;
+ border-top: $modal-footer-border-width solid $modal-footer-border-color;
+
+ // Easily place margin between footer elements
+ > :not(:first-child) { margin-left: .25rem; }
+ > :not(:last-child) { margin-right: .25rem; }
+}
+
+// Measure scrollbar width for padding body during modal show/hide
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+
+// Scale up the modal
+@include media-breakpoint-up(sm) {
+ // Automatically set modal's width for larger viewports
+ .modal-dialog {
+ max-width: $modal-md;
+ margin: $modal-dialog-margin-y-sm-up auto;
+ }
+
+ .modal-dialog-centered {
+ min-height: calc(100% - (#{$modal-dialog-margin-y-sm-up} * 2));
+ }
+
+ .modal-content {
+ @include box-shadow($modal-content-box-shadow-sm-up);
+ }
+
+ .modal-sm { max-width: $modal-sm; }
+
+}
+
+@include media-breakpoint-up(lg) {
+ .modal-lg { max-width: $modal-lg; }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_nav.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_nav.scss
new file mode 100644
index 00000000..fc82161e
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_nav.scss
@@ -0,0 +1,118 @@
+// Base class
+//
+// Kickstart any navigation component with a set of style resets. Works with
+// `<nav>`s or `<ul>`s.
+
+.nav {
+ display: flex;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.nav-link {
+ display: block;
+ padding: $nav-link-padding-y $nav-link-padding-x;
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+
+ // Disabled state lightens text
+ &.disabled {
+ color: $nav-link-disabled-color;
+ }
+}
+
+//
+// Tabs
+//
+
+.nav-tabs {
+ border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
+
+ .nav-item {
+ margin-bottom: -$nav-tabs-border-width;
+ }
+
+ .nav-link {
+ border: $nav-tabs-border-width solid transparent;
+ @include border-top-radius($nav-tabs-border-radius);
+
+ @include hover-focus {
+ border-color: $nav-tabs-link-hover-border-color;
+ }
+
+ &.disabled {
+ color: $nav-link-disabled-color;
+ background-color: transparent;
+ border-color: transparent;
+ }
+ }
+
+ .nav-link.active,
+ .nav-item.show .nav-link {
+ color: $nav-tabs-link-active-color;
+ background-color: $nav-tabs-link-active-bg;
+ border-color: $nav-tabs-link-active-border-color;
+ }
+
+ .dropdown-menu {
+ // Make dropdown border overlap tab border
+ margin-top: -$nav-tabs-border-width;
+ // Remove the top rounded corners here since there is a hard edge above the menu
+ @include border-top-radius(0);
+ }
+}
+
+
+//
+// Pills
+//
+
+.nav-pills {
+ .nav-link {
+ @include border-radius($nav-pills-border-radius);
+ }
+
+ .nav-link.active,
+ .show > .nav-link {
+ color: $nav-pills-link-active-color;
+ background-color: $nav-pills-link-active-bg;
+ }
+}
+
+
+//
+// Justified variants
+//
+
+.nav-fill {
+ .nav-item {
+ flex: 1 1 auto;
+ text-align: center;
+ }
+}
+
+.nav-justified {
+ .nav-item {
+ flex-basis: 0;
+ flex-grow: 1;
+ text-align: center;
+ }
+}
+
+
+// Tabbable tabs
+//
+// Hide tabbable panes to start, show them when `.active`
+
+.tab-content {
+ > .tab-pane {
+ display: none;
+ }
+ > .active {
+ display: block;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_navbar.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_navbar.scss
new file mode 100644
index 00000000..6b76649a
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_navbar.scss
@@ -0,0 +1,311 @@
+// Contents
+//
+// Navbar
+// Navbar brand
+// Navbar nav
+// Navbar text
+// Navbar divider
+// Responsive navbar
+// Navbar position
+// Navbar themes
+
+
+// Navbar
+//
+// Provide a static navbar from which we expand to create full-width, fixed, and
+// other navbar variations.
+
+.navbar {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap; // allow us to do the line break for collapsing content
+ align-items: center;
+ justify-content: space-between; // space out brand from logo
+ padding: $navbar-padding-y $navbar-padding-x;
+
+ // Because flex properties aren't inherited, we need to redeclare these first
+ // few properities so that content nested within behave properly.
+ > .container,
+ > .container-fluid {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ }
+}
+
+
+// Navbar brand
+//
+// Used for brand, project, or site names.
+
+.navbar-brand {
+ display: inline-block;
+ padding-top: $navbar-brand-padding-y;
+ padding-bottom: $navbar-brand-padding-y;
+ margin-right: $navbar-padding-x;
+ font-size: $navbar-brand-font-size;
+ line-height: inherit;
+ white-space: nowrap;
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+}
+
+
+// Navbar nav
+//
+// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
+
+.navbar-nav {
+ display: flex;
+ flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+
+ .nav-link {
+ padding-right: 0;
+ padding-left: 0;
+ }
+
+ .dropdown-menu {
+ position: static;
+ float: none;
+ }
+}
+
+
+// Navbar text
+//
+//
+
+.navbar-text {
+ display: inline-block;
+ padding-top: $nav-link-padding-y;
+ padding-bottom: $nav-link-padding-y;
+}
+
+
+// Responsive navbar
+//
+// Custom styles for responsive collapsing and toggling of navbar contents.
+// Powered by the collapse Bootstrap JavaScript plugin.
+
+// When collapsed, prevent the toggleable navbar contents from appearing in
+// the default flexbox row orienation. Requires the use of `flex-wrap: wrap`
+// on the `.navbar` parent.
+.navbar-collapse {
+ flex-basis: 100%;
+ flex-grow: 1;
+ // For always expanded or extra full navbars, ensure content aligns itself
+ // properly vertically. Can be easily overridden with flex utilities.
+ align-items: center;
+}
+
+// Button for toggling the navbar when in its collapsed state
+.navbar-toggler {
+ padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
+ font-size: $navbar-toggler-font-size;
+ line-height: 1;
+ background-color: transparent; // remove default button style
+ border: $border-width solid transparent; // remove default button style
+ @include border-radius($navbar-toggler-border-radius);
+
+ @include hover-focus {
+ text-decoration: none;
+ }
+
+ // Opinionated: add "hand" cursor to non-disabled .navbar-toggler elements
+ &:not([disabled]):not(.disabled) {
+ cursor: pointer;
+ }
+}
+
+// Keep as a separate element so folks can easily override it with another icon
+// or image file as needed.
+.navbar-toggler-icon {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ content: "";
+ background: no-repeat center center;
+ background-size: 100% 100%;
+}
+
+// Generate series of `.navbar-expand-*` responsive classes for configuring
+// where your navbar collapses.
+.navbar-expand {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ &#{$infix} {
+ @include media-breakpoint-down($breakpoint) {
+ > .container,
+ > .container-fluid {
+ padding-right: 0;
+ padding-left: 0;
+ }
+ }
+
+ @include media-breakpoint-up($next) {
+ flex-flow: row nowrap;
+ justify-content: flex-start;
+
+ .navbar-nav {
+ flex-direction: row;
+
+ .dropdown-menu {
+ position: absolute;
+ }
+
+ .dropdown-menu-right {
+ right: 0;
+ left: auto; // Reset the default from `.dropdown-menu`
+ }
+
+ .nav-link {
+ padding-right: .5rem;
+ padding-left: .5rem;
+ }
+ }
+
+ // For nesting containers, have to redeclare for alignment purposes
+ > .container,
+ > .container-fluid {
+ flex-wrap: nowrap;
+ }
+
+ .navbar-collapse {
+ display: flex !important; // stylelint-disable-line declaration-no-important
+
+ // Changes flex-bases to auto because of an IE10 bug
+ flex-basis: auto;
+ }
+
+ .navbar-toggler {
+ display: none;
+ }
+
+ .dropup {
+ .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+// Navbar themes
+//
+// Styles for switching between navbars with light or dark background.
+
+// Dark links against a light background
+.navbar-light {
+ .navbar-brand {
+ color: $navbar-light-active-color;
+
+ @include hover-focus {
+ color: $navbar-light-active-color;
+ }
+ }
+
+ .navbar-nav {
+ .nav-link {
+ color: $navbar-light-color;
+
+ @include hover-focus {
+ color: $navbar-light-hover-color;
+ }
+
+ &.disabled {
+ color: $navbar-light-disabled-color;
+ }
+ }
+
+ .show > .nav-link,
+ .active > .nav-link,
+ .nav-link.show,
+ .nav-link.active {
+ color: $navbar-light-active-color;
+ }
+ }
+
+ .navbar-toggler {
+ color: $navbar-light-color;
+ border-color: $navbar-light-toggler-border-color;
+ }
+
+ .navbar-toggler-icon {
+ background-image: $navbar-light-toggler-icon-bg;
+ }
+
+ .navbar-text {
+ color: $navbar-light-color;
+ a {
+ color: $navbar-light-active-color;
+
+ @include hover-focus {
+ color: $navbar-light-active-color;
+ }
+ }
+ }
+}
+
+// White links against a dark background
+.navbar-dark {
+ .navbar-brand {
+ color: $navbar-dark-active-color;
+
+ @include hover-focus {
+ color: $navbar-dark-active-color;
+ }
+ }
+
+ .navbar-nav {
+ .nav-link {
+ color: $navbar-dark-color;
+
+ @include hover-focus {
+ color: $navbar-dark-hover-color;
+ }
+
+ &.disabled {
+ color: $navbar-dark-disabled-color;
+ }
+ }
+
+ .show > .nav-link,
+ .active > .nav-link,
+ .nav-link.show,
+ .nav-link.active {
+ color: $navbar-dark-active-color;
+ }
+ }
+
+ .navbar-toggler {
+ color: $navbar-dark-color;
+ border-color: $navbar-dark-toggler-border-color;
+ }
+
+ .navbar-toggler-icon {
+ background-image: $navbar-dark-toggler-icon-bg;
+ }
+
+ .navbar-text {
+ color: $navbar-dark-color;
+ a {
+ color: $navbar-dark-active-color;
+
+ @include hover-focus {
+ color: $navbar-dark-active-color;
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_pagination.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_pagination.scss
new file mode 100644
index 00000000..286febc9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_pagination.scss
@@ -0,0 +1,72 @@
+.pagination {
+ display: flex;
+ @include list-unstyled();
+ @include border-radius();
+}
+
+.page-link {
+ position: relative;
+ display: block;
+ padding: $pagination-padding-y $pagination-padding-x;
+ margin-left: -$pagination-border-width;
+ line-height: $pagination-line-height;
+ color: $pagination-color;
+ background-color: $pagination-bg;
+ border: $pagination-border-width solid $pagination-border-color;
+
+ @include hover-focus {
+ color: $pagination-hover-color;
+ text-decoration: none;
+ background-color: $pagination-hover-bg;
+ border-color: $pagination-hover-border-color;
+ }
+
+
+ // Opinionated: add "hand" cursor to non-disabled .page-link elements
+ &:not([disabled]):not(.disabled) {
+ cursor: pointer;
+ }
+}
+
+.page-item {
+ &:first-child {
+ .page-link {
+ margin-left: 0;
+ @include border-left-radius($border-radius);
+ }
+ }
+ &:last-child {
+ .page-link {
+ @include border-right-radius($border-radius);
+ }
+ }
+
+ &.active .page-link {
+ z-index: 1;
+ color: $pagination-active-color;
+ background-color: $pagination-active-bg;
+ border-color: $pagination-active-border-color;
+ }
+
+ &.disabled .page-link {
+ color: $pagination-disabled-color;
+ pointer-events: none;
+ // Opinionated: remove the "hand" cursor set previously for .page-link
+ cursor: auto;
+ background-color: $pagination-disabled-bg;
+ border-color: $pagination-disabled-border-color;
+ }
+}
+
+
+//
+// Sizing
+//
+
+.pagination-lg {
+ @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
+}
+
+.pagination-sm {
+ @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_popover.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_popover.scss
new file mode 100644
index 00000000..3e416439
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_popover.scss
@@ -0,0 +1,183 @@
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: $zindex-popover;
+ display: block;
+ max-width: $popover-max-width;
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ font-size: $font-size-sm;
+ // Allow breaking very long words so they don't overflow the popover's bounds
+ word-wrap: break-word;
+ background-color: $popover-bg;
+ background-clip: padding-box;
+ border: $popover-border-width solid $popover-border-color;
+ @include border-radius($border-radius-lg);
+ @include box-shadow($popover-box-shadow);
+
+ .arrow {
+ position: absolute;
+ display: block;
+ width: $popover-arrow-width;
+ height: $popover-arrow-height;
+ margin: 0 $border-radius-lg;
+
+ &::before,
+ &::after {
+ position: absolute;
+ display: block;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ }
+ }
+}
+
+.bs-popover-top {
+ margin-bottom: $popover-arrow-height;
+
+ .arrow {
+ bottom: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
+ }
+
+ .arrow::before,
+ .arrow::after {
+ border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
+ }
+
+ .arrow::before {
+ bottom: 0;
+ border-top-color: $popover-arrow-outer-color;
+ }
+
+ .arrow::after {
+ bottom: $popover-border-width;
+ border-top-color: $popover-arrow-color;
+ }
+}
+
+.bs-popover-right {
+ margin-left: $popover-arrow-height;
+
+ .arrow {
+ left: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
+ width: $popover-arrow-height;
+ height: $popover-arrow-width;
+ margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners
+ }
+
+ .arrow::before,
+ .arrow::after {
+ border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
+ }
+
+ .arrow::before {
+ left: 0;
+ border-right-color: $popover-arrow-outer-color;
+ }
+
+ .arrow::after {
+ left: $popover-border-width;
+ border-right-color: $popover-arrow-color;
+ }
+}
+
+.bs-popover-bottom {
+ margin-top: $popover-arrow-height;
+
+ .arrow {
+ top: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
+ }
+
+ .arrow::before,
+ .arrow::after {
+ border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
+ }
+
+ .arrow::before {
+ top: 0;
+ border-bottom-color: $popover-arrow-outer-color;
+ }
+
+ .arrow::after {
+ top: $popover-border-width;
+ border-bottom-color: $popover-arrow-color;
+ }
+
+ // This will remove the popover-header's border just below the arrow
+ .popover-header::before {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ display: block;
+ width: $popover-arrow-width;
+ margin-left: ($popover-arrow-width / -2);
+ content: "";
+ border-bottom: $popover-border-width solid $popover-header-bg;
+ }
+}
+
+.bs-popover-left {
+ margin-right: $popover-arrow-height;
+
+ .arrow {
+ right: calc((#{$popover-arrow-height} + #{$popover-border-width}) * -1);
+ width: $popover-arrow-height;
+ height: $popover-arrow-width;
+ margin: $border-radius-lg 0; // make sure the arrow does not touch the popover's rounded corners
+ }
+
+ .arrow::before,
+ .arrow::after {
+ border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
+ }
+
+ .arrow::before {
+ right: 0;
+ border-left-color: $popover-arrow-outer-color;
+ }
+
+ .arrow::after {
+ right: $popover-border-width;
+ border-left-color: $popover-arrow-color;
+ }
+}
+
+.bs-popover-auto {
+ &[x-placement^="top"] {
+ @extend .bs-popover-top;
+ }
+ &[x-placement^="right"] {
+ @extend .bs-popover-right;
+ }
+ &[x-placement^="bottom"] {
+ @extend .bs-popover-bottom;
+ }
+ &[x-placement^="left"] {
+ @extend .bs-popover-left;
+ }
+}
+
+
+// Offset the popover to account for the popover arrow
+.popover-header {
+ padding: $popover-header-padding-y $popover-header-padding-x;
+ margin-bottom: 0; // Reset the default from Reboot
+ font-size: $font-size-base;
+ color: $popover-header-color;
+ background-color: $popover-header-bg;
+ border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);
+ $offset-border-width: calc(#{$border-radius-lg} - #{$popover-border-width});
+ @include border-top-radius($offset-border-width);
+
+ &:empty {
+ display: none;
+ }
+}
+
+.popover-body {
+ padding: $popover-body-padding-y $popover-body-padding-x;
+ color: $popover-body-color;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_print.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_print.scss
new file mode 100644
index 00000000..6505d3e9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_print.scss
@@ -0,0 +1,110 @@
+// stylelint-disable declaration-no-important, selector-no-qualifying-type
+
+// Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css
+
+// ==========================================================================
+// Print styles.
+// Inlined to avoid the additional HTTP request:
+// http://www.phpied.com/delay-loading-your-print-css/
+// ==========================================================================
+
+@if $enable-print-styles {
+ @media print {
+ *,
+ *::before,
+ *::after {
+ // Bootstrap specific; comment out `color` and `background`
+ //color: #000 !important; // Black prints faster: http://www.sanbeiji.com/archives/953
+ text-shadow: none !important;
+ //background: transparent !important;
+ box-shadow: none !important;
+ }
+
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+
+ // Bootstrap specific; comment the following selector out
+ //a[href]::after {
+ // content: " (" attr(href) ")";
+ //}
+
+ abbr[title]::after {
+ content: " (" attr(title) ")";
+ }
+
+ // Bootstrap specific; comment the following selector out
+ //
+ // Don't show links that are fragment identifiers,
+ // or use the `javascript:` pseudo protocol
+ //
+
+ //a[href^="#"]::after,
+ //a[href^="javascript:"]::after {
+ // content: "";
+ //}
+
+ pre {
+ white-space: pre-wrap !important;
+ }
+ pre,
+ blockquote {
+ border: $border-width solid #999; // Bootstrap custom code; using `$border-width` instead of 1px
+ page-break-inside: avoid;
+ }
+
+ //
+ // Printing Tables:
+ // http://css-discuss.incutio.com/wiki/Printing_Tables
+ //
+
+ thead {
+ display: table-header-group;
+ }
+
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+
+ // Bootstrap specific changes start
+
+ // Bootstrap components
+ .navbar {
+ display: none;
+ }
+ .badge {
+ border: $border-width solid #000;
+ }
+
+ .table {
+ border-collapse: collapse !important;
+
+ td,
+ th {
+ background-color: #fff !important;
+ }
+ }
+ .table-bordered {
+ th,
+ td {
+ border: 1px solid #ddd !important;
+ }
+ }
+
+ // Bootstrap specific changes end
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_progress.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_progress.scss
new file mode 100644
index 00000000..a5811168
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_progress.scss
@@ -0,0 +1,33 @@
+@keyframes progress-bar-stripes {
+ from { background-position: $progress-height 0; }
+ to { background-position: 0 0; }
+}
+
+.progress {
+ display: flex;
+ height: $progress-height;
+ overflow: hidden; // force rounded corners by cropping it
+ font-size: $progress-font-size;
+ background-color: $progress-bg;
+ @include border-radius($progress-border-radius);
+ @include box-shadow($progress-box-shadow);
+}
+
+.progress-bar {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ color: $progress-bar-color;
+ text-align: center;
+ background-color: $progress-bar-bg;
+ @include transition($progress-bar-transition);
+}
+
+.progress-bar-striped {
+ @include gradient-striped();
+ background-size: $progress-height $progress-height;
+}
+
+.progress-bar-animated {
+ animation: progress-bar-stripes $progress-bar-animation-timing;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_reboot.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_reboot.scss
new file mode 100644
index 00000000..53934131
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_reboot.scss
@@ -0,0 +1,505 @@
+// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
+
+// Reboot
+//
+// Normalization of HTML elements, manually forked from Normalize.css to remove
+// styles targeting irrelevant browsers while applying new styles.
+//
+// Normalize is licensed MIT. https://github.com/necolas/normalize.css
+
+
+// Document
+//
+// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
+// 2. Change the default font family in all browsers.
+// 3. Correct the line height in all browsers.
+// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
+// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so
+// we force a non-overlapping, non-auto-hiding scrollbar to counteract.
+// 6. Change the default tap highlight to be completely transparent in iOS.
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box; // 1
+}
+
+html {
+ font-family: sans-serif; // 2
+ line-height: 1.15; // 3
+ -webkit-text-size-adjust: 100%; // 4
+ -ms-text-size-adjust: 100%; // 4
+ -ms-overflow-style: scrollbar; // 5
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0); // 6
+}
+
+// IE10+ doesn't honor `<meta name="viewport">` in some cases.
+@at-root {
+ @-ms-viewport {
+ width: device-width;
+ }
+}
+
+// stylelint-disable selector-list-comma-newline-after
+// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
+article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
+ display: block;
+}
+// stylelint-enable selector-list-comma-newline-after
+
+// Body
+//
+// 1. Remove the margin in all browsers.
+// 2. As a best practice, apply a default `background-color`.
+// 3. Set an explicit initial text-align value so that we can later use the
+// the `inherit` value on things like `<th>` elements.
+
+body {
+ margin: 0; // 1
+ font-family: $font-family-base;
+ font-size: $font-size-base;
+ font-weight: $font-weight-base;
+ line-height: $line-height-base;
+ color: $body-color;
+ text-align: left; // 3
+ background-color: $body-bg; // 2
+}
+
+// Suppress the focus outline on elements that cannot be accessed via keyboard.
+// This prevents an unwanted focus outline from appearing around elements that
+// might still respond to pointer events.
+//
+// Credit: https://github.com/suitcss/base
+[tabindex="-1"]:focus {
+ outline: 0 !important;
+}
+
+
+// Content grouping
+//
+// 1. Add the correct box sizing in Firefox.
+// 2. Show the overflow in Edge and IE.
+
+hr {
+ box-sizing: content-box; // 1
+ height: 0; // 1
+ overflow: visible; // 2
+}
+
+
+//
+// Typography
+//
+
+// Remove top margins from headings
+//
+// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
+// margin for easier control within type scales as it avoids margin collapsing.
+// stylelint-disable selector-list-comma-newline-after
+h1, h2, h3, h4, h5, h6 {
+ margin-top: 0;
+ margin-bottom: $headings-margin-bottom;
+}
+// stylelint-enable selector-list-comma-newline-after
+
+// Reset margins on paragraphs
+//
+// Similarly, the top margin on `<p>`s get reset. However, we also reset the
+// bottom margin to use `rem` units instead of `em`.
+p {
+ margin-top: 0;
+ margin-bottom: $paragraph-margin-bottom;
+}
+
+// Abbreviations
+//
+// 1. Remove the bottom border in Firefox 39-.
+// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+// 3. Add explicit cursor to indicate changed behavior.
+// 4. Duplicate behavior to the data-* attribute for our tooltip plugin
+
+abbr[title],
+abbr[data-original-title] { // 4
+ text-decoration: underline; // 2
+ text-decoration: underline dotted; // 2
+ cursor: help; // 3
+ border-bottom: 0; // 1
+}
+
+address {
+ margin-bottom: 1rem;
+ font-style: normal;
+ line-height: inherit;
+}
+
+ol,
+ul,
+dl {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+ margin-bottom: 0;
+}
+
+dt {
+ font-weight: $dt-font-weight;
+}
+
+dd {
+ margin-bottom: .5rem;
+ margin-left: 0; // Undo browser default
+}
+
+blockquote {
+ margin: 0 0 1rem;
+}
+
+dfn {
+ font-style: italic; // Add the correct font style in Android 4.3-
+}
+
+// stylelint-disable font-weight-notation
+b,
+strong {
+ font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari
+}
+// stylelint-enable font-weight-notation
+
+small {
+ font-size: 80%; // Add the correct font size in all browsers
+}
+
+//
+// Prevent `sub` and `sup` elements from affecting the line height in
+// all browsers.
+//
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub { bottom: -.25em; }
+sup { top: -.5em; }
+
+
+//
+// Links
+//
+
+a {
+ color: $link-color;
+ text-decoration: $link-decoration;
+ background-color: transparent; // Remove the gray background on active links in IE 10.
+ -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.
+
+ @include hover {
+ color: $link-hover-color;
+ text-decoration: $link-hover-decoration;
+ }
+}
+
+// And undo these styles for placeholder links/named anchors (without href)
+// which have not been made explicitly keyboard-focusable (without tabindex).
+// It would be more straightforward to just use a[href] in previous block, but that
+// causes specificity issues in many other styles that are too complex to fix.
+// See https://github.com/twbs/bootstrap/issues/19402
+
+a:not([href]):not([tabindex]) {
+ color: inherit;
+ text-decoration: none;
+
+ @include hover-focus {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ &:focus {
+ outline: 0;
+ }
+}
+
+
+//
+// Code
+//
+
+// stylelint-disable font-family-no-duplicate-names
+pre,
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers.
+ font-size: 1em; // Correct the odd `em` font sizing in all browsers.
+}
+// stylelint-enable font-family-no-duplicate-names
+
+pre {
+ // Remove browser default top margin
+ margin-top: 0;
+ // Reset browser default of `1em` to use `rem`s
+ margin-bottom: 1rem;
+ // Don't allow content to break outside
+ overflow: auto;
+ // We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so
+ // we force a non-overlapping, non-auto-hiding scrollbar to counteract.
+ -ms-overflow-style: scrollbar;
+}
+
+
+//
+// Figures
+//
+
+figure {
+ // Apply a consistent margin strategy (matches our type styles).
+ margin: 0 0 1rem;
+}
+
+
+//
+// Images and content
+//
+
+img {
+ vertical-align: middle;
+ border-style: none; // Remove the border on images inside links in IE 10-.
+}
+
+svg:not(:root) {
+ overflow: hidden; // Hide the overflow in IE
+}
+
+
+// Avoid 300ms click delay on touch devices that support the `touch-action` CSS property.
+//
+// In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11
+// DON'T remove the click delay when `<meta name="viewport" content="width=device-width">` is present.
+// However, they DO support removing the click delay via `touch-action: manipulation`.
+// See:
+// * https://getbootstrap.com/docs/4.0/content/reboot/#click-delay-optimization-for-touch
+// * https://caniuse.com/#feat=css-touch-action
+// * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay
+
+a,
+area,
+button,
+[role="button"],
+input:not([type="range"]),
+label,
+select,
+summary,
+textarea {
+ touch-action: manipulation;
+}
+
+
+//
+// Tables
+//
+
+table {
+ border-collapse: collapse; // Prevent double borders
+}
+
+caption {
+ padding-top: $table-cell-padding;
+ padding-bottom: $table-cell-padding;
+ color: $text-muted;
+ text-align: left;
+ caption-side: bottom;
+}
+
+th {
+ // Matches default `<td>` alignment by inheriting from the `<body>`, or the
+ // closest parent with a set `text-align`.
+ text-align: inherit;
+}
+
+
+//
+// Forms
+//
+
+label {
+ // Allow labels to use `margin` for spacing.
+ display: inline-block;
+ margin-bottom: .5rem;
+}
+
+// Remove the default `border-radius` that macOS Chrome adds.
+//
+// Details at https://github.com/twbs/bootstrap/issues/24093
+button {
+ border-radius: 0;
+}
+
+// Work around a Firefox/IE bug where the transparent `button` background
+// results in a loss of the default `button` focus styles.
+//
+// Credit: https://github.com/suitcss/base/
+button:focus {
+ outline: 1px dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+}
+
+input,
+button,
+select,
+optgroup,
+textarea {
+ margin: 0; // Remove the margin in Firefox and Safari
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+button,
+input {
+ overflow: visible; // Show the overflow in Edge
+}
+
+button,
+select {
+ text-transform: none; // Remove the inheritance of text transform in Firefox
+}
+
+// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+// controls in Android 4.
+// 2. Correct the inability to style clickable types in iOS and Safari.
+button,
+html [type="button"], // 1
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; // 2
+}
+
+// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ box-sizing: border-box; // 1. Add the correct box sizing in IE 10-
+ padding: 0; // 2. Remove the padding in IE 10-
+}
+
+
+input[type="date"],
+input[type="time"],
+input[type="datetime-local"],
+input[type="month"] {
+ // Remove the default appearance of temporal inputs to avoid a Mobile Safari
+ // bug where setting a custom line-height prevents text from being vertically
+ // centered within the input.
+ // See https://bugs.webkit.org/show_bug.cgi?id=139848
+ // and https://github.com/twbs/bootstrap/issues/11266
+ -webkit-appearance: listbox;
+}
+
+textarea {
+ overflow: auto; // Remove the default vertical scrollbar in IE.
+ // Textareas should really only resize vertically so they don't break their (horizontal) containers.
+ resize: vertical;
+}
+
+fieldset {
+ // Browsers set a default `min-width: min-content;` on fieldsets,
+ // unlike e.g. `<div>`s, which have `min-width: 0;` by default.
+ // So we reset that to ensure fieldsets behave more like a standard block element.
+ // See https://github.com/twbs/bootstrap/issues/12359
+ // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
+ min-width: 0;
+ // Reset the default outline behavior of fieldsets so they don't affect page layout.
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+// 1. Correct the text wrapping in Edge and IE.
+// 2. Correct the color inheritance from `fieldset` elements in IE.
+legend {
+ display: block;
+ width: 100%;
+ max-width: 100%; // 1
+ padding: 0;
+ margin-bottom: .5rem;
+ font-size: 1.5rem;
+ line-height: inherit;
+ color: inherit; // 2
+ white-space: normal; // 1
+}
+
+progress {
+ vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.
+}
+
+// Correct the cursor style of increment and decrement buttons in Chrome.
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+[type="search"] {
+ // This overrides the extra rounded corners on search inputs in iOS so that our
+ // `.form-control` class can properly style them. Note that this cannot simply
+ // be added to `.form-control` as it's not specific enough. For details, see
+ // https://github.com/twbs/bootstrap/issues/11586.
+ outline-offset: -2px; // 2. Correct the outline style in Safari.
+ -webkit-appearance: none;
+}
+
+//
+// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+//
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+//
+// 1. Correct the inability to style clickable types in iOS and Safari.
+// 2. Change font properties to `inherit` in Safari.
+//
+
+::-webkit-file-upload-button {
+ font: inherit; // 2
+ -webkit-appearance: button; // 1
+}
+
+//
+// Correct element displays
+//
+
+output {
+ display: inline-block;
+}
+
+summary {
+ display: list-item; // Add the correct display in all browsers
+ cursor: pointer;
+}
+
+template {
+ display: none; // Add the correct display in IE
+}
+
+// Always hide an element with the `hidden` HTML attribute (from PureCSS).
+// Needed for proper display in IE 10-.
+[hidden] {
+ display: none !important;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_root.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_root.scss
new file mode 100644
index 00000000..ad550df3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_root.scss
@@ -0,0 +1,19 @@
+:root {
+ // Custom variable values only support SassScript inside `#{}`.
+ @each $color, $value in $colors {
+ --#{$color}: #{$value};
+ }
+
+ @each $color, $value in $theme-colors {
+ --#{$color}: #{$value};
+ }
+
+ @each $bp, $value in $grid-breakpoints {
+ --breakpoint-#{$bp}: #{$value};
+ }
+
+ // Use `inspect` for lists so that quoted items keep the quotes.
+ // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
+ --font-family-sans-serif: #{inspect($font-family-sans-serif)};
+ --font-family-monospace: #{inspect($font-family-monospace)};
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tables.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tables.scss
new file mode 100644
index 00000000..0e3b1198
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tables.scss
@@ -0,0 +1,180 @@
+//
+// Basic Bootstrap table
+//
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: $spacer;
+ background-color: $table-bg; // Reset for nesting within parents with `background-color`.
+
+ th,
+ td {
+ padding: $table-cell-padding;
+ vertical-align: top;
+ border-top: $table-border-width solid $table-border-color;
+ }
+
+ thead th {
+ vertical-align: bottom;
+ border-bottom: (2 * $table-border-width) solid $table-border-color;
+ }
+
+ tbody + tbody {
+ border-top: (2 * $table-border-width) solid $table-border-color;
+ }
+
+ .table {
+ background-color: $body-bg;
+ }
+}
+
+
+//
+// Condensed table w/ half padding
+//
+
+.table-sm {
+ th,
+ td {
+ padding: $table-cell-padding-sm;
+ }
+}
+
+
+// Bordered version
+//
+// Add borders all around the table and between all the columns.
+
+.table-bordered {
+ border: $table-border-width solid $table-border-color;
+
+ th,
+ td {
+ border: $table-border-width solid $table-border-color;
+ }
+
+ thead {
+ th,
+ td {
+ border-bottom-width: (2 * $table-border-width);
+ }
+ }
+}
+
+
+// Zebra-striping
+//
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
+
+.table-striped {
+ tbody tr:nth-of-type(odd) {
+ background-color: $table-accent-bg;
+ }
+}
+
+
+// Hover effect
+//
+// Placed here since it has to come after the potential zebra striping
+
+.table-hover {
+ tbody tr {
+ @include hover {
+ background-color: $table-hover-bg;
+ }
+ }
+}
+
+
+// Table backgrounds
+//
+// Exact selectors below required to override `.table-striped` and prevent
+// inheritance to nested tables.
+
+@each $color, $value in $theme-colors {
+ @include table-row-variant($color, theme-color-level($color, -9));
+}
+
+@include table-row-variant(active, $table-active-bg);
+
+
+// Dark styles
+//
+// Same table markup, but inverted color scheme: dark background and light text.
+
+// stylelint-disable-next-line no-duplicate-selectors
+.table {
+ .thead-dark {
+ th {
+ color: $table-dark-color;
+ background-color: $table-dark-bg;
+ border-color: $table-dark-border-color;
+ }
+ }
+
+ .thead-light {
+ th {
+ color: $table-head-color;
+ background-color: $table-head-bg;
+ border-color: $table-border-color;
+ }
+ }
+}
+
+.table-dark {
+ color: $table-dark-color;
+ background-color: $table-dark-bg;
+
+ th,
+ td,
+ thead th {
+ border-color: $table-dark-border-color;
+ }
+
+ &.table-bordered {
+ border: 0;
+ }
+
+ &.table-striped {
+ tbody tr:nth-of-type(odd) {
+ background-color: $table-dark-accent-bg;
+ }
+ }
+
+ &.table-hover {
+ tbody tr {
+ @include hover {
+ background-color: $table-dark-hover-bg;
+ }
+ }
+ }
+}
+
+
+// Responsive tables
+//
+// Generate series of `.table-responsive-*` classes for configuring the screen
+// size of where your table will overflow.
+
+.table-responsive {
+ @each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ &#{$infix} {
+ @include media-breakpoint-down($breakpoint) {
+ display: block;
+ width: 100%;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ -ms-overflow-style: -ms-autohiding-scrollbar; // See https://github.com/twbs/bootstrap/pull/10057
+
+ // Prevent double border on horizontal scroll due to use of `display: block;`
+ > .table-bordered {
+ border: 0;
+ }
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tooltip.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tooltip.scss
new file mode 100644
index 00000000..a03de574
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_tooltip.scss
@@ -0,0 +1,115 @@
+// Base class
+.tooltip {
+ position: absolute;
+ z-index: $zindex-tooltip;
+ display: block;
+ margin: $tooltip-margin;
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text();
+ font-size: $font-size-sm;
+ // Allow breaking very long words so they don't overflow the tooltip's bounds
+ word-wrap: break-word;
+ opacity: 0;
+
+ &.show { opacity: $tooltip-opacity; }
+
+ .arrow {
+ position: absolute;
+ display: block;
+ width: $tooltip-arrow-width;
+ height: $tooltip-arrow-height;
+
+ &::before {
+ position: absolute;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ }
+ }
+}
+
+.bs-tooltip-top {
+ padding: $tooltip-arrow-height 0;
+
+ .arrow {
+ bottom: 0;
+
+ &::before {
+ top: 0;
+ border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
+ border-top-color: $tooltip-arrow-color;
+ }
+ }
+}
+
+.bs-tooltip-right {
+ padding: 0 $tooltip-arrow-height;
+
+ .arrow {
+ left: 0;
+ width: $tooltip-arrow-height;
+ height: $tooltip-arrow-width;
+
+ &::before {
+ right: 0;
+ border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
+ border-right-color: $tooltip-arrow-color;
+ }
+ }
+}
+
+.bs-tooltip-bottom {
+ padding: $tooltip-arrow-height 0;
+
+ .arrow {
+ top: 0;
+
+ &::before {
+ bottom: 0;
+ border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
+ border-bottom-color: $tooltip-arrow-color;
+ }
+ }
+}
+
+.bs-tooltip-left {
+ padding: 0 $tooltip-arrow-height;
+
+ .arrow {
+ right: 0;
+ width: $tooltip-arrow-height;
+ height: $tooltip-arrow-width;
+
+ &::before {
+ left: 0;
+ border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
+ border-left-color: $tooltip-arrow-color;
+ }
+ }
+}
+
+.bs-tooltip-auto {
+ &[x-placement^="top"] {
+ @extend .bs-tooltip-top;
+ }
+ &[x-placement^="right"] {
+ @extend .bs-tooltip-right;
+ }
+ &[x-placement^="bottom"] {
+ @extend .bs-tooltip-bottom;
+ }
+ &[x-placement^="left"] {
+ @extend .bs-tooltip-left;
+ }
+}
+
+// Wrapper for the tooltip content
+.tooltip-inner {
+ max-width: $tooltip-max-width;
+ padding: $tooltip-padding-y $tooltip-padding-x;
+ color: $tooltip-color;
+ text-align: center;
+ background-color: $tooltip-bg;
+ @include border-radius($border-radius);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_transitions.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_transitions.scss
new file mode 100644
index 00000000..df5744b2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_transitions.scss
@@ -0,0 +1,36 @@
+// stylelint-disable selector-no-qualifying-type
+
+.fade {
+ opacity: 0;
+ @include transition($transition-fade);
+
+ &.show {
+ opacity: 1;
+ }
+}
+
+.collapse {
+ display: none;
+ &.show {
+ display: block;
+ }
+}
+
+tr {
+ &.collapse.show {
+ display: table-row;
+ }
+}
+
+tbody {
+ &.collapse.show {
+ display: table-row-group;
+ }
+}
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ @include transition($transition-collapse);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_type.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_type.scss
new file mode 100644
index 00000000..57d610f0
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_type.scss
@@ -0,0 +1,125 @@
+// stylelint-disable declaration-no-important, selector-list-comma-newline-after
+
+//
+// Headings
+//
+
+h1, h2, h3, h4, h5, h6,
+.h1, .h2, .h3, .h4, .h5, .h6 {
+ margin-bottom: $headings-margin-bottom;
+ font-family: $headings-font-family;
+ font-weight: $headings-font-weight;
+ line-height: $headings-line-height;
+ color: $headings-color;
+}
+
+h1, .h1 { font-size: $h1-font-size; }
+h2, .h2 { font-size: $h2-font-size; }
+h3, .h3 { font-size: $h3-font-size; }
+h4, .h4 { font-size: $h4-font-size; }
+h5, .h5 { font-size: $h5-font-size; }
+h6, .h6 { font-size: $h6-font-size; }
+
+.lead {
+ font-size: $lead-font-size;
+ font-weight: $lead-font-weight;
+}
+
+// Type display classes
+.display-1 {
+ font-size: $display1-size;
+ font-weight: $display1-weight;
+ line-height: $display-line-height;
+}
+.display-2 {
+ font-size: $display2-size;
+ font-weight: $display2-weight;
+ line-height: $display-line-height;
+}
+.display-3 {
+ font-size: $display3-size;
+ font-weight: $display3-weight;
+ line-height: $display-line-height;
+}
+.display-4 {
+ font-size: $display4-size;
+ font-weight: $display4-weight;
+ line-height: $display-line-height;
+}
+
+
+//
+// Horizontal rules
+//
+
+hr {
+ margin-top: $hr-margin-y;
+ margin-bottom: $hr-margin-y;
+ border: 0;
+ border-top: $hr-border-width solid $hr-border-color;
+}
+
+
+//
+// Emphasis
+//
+
+small,
+.small {
+ font-size: $small-font-size;
+ font-weight: $font-weight-normal;
+}
+
+mark,
+.mark {
+ padding: $mark-padding;
+ background-color: $mark-bg;
+}
+
+
+//
+// Lists
+//
+
+.list-unstyled {
+ @include list-unstyled;
+}
+
+// Inline turns list items into inline-block
+.list-inline {
+ @include list-unstyled;
+}
+.list-inline-item {
+ display: inline-block;
+
+ &:not(:last-child) {
+ margin-right: $list-inline-padding;
+ }
+}
+
+
+//
+// Misc
+//
+
+// Builds on `abbr`
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+// Blockquotes
+.blockquote {
+ margin-bottom: $spacer;
+ font-size: $blockquote-font-size;
+}
+
+.blockquote-footer {
+ display: block;
+ font-size: 80%; // back to default font-size
+ color: $blockquote-small-color;
+
+ &::before {
+ content: "\2014 \00A0"; // em dash, nbsp
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_utilities.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_utilities.scss
new file mode 100644
index 00000000..7b2a1ebe
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_utilities.scss
@@ -0,0 +1,14 @@
+@import "utilities/align";
+@import "utilities/background";
+@import "utilities/borders";
+@import "utilities/clearfix";
+@import "utilities/display";
+@import "utilities/embed";
+@import "utilities/flex";
+@import "utilities/float";
+@import "utilities/position";
+@import "utilities/screenreaders";
+@import "utilities/sizing";
+@import "utilities/spacing";
+@import "utilities/text";
+@import "utilities/visibility";
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_variables.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_variables.scss
new file mode 100644
index 00000000..2dde7115
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/_variables.scss
@@ -0,0 +1,874 @@
+// import font
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,400,300,600);
+// Variables
+//
+// Variables should follow the `$component-state-property-size` formula for
+// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.
+
+
+//
+// Color system
+//
+
+// stylelint-disable
+$white: #fff !default;
+$gray-100: #f8f9fa !default;
+$gray-200: #e9ecef !default;
+$gray-300: #dee2e6 !default;
+$gray-400: #ced4da !default;
+$gray-500: #adb5bd !default;
+$gray-600: #868e96 !default;
+$gray-700: #495057 !default;
+$gray-800: #343a40 !default;
+$gray-900: #212529 !default;
+$black: #000 !default;
+
+$grays: () !default;
+$grays: map-merge((
+ "100": $gray-100,
+ "200": $gray-200,
+ "300": $gray-300,
+ "400": $gray-400,
+ "500": $gray-500,
+ "600": $gray-600,
+ "700": $gray-700,
+ "800": $gray-800,
+ "900": $gray-900
+), $grays);
+
+$blue: #007bff !default;
+$indigo: #6610f2 !default;
+$purple: #6f42c1 !default;
+$pink: #e83e8c !default;
+$red: #dc3545 !default;
+$orange: #fd7e14 !default;
+$yellow: #ffc107 !default;
+$green: #28a745 !default;
+$teal: #20c997 !default;
+$cyan: #17a2b8 !default;
+
+$colors: () !default;
+$colors: map-merge((
+ "blue": $blue,
+ "indigo": $indigo,
+ "purple": $purple,
+ "pink": $pink,
+ "red": $red,
+ "orange": $orange,
+ "yellow": $yellow,
+ "green": $green,
+ "teal": $teal,
+ "cyan": $cyan,
+ "white": $white,
+ "gray": $gray-600,
+ "gray-dark": $gray-800
+), $colors);
+
+$primary: $blue !default;
+$secondary: $gray-600 !default;
+$success: $green !default;
+$info: $cyan !default;
+$warning: $yellow !default;
+$danger: $red !default;
+$light: $gray-100 !default;
+$dark: $gray-800 !default;
+
+$theme-colors: () !default;
+$theme-colors: map-merge((
+ "primary": $primary,
+ "secondary": $secondary,
+ "success": $success,
+ "info": $info,
+ "warning": $warning,
+ "danger": $danger,
+ "light": $light,
+ "dark": $dark
+), $theme-colors);
+// stylelint-enable
+
+// Set a specific jump point for requesting color jumps
+$theme-color-interval: 8% !default;
+
+// The yiq lightness value that determines when the lightness of color changes from "dark" to "light". Acceptable values are between 0 and 255.
+$yiq-contrasted-threshold: 150 !default;
+
+// Customize the light and dark text colors for use in our YIQ color contrast function.
+$yiq-text-dark: $gray-900 !default;
+$yiq-text-light: $white !default;
+
+// Options
+//
+// Quickly modify global styling by enabling or disabling optional features.
+
+$enable-caret: true !default;
+$enable-rounded: true !default;
+$enable-shadows: false !default;
+$enable-gradients: false !default;
+$enable-transitions: true !default;
+$enable-hover-media-query: false !default;
+$enable-grid-classes: true !default;
+$enable-print-styles: true !default;
+
+
+// Spacing
+//
+// Control the default styling of most Bootstrap elements by modifying these
+// variables. Mostly focused on spacing.
+// You can add more entries to the $spacers map, should you need more variation.
+
+$spacer: 1rem !default;
+$spacers: (
+ 0: 0,
+ 1: ($spacer * .25),
+ 2: ($spacer * .5),
+ 3: $spacer,
+ 4: ($spacer * 1.5),
+ 5: ($spacer * 3)
+) !default;
+
+// This variable affects the `.h-*` and `.w-*` classes.
+$sizes: (
+ 25: 25%,
+ 50: 50%,
+ 75: 75%,
+ 100: 100%
+) !default;
+
+// Body
+//
+// Settings for the `<body>` element.
+
+$body-bg: $white !default;
+$body-color: $gray-900 !default;
+
+// Links
+//
+// Style anchor elements.
+
+$link-color: theme-color("primary") !default;
+$link-decoration: none !default;
+$link-hover-color: darken($link-color, 15%) !default;
+$link-hover-decoration: underline !default;
+
+// Paragraphs
+//
+// Style p element.
+
+$paragraph-margin-bottom: 1rem !default;
+
+
+// Grid breakpoints
+//
+// Define the minimum dimensions at which your layout will change,
+// adapting to different screen sizes, for use in media queries.
+
+$grid-breakpoints: (
+ xs: 0,
+ sm: 576px,
+ md: 768px,
+ lg: 992px,
+ xl: 1200px
+) !default;
+
+@include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
+@include _assert-starts-at-zero($grid-breakpoints);
+
+
+// Grid containers
+//
+// Define the maximum width of `.container` for different screen sizes.
+
+$container-max-widths: (
+ sm: 540px,
+ md: 720px,
+ lg: 960px,
+ xl: 1140px
+) !default;
+
+@include _assert-ascending($container-max-widths, "$container-max-widths");
+
+
+// Grid columns
+//
+// Set the number of columns and specify the width of the gutters.
+
+$grid-columns: 12 !default;
+$grid-gutter-width: 30px !default;
+
+// Components
+//
+// Define common padding and border radius sizes and more.
+
+$line-height-lg: 1.5 !default;
+$line-height-sm: 1.5 !default;
+
+$border-width: 1px !default;
+$border-color: $gray-200 !default;
+
+$border-radius: .25rem !default;
+$border-radius-lg: .3rem !default;
+$border-radius-sm: .2rem !default;
+
+$component-active-color: $white !default;
+$component-active-bg: theme-color("primary") !default;
+
+$caret-width: .3em !default;
+
+$transition-base: all .2s ease-in-out !default;
+$transition-fade: opacity .15s linear !default;
+$transition-collapse: height .35s ease !default;
+
+
+// Fonts
+//
+// Font, line-height, and color for body text, headings, and more.
+
+// stylelint-disable value-keyword-case
+$font-family-sans-serif: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
+$font-family-monospace: "Open Sans", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
+$font-family-base: $font-family-sans-serif !default;
+// stylelint-enable value-keyword-case
+
+$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`
+$font-size-lg: ($font-size-base * 1.25) !default;
+$font-size-sm: ($font-size-base * .875) !default;
+
+$font-weight-light: 300 !default;
+$font-weight-normal: 400 !default;
+$font-weight-bold: 700 !default;
+
+$font-weight-base: $font-weight-normal !default;
+$line-height-base: 1.5 !default;
+
+$h1-font-size: $font-size-base * 2.5 !default;
+$h2-font-size: $font-size-base * 2 !default;
+$h3-font-size: $font-size-base * 1.75 !default;
+$h4-font-size: $font-size-base * 1.5 !default;
+$h5-font-size: $font-size-base * 1.25 !default;
+$h6-font-size: $font-size-base !default;
+
+$headings-margin-bottom: ($spacer / 2) !default;
+$headings-font-family: inherit !default;
+$headings-font-weight: 500 !default;
+$headings-line-height: 1.2 !default;
+$headings-color: inherit !default;
+
+$display1-size: 6rem !default;
+$display2-size: 5.5rem !default;
+$display3-size: 4.5rem !default;
+$display4-size: 3.5rem !default;
+
+$display1-weight: 300 !default;
+$display2-weight: 300 !default;
+$display3-weight: 300 !default;
+$display4-weight: 300 !default;
+$display-line-height: $headings-line-height !default;
+
+$lead-font-size: ($font-size-base * 1.25) !default;
+$lead-font-weight: 300 !default;
+
+$small-font-size: 80% !default;
+
+$text-muted: $gray-600 !default;
+
+$blockquote-small-color: $gray-600 !default;
+$blockquote-font-size: ($font-size-base * 1.25) !default;
+
+$hr-border-color: rgba($black, .1) !default;
+$hr-border-width: $border-width !default;
+
+$mark-padding: .2em !default;
+
+$dt-font-weight: $font-weight-bold !default;
+
+$kbd-box-shadow: inset 0 -.1rem 0 rgba($black, .25) !default;
+$nested-kbd-font-weight: $font-weight-bold !default;
+
+$list-inline-padding: .5rem !default;
+
+$mark-bg: #fcf8e3 !default;
+
+$hr-margin-y: $spacer !default;
+
+
+// Tables
+//
+// Customizes the `.table` component with basic values, each used across all table variations.
+
+$table-cell-padding: .75rem !default;
+$table-cell-padding-sm: .3rem !default;
+
+$table-bg: transparent !default;
+$table-accent-bg: rgba($black, .05) !default;
+$table-hover-bg: rgba($black, .075) !default;
+$table-active-bg: $table-hover-bg !default;
+
+$table-border-width: $border-width !default;
+$table-border-color: $gray-300 !default;
+
+$table-head-bg: $gray-200 !default;
+$table-head-color: $gray-700 !default;
+
+$table-dark-bg: $gray-900 !default;
+$table-dark-accent-bg: rgba($white, .05) !default;
+$table-dark-hover-bg: rgba($white, .075) !default;
+$table-dark-border-color: lighten($gray-900, 7.5%) !default;
+$table-dark-color: $body-bg !default;
+
+
+// Buttons + Forms
+//
+// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.
+
+$input-btn-padding-y: .375rem !default;
+$input-btn-padding-x: .75rem !default;
+$input-btn-line-height: $line-height-base !default;
+
+$input-btn-focus-width: .2rem !default;
+$input-btn-focus-color: rgba(theme-color("primary"), .25) !default;
+$input-btn-focus-box-shadow: 0 0 0 $input-btn-focus-width $input-btn-focus-color !default;
+
+$input-btn-padding-y-sm: .25rem !default;
+$input-btn-padding-x-sm: .5rem !default;
+$input-btn-line-height-sm: $line-height-sm !default;
+
+$input-btn-padding-y-lg: .5rem !default;
+$input-btn-padding-x-lg: 1rem !default;
+$input-btn-line-height-lg: $line-height-lg !default;
+
+$input-btn-border-width: $border-width !default;
+
+
+// Buttons
+//
+// For each of Bootstrap's buttons, define text, background, and border color.
+
+$btn-padding-y: $input-btn-padding-y !default;
+$btn-padding-x: $input-btn-padding-x !default;
+$btn-line-height: $input-btn-line-height !default;
+
+$btn-padding-y-sm: $input-btn-padding-y-sm !default;
+$btn-padding-x-sm: $input-btn-padding-x-sm !default;
+$btn-line-height-sm: $input-btn-line-height-sm !default;
+
+$btn-padding-y-lg: $input-btn-padding-y-lg !default;
+$btn-padding-x-lg: $input-btn-padding-x-lg !default;
+$btn-line-height-lg: $input-btn-line-height-lg !default;
+
+$btn-border-width: $input-btn-border-width !default;
+
+$btn-font-weight: $font-weight-normal !default;
+$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;
+$btn-focus-width: $input-btn-focus-width !default;
+$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;
+$btn-disabled-opacity: .65 !default;
+$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;
+
+$btn-link-disabled-color: $gray-600 !default;
+
+$btn-block-spacing-y: .5rem !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius: $border-radius !default;
+$btn-border-radius-lg: $border-radius-lg !default;
+$btn-border-radius-sm: $border-radius-sm !default;
+
+$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
+
+
+// Forms
+
+$input-padding-y: $input-btn-padding-y !default;
+$input-padding-x: $input-btn-padding-x !default;
+$input-line-height: $input-btn-line-height !default;
+
+$input-padding-y-sm: $input-btn-padding-y-sm !default;
+$input-padding-x-sm: $input-btn-padding-x-sm !default;
+$input-line-height-sm: $input-btn-line-height-sm !default;
+
+$input-padding-y-lg: $input-btn-padding-y-lg !default;
+$input-padding-x-lg: $input-btn-padding-x-lg !default;
+$input-line-height-lg: $input-btn-line-height-lg !default;
+
+$input-bg: $white !default;
+$input-disabled-bg: $gray-200 !default;
+
+$input-color: $gray-700 !default;
+$input-border-color: $gray-400 !default;
+$input-border-width: $input-btn-border-width !default;
+$input-box-shadow: inset 0 1px 1px rgba($black, .075) !default;
+
+$input-border-radius: $border-radius !default;
+$input-border-radius-lg: $border-radius-lg !default;
+$input-border-radius-sm: $border-radius-sm !default;
+
+$input-focus-bg: $input-bg !default;
+$input-focus-border-color: lighten(theme-color("primary"), 25%) !default;
+$input-focus-color: $input-color !default;
+$input-focus-width: $input-btn-focus-width !default;
+$input-focus-box-shadow: $input-btn-focus-box-shadow !default;
+
+$input-placeholder-color: $gray-600 !default;
+
+$input-height-border: $input-btn-border-width * 2 !default;
+
+$input-height-inner: ($font-size-base * $input-btn-line-height) + ($input-btn-padding-y * 2) !default;
+$input-height: calc(#{$input-height-inner} + #{$input-height-border}) !default;
+
+$input-height-inner-sm: ($font-size-sm * $input-btn-line-height-sm) + ($input-btn-padding-y-sm * 2) !default;
+$input-height-sm: calc(#{$input-height-inner-sm} + #{$input-height-border}) !default;
+
+$input-height-inner-lg: ($font-size-lg * $input-btn-line-height-lg) + ($input-btn-padding-y-lg * 2) !default;
+$input-height-lg: calc(#{$input-height-inner-lg} + #{$input-height-border}) !default;
+
+$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;
+
+$form-text-margin-top: .25rem !default;
+
+$form-check-input-gutter: 1.25rem !default;
+$form-check-input-margin-y: .3rem !default;
+$form-check-input-margin-x: .25rem !default;
+
+$form-check-inline-margin-x: .75rem !default;
+$form-check-inline-input-margin-x: .3125rem !default;
+
+$form-group-margin-bottom: 1rem !default;
+
+$input-group-addon-color: $input-color !default;
+$input-group-addon-bg: $gray-200 !default;
+$input-group-addon-border-color: $input-border-color !default;
+
+$custom-control-gutter: 1.5rem !default;
+$custom-control-spacer-x: 1rem !default;
+
+$custom-control-indicator-size: 1rem !default;
+$custom-control-indicator-bg: $gray-300 !default;
+$custom-control-indicator-bg-size: 50% 50% !default;
+$custom-control-indicator-box-shadow: inset 0 .25rem .25rem rgba($black, .1) !default;
+
+$custom-control-indicator-disabled-bg: $gray-200 !default;
+$custom-control-label-disabled-color: $gray-600 !default;
+
+$custom-control-indicator-checked-color: $white !default;
+$custom-control-indicator-checked-bg: theme-color("primary") !default;
+$custom-control-indicator-checked-box-shadow: none !default;
+
+$custom-control-indicator-focus-box-shadow: 0 0 0 1px $body-bg, $input-btn-focus-box-shadow !default;
+
+$custom-control-indicator-active-color: $white !default;
+$custom-control-indicator-active-bg: lighten(theme-color("primary"), 35%) !default;
+$custom-control-indicator-active-box-shadow: none !default;
+
+$custom-checkbox-indicator-border-radius: $border-radius !default;
+$custom-checkbox-indicator-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#{$custom-control-indicator-checked-color}' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$custom-checkbox-indicator-indeterminate-bg: theme-color("primary") !default;
+$custom-checkbox-indicator-indeterminate-color: $custom-control-indicator-checked-color !default;
+$custom-checkbox-indicator-icon-indeterminate: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='#{$custom-checkbox-indicator-indeterminate-color}' d='M0 2h4'/%3E%3C/svg%3E"), "#", "%23") !default;
+$custom-checkbox-indicator-indeterminate-box-shadow: none !default;
+
+$custom-radio-indicator-border-radius: 50% !default;
+$custom-radio-indicator-icon-checked: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='#{$custom-control-indicator-checked-color}'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$custom-select-padding-y: .375rem !default;
+$custom-select-padding-x: .75rem !default;
+$custom-select-height: $input-height !default;
+$custom-select-indicator-padding: 1rem !default; // Extra padding to account for the presence of the background-image based indicator
+$custom-select-line-height: $input-btn-line-height !default;
+$custom-select-color: $input-color !default;
+$custom-select-disabled-color: $gray-600 !default;
+$custom-select-bg: $white !default;
+$custom-select-disabled-bg: $gray-200 !default;
+$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions
+$custom-select-indicator-color: $gray-800 !default;
+$custom-select-indicator: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E"), "#", "%23") !default;
+$custom-select-border-width: $input-btn-border-width !default;
+$custom-select-border-color: $input-border-color !default;
+$custom-select-border-radius: $border-radius !default;
+
+$custom-select-focus-border-color: $input-focus-border-color !default;
+$custom-select-focus-box-shadow: inset 0 1px 2px rgba($black, .075), $input-btn-focus-box-shadow !default;
+
+$custom-select-font-size-sm: 75% !default;
+$custom-select-height-sm: $input-height-sm !default;
+
+$custom-select-font-size-lg: 125% !default;
+$custom-select-height-lg: $input-height-lg !default;
+
+$custom-file-height: $input-height !default;
+$custom-file-focus-border-color: $input-focus-border-color !default;
+$custom-file-focus-box-shadow: $input-btn-focus-box-shadow !default;
+
+$custom-file-padding-y: $input-btn-padding-y !default;
+$custom-file-padding-x: $input-btn-padding-x !default;
+$custom-file-line-height: $input-btn-line-height !default;
+$custom-file-color: $input-color !default;
+$custom-file-bg: $input-bg !default;
+$custom-file-border-width: $input-btn-border-width !default;
+$custom-file-border-color: $input-border-color !default;
+$custom-file-border-radius: $input-border-radius !default;
+$custom-file-box-shadow: $input-box-shadow !default;
+$custom-file-button-color: $custom-file-color !default;
+$custom-file-button-bg: $input-group-addon-bg !default;
+$custom-file-text: (
+ en: "Browse"
+) !default;
+
+
+// Form validation
+$form-feedback-margin-top: $form-text-margin-top !default;
+$form-feedback-font-size: $small-font-size !default;
+$form-feedback-valid-color: theme-color("success") !default;
+$form-feedback-invalid-color: theme-color("danger") !default;
+
+
+// Dropdowns
+//
+// Dropdown menu container and contents.
+
+$dropdown-min-width: 10rem !default;
+$dropdown-padding-y: .5rem !default;
+$dropdown-spacer: .125rem !default;
+$dropdown-bg: $white !default;
+$dropdown-border-color: rgba($black, .15) !default;
+$dropdown-border-radius: $border-radius !default;
+$dropdown-border-width: $border-width !default;
+$dropdown-divider-bg: $gray-200 !default;
+$dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;
+
+$dropdown-link-color: $gray-900 !default;
+$dropdown-link-hover-color: darken($gray-900, 5%) !default;
+$dropdown-link-hover-bg: $gray-100 !default;
+
+$dropdown-link-active-color: $component-active-color !default;
+$dropdown-link-active-bg: $component-active-bg !default;
+
+$dropdown-link-disabled-color: $gray-600 !default;
+
+$dropdown-item-padding-y: .25rem !default;
+$dropdown-item-padding-x: 1.5rem !default;
+
+$dropdown-header-color: $gray-600 !default;
+
+
+// Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+
+$zindex-dropdown: 1000 !default;
+$zindex-sticky: 1020 !default;
+$zindex-fixed: 1030 !default;
+$zindex-modal-backdrop: 1040 !default;
+$zindex-modal: 1050 !default;
+$zindex-popover: 1060 !default;
+$zindex-tooltip: 1070 !default;
+
+// Navs
+
+$nav-link-padding-y: .5rem !default;
+$nav-link-padding-x: 1rem !default;
+$nav-link-disabled-color: $gray-600 !default;
+
+$nav-tabs-border-color: $gray-300 !default;
+$nav-tabs-border-width: $border-width !default;
+$nav-tabs-border-radius: $border-radius !default;
+$nav-tabs-link-hover-border-color: $gray-200 $gray-200 $nav-tabs-border-color !default;
+$nav-tabs-link-active-color: $gray-700 !default;
+$nav-tabs-link-active-bg: $body-bg !default;
+$nav-tabs-link-active-border-color: $gray-300 $gray-300 $nav-tabs-link-active-bg !default;
+
+$nav-pills-border-radius: $border-radius !default;
+$nav-pills-link-active-color: $component-active-color !default;
+$nav-pills-link-active-bg: $component-active-bg !default;
+
+// Navbar
+
+$navbar-padding-y: ($spacer / 2) !default;
+$navbar-padding-x: $spacer !default;
+
+$navbar-brand-font-size: $font-size-lg !default;
+// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link
+$nav-link-height: ($font-size-base * $line-height-base + $nav-link-padding-y * 2) !default;
+$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;
+$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default;
+
+$navbar-toggler-padding-y: .25rem !default;
+$navbar-toggler-padding-x: .75rem !default;
+$navbar-toggler-font-size: $font-size-lg !default;
+$navbar-toggler-border-radius: $btn-border-radius !default;
+
+$navbar-dark-color: rgba($white, .5) !default;
+$navbar-dark-hover-color: rgba($white, .75) !default;
+$navbar-dark-active-color: $white !default;
+$navbar-dark-disabled-color: rgba($white, .25) !default;
+$navbar-dark-toggler-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-dark-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
+$navbar-dark-toggler-border-color: rgba($white, .1) !default;
+
+$navbar-light-color: rgba($black, .5) !default;
+$navbar-light-hover-color: rgba($black, .7) !default;
+$navbar-light-active-color: rgba($black, .9) !default;
+$navbar-light-disabled-color: rgba($black, .3) !default;
+$navbar-light-toggler-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='#{$navbar-light-color}' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"), "#", "%23") !default;
+$navbar-light-toggler-border-color: rgba($black, .1) !default;
+
+// Pagination
+
+$pagination-padding-y: .5rem !default;
+$pagination-padding-x: .75rem !default;
+$pagination-padding-y-sm: .25rem !default;
+$pagination-padding-x-sm: .5rem !default;
+$pagination-padding-y-lg: .75rem !default;
+$pagination-padding-x-lg: 1.5rem !default;
+$pagination-line-height: 1.25 !default;
+
+$pagination-color: $link-color !default;
+$pagination-bg: $white !default;
+$pagination-border-width: $border-width !default;
+$pagination-border-color: $gray-300 !default;
+
+$pagination-hover-color: $link-hover-color !default;
+$pagination-hover-bg: $gray-200 !default;
+$pagination-hover-border-color: $gray-300 !default;
+
+$pagination-active-color: $white !default;
+$pagination-active-bg: theme-color("primary") !default;
+$pagination-active-border-color: theme-color("primary") !default;
+
+$pagination-disabled-color: $gray-600 !default;
+$pagination-disabled-bg: $white !default;
+$pagination-disabled-border-color: $gray-300 !default;
+
+
+// Jumbotron
+
+$jumbotron-padding: 2rem !default;
+$jumbotron-bg: $gray-200 !default;
+
+
+// Cards
+
+$card-spacer-y: .75rem !default;
+$card-spacer-x: 1.25rem !default;
+$card-border-width: $border-width !default;
+$card-border-radius: $border-radius !default;
+$card-border-color: rgba($black, .125) !default;
+$card-inner-border-radius: calc(#{$card-border-radius} - #{$card-border-width}) !default;
+$card-cap-bg: rgba($black, .03) !default;
+$card-bg: $white !default;
+
+$card-img-overlay-padding: 1.25rem !default;
+
+$card-group-margin: ($grid-gutter-width / 2) !default;
+$card-deck-margin: $card-group-margin !default;
+
+$card-columns-count: 3 !default;
+$card-columns-gap: 1.25rem !default;
+$card-columns-margin: $card-spacer-y !default;
+
+
+// Tooltips
+
+$tooltip-max-width: 200px !default;
+$tooltip-color: $white !default;
+$tooltip-bg: $black !default;
+$tooltip-opacity: .9 !default;
+$tooltip-padding-y: .25rem !default;
+$tooltip-padding-x: .5rem !default;
+$tooltip-margin: 0 !default;
+
+$tooltip-arrow-width: .8rem !default;
+$tooltip-arrow-height: .4rem !default;
+$tooltip-arrow-color: $tooltip-bg !default;
+
+
+// Popovers
+
+$popover-bg: $white !default;
+$popover-max-width: 276px !default;
+$popover-border-width: $border-width !default;
+$popover-border-color: rgba($black, .2) !default;
+$popover-box-shadow: 0 .25rem .5rem rgba($black, .2) !default;
+
+$popover-header-bg: darken($popover-bg, 3%) !default;
+$popover-header-color: $headings-color !default;
+$popover-header-padding-y: .5rem !default;
+$popover-header-padding-x: .75rem !default;
+
+$popover-body-color: $body-color !default;
+$popover-body-padding-y: $popover-header-padding-y !default;
+$popover-body-padding-x: $popover-header-padding-x !default;
+
+$popover-arrow-width: 1rem !default;
+$popover-arrow-height: .5rem !default;
+$popover-arrow-color: $popover-bg !default;
+
+$popover-arrow-outer-color: fade-in($popover-border-color, .05) !default;
+
+
+// Badges
+
+$badge-font-size: 75% !default;
+$badge-font-weight: $font-weight-bold !default;
+$badge-padding-y: .25em !default;
+$badge-padding-x: .4em !default;
+$badge-border-radius: $border-radius !default;
+
+$badge-pill-padding-x: .6em !default;
+// Use a higher than normal value to ensure completely rounded edges when
+// customizing padding or font-size on labels.
+$badge-pill-border-radius: 10rem !default;
+
+
+// Modals
+
+// Padding applied to the modal body
+$modal-inner-padding: 1rem !default;
+
+$modal-dialog-margin: .5rem !default;
+$modal-dialog-margin-y-sm-up: 1.75rem !default;
+
+$modal-title-line-height: $line-height-base !default;
+
+$modal-content-bg: $white !default;
+$modal-content-border-color: rgba($black, .2) !default;
+$modal-content-border-width: $border-width !default;
+$modal-content-box-shadow-xs: 0 .25rem .5rem rgba($black, .5) !default;
+$modal-content-box-shadow-sm-up: 0 .5rem 1rem rgba($black, .5) !default;
+
+$modal-backdrop-bg: $black !default;
+$modal-backdrop-opacity: .5 !default;
+$modal-header-border-color: $gray-200 !default;
+$modal-footer-border-color: $modal-header-border-color !default;
+$modal-header-border-width: $modal-content-border-width !default;
+$modal-footer-border-width: $modal-header-border-width !default;
+$modal-header-padding: 1rem !default;
+
+$modal-lg: 800px !default;
+$modal-md: 500px !default;
+$modal-sm: 300px !default;
+
+$modal-transition: transform .3s ease-out !default;
+
+
+// Alerts
+//
+// Define alert colors, border radius, and padding.
+
+$alert-padding-y: .75rem !default;
+$alert-padding-x: 1.25rem !default;
+$alert-margin-bottom: 1rem !default;
+$alert-border-radius: $border-radius !default;
+$alert-link-font-weight: $font-weight-bold !default;
+$alert-border-width: $border-width !default;
+
+
+// Progress bars
+
+$progress-height: 1rem !default;
+$progress-font-size: ($font-size-base * .75) !default;
+$progress-bg: $gray-200 !default;
+$progress-border-radius: $border-radius !default;
+$progress-box-shadow: inset 0 .1rem .1rem rgba($black, .1) !default;
+$progress-bar-color: $white !default;
+$progress-bar-bg: theme-color("primary") !default;
+$progress-bar-animation-timing: 1s linear infinite !default;
+$progress-bar-transition: width .6s ease !default;
+
+// List group
+
+$list-group-bg: $white !default;
+$list-group-border-color: rgba($black, .125) !default;
+$list-group-border-width: $border-width !default;
+$list-group-border-radius: $border-radius !default;
+
+$list-group-item-padding-y: .75rem !default;
+$list-group-item-padding-x: 1.25rem !default;
+
+$list-group-hover-bg: $gray-100 !default;
+$list-group-active-color: $component-active-color !default;
+$list-group-active-bg: $component-active-bg !default;
+$list-group-active-border-color: $list-group-active-bg !default;
+
+$list-group-disabled-color: $gray-600 !default;
+$list-group-disabled-bg: $list-group-bg !default;
+
+$list-group-action-color: $gray-700 !default;
+$list-group-action-hover-color: $list-group-action-color !default;
+
+$list-group-action-active-color: $body-color !default;
+$list-group-action-active-bg: $gray-200 !default;
+
+
+// Image thumbnails
+
+$thumbnail-padding: .25rem !default;
+$thumbnail-bg: $body-bg !default;
+$thumbnail-border-width: $border-width !default;
+$thumbnail-border-color: $gray-300 !default;
+$thumbnail-border-radius: $border-radius !default;
+$thumbnail-box-shadow: 0 1px 2px rgba($black, .075) !default;
+
+
+// Figures
+
+$figure-caption-font-size: 90% !default;
+$figure-caption-color: $gray-600 !default;
+
+
+// Breadcrumbs
+
+$breadcrumb-padding-y: .75rem !default;
+$breadcrumb-padding-x: 1rem !default;
+$breadcrumb-item-padding: .5rem !default;
+
+$breadcrumb-margin-bottom: 1rem !default;
+
+$breadcrumb-bg: $gray-200 !default;
+$breadcrumb-divider-color: $gray-600 !default;
+$breadcrumb-active-color: $gray-600 !default;
+$breadcrumb-divider: "/" !default;
+
+
+// Carousel
+
+$carousel-control-color: $white !default;
+$carousel-control-width: 15% !default;
+$carousel-control-opacity: .5 !default;
+
+$carousel-indicator-width: 30px !default;
+$carousel-indicator-height: 3px !default;
+$carousel-indicator-spacer: 3px !default;
+$carousel-indicator-active-bg: $white !default;
+
+$carousel-caption-width: 70% !default;
+$carousel-caption-color: $white !default;
+
+$carousel-control-icon-width: 20px !default;
+
+$carousel-control-prev-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"), "#", "%23") !default;
+$carousel-control-next-icon-bg: str-replace(url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$carousel-control-color}' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"), "#", "%23") !default;
+
+$carousel-transition: transform .6s ease !default;
+
+
+// Close
+
+$close-font-size: $font-size-base * 1.5 !default;
+$close-font-weight: $font-weight-bold !default;
+$close-color: $black !default;
+$close-text-shadow: 0 1px 0 $white !default;
+
+// Code
+
+$code-font-size: 87.5% !default;
+$code-color: $pink !default;
+
+$kbd-padding-y: .2rem !default;
+$kbd-padding-x: .4rem !default;
+$kbd-font-size: $code-font-size !default;
+$kbd-color: $white !default;
+$kbd-bg: $gray-900 !default;
+
+$pre-color: $gray-900 !default;
+$pre-scrollable-max-height: 340px !default;
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-grid.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-grid.scss
new file mode 100644
index 00000000..fec27664
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-grid.scss
@@ -0,0 +1,35 @@
+/*!
+ * Bootstrap Grid v4.0.0-beta.3 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+@at-root {
+ @-ms-viewport { width: device-width; } // stylelint-disable-line at-rule-no-vendor-prefix
+}
+
+html {
+ box-sizing: border-box;
+ -ms-overflow-style: scrollbar;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: inherit;
+}
+
+@import "functions";
+@import "variables";
+
+//
+// Grid mixins
+//
+
+@import "mixins/breakpoints";
+@import "mixins/grid-framework";
+@import "mixins/grid";
+
+@import "grid";
+@import "utilities/flex";
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-reboot.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-reboot.scss
new file mode 100644
index 00000000..60c0df2e
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap-reboot.scss
@@ -0,0 +1,12 @@
+/*!
+ * Bootstrap Reboot v4.0.0-beta.3 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
+ */
+
+@import "functions";
+@import "variables";
+@import "mixins";
+@import "reboot";
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap.scss
new file mode 100644
index 00000000..42b2c1ab
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/bootstrap.scss
@@ -0,0 +1,42 @@
+/*!
+ * Bootstrap v4.0.0-beta.3 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+@import "functions";
+@import "variables";
+@import "mixins";
+@import "root";
+@import "reboot";
+@import "type";
+@import "images";
+@import "code";
+@import "grid";
+@import "tables";
+@import "forms";
+@import "buttons";
+@import "transitions";
+@import "dropdown";
+@import "button-group";
+@import "input-group";
+@import "custom-forms";
+@import "nav";
+@import "navbar";
+@import "card";
+@import "breadcrumb";
+@import "pagination";
+@import "badge";
+@import "jumbotron";
+@import "alert";
+@import "progress";
+@import "media";
+@import "list-group";
+@import "close";
+@import "modal";
+@import "tooltip";
+@import "popover";
+@import "carousel";
+@import "utilities";
+@import "print";
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_alert.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_alert.scss
new file mode 100644
index 00000000..db5a7eb4
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_alert.scss
@@ -0,0 +1,13 @@
+@mixin alert-variant($background, $border, $color) {
+ color: $color;
+ @include gradient-bg($background);
+ border-color: $border;
+
+ hr {
+ border-top-color: darken($border, 5%);
+ }
+
+ .alert-link {
+ color: darken($color, 10%);
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_background-variant.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_background-variant.scss
new file mode 100644
index 00000000..494439d2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_background-variant.scss
@@ -0,0 +1,21 @@
+// stylelint-disable declaration-no-important
+
+// Contextual backgrounds
+
+@mixin bg-variant($parent, $color) {
+ #{$parent} {
+ background-color: $color !important;
+ }
+ a#{$parent},
+ button#{$parent} {
+ @include hover-focus {
+ background-color: darken($color, 10%) !important;
+ }
+ }
+}
+
+@mixin bg-gradient-variant($parent, $color) {
+ #{$parent} {
+ background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_badge.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_badge.scss
new file mode 100644
index 00000000..eeca0b40
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_badge.scss
@@ -0,0 +1,12 @@
+@mixin badge-variant($bg) {
+ color: color-yiq($bg);
+ background-color: $bg;
+
+ &[href] {
+ @include hover-focus {
+ color: color-yiq($bg);
+ text-decoration: none;
+ background-color: darken($bg, 10%);
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_border-radius.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_border-radius.scss
new file mode 100644
index 00000000..2024febc
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_border-radius.scss
@@ -0,0 +1,35 @@
+// Single side border-radius
+
+@mixin border-radius($radius: $border-radius) {
+ @if $enable-rounded {
+ border-radius: $radius;
+ }
+}
+
+@mixin border-top-radius($radius) {
+ @if $enable-rounded {
+ border-top-left-radius: $radius;
+ border-top-right-radius: $radius;
+ }
+}
+
+@mixin border-right-radius($radius) {
+ @if $enable-rounded {
+ border-top-right-radius: $radius;
+ border-bottom-right-radius: $radius;
+ }
+}
+
+@mixin border-bottom-radius($radius) {
+ @if $enable-rounded {
+ border-bottom-right-radius: $radius;
+ border-bottom-left-radius: $radius;
+ }
+}
+
+@mixin border-left-radius($radius) {
+ @if $enable-rounded {
+ border-top-left-radius: $radius;
+ border-bottom-left-radius: $radius;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_box-shadow.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_box-shadow.scss
new file mode 100644
index 00000000..b2410e53
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_box-shadow.scss
@@ -0,0 +1,5 @@
+@mixin box-shadow($shadow...) {
+ @if $enable-shadows {
+ box-shadow: $shadow;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_breakpoints.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_breakpoints.scss
new file mode 100644
index 00000000..7c95c688
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_breakpoints.scss
@@ -0,0 +1,121 @@
+// Breakpoint viewport sizes and media queries.
+//
+// Breakpoints are defined as a map of (name: minimum width), order from small to large:
+//
+// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
+//
+// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
+
+// Name of the next breakpoint, or null for the last breakpoint.
+//
+// >> breakpoint-next(sm)
+// md
+// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// md
+// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
+// md
+@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
+ $n: index($breakpoint-names, $name);
+ @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
+}
+
+// Minimum breakpoint width. Null for the smallest (first) breakpoint.
+//
+// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// 576px
+@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
+ $min: map-get($breakpoints, $name);
+ @return if($min != 0, $min, null);
+}
+
+// Maximum breakpoint width. Null for the largest (last) breakpoint.
+// The maximum value is calculated as the minimum of the next one less 0.01px
+// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
+// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
+//
+// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// 767px
+@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
+ $next: breakpoint-next($name, $breakpoints);
+ @return if($next, breakpoint-min($next, $breakpoints) - .01px, null);
+}
+
+// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.
+// Useful for making responsive utilities.
+//
+// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// "" (Returns a blank string)
+// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
+// "-sm"
+@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
+ @return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
+}
+
+// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
+// Makes the @content apply to the given breakpoint and wider.
+@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($name, $breakpoints);
+ @if $min {
+ @media (min-width: $min) {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
+// Makes the @content apply to the given breakpoint and narrower.
+@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
+ $max: breakpoint-max($name, $breakpoints);
+ @if $max {
+ @media (max-width: $max) {
+ @content;
+ }
+ } @else {
+ @content;
+ }
+}
+
+// Media that spans multiple breakpoint widths.
+// Makes the @content apply between the min and max breakpoints
+@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($lower, $breakpoints);
+ $max: breakpoint-max($upper, $breakpoints);
+
+ @if $min != null and $max != null {
+ @media (min-width: $min) and (max-width: $max) {
+ @content;
+ }
+ } @else if $max == null {
+ @include media-breakpoint-up($lower) {
+ @content;
+ }
+ } @else if $min == null {
+ @include media-breakpoint-down($upper) {
+ @content;
+ }
+ }
+}
+
+// Media between the breakpoint's minimum and maximum widths.
+// No minimum for the smallest breakpoint, and no maximum for the largest one.
+// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
+@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
+ $min: breakpoint-min($name, $breakpoints);
+ $max: breakpoint-max($name, $breakpoints);
+
+ @if $min != null and $max != null {
+ @media (min-width: $min) and (max-width: $max) {
+ @content;
+ }
+ } @else if $max == null {
+ @include media-breakpoint-up($name) {
+ @content;
+ }
+ } @else if $min == null {
+ @include media-breakpoint-down($name) {
+ @content;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_buttons.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_buttons.scss
new file mode 100644
index 00000000..252e26ac
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_buttons.scss
@@ -0,0 +1,101 @@
+// Button variants
+//
+// Easily pump out default styles, as well as :hover, :focus, :active,
+// and disabled options for all buttons
+
+@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
+ color: color-yiq($background);
+ @include gradient-bg($background);
+ border-color: $border;
+ @include box-shadow($btn-box-shadow);
+
+ @include hover {
+ color: color-yiq($hover-background);
+ @include gradient-bg($hover-background);
+ border-color: $hover-border;
+ }
+
+ &:focus,
+ &.focus {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: $btn-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);
+ } @else {
+ box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);
+ }
+ }
+
+ // Disabled comes first so active can properly restyle
+ &.disabled,
+ &:disabled {
+ background-color: $background;
+ border-color: $border;
+ }
+
+ &:not([disabled]):not(.disabled):active,
+ &:not([disabled]):not(.disabled).active,
+ .show > &.dropdown-toggle {
+ color: color-yiq($active-background);
+ background-color: $active-background;
+ @if $enable-gradients {
+ background-image: none; // Remove the gradient for the pressed/active state
+ }
+ border-color: $active-border;
+
+ &:focus {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: $btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($border, .5);
+ } @else {
+ box-shadow: 0 0 0 $btn-focus-width rgba($border, .5);
+ }
+ }
+ }
+}
+
+@mixin button-outline-variant($color, $color-hover: #fff, $active-background: $color, $active-border: $color) {
+ color: $color;
+ background-color: transparent;
+ background-image: none;
+ border-color: $color;
+
+ &:hover {
+ color: color-yiq($color);
+ background-color: $active-background;
+ border-color: $active-border;
+ }
+
+ &:focus,
+ &.focus {
+ box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
+ }
+
+ &.disabled,
+ &:disabled {
+ color: $color;
+ background-color: transparent;
+ }
+
+ &:not([disabled]):not(.disabled):active,
+ &:not([disabled]):not(.disabled).active,
+ .show > &.dropdown-toggle {
+ color: color-yiq($color-hover);
+ background-color: $active-background;
+ border-color: $active-border;
+ // Avoid using mixin so we can pass custom focus shadow properly
+ box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
+ }
+}
+
+// Button sizes
+@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
+ padding: $padding-y $padding-x;
+ font-size: $font-size;
+ line-height: $line-height;
+ // Manually declare to provide an override to the browser default
+ @if $enable-rounded {
+ border-radius: $border-radius;
+ } @else {
+ border-radius: 0;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_caret.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_caret.scss
new file mode 100644
index 00000000..40478e49
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_caret.scss
@@ -0,0 +1,65 @@
+@mixin caret-down {
+ border-top: $caret-width solid;
+ border-right: $caret-width solid transparent;
+ border-bottom: 0;
+ border-left: $caret-width solid transparent;
+}
+
+@mixin caret-up {
+ border-top: 0;
+ border-right: $caret-width solid transparent;
+ border-bottom: $caret-width solid;
+ border-left: $caret-width solid transparent;
+}
+
+@mixin caret-right {
+ border-top: $caret-width solid transparent;
+ border-bottom: $caret-width solid transparent;
+ border-left: $caret-width solid;
+}
+
+@mixin caret-left {
+ border-top: $caret-width solid transparent;
+ border-right: $caret-width solid;
+ border-bottom: $caret-width solid transparent;
+}
+
+@mixin caret($direction: down) {
+ @if $enable-caret {
+ &::after {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: $caret-width * .85;
+ vertical-align: $caret-width * .85;
+ content: "";
+ @if $direction == down {
+ @include caret-down;
+ } @else if $direction == up {
+ @include caret-up;
+ } @else if $direction == right {
+ @include caret-right;
+ }
+ }
+
+ @if $direction == left {
+ &::after {
+ display: none;
+ }
+
+ &::before {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-right: $caret-width * .85;
+ vertical-align: $caret-width * .85;
+ content: "";
+ @include caret-left;
+ }
+ }
+
+ &:empty::after {
+ margin-left: 0;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_clearfix.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_clearfix.scss
new file mode 100644
index 00000000..11a977b7
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_clearfix.scss
@@ -0,0 +1,7 @@
+@mixin clearfix() {
+ &::after {
+ display: block;
+ clear: both;
+ content: "";
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_float.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_float.scss
new file mode 100644
index 00000000..48fa8b6d
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_float.scss
@@ -0,0 +1,11 @@
+// stylelint-disable declaration-no-important
+
+@mixin float-left {
+ float: left !important;
+}
+@mixin float-right {
+ float: right !important;
+}
+@mixin float-none {
+ float: none !important;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_forms.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_forms.scss
new file mode 100644
index 00000000..d25df182
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_forms.scss
@@ -0,0 +1,133 @@
+// Form control focus state
+//
+// Generate a customized focus state and for any input with the specified color,
+// which defaults to the `$input-focus-border-color` variable.
+//
+// We highly encourage you to not customize the default value, but instead use
+// this to tweak colors on an as-needed basis. This aesthetic change is based on
+// WebKit's default styles, but applicable to a wider range of browsers. Its
+// usability and accessibility should be taken into account with any change.
+//
+// Example usage: change the default blue border and shadow to white for better
+// contrast against a dark gray background.
+@mixin form-control-focus() {
+ &:focus {
+ color: $input-focus-color;
+ background-color: $input-focus-bg;
+ border-color: $input-focus-border-color;
+ outline: 0;
+ // Avoid using mixin so we can pass custom focus shadow properly
+ @if $enable-shadows {
+ box-shadow: $input-box-shadow, $input-focus-box-shadow;
+ } @else {
+ box-shadow: $input-focus-box-shadow;
+ }
+ }
+}
+
+
+@mixin form-validation-state($state, $color) {
+
+ .#{$state}-feedback {
+ display: none;
+ width: 100%;
+ margin-top: $form-feedback-margin-top;
+ font-size: $form-feedback-font-size;
+ color: $color;
+ }
+
+ .#{$state}-tooltip {
+ position: absolute;
+ top: 100%;
+ z-index: 5;
+ display: none;
+ width: 250px;
+ padding: .5rem;
+ margin-top: .1rem;
+ font-size: .875rem;
+ line-height: 1;
+ color: #fff;
+ background-color: rgba($color, .8);
+ border-radius: .2rem;
+ }
+
+ .form-control,
+ .custom-select {
+ .was-validated &:#{$state},
+ &.is-#{$state} {
+ border-color: $color;
+
+ &:focus {
+ border-color: $color;
+ box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
+ }
+
+ ~ .#{$state}-feedback,
+ ~ .#{$state}-tooltip {
+ display: block;
+ }
+ }
+ }
+
+ .form-check-input {
+ .was-validated &:#{$state},
+ &.is-#{$state} {
+ ~ .form-check-label {
+ color: $color;
+ }
+ }
+ }
+
+ .custom-control-input {
+ .was-validated &:#{$state},
+ &.is-#{$state} {
+ ~ .custom-control-label {
+ color: $color;
+
+ &::before {
+ background-color: lighten($color, 25%);
+ }
+ }
+
+ ~ .#{$state}-feedback,
+ ~ .#{$state}-tooltip {
+ display: block;
+ }
+
+ &:checked {
+ ~ .custom-control-label::before {
+ @include gradient-bg(lighten($color, 10%));
+ }
+ }
+
+ &:focus {
+ ~ .custom-control-label::before {
+ box-shadow: 0 0 0 1px $body-bg, 0 0 0 $input-focus-width rgba($color, .25);
+ }
+ }
+ }
+ }
+
+ // custom file
+ .custom-file-input {
+ .was-validated &:#{$state},
+ &.is-#{$state} {
+ ~ .custom-file-label {
+ border-color: $color;
+
+ &::before { border-color: inherit; }
+ }
+
+ ~ .#{$state}-feedback,
+ ~ .#{$state}-tooltip {
+ display: block;
+ }
+
+ &:focus {
+ ~ .custom-file-label {
+ box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
+ }
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_gradients.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_gradients.scss
new file mode 100644
index 00000000..ecd01f72
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_gradients.scss
@@ -0,0 +1,45 @@
+// Gradients
+
+@mixin gradient-bg($color) {
+ @if $enable-gradients {
+ background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;
+ } @else {
+ background-color: $color;
+ }
+}
+
+// Horizontal gradient, from left to right
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+@mixin gradient-x($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
+ background-repeat: repeat-x;
+}
+
+// Vertical gradient, from top to bottom
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+@mixin gradient-y($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
+ background-repeat: repeat-x;
+}
+
+@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
+ background-image: linear-gradient($deg, $start-color, $end-color);
+ background-repeat: repeat-x;
+}
+@mixin gradient-x-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-y-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-radial($inner-color: #555, $outer-color: #333) {
+ background-image: radial-gradient(circle, $inner-color, $outer-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-striped($color: rgba(255,255,255,.15), $angle: 45deg) {
+ background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid-framework.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid-framework.scss
new file mode 100644
index 00000000..41bdf464
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid-framework.scss
@@ -0,0 +1,69 @@
+// Framework grid generation
+//
+// Used only by Bootstrap to generate the correct number of grid classes given
+// any value of `$grid-columns`.
+
+@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
+ // Common properties for all breakpoints
+ %grid-column {
+ position: relative;
+ width: 100%;
+ min-height: 1px; // Prevent columns from collapsing when empty
+ padding-right: ($gutter / 2);
+ padding-left: ($gutter / 2);
+ }
+
+ @each $breakpoint in map-keys($breakpoints) {
+ $infix: breakpoint-infix($breakpoint, $breakpoints);
+
+ // Allow columns to stretch full width below their breakpoints
+ @for $i from 1 through $columns {
+ .col#{$infix}-#{$i} {
+ @extend %grid-column;
+ }
+ }
+ .col#{$infix},
+ .col#{$infix}-auto {
+ @extend %grid-column;
+ }
+
+ @include media-breakpoint-up($breakpoint, $breakpoints) {
+ // Provide basic `.col-{bp}` classes for equal-width flexbox columns
+ .col#{$infix} {
+ flex-basis: 0;
+ flex-grow: 1;
+ max-width: 100%;
+ }
+ .col#{$infix}-auto {
+ flex: 0 0 auto;
+ width: auto;
+ max-width: none; // Reset earlier grid tiers
+ }
+
+ @for $i from 1 through $columns {
+ .col#{$infix}-#{$i} {
+ @include make-col($i, $columns);
+ }
+ }
+
+ .order#{$infix}-first {
+ order: -1;
+ }
+
+ @for $i from 1 through $columns {
+ .order#{$infix}-#{$i} {
+ order: $i;
+ }
+ }
+
+ // `$columns - 1` because offsetting by the width of an entire row isn't possible
+ @for $i from 0 through ($columns - 1) {
+ @if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0
+ .offset#{$infix}-#{$i} {
+ @include make-col-offset($i, $columns);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid.scss
new file mode 100644
index 00000000..b75ebcbc
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_grid.scss
@@ -0,0 +1,52 @@
+/// Grid system
+//
+// Generate semantic grid columns with these mixins.
+
+@mixin make-container() {
+ width: 100%;
+ padding-right: ($grid-gutter-width / 2);
+ padding-left: ($grid-gutter-width / 2);
+ margin-right: auto;
+ margin-left: auto;
+}
+
+
+// For each breakpoint, define the maximum width of the container in a media query
+@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
+ @each $breakpoint, $container-max-width in $max-widths {
+ @include media-breakpoint-up($breakpoint, $breakpoints) {
+ max-width: $container-max-width;
+ }
+ }
+}
+
+@mixin make-row() {
+ display: flex;
+ flex-wrap: wrap;
+ margin-right: ($grid-gutter-width / -2);
+ margin-left: ($grid-gutter-width / -2);
+}
+
+@mixin make-col-ready() {
+ position: relative;
+ // Prevent columns from becoming too narrow when at smaller grid tiers by
+ // always setting `width: 100%;`. This works because we use `flex` values
+ // later on to override this initial width.
+ width: 100%;
+ min-height: 1px; // Prevent collapsing
+ padding-right: ($grid-gutter-width / 2);
+ padding-left: ($grid-gutter-width / 2);
+}
+
+@mixin make-col($size, $columns: $grid-columns) {
+ flex: 0 0 percentage($size / $columns);
+ // Add a `max-width` to ensure content within each column does not blow out
+ // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
+ // do not appear to require this.
+ max-width: percentage($size / $columns);
+}
+
+@mixin make-col-offset($size, $columns: $grid-columns) {
+ $num: $size / $columns;
+ margin-left: if($num == 0, 0, percentage($num));
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_hover.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_hover.scss
new file mode 100644
index 00000000..fd2f1e2c
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_hover.scss
@@ -0,0 +1,61 @@
+// stylelint-disable indentation
+@mixin hover {
+ // TODO: re-enable along with mq4-hover-shim
+// @if $enable-hover-media-query {
+// // See Media Queries Level 4: https://drafts.csswg.org/mediaqueries/#hover
+// // Currently shimmed by https://github.com/twbs/mq4-hover-shim
+// @media (hover: hover) {
+// &:hover { @content }
+// }
+// }
+// @else {
+ &:hover { @content; }
+// }
+}
+
+
+@mixin hover-focus {
+ @if $enable-hover-media-query {
+ &:focus {
+ @content;
+ }
+ @include hover { @content; }
+ } @else {
+ &:focus,
+ &:hover {
+ @content;
+ }
+ }
+}
+
+@mixin plain-hover-focus {
+ @if $enable-hover-media-query {
+ &,
+ &:focus {
+ @content;
+ }
+ @include hover { @content; }
+ } @else {
+ &,
+ &:focus,
+ &:hover {
+ @content;
+ }
+ }
+}
+
+@mixin hover-focus-active {
+ @if $enable-hover-media-query {
+ &:focus,
+ &:active {
+ @content;
+ }
+ @include hover { @content; }
+ } @else {
+ &:focus,
+ &:active,
+ &:hover {
+ @content;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_image.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_image.scss
new file mode 100644
index 00000000..0544f0d2
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_image.scss
@@ -0,0 +1,36 @@
+// Image Mixins
+// - Responsive image
+// - Retina image
+
+
+// Responsive image
+//
+// Keep images from scaling beyond the width of their parents.
+
+@mixin img-fluid {
+ // Part 1: Set a maximum relative to the parent
+ max-width: 100%;
+ // Part 2: Override the height to auto, otherwise images will be stretched
+ // when setting a width and height attribute on the img element.
+ height: auto;
+}
+
+
+// Retina image
+//
+// Short retina mixin for setting background-image and -size.
+
+// stylelint-disable indentation, media-query-list-comma-newline-after
+@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
+ background-image: url($file-1x);
+
+ // Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,
+ // but doesn't convert dppx=>dpi.
+ // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
+ // Compatibility info: https://caniuse.com/#feat=css-media-resolution
+ @media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx
+ only screen and (min-resolution: 2dppx) { // Standardized
+ background-image: url($file-2x);
+ background-size: $width-1x $height-1x;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_list-group.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_list-group.scss
new file mode 100644
index 00000000..278787bb
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_list-group.scss
@@ -0,0 +1,24 @@
+// List Groups
+
+@mixin list-group-item-variant($state, $background, $color) {
+ .list-group-item-#{$state} {
+ color: $color;
+ background-color: $background;
+ }
+
+ a.list-group-item-#{$state},
+ button.list-group-item-#{$state} {
+ color: $color;
+
+ @include hover-focus {
+ color: $color;
+ background-color: darken($background, 5%);
+ }
+
+ &.active {
+ color: #fff;
+ background-color: $color;
+ border-color: $color;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_lists.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_lists.scss
new file mode 100644
index 00000000..25185626
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_lists.scss
@@ -0,0 +1,7 @@
+// Lists
+
+// Unstyled keeps list items block level, just removes default browser padding and list-style
+@mixin list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_nav-divider.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_nav-divider.scss
new file mode 100644
index 00000000..493de03a
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_nav-divider.scss
@@ -0,0 +1,10 @@
+// Horizontal dividers
+//
+// Dividers (basically an hr) within dropdowns and nav lists
+
+@mixin nav-divider($color: #e5e5e5) {
+ height: 0;
+ margin: ($spacer / 2) 0;
+ overflow: hidden;
+ border-top: 1px solid $color;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_navbar-align.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_navbar-align.scss
new file mode 100644
index 00000000..b3516603
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_navbar-align.scss
@@ -0,0 +1,10 @@
+// Navbar vertical align
+//
+// Vertically center elements in the navbar.
+// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);`
+// to calculate the appropriate top margin.
+
+// @mixin navbar-vertical-align($element-height) {
+// margin-top: (($navbar-height - $element-height) / 2);
+// margin-bottom: (($navbar-height - $element-height) / 2);
+// }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_pagination.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_pagination.scss
new file mode 100644
index 00000000..ff36eb6b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_pagination.scss
@@ -0,0 +1,22 @@
+// Pagination
+
+@mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
+ .page-link {
+ padding: $padding-y $padding-x;
+ font-size: $font-size;
+ line-height: $line-height;
+ }
+
+ .page-item {
+ &:first-child {
+ .page-link {
+ @include border-left-radius($border-radius);
+ }
+ }
+ &:last-child {
+ .page-link {
+ @include border-right-radius($border-radius);
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_reset-text.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_reset-text.scss
new file mode 100644
index 00000000..71edb006
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_reset-text.scss
@@ -0,0 +1,17 @@
+@mixin reset-text {
+ font-family: $font-family-base;
+ // We deliberately do NOT reset font-size or word-wrap.
+ font-style: normal;
+ font-weight: $font-weight-normal;
+ line-height: $line-height-base;
+ text-align: left; // Fallback for where `start` is not supported
+ text-align: start; // stylelint-disable-line declaration-block-no-duplicate-properties
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ white-space: normal;
+ line-break: auto;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_resize.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_resize.scss
new file mode 100644
index 00000000..66f233a6
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_resize.scss
@@ -0,0 +1,6 @@
+// Resize anything
+
+@mixin resizable($direction) {
+ overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
+ resize: $direction; // Options: horizontal, vertical, both
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_screen-reader.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_screen-reader.scss
new file mode 100644
index 00000000..8f3eb1b1
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_screen-reader.scss
@@ -0,0 +1,35 @@
+// Only display content to screen readers
+//
+// See: http://a11yproject.com/posts/how-to-hide-content/
+// See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/
+
+@mixin sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ clip-path: inset(50%);
+ border: 0;
+}
+
+// Use in conjunction with .sr-only to only display content when it's focused.
+//
+// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+//
+// Credit: HTML5 Boilerplate
+
+@mixin sr-only-focusable {
+ &:active,
+ &:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ overflow: visible;
+ clip: auto;
+ white-space: normal;
+ clip-path: none;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_size.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_size.scss
new file mode 100644
index 00000000..b9dd48e8
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_size.scss
@@ -0,0 +1,6 @@
+// Sizing shortcuts
+
+@mixin size($width, $height: $width) {
+ width: $width;
+ height: $height;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_table-row.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_table-row.scss
new file mode 100644
index 00000000..84f1d305
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_table-row.scss
@@ -0,0 +1,30 @@
+// Tables
+
+@mixin table-row-variant($state, $background) {
+ // Exact selectors below required to override `.table-striped` and prevent
+ // inheritance to nested tables.
+ .table-#{$state} {
+ &,
+ > th,
+ > td {
+ background-color: $background;
+ }
+ }
+
+ // Hover states for `.table-hover`
+ // Note: this is not available for cells or rows within `thead` or `tfoot`.
+ .table-hover {
+ $hover-background: darken($background, 5%);
+
+ .table-#{$state} {
+ @include hover {
+ background-color: $hover-background;
+
+ > td,
+ > th {
+ background-color: $hover-background;
+ }
+ }
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-emphasis.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-emphasis.scss
new file mode 100644
index 00000000..58db3e0f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-emphasis.scss
@@ -0,0 +1,14 @@
+// stylelint-disable declaration-no-important
+
+// Typography
+
+@mixin text-emphasis-variant($parent, $color) {
+ #{$parent} {
+ color: $color !important;
+ }
+ a#{$parent} {
+ @include hover-focus {
+ color: darken($color, 10%) !important;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-hide.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-hide.scss
new file mode 100644
index 00000000..aa551fde
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-hide.scss
@@ -0,0 +1,9 @@
+// CSS image replacement
+@mixin text-hide() {
+ // stylelint-disable-next-line font-family-no-missing-generic-family-keyword
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-truncate.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-truncate.scss
new file mode 100644
index 00000000..3504bb1a
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_text-truncate.scss
@@ -0,0 +1,8 @@
+// Text truncate
+// Requires inline-block or block for proper styling
+
+@mixin text-truncate() {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_transition.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_transition.scss
new file mode 100644
index 00000000..7e33dee3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_transition.scss
@@ -0,0 +1,9 @@
+@mixin transition($transition...) {
+ @if $enable-transitions {
+ @if length($transition) == 0 {
+ transition: $transition-base;
+ } @else {
+ transition: $transition;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_visibility.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_visibility.scss
new file mode 100644
index 00000000..fe523d0e
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/mixins/_visibility.scss
@@ -0,0 +1,7 @@
+// stylelint-disable declaration-no-important
+
+// Visibility
+
+@mixin invisible($visibility) {
+ visibility: $visibility !important;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_align.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_align.scss
new file mode 100644
index 00000000..8b7df9f7
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_align.scss
@@ -0,0 +1,8 @@
+// stylelint-disable declaration-no-important
+
+.align-baseline { vertical-align: baseline !important; } // Browser default
+.align-top { vertical-align: top !important; }
+.align-middle { vertical-align: middle !important; }
+.align-bottom { vertical-align: bottom !important; }
+.align-text-bottom { vertical-align: text-bottom !important; }
+.align-text-top { vertical-align: text-top !important; }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_background.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_background.scss
new file mode 100644
index 00000000..1f18b2f3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_background.scss
@@ -0,0 +1,19 @@
+// stylelint-disable declaration-no-important
+
+@each $color, $value in $theme-colors {
+ @include bg-variant(".bg-#{$color}", $value);
+}
+
+@if $enable-gradients {
+ @each $color, $value in $theme-colors {
+ @include bg-gradient-variant(".bg-gradient-#{$color}", $value);
+ }
+}
+
+.bg-white {
+ background-color: $white !important;
+}
+
+.bg-transparent {
+ background-color: transparent !important;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_borders.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_borders.scss
new file mode 100644
index 00000000..ba02f045
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_borders.scss
@@ -0,0 +1,54 @@
+// stylelint-disable declaration-no-important
+
+//
+// Border
+//
+
+.border { border: $border-width solid $border-color !important; }
+.border-0 { border: 0 !important; }
+.border-top-0 { border-top: 0 !important; }
+.border-right-0 { border-right: 0 !important; }
+.border-bottom-0 { border-bottom: 0 !important; }
+.border-left-0 { border-left: 0 !important; }
+
+@each $color, $value in $theme-colors {
+ .border-#{$color} {
+ border-color: $value !important;
+ }
+}
+
+.border-white {
+ border-color: $white !important;
+}
+
+//
+// Border-radius
+//
+
+.rounded {
+ border-radius: $border-radius !important;
+}
+.rounded-top {
+ border-top-left-radius: $border-radius !important;
+ border-top-right-radius: $border-radius !important;
+}
+.rounded-right {
+ border-top-right-radius: $border-radius !important;
+ border-bottom-right-radius: $border-radius !important;
+}
+.rounded-bottom {
+ border-bottom-right-radius: $border-radius !important;
+ border-bottom-left-radius: $border-radius !important;
+}
+.rounded-left {
+ border-top-left-radius: $border-radius !important;
+ border-bottom-left-radius: $border-radius !important;
+}
+
+.rounded-circle {
+ border-radius: 50% !important;
+}
+
+.rounded-0 {
+ border-radius: 0 !important;
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_clearfix.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_clearfix.scss
new file mode 100644
index 00000000..e92522a9
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_clearfix.scss
@@ -0,0 +1,3 @@
+.clearfix {
+ @include clearfix();
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_display.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_display.scss
new file mode 100644
index 00000000..893b6387
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_display.scss
@@ -0,0 +1,56 @@
+// stylelint-disable declaration-no-important
+
+//
+// Utilities for common `display` values
+//
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .d#{$infix}-none { display: none !important; }
+ .d#{$infix}-inline { display: inline !important; }
+ .d#{$infix}-inline-block { display: inline-block !important; }
+ .d#{$infix}-block { display: block !important; }
+ .d#{$infix}-table { display: table !important; }
+ .d#{$infix}-table-row { display: table-row !important; }
+ .d#{$infix}-table-cell { display: table-cell !important; }
+ .d#{$infix}-flex { display: flex !important; }
+ .d#{$infix}-inline-flex { display: inline-flex !important; }
+ }
+}
+
+
+//
+// Utilities for toggling `display` in print
+//
+
+.d-print-block {
+ display: none !important;
+
+ @media print {
+ display: block !important;
+ }
+}
+
+.d-print-inline {
+ display: none !important;
+
+ @media print {
+ display: inline !important;
+ }
+}
+
+.d-print-inline-block {
+ display: none !important;
+
+ @media print {
+ display: inline-block !important;
+ }
+}
+
+.d-print-none {
+ @media print {
+ display: none !important;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_embed.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_embed.scss
new file mode 100644
index 00000000..d3362b6f
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_embed.scss
@@ -0,0 +1,52 @@
+// Credit: Nicolas Gallagher and SUIT CSS.
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ width: 100%;
+ padding: 0;
+ overflow: hidden;
+
+ &::before {
+ display: block;
+ content: "";
+ }
+
+ .embed-responsive-item,
+ iframe,
+ embed,
+ object,
+ video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+ }
+}
+
+.embed-responsive-21by9 {
+ &::before {
+ padding-top: percentage(9 / 21);
+ }
+}
+
+.embed-responsive-16by9 {
+ &::before {
+ padding-top: percentage(9 / 16);
+ }
+}
+
+.embed-responsive-4by3 {
+ &::before {
+ padding-top: percentage(3 / 4);
+ }
+}
+
+.embed-responsive-1by1 {
+ &::before {
+ padding-top: percentage(1 / 1);
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_flex.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_flex.scss
new file mode 100644
index 00000000..8e470384
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_flex.scss
@@ -0,0 +1,46 @@
+// stylelint-disable declaration-no-important
+
+// Flex variation
+//
+// Custom styles for additional flex alignment options.
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .flex#{$infix}-row { flex-direction: row !important; }
+ .flex#{$infix}-column { flex-direction: column !important; }
+ .flex#{$infix}-row-reverse { flex-direction: row-reverse !important; }
+ .flex#{$infix}-column-reverse { flex-direction: column-reverse !important; }
+
+ .flex#{$infix}-wrap { flex-wrap: wrap !important; }
+ .flex#{$infix}-nowrap { flex-wrap: nowrap !important; }
+ .flex#{$infix}-wrap-reverse { flex-wrap: wrap-reverse !important; }
+
+ .justify-content#{$infix}-start { justify-content: flex-start !important; }
+ .justify-content#{$infix}-end { justify-content: flex-end !important; }
+ .justify-content#{$infix}-center { justify-content: center !important; }
+ .justify-content#{$infix}-between { justify-content: space-between !important; }
+ .justify-content#{$infix}-around { justify-content: space-around !important; }
+
+ .align-items#{$infix}-start { align-items: flex-start !important; }
+ .align-items#{$infix}-end { align-items: flex-end !important; }
+ .align-items#{$infix}-center { align-items: center !important; }
+ .align-items#{$infix}-baseline { align-items: baseline !important; }
+ .align-items#{$infix}-stretch { align-items: stretch !important; }
+
+ .align-content#{$infix}-start { align-content: flex-start !important; }
+ .align-content#{$infix}-end { align-content: flex-end !important; }
+ .align-content#{$infix}-center { align-content: center !important; }
+ .align-content#{$infix}-between { align-content: space-between !important; }
+ .align-content#{$infix}-around { align-content: space-around !important; }
+ .align-content#{$infix}-stretch { align-content: stretch !important; }
+
+ .align-self#{$infix}-auto { align-self: auto !important; }
+ .align-self#{$infix}-start { align-self: flex-start !important; }
+ .align-self#{$infix}-end { align-self: flex-end !important; }
+ .align-self#{$infix}-center { align-self: center !important; }
+ .align-self#{$infix}-baseline { align-self: baseline !important; }
+ .align-self#{$infix}-stretch { align-self: stretch !important; }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_float.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_float.scss
new file mode 100644
index 00000000..01655e9a
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_float.scss
@@ -0,0 +1,9 @@
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .float#{$infix}-left { @include float-left; }
+ .float#{$infix}-right { @include float-right; }
+ .float#{$infix}-none { @include float-none; }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_position.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_position.scss
new file mode 100644
index 00000000..ef962edd
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_position.scss
@@ -0,0 +1,36 @@
+// stylelint-disable declaration-no-important
+
+// Common values
+
+// Sass list not in variables since it's not intended for customization.
+$positions: static, relative, absolute, fixed, sticky;
+
+@each $position in $positions {
+ .position-#{$position} { position: $position !important; }
+}
+
+// Shorthand
+
+.fixed-top {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: $zindex-fixed;
+}
+
+.fixed-bottom {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-fixed;
+}
+
+.sticky-top {
+ @supports (position: sticky) {
+ position: sticky;
+ top: 0;
+ z-index: $zindex-sticky;
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_screenreaders.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_screenreaders.scss
new file mode 100644
index 00000000..9f26fde0
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_screenreaders.scss
@@ -0,0 +1,11 @@
+//
+// Screenreaders
+//
+
+.sr-only {
+ @include sr-only();
+}
+
+.sr-only-focusable {
+ @include sr-only-focusable();
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_sizing.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_sizing.scss
new file mode 100644
index 00000000..e95a4db3
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_sizing.scss
@@ -0,0 +1,12 @@
+// stylelint-disable declaration-no-important
+
+// Width and height
+
+@each $prop, $abbrev in (width: w, height: h) {
+ @each $size, $length in $sizes {
+ .#{$abbrev}-#{$size} { #{$prop}: $length !important; }
+ }
+}
+
+.mw-100 { max-width: 100% !important; }
+.mh-100 { max-height: 100% !important; }
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_spacing.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_spacing.scss
new file mode 100644
index 00000000..b2e2354b
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_spacing.scss
@@ -0,0 +1,51 @@
+// stylelint-disable declaration-no-important
+
+// Margin and Padding
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ @each $prop, $abbrev in (margin: m, padding: p) {
+ @each $size, $length in $spacers {
+
+ .#{$abbrev}#{$infix}-#{$size} { #{$prop}: $length !important; }
+ .#{$abbrev}t#{$infix}-#{$size},
+ .#{$abbrev}y#{$infix}-#{$size} {
+ #{$prop}-top: $length !important;
+ }
+ .#{$abbrev}r#{$infix}-#{$size},
+ .#{$abbrev}x#{$infix}-#{$size} {
+ #{$prop}-right: $length !important;
+ }
+ .#{$abbrev}b#{$infix}-#{$size},
+ .#{$abbrev}y#{$infix}-#{$size} {
+ #{$prop}-bottom: $length !important;
+ }
+ .#{$abbrev}l#{$infix}-#{$size},
+ .#{$abbrev}x#{$infix}-#{$size} {
+ #{$prop}-left: $length !important;
+ }
+ }
+ }
+
+ // Some special margin utils
+ .m#{$infix}-auto { margin: auto !important; }
+ .mt#{$infix}-auto,
+ .my#{$infix}-auto {
+ margin-top: auto !important;
+ }
+ .mr#{$infix}-auto,
+ .mx#{$infix}-auto {
+ margin-right: auto !important;
+ }
+ .mb#{$infix}-auto,
+ .my#{$infix}-auto {
+ margin-bottom: auto !important;
+ }
+ .ml#{$infix}-auto,
+ .mx#{$infix}-auto {
+ margin-left: auto !important;
+ }
+ }
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_text.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_text.scss
new file mode 100644
index 00000000..f4b6e65e
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_text.scss
@@ -0,0 +1,52 @@
+// stylelint-disable declaration-no-important
+
+//
+// Text
+//
+
+// Alignment
+
+.text-justify { text-align: justify !important; }
+.text-nowrap { white-space: nowrap !important; }
+.text-truncate { @include text-truncate; }
+
+// Responsive alignment
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ @include media-breakpoint-up($breakpoint) {
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
+
+ .text#{$infix}-left { text-align: left !important; }
+ .text#{$infix}-right { text-align: right !important; }
+ .text#{$infix}-center { text-align: center !important; }
+ }
+}
+
+// Transformation
+
+.text-lowercase { text-transform: lowercase !important; }
+.text-uppercase { text-transform: uppercase !important; }
+.text-capitalize { text-transform: capitalize !important; }
+
+// Weight and italics
+
+.font-weight-light { font-weight: $font-weight-light !important; }
+.font-weight-normal { font-weight: $font-weight-normal !important; }
+.font-weight-bold { font-weight: $font-weight-bold !important; }
+.font-italic { font-style: italic !important; }
+
+// Contextual colors
+
+.text-white { color: #fff !important; }
+
+@each $color, $value in $theme-colors {
+ @include text-emphasis-variant(".text-#{$color}", $value);
+}
+
+.text-muted { color: $text-muted !important; }
+
+// Misc
+
+.text-hide {
+ @include text-hide();
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_visibility.scss b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_visibility.scss
new file mode 100644
index 00000000..823406dc
--- /dev/null
+++ b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/styles/bootstrap/utilities/_visibility.scss
@@ -0,0 +1,11 @@
+//
+// Visibility utilities
+//
+
+.visible {
+ @include invisible(visible);
+}
+
+.invisible {
+ @include invisible(hidden);
+}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/test.ts b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/test.ts
deleted file mode 100644
index 52acc194..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/test.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright © 2017 AT&T Intellectual Property.
- *
- * Copyright © 2018 IBM
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-
-import 'zone.js/dist/zone-testing';
-import { getTestBed } from '@angular/core/testing';
-import {
- BrowserDynamicTestingModule,
- platformBrowserDynamicTesting
-} from '@angular/platform-browser-dynamic/testing';
-
-declare const require: any;
-
-// First, initialize the Angular testing environment.
-getTestBed().initTestEnvironment(
- BrowserDynamicTestingModule,
- platformBrowserDynamicTesting()
-);
-// Then we find all the tests.
-const context = require.context('./', true, /\.spec\.ts$/);
-// And load the modules.
-context.keys().map(context);
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.app.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.app.json
deleted file mode 100644
index e44bdeb3..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.app.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "outDir": "../out-tsc/app",
- "types": ["node", "angular"]
- },
- "exclude": [
- "test.ts",
- "**/*.spec.ts"
- ]
-}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.spec.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.spec.json
deleted file mode 100644
index de773363..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tsconfig.spec.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "outDir": "../out-tsc/spec",
- "types": [
- "jasmine",
- "node"
- ]
- },
- "files": [
- "test.ts",
- "polyfills.ts"
- ],
- "include": [
- "**/*.spec.ts",
- "**/*.d.ts"
- ]
-}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tslint.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tslint.json
deleted file mode 100644
index 52e2c1a5..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/src/tslint.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "../tslint.json",
- "rules": {
- "directive-selector": [
- true,
- "attribute",
- "app",
- "camelCase"
- ],
- "component-selector": [
- true,
- "element",
- "app",
- "kebab-case"
- ]
- }
-}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tsconfig.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tsconfig.json
deleted file mode 100644
index f6e888a7..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tsconfig.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "compileOnSave": false,
- "compilerOptions": {
- "baseUrl": "./",
- "outDir": "./dist/out-tsc",
- "sourceMap": true,
- "declaration": false,
- "module": "es2015",
- "moduleResolution": "node",
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "target": "es5",
- "typeRoots": [
- "node_modules/@types"
- ],
- "types": [
- "angular",
- "jasmine"
- ],
- "lib": [
- "es2017",
- "dom"
- ]
- }
-}
diff --git a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tslint.json b/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tslint.json
deleted file mode 100644
index 6ddb6b29..00000000
--- a/ecomp-sdk/epsdk-app-overlay/src/main/webapp/ngapp/tslint.json
+++ /dev/null
@@ -1,131 +0,0 @@
-{
- "rulesDirectory": [
- "node_modules/codelyzer"
- ],
- "rules": {
- "arrow-return-shorthand": true,
- "callable-types": true,
- "class-name": true,
- "comment-format": [
- true,
- "check-space"
- ],
- "curly": true,
- "deprecation": {
- "severity": "warn"
- },
- "eofline": true,
- "forin": true,
- "import-blacklist": [
- true,
- "rxjs/Rx"
- ],
- "import-spacing": true,
- "indent": [
- true,
- "spaces"
- ],
- "interface-over-type-literal": true,
- "label-position": true,
- "max-line-length": [
- true,
- 140
- ],
- "member-access": false,
- "member-ordering": [
- true,
- {
- "order": [
- "static-field",
- "instance-field",
- "static-method",
- "instance-method"
- ]
- }
- ],
- "no-arg": true,
- "no-bitwise": true,
- "no-console": [
- true,
- "debug",
- "info",
- "time",
- "timeEnd",
- "trace"
- ],
- "no-construct": true,
- "no-debugger": true,
- "no-duplicate-super": true,
- "no-empty": false,
- "no-empty-interface": true,
- "no-eval": true,
- "no-inferrable-types": [
- true,
- "ignore-params"
- ],
- "no-misused-new": true,
- "no-non-null-assertion": true,
- "no-redundant-jsdoc": true,
- "no-shadowed-variable": true,
- "no-string-literal": false,
- "no-string-throw": true,
- "no-switch-case-fall-through": true,
- "no-trailing-whitespace": true,
- "no-unnecessary-initializer": true,
- "no-unused-expression": true,
- "no-use-before-declare": true,
- "no-var-keyword": true,
- "object-literal-sort-keys": false,
- "one-line": [
- true,
- "check-open-brace",
- "check-catch",
- "check-else",
- "check-whitespace"
- ],
- "prefer-const": true,
- "quotemark": [
- true,
- "single"
- ],
- "radix": true,
- "semicolon": [
- true,
- "always"
- ],
- "triple-equals": [
- true,
- "allow-null-check"
- ],
- "typedef-whitespace": [
- true,
- {
- "call-signature": "nospace",
- "index-signature": "nospace",
- "parameter": "nospace",
- "property-declaration": "nospace",
- "variable-declaration": "nospace"
- }
- ],
- "unified-signatures": true,
- "variable-name": false,
- "whitespace": [
- true,
- "check-branch",
- "check-decl",
- "check-operator",
- "check-separator",
- "check-type"
- ],
- "no-output-on-prefix": true,
- "use-input-property-decorator": true,
- "use-output-property-decorator": true,
- "use-host-property-decorator": true,
- "no-input-rename": true,
- "no-output-rename": true,
- "use-life-cycle-interface": true,
- "use-pipe-transform-interface": true,
- "component-class-suffix": true,
- "directive-class-suffix": true
- }
-}