At Facebook, employee communication and productivity are fundamental to maintaining a fast growing and valuable business. Facebook’s mission is to make the world more open and connected, and we are taking the same approach with how our employees interact, share and collaborate together. Traditionally, larger companies aren’t really that open and transparent on the inside, as not everyone knows why decisions are made or has the ability to freely discuss decisions outside the scope of their responsibility. There is a lot of room for innovation in employee communication and this has become a hot space for new ideas and products. At Facebook, we’re learning a lot of lessons about which useful end-user social products work for employees and which don’t. We’ve learned that effective enterprise communication tools need to be engineered specifically for our employees because our employee base and business needs are very unique.
On the internal tools productivity and communication team, we try to build libraries and abstractions that promote openness and we simultaneously build tools on top of them. A specific product I’ve developed at Facebook is our internal dashboards framework. A problem we have at Facebook is that there are so many requests for custom internal tools (from engineers and non-engineers alike) that our internal tools engineers have trouble keeping up. To help improve this situation with a scalable solution, the internal dashboards project has two specific overall goals:
- First, allow non-engineers to build powerful dynamic custom pages completely in the browser and without writing any code.
- Second, give engineers the ability to break down complex internal tools into simple widgets that are isolated, highly configurable, and reusable by other engineers and non-engineers. The result is that engineers will hopefully build robust widgets with well defined parameters and that smart non-engineers will be able to configure a given widget to render the information they’re looking for onto a dashboard.
A widget is defined as any child object of the main widget class. A widget has well defined parameters and will render HTML based on the parameters set when it is added to a dashboard. A dashboard is simply a page that has one or more widgets added to it that were configured by the dashboard creator.
Creating and maintaining a dashboard is done entirely in the browser. This makes it easier for non-engineers to assemble and maintain dynamic pages without an engineer’s support. For example, non-engineers can create a dashboard full of statistics such as the number of active users or the number of friendships created every day. There is already over a dozen data dashboards that have been created by different teams at Facebook to monitor the data trends they’re interested in.
Our internal communication team created and maintains a company dashboard that has information about product launches, company announcements, events, internal notes from people around the company, and an internal status update stream where people can post whatever’s on their mind to discuss topics with their coworkers in an open format. While a typical employee would look at these dashboards and see them as complete pages, an engineer would look at them as a bunch of configurable generic widgets. A widget is a class that fetches some kind of data and returns HTML based on it’s configuration and context. It has access to information about its environment, such as the person viewing the page, and the configuration settings saved by the person who added the widget to a specific location.
At a very high level a widget is very simple and looks something like this: class WidgetChild extends Widget { function setup { // fetch data and store it in the class } function render() { return html; } function renderPreferencesForm() { // render a form which a user will use to input preferences // for the widget.
Storing the preferences is handled by the // parent and you can easily access them in the setup and // render functions. } } We already have over 50 widgets that show all kinds of information. For example, we have a widget that will render a box showing some stories from an arbitrary RSS feed. It would expect as configuration settings, a URL for an RSS feed and the number of stories to show. The engineer could write code to fetch the given feed, parse it, and render a nice looking box with the number of stories asked for in it. From an engineering point of view, the code would be isolated in a child object of the widget class and be easily maintainable. From a user point of view, they would have a generic widget which can be used in dashboards throughout internal pages to show different internal or external RSS feed stories. The backbone of the dashboards architecture is a small but complex piece of code that stores which widgets are added to which dashboards and their configuration settings. In addition, some dashboards are viewer configurable. For example, we have various internal news feeds that show employee activity, and a dashboard creator might want to add a feed container to their dashboard capable of showing various feeds. A viewer of the dashboard can then add feed widgets to the container viewable only by them, and configure them to show things like internal statuses from everyone at the company or all code reviews done by engineers on their specific team. The dashboard framework will save and retrieve these user customized views of the same dashboard. This high level description of the dashboard framework provides an introduction to the kinds of tools and abstractions we’re building on the internal tools team. If you’re interested in building powerful tools in an extremely fast moving environment, consider applying for a software engineering position at Facebook at facebook.com/careers.
Michael, a Facebook engineer, loves making widgets!