Collaboration Store, Part LXXVII

“Set your goals high, and don’t stop till you get there.”
Bo Jackson

Last time, we started hacking up a copy of the Service Portal page sc_category, beginning with the HTML. Now we need to update the Server script to pull in our data so that we can bring up the widget and see how it looks. For the header portion, we need to pull in data about the store, which we can get from the instance record for the Host instance.

function fetchStoreDetails() {
	var instanceGR = new GlideRecord('x_11556_col_store_member_organization');
	if (instanceGR.get('instance', gs.getProperty('x_11556_col_store.host_instance'))) {
		data.store = {};
		data.store.name = instanceGR.getDisplayValue('name');
		data.store.description = instanceGR.getDisplayValue('description');
		data.store.logo = instanceGR.getValue('logo');
		data.store.sys_id = instanceGR.getUniqueValue();
	}
}

For the apps, we look to the application table. At this point, we just want to pull in all of the data, so we will save any filtering for later in the development process. Right now, we just want to see how our presentation is coming out.

function fetchItemDetails(items) {
	var appGR = new GlideRecord('x_11556_col_store_member_application');
	appGR.query();
	while (appGR.next()) {
		var item = {};
		item.name = appGR.getDisplayValue('name');
		item.short_description = appGR.getDisplayValue('description');
		item.picture = appGR.getValue('logo');
		item.version = appGR.getDisplayValue('current_version');
		item.provider = appGR.getDisplayValue('provider.name');
		item.providerLogo = appGR.provider.getRefRecord().getValue('logo');
		item.sys_id = appGR.getUniqueValue();
		item.hasPrice = false;
		item.page = 'sc_cat_item';
		item.type = appGR.getValue('sys_class_name');
		item.order = 0;
		item.sys_class_name = appGR.getValue('sys_class_name');
		items.push(item);
	}
}

Some of that is still left over from the original widget, but we’ll clean that up later. For now, we just want to get to the point where we can throw this widget on a page and bring it up and see what we have. A lot of the other code from the original can be tossed, but we will need to retain a few things related to the paging, which leaves us with this.

(function() {
	data.items = [];
	data.show_more = false;
	fetchStoreDetails();
	var itemsInPage = options.limit_item || 9;

	data.limit = itemsInPage;
	if (input && input.new_limit) {
		data.limit = input.new_limit;
	}
	if (input && input.items) {
		data.items = input.items.slice();//Copy the input array
	}

	if (input && input.startWindow) {
		data.endWindow = input.endWindow;
	} else {
		data.startWindow = 0;
		data.endWindow = 0;
	}

	fetchItemDetails(data.items);

	if (data.items.length > data.limit) {
		data.show_more = true;
	}

	data.more_msg = gs.getMessage(" Showing {0} items", data.limit);

	function fetchStoreDetails() {
		var instanceGR = new GlideRecord('x_11556_col_store_member_organization');
		if (instanceGR.get('instance', gs.getProperty('x_11556_col_store.host_instance'))) {
			data.store = {};
			data.store.name = instanceGR.getDisplayValue('name');
			data.store.description = instanceGR.getDisplayValue('description');
			data.store.logo = instanceGR.getValue('logo');
			data.store.sys_id = instanceGR.getUniqueValue();
		}
	}

	function fetchItemDetails(items) {
		var appGR = new GlideRecord('x_11556_col_store_member_application');
		appGR.query();
		while (appGR.next()) {
			var item = {};
			item.name = appGR.getDisplayValue('name');
			item.short_description = appGR.getDisplayValue('description');
			item.picture = appGR.getValue('logo');
			item.version = appGR.getDisplayValue('current_version');
			item.provider = appGR.getDisplayValue('provider.name');
			item.providerLogo = appGR.provider.getRefRecord().getValue('logo');
			item.sys_id = appGR.getUniqueValue();
			item.hasPrice = false;
			item.page = 'sc_cat_item';
			item.type = appGR.getValue('sys_class_name');
			item.order = 0;
			item.sys_class_name = appGR.getValue('sys_class_name');
			items.push(item);
		}
	}

})();

That should be enough to make it work. Now let’s create a page for our widget, call it collaboration_store, and bring it up in the Service Portal Designer. To begin, let’s drag a 3/9 container onto the page.

Dragging a 3/9 container onto the new portal page

Once we have our container in place, let’s find our new widget and drag it into the 9 portion of the 3/9 container.

Dragging our new widget onto the page

Eventually, we will want to come up some kind of search/filter widget for the 3 section of the 3/9 container, but for now we will just leave that empty, save what we have, and pull up the page in the Service Portal to see how things are looking.

First look at our new store layout

Not bad! Of course, we still have a lot of work to do on the Client script to handle things like switching to the alternate view, clicking on a tile, or paging through lengthy results, but the look and feel seems to work so far. I think it might be good to put the logo of the store in the header, but other than that, I do not see any significant changes that I would like to make at this point. I think it actually looks pretty good.

We’ll need to start working on the Client script now, once again stripping out those things related to catalogs and categories, and making sure that the toggle functions still work for switching back and forth between the tiles layout and the table layout. Also, we will need to figure out what we want to do when the operator clicks on an app. We could bring up the details of the application in a modal pop-up, navigate to a detail page, or even go straight into launching an install. That will all end up in the Client script as well.

One thing that we will need to add to the view is the state of the app on the instance, whether it is up to date, needs to be upgraded to the latest version, or has never been installed. The state of the app may determine what happens when you click on the app, so we will need to figure all that out as well. So much to figure out, but still it is a pretty good start. Next time, we will just keep forging ahead unless we have some test results to address.