Appendix B: Frequently asked questions (FAQs)
This topic contains various FAQs to help users quickly get answers to some commonly-asked questions.
Can an external css/js file plus CDN assets be added while creating a widgets?
Certainly! You can add external JavaScript, CSS, and HTML files and CDN assets when creating a widget. To do this, organize the external files (JavaScript, CSS, and HTML) into a custom folder structure in your widget, as follows:
-
Add a custom folder structure in your widget folder. For example:
/app /widgets /myWidget /js - widgetScript.js /css - widgetStyle.css /html - widgetTemplate.html /views - view.html
-
Add the .js files of the external library to the
/jsfolder in the widget folder and then reference the external files in theview.htmlfile of your widget:<!-- Include Widget JavaScript file --> <script src="widgets/installed/mywidget/js/widgetScript.js"></script> <!-- Include Widget CSS file --> <link rel="stylesheet" href="widgets/installed/myWidget/css/widgetStyle.css"> <!-- Include Widget HTML template --> <div ng-include="'widgets/installed/myWidget/html/widgetTemplate.html'"></div>
NOTE: Ensure that you specify the correct path based on your project structure.
Alternatively, if you do not want to add the external JS files, you can load the external JS file using CDN injection (
promise), when a third-party CDN is required. This code waits for the libraries to load before proceeding with the rest of the widget code:function loadJsAsync(jsPath) { var deferred = $q.defer(); var script = document.createElement("script"); script.type = "text/javascript"; script.src = jsPath; script.onload = function () { deferred.resolve(); }; script.onerror = function () { deferred.reject("Failed to load script: " + jsPath); }; document.getElementsByTagName("head")[0].appendChild(script); return deferred.promise; } const scriptsToLoad = [ 'https://unpkg.com/@hpcc-js/wasm@0.3.11/dist/index.min.js', 'https://unpkg.com/d3-graphviz@3.0.5/build/d3-graphviz.js' ]; await $q.all(scriptsToLoad.map(loadJsAsync));Additionally, you can use the timeout function to ensure that the file from CDN will be loaded before rendering the widget functionality:
$timeout(function () { loadJs('https://cdnjs.cloudflare.com/ajax/libs/d3-sankey/0.12.3/d3-sankey.min.js'); fetchData(); }, 1000);In this case, the execution of the widget function is delayed by 1000 ms. The return value of calling
$timeoutis a 'promise' that is resolved when the delay has passed and thetimeoutfunction, if provided, is executed.Reference Widgets: widget-custom-picklist-message and widget-task-management.
How do I make a widget compatible with a supported theme?
To make a widget compatible with a supported theme, use $rootScope.theme to access the current theme in your AngularJS application. Once $rootScope.theme returns the current theme, you can check its value to determine if it is "light," "dark," or "space."
NOTE: When making API calls, refer to the "space" theme as "steel".
var theme = $rootScope.theme;
if (theme.id === "light") {
$scope.cardTilesThemeColor.cardBackgroundColor = "#eeeeee";
} else if (theme.id === "steel") {
$scope.cardTilesThemeColor.cardBackgroundColor = "#29323e";
} else {
$scope.cardTilesThemeColor.cardBackgroundColor = "#262626";
}
Reference Widgets: widget-record-card-tiles, widget-record-summary-card
How do I display a widget on specific pages within FortiSOAR?
The info.json file in a widget, especially in the context of certain web applications or platforms, often serves as a configuration file that provides metadata about the widget. It contains information about the widget's name, description, version and other configuration details.
The pages section in the info.json file specifies the pages or sections where the widget should be visible. The "pages" section in your widget's info.json is a required field containing an array of pages where the widget should be displayed. For example, if you want your widget to be displayed in Dashboards and Reports, you should include them in the "pages" section of your widget's info.json file:
{
"metadata": {
"pages": [
"Dashboard",
"Reports"
],
"certified": "No",
"publisher": "Community",
"compatibility": [
"7.2.0",
"7.0.2"
]
},
"name": "roiCalculator",
"title": "ROI Calculator",
"subTitle": "Uses playbook tags to display an accurate automation ROI",
"version": "1.0.0"
}
Reference Widgets: widget-roi-calculator, widget-record-summary-card
How can I access the module record context for a widget written for the View Panel?
To access the module record context from the View Panel, use $state.params.module to access the module name and $state.params.id to access the record ID. It is common practice to use 'UI-Router' for routing in AngularJS applications.
Modules.get({
module: $state.params.module,
id: $state.params.id
})
Reference Widgets: widget-custom-picklist-message and widget-sla-countdown-timer.
What is the process to submit a widget to Content Hub?
The process for submitting your widget is listed at: https://github.com/fortinet-fortisoar/how-tos.
Can I write a service specific to a widget?
Certainly! You can write a service specific to a widget. To do this, add the service file into a custom folder structure and then including this file in the view.html in your widget:
-
Add a custom folder structure in your widget folder. For example:
/app /widgets /myWidget /js - widgetScript.service.js /views - view.html -
Add the script file of the external library to the
/jsfolder in the widget folder and then reference this script file in theview.htmlfile of your widget:<!-- Include Widget JavaScript service file --> <script src="widgets/installed/myWidget/js/widgetScript.service.js"></script>
NOTE: Ensure that you specify the correct path based on your project structure.
Reference Widgets: widget-custom-picklist-message and widget-task-management.
How to find out the current context of the widget?
The current context of a widget provides you information such as whether the widget is on Dashboard or View Panel (Record details page). To find out if the current context of widget is for example, the 'View Panel', use the following code snippet:
isViewPanelPage = $state.current && $state.current.name.indexOf('viewPanel') !== -1;