--- /dev/null
+import {Component, EventEmitter, OnInit, AfterViewInit, Input,
+ Output, ViewChild, forwardRef} from '@angular/core';
+import {ControlValueAccessor, FormGroup, FormControl, NG_VALUE_ACCESSOR} from '@angular/forms';
+import {IdlObject} from '@eg/core/idl.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {ComboboxComponent, ComboboxEntry} from '@eg/share/combobox/combobox.component';
+
+/** Ingtegrated org unit and copy location selector */
+
+const PAD_SPACE = ' '; // U+2007
+
+@Component({
+ selector: 'eg-org-copy-loc-select',
+ templateUrl: 'eg-org-copy-loc-select.html',
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => OrgCopyLocSelectComponent),
+ multi: true
+ }
+ ]
+})
+export class OrgCopyLocSelectComponent implements AfterViewInit {
+
+ @Input() orgDisplayField = 'shortname';
+
+ @ViewChild('cbox', {static: false}) cbox: ComboboxComponent;
+
+ entries: ComboboxEntry[] = [];
+
+ propagateChange = (_: ComboboxEntry) => {};
+ propagateTouch = () => {};
+
+ constructor(
+ private org: OrgService,
+ private pcrud: PcrudService,
+ private auth: AuthService
+ ) {}
+
+ ngAfterViewInit() {
+ this.pcrud.search('acplg',
+ {owner: this.org.fullPath(this.auth.user().ws_ou(), true)},
+ {}, {atomic: true}
+ ).toPromise().then(groups => this.buildTree(groups));
+ }
+
+ buildTree(groups: IdlObject[], org?: IdlObject) {
+
+ if (!org) {
+ org = this.org.root();
+ this.entries = [];
+ }
+
+ const depth = org.ou_type().depth();
+
+ // Current org unit
+ this.entries.push({
+ id: 'org_' + org.id(),
+ label: this.formatLabel(org[this.orgDisplayField](), depth)
+ });
+
+ // Groups sorted above this org unit's children.
+ groups
+ .filter(grp => grp.owner() === org.id() && grp.top() === 't')
+ .sort((a, b) => a.pos() < b.pos() ? -1 : 1)
+ .forEach(grp => this.entries.push({
+ id: 'grp_' + grp.id(),
+ label: this.formatLabel(grp.name(), depth + 1)
+ }));
+
+ // Org unit children
+ org.children()
+ .sort((a, b) => a[this.orgDisplayField]() < b[this.orgDisplayField]() ? -1 : 1)
+ .forEach(org => this.buildTree(groups, org));
+
+ // Groups sorted below this org unit's children.
+ groups
+ .filter(grp => grp.owner() === org.id() && grp.top() === 'f')
+ .sort((a, b) => a.pos() < b.pos() ? -1 : 1)
+ .forEach(grp => this.entries.push({
+ id: 'grp_' + grp.id(),
+ label: this.formatLabel(grp.name(), depth + 1)
+ }));
+
+ if (org.id() === this.org.root().id()) {
+ // Pass the list of entries afters fully compiled.
+ this.cbox.entries = this.entries;
+ }
+ }
+
+ formatLabel(label: string, depth: number): string {
+ return PAD_SPACE.repeat(depth) + label;
+ }
+
+ cboxChange(entry: ComboboxEntry) {
+ this.propagateChange(entry);
+ }
+
+ writeValue(entry: ComboboxEntry) {
+ if (this.cbox) {
+ this.cbox.selectedId = entry ? entry.id : null;
+ }
+ }
+
+ registerOnChange(fn) {
+ this.propagateChange = fn;
+ }
+
+ registerOnTouched(fn) {
+ this.propagateTouch = fn;
+ }
+}
+
+