diff --git a/angular.json b/angular.json index e578c02c5..c40c1ea22 100644 --- a/angular.json +++ b/angular.json @@ -127,7 +127,8 @@ "serve": { "builder": "@angular-builders/custom-webpack:dev-server", "options": { - "browserTarget": "project:build" + "browserTarget": "project:build", + "proxyConfig": "./proxy.conf.json" }, "configurations": { "audev": { diff --git a/package.json b/package.json index 774aaf5e7..cd5ab2d75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "auscope-portal", - "version": "6.2.0", + "version": "6.2.1", "license": "MIT", "scripts": { "ng": "ng", diff --git a/proxy.conf.json b/proxy.conf.json index be91f5a1b..85aecaf03 100644 --- a/proxy.conf.json +++ b/proxy.conf.json @@ -1,8 +1,10 @@ { - "/": { - "target": "http://localhost:8080/AuScope-Portal", - "secure": false, - "pathRewrite": {"^/" : ""}, - "logLevel":"debug" - } -} \ No newline at end of file + "context": [ + "/AuScope-Portal/**", + "/api/**" + ], + "target": "http://localhost:8080/", + "secure": false, + "logLevel": "debug", + "changeOrigin": true +} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 000000000..7d8622b84 --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { environment } from '../environments/environment'; +import { LoggedInComponent } from './menupanel/login/logged-in.component'; +import { LoginComponent } from './menupanel/login/login.component'; +import { PortalComponent } from './portal/portal.component'; + + +const baseUrl = environment.portalBaseUrl.replace(/^\/|\/$/g, ''); + +/** + * Application routes. + * Add the following to a route to ensure only authenticated users can access: + * canActivate: [AuthGuard] + */ +const routes: Routes = [ + { path: '', pathMatch: 'full', component: PortalComponent }, + { path: 'login', component: LoginComponent }, + { path: 'login/loggedIn', component: LoggedInComponent }, + { path: baseUrl, redirectTo: '/', pathMatch: 'full' }, + { path: '**', redirectTo: '/' } +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule {} diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 000000000..90c6b6463 --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 000000000..dc0cf3d64 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; +/** + * Top level application component, holds the router outlet + * + * @export + * @class AppComponent + */ +@Component({ + selector: 'app-component', + templateUrl: './app.component.html' +}) + +export class AppComponent { + + constructor() {} + +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 953b77714..0a49e2a2a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -4,11 +4,17 @@ import { NgModule } from '@angular/core'; import { ModalModule } from 'ngx-bootstrap/modal'; import { NouisliderModule } from 'ng2-nouislider'; import { CommonModule } from '@angular/common'; +import { BrowserModule } from '@angular/platform-browser'; // Cesium icons import { MatTooltipModule } from '@angular/material/tooltip'; // Components +import { AppComponent } from './app.component'; +import { PortalComponent } from './portal/portal.component'; +import { LoginMenuComponent } from './menupanel/login/login-menu.component'; +import { LoginComponent } from './menupanel/login/login.component'; +import { LoggedInComponent } from './menupanel/login/logged-in.component'; import { CsMapComponent } from './cesium-map/csmap.component'; import { CesiumMapPreviewComponent } from './menupanel/common/infopanel/cesiummappreview/cesium.preview.component'; import { LayerPanelComponent } from './menupanel/layerpanel/layerpanel.component'; @@ -93,11 +99,25 @@ import { NgxColorsModule } from 'ngx-colors'; import {MatProgressBarModule} from '@angular/material/progress-bar'; import {MatCardModule} from '@angular/material/card'; import { getSaver, SAVER } from './modalwindow/layeranalytic/nvcl/saver.provider'; + +// Routing +import { AppRoutingModule } from './app-routing.module'; + +// Auth +import { UserStateService } from './services/user/user-state.service'; +import { AuthGuard } from './services/auth/auth.guard'; +import { AuthService } from './services/auth/auth.service'; + PlotlyModule.plotlyjs = PlotlyJS; @NgModule({ declarations: [ + AppComponent, + PortalComponent, + LoginComponent, + LoggedInComponent, + LoginMenuComponent, CsMapComponent, CesiumMapPreviewComponent, LayerPanelComponent, @@ -136,10 +156,12 @@ PlotlyModule.plotlyjs = PlotlyJS; RecordModalComponent ], providers: [ AuscopeApiService, FilterService, RectanglesEditorService, AdvancedComponentService, SearchService, - NVCLService, MSCLService, BoundsService, GraceService, { provide: SAVER, useFactory: getSaver } + NVCLService, MSCLService, BoundsService, GraceService, { provide: SAVER, useFactory: getSaver }, + UserStateService, AuthGuard, AuthService ], imports: [ PortalCoreModule.forRoot(environment, config), + AppRoutingModule, PortalCorePipesModule, ClipboardModule, ModalModule.forRoot(), @@ -167,18 +189,11 @@ PlotlyModule.plotlyjs = PlotlyJS; AngularCesiumWidgetsModule, NgbModule, FormsModule, - ReactiveFormsModule + ReactiveFormsModule, + BrowserModule ], bootstrap: [ - CsMapComponent, - LayerPanelComponent, - CustomPanelComponent, - ActiveLayersPanelComponent, - PermanentLinkComponent, - DataExplorerComponent, - PortalDetailsPanelComponent, - HelpMenuComponent, - SearchPanelComponent + AppComponent ] }) export class AppModule { } diff --git a/src/app/menupanel/login/logged-in.component.ts b/src/app/menupanel/login/logged-in.component.ts new file mode 100644 index 000000000..e92dd6c71 --- /dev/null +++ b/src/app/menupanel/login/logged-in.component.ts @@ -0,0 +1,19 @@ +import { Component, OnInit } from '@angular/core'; + +import { AuthService } from '../../services/auth/auth.service'; + +@Component({ + selector: 'app-logged-in', + template: ``, + styles: [] +}) +export class LoggedInComponent implements OnInit { + + constructor(private authService: AuthService) {} + + ngOnInit() { + // Inform the auth service + this.authService.onLoggedIn(); + } + +} diff --git a/src/app/menupanel/login/login-menu.component.html b/src/app/menupanel/login/login-menu.component.html new file mode 100644 index 000000000..87f27984d --- /dev/null +++ b/src/app/menupanel/login/login-menu.component.html @@ -0,0 +1,14 @@ +
+
+ + +
+
+
+
+ +
+
\ No newline at end of file diff --git a/src/app/menupanel/login/login-menu.component.scss b/src/app/menupanel/login/login-menu.component.scss new file mode 100644 index 000000000..0596f4475 --- /dev/null +++ b/src/app/menupanel/login/login-menu.component.scss @@ -0,0 +1,28 @@ +@import '../../globals'; + +.user-menu { + color: $text-colour; +} + +.user-button { + color: #d8d9d7; +} + +.user-button:hover { + color: white; +} + +.user-menu:hover { + color: $text-highlight-colour; +} + +::ng-deep { + .mat-menu-panel { + margin-top: 10px; + } + + .mat-menu-content { + background-color: $background-colour; + } + +} \ No newline at end of file diff --git a/src/app/menupanel/login/login-menu.component.ts b/src/app/menupanel/login/login-menu.component.ts new file mode 100644 index 000000000..6a7ed40a5 --- /dev/null +++ b/src/app/menupanel/login/login-menu.component.ts @@ -0,0 +1,47 @@ +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { AuthService } from 'app/services/auth/auth.service'; +import { UserStateService } from '../../services/user/user-state.service'; + +@Component({ + selector: '[app-login-menu]', + templateUrl: './login-menu.component.html', + styleUrls: ['./login-menu.component.scss'] +}) +export class LoginMenuComponent { + + username: string; + + constructor(private router: Router, private authService: AuthService, private userStateService: UserStateService) { + this.authService.checkServerLogin(); + this.userStateService.user.subscribe(user => { + if (user) { + this.username = user.fullName; + } + }); + } + + /** + * Check is a user is logged in. + * + * @returns true if user logged in, false otherwise + */ + isUserLoggedIn(): boolean { + return this.authService.isLoggedIn; + } + + /** + * Redirect to login page + */ + login() { + this.router.navigate(['login']); + } + + /** + * Logout current user + */ + logOut() { + this.authService.logout(); + } + +} diff --git a/src/app/menupanel/login/login.component.html b/src/app/menupanel/login/login.component.html new file mode 100644 index 000000000..4c1a26c54 --- /dev/null +++ b/src/app/menupanel/login/login.component.html @@ -0,0 +1,12 @@ +
+
+
+

AuScope Discovery Portal

+ +

Please log in using one of the options below

+
+
+ +
+
+
diff --git a/src/app/menupanel/login/login.component.scss b/src/app/menupanel/login/login.component.scss new file mode 100644 index 000000000..2d1a5c5dd --- /dev/null +++ b/src/app/menupanel/login/login.component.scss @@ -0,0 +1,37 @@ +@import 'app/globals'; + +.login-page { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: auto; + background: $auscope-royal-blue; + text-align: center; + color: #fff; + padding: 3em; + + .user-avatar { + -webkit-border-radius: 50%; + border-radius: 50%; + border: 2px solid #fff; + } + + .login-message { + margin: 10px 0 20px 0; + } + + .login-button { + cursor: pointer; + } + + img { + margin-bottom: 10px; + } + + i { + margin-bottom: 10px; + } + +} diff --git a/src/app/menupanel/login/login.component.ts b/src/app/menupanel/login/login.component.ts new file mode 100644 index 000000000..4f4f1500b --- /dev/null +++ b/src/app/menupanel/login/login.component.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; +import { routerTransition } from '../../router.animations'; +import { environment } from '../../../environments/environment'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'], + animations: [routerTransition()] +}) +export class LoginComponent { + constructor() {} + + // TODO: We may need to store some user site settings to local storage if not saved to DB for post-auth + + /** + * Google login + */ + loginGoogle() { + window.location.href = environment.portalBaseUrl + 'oauth2/authorization/google'; + } + + /** + * Australia Access Federation (AAF) login + */ + loginAaf() { + window.location.href = environment.portalBaseUrl + 'login/aaf'; + } + + /** + * Github login + */ + loginGithub() { + window.location.href = environment.portalBaseUrl + 'oauth2/authorization/github'; + } + +} diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts new file mode 100644 index 000000000..4875d55b0 --- /dev/null +++ b/src/app/models/user.model.ts @@ -0,0 +1,9 @@ +/** + * User Models + */ +export interface User { + fullName: string; + email: string; + // Currently unused + acceptedTermsConditions: number; +} diff --git a/src/app/portal/portal.component.html b/src/app/portal/portal.component.html new file mode 100644 index 000000000..be1ac1580 --- /dev/null +++ b/src/app/portal/portal.component.html @@ -0,0 +1,92 @@ + + + + + + + + + +
+ +
+ +
+ +
+ + + + + diff --git a/src/app/portal/portal.component.ts b/src/app/portal/portal.component.ts new file mode 100644 index 000000000..0ece36de6 --- /dev/null +++ b/src/app/portal/portal.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +/** + * Defines the overall app layout + */ +@Component({ + selector: 'app-portal', + templateUrl: './portal.component.html', + styleUrls: ['../../styles.scss'] +}) +export class PortalComponent { + + constructor() {} + +} diff --git a/src/app/router.animations.ts b/src/app/router.animations.ts new file mode 100644 index 000000000..197500631 --- /dev/null +++ b/src/app/router.animations.ts @@ -0,0 +1,65 @@ +import { animate, state, style, transition, trigger } from '@angular/animations'; + +export function routerTransition() { + return slideToTop(); +} + +export function slideToRight() { + return trigger('routerTransition', [ + state('void', style({})), + state('*', style({})), + transition(':enter', [ + style({ transform: 'translateX(-100%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' })) + ]), + transition(':leave', [ + style({ transform: 'translateX(0%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateX(100%)' })) + ]) + ]); +} + +export function slideToLeft() { + return trigger('routerTransition', [ + state('void', style({})), + state('*', style({})), + transition(':enter', [ + style({ transform: 'translateX(100%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateX(0%)' })) + ]), + transition(':leave', [ + style({ transform: 'translateX(0%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateX(-100%)' })) + ]) + ]); +} + +export function slideToBottom() { + return trigger('routerTransition', [ + state('void', style({})), + state('*', style({})), + transition(':enter', [ + style({ transform: 'translateY(-100%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateY(0%)' })) + ]), + transition(':leave', [ + style({ transform: 'translateY(0%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateY(100%)' })) + ]) + ]); +} + +export function slideToTop() { + return trigger('routerTransition', [ + state('void', style({})), + state('*', style({})), + transition(':enter', [ + style({ transform: 'translateY(100%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateY(0%)' })) + ]), + transition(':leave', [ + style({ transform: 'translateY(0%)' }), + animate('0.5s ease-in-out', style({ transform: 'translateY(-100%)' })) + ]) + ]); +} diff --git a/src/app/services/api/auscope-api.service.ts b/src/app/services/api/auscope-api.service.ts index 2a55bb5aa..517863b32 100644 --- a/src/app/services/api/auscope-api.service.ts +++ b/src/app/services/api/auscope-api.service.ts @@ -1,5 +1,6 @@ import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; +import { User } from 'app/models/user.model'; import { Observable, of, throwError } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { environment } from '../../../environments/environment'; @@ -34,8 +35,7 @@ export class AuscopeApiService { } private apiPost(endpoint: string, params = {}, options = {}): Observable { - const url = environment.portalBaseUrl + endpoint; - + const url = environment.portalProxyUrl + endpoint; const body = new FormData(); for (const key in params) { const val = params[key]; @@ -52,9 +52,8 @@ export class AuscopeApiService { } private apiGet(endpoint: string, params = {}, options?): Observable { - const url = environment.portalBaseUrl + endpoint; + const url = environment.portalProxyUrl + endpoint; const opts: { observe: 'body' } = { ...options, observe: 'body', params: params }; - return this.http.get>(url, opts).pipe(switchMap(apiData)); } @@ -105,4 +104,8 @@ export class AuscopeApiService { return this.apiGet('suggestTerms.do', params); } + public get user(): Observable { + return this.apiGet('secure/getUser.do'); + } + } diff --git a/src/app/services/auth/auth.guard.ts b/src/app/services/auth/auth.guard.ts new file mode 100644 index 000000000..dc8643297 --- /dev/null +++ b/src/app/services/auth/auth.guard.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@angular/core'; +import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { AuthService } from './auth.service'; +import { UserStateService } from '../user/user-state.service'; + +/** + * AuthGuard is not so useful at the moment with all pages available to the user, + * but may become useful down the track if we want to limit access to pages (by adding + * "canActivate [AuthGuard]" to the route deinfintion). + */ +@Injectable() +export class AuthGuard implements CanActivate { + + constructor(private router: Router, + private authService: AuthService, + private userStateService: UserStateService) {} + + canActivate(router: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + const url: string = state.url; + return this.checkLogin(url); + } + + checkLogin(url: string): Observable | boolean { + if (this.authService.isLoggedIn) { + return this.userStateService.user.pipe(map( + // Later we can use 'user' to check T&C's etc. if necessary + user => { + return true; + } + )); + } + // Navigate to the login page + this.router.navigate(['/login']); + return false; + } + +} diff --git a/src/app/services/auth/auth.service.ts b/src/app/services/auth/auth.service.ts new file mode 100644 index 000000000..46fb0152c --- /dev/null +++ b/src/app/services/auth/auth.service.ts @@ -0,0 +1,63 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { UserStateService } from '../user/user-state.service'; +import { environment } from 'environments/environment'; + +@Injectable() +export class AuthService { + + constructor(private userStateService: UserStateService, + private router: Router, + private http: HttpClient) {} + + logout(): void { + localStorage.removeItem('isLoggedIn'); + this.http.get(environment.portalProxyUrl + 'logout').subscribe(() => { + this.userStateService.removeUser(); + this.router.navigate(['']); + }); + } + + /** + * Update the local user object to see if the User has been logged out of + * the server, but the front end doesn't know it yet + */ + checkServerLogin(): void { + this.userStateService.updateUser().subscribe(user => { + if (user === null) { + localStorage.removeItem('isLoggedIn'); + } else { + localStorage.setItem('isLoggedIn', 'true'); + } + }, () => { + localStorage.removeItem('isLoggedIn'); + }); + } + + onLoggedIn() { + this.userStateService.updateUser().subscribe(user => { + localStorage.setItem('isLoggedIn', 'true'); + this.router.navigate(['/']); + }); + } + + public get isLoggedIn(): boolean { + return localStorage.getItem('isLoggedIn') === 'true'; + } + + public get redirectUrl(): string { + return localStorage.getItem('redirectUrl'); + } + + public set redirectUrl(url: string) { + localStorage.setItem('redirectUrl', url); + } + + resetRedirectUrl(): string { + const url = localStorage.getItem('redirectUrl'); + localStorage.removeItem('redirectUrl'); + return url; + } + +} diff --git a/src/app/services/user/user-state.service.ts b/src/app/services/user/user-state.service.ts new file mode 100644 index 000000000..85a3129a0 --- /dev/null +++ b/src/app/services/user/user-state.service.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { User } from '../../models/user.model'; +import { AuscopeApiService } from '../api/auscope-api.service'; + + +@Injectable() +export class UserStateService { + + private _user: BehaviorSubject = new BehaviorSubject(null); + public readonly user: Observable = this._user.asObservable(); + + constructor(private apiService: AuscopeApiService) {} + + public updateUser(): Observable { + return this.apiService.user.pipe( + map((user: User) => { + // If full name is empty (as with AAF login), use email address as name + if (user.fullName === undefined || user.fullName === '') { + user.fullName = user.email; + } + this._user.next(user); + + // TODO: Update bookmarks when we have them + + return user; + }, + // Failure to retrieve User means no User logged in + () => { + this.removeUser(); + })); + } + + public removeUser() { + this._user.next(null); + } + +} diff --git a/src/environments/environment.au2.ts b/src/environments/environment.au2.ts index 914b95b21..58f8d6bf5 100644 --- a/src/environments/environment.au2.ts +++ b/src/environments/environment.au2.ts @@ -13,6 +13,7 @@ export const environment = { production: true, getCSWRecordEndP: 'getKnownLayers.do', portalBaseUrl: 'https://au-portal-2.it.csiro.au/api/', + portalProxyUrl: '/api/', hostUrl: 'https://au-portal-2.it.csiro.au/portal/index.htm', nVCLAnalyticalUrl: 'https://nvclanalytics.azurewebsites.net/NVCLAnalyticalServices/', googleAnalyticsKey: null, diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts index e4ed4a4be..131c734ff 100644 --- a/src/environments/environment.dev.ts +++ b/src/environments/environment.dev.ts @@ -13,6 +13,7 @@ export const environment = { production: false, getCSWRecordEndP: 'getKnownLayers.do', portalBaseUrl: 'https://au-portal-dev.it.csiro.au/api/', + portalProxyUrl: '/api/', hostUrl: 'https://au-portal-dev.it.csiro.au/index.htm', nVCLAnalyticalUrl: 'https://nvclanalytics.azurewebsites.net/NVCLAnalyticalServices/', googleAnalyticsKey: null, diff --git a/src/environments/environment.prod-https.ts b/src/environments/environment.prod-https.ts index d18b51183..29cd83d98 100644 --- a/src/environments/environment.prod-https.ts +++ b/src/environments/environment.prod-https.ts @@ -13,6 +13,7 @@ export const environment = { production: true, getCSWRecordEndP: 'getKnownLayers.do', portalBaseUrl: 'https://auscope-portal.geoanalytics.csiro.au/api/', + portalProxyUrl: '/api/', hostUrl: 'https://auscope-portal.geoanalytics.csiro.au/index.htm', nVCLAnalyticalUrl: 'https://nvclanalytics.azurewebsites.net/NVCLAnalyticalServices/', googleAnalyticsKey: null, diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 41cdafea1..238a1218b 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -13,6 +13,7 @@ export const environment = { production: true, getCSWRecordEndP: 'getKnownLayers.do', portalBaseUrl: 'http://portal.auscope.org.au/api/', + portalProxyUrl: '/api/', hostUrl: 'http://portal.auscope.org.au/index.htm', nVCLAnalyticalUrl: 'https://nvclanalytics.azurewebsites.net/NVCLAnalyticalServices/', googleAnalyticsKey: null, diff --git a/src/environments/environment.ts b/src/environments/environment.ts index c45caa61b..894ec5da9 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -13,6 +13,7 @@ export const environment = { getCSWRecordEndP: 'getKnownLayers.do', // portalBaseUrl: 'http://localhost:8080/AuScope-Portal/', portalBaseUrl: 'https://au-portal-dev.it.csiro.au/api/', + portalProxyUrl: '/api/', hostUrl: 'http://localhost:4200/index.htm', nVCLAnalyticalUrl: 'https://nvclanalytics.azurewebsites.net/NVCLAnalyticalServices/', googleAnalyticsKey: null, diff --git a/src/extension/img/GitHub_Logo.png b/src/extension/img/GitHub_Logo.png new file mode 100644 index 000000000..812b7f227 Binary files /dev/null and b/src/extension/img/GitHub_Logo.png differ diff --git a/src/extension/img/aaf_service_223x54.png b/src/extension/img/aaf_service_223x54.png new file mode 100644 index 000000000..8f001b666 Binary files /dev/null and b/src/extension/img/aaf_service_223x54.png differ diff --git a/src/extension/img/btn_google_signin_dark_normal_web.png b/src/extension/img/btn_google_signin_dark_normal_web.png new file mode 100644 index 000000000..b1327b4f7 Binary files /dev/null and b/src/extension/img/btn_google_signin_dark_normal_web.png differ diff --git a/src/index.htm b/src/index.htm index 5918fbba0..5dce2d6d8 100644 --- a/src/index.htm +++ b/src/index.htm @@ -1,156 +1,44 @@ - - - AuScope Discovery Portal - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
- -
- - - - - - - - - - - - - - - - - + + + AuScope Discovery Portal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/styles.scss b/src/styles.scss index b1821a382..cdbf41082 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -306,12 +306,6 @@ label { } /* top level menu control in sidebar */ - - .menuBtn + h5 > ul { - /*opacity: 0.01; max-height: 0px; transition: opacity 1s, max-height 1s;*/ - display: none; - } - .menuBtn:checked + h5 > ul { /*opacity: 1; max-height: 999px; transition: opacity 1s, max-height 1s;*/ display: block;