Using Chart.js client-side in Atlasboard - client-side

How can a third-party javascript library be made available for client-side use in Atlasboard? require doesn't work in widgets, and I don't want to have to import the whole library into every widget that uses the library.

Place the javascript library file (such as Chart.min.js) in assets/javascripts/.
In the JSON config for the dashboard(s) which will load the widgets that will rely on the library, add the name of the library to the layout.customJS array:
Example:
{
"title": "My Dashboard",
"titleVisible": false,
"description": "a neat dashboard",
"layout": {
"gridSize" : { "columns" : 20, "rows" : 12 },
"customJS" : ["Chart.min.js"],
"widgets" : [
...
]
},
"config": {
...
}
}
Nothing special needs to be done in the Widget. You can just use the library:
var graph = new Chart(ctx).Radar(data);

Related

VSCode - Automatically Create Matching CSS files

Problem
I am currently create a React web app and I am creating my own components that also have their own CSS files. Currently I have to create a matching CSS file everytime I create a component. I was hoping for something sort of how like when you create a project in Visual Studio is will create a .aspx page as well as a .cs file along with it.
My current structure is ../src/components/DashNav.js and the matching stylesheet would be ../src/styles/components/DashNav.scss
Question
Does anyone know if there is a way to trigger a creation of a new file each time a js file is created?
If not, is there any extensions that anyone would recommend? I have already seen VSCODE Create File Folder but that doesn't do me really any good since I can just do this in the terminal.
Folder Templates is the extension that I'm using for this right now. Here is how I've set up my folder structure and and file templates in settings.json
"folderTemplates.structures": [
{
"name": "My Custom Template",
"omitParentDirectory": true,
"structure": [
{
"fileName": "<FTName>.js",
"template": "React Functional Component"
},
{
"fileName": "<FTName>.module.css",
"template": "CSS Module"
}
]
}
],
"folderTemplates.fileTemplates": {
"React Functional Component": [
"import styles from '<FTName>.module.css';",
"",
"export const <FTName> = (props) => {",
" return <div></div>;",
"};"
],
"CSS Module": ".<FTName | lowercase> {}"
}

Can I get Bokeh to NOT generate javascript all on one line?

I've never worked with Bokeh before, so apologies if this question doesn't make sense. I have a plot that someone else generated using Bokeh and it has a huge JSON object (docs_json) that is all on the same line. I need to import this plot into a WordPress site which has a line length limit. Is there any way I can get Bokeh to generate that JSON in a prettified form rather than squishing the whole thing onto one line?
I'm in a situation where I'm working with 100s of plots being generated continuously, so I'd prefer not to have to manually touch each plot after it is generated.
Yes, the simplest way is to use the BOKEH_PRETTY environment variable when running any Bokeh code, e.g.
BOKEH_PRETTY=true python iris.py
Results in HTML output with embedded JSON that looks like:
<script type="application/json" id="4074acb8-0b70-4591-8d43-99873a9e1bc4">
{
"9d745210-1f6a-4c22-b8ca-c3d2b3829a8f": {
"roots": {
"references": [
{
"attributes": {
"bottom_units": "screen",
"fill_alpha": {
"value": 0.5
},
...
],
"root_ids": [
"ce2c1a38-e3e5-4155-9a80-6860dc284dbc"
]
},
"title": "Bokeh Application",
"version": "0.12.15dev1"
}
}
</script>
All of Bokeh's settings and their associated environment variables are documented in the reference guide:
https://docs.bokeh.org/en/latest/docs/reference/settings.html

How to have multiple output files in gruntfile.js when running requirejs

In Gruntfile.js for grunt-contrib-requirejs I can only register one task and I can only have one output file i.e. home_scripts.pack.js. However, I want to have as many as I want output files based on different 'include' criteria. For example, home_scripts.pack.js, checkout_scripts.pack.js, product_scripts.pack.js etc. This way each page will only load JS that is using:
This is invalid, however I want to do something similar:
requirejs: {
compile1: {
options: {
baseUrl: 'C:/project/js',
mainConfigFile: 'C:/project/js/app.js',
name: 'app',
paths: {
requireLib: 'C:/project/js/require.min'
},
*include: ['requireLib', 'home_page_internal.js'],*
*out: 'C:/project/js/home_scripts.pack.js'*
}
}
},
compile2: {
options: {
baseUrl: 'C:/project/js',
mainConfigFile: 'C:/project/js/app.js',
name: 'app',
paths: {
requireLib: 'C:/project/js/require.min'
},
*include: ['requireLib', 'checkout_internal.js'],*
*out: 'C:/project/js/checkout_scripts.pack.js'*
}
}
}
}
The code with asterisk above is the code I want to generate output files different for each page. However, if there is a more efficient way to generate and load large number of JS plugin files and modules through requireJS optimizer using grunt, I'm open to suggestions.
Thanks,
You need to take a look at RequireJS Multipage Example
It depicts how to use concatenation on basis of need of the page.
So your options will look like.
requirejs : {
compile : {
"baseUrl": "app",
"dir": "app/built",
"include": "main.js",
"paths": {
"angular": "bower_components/angular/angular.min",
"css" : "bower_components/require-css/css.min",
"text" : "bower_components/requirejs-text/text",
"css-builder" : "bower_components/require-css/css-builder",
"normalize" : "bower_components/require-css/normalize"
},
"modules" : [
{
"name" : "app",
"include" : ["text", "css"]
},
{
"name" : "modules/module1",
"include" : [],
"exclude" : ["app"]
},
{
"name" : "modules/module2",
"include" : [],
"exclude" : ["app"]
},
{
"name" : "modules/module3",
"include" : [],
"exclude" : ["app"]
} ]
}
}
Ignore other config and check modules config. It's an array which takes multiple AMD module and each will be concatenated in its own file.
In case of SPA, if you need to exclude any common modules which you dont want to be included in subsequent modules. In this case app module incorporates all the library layer and hence it is excluded from the subsequent modules.

How to effect new changes to user dashboards in alfresco share?

If I were to change user/site dashboard preset(s), is it possible to effect the change(s) to already created users in alfresco?
See this Share webscript : /components/dashboard/customise-dashboard
I use this script a long time ago, so I don't remind very well the parameters needed... but there is a property in the object parameter you must avoid...
EDIT : execute script /components/dashboard/customise-dashboard with POST method
Here an example of the request body :
{
"dashboardPage": "site/site1/dashboard",
"templateId": "dashboard-2-columns-wide-right",
"dashlets": [
{
"url": "/components/dashlets/site-links",
"regionId": "component-1-1",
"originalRegionId": "component-1-1"
},
{
"url": "/components/dashlets/calendar",
"regionId": "component-1-2",
"originalRegionId": "component-1-2"
},
{
"url": "/components/dashlets/wiki",
"regionId": "component-1-3",
"originalRegionId": "component-2-3"
},
{
"url": "/components/dashlets/docsummary",
"regionId": "component-2-1",
"originalRegionId": "component-2-1"
},
{
"url": "/components/dashlets/activityfeed",
"regionId": "component-2-2",
"originalRegionId": "component-2-2"
}
]
}
This I have only tried out in 4.2.c.
I navigated to the surf-config/components directory in the explorer (Very well hidden so use the left explorer pane) and manually deleted the xml configs for users. (Or run a javascript script from javascript console which does the same thing), afterwards I used the surf console tool to refresh all components and it worked.

chrome extension content script can not access to iframes

i want to make a chrome extension on google reader and i found a problem. content script can not access to iframes. For all n, window.frames[n] = undefined. And i have this "all_frames": true in manifest.json. Or someone could tell me how to add a button under each article. Thank you!
From taking a quick look at Google Reader's rendered HTML, the only button that is in an IFRAME appears to be the Google Plus +1 button - all the other buttons are not in an IFRAME. So you don't need to worry about the IFRAME.
I'm assuming that the existing buttons are the buttons that appear underneath each article: +1, Share, Email, Keep Unread, Add Tags.
If you want to add a new button to the existing article buttons all you need to do is enumerate the DOM - specifically the "entry-actions" DIV classes and append say a new SPAN with your element/button to each article.
I suspect (but not sure) that Reader may dynamically update the DOM with new articles. If this is the case you may need to track new articles being added to the DOM so you can add your button again. To do this add an event listener for DOMNodeInserted - e.g.
document.addEventListener('DOMNodeInserted', onNodeInserted, false);
UPDATE:
The reason you can't see ".entry-actions" class is because it is added dynamically.
Here is a working very basic example. This will monitor the DOM and when it sees an entry-actions DIV that doesn't have our ".myclass" SPAN button, will add it.
You need to have jquery included in your extension for this to work. I've used jquery-1.7.1.min.js in this example. You will also need an icon file called foo.png too if you cut and paste the example.
manifest.json
{
// Required
"name": "Foo Extension",
"version": "0.0.1",
// Recommended
"description": "A plain text description",
"icons": { "48": "foo.png" },
//"default_locale": "en",
// Pick one (or none)
"browser_action": {
"default_icon": "Foo.png", // optional
"default_title": "Foo Extension" // optional; shown in tooltip
},
"permissions": [ "http://*/", "https://*/", "tabs" ],
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["jquery-1.7.1.min.js", "content_script.js" ],
"run_at": "document_idle"
}
]
}
content_script.js
var timer;
document.addEventListener('DOMNodeInserted', onNodeInserted, false);
function onNodeInserted(e)
{
if(timer) clearTimeout(timer);
timer = setTimeout("addButtons()", 250);
}
function addButtons()
{
console.log('add buttons');
var $actions = $(".entry-actions").filter(function() {
return $(this).find('.myclass').length === 0;
});
$actions.append('<span class="myclass">My button</span>');
}

Resources