GithubHelp home page GithubHelp logo

aldaviva / floorplan Goto Github PK

View Code? Open in Web Editor NEW
166.0 166.0 58.0 1.86 MB

🗺️ Floorplan, seating chart, and employee directory for Blue Jeans.

Makefile 0.05% JavaScript 77.12% CSS 14.94% HTML 7.85% Shell 0.03%
directory employee-directory floorplan map seating-chart

floorplan's Introduction

Floorplan

Where do people sit in the offices of Blue Jeans Network? What's that person's name, whose face I remember but never really met? I've heard of this person, but I don't know their face. Where are the different teams grouped? What is A2's email address?

Floorplan view

Floorplan

Administrative view

Floorplan Admin

Buzzwords

  • Backbone
  • Express
  • GraphicsMagick
  • Handlebars
  • jQuery
  • LESS
  • Mongo
  • Node
  • Q
  • SVG

Prerequisites

Install

  1. Clone the GitHub repository

     git clone https://github.com/Aldaviva/floorplan.git
     cd floorplan
    
  2. Install dependencies

     make install-deps
    

    This installs Graphicsmagick and several NPM modules.

  3. Set permissions so the server can write to the directories where CSS stylesheets and people's photos are saved

     chmod +rwx public/styles data/photos
    
  4. Create a configuration file based on the example

     cp config.example.json config.json
    
  5. You may edit the configuration file and change any settings you want, although the server will run with the default settings.

    • wwwPort is the TCP port on which the Floorplan HTTP server listens. Useful if you want the server to listen on a different port, like 80 or 8080. With the default value of 3000, you can access the Floorplan web interface by going to http://127.0.0.1:3000/.

    • dbHost is the host on which the MongoDB server runs. Useful if you have a MongoDB server on a different computer. With the default value of "127.0.0.1", the MongoDB server is on the same computer as Floorplan.

    • dbPort is the TCP port on which the MongoDB server listens. Useful if you have a non-default MongoDB configuration. With the default value of 27017, Floorplan will connect to a MongoDB server with a default configuration.

    • dbName is the name of the MongoDB database that will be used to store people added to Floorplan. Useful if you want to run multiple different Floorplan instances on the same MongoDB server. With the default value of "floorplan", people documents will be stored in the people collection of the floorplan database in your MongoDB server.

      If you want to connect to the database yourself, you can run

        mongo floorplan
        > db.people.find()
      
    • mountPoint is the HTTP path under which the Floorplan web interface will be served. Useful if you want to reverse-proxy the Floorplan server through another HTTP server like Apache or Nginx due to TLS or a desire to serve multiple services on port 80. With the default value of "/", you can access the Floorplan web interface by going to http://127.0.0.1:3000/, but if you changed mountPoint to /floorplan, you would have to go to http://127.0.0.1:3000/floorplan.

Run

node index.js

Use Ctrl+C to stop.

Usage

Viewing the Floorplan

Go to http://127.0.0.1:3000 in your web browser. You should see a blue page that says "MV" in the top left.

Adding people

Go to http://127.0.0.1:3000/admin/` in your web browser. You should see a white page that says "add person" in the top left.

Fill in the person's full name and any other details you want to set, then click the blue Save button.

Now when you view the Floorplan, the new person should appear in the list to the left and, if you assigned an office and seat, their photo will appear in their seating position.

Adding offices

  1. Go to the views/maps directory.
  2. Copy or edit the SVG files here.
  3. Restart the server for your changes to take effect.
  • The SVG files define
    • the dimensions of the office using the /svg/@viewBox attribute (minX, minY, width, height). (0,0) is the top-left corner of the SVG canvas.
    • the size and positions of the seats (minX, minY) using the JavaScript <script> elemnent to define this.SEATS.mv.iconSize and this.SEATS.mv.seatPositions. If you change the name of the office from "mv", make sure you change it here too.
    • the polygon.background element is the shape of the office footprint, which turns white in the Admin UI's seat choosing interface so the page isn't visible through the walls.
    • the g.walls and child g.innerWalls groups are the shapes that define where the walls of the office are, with differing styles
    • the g.roomNames group shows text on the Floorplan. Multiline text uses tspan elements for positioning. g.room groups optionally shows detailed conference room information, some of which (endpoint:id, .statusBadge) rely on external systems to work.
    • g.seats and g.photos are always empty, and will be populated by the client-side presentation layer to show where people sit.
    • .arrow links in some maps are used to navigate between offices that are spatially local to each other.
  • Map styles are set in public/styles/Map.less, including the way walls and text are rendered.
  • The street address and optional Yelp review link are defined in public/scripts/IntroView.js.
  • The office changer links in the top left are defined in public/scripts/ListPane.js.
    • The total number of offices is defined in public/styles/definitions.less.
    • The number of columns for the office changer links is defined in public/styles/ListPane.less.
  • The Admin UI office chooser is defined in views/admin.hbs.

I find that the easiest way to generate the SVG files is to

  1. Copy an existing SVG file

  2. Open the SVG in Adobe Illustrator to set the walls and seating positions visually. The seats can just be squares for now. Room areas can be any shapes you want.

  3. Export the SVG from Illustrator without overwriting my SVG using the View Code button

  4. Set the viewBox attribute value's top left position, width, and height to be the same as the Illustrator artboard.

  5. Copy the g.walls and g.innerWalls groups into my SVG

  6. Copy the rect elements you made for the seating positions into a text editor, preferrably one with column editing like Sublime Text, and convert their x and y attributes into a JavaScript array of [x, y] pairs:

    Temporary SVG code generated by Illustrator for seat rectangles

     <g class="seats">
         <rect width="20" height="20" x="146.363" y="927.371" />
         <rect width="20" height="20" x="847.134" y="813.174" />
     </g>
    

    JavaScript seats object array

     this.SEATS.mv = {
         iconSize: 20,
         seatPositions: [
             [146.363, 927.371],
             [847.134, 813.174]
         ]
     };
    
  7. Set the g.room .roomArea to be the room area shapes you made.

  8. Change the g.roomNames text, restart the server, and line up the text coordinates using your browser's Developer Tools for fine positioning.

floorplan's People

Contributors

aldaviva avatar hkarakose avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

floorplan's Issues

Log to disk

As an HR administrator, I would like to be able to review the logs to see details of changes, so I can tell when an unexpected change happened.

Setting up Floorplan

Hello,

I've installed Node, NPM and MongoDB on my Linux Ubuntu 16.04 Server. But when I run $ node index.js I get the following error:

floorplan@floorplan:~/floorplan$ node index.js
Listening on http://*:3000
/home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/connection/server.js:481
throw err;
^

TypeError: callback is not a function
at Server.Base._callHandler (/home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/connection/base.js:378:7)
at /home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/connection/server.js:468:18
at exports.MongoReply.MongoReply.parseBody (/home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:137:5)
at exports.ConnectionPool. (/home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/connection/server.js:426:20)
at emitOne (events.js:115:13)
at exports.ConnectionPool.emit (events.js:210:7)
at exports.Connection. (/home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:191:13)
at emitTwo (events.js:125:13)
at exports.Connection.emit (events.js:213:7)
at Socket. (/home/floorplan/floorplan/node_modules/mongodb/lib/mongodb/connection/connection.js:384:22)

Dumb question but Step 5: mentions the dbName of floorplan, is that assumed that the database was created prior to running $ node index.js ?

Thanks and sorry about the trouble.

When sending employee recognition, remember sender name

As someone submitting employee recognition for not-the-first-time, I want the site to remember the name I used previously, so I don't have to keep typing my name (which never changes) over and over again.

The user should be given their previously-used name as the default filled-in value for the fromName <input>. They can still change it by typing over the default value.

Hotkey / to focus search box

As a Luke, I would like to have the "/" key bring my cursor focus to the search input box on floorplan so that I can stop doing that and wondering for half a second why the world has not shaped itself to my will.

Allow admin to nullify desk of person

As an administrator, I want to be able to remove the association between a person and the desk they were sitting at without having to specify a new desk, so that when someone takes their desk I can update the floorplan without finding out where they went or outright deleting them.

Attempting to modernize & deploy the app

Hey @Aldaviva & all. Where I'm currently working (a VFX shop), the boss was looking for a good floor plan solution. We came across this, and it seemed to be really promising. However, it looks like the code base is a few years old: deploying it on an updated Node+Mongo combination, doesn't seem to be that straight-forward. I'm not a Node.js guy, but I am a "jack of all trades", so figured it would be interesting to see what would happen in trying to get this app modernized (also grateful to said boss for letting me try). Think it's mostly there: followed most of the porting advice I could find for going to Express 4; applied StandardJS formatting; tried to update the MongoDB handler; implemented logging & custom directories.... It's still not fully there though. Can you all take a look please?

https://github.com/unquietwiki/floorplan

How to Install

Hey i need some help. I was able to clone it install the db service and but run into problems with the config.json file
When installing from the npm i run into a bunch of errors:
npm ERR! not a package /home/user/floorplan/config.json
npm ERR! addLocal Could not install /home/user/floorplan/config.json

The debug file looks like this:
0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/nodejs', '/usr/bin/npm', 'install', 'package.json' ]
2 info using [email protected]
3 info using [email protected]
4 silly loadCurrentTree Starting
5 silly install loadCurrentTree
6 silly install readLocalPackageData
7 silly fetchPackageMetaData package.json
8 silly fetchOtherPackageData package.json
9 silly cache add args [ 'package.json', null ]
10 verbose cache add spec package.json
11 silly cache add parsed spec Result {
11 silly cache add raw: 'package.json',
11 silly cache add scope: null,
11 silly cache add name: null,
11 silly cache add rawSpec: 'package.json',
11 silly cache add spec: '/home/user/floorplan/package.json',
11 silly cache add type: 'local' }
12 silly addLocalTarball shasum (computed) 6844bb9c3c02dd21de6d2a3cde0c99b21f36c751
13 verbose addTmpTarball /home/user/floorplan/package.json not in flight; adding
14 verbose addTmpTarball validating metadata from /home/user/floorplan/package.json
15 verbose tar unpack /home/user
/floorplan/package.json
16 verbose tar unpacking to /tmp/npm-11586-fde7ba94/unpack-51a0e890
17 silly gentlyRm /tmp/npm-11586-fde7ba94/unpack-51a0e890 is being purged
18 verbose gentlyRm don't care about contents; nuking /tmp/npm-11586-fde7ba94/unpack-51a0e890
19 silly gunzTarPerm modes [ '775', '664' ]
20 error not a package /home/bradycarmody/floorplan/package.json
21 error addLocal Could not install /home/bradycarmody/floorplan/package.json
22 silly fetchPackageMetaData Error: ENOENT: no such file or directory, open '/tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json'
22 silly fetchPackageMetaData at Error (native)
22 silly fetchPackageMetaData error for package.json { [Error: ENOENT: no such file or directory, open '/tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json']
22 silly fetchPackageMetaData errno: -2,
22 silly fetchPackageMetaData code: 'ENOENT',
22 silly fetchPackageMetaData syscall: 'open',
22 silly fetchPackageMetaData path: '/tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json' }
23 silly rollbackFailedOptional Starting
24 silly rollbackFailedOptional Finishing
25 silly runTopLevelLifecycles Starting
26 silly runTopLevelLifecycles Finishing
27 silly install printInstalled
28 verbose stack Error: ENOENT: no such file or directory, open '/tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json'
28 verbose stack at Error (native)
29 verbose cwd /home/user/floorplan
30 error Linux 4.4.0-62-generic
31 error argv "/usr/bin/nodejs" "/usr/bin/npm" "install" "package.json"
32 error node v4.2.6
33 error npm v3.5.2
34 error path /tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json
35 error code ENOENT
36 error errno -2
37 error syscall open
38 error enoent ENOENT: no such file or directory, open '/tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json'
39 error enoent ENOENT: no such file or directory, open '/tmp/npm-11586-fde7ba94/unpack-51a0e890/package.json'
39 error enoent This is most likely not a problem with npm itself
39 error enoent and is related to npm not being able to find a file.

Show error message when photo upload fails

Currently, a failed photo upload results in a 400 that the UI silently ignores. The only hint to the user is that the save button stays blue instead of turning gray.

It would be nice to tell the user that something went wrong. There doesn't have to be a custom UI, just a standard alert box would work.

Admin: fetch on activate

As an administrator, I may edit a person right after a different administrator edited the same person. If I loaded the admin page before the change was made, I will have stale data, and the other admin's changes will be silently overwritten.

Proposed solution
When a person is confirmed to be activated, the Editor should not set the model immediately. Instead, fetch the model, and when that completes, replace and render as usual.

Uploading images rasterizes rotation flag

As an administrator, I want the photo upload service to automatically rotate the image if the rotation flag is present in the EXIF metadata, so that users' browsers are not responsible for forgetting to implement image rotation.

Warn when adding person with non-unique name

It's easy for two admins to decide to add a person, and then we have duplicate entries. There is no enforced uniqueness check on the fullname field in case there really are two people with the same name.

Proposed solution
When saving a new person, have the UI check for fullname uniqueness and show a modal warning that lets the admin know about the possible collision. They can either go ahead and save anyway, or go back to editing the unsaved entry.

Opera Blink hides photos in SVG when filtering by tags

Steps to reproduce

  1. Open Opera Next 21.0.1432.48 for Windows
  2. Go to http://floorplan.bluejeansnet.com/floorplan/mv
  3. Click on "SUPP" in the bottom-left corner of the screen

Expected behavior

  • Profile photos of support people stay opaque in the map
  • Profile photos of everyone else become semitransparent in the map
  • List on the left side of the screen only shows support people instead of everyone

Actual behavior

  • Profile photos of almost everyone disappear from the map (but are still clickable)
  • Profile pictures for Jihan, Alex B., Alex D., and Akshay become semitransparent
  • List on the left side of the screen correctly shows support people only

ListPane should show all people, not just current office

As an employee, I want to be able to use the ListPane to search and browse for people without having to specify which office they're in first, so that I can find the person more easily.

Currently, only people from the currently selected office are shown in the list, and the user must go to the correct office before the results will show the person.

If a user clicks a person whose office is not the currently displayed office, navigate to the page for that office and show that person's details.

Depends on #6.

Require full name when submitting accolades

Add some validation to the accolades form submission that checks to make sure the user entered at least two words in the fromName field, and prompt them if they try to submit an invalid form.

Case is less important because our UI happens to render this field in all uppercase.

Serve person photos with headers that allow more aggressive caching

Currently, it seems like loading Floorplan with a hot cache will make a ton of If-Modified-Since requests for the person photos, which returns 304s and prevents retransmission of the entire image.

Ideally, we could send additional headers (like Expires) that allows browsers to load the photos from cache without blocking on a server response first.

Handle images with multiple EXIF orientation fields

If an image's EXIF metadata contains more than one instance of the Orientation flag, graphicsmagick will return each value, separated by a newline.

For example, if an image's metadata looks like

Orientation=1
Orientation=1
ResolutionUnit=2

then identifying an image with the format string { "width": %w, "height": %h, "format": "%m", orientation: "%[EXIF:Orientation]" } results in

{ "width": 546, "height": 522, "format": "JPEG", "orientation": "1
1" }

which is not valid JSON because there is a line break in the middle of a string. The ensuing exception causes the upload to fail.

Show contractors

  • Use a unique tag ("CON"?)
  • Don't show by default
  • Can only show using HR mode or console command or some other hidden feature (or maybe tag just defaults to off in the TagGrid)

Export person database to CSV

As an HR administrator, I would like to see the entire database in a spreadsheet, so I can audit the values for correctness.

DetailPane scrolling

If the viewport is too short, the DetailPane overlaps with the Suggest a Correction link. Any content below the bottom of the viewport cannot be viewed or scrolled to.

Add some overflow scrolling to the DetailPane, tweak geometry to prevent overlap.

Persist search query across page loads

As a user who is trying to find someone on Floorplan, I would like to type their name and click their list row and have them be the only opaque photo on the map, even if they were in a different office than the one I searched from, so that I don't have to retype their name once the new page loads.

Add G&A, IT tags

As HR, I prefer accuracy and granularity of tags over maintaining a 12-tag limit, so people can search more easily and because IT is going to grow in the next few months anyway.

In Admin, add checkboxes for the new tags.

optional: Maybe add people to these tags on the prod DB

Remove company filter from LinkedIn "search for profile" link

When a person is added to the floorplan, it's probably because they just joined the company, so they probably haven't updated their LinkedIn profile to set their company to Blue Jeans. This makes the LinkedIn search not return the person in the results, so the user has to clear the company filter from the search.

It would be better if the link did not filter by company. It would obviate this filter-clearing step for users, and would probably not pollute the results with false positives that much because LinkedIn will still rank by connection count and the strict nature of full-name criteria.

User being added through Admin page gets "_id" of null

Apologies for stopping by with another possible bug report.

When adding a new user through the Admin page, everything looks to go through okay. Once you add a second user, however, if you switch over to the floorplan page, you'll see that the first added user is gone. The last created user will still be available, but any user created through the Admin page other than the last one will disappear.

https://prnt.sc/gtc3sw

Looking at the "people" collection in the floorplan database, it looks like users created through the Admin site get a "_id" value of null. Only one object in the collection can have that null "_id", so the older added users disappear.

If I add users manually through the mongo shell, the users get an "_id" value of "ObjectId("stringOfCharacters") and the users persist in the database and on the Admin/Floorplan sites.

For what it's worth, this happens for me on Ubuntu 16.04 and Centos 7.

Not related at all, but a fresh install pops up with broken images and formatting until permissions are sorted on public/styles. Granting rwx to everyone to that directory fixed the issue and allows the page to render successfully. Prior to fixing permissions, an error can be seen accessing all.css. Think LESS may be unable to convert files in that directory with the default permissions.

Cannot add first person to database due to sorted element insertion logic not handling empty collection

When you save your first person, the list of people on the left tries to add a row for them. However the row insertion logic relies on there already being an existing person row in that list so it can insert the new person either before or after them. When the collection only contains one item, the new person you are trying to insert, there is no existing person to use while inserting, so the DOM insertion fails and the API call to persist the new person is never sent.

Soft delete people instead of hard delete

When a person is deleted, they are removed from the database, and their properties cannot be recovered.

Instead, we could set a flag on the document, or move it to a different collection.

Restoration of deleted people is not required.

This is to prevent someone from just deleting the database.

Editor seat picker: icon never appears for new people and people being set to a different office

Steps to reproduce

  1. Get a person (new or existing)
  2. Set them to a different office
  3. Use the seat picker to assign their seat, which dismisses the seat picker
  4. Open the seat picker again

Expected result

  • Person appears in the correct place on the Floorplan page (upon reload)
  • Person appears in the correct place in the seat picker

Actual result

  • Person appears in the correct place on the Floorplan page (upon reload)
  • The person 's icon is missing from the seat picker
  • The person's blue placeholder square is in the wrong place in the small seat picker if they used to have a seat in a different office.

Deep link to person on Floorplan page

If the URL contains a hash with a person's ID in it, activate that person.

When activating a person, update the hash.

Practically speaking, this will be a copy+paste of the History API calls from the Admin page.

Add endpoint labels for Polycom HTTP control protocols

Previously, the only Polycom control protocol was POLYCOM_TELNET.

Now there is also POLYCOM_HTTP_HDX and POLYCOM_HTTP_REALPRESENCE.

The floorplan UI should still just use the label "Polycom" for these new control protocols.

How to use?

Looks nice, but I am missing some info on how to setup your app.

I cloned the project, ran npm install, created the database and config.json.

Now when I try to add people via /admin I get some errors in the console:

GET http://floorplan.bluejeansnet.com:8080/taas/now?timezone=Europe/London net::ERR_NAME_NOT_RESOLVED jquery.js:6
failed to fetch current london time: error Map.js:232
Map.js:233
GET http://people/ net::ERR_NAME_NOT_RESOLVED jquery.js:6x.support.cors.e.crossDomain.send jquery.js:6x.extend.ajax jquery.js:6a.ajax backbone.js:1a.sync backbone.js:1h.extend.sync backbone.js:1h.extend.fetch backbone.js:1(anonymous function) admin.js:38(anonymous function) admin.js:59
GET http://localhost:3000/scripts/lib/jquery-2.0.3.min.map 404 (Not Found) :3000/scripts/lib/jquery-2.0.3.min.map:1
GET http://localhost:3000/scripts/lib/backbone-min.map 404 (Not Found) :3000/scripts/lib/backbone-min.map:1

When I click add person I see "You have unsaved changes..."

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.