Thanks for the thoughts Ohad. I, for one, do not think making a
singular decision is the right approach as you mention as this is true
of any other type of change that would be made (e.g. to switch to
Dynflow for orchestration has taken time and small steps as well). I
do want to clarify a few points below because I think there are some
misconceptions that I have heard time and time again.
> Just to make sure, please read my reply in positive light as thats how i
> wrote it
>
>>
>> All,
>>
>> I will include some specific responses inline below, however, as the
>> person who originally pushed Katello down this road, I'd like to give
>> some insight into the history of the choice we made.
>>
>> During the days that Katello was the open-source project for what
>> became Cloud Forms 1.0, we had a UI that reflected the typical 960px
>> centered view but with lots of progressive JavaScript mechanisms such
>> as, for those that know, tupane. Over time, users and developers alike
>> started requesting more and more dynamic functionality. This led to
>> creating a swath of spaghetti that interlinked Rails views, UI only
>> controllers and and JavaScript within one another (e.g. the original
>> tupane code
>> katello/app/assets/javascripts/common/panel.js at KATELLO-1.3 Ā· Katello/katello Ā· GitHub).
>
>
> this is indeed true for Katello, but on the other side, Foreman is 5 years
> old (today!) and we don't have spaghetti code at all,
> the most "complicated" js we have is in the host edit form, totaling about
> 600 lines, surely that's not that bad.
> we can and should improve our UI implementation, but based on my experience
> i cant say that ERB/JS is evil or not manageable etc.
First, Happy birthday! Second, the combination of JS (via jQuery
selectors), erb, and erb.js is to me spaghetti. The use of erb.js
links JS snippets to your Rails controllers and the data therein
making it hard to determine where a particular chunk of JS
functionality is coming from. jQuery style selectors to produce
workflows is not scalable and leads to the issues that we encountered.
You are required to build views and view chunks that have specific
classes and IDs that your JavaScript then grabs and manipulates that
makes figuring out which file manipulates what view difficult.
>
>>
>> Once we hashed out, via design meetings, what new design we wanted for
>> all pages that represented a table + object details I began to
>> investigate if there was a better way to build this new design. I had
>> grown tired of the increasing effort to sustain the spaghetti due to
>> how inter-weaved all the pieces (views, JS, controller, helpers) had
>> become and looked for what new tools were out there. This led me to
>> investigate a number of JavaScript frameworks to see if we could do
>> better. I took a basic premise: build a table view that only changes
>> out the data. I then built this using Backbone, AngularJS, Knockout,
>> and early Ember. At the time, these were the most popular frameworks
>> that my research could discern. I quickly found that I was building
>> the AngularJS application faster and more understandably than the
>> rest. However, I did not stop there. I also considered:
>>
>> a) Does the framework have longevity? Will there be support 2 years from
>> now?
>> b) How easy is to build JS components?
>> c) How easy is it for a new developer to get on board?
>> d) Can the code written with said framework be tested?
>
>
> That is indeed great, however, at the same time, i assume it took you at
> least one year to learn, implement etc.
> The benefit of using common / simple UI practices, means that we dont have
> to spend a lot of time in design, learning and testing which is outside the
> scope of our tool.
> It also means, that a lot of existing tools can be used, we use a lot of JS
> libs (charting, editor, bootstrap, novnc, spice, multi select, data tables,
> etc), that are either based on json( e.g. data tables) or on pure html
> (which is also a very good official api such as multi select).
Honestly, it took me about 2 months. After a year we were building
prototypes with ease, spinning up new pages and the bulk of our time
and effort was spent getting our API controllers into proper shape
because they had been neglected in favor of our previous UI
controllers. In the Angular world there are plenty of libraries
available for use (http://ngmodules.org/) and wrappers around
existing, popular libraries (e.g.
Angular directives for Bootstrap).
>
>
> in other words, you've have built a framework based on angular, while it can
> be the best framework in the world, the original question remains, should we
> spend all of this time building a framework for a new UI workflow?
We did not build a framework. This is the equivalent of saying that
Foreman is a framework. We built some common tools and functionality
just as a helper or application controller in a Rails application
centralizes common functionality.
>>
>>
>> The reasons I inevitably went with Angularjs, and should address some
>> concerns folks have mentioned are:
>>
>> a) A primary goal of the Angularjs team is to build Angularjs using
>> methods and functionality that future Javascript specs are declaring
>> such that when those are implemented natively by the browser, the
>> Angularjs team can remove that functionality from the library and thus
>> reduce the foot print. And, where they see a concept created by them
>> that could be useful to the larger community, pushing those changes to
>> the browser spec so as to remove it from their library. A good example
>> of this is the watch/observe functionality that is now making it's way
>> into the browser.
>>
>> Some stats:
>> 27.2k stars on Github
>> 928 contributors
>> 4 years old
>> 54k tagged questions on stack overflow
>> ('angularjs' tag wiki - Stack Overflow)
>> 75k+ hits on youtube when searching "angularjs"
>>
>> b) Directives made creating components easy, and although the toughest
>> part of angular, this was easier than building components using basic
>> JS.
>>
>> c) I'll let other developers who have built things subsequently chime
>> in here. For me, things are much quicker and have not degraded over
>> time like before. There are lots of tools for learning, plenty of
>> tutorials, videos and tons of short videos. Websites such as
>> http://angular.codeschool.com/. They also have case studies from third
>> parties - https://builtwith.angularjs.org/.
>>
>> d) Angularjs came built with testing in mind via their test runner
>> Karma. We have since been able to write tests for all aspects of our
>> JS, generate coverage, run a Jenkins job on each PR for the testing.
>> Further, the tests can be run from the command line and run in less
>> than a minute.
>>
>> After considering all of the above, I decided to build out the design
>> that had been created and spec'd out with Angularjs for the most
>> complex object we had (i.e. systems). I did this in order to
>> illuminate any pitfalls that may occur when applied to a complex
>> object. Further, I did not radically overhaul and push this upon the
>> project. Rather, I took an approach of showing off the steps along the
>> way to developers, asking questions of developers when I faced design
>> choices, and eventually providing this new look'n'feel and interface
>> via an experimental UI mode.
>>
>> This experimental mode was a toggle-able user preference that when
>> enabled hid the old UI and displayed the new UI components. This
>> allowed users to play with and try out the new pieces without having
>> to completely give up (or break) old functionality. After we got the
>> experimental UI to the point of being ready for prime time, we then
>> flipped the scenario such that the old UI was still around but in a
>> legacy mode that a user could toggle on or off. This allowed us to
>> step through the building with a new implementation style as well as
>> test and use new pieces without having to make radical change.
>>
>> As others have mentioned, a side benefit of this approach was that we
>> only needed to maintain one set of API controllers. This meant that we
>> found gaps in the logic that our UI controllers and API controllers
>> were assuming as well as gaps in the authentication by centralizing to
>> a single entry point.
>
>
> I still dont see it as plus, API needs to be stable, and cant be modified,
> while UI controllers can evolve quicker and allow breaking changes when you
> want to change your UI.
>>
>>
>> The reason, in the previous thread, that I brought up the idea of UI
>> plugins was based upon our previous experience with experimental mode.
>> Creating UI plugins seems like a great way to not disrupt the core,
>> while simultaneously providing a method for the community to try out
>> this new way of creating and new design patterns. If, in the end, we
>> can convince you of what we believe with respect to how we should
>> build UI's in the Foreman community, then we can easily pull these
>> changes into the project as the main method.
>>
>> I have, at times, got the impression that some feel as if we did not
>> take a measured and reasoned approach towards converting how we built
>> the Katello UI in the past to how we build it now. I hope this helps
>> explain a bit about where we are coming from, why we made the choices
>> we did and why we believe in the approach that we took.
>
>
> Overall, I think you guys did what is right for Katello, For foreman, I'm
> having a hard time justifying a rewrite, overall the issues i see are:
>
> Bastion:
> - make simple pages complex (its much easier to use existing foreman helpers
> for the avg community developer)
Much easier is subjective, and I'd argue this lacks evidence on either side.
> - requires a whole different skillset (ruby, rails and now javascript,
> angular, api, json etc)
Fair point, although JS already exists within Foreman and knowledge of
the API and it's JSON doesn't seem like asking for much compared to
the other knowledge that is required. This, however, can only be
proven/shown over time and with users trying.
> - is not extendable by plugins
> - rewrite most likely will break existing plugins
I'd argue that this is not true for current Foreman core either.
Pointing users to a library (deface) that can manipulate the UI in any
way they want is not providing extension and cannot scale. You can
never know what parts of the UI any user is changing at any given time
and thus any change to the UI is subject to breaking existing plugins.
However, I wouldn't argue for ever doing a drastic, quick change but
rather, like an API change, introduce it over time.
> - normally, takes longer to implement
> - has no equivalent helpers like rails / foreman.
As I always tell Tom when he makes passionate arguments, please
provide data and evidence.
>
> on the plus side, I do admit that our JS testing is lacking, and that some
> pages are over complicated, refactoring will solve it, but i can't say that
> AngularJS is the only solution.
>
> Further, pure client side implementation is not required for a management
> app with a limited amount of usersā¦ its obviously a plus, and there is a
> good chance that I myself would start with Angular if I had started today,
> but I have the feeling that the UI does not require that much of an
> attention compared to the actual features the application can provide.
I agree that a client side implementation is not required, and this
argument is not dealing with the scale of users but rather the
requirements around building dynamic components and workflows. The
original aspects that drove our push for client side was due in part
to requirements. We received requirements that increasing requested
dynamic interface components that provided workflows, and data views
and manipulation. Which we found were easier and quicker to build
through pure client side implementations and hitting the API than
attempting to combine Rails controller, views and jQuery.
As you said, the only course of action is to take the open source
approach, keep believing in what we believe and push to help others
see it as we do
Ā·Ā·Ā·
On Wed, Sep 10, 2014 at 9:56 AM, Ohad Levy wrote:
> On Wed, Sep 10, 2014 at 4:12 PM, Eric D Helms wrote:
IMHO, we need to be as useful as possible (e.g. integrate with X, do Y etc)
while providing a high quality look & feel, I also believe that most users
that use both foreman / katello, do not see / feel the difference between
the pages at first.
and if performance is an issue, there are simple ways using turbolinks [1]
etc, that can mitigate that as well.
lastly, Iām not against improving, Iām mostly worried that it would slow us
down, and introduce a bottleneck, imho we must:
- unify look and feel, this is needed regardless of the technologies used.
- provide bastion as a plugin, so it wont work only in the context of
katello
- try to provide new ui plugins (as Joseph and Tom are doing with
Ember/Angular)
- continue developing the application as a whole, as neither UI will be
rewritten in the near future.
in the mean while, try to promote bastion (or any other new stuff that you
want to promote), make sure developers can consume it easily and get the buy
in from users/developers.
[1]
another turbolinks attempt Ā· ohadlevy/foreman@cf1498f Ā· GitHub
Ohad
Eric
On Wed, Sep 10, 2014 at 6:25 AM, Ivan Necas inecas@redhat.com wrote:
----- Original Message -----
Hey Tom,
JS - Katelloās UI is rendered entirely client side using angular.js
javascript (wrapped in an engine called ābastionā, which is the name
Iāll use here). Bastion provides an MVC layer on the client and
populates its data by making api calls to get json which it then uses
to fill in the html. If the organization page were to be rewritten in
bastion, viewing the page source would look almost empty. The
difference would be that when the Users tab was selected in the UI,
an
ajax api call would be made to the server to get the users that were
available to add to the org and rendered then. Clicking a user to add
them could also make another ajax call to update the org and reflect
that change right away in the UI.
Being total noob in the JS world (thus AngularJS), I donāt get what
drives the need for Bastion. Iāve read its description but I still
donāt
understand why you donāt use plain AngularJS.
In my understanding, the bastion is set of tools and ways how to
organize
the Angular code and couple of helpers on top of it. You can go many
ways with Angular, and bastion chooses some of them. Itās more like
preset angular environment that has already some structure. When
starting
with angular from scratch, you would probably soon end up with something
very similar.
Another way to think of the ācoreā aspects of Bastion, are if you took
the application controller, api controller, application helper and
other bits such as authorization from the Foreman rails application.
With those pieces you can use mostly regular Rails to build out
individual entities but you still need those common pieces that you
donāt want to re-invent for each controller/model pair or even plugin.
The core of Bastion provides some of these common functionality and
helpers to make re-using UI patterns easier. The goal is that as a
basic UI developer you should only have to care about the business
logic.
ERB pro - Very simple to write
ERB pro - Can access entire code and database readily when building
the UI
ERB pro - Plugins can use ādefaceā package to make changes
ERB con - Plugins have to use ādefaceā package to make changes
Not if we build APIs - and weāve done that previously. We need an API
for plugins to extend things no matter if we have ERB or JS.
True: the question is whether this API is forming. Might be interesting
to see if the Angular approach could bring some interesting features
here.
ERB con - Two server side controllers, one for API and one for UI
ERB con - Full page reloads very common
Why JavaScript people tend to list this as a problem? Really, page
refreshing is no big deal, if the app is properly coded, browser cache
works for all assets and pages are clean, itās almost instant. At least
thatās my take from working on Foreman, I have to admit that static
portions of JS pages load faster but once you have some data on a page,
you need to wait for it anyway.
I donāt see this as a problem. But there is something nice about only
changing the part of the page that needs to b