Custom Client UI Dashboard - HTML+JS+JSON

Hi,

I’m working on a Self-Service project for my company and I’m playing with the options.
I decided to try and create a dashboard that will show the version\status of installed security software\apps on the machine.
In-order to provide the information and make this dashboard also agile I decided to include HTML+JS+JSON.
The JSON file will contain the apps name, relevance, and an icon\pic. for example:
{
“applications”: [
{
“name”: “Symantec WSS”,
“relevance”: “version of file “C:\Program Files\Symantec\WSS Agent\wssad.exe””,
“icon_path”: “wss.ico”
},
{
“name”: “Defender”,
“relevance”: “version of file “C:\Program Files\Windows Defender Advanced Threat Protection\MsSense.exe””,
“icon_path”: “Defender.ico”
}
]
}

The problem is that there is something wrong with the relevance in a way that I cannot understand.
Although the relevance prints correctly when I past it as is, it gets an error when I’m using the <?relevance ... ?> for it to be queried:

But without the <?relevance ... ?> it actually provides the correct syntax (for example: version of file “C:\Program Files\Symantec\WSS Agent\wssad.exe”) and I cannot understand what is wrong.

Full Disclosure - I’m working on it using a paid account for ChatGPT.

Does anyone know how to assist me on that field?

Dashboards use “session relevance”, not “client relevance” and are evaluated essentially by Web Reports in the background, not directly against any agents. If you want to build a dashboard with this data then you need to have properties that have this info and then you write the session relevance to query those - for example: values of results (bes computers whose (name of computer of it = “MyComputer”), bes properties whose (name of it = “MyProperty”))

Hi,
Thank you for the information, but you are wrong.
Please refer the following link: https://help.hcltechsw.com/bigfix/10.0/platform/Platform/Config/c_creating_client_dashboards.html

Apologies, I misread the title and assumed you meant Console dashboards… Never used Client Dashboards I am afraid but if I had to venture a guess it would be how to call the relevance evaluation. The <?relevance ?> tag is supposed to do that but it is making it hardcoded essentially and it may not play well with other languages, what you need is probably some JS-equivalent way to call the evaluation. In WR/Console Dashboards there is one that works just fine (see example below - you will notice I pass java variables and form options to the session relevance query dynamically), see if it works for you as well:

var relevance = '(html "<table id=%22resultsTable%22 class=%22sortable%22><tr><th>Computer</th><th>Operating <br> System</th><th>IP Address</th><th>Last Report Time</th><th>Uptime</th><th>Reboot Needed</th><th>Critical Patch Reboot Needed</th><th>Compliance (%25)</th><th>Applicable Components</th><th>Installed and Patched</th><th>Still Relevant</th></tr>" & it & html "</table>") of concatenations of trs of (td of item 0 of it & td of item 1 of it & td of item 2 of it & td of(item 3 of it as string) & td of (item 6 of it as string) & td of (item 8 of it as string) & td of (concatenation (html "<br/>") of (substrings separated by "||" of item 7 of it as string)) & td "align=right" of (if (item 4 of it = 0) then ("100") else (if ((((item 5 of it as floating point / item 4 of it as floating point) * 100) as string) starts with "NaN") then("0") else ((((item 4 of it - item 5 of it) as floating point / item 4 of it as floating point) * 100) as string)) ) & td "align=right"  of(item 4 of it as string) & td "align=right" of ((item 4 of it - item 5 of it) as string) & td "align=right"  of (item 5 of it as string)) of ((if(exists link of it) then(link of it) else (html "<none>")), (if (exists operating system of it) then (operating system of it) else ("<unknown>")), (if (exists ip addresses of it) then (concatenation (html "<br/>") of (ip addresses of it as string)) else (html " ")), ((year of it as string & "/" & month of it as two digits & "/" & day_of_month of it as two digits) of  date(local time zone) of it & " "& (two digit hour of it as string & ":" & two digit minute of it as string & ":" & two digit second of it as string) of time (local time zone) of it) of last report time of it, number of results from (source fixlets whose (name of it != "Remove Approval") of components whose (include in relevance flag of it) of component groups of bes fixlets whose (baseline flag of it = true and (' + baselineName.options[baselineName.selectedIndex].value  + '))) whose (exists first became relevant of it) of it, number of results from (source fixlets whose (name of it != "MGTI - PROD - ALL - Remove Approval") of components whose (include in relevance flag of it) of component groups of bes fixlets whose (baseline flag of it = true and (' + baselineName.options[baselineName.selectedIndex].value  + '))) whose (relevant flag of it = true) of it, values of results (it,bes properties whose (name of it  ="Uptime")), concatenation "||" of values of results (it,bes properties whose (name of it  ="Critical Patch Reboot Required")), values of results (it,bes properties whose (name of it  ="Reboot Needed"))) of' + computerFilter;

//alert(relevance);
strResponse = EvaluateRelevance(relevance);
divRes.innerHTML = strResponse2 + strResponse;

Thank you for your comment.
I’m not sure how to implement this method into my project, do you see a way that you can lead me to it?

I am not entirely sure what your intention is to comment further. What is the output format you desire from the dashboard? As I said, I haven’t worked with Client Dashboards, so not much hands on experience and not 100% sure if what you intend is achievable. If not creating BigFix action to output the data to format you need should be easily doable too.

You may need to dig in to the details about how the relevance and the HTML are rendered. Without knowing your implementation details, I can tell you it’s possible - I’ve built SSA Client Dashboards that use JavaScript and dataTables.

When the SSA is rendered, the original dashboard (under the BES Client\__UISupport directory) is evaluated by the BES Client and all of the <? relevance ?> tags are substituted in (this runs as LocalSystem, and no JavaScriot runs at this point).

Then the resulting HTML files are copied to a per-user directory (under the users App data or Temp folder, I don’t recall which).

When the SSA is displayed and the JavaScript loads, it’s running under the users account, it’s no longer LocalSystem and the relevance tags are no longer present, having already been replaced with static values by the client.

You’d need to ensure the user can access the JSON file (permissions) and that the JavaScript can locate the JSON (could have a relative path problem since the HTML has been relocated to the user profile at that point).

Thank you for your comment :slight_smile:

I will try to explain further:
MY data.json:

{
    "applications": [
        {
            "name": "Symantec WSS",
            "relevance": "version of file \"C:\\Program Files\\Symantec\\WSS Agent\\wssad.exe\"",
            "icon_path": "wss.ico"
        },
        {
            "name": "Defender",
            "relevance": "version of file \"C:\\Program Files\\Windows Defender Advanced Threat Protection\\MsSense.exe\"",
            "icon_path": "Defender.ico"
        }
    ]
}

The JS part from my _dashboard.html:

<script>
    // Fetch data from data.json and display it
    fetch('data.json')
        .then(response => response.json())
        .then(data => {
            let container = document.getElementById("apps-container");
            
            data.applications.forEach(app => {
                // Create a card for each application
                let appCard = document.createElement("div");
                appCard.className = "app-card";
                
                // Application icon
                let appIcon = document.createElement("img");
                appIcon.className = "app-icon";
                appIcon.src = app.icon_path;
                appCard.appendChild(appIcon);
                
                // Application name
                let appName = document.createElement("h3");
                appName.textContent = app.name;
                appCard.appendChild(appName);
                
                // Application relevance
                let appRelevance = document.createElement("p");
                appRelevance.innerHTML = '<?relevance ' + app.relevance + ' ?>';
                appCard.appendChild(appRelevance);
                
                // Append the app card to the container
                container.appendChild(appCard);
            });
        });
</script>

the results:


The error indicates that the HTML is catching the tag and BigFix is trying to query the relevance -Am I wrong?

I’ve tested in many ways to see what can cause this and I cannot understand:
I tried to change the relevance to now instead of something that might handle char escape - didn’t work but probably not related to char escape.
I tried to move the relevance tags to the JSON and so the JavaScript pulls all the tags with the relevance from the JSON - nothing.
I wrote the tags+relevance in the script instead of pulling from the JSON [for example: appRelevance.innerHTML = ‘<?relevance now ?>’;] - it worked, but you can understand in how many ways this cannot be done this way.
I asked GPT to simulates the html’s results and it provided with the correct way to print the tags + relevance.
This is very strange for me!!

Hm. I wouldn’t expect that to work (the Relevance tags should, I think, be evaluated before the JavaScript supplies values), but… at minimum the JSON format doesn’t seem correct. The literal doublequotes in the filepath have to be escaped in JSON as '\" and the literal backquotes have to be escaped as \\

Ah, ok, so that was the Forum formatting that interfered. I’ll put your code into code tags above - but the original problem remains that Relevance tags are evaluated before JavaScript.

@JasonWalker, is there EvaluateRelevance(“some relevance”) relevance available in the Client Dashboards, just like there is one if we create Console Dashboard or Custom Web Report? That may sort the order of things.

I’m not sure what you mean by that…
can you share an example?

I was looking for that but haven’t found anything yet

I think you have the example right now - check the rendered HTML source, in either __UICache or the per-user file. I expect the relevance tags are not evaluating properly because relevance runs before JavaScript, so those elements don’t exist until the JavaScript runs and creates them.

Basically I don’t know a way to make that approach work - I think you’ll need to build out all the data, in the HTML. I don’t think you’ll be able to evaluate relevance statements after the JavaScript runs, and I don’t see a way yet to render relevance dynamically (in server Dashboards and wizards we have JavaScript Relevance() and EvaluateRelevance() functions, supplied in wizards.js, but I don’t think the SSA has that)

1 Like

I appreciate that, thank you.
I will change the approach.