“Slow, steady progress is better than daily excuses.”
— Robin Sharma
Now that we have managed to create an Update Set from our UI Action, it is time to figure out how to best accomplish the rest of the tasks needed to complete the publication of our Scoped Application to the Host instance. We will need another pop-up window to control the rest of the activities and to report the status to the operator, as the original pop-up went away when the progress bar appeared, and the progress bar goes away once you click on the Done button (an unnecessary click for our purposes, which I would like to avoid at some point, but for now, we will leave it alone and focus on other, more important activities). The next pop-up window should be the last, as it will be a fully custom component and we should be able to control all of the events from this point forward.
Here is what I am thinking at this point: We can create a simple UI that lists all of the steps necessary to complete our objective, and reveal them one at a time as we progress through the work involved. We can have three different icons ahead of each item on the list, one for in progress, one for success, and another for failure, and then show/hide the icons based on the current status of each step in the process. To make that work, we would have to contact the server side for each step along the way, updating the UI on the client side with the status returned from each server call. Once we successfully complete the final step, we can reveal a Done button to close the pop-up.
To find some appropriate icons, I entered image_picker.do in the left-hand navigator to bring up the list of all of the images currently in the /images/ directory of the platform.
I selected the following icons to represent the associated stages for each step:
- In progress: /images/loading_anim4.gif
- Complete: /images/check32.gif
- Error: /images/delete_row.gif
As with many things on the Now Platform, there are many ways in which we can develop a pop-up dialog. I am most comfortable with building Service Portal widgets, and I have used widgets for UI pop-ups before, so that was a tempting way to go. However, the initial pop-up that we customized for our UI Action was a straight UI Page, so I decided that, if I wanted to keep things consistent, I should build this new pop-up the same way. So I cloned our original publish_app_dialog_cs UI Page to create publish_app_dialog_cs_2. Then I went in to our original UI Page and removed this code:
var notification = {"getAttribute": function(name) {return 'true';}};
CustomEvent.fireTop(GlideUI.UI_NOTIFICATION + '.update_set_change', notification);
window.location.href = "sys_update_set.do?sys_id=" + updateSetId;
… which took you to the newly created Update Set when everything was finished, and replaced it with this:
var dialogClass = GlideModal ? GlideModal : GlideDialogWindow;
var dd2 = new dialogClass("x_11556_col_store_publish_app_dialog_cs_2");
dd2.setTitle(new GwtMessage().getMessage('Publish to Collaboration Store'));
dd2.setPreference('sysparm_mbr_app_id', this.mbrAppId);
dd2.setPreference('sysparm_app_sys_id', this.appId);
dd2.setPreference('sysparm_upd_set_id', updateSetId);
dd2.setWidth(500);
dd2.render();
… which now pops up our newly cloned UI Page in a new modal dialog. Now we actually have to build out the page. To begin, as I usually do, I started with the HTML of the presentation layer, which came out like this:
<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="true" xmlns:j="jelly:core" xmlns:g="glide" xmlns:g2="null">
<g2:evaluate jelly="true">
var existingVersions = '';
var mbrAppId = jelly.sysparm_mbr_app_id;
var appSysId = jelly.sysparm_app_sys_id;
var updSetId = jelly.sysparm_upd_set_id;
var appAction = 'Updating';
if (mbrAppId == 'new') {
appAction = 'Creating';
}
</g2:evaluate>
<g:ui_form>
<style type="text/css">
#publish_to_update_set_dialog_container input {
width: 100%;
margin-bottom: 10px;
}
#publish_to_update_set_dialog_container label {
text-align: right;
}
</style>
<div id="publish_to_collaboration_store_dialog_container">
<div class="modal-body">
${gs.getMessage('Completing the process of publishing the application to the Collaboration Store')}
<input id="mbr_app_id" type="hidden" value="$[mbrAppId]"/>
<input id="app_sys_id" type="hidden" value="$[appSysId]"/>
<input id="upd_set_id" type="hidden" value="$[updSetId]"/>
</div>
<div style="padding-left: 50px;">
<div class="row" id="phase_1">
<image id="loading_1" src="/images/loading_anim4.gif" style="width: 16px; height: 16px;"/>
<image id="success_1" src="/images/check32.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<image id="error_1" src="/images/delete_row.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<span style="margin-left: 5px; font-weight:bold;">
Converting Update Set to XML
</span>
</div>
<div class="row" id="phase_2" style="visibility: hidden; display: none;">
<image id="loading_2" src="/images/loading_anim4.gif" style="width: 16px; height: 16px;"/>
<image id="success_2" src="/images/check32.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<image id="error_2" src="/images/delete_row.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<span style="margin-left: 10px; font-weight:bold;">
$[appAction] the Application record
</span>
</div>
<div class="row" id="phase_3" style="visibility: hidden; display: none;">
<image id="loading_3" src="/images/loading_anim4.gif" style="width: 16px; height: 16px;"/>
<image id="success_3" src="/images/check32.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<image id="error_3" src="/images/delete_row.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<span style="margin-left: 10px; font-weight:bold;">
Creating the Version record
</span>
</div>
<div class="row" id="phase_4" style="visibility: hidden; display: none;">
<image id="loading_4" src="/images/loading_anim4.gif" style="width: 16px; height: 16px;"/>
<image id="success_4" src="/images/check32.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<image id="error_4" src="/images/delete_row.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<span style="margin-left: 10px; font-weight:bold;">
Sending the Application record to the Host instance
</span>
</div>
<div class="row" id="phase_5" style="visibility: hidden; display: none;">
<image id="loading_5" src="/images/loading_anim4.gif" style="width: 16px; height: 16px;"/>
<image id="success_5" src="/images/check32.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<image id="error_5" src="/images/delete_row.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<span style="margin-left: 10px; font-weight:bold;">
Sending the Version record to the Host instance
</span>
</div>
<div class="row" id="phase_6" style="visibility: hidden; display: none;">
<image id="loading_6" src="/images/loading_anim4.gif" style="width: 16px; height: 16px;"/>
<image id="success_6" src="/images/check32.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<image id="error_4" src="/images/delete_row.gif" style="width: 16px; height: 16px; visibility: hidden; display: none;"/>
<span style="margin-left: 10px; font-weight:bold;">
Sending the Update Set XML to the Host instance
</span>
</div>
</div>
</div>
</g:ui_form>
</j:jelly>
Basically, it is the same block of code repeated 6 times for the six remaining tasks needed to complete the process. Each item in the list contains a description of the step along with our three icons, only one of which should appear at any given time. Initially, the in progress icon is visible as soon as the step becomes visible, and my plan is to hide that one and reveal one of the other two, depending on how things came out once the step has been completed.
Here is how it looks when it first appears:
That takes care of the easy part. Now we have to put all of the code underneath of the UI to actually do all of the things that need to be done. That’s quite a bit of work, so let’s say we will get started on that next time out.