url="/eg/staff/admin/local/config/circ_matrix_matchpoint"></eg-link-table-link>
<eg-link-table-link i18n-label label="Closed Dates Editor"
url="/eg/staff/admin/local/actor/closed_dates"></eg-link-table-link>
+ <eg-link-table-link i18n-label label="Item Alert Types"
+ url="/eg/staff/admin/local/config/copy_alert_types"></eg-link-table-link>
+ <eg-link-table-link i18n-label label="Item Alert Suppression"
+ routerLink="/staff/admin/local/actor/copy_alert_suppress"></eg-link-table-link>
+ <eg-link-table-link i18n-label label="Item Tags"
+ routerLink="/staff/admin/local/asset/copy_tag"></eg-link-table-link>
<!-- do-able with a list of IDL classes to add to the edit dialog -->
<eg-link-table-link i18n-label label="Field Documentation"
url="/eg/staff/admin/local/config/idl_field_doc"></eg-link-table-link>
<eg-link-table-link i18n-label label="Shelving Location Groups"
url="/eg/staff/admin/local/asset/copy_location_group"></eg-link-table-link>
<eg-link-table-link i18n-label label="Shelving Location Order"
- url="/eg/staff/admin/local/asset/copy_location_order"></eg-link-table-link>
+ routerLink="/staff/admin/local/asset/shelving_location_order"></eg-link-table-link>
<eg-link-table-link i18n-label label="Shelving Locations Editor"
routerLink="/staff/admin/local/asset/copy_location"></eg-link-table-link>
<eg-link-table-link i18n-label label="Standing Penalties"
AdminLocalSplashComponent,
AddressAlertComponent,
AdminCarouselComponent,
- StandingPenaltyComponent
+ StandingPenaltyComponent,
],
imports: [
AdminCommonModule,
import {AdminCarouselComponent} from './admin-carousel.component';
import {StandingPenaltyComponent} from './standing-penalty.component';
-const routes: Routes = [{
+const routes: Routes = [ {
+ path: 'asset/shelving_location_order',
+ loadChildren: '@eg/staff/admin/local/shelving-location/shelving-location.module#ShelvingLocationModule'
+},{
path: 'splash',
component: AdminLocalSplashComponent
}, {
}, {
path: ':schema/:table',
component: BasicAdminPageComponent
-}];
+},
+
+];
@NgModule({
imports: [RouterModule.forChild(routes)],
--- /dev/null
+<div (mouseenter) = "onMouseEnter()" (mouseleave) = "onMouseLeave()"
+ [ngStyle] = "{display:'flex', flexDirection:'row'}">
+ <span *ngIf = "displaySelection()"
+ [ngStyle] = "divider_style" class = "material-icons">keyboard_arrow_right
+ </span>
+ <button class="btn btn-lg" (mousedown) = "onMouseDownEvent()"
+ (mouseup) = "onMouseUpEvent()" [style.fontSize.px] = "13" aria-grabbed="displaySelection()" #button>
+ {{index+1}}. <ng-content></ng-content>
+ </button>
+</div>
--- /dev/null
+import {Component, OnInit, Input,Output, EventEmitter, ViewChild, ElementRef} from '@angular/core';
+
+@Component({
+ selector:'card',
+ templateUrl: './card.component.html'
+})
+
+export class CardComponent implements OnInit {
+ @Input() content:any;
+ @Input() index:number;
+ @Input() content_length:number;
+ @Input() is_mouse_down:boolean;
+ @Input() index_for_card:number;
+ @Output() detectMouseUpEvents = new EventEmitter<any>();
+ @Output() detectMouseDownEvents = new EventEmitter<any>();
+ @ViewChild('button', { static: false }) button: ElementRef;
+ detect_drag = false;
+
+ card_style = {
+ display:"flex",
+ flexDirection:"column"
+ }
+
+ divider_style = {
+ marginTop:"4px",
+ width:"2px"
+ }
+
+ constructor() {
+ }
+
+ ngOnInit() {};
+
+ onMouseEnter() {
+ this.detect_drag = true;
+ this.button.nativeElement.focus()
+ }
+ onMouseLeave() {
+ this.detect_drag = false;
+ }
+
+ onMouseUpEvent() {
+ this.is_mouse_down = false;
+ this.detectMouseUpEvents.emit(this.index);
+ }
+
+ onMouseDownEvent() {
+ this.is_mouse_down = true;
+ this.detectMouseDownEvents.emit(this.index);
+ }
+
+ displaySelection() {
+ if ((this.is_mouse_down == true && this.detect_drag == true) || this.index_for_card == this.index) {
+ this.button.nativeElement.focus()
+ return true;
+ }
+ return false;
+ }
+}
--- /dev/null
+<div [ngStyle]="table_container" (keydown)="onKeyDown($event.key)">
+ <div [ngStyle]="card_container" (mouseleave)="onMouseLeave()" (mouseenter)="onMouseEnter()">
+ <ng-container *ngIf="mutable_content_list && mutable_content_list.length > 0">
+ <ul aria-dropeffect="move">
+ <div *ngFor="let content of mutable_content_list; let i = index">
+ <ng-container *ngIf="content">
+ <card [content]="content" [index]="i"
+ [content_length]="mutable_content_list.length"
+ [is_mouse_down]="is_mouse_down"
+ [index_for_card]="index_for_card"
+ (detectMouseDownEvents)="onMouseDown($event)"
+ (detectMouseUpEvents)="onMouseUp($event)"
+ >
+ {{content.name}} ({{content.shortname}})
+ </card>
+ </ng-container>
+ </div>
+ </ul>
+ </ng-container>
+ </div>
+</div>
\ No newline at end of file
--- /dev/null
+import {Component, OnInit, Input,Output,EventEmitter, SimpleChanges} from '@angular/core';
+
+/**
+ * Creates a class for the pairs.
+ */
+class Pair {
+ 1:number;
+ 2:number;
+}
+
+@Component({
+ selector:'sortable-list',
+ templateUrl: './sortable-list.component.html'
+})
+
+export class SortableListComponent implements OnInit {
+ @Input() content_list:any;
+ @Input() is_mouse_down = false;
+ @Input() is_submit_button_pressed = false;
+ @Output() saveContent = new EventEmitter<any>();
+ @Output() detectMousePosition = new EventEmitter<boolean>();
+ @Output() nodeIsSelected = new EventEmitter<any>();
+ @Output() toggleDragAndDrop = new EventEmitter<any>();
+ @Output() tableRender = new EventEmitter<any>();
+ @Output() toggleKeyboardSelection = new EventEmitter<boolean>();
+ @Output() haveDetectedChanges = new EventEmitter<void>();
+ detect_mouse_leave = false;
+ mutable_content_list:any;
+ mutable_content_dictionary = {};
+ card_pairs:Pair;
+ index_for_card:number;
+
+ /**
+ * The Following are style variables to style to tabs and cards in the html file.
+ */
+
+ table_container = {
+ display:"flex",
+ flexDirection:"row",
+ justifyContent:"flex-start"
+ }
+
+ card_container = {
+ display:"flex",
+ flexDirection:"column",
+ justifyContent:"center",
+ width:"300px",
+ marginRight:"10px"
+ }
+
+ button_style = {
+ margin:"auto",
+ }
+
+ constructor() {};
+
+ ngOnInit() {
+ this.onRender();
+ };
+
+ ngOnChanges(changes: SimpleChanges){
+ if (changes['is_submit_button_pressed'] && changes['is_submit_button_pressed'].currentValue){
+ this.applyChanges();
+ }
+ }
+
+ onRender(){
+ this.tableRender.emit();
+ this.card_pairs = new Pair();
+ this.mutable_content_dictionary = this.content_list;
+ //Retains immutability when saving string to another variable.
+ this.mutable_content_list = this.convertDictionaryToList(this.content_list).slice(0);
+ }
+
+ ngOnChange() {}
+
+ ngAfterViewInit() {}
+
+ applyChanges() {
+ this.saveContent.emit(this.mutable_content_list);
+ }
+
+ onKeyDown(keyType) {
+ if(this.card_pairs[1]) this.toggleKeyboardSelection.emit(true);
+ if(keyType == "Control") this.onCtrlDown();
+ if(keyType == "ArrowDown") this.onDownKeyDown();
+ if(keyType == "ArrowUp") this.onUpKeyDown();
+ if(keyType == "Enter") this.onEnterDown();
+ if(keyType == "Shift") this.onShiftDown();
+ }
+
+ onUpKeyDown() {
+ if(this.index_for_card == 0) {
+ this.index_for_card = this.mutable_content_list.length-1
+ } else {this.index_for_card--};
+ }
+
+ onDownKeyDown() {
+ if(!this.index_for_card) {
+ this.index_for_card = 0;
+ }
+ if(this.index_for_card == this.mutable_content_list.length-1) {
+ this.index_for_card = 0;
+ } else {this.index_for_card++};
+ }
+
+ onCtrlDown() {
+ this.index_for_card = 0;
+ }
+
+ onShiftDown() {
+ this.index_for_card = 0;
+ this.card_pairs = new Pair();
+ this.toggleKeyboardSelection.emit(false);
+ }
+
+ onEnterDown() {
+ if(this.card_pairs[1] == undefined && this.card_pairs[1] == null) {
+ this.card_pairs[1] = this.index_for_card;
+ this.nodeIsSelected.emit(this.mutable_content_list[this.index_for_card]);
+ this.toggleKeyboardSelection.emit(true);
+ } else {
+ this.card_pairs[2] = this.index_for_card;
+ if ((this.card_pairs[1] != this.card_pairs[2])
+ && this.card_pairs[2] != undefined && this.card_pairs[2] != null) {
+ this.toggleKeyboardSelection.emit(false);
+ this.haveDetectedChanges.emit();
+ this.reorderContentListFromCards(this.card_pairs, this.mutable_content_list);
+ }
+ }
+ }
+
+ onMouseLeave() {
+ this.toggleDragAndDrop.emit(false);
+ }
+
+ onMouseEnter() {
+ this.toggleDragAndDrop.emit(true);
+ }
+
+ onMouseDown(index) {
+ this.detect_mouse_leave = true;
+ this.is_mouse_down = true;
+ this.card_pairs[1] = index;
+ this.detectMousePosition.emit(true);
+ this.toggleKeyboardSelection.emit(false);
+ this.toggleDragAndDrop.emit(true);
+ this.nodeIsSelected.emit(this.mutable_content_list[index]);
+ this.index_for_card = index
+ }
+
+ onMouseUp(index) {
+ this.toggleDragAndDrop.emit(false);
+ this.detectMousePosition.emit(false);
+ if (this.card_pairs[1] != undefined && this.card_pairs[1] != null) {
+ this.card_pairs[2] = index;
+ this.is_mouse_down = false;
+ if ((this.card_pairs[1] != this.card_pairs[2])
+ && this.card_pairs[2] != undefined
+ && this.card_pairs[2] != null) {
+ this.haveDetectedChanges.emit()
+ this.reorderContentListFromCards(this.card_pairs, this.mutable_content_list);
+ }
+ } else {
+ this.is_mouse_down = false;
+ }
+ this.index_for_card = index
+ }
+
+ /**
+ * Converts a list into a dictionary to decrease the time complexity of multiple rearrangements.
+ * @param list The list that is to be converted
+ */
+ convertListToDictionary(list) {
+ var dictionary = {}
+ list.forEach(function (element, index) {
+ dictionary[index] = element;
+ });
+ this.mutable_content_dictionary = dictionary;
+ }
+
+ convertDictionaryToList(dictionary) {
+ var new_list = [];
+ for(var x = 0; x < Object.keys(dictionary).length; x++) {
+ if (dictionary[x]) new_list.push(dictionary[x]);
+ }
+ return new_list;
+ }
+
+ /**
+ * Reorders the content list using the pairs provided by the user.
+ * @param pairs The pairs provided by the user.
+ * @param list The List that is to be reordered.
+ */
+ reorderContentListFromCards(pairs, list) {
+ this.mutable_content_list =
+ this.convertDictionaryToList(this.reorderDictionary(this.mutable_content_dictionary, pairs));
+ this.card_pairs = new Pair();
+ }
+
+ reorderDictionary(dictionary, paired_values) {
+ var new_dictionary = new Object();
+ new_dictionary = Object.assign({...dictionary, [paired_values[2]]:dictionary[paired_values[1]]});
+ new_dictionary = this.alternateLoopWithHighestValueInPair(dictionary, new_dictionary, paired_values);
+ this.mutable_content_dictionary = Object.assign({...new_dictionary});
+ return this.mutable_content_dictionary;
+ }
+
+ alternateLoopWithHighestValueInPair(dictionary, new_dictionary, paired_values) {
+ if(paired_values[2] > paired_values[1]) {
+ for(var y = 0; y < paired_values[1]; y++) {
+ new_dictionary[y] = dictionary[y];
+ }
+ for(var z = paired_values[1]; z < paired_values[2]; z++) {
+ new_dictionary[z] = dictionary[z+1];
+ }
+
+ for(var x = Object.keys(dictionary).length-1; x > paired_values[2]; x--) {
+ new_dictionary[x] = dictionary[x];
+ }
+ } else {
+
+ for(var y = 0; y < paired_values[2]; y++) {
+ new_dictionary[y] = dictionary[y];
+ }
+
+ for(var z = paired_values[2]; z < paired_values[1]; z++) {
+ new_dictionary[z+1] = dictionary[z];
+ }
+
+ for(var x = Object.keys(dictionary).length-1; x > paired_values[1]; x--) {
+ new_dictionary[x] = dictionary[x];
+ }
+ }
+ return Object.assign({...new_dictionary});
+ }
+}
+
--- /dev/null
+<div (mouseup)="disableMouseUp()" (mouseleave)="disableMouseUp()" [style.height.vh]="100">
+ <eg-staff-banner bannerText="Shelving Location Order" i18n-bannerText>
+ </eg-staff-banner>
+ <div class="row mt-3">
+ <div class="col-md-3">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <div class="input-group-text" i18n>Context Org Unit</div>
+ <eg-org-select domId="acpl" [applyDefault]="true" (onChange)="setOrg($event)"></eg-org-select>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-3">
+ <button class="btn btn-lg btn-primary" (click)="is_submit_button_pressed = true" i18n>Apply Changes?</button>
+ </div>
+ </div>
+ <p>To move an item, drag it up or down with the mouse.</p>
+ <p>To use the keyboard selection, use the up and down arrow keys to select,
+ press control key to return to the top of the list,
+ press the shift key to reset the selection process.
+ </p>
+ <div>
+ <ng-container *ngIf="orders && locations && locations[0]">
+ <sortable-list
+ #sortableTable
+ [is_submit_button_pressed]="is_submit_button_pressed"
+ [content_list]="ordered_locations"
+ [is_mouse_down]="detect_mouse_down"
+ (saveContent)="applyChanges($event)"
+ (tableRender)="findLocation(locations)"
+ (toggleDragAndDrop)="toggleDragAndDrop($event)"
+ (nodeIsSelected)="displaySelectedNode($event)"
+ (detectMousePosition)="onMouseDown($event)"
+ (toggleKeyboardSelection)="toggleKeyboardSelection($event)"
+ (haveDetectedChanges)="haveDetectedChanges()">
+ </sortable-list>
+ </ng-container>
+ </div>
+ <div *ngIf="detect_mouse_down && detect_mouse"
+ [ngStyle]="position_styling"
+ [style.top.px]="mouse_y_position+25"
+ [style.left.px]="mouse_x_position-75">
+ {{selected_node.name}} ({{selected_node.shortname}})
+ </div>
+ <div *ngIf="toggle_keyboard_display"
+ [ngStyle]="keyboard_position_styling">
+ {{selected_node.name}} ({{selected_node.shortname}})
+ </div>
+</div>
\ No newline at end of file
--- /dev/null
+import { Component, HostListener, OnInit, ViewChild } from '@angular/core';
+import {SortableListComponent} from '../share/sortable-list.component';
+import { IdlService, IdlObject } from '@eg/core/idl.service';
+import { OrgService } from '@eg/core/org.service';
+import { PcrudService } from '@eg/core/pcrud.service';
+
+class Category {
+ name: string;
+ owning_lib: string;
+ shortname: string;
+ unhashed_location: any;
+ unhashed_order: any;
+ location: any;
+ position: any;
+}
+
+@Component({
+ templateUrl: './shelving-location-order.component.html'
+})
+
+export class ShelvingLocationOrderComponent implements OnInit {
+
+ @ViewChild('sortableTable', { static: false }) sortableTable: SortableListComponent;
+
+ contextOrg: IdlObject;
+ orders: any;
+ locations: any;
+ finding_orders = false;
+ ordered_locations = {};
+ complete_order_list = [];
+ id_log = [];
+ lib_tree = [];
+ active_libraries = [];
+ mouse_x_position: number;
+ mouse_y_position: number;
+ detect_mouse_down = false;
+ detect_mouse = false;
+ selected_node: any;
+ is_submit_button_pressed = false;
+ toggle_keyboard_display = false;
+ detectChanges: boolean;
+
+ /**
+ * Styles the little box that indicates something is selected.
+ */
+ position_styling = {
+ backgroundColor: "white",
+ boxShadow: "5px 4px 10px 2px #5B5A5A",
+ textAlign: "center",
+ padding: "3px",
+ width: '80px',
+ position: 'fixed',
+ }
+
+ keyboard_position_styling = {
+ backgroundColor: "white",
+ boxShadow: "5px 4px 10px 2px #5B5A5A",
+ textAlign: "center",
+ padding: "10px",
+ fontSize: "30px",
+ width: '200px',
+ top:'200px',
+ left:'300px',
+ position: 'fixed',
+ }
+
+ constructor(
+ private pcrud: PcrudService,
+ private idl: IdlService,
+ private org: OrgService,
+ ) {
+ }
+
+ ngOnInit() {//Use the root org unit to create a library tree
+ if (this.lib_tree.length == 0) {
+ this.createBranch(this.idl.toHash(this.org.root(), false));
+ }
+ }
+
+ checkObjectLength(object) {
+ return Object.keys(object).length;
+ }
+
+ detectMouseLeave() {
+ this.detect_mouse = false;
+ }
+
+ toggleDragAndDrop(toggle) {
+ this.detect_mouse = toggle;
+ }
+
+ disableMouseUp() {
+ this.detect_mouse_down = false;
+ }
+
+ onMouseDown(is_mouse_down) {
+ this.detect_mouse_down = is_mouse_down;
+ }
+
+ toggleKeyboardSelection(isDisplayed) {
+ this.toggle_keyboard_display = isDisplayed;
+ }
+
+ displaySelectedNode(node) {
+ this.selected_node = node;
+ }
+
+ /**
+ * Maps the values of the specified category to an array of objects, whose keys hold the necessary values.
+ */
+ mappingLocation() {
+ this.locations = {};
+ this.orders = {};
+ this.pcrud.search('acplo', {org : this.contextOrg.id()}, {order_by : {acplo : 'position'}})
+ .subscribe(element => {
+ var categ = new Category();
+ categ.unhashed_order = element;
+ this.orders[element.location()] = categ;
+ });
+ var location_index = 0;
+ this.pcrud.search('acpl', {owning_lib : this.id_log, deleted : 'f'}).subscribe(element => {
+ var categ = new Category();
+ var unhashed_element = element;
+ var hashed_element = this.idl.toHash(element, false);
+ var found_library = this.findLibrary(hashed_element.owning_lib)
+ categ.name = hashed_element.name;
+ categ.owning_lib = found_library.name;
+ categ.shortname = found_library.shortname;
+ categ.unhashed_location = unhashed_element;
+ this.locations[location_index] = categ;
+ location_index++;
+ });
+ }
+
+ /**
+ * Take the existing locations and orders them using the existing orders.
+ * If one doesn't exist, then append them to the end of the object
+ * @param locations The locations that are to be ordered.
+ */
+ findLocation(locations) {
+ var unordered_locations = [];
+ var greatest_order_position = 0;
+ for(var x = 0; x < Object.keys(locations).length; x++ ) {
+ var location_identification = this.orders[
+ locations[x].unhashed_location.id()
+ ];
+ if(!location_identification) {
+ //If there isn't an order for the location, then add to list of unordered locations.
+ unordered_locations.push((Object.assign({...locations[x]})));
+ }else {
+ var order_position = location_identification.unhashed_order.position();
+ if (this.ordered_locations[order_position - 1]) {
+ unordered_locations.push(Object.assign({...locations[x], ...location_identification}));
+ } else {
+ if(order_position > greatest_order_position) greatest_order_position = order_position; //Find the highest order position
+ this.ordered_locations[order_position - 1] = Object.assign({...locations[x], ...location_identification});
+ }
+ }
+ }
+ //After the ordered locations have been ordered, then add in the unordered ones.
+ unordered_locations.forEach((location, index) => {
+ this.ordered_locations[greatest_order_position + index] = location;
+ });
+ }
+
+ /**
+ * Finds the Library name, using the library id.
+ * @param lib_id The id that is to be used to find the name.
+ */
+ findLibrary(lib_id) {
+ var lib_name;
+ this.active_libraries.forEach(library => {
+ if (library.id == lib_id){
+ lib_name = {
+ name: library.name,
+ shortname: library.shortname,
+ };
+ }
+ });
+ return lib_name;
+ }
+
+ /**
+ * Starts from parent, logs id, looks for a specific key, checks to see if it has any children. If so
+ * rinse repeat.
+ * @param parent_node The uppermost parent node.
+ */
+ nodeTrailing(parent_node) {
+ this.findParent(parent_node);
+ }
+
+ /**
+ * Creates a tree of the different library branches
+ * @param node The parent node, of which, the branches 'branch out'
+ */
+ createBranch(node) {
+ this.lib_tree.push(node);
+ node.children.forEach(child => {
+ this.createBranch(child);
+ });
+ }
+
+ /**
+ * Checks if the node passed in has a parent node. If so, follow that branch, while saving the child nodes,
+ * until the root node is found.
+ * @param node The node that is to be checked for a parent.
+ */
+ findParent(node) {
+ this.id_log.push(node.id);
+ this.active_libraries.push(node);
+ var filteredTree = this.lib_tree.filter(branch => branch.ou_type.depth <= (node.ou_type.depth - 1)); //Creates a filtered branch
+ filteredTree.forEach(branch => {
+ if((branch.id == node.parent_ou) &&
+ this.isChild(branch.children, node)) {
+ this.findParent(branch);
+ }
+ });
+ }
+
+ /**
+ * Using the given parameters, checks if the 'node' passed is the parent of the 'children' parameter passed in.
+ * @param children The array of children nodes that is to be checked.
+ * @param node The assumed parent node.
+ */
+ isChild(children, node) {
+ var names_are_equal = false;
+ children.forEach(child => {
+ if (child.shortname == node.shortname){
+ names_are_equal= true;
+ }
+ });
+ return names_are_equal;
+ }
+
+
+ /**
+ * When the org unit changes, then wipe the id log, locations, and orders. Then retrieve new data
+ * @param object The new org unit
+ */
+ setOrg(org_unit) {
+ this.id_log = [];
+ this.locations = {};
+ this.orders = {};
+ this.ordered_locations = {};
+ this.contextOrg = org_unit;
+ this.nodeTrailing(this.idl.toHash(org_unit, false))
+ this.mappingLocation();
+ }
+
+ /**
+ * Creates Order if one doesn't yet exist.
+ * @param unfinished_order The order without an id.
+ * @param order_index The index of the unfinished order, used for the position.
+ */
+ createOrder(unfinished_order, order_index){
+ var new_order = this.idl.create('acplo');
+ new_order.id(unfinished_order.unhashed_order.id());
+ new_order.location(unfinished_order.unhashed_location.id());
+ new_order.org(this.contextOrg.id());
+ new_order.position(order_index + 1);
+ return this.pcrud.create(new_order);
+ }
+
+ buildOrder(unfinished_order, order_index) {
+ var new_order = this.idl.create('acplo');
+ if (unfinished_order.unhashed_order) {
+ new_order.id(unfinished_order.unhashed_order.id());
+ new_order.location(unfinished_order.unhashed_location.id());
+ new_order.org(this.contextOrg.id());
+ new_order.position(order_index + 1);
+ return this.pcrud.update(new_order);
+ } else {
+ return this.createOrder(unfinished_order, order_index);
+ }
+ }
+
+ haveDetectedChanges() {
+ this.detectChanges = true;
+ }
+
+ applyChanges(new_locations) {
+ this.detectChanges = false;
+ this.is_submit_button_pressed = false;
+ new_locations.forEach((location, index) => {
+ this.buildOrder(location,index).subscribe(order => {});
+ });
+ }
+
+ @HostListener('mousemove', ['$event'])
+ mouseMove($event: MouseEvent) {
+ this.mouse_y_position=$event.clientY;
+ this.mouse_x_position=$event.clientX;
+ }
+ @HostListener('window:beforeunload', ['$event'])
+ onWindowClose(event: any) {
+ if (this.detectChanges) {
+ return window.confirm("Are You Sure You Want To Leave Without Saving?")
+ }
+ return true;
+ };
+}
\ No newline at end of file
--- /dev/null
+import {NgModule} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {ShelvingLocationOrderComponent} from './shelving-location-order.component';
+
+const routes: Routes = [{
+ path: '',
+ component: ShelvingLocationOrderComponent
+}];
+
+@NgModule({
+ imports: [RouterModule.forChild(routes)],
+ exports: [RouterModule]
+})
+
+ export class ShelvingLocationRoutingModule {}
\ No newline at end of file
--- /dev/null
+import {NgModule} from '@angular/core';
+import {AdminCommonModule} from '@eg/staff/admin/common.module';
+import {TreeModule} from '@eg/share/tree/tree.module';
+import {ShelvingLocationRoutingModule} from './shelving-location-routing.module';
+import {ShelvingLocationOrderComponent} from './shelving-location-order.component';
+import {SortableListComponent} from '@eg/staff/admin/local/share/sortable-list.component';
+import {CardComponent} from '@eg/staff/admin/local/share/card.component';
+
+ @NgModule({
+ declarations: [
+ ShelvingLocationOrderComponent,
+ SortableListComponent,
+ CardComponent
+ ],
+ imports: [
+ AdminCommonModule,
+ ShelvingLocationRoutingModule,
+ TreeModule
+ ],
+ exports: [
+ ],
+ providers: []
+ })
+ export class ShelvingLocationModule {}
\ No newline at end of file