Home Community Uploads
image

Cireson Partners, Customers and Community members share your customizations and examples here to help benefit the community as a whole to earn Kudos and badges.

DISCLAIMER

All files and projects located here are provided and come "as-is" and without any warranty or support. Use at your own risk. Your use of Community Uploads is subject to our Terms of Use.

Cireson does not and will not support or maintain these enhancements, extensions, and scripts.

For Team Cireson uploads click here.

Active Work Items badges on menu items

13

Comments

  • Mina_SaidiMina_Saidi Customer IT Monkey ✭

    Hi All,

    Thank for this. I have set this up in our dev environment and I was wondering if its possible to show you when work items have been updated, e.g. status, comments added? at the moment it seems to only show me total work items in team view, unassigned work items in team view, my request and my work. it doesn't tell me when my work items/my requests have been updated as in comments added or status changed?

    any ideas? or have I done something wrong?

  • Gerhard_GoossensGerhard_Goossens Customer Advanced IT Monkey ✭✭✭

    Hi All,

    Thank for this. I have set this up in our dev environment and I was wondering if its possible to show you when work items have been updated, e.g. status, comments added? at the moment it seems to only show me total work items in team view, unassigned work items in team view, my request and my work. it doesn't tell me when my work items/my requests have been updated as in comments added or status changed?

    any ideas? or have I done something wrong?

    I just came out of a meeting where this was discussed. 
  • Gerhard_GoossensGerhard_Goossens Customer Advanced IT Monkey ✭✭✭
    I changed the code a bit to only show the badges on My Work and Team Work.
    Our analysts are trying to be very productive and open up to 20 tabs that create a lot of noise on the DB.

    So it just wrapped the code that generates the badge in an if statement to check if they are on My Work or Team Work :-)

    if (window.location.href.indexOf("f94d43eb-eb42-4957-8c48-95b9b903c631") > -1 || window.location.href.indexOf("cca5abda-6803-4833-accd-d59a43e2d2cf") > -1) {<br>		var badgeObserver = new MutationObserver(function (mutations) {<br>			var targetElement = $('#side_nav');<br>			if (targetElement.length > 0) {<br>				ApplyStyleSheetBadge(); // Add CSS<br>				createBadges(); // This will run on page load<br>				setInterval(function () {<br>					loadBadges() // this will run after every 60 seconds<br>				}, 120000);<br>				badgeObserver.disconnect();<br>			}<br>		});<br>	}<br><div></div>

  • Ryan_LaneRyan_Lane Cireson Support Advanced IT Monkey ✭✭✭
    Hi @Gerhard_Goossens
    To work with productive users and their multiple tabs I would suggest looking into using session storage to share badge count data between open tabs/windows on a single client.  The portal already uses the store plugin accessed via app.storage to handle sharing session data between page loads and tabs for navigation, grid states, view panels and quite a few other features.
    In my case I primarily use store for handing debug state and custom data between page loads:
    // Get custom session storage.
    app.storage.custom = store.namespace('custom');
    
    // Check if custom session storage value 'DEBUG_ENABLED' is true.<br>if (app.storage.custom('DEBUG_ENABLED')) {
      // Debug Code Here 
    }
    
    // Enable DEBUG Mode via Console/Script/Plugin
    // app.storage.custom.set('DEBUG_ENABLED', true);
    
    // Disable DEBUG Mode via Console/Script/Plugin
    // app.storage.custom.set('DEBUG_ENABLED', false); 
    Making this session data useful for a multiple tab, asynchronous setup is a bit more involved then just adding a check during run-time so we're going to look at adding a listener to each window to monitor and process changes.  Fortunately, whenever store is used there is a storage event that we can subscribe to.
    Here's some example code to monitor for and set session data changes via the storage event:
    /*
     * Add listener for <b>storage </b>event in all tabs.
     */
    $(window).on('storage', function (event) {
      if (event.key === 'custom.BadgeContent') {
        // Update Badge Content Here
        console.log('BadgeContent Updated', {
          oldValue: event.originalEvent.oldValue,
          newValue: event.originalEvent.newValue,
        });
      }
    });
    
    /*
     * Set custom session value in tab.
     * <b>storage </b>event will trigger in all tabs except originating tab.
     */ 
    app.storage.custom.set('BadgeContent', {test: performance.now()} );
    
    Here's the code in action with two separate windows passing data to each other:
    Initial event subscription using $.on() in both left and right windows:

    From there we call set in the left window which triggers the storage event in the right window:

    Continuing we call set in the right window which triggers the storage event in the left window:


    From this point it's a matter of organizing how each tab will know that the data needs to be refreshed and when.  I think something like a LastModified timestamp and PendingUpdate timestamp to track how old the current badge data is and if another tab is potentially retrieving the data would be a good start.
    The pseudo workflow for intervals would be:
    Set 60 second interval for checking <b>LastModified </b>session value.<br>On interval elapsed check if <b>LastModified </b>is older than timeout value (~60 seconds).<br>&nbsp; If true then:<br>&nbsp; &nbsp; Check if <b>PendingUpdate</b> is older than pending timeout value (~2 seconds or average max query duration) to account for closed tabs/windows.<br>&nbsp; &nbsp; &nbsp; If true then:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Set <b>PendingUpdate</b> timestamp and retrieve data in current tab.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Once data is returned:
                Set <b>LastModified</b> timestamp.
                Update badge count displays in current tab.
                Update session data to trigger <b>storage</b> listeners in other tabs.<br>&nbsp; &nbsp; &nbsp; If false then:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Do nothing and wait for next 60 second interval to elapse.<br>&nbsp; If false then:<br>&nbsp; &nbsp; Do nothing and wait for next 60 second interval to elapse.
    Note With this there will be a little bit of play depending on when the secondary tab(s) load that could account for a small range of waiting between refreshes in secondary tabs.  Checking immediately for stored data on page load and then performing the interval may resolve this issue.
    Additional Note Checking to see if window/tab is currently active could also help in determining when and which tabs should refresh their badge counts.

    Hopefully this was helpful as an idea for handling the increased traffic.  Please let me know if you have any questions.  I'd be glad to help!
  • Steve_ClarkeSteve_Clarke Customer Adept IT Monkey ✭✭
    edited March 2019
    Hey guys,

    I have created a new view for unassigned requests based off of a saved search. I am not sure how to reference this saved search in the following code, particularly the highlighted line which I believe would need to get the search result count.

    if(myRequests) {
    $.getJSON('/api/V3/WorkItem/GetGridWorkItemsMyRequests', { "userId": session.user.Id,"showInactiveItems": false }, function (data) {var badge = $('a[href="/Page/4534db6e-462d-4676-88c9-f684c19eb3ce"] .menu-badge');if (data.length > 0) {badge.removeClass('no-badge');badge.text(data.length);} else {badge.addClass('no-badge');badge.text('');}});}



    If anyone could provide some assistance that would be awesome.

    Thanks,

    Steve
  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    You are correct, you need to point to a different endpoint for your saved search.  You'll have to try this out, but I'll try to point you in the right direction.

    On a saved search page, the grid itself calls
    <b>/search/GetAdHocResults?dataTable="WorkItem"&filterCriteria=</b><<huge JSON object representing your search criteria>><br>

    If you want to grab the particular filter for your particular search, go to the saved search page for your unassigned requests, and in the browser console, type 
    var grid = $($('div.grid-container')[0]).data('kendoGrid'); var filterCriteria =&nbsp;grid.dataSource.options.transport.read.data.filterCriteria;<br>
    Just copy the value of filterCriteria to the clipboard.

    Then you can modify your code above to something like:
    if(myRequests) {
    $.getJSON('/search/GetAdHocResults', { "dataTable": "WorkItem", "filterCriteria": << PASTE YOUR CRITERIA HERE, IN QUOTES >> }, function (data) { var badge = $('a[href="/Page/4534db6e-462d-4676-88c9-f684c19eb3ce"] .menu-badge'); if (data.length > 0) { badge.removeClass('no-badge'); badge.text(data.length); } else { badge.addClass('no-badge'); badge.text(''); } }); }

  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    @Ryan_Lane, I have tried out your idea.  I've had some trouble carving out time to really dig in and measure it, but at a quick glance at least, I think it is working!
  • Steve_ClarkeSteve_Clarke Customer Adept IT Monkey ✭✭
    Thanks @Tom_Hendricks. I am still struggling to get it working but thank you for the starting point.
  • Tom_HendricksTom_Hendricks Customer Super IT Monkey ✭✭✭✭✭
    This is the part I haven't had time to look at, but I wonder if it might be causing you issues--I'm not sure if the results from saved searches are coming back in a single JSON object, or from many.  I say that only because of all the network traffic that occurs with a saved search grid vs a SQL or OData grid.  What I pulled in my example is from the DataSource on the Kendo grid, but there might be more going on here in addition.  

    At some point, I would probably say that re-writing this as a SQL query would be much easier, but I also kind of want to see how this could work.  :)
  • Steve_ClarkeSteve_Clarke Customer Adept IT Monkey ✭✭
    Thanks for your help @Tom_Hendricks. Funny you should say about the SQL query because that is exactly what I did on Friday. Ended up getting it working that way which was much easier in the end, and probably a bit cleaner.

    Thanks again for jumping in and providing your thoughts/assistance  :)
  • Gerhard_GoossensGerhard_Goossens Customer Advanced IT Monkey ✭✭✭
    @Brett_Moffett WOW, this is awesome. Thank you for the commitment to make this awesome addon even better. 
  • Mark_GearyMark_Geary Customer IT Monkey ✭
    HI I use this but I cant get it to work on the Active work as we have changed the name of ours to It department work list. What do I need to change to with this?
  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭
    You will need to grab the view's GUID (In the URL of the page) and replace it in the JS code.
    The code is fairly well documented so you should see where to replace it.
    Let me know if you need a hand and we can work through it here on the community.
  • Mark_GearyMark_Geary Customer IT Monkey ✭
    Hi I have put the GUID from the URL in the one area in the JS and in the SQL as well for the active work Items but it still is not showing works on the rest.
  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭

    Hello all.

    New version.

    Version 1.2.1

    1. You can now configure the number of days a Work Item is not modified for before it shows up on the Stale Work Item count.

    You can get the latest version at the GitHub repository:

    https://github.com/BrettMoff/CiresonBadges
    


    Future Features:

    • Disable\Enable Count badge (Not sure this is a particularly useful badge)
    • Setting for refresh time


  • Matt_OvertonMatt_Overton Customer Adept IT Monkey ✭✭

    Thanks for this @Brett_Moffett !


    I'm having a similar issue to @Mark_Geary where I can't seem to get it to work for the pages that have different GUIDs. I've copied the GUIDs for My Work, My Requests and Active Work into the JS in the relevant places, but no joy - the badges simply aren't appearing on any of them.

    I can only get it to work for the Team icons and Watch List. What could I be doing wrong?

  • Ryan_Kennedy1Ryan_Kennedy1 Customer IT Monkey ✭
    edited January 2020

    Nice Work @Martin_Blomgren / @Brett_Moffett .

    I was noticing that the blue badge for the Work Item Count in My Work wasn't matching the total number of work items in that view as it wasn't counting work items where the user was the Primary Owner.

    I fixed it by modifying the ' Test_BadgestMyWorkQuery.sql ' file from this :

    where ( WorkItem.AssignedUserId = @UserId --@UserId is a special Cireson token for the logged-in user GUID.

    OR ReviewObjects.ReviewerId = @UserId)


    To this :

    where ( WorkItem.AssignedUserId = @UserId --@UserId is a special Cireson token for the logged-in user GUID.

    OR ReviewObjects.ReviewerId = @UserId OR WorkItem.PrimaryOwnerId = @UserId)

  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭

    Update the GitHub repository and we can check it in for everyone else. :)

    Nice work.

  • Ryan_Kennedy1Ryan_Kennedy1 Customer IT Monkey ✭

    No worries, done

  • Jacky_GrossJacky_Gross Customer Adept IT Monkey ✭✭

    Hello all,

    After upgrading the Cireson portal to version 11.2.3.2016, this customizatiion no longer works.

    Do you have any news to solve this?

    Thanks

  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭

    Hi @Jacky_Gross

    I've not tested it on the latest version in my lab. I'll test it tomorrow and try to see if I can find the issue. My guess is a HTML tag isn't explicitly closed and therefore is not being displayed correctly.

    As soon as I have any answers I will post back here.


    Thanks

    Brett

  • Jacky_GrossJacky_Gross Customer Adept IT Monkey ✭✭

    We can see this error :

    It could be that the Cireson API changed ?

  • Richard_TerpstrRichard_Terpstr Customer IT Monkey ✭
    edited April 2022


    Was there more information about this? We are using version 11.3.0.2016 and i can't get it working.

    Thanks and thank you for this great customization

  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭

    Hi @Richard_Terpstr and @Jacky_Gross I'm very sorry for the late reply, I've been away and buried in many other things.

    I took a look at this in my lab and it is working OK.

    I've also installed it in a customers environment last week and it is working fine there also in the latest version of the portal.

    I'm not sure if during an upgrade the views or custom data sets may have been removed from the database... I think it might be worth re-running the SQL queries in your environment that you first ran. The UniqueID will need to be the same as the one you generated and used the first time round so be careful of that. If you ran the code directly from the GitHub repo then those values have not changed.

    If your company has Cireson+ level support, feel free to log a support ticket for this one as it will be covered by the higher level of support.

    Looking forward to hearing from you and hopefully get this working again for you.


    Brett

  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭
    edited September 2022

    Hello all.

    I came across a scenario that the views a customer was using was renamed from "Active Work" to "All Work" and the code needed to be updated to accommodate.

    Instead, I decided to open the code and add some new settings that would allow admins to set the name of the default views to ensure it is easy to change these as needed.

    v1.3 introduces these new settings as well as allowing for logging in to the console browser and more code comments.

    https://github.com/BrettMoff/CiresonBadges/releases/

  • Andrew_ReiterAndrew_Reiter Customer IT Monkey ✭

    Brett, thank you for your work on updating this enhancement! We use it in our environment for keeping tabs on unassigned work items. It used to pick up manual activities that did not have an implementor, but that doesn't seem to work anymore in recent versions of the portal and/or enhancement. Is that something you are familiar with?

  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭

    Hi @Andrew_Reiter

    I have changed the code in recent versions to use oData source rather than SQL queries where possible.

    While there are still some SQL queries, I think the ones you are referenceing are using oData API calls.

    Badges for Team Work and Team Requests use the following calls:

    "/api/V3/WorkItem/GetMyTeamRequest?userId=" + session.user.Id + "&showInactiveItems=false&isScoped=false"
    "/api/V3/WorkItem/GetGridWorkItemsMyGroups?userId=" + session.user.Id + "&isScoped=false&showActivities=false&showInactiveItems=false"
    

    As you can see, there are values for "showActivities=false" and "showInactiveItems=false"

    It would be possible to edit the code and change either line 161 or 177 to set the show activity to true.

    I'll add it as a suggestion to have those values as settings that can be configured in the solution to make it easier to enable\disable in future.

    If you are wanting to see activities on My requests, My Work or Active Work, these all come down to SQL. I would need to create a custom SQL query to enable these. Again, easy enough to do and load them all in, then have the setting choose which one to return. :)

    In the short term, you can edit the SQL query directly in the Portal Admin Settings, and Dashboard Query Settings. Edit the SQL there and it will flow on in to the solution.

    Hope this helps.

  • Andrew_ReiterAndrew_Reiter Customer IT Monkey ✭

    @Brett_Moffett, thanks for your reply. I see what you are referring to in the code and in the dashboard query settings in our test environment. I'll go ahead and try to adjust the code directly for Team Work, which is the main location we relied on this.

  • Brett_MoffettBrett_Moffett Cireson PACE Super IT Monkey ✭✭✭✭✭

    Glad that all makes sense.

    If you have any other ideas, please add any feature requests you would like to see add to this solution to either this thread or directly to the GitHub Repo.

Sign In or Register to comment.