How can i read external json file in Azure-devops-extension development? - azure-devops

I am trying to read json file inside "index.html" file of the project, since for azure devops extension we already have require.js library, hence wanted to use the same capability of it to import "config.json" file inside "index.html" file.
basic file structure:
|-index.html
|-static  |-icon.png
|    |-config.json
|-vss-extension.json
my index.html file look somewhat like this :
init block
VSS.init({
explicitNotifyLoaded: true,
usePlatformScripts: true,
setupModuleLoader: true,
moduleLoaderConfig: {
paths: {
"Static": "static"
}
}
});
require block
VSS.require(
["TFS/WorkItemTracking/Services", "Static/config"],
function (_WorkItemServices, ConfigJson) {
VSS.ready(function(){
VSS.register(VSS.getContribution().id, function () {
return {
// Called when the active work item is modified
onFieldChanged: function (args) {
console.log(
"inside onfield : " +
JSON.stringify(ConfigJson)
);
}
....
};
});
VSS.notifyLoadSucceeded();
})
});
My vss-extension.json file :
File block
"files": [
{
"path": "static/config.json",
"addressable": true,
"contentType": "application/json"
},
....
]
I am always getting require.js Script error: https://requirejs.org/docs/errors.html#scripterror
Took reference from:
https://github.com/ALM-Rangers/Show-Area-Path-Dependencies-Extension/blob/master/src/VSTS.DependencyTracker/vss-extension.json for vss-extension file.
https://github.com/ALM-Rangers/Show-Area-Path-Dependencies-Extension/blob/master/src/VSTS.DependencyTracker/index.html for index.html

I am afraid that you couldn't directly get the content of the json file.
But you could try to use the HTTP request to get the content.
Please refer to the following sample:
onFieldChanged: function (args) {
var request = new XMLHttpRequest();
request.open('GET', 'config.json', true);
request.send(null);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
var type = request.getResponseHeader('Content-Type');
console.log( "inside onfield : " + JSON.stringify(request.responseText));
}
}
Check out these two tickets for details.
Loading a JSON file in a VSTS extension
read local JSON file into variable

Is VSS using unmodified RequireJS? If yes, then you can use JSON plugin, which will help:
https://github.com/millermedeiros/requirejs-plugins
Using it is pretty simple, you just have to add a prefix json! when specifying a json file as a dependency:
VSS.require(
["TFS/WorkItemTracking/Services", "json!Static/config"],
function (_WorkItemServices, ConfigJson) {
VSS.ready(function(){
VSS.register(VSS.getContribution().id, function () {
return {
// Called when the active work item is modified
onFieldChanged: function (args) {
console.log(
"inside onfield : " +
JSON.stringify(ConfigJson)
);
}
....
};
});
VSS.notifyLoadSucceeded();
})
});

Related

Strapi email designer plugin reference template to record

I'm currently developing a multi-tenant API with Strapi and for one of the parts I use the Strapi email designer plugin because I want to send some emails but I want them to be custom designed for each tenant, the problem is that the plugin's table is not accessible in the content manager of Strapi so I can only hard code the template to a specific endpoint, is there a way to have the plugin table in the content manager or for it to be referenced to a content manager table something like:
(table)tenant->(field)templateId => (ref-table)plugin-email-designer->(ref-field)templateId
you know so I can switch and set dynamically from the Strapi panel and not with hard-coded endpoints
I've checked your issue briefly, and there is option you are going to like, but it involves using patch-package...
So, let's assume that you have strapi project created and you have added strapi-plugin-email-designer and you are using yarn v1.xx.xx:
yarn add patch-package postinstall-postinstall
Go to node_modules/strapi-plugin-email-designer/server/content-types/email-template/schema.json
change following fileds:
{
...
"pluginOptions": {
"content-manager": {
"visible": true
},
"content-type-builder": {
"visible": true
}
},
...
}
now run
yarn patch-package strapi-plugin-email-designer
now open your projects package.json and add to scripts:
{
"scripts": {
...
"postinstall": "patch-package"
}
}
run
yarn build
yarn develop
head to admin ui, you should see new Collection:
so now you can do that:
Sending Email
Let's assume you added a relation has one called email_template to your model.
Next we need to add custom route, so in /src/api/tenant/routes/ create file called routes.js
/src/api/tenant/routes/routes.js
module.exports = {
routes: [
{
method: 'POST',
path: `/tenants/:id/send`,
handler: `tenant.send`
}
]
}
now, we need to add handler to controller:
/src/api/tenant/controllers/tenant.js
"use strict";
/**
* tenant controller
*/
const { createCoreController } = require("#strapi/strapi").factories;
module.exports = createCoreController("api::tenant.tenant", ({ strapi }) => ({
async send(ctx) {
const { id } = ctx.params;
const { data } = ctx.request.body;
// notice, if you need extra validation you add it here
// if (!data) return ctx.badRequest("no data was provided");
const { to, subject } = data;
const { email_template, ...tenant } = await strapi.db
.query("api::tenant.tenant")
// if you have extra relations it's better to populate them directly here
.findOne({ where: { id }, populate: ["email_template"] });
console.log(email_template);
try {
await strapi
.plugin("email-designer")
.service("email")
.sendTemplatedEmail(
{
to,
//from, < should be set in /config/plugins.js email.settings.defaultFrom
//replayTo < should be set in /config/plugins.js email.settings.defaultReplyTo
},
{
templateReferenceId: email_template.templateReferenceId,
subject,
},
{
...tenant,
// this equals to apply all the data you have in tenant
// this may need to be aligned between your tenant and template
}
);
return { success: `Message sent to ${to}` };
} catch (e) {
strapi.log.debug("📺: ", e);
return ctx.badRequest(null, e);
}
},
}));
don't forget to enable access to /api/tenants/:id/send in admin panel, Settings - Roles
POST http://localhost:1337/api/tenants/1/send
{
"data": {
"to" : "email#example.com",
"subject": "Hello World"
}
}
response:
{
"success": "Message sent to email#example.com"
}
pls note, there is no template validation, e.g. if you give it a wrong template it would not be happy

Why is my Upload-File POST not working using NEST.JS and Multer?

I try to make a simple file upload REST interface using NEST.JS and MULTER -- but its not working. I am able to POST a binary file debug.log to the URL, and I see the "Hello undefined" message, but the uploaded file neither is created at the given folder uploads nor it is rejected because the extension is not correct - according to the file filter.
However, no exception or error is shown.
Why is multer not working?
Why is the #Uploadedfile() file shown as undefined?
Thanks
import { Controller, Post, Request, UseInterceptors, FileInterceptor, UploadedFile, HttpCode, HttpException, HttpStatus } from '#nestjs/common';
import { diskStorage, File } from 'multer';
const path = require('path');
const myStorage = diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads/');
},
limits: { fileSize: 1000000 },
fileFilter: function (req, file, cb) {
const extension = path.extname(file.originalname).toLowerCase()
const mimetyp = file.mimetype
if (extension !== '.jpg' || mimetyp !== 'image/jpg') {
cb(new HttpException('Only images are allowed', HttpStatus.NOT_ACCEPTABLE));
}
cb(null, true);
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '_' + Date.now() + '.jpg');
}
});
#Controller('documents')
export class DocumentsController {
#Post()
#HttpCode(HttpStatus.OK)
#UseInterceptors(FileInterceptor('file', { storage: myStorage }))
public async addDocument(#UploadedFile() file): Promise<any> {
console.log("Hello " + file);
}
}
I know it's a late reply for the person who asked this question, but the answer is for the people who will face it in the future.
First, check the nestjs documentation
If MulterModule registered in the *.module.ts file it creates the upload directory outside of the src folder. which is a good practice.
MulterModule.register({
dest: './upload',
});
If there is a need to change the destination directory use destination: String|callback from DiskStorageOptions or dest:string from FileInterceptor. For upload path use like src/../upload to keep the folder outside the src directory.
Other problems from the above code mentioned in the question:
I see the "Hello undefined" message
reason console.log("Hello " + file); here file is Object and trying concatenate with String.
change it to console.log("Hello ", file);
the extension is not correct, no exception or error is shown
fileFilter: function (req, file, cb) {
const extension = path.extname(file.originalname).toLowerCase()
const mimetyp = file.mimetype
if (extension !== '.jpg' || mimetyp !== 'image/jpg') {
cb(new HttpException('Only images are allowed', HttpStatus.NOT_ACCEPTABLE));
}
cb(null, true);
}
Here need to add a return.

How do I extend loader widget in Magento 2 so that a background image is shown everytime the loader appears

I have been trying to extend magento 2's $.mage.loader widget. I have have a requirejs-config.js file with the following lines
var config = {
map: {
'*': {
'mage/loader' : 'Youssuph_Bakerscheckout/js/custom-mage-loader'
}
}
};
And the content of custom-mage-loader.js file is
define([
'jquery',
'mage/template',
'jquery/ui',
'mage/translate'],
function ($, mageTemplate) {
'use strict';
$.widget("bakers.loader", $.mage.loader, {
options: {
icon: '',
texts: {
loaderText: $.mage.__('Please wait...'),
imgAlt: $.mage.__('Loading...')
},
template:
'<div class="loading-mask" data-role="loader">' +
'<div class="loader">' +
'<img alt="<%- data.texts.imgAlt %>" src="'+loadingBakersLogo+'">' +
'<p><%- data.texts.loaderText %></p>' +
'</div>' +
'</div>'
}
});
return $.bakers.loader;
});
i have confirmed that this file loads in the browser but it just doesn't work. The loader works normally during page load and I see error message -
Base is not a function
What am I doing wrong?
Your requirejs-config.js it's right, but your js file no, change the params like this:
define([
'jquery',
'jquery/ui',
'mage/loader'],
function ($) {
$.widget('your_namespace.loader', $.mage.loader, {
options: {
texts: {
loaderText: $.mage.__('Foo')
},
template:
'<div>Your template</div>'
}
});
return $.your_namespace.loader;
});
Now use: jQuery('body').loader('show') and see your new custom loader!
Its been a while but if anybody else stumbles upon this answer.
vjurado is not correct. The mistake lays in requirejs-config.js. Correct will be a reference withouth the "mage/", like this:
var config = {
map: {
'*': {
'loader' : 'Youssuph_Bakerscheckout/js/custom-mage-loader'
}
}
};
The custom-mage-loader.js is correct as posted in the initial question.

how to use third party javascript code in magento2 payment?

I am facing problem while adding third party javascript code in my payment module in magento2.
following is my code.
define(
[
'Magento_Payment/js/view/payment/cc-form',
'jquery',
'Vendorname_Modulename/js/stsdk'
'Magento_Payment/js/model/credit-card-validation/validator'
],
function (Component, $, STDirect) {
'use strict';
return Component.extend({
defaults: {
template: 'Vendorname_Modulename/payment/module-form'
},
getCode: function() {
return 'vendor_module';
},
isActive: function() {
return true;
},
validate: function() {
STDirect.setupSDK('23842', "testnumber", 'typeofenv');
STDirect.card.createToken(number, exp_month, exp_year, ccv, function (result) {
var secretkey = '';
if(result.status==0){
secretkey = result.card.secretkey;
}
document.write(JSON.stringify(result));
alert(secretkey);
});
var $form = $('#' + this.getCode() + '-form');
return $form.validation() && $form.validation('isValid');
}
});
}
);
I have tried above code, stsdk.js is loaded in network but it gives me following error :
ReferenceError: STDirect is not defined
STDirect.setupSDK('23842', "testnumber", 'sandbox');
I have also checked by load this js file in header but same error appear.
My question is how to execute third party javascript code in define scope.
I tried with the custom javascript function after define function but it is also not callable from validate function and when I use require[] function within define function it raise error.
I appreciate any help.

Create a document using CMIS in Javascript

I am trying to create a document in the SAP Document Center of HCP using Javascript and I can not. SAP Document Center uses the CMIS protocol for communication with other applications. I have been able to connect from my SAPUI5 application with the SAP Document Center. I have also managed to create a folder as follows:
createFolder: function(repositoryId, parentFolderId, folderName) {
var data = {
objectId: parentFolderId,
cmisaction: "createFolder",
"propertyId[0]": "cmis:name",
"propertyValue[0]": folderName,
"propertyId[1]": "cmis:objectTypeId",
"propertyValue[1]": "cmis:folder"
};
$.ajax("/destination/document/mcm/json/" + repositoryId + "/root", {
type: "POST",
data: data
}).done(function() {
MessageBox.show("Folder with name " + folderName + " successfully created.");
}).fail(function(jqXHR) {
MessageBox.show("Creation of folder with name " + folderName + " failed. XHR response message: " + jqXHR.responseJSON.message);
});
},
However, I find it impossible to create a document. I can not find an internet sample for the CMIS "createDocument" method. There are many examples for Java but nothing to do with Javascript. I do not know what the structure of the data to send. The code is as follows:
createDocument: function(repositoryId, parentFolderId, documentName, content) {
/**
* 'content' contains the whole document converted to a base64 string like this:
* "data:application/pdf;base64,JVBERi0xLjUNJeLjz9MNCjIxNCAwIG9iag08P..."
*/
var data = {
objectId: parentFolderId,
cmisaction: "createDocument",
contentStream: content,
"propertyId[0]": "cmis:name",
"propertyValue[0]": documentName,
"propertyId[1]": "cmis:objectTypeId",
"propertyValue[1]": "cmis:document"
};
$.ajax("/destination/document/mcm/json/" + repositoryId + "/root", {
type: "POST",
data: data
}).done(function() {
MessageBox.show("Document with name " + documentName + " successfully created.");
}).fail(function(jqXHR) {
MessageBox.show("Creation of document with name " + documentName + " failed. XHR response message: " + jqXHR.responseJSON.message);
});
},
With this I create a file record within the SAP Document Center but it does not take the data. An unformatted file is created, when it should have the format sent (PDF, txt, Excel, Doc, ...).
Does anyone know how to do it?
Regards.
Links of interest:
CMIS Standard
http://docs.oasis-open.org/cmis/CMIS/v1.1/os/CMIS-v1.1-os.html#x1-1710002
Usage examples for Java (not Javascript)
http://chemistry.apache.org/java/developing/guide.html
I have been through a similar problem. My solution is to change it from base64 to a FormData approach, so I got the file input value instead of the content base64 string. It worked fine.
this.createObject = function (fileInput, objectName,folderId, cbOk, cbError) {
if (!folderId) {
folderId = _this.metadata.rootFolderId;
}
var documentData = {
'propertyId[1]': 'cmis:objectTypeId',
'propertyValue[1]': 'cmis:document',
'propertyId[0]': 'cmis:name',
'propertyValue[0]': objectName,
'objectId': folderId,
'cmisaction': 'createDocument',
'content' : fileInput
};
var formData = new FormData();
jQuery.each(documentData, function(key, value){
formData.append(key, value);
});
$.ajax({
url: _this.metadata.actionsUrl,
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
cbOk(data);
},
error: function(err){
cbError(err);
}
});
};
In the view.xml add following lines.
<FileUploader id="fileUploader"
name="myFileUpload"
uploadUrl="/cmis/root"
width="400px"
tooltip="Upload your file to the local server"
uploadComplete="handleUploadComplete"
change='onChangeDoc'/>
the upload url will be url to the neo destination. In the neo.app.json add the following lines.
{
"path": "/cmis",
"target": {
"type": "destination",
"name": "documentservice"
},
"description": "documentservice"
}
In the controller.js add the following lines of code.
if (!oFileUploader.getValue()) {
sap.m.MessageToast.show("Choose a file first");
return;
}
var data = {
'propertyId[0]': 'cmis:objectTypeId',
'propertyValue[0]': 'cmis:document',
'propertyId[1]': 'cmis:name',
'propertyValue[1]': file.name,
'cmisaction': 'createDocument'
};
var formData = new FormData();
formData.append('datafile', new Blob([file]));
jQuery.each(data, function(key, value) {
formData.append(key, value);
});
$.ajax('/cmis/root', {
type: 'POST',
data: formData,
cache: false,
processData: false,
contentType: false,
success: function(response) {
sap.m.MessageToast.show("File Uploaded Successfully");
}.bind(this),
error: function(error) {
sap.m.MessageBox.error("File Uploaded Unsuccessfully. Save is not possible. " + error.responseJSON.message);
}
});
In the neo cloud, maintain the url for following configuration in destination tab. https://testdaasi328160trial.hanatrial.ondemand.com/TestDaaS/cmis/json/repo-id
repo-id will be your repository key.
this will solve the problem. You will be able to upload and the document.