import {AddressAlertComponent} from './address-alert.component';
import {AdminCarouselComponent} from './admin-carousel.component';
import {StandingPenaltyComponent} from './standing-penalty.component';
+import {CopyLocationOrderComponent} from './copy-location-order.component';
+import {TableListComponent} from './share/table-list.component';
+import {CardComponent} from './share/card.component';
@NgModule({
declarations: [
AdminLocalSplashComponent,
AddressAlertComponent,
AdminCarouselComponent,
- StandingPenaltyComponent
+ StandingPenaltyComponent,
+ CopyLocationOrderComponent,
+ TableListComponent,
+ CardComponent
],
imports: [
AdminCommonModule,
--- /dev/null
+<div (mouseup)="disableMouseUp()" (mouseleave)="disableMouseUp()" [style.height.vh]="100">\r
+ <eg-staff-banner bannerText="Shelving Location Order" i18n-bannerText>\r
+ </eg-staff-banner>\r
+ <div>\r
+ <h3>Context Org Unit</h3>\r
+ <div [style.width.%]="30">\r
+ <eg-org-select domId="acpl" [applyDefault]="true" (onChange)="onChange($event)"></eg-org-select> \r
+ </div>\r
+ </div> \r
+ <p>To move an item, drag it up or down with the mouse.</p>\r
+ <ng-container *ngIf="locations && locations.length>0">\r
+ <table-list \r
+ [content_list]="locations" \r
+ [is_mouse_down]="detect_mouse_down"\r
+ (saveContent)="applyChanges($event)"\r
+ (toggleDragAndDrop)="toggleDragAndDrop($event)" \r
+ (nodeIsSelected)="displaySelectedNode($event)" (detectMousePosition)="onMouseDown($event)"></table-list>\r
+ </ng-container>\r
+ <div *ngIf="detect_mouse_down && detect_mouse"\r
+ [ngStyle]="position_styling" \r
+ [style.top.px]="mouse_y_position+25" \r
+ [style.left.px]="mouse_x_position-75" >{{selected_node.name}} ({{selected_node.shortname}})</div>\r
+</div>
\ No newline at end of file
--- /dev/null
+import {Component, OnInit, HostListener} from '@angular/core';\r
+import {PcrudService} from '@eg/core/pcrud.service';\r
+import {AuthService} from '@eg/core/auth.service';\r
+import {ToastService} from '@eg/share/toast/toast.service';\r
+import { IdlService } from '@eg/core/idl.service';\r
+\r
+\r
+\r
+class Category {\r
+ name:string;\r
+ owning_lib:string;\r
+ shortname:string;\r
+ unhashed_element:any;\r
+}\r
+\r
+@Component({\r
+ templateUrl: './copy-location-order.component.html'\r
+})\r
+\r
+export class CopyLocationOrderComponent implements OnInit {\r
+ orders:any;\r
+ locations:any;\r
+ id_log=[];\r
+ lib_tree=[];\r
+ active_libraries=[];\r
+ mouse_x_position:number; \r
+ mouse_y_position:number;\r
+ detect_mouse_down=false;\r
+ detect_mouse = false;\r
+ selected_node:any;\r
+\r
+ position_styling={\r
+ backgroundColor:"white",\r
+ boxShadow:"5px 4px 10px 2px #5B5A5A",\r
+ textAlign:"center",\r
+ padding:"3px",\r
+ width:'80px',\r
+ position:'fixed',\r
+ }\r
+\r
+ constructor(\r
+ private pcrud: PcrudService,\r
+ private idl: IdlService,\r
+ private toast: ToastService, \r
+ private auth: AuthService,\r
+ ) {\r
+ }\r
+\r
+ ngOnInit() {\r
+ //this.createTree(); \r
+ //this.filterGrid(this.auth.user().ws_ou());\r
+ };\r
+\r
+ detectMouseLeave(){\r
+ this.detect_mouse=false;\r
+ }\r
+\r
+ toggleDragAndDrop(toggle){\r
+\r
+ this.detect_mouse=toggle;\r
+ }\r
+\r
+ disableMouseUp(){ \r
+ this.detect_mouse_down=false;\r
+ }\r
+ onMouseDown(is_mouse_down){\r
+ this.detect_mouse_down=is_mouse_down;\r
+ }\r
+ \r
+\r
+ displaySelectedNode(node){\r
+ this.selected_node=node;\r
+ }\r
+\r
+ /**\r
+ * Initializes the search for the library tree and the array of the library locations.\r
+ * @param org The authorized user passed in during initialization.\r
+ */\r
+ filterGrid(org) {\r
+ // fetch the locations and order entries\r
+ if(!this.orders) {\r
+ this.pcrud.search('acplo', {org : org}, {order_by : {acplo : 'position'}})\r
+ .subscribe(elements => console.log("Order",elements));\r
+ this.mappingLocation();\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Maps the values of the specified category to an array of objects, whose keys hold the necessary values.\r
+ */\r
+ mappingLocation(){ \r
+ this.locations=[];\r
+ this.pcrud.search('acpl',\r
+ {owning_lib:this.id_log, deleted : 'f'}\r
+ ).subscribe(element => {\r
+ var categ = new Category();\r
+ var unhashed_element=element;\r
+ var hashed_element = this.idl.toHash(element, false);\r
+ var found_library = this.findLibrary(hashed_element.owning_lib)\r
+ categ.name=hashed_element.name;\r
+ categ.owning_lib= found_library.name;\r
+ categ.shortname=found_library.shortname;\r
+ categ.unhashed_element=unhashed_element;\r
+ this.locations.push(categ);\r
+ });\r
+ this.id_log=[];\r
+ }\r
+\r
+ /**\r
+ * Finds the Library name, using the library id.\r
+ * @param lib_id The id that is to be used to find the name.\r
+ */\r
+ findLibrary(lib_id){\r
+ var lib_name;\r
+ this.active_libraries.forEach(library=>{\r
+ if(library.id==lib_id){\r
+ lib_name= {\r
+ name:library.name,\r
+ shortname:library.shortname\r
+ };\r
+ }\r
+ })\r
+ return lib_name;\r
+ }\r
+\r
+ /**\r
+ * Starts from parent, logs id, looks for a specific key, checks to see if it has any children. If so\r
+ * rinse repeat.\r
+ * @param parent_node The uppermost parent node. \r
+ */\r
+ nodeTrailing(parent_node){\r
+ this.findParent(parent_node);\r
+ }\r
+\r
+ /**\r
+ * Creates a tree of the different library branches\r
+ * @param node The parent node, of which, the branches 'branch out'\r
+ */\r
+ createBranch(node){\r
+ this.lib_tree.push(node);\r
+ node.children.forEach(child => {\r
+ this.createBranch(child);\r
+ });\r
+ }\r
+\r
+ /**\r
+ * Checks if the node passed in has a parent node. If so, follow that branch, while saving the child nodes,\r
+ * until the root node is found.\r
+ * @param node The node that is to be checked for a parent.\r
+ */\r
+ findParent(node){\r
+ this.id_log.push(node.id);\r
+ this.active_libraries.push(node);\r
+ var filteredTree= this.lib_tree.filter(branch=> branch.ou_type.depth<=(node.ou_type.depth-1)); //Creates a filtered branch\r
+ filteredTree.forEach(branch =>{\r
+ if\r
+ (\r
+ ( branch.id==node.parent_ou)\r
+ && this.isChild(branch.children, node)\r
+ )\r
+ {\r
+ this.findParent(branch);\r
+ }\r
+ })\r
+ }\r
+\r
+ /**\r
+ * Using the given parameters, checks if the 'node' passed is the parent of the 'children' parameter passed in.\r
+ * @param children The array of children nodes that is to be checked.\r
+ * @param node The assumed parent node.\r
+ */\r
+ isChild(children, node){\r
+ var names_are_equal = false;\r
+ children.forEach(child => {\r
+ if(child.shortname==node.shortname){\r
+ names_are_equal= true;\r
+ } \r
+ })\r
+ return names_are_equal;\r
+ }\r
+\r
+ onChange(object){\r
+ if(this.lib_tree.length==0){\r
+ this.createBranch(this.idl.toHash(object, false));\r
+ }\r
+ this.nodeTrailing(this.idl.toHash(object, false))\r
+ this.mappingLocation();\r
+ }\r
+\r
+ applyChanges(new_locations){\r
+ var library_locations=[];\r
+ new_locations.forEach(element => {\r
+ library_locations.push(element.unhashed_element) \r
+ });\r
+ var library =this.pcrud.update(library_locations); \r
+ \r
+ console.log(library.subscribe(object=> console.log(object))) \r
+ }\r
+ \r
+ @HostListener('mousemove', ['$event'])\r
+ mouseMove($event: MouseEvent) {\r
+ this.mouse_y_position=$event.clientY;\r
+ this.mouse_x_position=$event.clientX;\r
+ }\r
+\r
+\r
+}\r
+\r
import {AddressAlertComponent} from './address-alert.component';
import {AdminCarouselComponent} from './admin-carousel.component';
import {StandingPenaltyComponent} from './standing-penalty.component';
+import {CopyLocationOrderComponent} from './copy-location-order.component';
const routes: Routes = [{
path: 'splash',
path: 'config/standing_penalty',
component: StandingPenaltyComponent
}, {
+ path: 'asset/copy_location_order',
+ component: CopyLocationOrderComponent
+}, {
path: ':schema/:table',
component: BasicAdminPageComponent
-}];
+}
+
+];
@NgModule({
imports: [RouterModule.forChild(routes)],
--- /dev/null
+\r
+\r
+<div \r
+(mouseenter)="onMouseEnter()" \r
+(mouseleave)="onMouseLeave()"\r
+[ngStyle]="{display:'flex', flexDirection:'row'}">\r
+ <span *ngIf="is_mouse_down==true && detect_drag==true"\r
+ [ngStyle]="divider_style" class="material-icons">keyboard_arrow_right</span>\r
+ <button class="btn btn-lg"\r
+ (mousedown)="onMouseDownEvent()" \r
+ (mouseup)="onMouseUpEvent()" \r
+ [style.fontSize.px]="10"\r
+ >{{index+1}}. <ng-content></ng-content></button>\r
+</div>\r
--- /dev/null
+\r
+import {Component, OnInit, Input,Output, EventEmitter, ViewChild} from '@angular/core';\r
+\r
+@Component({\r
+ selector:'card',\r
+ templateUrl: './card.component.html'\r
+})\r
+\r
+export class CardComponent implements OnInit {\r
+ @Input() content:any;\r
+ @Input() index:number;\r
+ @Input() content_length:number;\r
+ @Output() detectMouseUpEvents= new EventEmitter<any>();\r
+ @Output() detectMouseDownEvents= new EventEmitter<any>();\r
+ detect_drag=false;\r
+ @Input() is_mouse_down:boolean;\r
+\r
+ card_style={\r
+ display:"flex",\r
+ flexDirection:"column"\r
+ }\r
+\r
+ divider_style={\r
+ marginTop:"4px",\r
+ width:"2px"\r
+ }\r
+\r
+ constructor() {\r
+ }\r
+ \r
+\r
+ ngOnInit() {};\r
+\r
+ onMouseEnter(){\r
+ this.detect_drag=true;\r
+ }\r
+ onMouseLeave(){\r
+ this.detect_drag=false;\r
+ }\r
+\r
+ onMouseUpEvent(){\r
+ this.is_mouse_down=false;\r
+ this.detectMouseUpEvents.emit(this.index)\r
+ }\r
+ \r
+ onMouseDownEvent(){\r
+ this.is_mouse_down=true;\r
+ this.detectMouseDownEvents.emit(this.index);\r
+ }\r
+}\r
--- /dev/null
+\r
+\r
+<div [ngStyle]="table_container">\r
+ <div [ngStyle]="card_container" (mouseleave)="onMouseLeave()" (mouseenter)="onMouseEnter()"> \r
+ <button class="btn btn-lg" (click)="applyChanges()" [ngStyle]="button_style">Apply Changes?</button>\r
+ <div *ngFor="let content of mutable_content_list; let i = index">\r
+ <card \r
+ [content]="content" [index]="i"\r
+ [content_length]="mutable_content_list.length"\r
+ [is_mouse_down]="is_mouse_down"\r
+ (detectMouseDownEvents)="onMouseDown($event)" \r
+ (detectMouseUpEvents)="onMouseUp($event)" >{{content.name}} ({{content.shortname}})</card>\r
+ </div>\r
+ </div>\r
+ <div>\r
+ </div>\r
+</div>\r
--- /dev/null
+\r
+import {Component, OnInit, Input,Output,EventEmitter} from '@angular/core';\r
+\r
+/**\r
+ * Creates a class for the pairs.\r
+ */\r
+class Pair {\r
+ 1:number;\r
+ 2:number;\r
+}\r
+\r
+@Component({\r
+ selector:'table-list',\r
+ templateUrl: './table-list.component.html'\r
+})\r
+\r
+export class TableListComponent implements OnInit {\r
+ @Input() content_list:any;\r
+ @Output() saveContent= new EventEmitter<any>();\r
+ @Output() detectMousePosition = new EventEmitter<boolean>();\r
+ @Output() nodeIsSelected = new EventEmitter<any>();\r
+ @Output() toggleDragAndDrop = new EventEmitter<any>();\r
+ @Input() is_mouse_down=false;\r
+ detect_mouse_leave=false;\r
+ mutable_content_list:any;\r
+ mutable_content_dictionary={};\r
+ card_pairs:Pair;\r
+\r
+ /**\r
+ * The Following are style variables to style to tabs and cards in the html file.\r
+ */\r
+\r
+ table_container={\r
+ display:"flex",\r
+ flexDirection:"row",\r
+ justifyContent:"flex-start"\r
+ }\r
+ \r
+ card_container={ \r
+ display:"flex",\r
+ flexDirection:"column",\r
+ justifyContent:"center",\r
+ width:"300px",\r
+ marginRight:"10px"\r
+ }\r
+\r
+ button_style={\r
+ margin:"auto"\r
+ }\r
+\r
+ constructor() {\r
+ };\r
+\r
+ ngOnInit() {\r
+ this.card_pairs= new Pair(); \r
+ this.convertListToDictionary(this.content_list);\r
+ this.mutable_content_list= this.content_list.slice(0, this.content_list.length);//Retains immutability when saving string to another variable.\r
+ \r
+ };\r
+\r
+ ngAfterViewInit(){\r
+ }\r
+ applyChanges(){\r
+ this.saveContent.emit(this.mutable_content_list);\r
+ }\r
+\r
+ onMouseLeave(){\r
+ //this.is_mouse_down=false; \r
+ this.toggleDragAndDrop.emit(false);\r
+\r
+ }\r
+ onMouseEnter(){\r
+ this.toggleDragAndDrop.emit(true);\r
+ }\r
+\r
+ onMouseDown(index){ \r
+ this.detect_mouse_leave=true; \r
+ this.is_mouse_down=true;\r
+ this.card_pairs[1]=index;\r
+ this.detectMousePosition.emit(true);\r
+ this.toggleDragAndDrop.emit(true);\r
+ this.nodeIsSelected.emit(this.mutable_content_list[index]);\r
+ }\r
+ onMouseUp(index){\r
+ this.toggleDragAndDrop.emit(false);\r
+ this.detectMousePosition.emit(false);\r
+ if(this.card_pairs[1]!=undefined && this.card_pairs[1]!=null){ //Checks if the tab pair is a number\r
+ this.card_pairs[2]=index; \r
+ this.is_mouse_down=false;\r
+ if((this.card_pairs[1]!= this.card_pairs[2]) && this.card_pairs[2]!=undefined && this.card_pairs[2]!=null){ //Checks if the tab pair is a number\r
+ this.reorderContentListFromCards(this.card_pairs, this.mutable_content_list);\r
+ } \r
+ }else{ \r
+ this.is_mouse_down=false;\r
+ } \r
+ } \r
+\r
+ /**\r
+ * Converts a list into a dictionary to decrease the time complexity of multiple rearrangements.\r
+ * @param list The list that is to be converted\r
+ */\r
+ convertListToDictionary(list){\r
+ var dictionary ={}\r
+ list.forEach(function (element, index) {\r
+ dictionary[index]=element;\r
+ });\r
+ this.mutable_content_dictionary=dictionary;\r
+ }\r
+\r
+ \r
+ convertDictionaryToList(dictionary){\r
+ var new_list=[];\r
+ for(var x =0; x<Object.keys(dictionary).length;x++){\r
+ new_list.push(dictionary[x]);\r
+ }\r
+ return new_list;\r
+ }\r
+\r
+\r
+ /**\r
+ * Reorders the content list using the pairs provided by the user.\r
+ * @param pairs The pairs provided by the user.\r
+ * @param list The List that is to be reordered.\r
+ */\r
+ reorderContentListFromCards(pairs, list){\r
+ // var new_content_list = list.slice(0,list.length);\r
+ // new_content_list.splice(pairs[1],1);//Rearrange the element into the selected place.\r
+ // new_content_list.splice(pairs[2], 0, list[pairs[1]]); \r
+ // this.mutable_content_list=new_content_list;\r
+ this.mutable_content_list=this.convertDictionaryToList(\r
+ this.reorderDictionary(this.mutable_content_dictionary, pairs)\r
+ ); \r
+ this.card_pairs=new Pair();//Reset the pairs\r
+ }\r
+\r
+ reorderDictionary(dictionary, paired_values){\r
+ var new_dictionary = new Object();\r
+ new_dictionary=Object.assign({...dictionary, [paired_values[2]]:dictionary[paired_values[1]]}); \r
+ new_dictionary=this.alternateLoopWithHighestValueInPair(dictionary, new_dictionary, paired_values); \r
+ this.mutable_content_dictionary= Object.assign({...new_dictionary});\r
+ return this.mutable_content_dictionary;\r
+ }\r
+\r
+ alternateLoopWithHighestValueInPair(dictionary, new_dictionary, paired_values){ \r
+ if(paired_values[2]>paired_values[1]){ \r
+ \r
+ for(var y=0; y<paired_values[1]; y++){\r
+ new_dictionary[y]=dictionary[y];\r
+ } \r
+ for(var z=paired_values[1]; z<paired_values[2]; z++){\r
+ new_dictionary[z]=dictionary[z+1];\r
+ } \r
+ \r
+ for(var x = Object.keys(dictionary).length-1; x > paired_values[2]; x--){\r
+ new_dictionary[x]=dictionary[x];\r
+ }\r
+ }else{\r
+ \r
+ for(var y=0; y<paired_values[2]; y++){\r
+ new_dictionary[y]=dictionary[y];\r
+ } \r
+\r
+ for(var z=paired_values[2]; z<paired_values[1]; z++){\r
+ new_dictionary[z+1]=dictionary[z];\r
+ } \r
+ \r
+ for(var x = Object.keys(dictionary).length-1; x > paired_values[1]; x--){\r
+ new_dictionary[x]=dictionary[x];\r
+ }\r
+ } \r
+ return Object.assign({...new_dictionary});\r
+ }\r
+}\r
+\r