|
| 1 | +# Layout Editor Documentation |
| 2 | + |
| 3 | +This readme explains how the layout editor works and how to set up new room objects. |
| 4 | + |
| 5 | +You can access the view with this url within your main container |
| 6 | + |
| 7 | +`/cageui/WNPRC/EHR/layoutEditor.view` |
| 8 | + |
| 9 | +If you are running the dev server just edit it slightly. |
| 10 | + |
| 11 | +`/cageui/WNPRC/EHR/layoutEditorDev.view` |
| 12 | + |
| 13 | +In order to use this project, make sure to enable the module in your folder set up within labkey. |
| 14 | + |
| 15 | +This project was built for the Chrome browser. If you use a different browser, it may not work as expected. Additionally, |
| 16 | +the layout editor was not built for mobile devices. The idea behind this is that once the users build the rooms, they can |
| 17 | +be modified on mobile from different endpoints but the act of room creation is better done on desktop. |
| 18 | + |
| 19 | + |
| 20 | +# Workflow in detail |
| 21 | + |
| 22 | +## Context Manager |
| 23 | + |
| 24 | +The main layout editor entry point is `LayoutEditor.tsx`. This file loads in previous room data if required or simply starts |
| 25 | +a new room layout. When starting a new room layout, the user can select a room size from a list of predefined sizes. These sizes |
| 26 | +are present in the `constants.ts` file. Once a room is created with a certain size, this cannot be changed. |
| 27 | + |
| 28 | +The layout editor initializes with a context manager `LayoutEditorContextManager.tsx` with its types described in |
| 29 | +`layoutEditorContextTypes.ts`. This context manager serves as a place to store the room state and has functions |
| 30 | +for any edits that might occur to the room state. |
| 31 | + |
| 32 | +In the context manager (CM) there are two Room objects, **localRoom** and **room**, **room** serves as the initial room or |
| 33 | +previous room, and **localRoom** is the room that has changes applied to. This allows development to work with the previous room and |
| 34 | +the current room that has local changes applied to it. You can use **room** when saving to check for changes or apply previous room data |
| 35 | +to the **localRoom** that is being saved, **room** should not be modified at all during development. |
| 36 | + |
| 37 | +**unitLocs** is another important state within the CM. This state tracks cage positional data within the layout and |
| 38 | +serves it in an easy-to-access object. Its keys are rack types and the values contain the x and y global coords of the cage object. |
| 39 | +This state tracks the locations of the cages, by rack type. This is used within the editor to determine if two cages are |
| 40 | +adjacent to each other. Any action that changes the cage location in the editor should update this state with the |
| 41 | +new locations. Please note that the coordinates here are global coords. |
| 42 | + |
| 43 | +The last important state in the CM is **cageConnections** this state tracks which cages |
| 44 | +are connected/merged to other cages and is used within the CM when deleting cages to split cages into new groups. |
| 45 | +An example this is what happens when you have a row of three connected cages and delete the middle cage? The system will |
| 46 | +have to split up the remaining two cages on either side into new groups to handle this correctly. This is a complicated |
| 47 | +group of functions that hopefully shouldn't need to be updated as it should be working, but it's worth noting here. Additionally, |
| 48 | +it can be avoided by proper room creation or by deleting the entire group of cages/racks and rebuilding them if needed. |
| 49 | + |
| 50 | +### **Important** |
| 51 | + |
| 52 | +While the CM manages the state, this doesn't automatically handle the changes completely. There is a lot of DOM |
| 53 | +manipulation with adding new objects, merging cages, connecting racks, etc. These DOM changes cannot |
| 54 | +be performed within the CM and have to be done on the same file that the layout-grid SVG is served from. That is why the |
| 55 | +`Editor.tsx` file is very long. |
| 56 | + |
| 57 | +## Editor |
| 58 | + |
| 59 | +The `Editor.tsx` file is another important file here in the layout editor portion of the project. |
| 60 | +This file manages all the SVG DOM manipulation and changes that occur when adding and moving objects around the room. |
| 61 | +The file is also where the majority of the code is written for the layout editor. |
| 62 | +By pairing this file with the context manager and any used functions within the helper files you essentially have the |
| 63 | +entire layout editor. The editor file uses effects to track changes to the unitLocs state to determine if a merge or connect |
| 64 | +is requested, if the room should be reloaded with new changes to **localRoom** or when objects/cages are added to the layout. |
| 65 | +It uses D3.js and basic DOM functions to handle the dragging and placement of the objects within the editor. |
| 66 | + |
| 67 | +## Templates vs Real layouts |
| 68 | + |
| 69 | +The layout editor supports two styles of rooms, templates and real. While similar in building they differ on a couple |
| 70 | +fundamentals. Template rooms are created with the idea that they do not represent a real physcial location. They are merely |
| 71 | +a layout that will be loaded into the editor in the future for easier building by users. The major difference and key point |
| 72 | +here is that when a cage is dragged onto the layout it is considered to be a "default" of that cage type. "Defaults" do not |
| 73 | +represent real racks or cages and as such they cannot be saved in real rooms. So in order to save a room as a template, |
| 74 | +it's racks must all be a "default" type, otherwise it will throw an error. Likewise in order for a real room to be saved |
| 75 | +it cannot have any "default" types and the user must assign a real physical rack to that position. The system will not show |
| 76 | +racks that are already in other rooms preventing double assignment. |
| 77 | + |
| 78 | +## Editor Context Menu |
| 79 | + |
| 80 | +Every object that can be placed within the room has a context menu that the user can access via right-clicking. |
| 81 | +Room objects and cages have different menus, but they use the same component. Developers can add additional components to the |
| 82 | +context menu via the "menuItems" prop. Refer to the `CageUI Insturctions.html` file on what each current menu item will do. |
| 83 | + |
| 84 | +## Adding New Objects |
| 85 | + |
| 86 | +If you would like to add additional room objects or cage sizes that is also possible. Here is what you will have to do to |
| 87 | +make this possible. |
| 88 | + |
| 89 | +1. Create your SVG file within an editor, I used Adobe Illustrator for this and exported it as an SVG. Once you create this |
| 90 | +file that will be used as your object add it to `CageUI/resources/web/CageUI/static`. |
| 91 | + 1. If you encounter issues with loading the file after adding it here try going to `localhost:8080/cageui/static/{filename}.svg` |
| 92 | +to ensure that it works and is loaded in correctly. |
| 93 | +2. Add your object under the correct enum in `typings.ts`. |
| 94 | + 1. If your new object is a rack/cage type add it under RackTypes, create a default as well. |
| 95 | + 2. If your new object is a room object (ex. door) then add it under RoomObjectTypes. |
| 96 | + 3. Add your new object to ehr_lookups.cageui_item_types. Ensure your enum value and table values are matching. Additionally, |
| 97 | +if your item is a caging type, give it a size in the description field of the table. The size is the number of cells of the object both length and width. |
| 98 | +This is untested for caging types that aren't perfect squares. |
| 99 | +3. Next you should add your object into the `Editor.tsx` file via the **RoomItemTemplate** component. Look to others for examples. |
| 100 | + |
| 101 | +If done correctly, your new object should be available to be placed within the editor. |
| 102 | + |
| 103 | +## Important Notes |
| 104 | + |
| 105 | +Here are some additional things to keep in mind when using the layout editor. |
| 106 | + |
| 107 | +1. When cages are placed within the layout they are assigned a rack group, rack and then their cage number/id |
| 108 | +2. Users can merge two cages. When this is done, it moves the dragged cage into the target cages rack. |
| 109 | +3. Users can connect two cages. When this is done, it moves the dragged cage and rack into the target cages rack group. |
| 110 | +4. Merging and connecting is created with the idea that it lets users build racks and then connect racks, all from single cages. These |
| 111 | +changes are reflected within the DOM as well as the state. |
| 112 | + 1. To get a grasp on what goes on here, I would suggest inspecting the 'layout-grid' SVG within the DOM and using an |
| 113 | + effect to console log the localRoom state variable from the Editor.tsx file. |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | + |
| 118 | + |
| 119 | + |
| 120 | + |
| 121 | + |
| 122 | + |
| 123 | + |
| 124 | + |
0 commit comments