Return to Jive Software

Jivespace Community Blog

7 Posts tagged with the widget tag

Out with the old

 

old_open_cases_widget.png

 

In the past, when a customer wanted to check on the status of any of their open cases they would log into their secure space overview page and use the Community Open Cases widget. This widget was designed with a very simple goal in mind, just display the open cases with a bit of extra information and an emphasis on Severity 1 issues. This proved useful for quite some time and gave customers a good overview of what was going on with their community from a support perspective.

 

However, there was one major flaw. Customers had no way of interacting with this information and often found it very difficult to organize this data in a manner that they could use quickly and efficiently. Welcome, open cases widget 2.0!

 

 

 

 

The new and improved open cases widget

 

new_open_cases_widget.png

 

Along with our upgrade of the Supportal to SBS 3.0, I took on the job of updating this widget to provide customers with better control over their open cases. There are two major upgrades that I gave this widget which have enhanced the way people use it:

 

1. Cases broken down by Severity

 

Instead of displaying all the open cases in a potentially enormous group, I've broken down the display into 3 distinctive parts. This is especially helpful for customers with more than 10+ open support cases at a time and allows customers to quickly see if they have any Level 1 issues that they need to attend to quickly.

 

2. New case option available: Priority

 

To the right of every case status is a set of up and down buttons which control the individual priority of every issue (within their respective severity).

 

 

 

 

 

Okay great, so how do I use it?

 

Step 1: Log in

 

Log into the Supportal and visit your Company's secure space "Overview" tab

 

overview.png

 

Step 2: Organize open cases

 

Browse through any open cases and use the "move up/move down" buttons to re-order them. All the moving on the screen will be done in real-time thanks to our good old friend Javascript. You may recognize these buttons from SBS, as they are used to control the location of profile fields on the admin console registration settings page.

 

priority_control.png

 

Step 3: Don't forget to Save!

 

As of right now, your cases will be in the order you want on the overview page, but there is one final step. You will need to click the Save Settings button at the bottom right hand corner of the widget. This will take the current ordering of your widget and persist the case priorities to the database.

 

save_settings.png

 

You will receive a friendly notification at the top of the widget that your Priority changes have been successfully saved, and you are done!

 

settings_saved.png

 

 

 

Well that's easy enough, how does it all work?

 

I'm glad you asked--it's really quite simple.

 

 

Displaying the widget

 

First off, the widget loads up all the non-closed cases within a secure space and puts them into three different Collections (one for each severity):

 

for (String caseID : caseIDs) {
    try {
        SupportCase supportCase = supportCaseManager.getSupportCase(Long.parseLong(caseID));
        String status = supportCase.getStatus();
        if (status != null && !caseStatusManager.isClosedStatus(status)) {
            String severity = supportCase.getSeverity();
            String priority = supportCase.getPriority();
            supportCase.setPriority(priority != null ? priority : "0");
 
            if(severity.equals("Level 1")) {
                openSev1Cases.add(supportCase);
                Collections.sort(openSev1Cases, new CaseComparator());
            }
            else if(severity.equals("Level 2")) {
                openSev2Cases.add(supportCase);
                Collections.sort(openSev2Cases, new CaseComparator());
            }
            else {
                openSev3Cases.add(supportCase);
                Collections.sort(openSev3Cases, new CaseComparator());
            }
        }
    }
    catch (NotFoundException e) {
        log.error("Could not retreive support case in OpenCasesWidget: " + e.getMessage());
    }
}

(Ideally this will get refactored soon to allow for more or less than 3 severities instead of being hard-coded. But it will work for now.)

 

 

The CaseComparator() orders all the currently open cases by their priority in the database. If nothing has yet been set, it will be put in the order that the cases were created.

 

 

The fancy effects

 

The cases are now sent to the template, where they are displayed in their respective severity grouping and automatically hooked into the Javascript functions that allow the up/down buttons to work. When you click on one of the buttons the following Javascript magic happens:

 

1. References to the required objects on the screen are loaded up using Javascript:

 

var moveUp = function(e, type) {
    Event.stop(e);
    var ansc = this.up(".case-field");
    if(ansc != undefined) {
        ansc.previous().insert({before: ansc});
        updateHiddenField(ansc, ansc.next());
    }
    updateOrderingAnchors(type);
}

 

2. A hidden priority field for each case is updated with the new ordering value:

 

var updateHiddenField = function(element, newElement) {
    var temp = element.select(".case-priority")[0].value;
    element.select(".case-priority")[0].value = newElement.select(".case-priority")[0].value;
    newElement.select(".case-priority")[0].value = temp;
}

 

3. The ordering of the case above (or below if the down arrow was pressed) will be swapped on screen and the list rebuilt:

 

var updateOrderingAnchors = function(type) {
    if(type == "1") {
        var elms = $("sev1-case-list-body").select("tr");
    }else if(type == "2") {
        var elms = $("sev2-case-list-body").select("tr");
    }else{
        var elms = $("sev3-case-list-body").select("tr");
    }
    elms.each(function(tr, i) {
        var anchors = tr.select(".field-moveup")[0];
        if (i <= 0) {
            anchors.update("<span class='move-up-disabled'>move up</span>");
        }
        else {
            anchors.update(new Element("a", {"class": "anchor-move-up", href: "#"}).update("move up"));
        }
        anchors = tr.select(".field-movedown")[0];
        if (i == elms.length - 1) {
            anchors.update("<span class='move-down-disabled'>move down</span>");
        }
        else {
            anchors.update(new Element("a", {"class": "anchor-move-down", href: "#"}).update("move down"));
        }
    });
    bindAnchors();
}

 

 

4. Now that the ordering is complete, you click the Save Settings button which makes a call to this Javascript to call a DWR method and display the nice notification at the top of the widget:

 

CasePriorityAction.setPriorities( values, {
    callback:function() {
        $('save-button').enable();
        $('jive-success-box').style.display = "block";
        Effect.Fade($('jive-success-box'),{delay: 3, duration: 5});
    }
});

 

 

 

Saving the data

 

The final step involves saving this to the database, which is done by the call to the setPriorities DWR method as noted above. This loops through all the cases on the screen and sets the priorities in the database accordingly:

 

public void setPriorities(List<String> values) {
    try {
        for(String value : values){
            String[] vars = value.split("-");
            SupportCase supportCase = supportCaseManager.getSupportCase(Long.parseLong(vars[1]));
            supportCase.setPriority(vars[2]);
            
            supportCaseManager.updateSupportCase(supportCase);
        }
    }
    catch (NotFoundException e) {
        log.error("Could not retreive case in CasePriorityAction: " + e.getMessage());
    }
}

 

 

 

I hope this information provides you with interesting insight into how our custom development allows us to work smarter and more efficiently with all our customers.  We want these new features to enrich your Jive experience!

 

As always, Jive welcomes any and all feedback about this feature and the Supportal in general.  Please comment on this post or start a discussion in our Supportal Feedback space.

1,691 Views 3 Comments Permalink Tags: jivespace, customization, support, development, widget, javascript, supportal, sbs

This post is the third in a series of blog posts about customizing for Clearspace 2.x. The previous posts covered general information about Customizations in Clearspace 2.x and upgrading themes and FTL files. This post continues the series with more information about widgets.

 

Widgets can be used much more broadly in version 2 than previously, so most of your widget-specific upgrade changes are related to this broader support. In version 1 a system or space administrator could use widgets only to assemble a space or community overview page. In version 2 both administrators and users can customize page layouts in several areas. Widgets can be used on the Clearspace instance home page (which has been rendered from main.ftl), a user's personal home page, a community/space overview page, a project overview page.

 

Note that unless your widget is extremely simple, you're likely to also need to keep in mind API changes and FreeMarker changes. For example, version 2 requires that widgets acquire references to Clearspace manager beans using Spring. The rest of widget development model  -- artifacts involved, how you deploy them, and so on  -- is unchanged from version 1.

 

When upgrading a widget (or developing a new one on version 2), you use the @WidgetTypeMarker annotation to specify which of the display contexts your widget is allowed in. Deciding which contexts to allow is an important part of your widget's design. For example, you might decide that a widget that takes a very individual-oriented set of property values (such as the Tag widget, which displays content associated with a particular tag) isn't useful in high-level contexts such as the instance or space home pages (where the broad set of people viewing might want views on a large variety of tags).

 

The @WidgetTypeMarker annotation supports values from the WidgetType enumeration. Here's an example that includes all of those values:

 

@WidgetTypeMarker({WidgetType.HOMEPAGE, WidgetType.PERSONALIZEDHOMEPAGE, 
    WidgetType.COMMUNITY, WidgetType.PROJECT})
@PropertyNames("myProperty")
public class MyWidget extends BaseWidget {
    // Implementation code omitted.
}

In order to reduce the tight coupling between the widget views (which are typically built using FreeMarker) and the rest of the Clearspace application, the widget context that was previously populated with a reference to the current context via a JiveContext instance has been modified so that the widget view no longer has access to that instance. That means that you'll need to provide everything that your widget view needs through the properties that the widget interface requires. Typically you'll create a widget class that extends BaseWidget and then you'll override this method:

 

protected Map<String, Object> loadProperties(WidgetContext widgetContext, ContainerSize size)

So in the previous version of Clearspace, you might have had something like this in the FTL file that's your widget's view:

 

${widgetContext.jiveContext.communityManager.rootCommunity.ID?c}

Because the JiveContext instance has been removed from the WidgetContext class, you'll need to provide your view with the properties it needs explicitly in your widget. Here's an example:

 

public class MyWidget extends BaseWidget {

    // Declare a property variable and setter for injection by Spring.
    private CommunityManager communityManager;
    public void setCommunityManager(CommunityManager cm) {
        this.communityManager = cm;
    }

    protected Map<String, Object> loadProperties(WidgetContext widgetContext, 
        ContainerSize size)
    {
        Map<String, Object> properties = super.loadProperties(widgetContext, size);
        // Implementation code omitted.
        properties.put("rootCommunityID", communityManager.getRootCommunity().getID());
        return properties;
    }
}

Finally, because you can create a widget that exists in multiple parts of the application (the homepage, a personalized homepage, a community, a project), you'll sometimes want to change the behavior of your widget based on where the widget is being rendered. You can determine the render context of your widget by checking the type of the WidgetContext class that you're given in the loadProperties method. Here's some example code that shows how you can determine what context the widget is in:

 

public class MyWidget extends BaseWidget {
    protected Map<String, Object> loadProperties(WidgetContext widgetContext, ContainerSize size) {
        Map<String, Object> properties = super.loadProperties(widgetContext, size);
        if (widgetContext.getWidgetType() == WidgetType.COMMUNITY) {
            CommunityWidgetContext cwc = (CommunityWidgetContext)widgetContext;
            // Do something specific for the community
        }
        else if (widgetContext.getWidgetType() == WidgetType.HOMEPAGE) {
            HomepageWidgetContext hwc = (HomepageWidgetContext)widgetContext;
            // Do something specific for the homepage
        } 
        else if (widgetContext.getWidgetType() == WidgetType.PERSONALIZEDHOMEPAGE) {
            PersonalizedHomepageWidgetContext phwc = 
                (PersonalizedHomepageWidgetContext)widgetContext;
            // Do something specific for the personalized homepage    
        }
        else if (widgetContext.getWidgetType() == WidgetType.PROJECT) {
            ProjectWidgetContext wwc = (ProjectWidgetContext)widgetContext;
            // Do something specific for the project
        }
    
        properties.put("rootCommunityID", communityManager.getRootCommunity().getID());
        return properties;
    }
}

 

The information above along with more details can be found in the Upgrading Extensions to 2.0 documentation.

 

You can also watch a video and download a presentation to learn more about how to write new widgets for Clearspace 2.0 from Aaron Johnson, Engineering Manager at Jive.

 

 

1,666 Views 0 Comments Permalink Tags: clearspace, widget, widget, widgets, 2.0

Learn all about how to write new widgets for Clearspace 2.0 from Aaron Johnson, Engineering Manager at Jive.

 

 

You can also download the Quicktime version (Caution: file is ~285MB), or you can watch a larger version online, which will improve readability of embedded screenshots (recommended).

 

The entire presentation is also attached below as a PDF file.

 

You can also watch an earlier video about developing widgets for Clearspace 2.0

1,435 Views 0 Comments Permalink Tags: plugin, jivespace, jivespace, podcast, video, clearspace, widget, 2.0

Samee from SourceN just published a new widget that can be used to add an expandable tree view of communities to any customized space. The Community Navigation Widget was created at the request of another community member, Eric Tufts who wanted to replicate the functionality of the browse drop-down menu embedded in a space.

 

Please try it out and provide feedback in the comments area of the plugin.

 

Don't forget that we have many more plugins and widgets available for download on the Plugins page.

1,114 Views 0 Comments Permalink Tags: plugin, widget, navigation, sourcen, sourcen

We've had requests for Calendar functionality in Clearspace, but so far, we haven't had an easy way to add a Calendar. Now, with Jive's recent Jotlet.net acquisition, we have a way for people to add calendars to Clearspace customized space pages with the Jotlet.net Calendar Plugin!

 

This simple Jotlet.net Calendar Widget is a plugin that contains a widget that lets you show and edit any or all of your Jotlet.net calendars on your Clearspace community, homepage, or project pages.

 

Or if you just want to see how Adam Wulf created this widget, you can find the source code in our svn repository. You can also find the Jotlet.net Calendar widget and more plugins for Clearspace in Plugin Downloads

1,425 Views 5 Comments Permalink Tags: plugin, clearspace, widget, widget, 2.0, jotlet

I took the best 6 minutes out of a presentation that Fred Brock of Jive Software delivered to our engineering teams to teach all of us about the best ways to develop widgets for Clearspace 2.0. This is a must-see for anyone wanting to write widgets for Clearspace 2.0! I've also attached a PDF version of the slides from Fred's presentation.

 

 

Or you can download the Quicktime movie (Caution: ~85MB file)

2,122 Views 1 Comments Permalink Tags: jivespace, podcast, video, video, clearspace, beta, widget

Watch this video to learn more about how Rick Palmer from Jive Software created a widget for Clearspace to display more information about users. You can also get more information about the User Stats Widget Plugin, download it, or view the source code on Jivespace.<br><br>

 

 

 

Or you can download the Quicktime version (Caution! ~250 MB file!)

1,054 Views 0 Comments Permalink Tags: podcast, video, clearspace, plugins, plugins, widget


Actions

Incoming Links