Bitrix24 Application Embedding - bitrix

I am working on an application for my Bitrix system. I'm trying to embed into the tasks module, but I'm having some trouble getting the embedding to actually work. Below is my javascript code that should be handling the embedding.
BX24.rest.callMethod(
'placement.bind',
params: {
PLACEMENT: 'TASK_VIEW_TAB',
HANDLER: '*URL FOR CODE WITHIN BITRIX SERVER*',
TITLE: 'Test Tab',
DESCRIPTION: 'Test Tab',
}
);
Have I done something incorrectly in my code? This is the code that is set up to run when the application is installed. If this is all I need, perhaps I'm missing a step that actually installs the application (it's a private application currently).

Syntax should be as follows:
BX24.callMethod(
'placement.bind',
{
PLACEMENT: 'TASK_VIEW_TAB',
HANDLER: '*URL FOR CODE WITHIN BITRIX SERVER*',
TITLE: 'Test Tab',
DESCRIPTION: 'Test Tab',
}
);

Don't forget to set Access permissions for "Application embedding (placement)" in order to use placement methods.

Related

Processing \Animation in NetSuite

I have this client script which copies the line number entered in Copy line# and creates new lines from number of lines entered in Copy #Times.
This thing takes time when you increase the number of lines you require to copy. So can we give any processing animation till all the lines are set so user dont have to worry?
I have tried giving dialog.create but it didnt work. I want the animation to stay until script is executing and after that stop.
var options = {
title: 'Alert',
message: 'Processing. Please wait.',
buttons: [{
label: 'OKK...',
value: 1
},
]
};
dialog.create(options).then(success)
return (true);
success is a function I am calling.
The N/ui/dialog module is intended for showing dismissable messages, and won't really work for progress bars as you cannot hide the buttons, nor close it via code. I would recommend looking at a third party library. A very popular one is SweetAlert2, and there is some sample code on the NetSuite Professionals site for using it with NetSuite.
If you just want a quick hack, you could just used the Ext.js library that NetSuite includes by default on all pages. However I would highly recommend not doing so for any production code because NetSuite could update or remove it at any time in a future upgrade.
var messageBox = Ext.MessageBox.show({
title: 'Lines are being copied...',
msg: 'This may take a couple minutes',
wait: true,
width: 250
});
// your work here
messageBox.hide()

How to make node cms modular

I want to make my node cms (at this moment only login,reg, articles) modular. Like you can add or remove any module just be deleting or adding folder. But i cant find any correct or smart or any way to do it. Have you any experience, guides or examples that can help?
I am relatively new in node.
At this moment it looks like this.
This question is a bit too broad in the context of creating a modular cms, however when talking about node modules, even if you just add or delete a folder you still have to require them in your code.
I would say that there are 2 types of plugins that you can have:
Supported plugins - plugins that you create and give the users the option to include them or not
Anonymous plugins - plugins that everyone can create, and need to be included in your application via some kind of interface.
The second type of plugins are more complicated, so I will refer only to the first type. An easy way to include them in your code is to have a JSON where you list the properties of each plugin, and then require each plugin in your code. Using try/catch will prevent your application from crashing if the plugin does not exist:
var allowedPlugins = [
{name: "login", path: "login/index.js", loaded: false, module: null},
{name: "reg", path: "reg/reg.js", loaded: false, module: null},
{name: "articles", path: "articles/all.js", loaded: false, module: null}
];
allowedPlugins.forEach((plug) => {
try {
var module = require(plug.path);
plug.loaded = true;
plug.module = module;
} catch(err) {}
});
Later in your code you can do:
if (allowedPlugins.login.loaded) {
var login = allowedPlugins.login.module;
login.doLogic(...)
}

Check env variables in serverless.yml file (Serverless Framework)

I am new to using serverless framework and I would like to check that env variables inside serverless.yml are changing according to the stage I am on. Here is what I have in serverless.yml:
service: items
custom:
customDomain:
domainName: api.app.com
certificateName: '*.api.app.com'
basePath: ''
stage: ${self:provider.stage} <=== (Variable to check)
createRoute53Record: true
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
serverless-iam-roles-per-function:
defaultInherit: true
.......
provider:
name: aws
runtime: nodejs8.10
......
......
process_updates:
handler: handler.processUpdates
iamRoleStatements:
- Effect: "Allow"
Action:
- s3:*
Resource:
- "arn:aws:s3:::${file(./config.${self:provider.stage}.json):items_updates}/*"
Config.dev.json:
{
"items_updates": "dev-items-updates"
}
Config.prod.json:
{
"items_updates": "prod-items-updates"
}
So, I would like to know if there is a way to print the following variables
${self:provider.stage} and ${file(./config.${self:provider.stage}.json):items_updates} when the deployment is happening. And is there best practice using different env with serverless framework?
Thanks in advance !
Plugin?
If you want to tie into Serverless lifecycle events, and do stuff, one typical approach would be to write a plugin.
I found the learning curve with Serverless plugin development to be quite gentle, and would recommend writing one to any Serverless user that hasn't done so.
However, sometimes a plugin is overkill, or undesirable for other reasons.
Workaround
One very handy (yet often overlooked) feature of Serverless is that it can resolve variables from javascript files.
Note the exported function with this signature:
module.exports = (serverless) => { ... }
This serverless object gives you access to all sorts of stuff:
Command line args can be found on serverless.processedInput.options.
Your service can be found at serverless.service.
Concrete Case
In your case, you could either put your ${env}-items-updates data directly into a .js function, or have your function read up the file(s).
For the sake of simplicity, I'll assume you're willing to stuff the data right into the function. I'll also illustrate using only a singe items-updates.js file, rather than separate files per stage.
items-updates.js:
module.exports = (serverless) => {
const stage = serverless.service.provider.stage;
serverless.cli.log(`Resolving items-updates for stage ${stage}`);
switch (stage) {
case 'dev':
return {}; // Your dev-items-updates here
case 'prod':
return {}; // Your prod-items-updates here
}
}
Then in your iamRoleStatements:
Resource:
- ${file(./items-updates.js)}
Note: While the example above shows a default export, I do typically use named exports, so I can put more than one resource in a single js file.

Silent printing in electron

I am currently building an electron app. I have a PDF on my local file system which I need to silently print out (on the default printer). I came across the node-printer library, but it doesn't seem to work for me. Is there an easy solution to achieve this?
Well first of all it is near impossible to understand what you mean with "silent" print. Because once you send a print order to your system printer it will be out of your hand to be silent at all. On Windows for example once the order was given, at least the systemtray icon will indicate that something is going on. That said, there are very good described features for printing with electron even "silent" is one of them:
You need to get all system printers if you do not want to use the default printer:
contents.getPrinters()
Which will return a PrinterInfo[] Object.
Here is an example how the object will look like from the electron PrtinerInfo Docs:
{
name: 'Zebra_LP2844',
description: 'Zebra LP2844',
status: 3,
isDefault: false,
options: {
copies: '1',
'device-uri': 'usb://Zebra/LP2844?location=14200000',
finishings: '3',
'job-cancel-after': '10800',
'job-hold-until': 'no-hold',
'job-priority': '50',
'job-sheets': 'none,none',
'marker-change-time': '0',
'number-up': '1',
'printer-commands': 'none',
'printer-info': 'Zebra LP2844',
'printer-is-accepting-jobs': 'true',
'printer-is-shared': 'true',
'printer-location': '',
'printer-make-and-model': 'Zebra EPL2 Label Printer',
'printer-state': '3',
'printer-state-change-time': '1484872644',
'printer-state-reasons': 'offline-report',
'printer-type': '36932',
'printer-uri-supported': 'ipp://localhost/printers/Zebra_LP2844',
system_driverinfo: 'Z'
}
}
To print your file you can do it with
contents.print([options])
The options are descriped in the docs for contents.print():
options Object (optional):
silent Boolean (optional) - Don’t ask user for print settings. Default is false.
printBackground Boolean (optional) - Also prints the background color and image of the web page. Default is false.
deviceName String (optional) - Set the printer device name to use. Default is ''.
Prints window’s web page. When silent is set to true, Electron will pick the system’s default printer if deviceName is empty and the default settings for printing.
Calling window.print() in web page is equivalent to calling webContents.print({silent: false, printBackground: false, deviceName: ''}).
Use page-break-before: always; CSS style to force to print to a new page.
So all you need is to load the PDF into a hidden window and then fire the print method implemented in electron with the flag set to silent.
// In the main process.
const {app, BrowserWindow} = require('electron');
let win = null;
app.on('ready', () => {
// Create window
win = new BrowserWindow({width: 800, height: 600, show: false });
// Could be redundant, try if you need this.
win.once('ready-to-show', () => win.hide())
// load PDF.
win.loadURL(`file://directory/to/pdf/document.pdf`);
// if pdf is loaded start printing.
win.webContents.on('did-finish-load', () => {
win.webContents.print({silent: true});
// close window after print order.
win = null;
});
});
However let me give you a little warning:
Once you start printing it can and will get frustrating because there are drivers out there which will interpret data in a slightly different way. Meaning that margins could be ignored and much more. Since you already have a PDF this problem will most likely not happen. But keep this in mind if you ever want to use this method for example contents.printToPDF(options, callback). That beeing said there are plently of options to avoid getting frustrated like using a predefined stylesheet like descriped in this question: Print: How to stick footer on every page to the bottom?
If you want to search for features in electron and you do not know where they could be hidden, all you have to do is to go to "all" docs and use your search function: https://electron.atom.io/docs/all/
regards,
Megajin
I recently published NPM package to print PDF files from Node.js and Electron. You can send a PDF file to the default printer or to a specific one. Works fine on Windows and Unix-like operating systems: https://github.com/artiebits/pdf-to-printer.
It's easy to install, just (if using yarn):
yarn add pdf-to-printer
or (if using npm):
npm install --save pdf-to-printer
Then, to silently print the file to the default printer you do:
import { print } from "pdf-to-printer";
print("assets/pdf-sample.pdf")
.then(console.log)
.catch(console.error);
To my knowledge there is currently no way to do this directly using Electron because while using contents.print([]) does allow for 'silently' printing HTML files, it isn't able to print PDF views. This is currently an open feature request: https://github.com/electron/electron/issues/9029
Edit: I managed to work around this by converting the PDF to a PNG and then using Electron's print functionality (which is able to print PNGs) to print the image based view. One of the major downsides to this is that all of the PDF to PNG/JPEG conversion libraries for NodeJS have a number of dependencies, meaning I had to implement them in an Express server and then have my Electron app send all PDFs to the server for conversion. It's not a great option, but it does work.

How to modify dashlets to auto-refresh?

Is there a simple way to modify a dashlet to automatically re-load itself periodically?
I am particularly thinking of the "My Tasks" dashlet - we are using pooled review workflows, so tasks may come and go all the time as they are created and then are claimed.
It may be frustrating for users to keep clicking on tasks that turn out to have already been claimed - or having to remember to keep re-loading their Dashboard page. I'd prefer the dashlet to refresh on a timed interval so it's always reasonably up to date.
In order to do this you will need to add a new capability to the client-side class Alfresco.dashlet.MyTasks (docs, source) found in the file components/dashlets/my-tasks.get.js. First you will need to add a new method to the prototype extension specified as the second parameter in the YAHOO.lang.augmentObject() call, e.g.
...
}, // end of last OOTB function - add a comment here
// begin changes
reloadData: function MyTasks_onReady()
{
this.widgets.alfrescoDataTable.loadDataTable(
this.options.filters[this.widgets.filterMenuButton.value]
);
}
// end changes
});
})();
It's not the ideal development environment, you can modify the JS file directly in the Share webapp, although you will also need to update the corresponding -min.js file.
Once you've done this, check that it works by running the following line in your browser's JavaScript console
Alfresco.util.ComponentManager.findFirst("Alfresco.dashlet.MyTasks").reloadData();
If that works, then you can wire up your new method to a title bar action (see my DevCon presentation for more background info), in the dashlet web script. The method depends on whether you are using v4.2 or a previous version, but if it is the latter then you need to add some code to the dashlet's Freemarker file my-tasks.get.html.ftl (under WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/dashlets).
In that file you should see some JavaScript code inside a <script> tag, this sets up an instance of the client-side class and some utility classes, the contents of which you can replace with the following, to add your custom title bar action.
(function()
{
var dashlet = new Alfresco.dashlet.MyTasks("${jsid}").setOptions(
{
hiddenTaskTypes: [<#list hiddenTaskTypes as type>"${type}"<#if type_has_next>, </#if></#list>],
maxItems: ${maxItems!"50"},
filters:
{<#list filters as filter>
"${filter.type?js_string}": "${filter.parameters?js_string}"<#if filter_has_next>,</#if>
</#list>}
}).setMessages(${messages});
new Alfresco.widget.DashletResizer("${id}", "${instance.object.id}");
var refreshDashletEvent = new YAHOO.util.CustomEvent("onDashletRefresh");
refreshDashletEvent.subscribe(dashlet.reloadData, dashlet, true);
new Alfresco.widget.DashletTitleBarActions("${args.htmlid}").setOptions(
{
actions:
[
{
cssClass: "refresh",
eventOnClick: refreshDashletEvent,
tooltip: "${msg("dashlet.refresh.tooltip")?js_string}"
},
{
cssClass: "help",
bubbleOnClick:
{
message: "${msg("dashlet.help")?js_string}"
},
tooltip: "${msg("dashlet.help.tooltip")?js_string}"
}
]
});
})();
You will need to add some styles for the class name specified, in the dashlet's CSS file my-tasks.css, such as the following
.my-tasks .titleBarActions .refresh
{
display: none;
background-image: url('refresh-icon.png');
}
The icon file (here is one you could re-use) must be in the same directory as the CSS file.
Lastly you'll need to define the label dashlet.refresh.tooltop used for the title bar action's tooltip. You can do this in the dashlet web script's .properties file.
For a similar example, check out the source of my Train Times dashlet, which features a refresh title bar action.
In some ways it's actually easier to define your own dashlets than it is to extend the Alfresco-supplied ones, but if you have the option of using 4.2.x, the new method allows you to extend the existing components without duplicating any code, which obviously makes upgrades much easier.

Resources