rec[field.name](org.id());
}
}
-
- /* TODO
- // retrieve values from any fields controlled
- // by custom templates, which for the moment all
- // expect to be passed an ordinary flat value
- if (field.name in $scope.rec_flat) {
- rec[field.name]($scope.rec_flat[field.name]);
- }
- */
});
}
--- /dev/null
+/*j
+ * <eg-string #helloStr text="Hello, {{name}}" i18n-text></eg-string>
+ *
+ * import {EgStringComponent} from '@eg/share/string.component';
+ * @ViewChild('helloStr') private helloStr: EgStringComponent;
+ * ...
+ * this.helloStr.currrent().then(s => console.log(s));
+ *
+ */
+import {Component, Input, OnInit, ElementRef, TemplateRef} from '@angular/core';
+import {EgStringService} from '@eg/share/string/string.service';
+
+@Component({
+ selector: 'eg-string',
+ template: `
+ <span style='display:none'>
+ <ng-container *ngTemplateOutlet="template; context:ctx"></ng-container>
+ </span>
+ `
+})
+
+export class EgStringComponent implements OnInit {
+
+ @Input() key: string;
+ @Input() ctx: any;
+ @Input() template: TemplateRef<any>;
+
+ constructor(private elm: ElementRef, private strings: EgStringService) {
+ this.elm = elm;
+ this.strings = strings;
+ }
+
+ ngOnInit() {
+ this.strings.register({
+ key: this.key,
+ resolver: (ctx:any) => this.current(ctx)
+ });
+ }
+
+
+ // Apply the new context if provided, give our container a
+ // chance to update, then resolve with the current string.
+ current(ctx?: any): Promise<string> {
+ if (ctx) this.ctx = ctx;
+ return new Promise(resolve => {
+ setTimeout(() => resolve(this.elm.nativeElement.textContent));
+ });
+ }
+}
+
--- /dev/null
+import {Injectable} from '@angular/core';
+
+interface EgStringAssignment {
+ key: string, // keyboard command
+ resolver: (ctx:any) => Promise<string>
+};
+
+@Injectable()
+export class EgStringService {
+
+ strings: {[key:string] : EgStringAssignment} = {};
+
+ constructor() {}
+
+ register(assn: EgStringAssignment) {
+ this.strings[assn.key] = assn;
+ }
+
+ interpolate(key: string, ctx: any): Promise<string> {
+ if (!this.strings[key])
+ return Promise.reject('No Such String');
+ return this.strings[key].resolver(ctx);
+ }
+
+}
+
+
--- /dev/null
+#eg-toast-container {
+ min-width: 250px;
+ text-align: center;
+ border-radius: 2px;
+ padding: 10px;
+ position: fixed;
+ z-index: 1;
+ right: 15px;
+ bottom: 5px;
+}
+
--- /dev/null
+<div id="eg-toast-container" *ngIf="message">
+ <ngb-alert [type]="message.style" (close)="dismiss(message)">{{message.text}}</ngb-alert>
+</div>
--- /dev/null
+import {Component, Input, OnInit, ViewChild} from '@angular/core';
+import {EgToastService, EgToastMessage} from '@eg/share/toast/toast.service';
+
+const EG_TOAST_TIMEOUT = 3000;
+
+@Component({
+ selector: 'eg-toast',
+ templateUrl: './toast.component.html',
+ styleUrls: ['./toast.component.css']
+})
+export class EgToastComponent implements OnInit {
+
+ message: EgToastMessage;
+
+ // track the most recent timeout event
+ timeout: any;
+
+ constructor(private toast: EgToastService) {
+ }
+
+ ngOnInit() {
+ this.toast.messages$.subscribe(msg => this.show(msg));
+ }
+
+ show(msg: EgToastMessage) {
+ this.dismiss(this.message);
+ this.message = msg;
+ this.timeout = setTimeout(
+ () => this.dismiss(this.message),
+ EG_TOAST_TIMEOUT
+ );
+ }
+
+ dismiss(msg: EgToastMessage) {
+ this.message = null;
+ if (this.timeout) {
+ clearTimeout(this.timeout);
+ this.timeout = null;
+ }
+ }
+}
+
+
--- /dev/null
+import {Injectable, EventEmitter} from '@angular/core';
+
+export interface EgToastMessage {
+ text: string,
+ style: string
+};
+
+@Injectable()
+export class EgToastService {
+
+ messages$: EventEmitter<EgToastMessage>;
+
+ constructor() {
+ this.messages$ = new EventEmitter<EgToastMessage>();
+ }
+
+ sendMessage(msg: EgToastMessage) {
+ this.messages$.emit(msg);
+ }
+
+ success(text: string) {
+ this.sendMessage({text: text, style: 'success'});
+ }
+
+ info(text: string) {
+ this.sendMessage({text: text, style: 'info'});
+ }
+
+ warning(text: string) {
+ this.sendMessage({text: text, style: 'warning'});
+ }
+
+ danger(text: string) {
+ this.sendMessage({text: text, style: 'danger'});
+ }
+
+ // Others?
+}
+
import {EgOpChangeComponent} from '@eg/staff/share/op-change/op-change.component';
import {EgToastService} from '@eg/share/toast/toast.service';
import {EgToastComponent} from '@eg/share/toast/toast.component';
+import {EgStringComponent} from '@eg/share/string/string.component';
+import {EgStringService} from '@eg/share/string/string.service';
/**
* Imports the EG common modules and adds modules common to all staff UI's.
EgAccessKeyDirective,
EgAccessKeyInfoComponent,
EgToastComponent,
+ EgStringComponent,
EgOpChangeComponent
],
imports: [
EgAccessKeyDirective,
EgAccessKeyInfoComponent,
EgToastComponent,
+ EgStringComponent,
EgOpChangeComponent
]
})
ngModule: EgStaffCommonModule,
providers: [ // Export staff-wide services
EgAccessKeyService,
+ EgStringService,
EgToastService
]
};
</div>
<!-- / FM Editor Experiments ----------------------------- -->
-
<!-- Progress Dialog Experiments ----------------------------- -->
<div class="row mb-3">
<eg-progress-dialog #progressDialog>
<!-- /Progress Dialog Experiments ----------------------------- -->
<!-- eg toast -->
-<button class="btn btn-info" (click)="testToast()">Test Toast Message</button>
+<div class="row mb-3">
+ <button class="btn btn-info" (click)="testToast()">Test Toast Message</button>
+</div>
+
+<!-- eg strings -->
+<!--
+<div class="row mb-3">
+ <eg-string #helloString text="Hello, {{name}}" i18n-text></eg-string>
+ <button class="btn btn-success" (click)="testStrings()">Test Strings</button>
+</div>
+-->
+
+<div class="row mb-3">
+ <ng-template #helloStrTmpl let-name="name" i18n>Hello, {{name}}</ng-template>
+ <!--
+ <eg-string #helloStr key="helloKey" [template]="helloStrTmpl"></eg-string>
+ -->
+ <eg-string key="staff.sandbox.test" [template]="helloStrTmpl"></eg-string>
+ <button class="btn btn-success" (click)="testStrings()">Test Strings</button>
+</div>
+
-import {Component, OnInit, ViewChild} from '@angular/core';
+import {Component, OnInit, ViewChild, Input, TemplateRef} from '@angular/core';
import {EgProgressDialogComponent} from '@eg/share/dialog/progress.component';
import {EgToastService} from '@eg/share/toast/toast.service';
+import {EgStringService} from '@eg/share/string/string.service';
+import {Observable} from 'rxjs/Rx';
@Component({
templateUrl: 'sandbox.component.html'
@ViewChild('progressDialog')
private progressDialog: EgProgressDialogComponent;
+ //@ViewChild('helloStr') private helloStr: EgStringComponent;
+
+
+ testStr: string;
+ @Input() set testString(str: string) {
+ this.testStr = str;
+ }
+
+ name: string = 'Jane';
+
constructor(
+ private strings: EgStringService,
private toast: EgToastService
) {}
ngOnInit() {
+
}
showProgress() {
this.progressDialog.open();
- this.progressDialog.update({value: 1, max: 100})
- setTimeout(() => this.progressDialog.update({value: 5}), 1000);
- setTimeout(() => this.progressDialog.update({value: 10}), 2000);
- setTimeout(() => this.progressDialog.update({value: 50}), 3000);
- setTimeout(() => this.progressDialog.update({value: 95}), 4000);
- setTimeout(() => this.progressDialog.close(), 5000);
+
+ // every 250ms emit x*10 for 0-10
+ Observable.timer(0, 250).map(x => x * 10).take(11).subscribe(
+ val => this.progressDialog.update({value: val, max: 100}),
+ err => {},
+ () => this.progressDialog.close()
+ );
}
testToast() {
this.toast.success('HELLO TOAST TEST');
+ setTimeout(() => this.toast.danger('DANGER TEST AHHH!'), 4000);
+ }
+
+ testStrings() {
+ this.strings.interpolate('staff.sandbox.test', {name : 'janey'})
+ .then(txt => this.toast.success(txt));
+
+ setTimeout(() => {
+ this.strings.interpolate('staff.sandbox.test', {name : 'johnny'})
+ .then(txt => this.toast.success(txt));
+ }, 4000);
}
}
--- /dev/null
+<ng-template #dialogContent>
+ <div class="modal-header bg-info">
+ <h4 class="modal-title" i18n>Change Operator</h4>
+ <button type="button" class="close"
+ i18n-aria-label aria-label="Close"
+ (click)="dismiss('cross_click')">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <form class="form-validated">
+ <div class="form-group row">
+ <label class="col-lg-4 text-right font-weight-bold" for="username" i18n>Username</label>
+ <input
+ type="text"
+ class="form-control col-lg-7"
+ id="username"
+ name="username"
+ required
+ (keyup)="checkEnter($event)"
+ autocomplete="username"
+ i18n-placeholder
+ placeholder="Username..."
+ [(ngModel)]="username"/>
+ </div>
+
+ <div class="form-group row">
+ <label class="col-lg-4 text-right font-weight-bold"
+ for="password" i18n>Password</label>
+ <input
+ type="password"
+ class="form-control col-lg-7"
+ id="password"
+ name="password"
+ required
+ (keyup)="checkEnter($event)"
+ autocomplete="current-password"
+ i18n-placeholder
+ placeholder="Password..."
+ [(ngModel)]="password"/>
+ </div>
+
+ <div class="form-group row">
+ <label class="col-lg-4 text-right font-weight-bold"
+ for="loginType" i18n>Login Type</label>
+ <select
+ class="form-control col-lg-7"
+ id="loginType"
+ name="loginType"
+ placeholder="Login Type..."
+ i18n-placeholder
+ required
+ [(ngModel)]="loginType">
+ <option value="temp" selected i18n>Temporary</option>
+ <option value="staff" i18n>Staff</option>
+ <option value="persist" i18n>Persistent</option>
+ </select>
+ </div>
+ </form>
+ </div>
+ <div class="modal-footer">
+ <button (click)="login()" class="btn btn-info" i18n>OK/Continue</button>
+ <button (click)="dismiss('canceled')" class="btn btn-warning ml-2" i18n>Cancel</button>
+ </div>
+</ng-template>
--- /dev/null
+import {Component, OnInit, Input, Renderer} from '@angular/core';
+import {EgAuthService} from '@eg/core/auth.service';
+import {EgDialogComponent} from '@eg/share/dialog/dialog.component';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'eg-op-change',
+ templateUrl: 'op-change.component.html'
+})
+
+export class EgOpChangeComponent
+ extends EgDialogComponent implements OnInit {
+
+ @Input() username: string;
+ @Input() password: string;
+ @Input() loginType: string = 'temp';
+
+ constructor(
+ private modal: NgbModal, // required for passing to parent
+ private renderer: Renderer,
+ private auth: EgAuthService) {
+ super(modal);
+ }
+
+ ngOnInit() {
+
+ // Focus the username any time the dialog is opened.
+ this.onOpen$.subscribe(
+ val => this.renderer.selectRootElement('#username').focus()
+ );
+ }
+
+ checkEnter($event: any): void {
+ if ($event.keyCode == 13)
+ this.login();
+ }
+
+ login() {
+ if (!(this.username && this.password)) return;
+
+ this.auth.login(
+ { username : this.username,
+ password : this.password,
+ workstation : this.auth.workstation(),
+ type : this.loginType
+ }, true // isOpChange
+ ).then(
+ ok => {
+ console.log('OP change succeeded'),
+ this.close('login OK');
+ },
+ notOk => {
+ console.warn('OP change failed')
+ }
+ );
+ }
+}
+
+