Next lesson playing in 5 seconds

  • Overview
  • Transcript

3.2 Initial Setup

In this lesson, we’ll set up the various client dependencies of our project—including React, React-Bootstrap, D3 and FixedDataTable. We’ll also create the top-level UI structure based on the wireframes we saw in the earlier lesson.

Related Links

3.2 Initial Setup

In this lesson we'll set up our client's site libraries and also build the URL skeleton matching the wire frames and visual design. So let's get started here. Let's first set up our client's side modules, starting with d3 react-bootstrap which gives you the react components matching the bootstrap classes. The bootstraps css library fixed data table which is a library from Facebook for handling data groups and finally lodash which is a library with some functional help books. With that let's kick start our server and start building some react components. So now if we launch localhost:8080, we can see where we left off in our previous lesson. So let's start off by creating our top level component, which I'm going to call HarViewer. Now, all of these components will be organized inside the component folder under source. So let us go ahead and create that. And then create the HarViewer.jsx file inside that. But the first step here is to import multiple dependencies, starting with react, and then also adding lodash and some of the components from react-bootstrap. You'll also be using the FixedDataTable for our data grid, so let's get that as well. So now we can go ahead and create our class which is the HarViewer Component that extends from React.Component. Now it is very common for most React components to include the boiler plate of the constructor function and the render function. Inside the constructor you normally call super and also initialize the state for the component. The render function is where we create the visual tree. So in this case, we'll start using the react-bootstrap and start building our grid. The react-bootstrap library is actually very handy. It's taken the classes in bootstrap and created components for them. This gives you a very nice way to create a component tree without resorting to devs and spans and remembering which classes to use from bootstrap. You can just use the grid row and column tags to set up the grid. So here I'm filling up a single column that spans the default 12 column grid in bootstrap, and adding a page header to it. Now if we check our app, on the browser we can see that nothing has changed. Well, obviously because we haven't included the HarViewer component inside app.jsx. So let's go ahead and quickly do that. Let's import our HarViewer component and make that the root of the react componentry. And with that we can see that our page header is finally showing up. Now the next thing we need is the data grid. Let's go ahead and start using the fixed data table and use the table and column tags to create our data grid. I'll make separate row for that, and add the table tag to it, and also, a bunch of columns. Now, each of these columns includes the dataKey, which is the property on the row objects that will be used to render that particular column. You'll also be needing the width and label to set the display title for that column. Now this table is gonna show you the list of all the requests that were made from the client's site. So I best [INAUDIBLE] be sure the URL in our first column. The second will be the file size handled by the size property on the row object and finally we'll show a timeline that gives you the request response times for handling the requests. I'm gonna set the width of each of these columns with a state property called columnWidths. So let's go ahead and do that. Now these columns are meant to be resizable. So as you resize, you want to set a new value into these column widths. And following the standard React model, we create a state property for that. And then each time you set the state, it'll force a render which will then pick up the new value. So let's set the default values now for the column widths with the straight property for the URL size and time columns. And while we're at it, let's also create straight properties for the table width and height. So now let's set the width of each others columns from the state and also mark them as resizable. For the timeline column in particular, I want to set a minimum width to 200 pixels. So that ensures that it never goes below that. Now let's configure the table, and set some office necessary properties. Such as the row count, which gives you the number of rows to display. We'll pull this value from the component props. And name it as entries. So this will be this.props.entries.length, and it'll create the property inside the HarViewer defaultProps. This is the standard way in which you do it for ESX classes and React. We'll add a few more properties to the table, which will be the width and height and also the header and row heights. Along with that, we need a property called the rowGetter, that supplies the row object, given an index. Now this is a function we create in our component class. Now, we're using this convention of prefixing with underscore, to indicate that it's a private function. Now this function takes in the index, and returns the row object, from the entries array. So at this point we have our basic table setup. Let's see how it looks like on the browser. And we have some problems there. Looks like we have missed out the CSS file that points to the fixed error table. So let's go and fix that and add it to the HarViewer JSX file. So with that, we have some semblance of a table appearing on the page. All right. Now I will try resizing these columns, so you will see that they are still not working as expected. So let's go ahead and fix that. Now to fix that, we need to use a standard technique in fix data table. Which is first to indicate whether we are in the column resizing mode, by using the isColumnResizing, which is a Boolean property. We'll track this on our state object. Additionally, we need the onColumnResizeEndCallback, which is a callback function that gets called once the column has finished resizing. Here is where we set the column width on the different columns and ensure that the table has been resized properly. The callback function gets the new column width and also the data key pointing to the column. So all we need to do is change your column width property on the state and that triggers to re-render with the new column size. So now if we get back to our UI and try resizing the columns, they should be behaving as expected. Now, along with column sizing, let's also take care of table resizing to ensure that the table is always within the bounds of the page. The way to do this is to listen to the window.resize event. And a good place to set up the event listener would be in the componentDidMount event hook. So let's set up our window resize event handler over here. Now the window resize event gets called very frequently, so we don't want it doing a lot of work each time this event gets called. And a good way to avoid doing that is to actually debounce the event handler. And that's what we do with the debounce lodash functional helper. This is a common trick when you want to handle high frequency events in UI. Just debounce it. The resize handler itself is fairly straightforward. What we're doing is setting the width of the table to be within the width of the parent container. And adding some padding on the side just to ensure there is some gap between the left and right edges. Similarly, we'll also adjusting the tableHeight to ensure that the table always stays within the page. The constant gutterWidth that we've introduced over here is essentially the gutter used for the Bootstrap library which is in our case is about 30 pixels. Now let's check back on our UI to see where we are, and it looks like we have an exception over there. Yep, that's a typo introduced, so the equal to should really be a minus sign. With that we should have fixed our issue. And now if we check back and resize our window, we can see the table automatically adjust to the width of the page. Let's make some quick cosmetic adjustments over here. We'll adjust our CSS for the page and also include the react bootstrap library the CSS for that so that things start looking much nicer. And with those changes, our page should look far closer to the visual design. Let's try adding a few other components to our page. Starting with the select control that allows us to choose the har file. When the onChange event on the select get fired, that's when we pick our new HAR file and we render the page without all the details. We'll also add a placeholder for the pie chart. And for now we can just leave it as a paragraph. For the next set of buttons that we'll be adding over here will be a set of filters that allows you to filter the table by a file type. For this we'll use the radio button group from bootstrap which allows you to select only one of the several radio buttons. And when a selection is made that's when you fill out the table. Now, these filter buttons are based on MIME types that are very similar to the ones you will see in Chrome DevTools. Things like script, document, images, JSON, editor, etc. And we'll use these MIME types that we'll be creating in a separate file. For now I'll make a reference to this MIMEs type object. And I'll loop over all the different supported types and create a button for each of them. In fact, the createButton function will be creating our bootstrap button and set the key to the type of file that we want to handle. We'll also set the eventHhandler when the button gets clicked. And this then will actually perform the filtering. For now we'll just call it filterRequested. Now let's take a quick look at the MIME types for JS file. I'm gonna create this in the core folder under source. And this is just gonna be a list of all the file types that we support. In some cases there are multiple MIME time corresponding to a file extension and we keep track of all of that over here. From this file we'll export these MIME types and also function called identify. Which given a MIME type use the category under which it belongs. So now that we have this file, let's import it as dependency in our HarViewer. Now let's see where our UI stands. And it looks like we have exceptions. Seems like I haven't specified the sampleChanged function. That should be called when the select box gets changed. Let's fix that. So now that's fixed, let's also add the filter text box that allows you to filter on the URL. Now this should be along the same line as the filter bar, let's quickly add that. When the text changes in this text box that's when we filter the table to only show URLs that match this text. And this will be taken care in the _filterTextChanged function. Now one minor UI fix that I want to make over here is for the table that seems to be extending beyond its parent container. So let me first give a reference name to this table. I'll call it the entries table, with the ref property of react. This allows us to access a download, and get its parents rather than getting the parent of the entire component. And that seems to be the problem that we have. So here instead of getting the parent node of the HarViewer component. We really should be getting the parent of the entries table. And with that change we should have our table filling within the bounds of the parent container. Filter down for the width and also its height. And with that, let's call it a wrap for this lesson. In the next lesson we'll start adding some functionality to this entries table. I'll see you there.

Back to the top