[Freeipa-devel] webUI code restructuring [wall of text, diagrams, ... you've been warned!]

Adam Young ayoung at redhat.com
Tue Sep 7 13:25:09 UTC 2010


On 09/07/2010 08:45 AM, Pavel Zuna wrote:
> Last week I started working on integrating the jQuery UI and jQuery 
> BBQ libraries into the project. I played around with them a little bit 
> and it turned out, that they are really great and bring a lot of value.
>
> jQuery UI is a library of widgets like tabs, dialogs, tree views and a 
> lots of other cool stuff.
>
> jQuery BBQ is a plugin for URL query string manipulation. It's main 
> advantage to us, is that it enables to get/push states (URL fragment 
> changes). This means that we don't have to reconstruct the whole state 
> every time. It is also friendly to the Back button and other standard 
> features of internet browsers.
>
> Both libraries are mature and easy to use.
>
> At first, I though "OK, that's cool! I'll just rewrite the navigation 
> file and we're set." In the end, I had to rewrite almost everything 
> due to not very well defined interfaces and dependencies. It took me 
> more than a week including the week-end, but I had one of those 
> creative blasts and I had fun doing it. :)
>
> I thought this is a good opportunity to restructure the webUI code. We 
> are at the point were we've identified a great deal of emerging 
> patterns in the code and we aren't too far yet. It was only about 2000 
> lines or so.
>
> Since I'm probably going back to IPA backend work with Rob in the 
> upcoming weeks, I thought it would be nice to reach a certain 
> milestone in the webUI. This is my shot at it.
>
> Anyway, here's the design I propose (and have already implemented, so 
> that you can see the benefits for yourselves):
>
> Take a look at the diagram I attached to this mail.

Looks dead on.  Those were roughly the splits I was thinking about.  I'm 
not surpruised it took you this long:  I've put off making changes like 
these due to the time commitment and the need top keep showing 
features.  Well done.

>
> Basically I split the code into two parts. One specific to our project 
> and one with re-usable code, that goes on top the of IPA framework 
> (ipalib; plugable architecture and all that). Module dependencies 
> (arrows with holes in them) and roles are now clearly defined.
>
> I'm going to create another diagram depicting the code flow for better 
> understanding.

That will be useful.  Once we push this patch, we should post these on 
the site.
>
> I'm also going to privately send everyone on the team a link to a live 
> demo. I don't feel like it should be on this public list. You can of 
> course checkout the whole code there.
>
>
> Now, how does the code work and how do we use/modify it for feature XYZ?
> ------------------------------------------------------------------------
>
> Everything is tied together in the webui.js file. This file includes 
> basically only two functions and a definition list used to generate 
> tabs. The functions are the application entry point (the document 
> ready event handler), where all initialization is performed, and the 
> "main loop" (the document hashchange event handler) used to track 
> changes in the state of the webUI. The definition list contains a list 
> of tabs and callbacks to generate their content.
>
> Callback for generating tab content take only one parameter: the div 
> that represent the tab content. They shouldn't care about anything 
> else than their own tab! The div should be enough to identify 
> everything, that's required (for example what kind of IPA business 
> object is handled there).
>
> The only callback currently used is the `ipa_entity_setup` function 
> from entity.js. It is a generic wrapper, that takes information from 
> entity specific files (user.js, group.js, ...) + metadata and uses it 
> to create facets. It basically glues functionality of all CRUD widgets 
> files.
>
> The entity specific files are the place to make modifications like 
> adding/removing attributes to an object, change the order of 
> attributes, change what attributes are listed in a search, generate 
> special input elements for attributes that require them (attribute 
> callbacks).
>
> Some examples:
> * We need a new attribute for object X, that displays a calendar for 
> selecting dates.
> => add attribute to details definition list of object X, define 
> attribute callback to generate the calendar
> * We need a new field to be displayed in the dialog when adding object Y.
> => add attribute to add definition list of object Y, define attribute 
> callback
> to generate the field if it has some special requirements
> * We need to handle a new state in the webUI
> => Modify the "main loop" in webui.js
> * We need a whole new tab with something different that what we have now
> => add tab to navigation definition list in webui.js, create a 
> callback, that
> generates what's supposed to be the tabs content
>
> And so on...
>
> Everything is customizable, but the defaults are good enough for 90% 
> of cases.

This should be the tagline of the UI code.
>
>
> What is a webUI state?
> ----------------------
> It's a certain combination of values in the URL fragment (that's the 
> portion of URLs after the # sign). Using the URL fragment saves us 
> from reloading the web pages (and all those bulky javascript files) 
> every time the user does something. We're going fully AJAX.
>
>
> How to change a webUI state in the code?
> ----------------------------------------
> Before we always had to reconstruct the whole URL. Doing ugly things 
> like:
> document.location = document.location - fragmet + something + 
> '&thisandthat=' something_else + // and more
>
> Now we can just do:
> $.bbq.pushState({something: somevalue});
> And to retrieve:
> something = $.bbq.getState('something');

You'll have to explain how it keeps everything straight and separate.


>
> Much nicer and we don't have to worry about overwriting states by 
> mistake.
>
>
> How does this whole thing integrate with what we have in master?
> ----------------------------------------------------------------
> If we decide to adopt it, I'm going to create a patch that goes over 
> the current master branch. It shouldn't be a big problem; a matter of 
> 2-3 hours of work.
>
> I already integrated some of Adam's latest patches (associations, 
> automatic sampledata retrieval, ...).

Should I commit the associations patch first?

>
>
> So is this just code restructuring or does it have some new features?
> ---------------------------------------------------------------------
> It has better transisions between webUI states. All the advantages of 
> jQuery UI and jQuery BBQ.
>
> We have nice dialogs for adding new objects.
>
> The content of different tabs is independent. You can click on Group, 
> check something and click back to user without loosing the user tab 
> state.
>
> All webUI states are bookmarkable! You can save your session by simply 
> creating a bookmark.

Nice!

>
>
> What to do, if this is adopted?
> -------------------------------
> I think there will be 4 main areas, where most work will be distributed.
>
> - It's almost time to add CSS styles to make the UI look usable
> - Callbacks for all kinds of special attributes and adding new IPA 
> objects to the UI
> - Maintenance of core scripts
> - Adding completely new features like work-flows, wizards, 
> localization, ...
>
> If I'm to go back to IPA backend work with Rob in the upcoming weeks. 
> I suggest we let Andy handle the CSS, callbacks and adding new objects 
> (at least for now). Adam could work closely with the UXD team on new 
> features. I don't want to drop the UI work completely, so I could take 
> maintenance and helping out with whatever is needed.
>
> This is just a suggestion btw.
>
>
>
> Enough text. Waiting for comments. :)
>
> Pavel

I'm impressed.  I had hoped that this would be the end state.  Thanks 
for seeing it through.  I'll review the patch top priority.






More information about the Freeipa-devel mailing list