Using feature flags in complex UI changes - javascript

To simplify matters, lets say there's a single HTML page with it's CSS and JS file. No server.
Now comes a request to toggle features on/off in this simple web UI.
The problem is, for example, a new feature would mean changing the HTML structure to add a new component, so now the HTML is a little different.
Also, the CSS of the page itself needs to change in order to support the new component. also, of course, there is javascript code that needs to be changed to fit with the changes made to the HTML..
Of course, if this component was completely "isolated" and had just it's own CSS, javascript and html template file, it was much much easier, but it does require changes to things around it, to the HTML/CSS/JS of the page it resides in.
How can such a complex process be reduced to a simple "feature toggle"?
Also, to bring the complexity to a new level, this new feature might need changes to some library version used in the project, but that's a whole other level of difficulty when toggling features.. but lets ignore this part on the discussion because I am more interested on the matter mentioned above.

I came up with the following way:
System is basically made out of:
index.html (basic HTML entry point which everything loads into)
HTML template files
SCSS files
Architecture-related javascript files
javascript controllers (kinda like pages. control page events and which components to use in it)
javascript components (imagine tables, grids, tree menus, breadcrumbs...)
home.html template example:
<div class='col'>
<component class='line-chart'></component>
<component class='table'></component>
</div>
<div class='col'>
<component class='bar-chart'></component>
</div>
Steps I did (Simplified):
Create a way to switch features on/off within the UI:
Create aמ architecture (system/app-related) javascript file which its task is to create a dropdown which from a person could choose which features to toggle, and the result is saved in localstorage.
Append the dropdown to the page.
When a user selects a feature, reload the page and after refresh, read the features from localstorage and save them to the architecture state object, under the property "features", to be used later.
Create a feature: "home-v2"
So, I'm working on the Master branch (like a boss) and I want to create some big changes in some page, and add a few components and move other existing ones around. What I did was:
Copy the SCSS file of the page _home.scss and rename to _feature-home-v2--home.scss (it will be automatically imported via the main.scss using globbing)
Copy the template file of the page home.html and rename to feature-home-v2--home.html
Import the javascript components files which will be used to the page controller javascript file.
Write some if statements
This is the "ugly" part, where I must set what to will be done according to each feature. So, for my new example feature home-v2 I will need to do a few things:
go to the home page javascript controller file and go to the line where I load the HTML template, and check if the app State "features" object for
something like this:
var templateName = `home`;
if( app.state.features['v2--home'] )
templateName = `feature-home-v2--` + templateName;
Now that the page is using a different HTML structure, which can look like similar to the default home page but with more components and some are in different order:
feature-home-v2--home.html template example:
<component class='breadcrumbs'></component>
<div class='col'>
<component class='table'></component>
<component class='line-chart'></component>
</div>
<div class='col'>
<component class='pie-chart'></component>
</div>
I can now load the imported controllers to where they reside (before they might have been imported but weren't initialized on the page).
Thoughts on the process:
Hitting ctrl-p in Sublime and starting to type feature- will show only the feature-related files.
Produce larger output from the build process, and doesn't use different GIT branches per-feature.
Features should be merged quickly/discarded so the code won't get messy with many features.
using all the features on a single-branch allows to quickly adding/removing with ease of a custom dropdown with checkbox/radio.
GIT commits must be remembered to be named according to the feature worked on, to maintain GIT order with sensible names.
For more complex changes, other files might be needed to be cloned and renamed, even top-order controllers themselves.

I think the best way to replicate flags is to just create a JSON file with ids that you want hide. Then just have the Javascript FileReader (https://developer.mozilla.org/en-US/docs/Web/API/FileReader) read in, parse the JSON, and hide the mapped ids that are false.
Lets say your toggable feature were the following input boxes:
<input id="input_box"/>
<input id="input_box2"/>
Your text file would contain this:
{
input_box: false,
input_box2: true
}
input_box would be hidden, while input_box2 would be shown. This seems like the only way to enable flags, unless you want to put it in the URL.

Related

Can I nest an web app in another web app?

At the moment, I need to create an app that will dynamically change it's sections
This is the app layout.
The main section would be an independent webapp, because it would keep changing it's contents.
The nav bar it's basically a set of images that work as buttons and change the contents of the main section.
The side bar have some parallel uses, but it can work with the "main webapp" (the one that contains all sections
That's why I think having a nested webapp would be the best solution. I tried google site but since I can't really control it I dropped the idea.
But it's possibly to achieve that? At the moment the app need to refresh the whole page to apply even the smallest HTML change
Im a little confused, You could have that part dynamically generate information in the main section and everything else be static.
And the web app will update anytime you change the code weather its a small html changes or logic changes. unless its deployed and you dont have sync on, then you need to manually sync it to show the changes.
Update:
I solved my issue stacking divs and changing the active one by hiding the others.
I also using an include with my templates, in a way I can split my HTML code in a main template.
I use two types of includes:
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
And
function includeTemplate(template) {
return HtmlService.createTemplateFromFile(template).evaluate().getContent();
}
one used to include static HTML and other dinamic HTML (templates)

What is the best way to ensure a component's client lib files only load on the page when the component is present?

I'm new to AEM. Currently we have one template for each page on our site. All components have the category "project_name.components" and I am calling the client libs in a header file with:
<sly data-sly-call="${clientLib.css # categories='project_name.components'}" />
<sly data-sly-call="${clientLib.js # categories='project_name.components'}" />
However, I have a breadcrumbs component that isn't on every page, but, as expected, the client libs files for it are showing up regardless and causing some issues with the existing default breadcrumbs's styles/scripts.
I have given the new breadcrumb component a test category name of "project_name.breadcrumbs". Is there a way to use this category name in some type of an if/else statement in the same header file that will only call the breadcrumb client lib files if the breadcrumb has been dragged onto the page?
A few thoughts:
The easiest way is to include the client library as part of the component that uses it rather than including it somewhere else. The downside of this is that the CSS you may want to load early in the HEAD section of a page won't be present until somewhere in the BODY.
If your CSS styling is impacting things it shouldn't, then the CSS styling needs to have sufficient selectors so that it won't break things to which it shouldn't apply. Perhaps you can add a class to the breadcrumbs and make all the styling only be applied to stuff under a tag that has the class. If you changed the CSS this way, it wouldn't negatively affect pages when they don't use the breadcrumb (though it could have a downside of bloating your page footprint if it isn't something that will be loaded and browser cached to be used in the future).
Otherwise, you could add logic that runs at the page level that will examine the node and see which components are included and then add conditional logic to only add the client library when the page is using the component. But that is more back-end work. So you can add the if/else statement as you suggested, but it is up to you to write the code behind it--there is nothing built-in that will conditionally do that check to my knowledge.

How to save and load a page with two angular2 components from local storage?

I have been trying to save and load a page with two angular2 components from local storage with the next code but the css from components is never applied.
This is my code to save:
localStorage.setItem('body', JSON.stringify(document.getElementById("body").innerHTML));
This is my code to load:
document.getElementById("body").innerHTML=JSON.parse(localStorage.getItem("body"));
I hope to have explained my problem well
Sorry, you cannot do that. Angular likes to take over a lot of the DOM, so you cannot just replace the entire body of the DOM. However, if instead of doing the entire "body", you did a subset, then you could do this:
<div [innerHTML]="htmlVar">
</div>
Where htmlVar is a variable you loaded with something like:
this.htmlVar = JSON.parse(localStorage.getItem("htmlVar"))
Watch out, by default innerHTML will strip out lots of "unsafe" html. You can reenable most of them by calling DomSanitizer. Please note that you cannot use any Angular features in the html, like links with routerLink.

How to stop angular merging different pages to make them look the same?

I have a chat website using node js and angular, and I have made the login/signup and chat page using these. but the problem is, whenever I load the chat page it uses the style from the other pages, and basically acts like a different section of the same page, It also merges the login/signup together, which is ok, because they have the same style just different number of form boxes, I want to stop angular from merging the styles from the login/signup with the chat and have it use its own style.
All help would be very much apreciated, thanks in advance.
And as far as I have been told and know, there is nothing in my own code that is preventing this, it is only angular itself. strong textBy the way, As far as I know, certain things the body of the different pages cant be individually styled, and If I were to merge html's it would take a while and research and I dont really want to do so.
The idea of loading pages as partials is not loading its css and js files etc.
You need to have only one file as index.html and inside,
define <ui-view> tag this is where you have to load all your partials to, but not an entire page, having html tags and everything.
Take a look at this pattern to load all your partials into one file.
and then,
I highly recommend you check this web site out to set nodejs to set all the missing routes to your html file as well as defining your "/css", "/js" etc.
I have just merged these two working methods to make a very concrete restful application structure.
All you have to do to avoid this problem is to write your css with starting parent class. In this way your css will work only if you have parent element with specific class.
.signIn .button {
}
.chat .button {
}
Write it like this and the button in different elements will have different style

Having same <div> on all my sites

I want to create a site like any other. I want the "thing" at the top (home downloads and stuff) to be on all my pages. Do I need to copy and paste the same code over and over again?
put the common part in your header/some specific file and use ,since you will be using header/some specific file on all pages so the desired content will also be loaded.
Learn Psd to html conversion For batter understanding the divs and styles modification and customization.. your divs and tags can be easily maintained with your stylesheet by giving id and classes you can also give one dive multiple classes and ids,
you are talking about master page i think
that is one in style and in that page you're showing other page, likely we can say one template page and many functionality see this and
see this
As far as I'm concerned pretty much all the intelligent options for solving this problem are mentioned in this question
Use a server-side template (e.g.php), use a client-side template (e.g. handlebars), use javascript, or you could use a static site generator like Jekyll.

Categories