LP#626157 Ang2 experiments
authorBill Erickson <berickxx@gmail.com>
Sun, 26 Nov 2017 14:20:17 +0000 (09:20 -0500)
committerBill Erickson <berickxx@gmail.com>
Mon, 11 Dec 2017 17:39:51 +0000 (12:39 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
14 files changed:
Open-ILS/webby-src/src/app/base.module.ts
Open-ILS/webby-src/src/app/core/auth.service.ts
Open-ILS/webby-src/src/app/staff/admin/workstation/admin-ws.module.ts
Open-ILS/webby-src/src/app/staff/admin/workstation/workstations.component.html
Open-ILS/webby-src/src/app/staff/admin/workstation/workstations.component.ts
Open-ILS/webby-src/src/app/staff/login.component.html
Open-ILS/webby-src/src/app/staff/login.component.ts
Open-ILS/webby-src/src/app/staff/nav.component.css
Open-ILS/webby-src/src/app/staff/nav.component.html
Open-ILS/webby-src/src/app/staff/resolver.service.ts
Open-ILS/webby-src/src/app/staff/staff.component.html
Open-ILS/webby-src/src/app/staff/staff.component.ts
Open-ILS/webby-src/src/app/staff/staff.module.ts
Open-ILS/webby-src/src/index.html

index 553e8aa..a464f61 100644 (file)
@@ -3,22 +3,22 @@
  * It provides the root router and a simple welcome page for 
  * users that end up here accidentally.
  */
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule }      from '@angular/core';
-import { Router }        from '@angular/router'; // Debugging
-import { NgbModule }     from '@ng-bootstrap/ng-bootstrap';
-import { CookieModule }  from 'ngx-cookie'; // import CookieMonster
+import {BrowserModule} from '@angular/platform-browser';
+import {NgModule} from '@angular/core';
+import {Router} from '@angular/router'; // Debugging
+import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
+import {CookieModule} from 'ngx-cookie'; // import CookieMonster
 
-import { EgBaseComponent }     from './base.component';
-import { EgBaseRoutingModule } from './routing.module';
-import { WelcomeComponent }    from './welcome.component';
+import {EgBaseComponent} from './base.component';
+import {EgBaseRoutingModule} from './routing.module';
+import {WelcomeComponent} from './welcome.component';
 
 // Import and 'provide' globally required services.
-import { EgEventService } from '@eg/core/event.service';
-import { EgIdlService }   from '@eg/core/idl.service';
-import { EgNetService }   from '@eg/core/net.service';
-import { EgAuthService }  from '@eg/core/auth.service';
-import { EgStoreService } from '@eg/core/store.service';
+import {EgEventService} from '@eg/core/event.service';
+import {EgIdlService} from '@eg/core/idl.service';
+import {EgNetService} from '@eg/core/net.service';
+import {EgAuthService} from '@eg/core/auth.service';
+import {EgStoreService} from '@eg/core/store.service';
 
 @NgModule({
   declarations: [
index ec97f37..3e78d87 100644 (file)
@@ -196,13 +196,11 @@ export class EgAuthService {
                 return;
             }
 
-            console.debug(`Verifying workstation ${this.user().wsid()}`);
-            
             this.egStore.getItem('eg.workstation.all')
             .then(workstations => {
                 if (!workstations) workstations = [];
 
-                var ws = workstations.filter(
+                let ws = workstations.filter(
                     w => {return w.id == this.user().wsid()})[0];
 
                 if (ws) {
index 43eb5de..743ef85 100644 (file)
@@ -1,8 +1,9 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { FormsModule } from '@angular/forms';
-import { EgAdminWsRoutingModule } from './routing.module';
-import { EgWorkstationsComponent } from './workstations.component';
+import {NgModule} from '@angular/core';
+import {CommonModule} from '@angular/common';
+import {FormsModule} from '@angular/forms';
+import {EgAdminWsRoutingModule} from './routing.module';
+import {EgWorkstationsComponent} from './workstations.component';
+
 
 @NgModule({
   declarations: [
@@ -11,7 +12,7 @@ import { EgWorkstationsComponent } from './workstations.component';
   imports: [
     EgAdminWsRoutingModule,
     CommonModule,
-    FormsModule
+    FormsModule,
   ]
 })
 
index becc930..ebb2b8f 100644 (file)
@@ -1,6 +1,60 @@
+<div class="col-md-10 offset-md-1">
+  <div class="alert alert-warning" *ngIf="removingWs" i18n>
+    Workstation {{removingWs}} is no longer valid.  Removing registration.
+  </div>
+  <div class="alert alert-danger" *ngIf="workstations.length == 0">
+    <span i18n>Please register a workstation.</span>
+  </div>
+  <div class="row">
+    <div class="col-md-6">
+      <span i18n>Register a New Workstation For This Browser</span>
+    </div>
+  </div>
+
+  <!--
+  <div class="row">
+    <div class="col-md-6">
+      <div class="input-group">
+        <div class="input-group-btn">
+          <b>org selector...</b>
+          <eg-org-selector 
+            selected="contextOrg"
+            hidden-test="wsOrgHidden">
+            disable-test="cant_have_users">
+          </eg-org-selector>
+        </div>
+        <input type='text' class='form-control'  
+          i18n-title
+          title="Workstation Name"
+          i18n-placeholder
+          placeholder="Workstation Name"
+          [(ngModel)]='newWSName'/>
+        <div class="input-group-btn">
+          <button class="btn btn-default" *ngClick="registerWs()">
+            <span i18n>Register</span>
+          </button>
+        </div>
+      </div>
+    </div>
+  </div>
+  -->
+
+  <div class="row new-entry">
+    <div class="col-md-6">
+      <span i18n>Workstations Registered With This Browser</span>
+    </div>
+  </div>
+  <div class="row">
+    <div class="col-md-6">
+      <select 
+        class="form-control"
+        i18n-placeholder 
+        [(ngModel)]="selectedWs">
+        <option *ngFor="let ws of workstations" value="{{ws.id}}">
+          {{ws.name}}
+        </option>
+      </select>
+    </div>
+  </div>
+</div>
 
-<br/>
-<br/>
-<br/>
-<br/>
-<b> WORKSTATIONS ADMIN </b>
index aebfa06..bf7717d 100644 (file)
@@ -1,7 +1,8 @@
-import { Component, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-import { EgNetService } from '@eg/core/net.service';
-import { EgAuthService } from '@eg/core/auth.service';
+import {Component, OnInit} from '@angular/core';
+import {ActivatedRoute} from '@angular/router';
+import {EgNetService} from '@eg/core/net.service';
+import {EgStoreService} from '@eg/core/store.service';
+import {EgAuthService} from '@eg/core/auth.service';
 
 @Component({
   templateUrl: 'workstations.component.html'
@@ -9,16 +10,23 @@ import { EgAuthService } from '@eg/core/auth.service';
 
 export class EgWorkstationsComponent implements OnInit {
 
+    workstations: Object[] = [];
+    removingWs: boolean = false;
+
     constructor(
         private route: ActivatedRoute,
         private egNet: EgNetService,
-        private egAuth: EgAuthService
+        private egAuth: EgAuthService,
+        private egStore: EgStoreService
     ) {}
 
     ngOnInit() {
 
         console.log('EgWorkstationsComponent:ngOnInit()');
 
+        this.egStore.getItem('eg.workstation.all').then(
+            res => this.workstations = res
+        );
     }
 }
 
index 73a6b38..ae74776 100644 (file)
@@ -1,38 +1,90 @@
-<div class="row" style="margin-top: 60px;"><!-- why margin needed? -->
-  <div class="col-md-6 offset-md-3">
-    <fieldset>
-      <legend i18n>Sign In</legend>
+<!--
+<mat-grid-list cols="3" rowHeight="3:2">
+  <mat-grid-tile></mat-grid-tile>
+  <mat-grid-tile>
+    <style>
+      #staff-login-form { width: 80% }
+      mat-form-field { width: 80% }
+    </style>
+    <form (ngSubmit)="handleSubmit()" #loginForm="ngForm" id="staff-login-form">
+
+      <h3 i18n>Sign In</h3>
       <hr/>
-      <form (ngSubmit)="handleSubmit()" #loginForm="ngForm">
 
-        <div class="form-group">
-          <label for="username" i18n>Username</label>
+      <p>
+        <mat-form-field>
           <input 
             type="text" 
-              class="form-control" 
-              id="username" 
-              name="username"
-              required
-              i18n-placeholder
-              placeholder="Username" 
-              [(ngModel)]="args.username"/>
-        </div>
-
-        <div class="form-group">
-          <label for="password" i18n>Password</label>
+            id="username" 
+            name="username"
+            matInput
+            required
+            i18n-placeholder
+            placeholder="Username" 
+            [(ngModel)]="args.username"/>
+        </mat-form-field>
+      </p>
+
+      <p>
+        <mat-form-field>
           <input 
             type="password" 
             class="form-control"
             id="password" 
             name="password"
+            matInput
             required
             i18n-placeholder
             placeholder="Password" 
             [(ngModel)]="args.password"/>
-        </div>
+        </mat-form-field>
+      </p>
+
+      <p>
+        <button mat-raised-button type='submit' color='primary' i18n>
+          Sign in
+        </button>
+      </p>
+
+    </form>
+  </mat-grid-tile>
+  <mat-grid-tile></mat-grid-tile>
+</mat-grid-list>
+-->
+
+<div class="col-md-6 offset-md-3">
+  <fieldset>
+    <legend i18n>Sign In</legend>
+    <hr/>
+    <form (ngSubmit)="handleSubmit()" #loginForm="ngForm">
+
+      <div class="form-group">
+        <label for="username" i18n>Username</label>
+        <input 
+          type="text" 
+          class="form-control"
+          id="username" 
+          name="username"
+          required
+          i18n-placeholder
+          placeholder="Username" 
+          [(ngModel)]="args.username"/>
+      </div>
+
+      <div class="form-group">
+        <label for="password" i18n>Password</label>
+        <input 
+          type="password" 
+          class="form-control"
+          id="password" 
+          name="password"
+          required
+          i18n-placeholder
+          placeholder="Password" 
+          [(ngModel)]="args.password"/>
+      </div>
 
-        <button type="submit" class="btn btn-primary" i18n>Sign in</button>
-      </form>
-    </fieldset>
-  </div>
+      <button type="submit" class="btn btn-light" i18n>Sign in</button>
+    </form>
+  </fieldset>
 </div>
index 7886575..599562d 100644 (file)
@@ -2,6 +2,7 @@ import { Component, OnInit, Renderer } from '@angular/core';
 import { Location } from '@angular/common';
 import { Router } from '@angular/router';
 import { EgAuthService, EgAuthWsState } from '@eg/core/auth.service';
+import { EgStoreService } from '@eg/core/store.service'; // TODO: testing
 
 @Component({
   templateUrl : './login.component.html'
@@ -23,7 +24,8 @@ export class EgStaffLoginComponent implements OnInit {
       private router: Router,
       private ngLocation: Location,
       private renderer: Renderer,
-      private egAuth: EgAuthService
+      private egAuth: EgAuthService,
+      private egStore: EgStoreService 
     ) {}
     
     ngOnInit() {
@@ -35,6 +37,12 @@ export class EgStaffLoginComponent implements OnInit {
         this.renderer.selectRootElement('#username').focus();
 
         // load browser-local workstation data
+
+        // TODO: insert for testing.
+        this.egStore.setItem(
+          'eg.workstation.all', 
+          [{name:'BR1-skiddoo',id:1,owning_lib:4}]
+        ); 
     }
 
     handleSubmit() {
@@ -45,6 +53,7 @@ export class EgStaffLoginComponent implements OnInit {
         this.egAuth.login(this.args).then(
             ok => {
                 this.egAuth.redirectUrl = null;
+
                 if (this.egAuth.workstationState == EgAuthWsState.NOT_FOUND_SERVER) {
                     // User is logged in without a workstation.
                     // Redirect them to the WS admin page.
@@ -54,7 +63,8 @@ export class EgStaffLoginComponent implements OnInit {
                     // Force reload of the app after a successful login.
                     // This allows the route resolver to re-run with a 
                     // valid auth token and workstation.
-                    window.location.href = this.ngLocation.prepareExternalUrl(url);
+                    window.location.href = 
+                        this.ngLocation.prepareExternalUrl(url);
                 }
             },
             notOk => {
index 288f14b..96946d5 100644 (file)
@@ -1,32 +1,39 @@
-#staff-navbar.navbar-default {
+#staff-navbar {
     background: -webkit-linear-gradient(#00593d, #007a54);
     background-color: #007a54;
     color: #fff;
+    font-size: 14px;
 }
-#staff-navbar.navbar-default .navbar-nav>li>a {
+#staff-navbar .navbar-expander {
+  margin-right: auto;
+}
+#staff-navbar .navbar-nav>li>a {
     color: #fff;
     padding-top: 5px;
-    padding-bottom: 5px;
+    padding-bottom: 1px;
+}
+#staff-navbar .nav-item {
+  margin-right: 10px;
 }
-#staff-navbar.navbar-default .navbar-nav>li>a:hover {
+#staff-navbar .navbar-nav>li>a:hover {
     color: #ddd;
+    cursor: pointer;
 }
-#staff-navbar.navbar-default .navbar-nav > .open > a,
-#staff-navbar.navbar-default .navbar-nav > .open > a:focus,
-#staff-navbar.navbar-default .navbar-nav > .open > a:hover {
+#staff-navbar .navbar-nav > .open > a,
+#staff-navbar .navbar-nav > .open > a:focus,
+#staff-navbar .navbar-nav > .open > a:hover {
     background-color: #7a7a7a;
 }
-#staff-navbar.navbar-default .navbar-nav>.dropdown>a .caret {
+#staff-navbar .navbar-nav>.dropdown>a .caret {
     border-top-color: #fff;
     border-bottom-color: #fff;
 }
-#staff-navbar.navbar-default .navbar-nav>.dropdown>a:hover .caret {
+#staff-navbar .navbar-nav>.dropdown>a:hover .caret {
     border-top-color: #ddd;
     border-bottom-color: #ddd;
 }
-#staff-navbar .nav-left {
-  margin-right: auto;
-}
-#staff-navbar .nav-right {
-  margin-right: 6px;
+/* remove dropdown carret for icon-based entries */
+#staff-navbar .no-caret::after {
+    display:none;
 }
+
index b7d566b..e5f32cd 100644 (file)
@@ -4,15 +4,18 @@ href="./stuff"
 direct routing
 routerLink="/suff"
 -->
+
 <nav id="staff-navbar" class="navbar fixed-top navbar-expand navbar-default">
   <div class="collapse navbar-collapse">
-    <ul class="navbar-nav nav-left">
-      <li class="nav-item active">
-        <a i18n class="nav-link" routerLink="/staff/splash">Home</a>
+    <ul class="navbar-nav">
+      <li class="nav-item">
+        <a i18n class="nav-link" routerLink="/staff/splash">
+          <i class="material-icons">home</i>
+        </a>
       </li>
       <li ngbDropdown class="nav-item dropdown">
         <a ngbDropdownToggle i18n class="nav-link dropdown-toggle">
-          Dropdown link
+         Circulation 
         </a>
         <div class="dropdown-menu" ngbDropdownMenu>
           <a i18n class="dropdown-item" routerLink="/staff">Test Action</a>
@@ -21,9 +24,12 @@ routerLink="/suff"
         </div>
       </li>
     </ul>
-    <ul class="navbar-nav nav-right">
-      <li ngbDropdown class="nav-item dropdown">
-        <a ngbDropdownToggle i18n class="nav-link dropdown-toggle">Hamburger</a>
+    <ul class="navbar-expander"></ul>
+    <ul class="navbar-nav">
+      <li ngbDropdown class="nav-item dropdown" placement="bottom-right">
+        <a ngbDropdownToggle i18n class="nav-link dropdown-toggle no-caret">
+          <i class="material-icons">more_vert</i>
+        </a>
         <div class="dropdown-menu" ngbDropdownMenu>
           <a i18n class="dropdown-item" routerLink="/staff/login">Logout</a>
         </div>
index ac7841e..83dba49 100644 (file)
@@ -58,7 +58,7 @@ export class EgStaffResolver implements Resolve<Observable<any>> {
                 }, 
                 tokenNotOk => {
                     // Authtoken is not OK.
-                    this.egAuth.redirectUrl = this.router.url;
+                    this.egAuth.redirectUrl = state.url;
                     this.router.navigate([this.loginPath]);
                     observer.complete();
                 }
index 36ae852..0c4993d 100644 (file)
@@ -2,5 +2,8 @@
 <eg-staff-nav-bar></eg-staff-nav-bar>
 
 <!-- page content -->
-<router-outlet></router-outlet>
+<!-- margin is there to accommodate navbar -->
+<div style="margin-top:74px">
+  <router-outlet></router-outlet>
+</div>
 
index 5bfc81e..6f7ba18 100644 (file)
@@ -38,7 +38,8 @@ export class EgStaffComponent implements OnInit {
 
         this.route.data.subscribe((data: {staffResolver : any}) => {
             console.debug('EgStaff ngOnInit complete');
-        });
+     
+      });
     }
 
     /**
index 529528d..456c582 100644 (file)
@@ -1,13 +1,13 @@
-import { CommonModule } from '@angular/common';
-import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {FormsModule} from '@angular/forms';
+import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
 
-import { EgStaffComponent } from './staff.component';
-import { EgStaffRoutingModule } from './routing.module';
-import { EgStaffNavComponent } from './nav.component';
-import { EgStaffLoginComponent } from './login.component';
-import { EgStaffSplashComponent } from './splash.component';
+import {EgStaffComponent} from './staff.component';
+import {EgStaffRoutingModule} from './routing.module';
+import {EgStaffNavComponent} from './nav.component';
+import {EgStaffLoginComponent} from './login.component';
+import {EgStaffSplashComponent} from './splash.component';
 
 @NgModule({
   declarations: [
@@ -20,8 +20,7 @@ import { EgStaffSplashComponent } from './splash.component';
     EgStaffRoutingModule,
     FormsModule,
     NgbModule
-  ],
-  providers: []
+  ]
 })
 
 export class EgStaffModule { 
index 6036b5d..3d65f2d 100644 (file)
@@ -3,10 +3,13 @@
 <head>
   <meta charset="utf-8">
   <title i18n="Page Title">Eg</title>
-  <base href="/">
+  <base href="/webby">
 
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
+  <!-- todo -->
+  <!-- see self-hosting options https://google.github.io/material-design-icons/#icon-font-for-the-web -->
+  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
   <!-- link to bootstrap manually for the time being.  With 
         ng-bootstrap, we only need the CSS, not the JS -->
   <link rel="stylesheet"