 Good morning. Okay, everyone's paying attention. I know it's just before lunch So today Doug and I are going to help you learn how to write an AngularJS plugin And since this is a hands-on lab, we are going to actually write an AngularJS plugin So the things we are going to cover today First we will talk about the overview of an AngularJS plugin and then talk about how this Workshop is going to be structured. So you have an idea of what to expect After that, we are going to talk about some basics of the AngularJS plugin And the plugin structure that you need to understand and Then we'll move on to lab one which is basically where you'll start to enhance on coding So I hope you all got your coding hats on Hands-on sure So in the first lab, we're going to start out by writing an AngularJS plugin Which is going to put up a panel in horizon. So just your basic things and from that point on we are going to talk about some Development tools and tips that you'll be using or you can be using when you're doing development Then we'll move on to lab two which is going to build on what we did in lab one So for lab two, we're going to talk about how you can modify a table that you put up on a panel More often than not people are going to be putting up tables on on panel So this is a very common use case that you'll run into We'll then deep dive into the AngularJS and service interactions So this is where we will tie in how you're interacting with your API's and services so that you're getting back data and interacting And then we'll use the concepts that we are going to learn into lab three and Basically add a table row action So we'll provide you with some code that you can use as a starting point and then add some actions to the table rows Once we are done with that lab We'll talk about some other things that you need to know about when writing an AngularJS plug-in like How to do a DevStack plug-in as well as updating the horizon plug-in registry And then we'll talk a little bit about what we did with the load balance as a service version to plug-in That is now released as part of the Mitaka release and then we'll have some references that you can take with you And then we'll wrap it up for the day Okay Plug-ins are basically a way where they allow you to extend an existing functionality as a general rule and That allows you to not only control what content you have But it also isolates you from some of the base changes that may be going on in the underlying code So in our case for example if there's changes going on in Horizon Then you know you have a way of isolating yourself somewhat And I'll talk about that a little bit into your plug-in So one thing you need to understand is Horizon Has been on a path to move to AngularJS the base code that is and Because there's a lot of code in Horizon. It's not something that's going to happen in one release It's a you know work in progress There are parts of Horizon that have moved to AngularJS, but not all of it has moved So for example, the launch instance wizard is completely AngularJS now so That's very important for you to keep in mind when you're writing an AngularJS plug-in because you may run into issues Because of changes happening in the underlying code in Horizon So the best way to do your AngularJS plug-in development is to sort of you know Coordinate with the Horizon team if you run into issues Be there in the channel with them open stack dash Horizon It's you know, the Horizon team is really good. They're very active in the IRC channel as well So, you know just to work with them Okay, so let's say you're trying to write an AngularJS plug-in The first thing you need to do is create a separate repository all the AngularJS plugins are in their own repository and Make sure you give it a meaningful name and what do I mean by a meaningful name? It means that it should have one of the suffixes that are well recognized So one of the dash dashboard dash UI or dash Horizon That's a good suffix to have for your for your repo name Because the infra project will then recognize it as a Django project So it is important to make sure you give it a name that abides by this Your AngularJS plug-in is going to be a collection of JavaScript files and static resources So what we want to do is we want to make sure we put all our static resources In the static folder and so you'll see that when we go over the plug-in structure and what the tree looks like on where the files are residing and it's important because the Django static collector then knows where to pick it up and Distribute to the browser correctly Okay, workshop overview so things to know about the workshop first of all Everyone that had RSVP'd up until Friday Should have gotten an email from me asking for you to do a setup a pre-labs setup on your laptops So make sure you've already done that if you haven't go ahead and start it now It does take a few minutes. So it's important that you get that down going The workshop is going to be covering AngularJS from a code perspective So the things we are not going to cover are you know unit testing or How to integrate your plug-in into the infra project or the details of how the translation process is going to work Or how can you package your plug-in? So the goal here is to write code. So all the peripheral things are not Something that we'll cover in this workshop The workshop is geared towards writing an AngularJS plug-in in horizon It's not a general AngularJS plug-in workshop and now Doug is going to Take us into more details about an AngularJS plug-in and the artifacts that we need to understand from a base Concept perspective Great. Thanks So if you want to follow along locally on your PC If you're looking at the code, this might be a good time to do a get check out lab dash one is the tag that corresponds to this code and so The first bit of code if you look at the the dashboards tree You're gonna see it see a lot of pys suffixes and you might be thinking Doug what gives I thought this was gonna be an AngularJS plug-in workshop Horizon is still uses Django on the server side the plug-in plug-in mechanism is still Django Python based So the way that horizon is going to find out about your plug-in is still through Django and some of the older Mechanisms if you've written horizon plug-ins before as we go down in particular. We'll talk about this file This is the one that ties Your plug-in to horizon and really tells it where to find the other parts As we look down here under the static bit This is where this is where the fun is going to begin. You'll see we have a couple of JavaScript files There's an HTML file and that's actually our first little bit of angular and our small angular Template that we'll take a look at So the enabled file this is again the file that tells horizon about your plug-in and what kinds of things are in it it has It's prefixed with an alpha numeric string that tells that the order is going to be loaded By horizon so later plug-ins could overwrite Previous plug-ins. It also tells horizon what order in the tree. You'd like your plug-in to show up again, this is Python code and This is going one of that that key elements in this file is it's going to point to your panel P y Which again if you're if you've written horizon plug-ins in Python before Tells horizon exactly how to represent your panel in the tree and when it should be displayed So let's take a look at that panel P y so the panel P y specifies the Name that's going to show up in the navigation and at the point where I took this Screen capture you can see you know the name sample here would actually show up in the left side navigation of horizon It includes a slug which is a panel's unique identifier. It's going to end up in the URL for some of the Python Django related interactions and Finally it says who can see this panel or what services need to be available for my panel to be relevant All right here the the the sample we're building is actually built on Interacting with the neutron service So we've I've indicated that the network service should be available in order for this plug-in to show up URLs that P y is a file that again is familiar if you've written a Python plug-in before it tells Django where to find the URLs to get to the resources in the code We're gonna see here that that four up for a Angular-based plug-in. There's actually only one URL that that's gonna be that's gonna be mapped and where it's you know The mapping is happening right here, and we are telling horizon how to find our index File so that angular routing can take over. We'll take a look at that later as the lab goes on so the views dot P y is is the thing that's referenced by the URLs and it's you know pointing into our our our Project sample index dot HTML As we take a look inside we're gonna find that that's actually still at a Django template all of the horizon angular code Inherits from this Django template to have appropriate places for the angular code to plug in So here is the Django template it includes places that are gonna be overridden by Angular code and here's here's our very first little bit of Angular we're looking at right here We're telling angular that the things that go inside the main block here are going to be a view It's our first our first tie-in point A couple of things that might be unique to your plug-in you do we do still get to set the the title here Yeah, that should that should be it So now we're getting to the good stuff. We're actually looking at some some angular code at this point Table that HTML for for the lab one example is is straightforward. It should look a lot like HTML If you've looked at angular, you might recognize that this HZ page header is actually a An angular directive, so there's actually a little bit of code that ties in behind that Let's just do this sort of templating thing as well Is angular we'll touch on that during the first lab Sample module.js is our top top level angular file It's a You know, it's a module. It's always the thing that tells angular how to find the other JavaScript parts In the code and it's a good place to put any anything that is going to be scoped to your entire plug-in Constance you may want to use throughout the throughout the application Or routing information or that sort of thing. That's really high-level type information. So with that let's crack open the code Hopefully everybody's done this setup. I'm happy to walk around and help with that if anybody's had trouble later But what we're going to do is we're going to go into the check out lab one starting point And we're going to take a look at that You know panel PY like we talked about and go in and just change that the left navigation so that you can See your name in the left in the left navigation and we'll go into the angular template and go ahead and just Change the text to be hello your name or some other clever text So we'll go ahead and take maybe five or a minute five or ten minutes now your turn to write code We'll walk around and answer questions. Thanks Make sure that you do get check out lab one because we've provided some base code for you to build on to do this lab So that'll get you to the point where you're ready to work on this lab Good point. Thanks, right So, oh, I'm sorry. I'm sorry. Yeah, I see I see I see So Martin has asked a good question that what I'm saying to do get check out lab one You should see D into where the the code has been checked out with the instructions and so that would be under opt stack Sample dashboard sample dashboard. Yeah sample underscore dashboard. So change to that directory where this and this is the where the Plug-in code lives and go ahead and click Check out lab one Thanks, Martin. Other basic questions that people have before getting started And just so we are more clear about what we're asking to do Once you do a good checkout lab one, you should see this page so right here under Lab one is a new panel that you should see that has text of hello lab one So what we want you to do is basically change that so that you have your first name here instead of lab one And you have your hello first name here instead of hello lab one So this will help you understand what files are being used Where? Yeah, I'm sorry. Could you repeat the questions? Are the slides posted anywhere? So the slides are not posted anywhere yet, but once the recording is available We'll make the slides available as well either You know, I think in the previous releases I mean previous summits in the schedule They have provided place where you can post slides or as part of the video recording We could put a comment where the slides will be posted So one way or the other they will be available, but later on you'll have to check back Were you hoping and the lab repo is also available? So, you know if you want to continue working on the lab after you go back, you know You have the link to the repo so that will be available Were you hoping to have the slides available to help step through the lab or just for reference later? hand out So in case you're wondering what the password is to log in it's open stack one or lowercase So if someone is not seeing their changes reflected on the browser Make sure that you're running that update underscore static script that's provided So so so one awkwardness that is apparently built into our lab There's a goodies directory that has a useful script for updating when you're running from Apache and there's a file That I don't see in front of me update Static ssh or something like this it would be really great to copy that out of the git repository Put it maybe in your home directory and run it there because as we step through the labs That file is going to disappear my apologies. I've got a question so a problem that a couple people have had if you set up last night in your dev stack directory the local comp will have a problem line in it and It's offline equals true and if you find that you are are having trouble running dev stack or you're running dev stack and it's not Not finishing Remove that line and then run stack dot sh again. That should move people along How is progress through the first lab going it does anybody looking at their name and their web browser yet? Martin our hero Let's take it. Let's let's take a few minutes and get through I think it's I think it's important that we get to this first exercise that you so you have an environment That's working. So I'll just start at the front again. Let's ask your questions and let's let's get people through it So you can so you can see what's going on? so, can I get a show of hands on how many people are done with the lab or at least are able to see the The skeleton dashboard that we had the place that we had put in Just trying to get a feel of how far along people are or are people struggling Because we do have lab two and three that will basically give you a more angular. Yes core feel is Anyone done with the lab one? Okay, just I'm sorry Kind of sort of is okay, too. Okay, so if you're stuck then raise your hands Didn't find the module Run this command and then try to start the web And They couldn't find the module right so then I get cloned it Directory these two directories and So how do I run this run that last command so it finds the sample dashboard? The last Okay, so I see some people have had some success from the lab Maybe some others haven't we've slightly surpassed our five minutes allotted to get through the lab So I think we'll go ahead and move forward and so we were looking forward taking this modifying it so your name could be seen here and Both in the the left side navigation as well as within the page that has the angular in it And these are these are the code change. I was okay code changes. I was looking for us to make Here under in the Opstack sample dashboard directory. I was looking for Going into the panel py and just you know putting in your name here for the name of the panel That'll that'll that's what we'll show up in the left side navigation and then inside Underneath the static directory. So that's where the angular goodies live Going down to the table html and just messing with this markup and maybe you know putting your name inside the markup So some things that some of us discovered along the way. They were useful is using chrome Is a night as a nice way to get JavaScript debugging Firefox certainly has a debugger My personal experience is that when I'm debugging angular I get better error messages from chrome It's more what shows up in the console is more Helpful there are some horizon horizon settings that Some of us may have adjusted I want you to be aware of them So compress enabled false if we get if we get to the point where we're debugging JavaScript This is a useful thing to do When your JavaScript is being served by Django without it It's being all slammed together into one big file with a random looking name That can be really hard to debug if you set compress enabled equals false and it's going to keep those separate and It makes the debugging much easier because what you see in the debugger actually matches your source Also, if you're using the development server, which I covered for some of you and separately You're going to change need to change your web route to slash so it matches what's being used You'll see that sort of information and the horizon developer getting started information And again once we get into writing JavaScript Sometimes it's really simple a simple debug tool is just to throw a console log inside your code It'll spit out an object to the console or set of objects and you can see what's going on that way So again, so we some of us went through this already But you can run the Django development server from horizon and to do this to do this you would go into the op stack horizon directory and horizon has a The Django development server. It does some nice things for you like Reloading code automatically. It's also very easy to run it in a virtual environment if you need to by leaving out the dash n parameter And so this would start serving up horizon on port 8081 Again, if you do this you need to use the configuration settings I showed on the previous chart to change the web route to slash and Also, here's the content of the script. I think some people actually got to break inside of that already To Updates when you to do the updates when you're using a patchy So you're gonna find as you do this development and you put a patch out for review If you have people who are not really familiar with that horizon angular looking at it They'll pull down your patch and it won't work until they do these steps That's why I provided those steps in a script under the Miss goodies directory It'll be used for you to make so your own version of that script and pass it out to your friends as they're reviewing your code So let's go ahead and move on and talk about some of the lab to Materials you can go ahead and from the the opt stack sample plug-in directory Check out lab to if you want to follow along locally so Sample network P y is a file. It's Defining the rest interfaces to the plug-ins client And so it's actually it's it's actually providing a service from the server that your horizon is going to talk to from angular to get information People use the word horizon API for this sometimes our rest API Because it is a point we are getting you're gonna be serving up Jason from Yes, should we Commit the changes. Oh, oh, oh, oh So I so the question is about how to do get check out lab two because I already had you make some changes in lab one Two two ways you can handle that I'll leave that to your discretion One is to do get stash that'll shove off your changes to the side so you can take a look at them later Or if you think that you understood what you changed and don't want to necessarily refer to that code again You can just do get get reset dash dash hard Origin master and that'll bring you back to the master branch the master set of code and then you can do get check out lab two So horizon has some back back to serving up Jason from horizon for your angular code to consume Horizon has some utilities that are useful to help do this And if you look at the at the file I've provided You know a couple of the points to note here are this Python decorator you are URLs register Tells horizon that the class inside is implementing a rest API that's going to be consumed by dang jang it by by angular and Turns out the class name is almost irrelevant, but give it a good name and extend generic view The URL Specifies at what URL is my rest API going to be serving from and then inside there's another decorator rest Utils Ajax that tells horizon. This is where one of my Rest methods are going to be implemented implemented for the first sample. I've just implemented a get so when we want to get the Networks, you know, I'm making a Python call to do that What one of the things we do in horizon as we wrap the Python calls in an extra level of abstraction I've said a bit a bit about it here We didn't actually implement one of these for this sample in the same way that we didn't for albast dashboard because we were just able to import the existing horizon API wrapper I'll leave the chart here. Not gonna spend much time on it at this point So now stepping back to the angular side So the networks controller JS file it's important one to take a look at this is that angular Controller and it's gluing the what happens with the view, which is the HTML that we were messing with before To the model, which is where you know data is coming from so it's it's gluing together the pieces Some things you're going to see in this file are that we're telling We're telling angular in this case You know this this this code should be part of the of the horizon dashboard project sample networks module and I am providing a controller So that means I'm I'm matching up this text which I can put into my HTML as a controller with this JavaScript class name So here I've got dependencies that are being injected There's more than one way to do this in angular if you're writing a horizon plug-in It's important that you choose this style of dependency injection So we're calling out dependencies by by name here And we're saying angular when you when you build my sample network table controller object Please provide me with with an angular no service API sample network object and a horizon dashboard sample Actions batch actions object and a row actions object And so we tell angular this and angular is very compliant that way so when our Are our controllers being instantiated it passes in the objects that we requested in the order that we asked for them so this First API parameter in our JavaScript will correspond to what angular found for this object and so on for the other three The other three dependencies a table HTML So one of the things you'll find now is that the table HTML is updated for lab to We've called out the controller Sample networks controller as table. This is the name that needs to match the name that we registered before Horizon uses a smart table angular Package and so here we're we're interacting with with that. This is an important interaction for your table What this means is that table that source is where your controller is going to put the data that you want to be in the table and Smart table is oddly enough smart So it's going to do things like Understand that you've sorted your table or you've maybe done some filtering and you're not showing all the items in the table And so smart table is going to place The sorted and filtered list of items that we're actually working with into table items so that when we go through later and we're Looping through with NG repeat, which is an actual angular directive when we're looping through this table We're going to loop over only the items that are filtered and in the order that they're sold that they're sorted as the smart table informed us and One other file to take a look at is this sample network service JS file So this is a wrapper on the JavaScript code that knows how to interact with the the rest API So at this point our intent was to skip was to go into lab 2 and I think I maybe need to consult with Neela briefly about how we handle our last few minutes and get out the most useful information we can I Don't think we'll finish lab 2 in our allotted time So so Give it given our late time, which we'll wrap up in just a few minutes. I'm gonna skip ahead a bit Certainly we'll make this chart available. You can work through the exercises I think it's intended to be a step-by-step wait To get familiar with some of the angular plug-in stuff Good stuff here. Don't be sure to take a look at but but I want to make sure we have a few minutes to point out the resources The places you're going to go To get extra help to get extra information One thing to think about as you're writing your plug-in is Putting a DevStack plug-in inside your repository is very helpful It's an easy way to go out and get your plug-in installed in the right context You don't have to worry about PIP installs remembering to copy over that enabled file all the time You know write a DevStack DevStack plug-in. It's very simple And there's one included in the sample project that that should serve as a good template The horizon team keeps a registry of of plug-ins. It's really just a file where they list everybody who's working on a horizon plug-in It's a helpful communication mechanism. It lets people know that your plug-in is out there They can be aware of it as you start work and you have a repository available take a look there Register your plug-in so the horizon team knows you're there My team has worked on We're here because we worked on a load balancer as a service v2 angular js plug-in And so a lot of our sample material was taken from that plug-in If you have questions about how to do more advanced things after you've worked through the tutorial I think our plug-in is a good place to go and take a look and See some more advanced usage of how to really fill out a table or do a more advanced form And so again, here's the repository for the lab There's there's a Horizon tutorial the horizon team has written a tutorial sort of their perspective on how to think about angular plug-ins I think you'll find it's very compatible what we've talked about today And our teams new trying neutron albast dashboard plug-in is available again. Here's the URL. I Appreciate your time working through the lab today. It's been a pleasure. I hope you learned a lot and Angular goes well for you