SmartIT_Extensions/BMC/smart-it-full/scripts/app/common/attachment-service.js

741 lines
36 KiB
JavaScript

"use strict";
(function () {
'use strict';
angular.module('myitsmApp')
.service('attachmentService', ['$resource', '$http', '$timeout', 'systemAlertService', '$q', '$modal', 'objectValueMapperService',
'configurationModel', '$filter',
function ($resource, $http, $timeout, systemAlertService, $q, $modal, objectValueMapperService, configurationModel, $filter) {
var resource = $resource('', {}, {
getAttachmentsInfo: {
url: '/smartit/rest/attachment/info/:type/:id',
method: 'GET',
isArray: true
},
getPlansForChangeRequest: {
url: '/smartit/rest/change/plans/:id',
method: 'GET',
isArray: true
},
getPlansForRelease: {
url: '/smartit/rest/release/:id/plans',
method: 'GET',
isArray: true
},
uploadAttachment: {
url: '/smartit/rest/attachment/file/:type/:id',
method: 'POST',
isArray: true,
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
if (data.length > 0) {
_.each(data, function (attachment) {
formData.append('file[]', attachment.file);
});
}
else {
formData.append('file', data.file);
}
return formData;
}
},
uploadProfileThumbnail: {
url: '/smartit/rest/:type/:id/thumbnail?:query',
method: 'PUT',
isArray: false,
transformRequest: function (data) {
var formData = new FormData();
formData.append('file', data.file);
return formData;
},
transformResponse: function (data) {
return { thumbnail: data };
},
headers: {
'Content-Type': undefined
}
},
addWorknoteWithAttachment: {
url: '/smartit/rest/attachment/file/:type/:id/worknote',
method: 'POST',
isArray: true,
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append('text', data.noteText || data.worknote);
!_.isUndefined(data.access) && formData.append('access', data.access);
!_.isUndefined(data.locked) && formData.append('locked', data.locked);
!_.isUndefined(data.brokerVendorName) && formData.append('brokerVendorName', data.brokerVendorName);
data.shareWithVendor && formData.append('shareWithVendor', true);
!_.isUndefined(data.vendorTicketId) && formData.append('vendorTicketId', data.vendorTicketId);
data.workInfoType && formData.append('type', data.workInfoType);
if (data['Email.Subject']) {
formData.append('Email.Subject', data['Email.Subject']);
formData.append('Email.Body', data['Email.Body']);
data['Email.From.Person'] && formData.append('Email.From.Person', JSON.stringify(data['Email.From.Person']));
data['Email.To.Person'] && formData.append('Email.To.Person', JSON.stringify(data['Email.To.Person']));
data['Email.To.InternetEmail'] && formData.append('Email.To.InternetEmail', data['Email.To.InternetEmail']);
}
if (data.attachments.length > 0) {
if (data.attachments.length === 1) {
formData.append('file', data.attachments[0].file);
}
else {
for (var i = 0, l = data.attachments.length; i < l; i++) {
formData.append('file[]', data.attachments[i].file);
}
}
}
return formData;
}
},
addWorknoteWithAttachmentBulk: {
url: '/smartit/rest/attachment/file/bulk/worknote',
method: 'POST',
isArray: true,
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append('text', data.noteText || data.worknote);
!_.isUndefined(data.access) && formData.append('access', data.access);
!_.isUndefined(data.locked) && formData.append('locked', data.locked);
if (data['Email.Subject']) {
formData.append('Email.Subject', data['Email.Subject']);
formData.append('Email.Body', data['Email.Body']);
data['Email.From.Person'] && formData.append('Email.From.Person', JSON.stringify(data['Email.From.Person']));
data['Email.To.Person'] && formData.append('Email.To.Person', JSON.stringify(data['Email.To.Person']));
data['Email.To.InternetEmail'] && formData.append('Email.To.InternetEmail', data['Email.To.InternetEmail']);
}
if (data.attachments.length > 0) {
if (data.attachments.length === 1) {
formData.append('file', data.attachments[0].file);
}
else {
for (var i = 0, l = data.attachments.length; i < l; i++) {
formData.append('file[]', data.attachments[i].file);
}
}
}
if (data.ticketList) {
formData.append('ticketList', JSON.stringify(data.ticketList));
}
return formData;
}
},
addAttachmentToWorknote: {
url: '/smartit/rest/attachment/file/worknote/:type/:id',
method: 'POST',
isArray: true,
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append('file', data.file);
return formData;
}
},
createChangePlan: {
url: '/smartit/rest/:type/:id/plans',
method: 'POST',
isArray: true,
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
return prepareFormDataForPlans(data);
}
},
updateChangePlan: {
url: '/smartit/rest/:type/:parentId/plans/:id',
method: 'PUT',
isArray: true,
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
return prepareFormDataForPlans(data);
}
},
deletePlan: {
url: '/smartit/rest/:type/:parentId/plans/:planId',
method: 'DELETE'
//isArray: true,
//headers: {'Content-Type': undefined},
/*transformRequest: function (data) {
return prepareFormDataForPlans(data);
}*/
}
///rest/change/<id>/plans/<planId>
});
/**
* Get attachments info
* @param id
* @param type
* @returns {ng.IPromise<TResult>}
*/
this.getAttachmentsInfo = function (id, type) {
if (type === EntityVO.TYPE_CHANGE) {
return this.getPlansForChangeRequest(id);
}
if (type === EntityVO.TYPE_RELEASE) {
return this.getPlansForRelease(id);
}
return resource.getAttachmentsInfo({ id: id, type: type }).$promise
.then(function (response) {
if (!response[0]) {
return [];
}
return normalizeAttachments(response);
});
};
/**
* Get plans with attachments for Change request
* @param id
* @param {Array} plansFilter
* @returns {ng.IPromise<TResult>}
*/
this.getPlansForRelease = function (id, plansFilter) {
var types = _.isArray(plansFilter) ? plansFilter.join() : plansFilter;
var params = types ? { types: types } : {};
params.id = id;
return resource.getPlansForRelease(params).$promise
.then(function (response) {
if (!response[0] || !response[0].items || !response[0].items[0].objects) {
return [];
}
var plans = response[0].items[0].objects;
var planGroupIndexing = {}, groupedPlans = _.groupBy(plans, function (item) {
return item.workNote.workNoteTypeId;
});
_.each(plans, function (plan) {
if (plan.workNote.attachmentCount > 0) {
plan.attachmentInfos = normalizeAttachments(plan);
}
if (groupedPlans[plan.workNote.workNoteTypeId].length > 1) {
planGroupIndexing[plan.workNote.workNoteTypeId] ? planGroupIndexing[plan.workNote.workNoteTypeId]++ : (planGroupIndexing[plan.workNote.workNoteTypeId] = 1);
plan.typeIndex = planGroupIndexing[plan.workNote.workNoteTypeId];
}
});
return plans;
});
};
/**
* Get plans with attachments for Change request
* @param id
* @param {Array} plansFilter
* @returns {ng.IPromise<TResult>}
*/
this.getPlansForChangeRequest = function (id, plansFilter) {
var types = _.isArray(plansFilter) ? plansFilter.join() : plansFilter;
var params = types ? { types: types } : {};
params.id = id;
return resource.getPlansForChangeRequest(params).$promise
.then(function (response) {
if (!response[0] || !response[0].items || !response[0].items[0].objects) {
return [];
}
var plans = response[0].items[0].objects;
var planGroupIndexing = {}, groupedPlans = _.groupBy(plans, function (item) {
return item.workNote.workNoteTypeId;
});
_.each(plans, function (plan) {
if (plan.workNote.attachmentCount > 0) {
plan.attachmentInfos = normalizeAttachments(plan);
}
if (groupedPlans[plan.workNote.workNoteTypeId].length > 1) {
planGroupIndexing[plan.workNote.workNoteTypeId] ? planGroupIndexing[plan.workNote.workNoteTypeId]++ : (planGroupIndexing[plan.workNote.workNoteTypeId] = 1);
plan.typeIndex = planGroupIndexing[plan.workNote.workNoteTypeId];
}
});
return plans;
});
};
/**
* Get attachment file
*
* @param type
* @param attachment
* @returns {*}
*/
this.getAttachmentFile = function (type, attachment, returnAsBlob, isMyITComment) {
attachment.loadingDetails = true;
var request;
// For broadcast created from AR (or any attachment created from comment), the attachment will contain attachmentReference
if (!_.isEmpty(attachment.attachmentReference)) {
request = {
method: 'POST',
url: '/smartit/rest/attachment/file/' + type,
data: attachment.attachmentReference,
responseType: 'blob'
};
}
// Comments from MyIT via POI Asset
else if (attachment.id && isMyITComment) {
request = {
method: 'GET',
url: '/smartit/rest/attachment/social/file/download/' + attachment.id,
responseType: 'blob'
};
}
// For broadcast created from UC, the attachment will not contain attachmentReference, use a different rest call
// so that attachment is retrieved from Social instead of AR
else if (attachment.id) {
request = {
method: 'GET',
url: '/smartit/rest/attachment/file/' + type + '/get/' + attachment.id,
responseType: 'blob'
};
}
else {
return $q.reject('attachment info missing');
}
if (window.FormData) {
return $http(request).success(function (fileAsBlob) {
if (returnAsBlob) {
return fileAsBlob;
}
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
// IE Specific
var blobObject = new Blob([fileAsBlob]);
window.navigator.msSaveOrOpenBlob(blobObject, attachment.name);
attachment.loadingDetails = false;
}
else {
// use timeout to get around the '$digest already in progress' exception
$timeout(function () {
var a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
var objectUrl = URL.createObjectURL(fileAsBlob);
attachment.loadingDetails = false;
a.href = objectUrl;
a.download = attachment.name;
a.click();
// FireFox won't work if this line is present -> URL.revokeObjectURL(objectUrl);
a.remove();
}, 0);
}
});
}
else {
var url = '/smartit/rest/attachment/file/' + type + '?name=' + attachment.name;
if (!_.isEmpty(attachment.attachmentReference)) {
_.each(attachment.attachmentReference, function (refValue, key) {
url += '&' + key + '=' + refValue;
});
}
else if (attachment.id) {
url = '/smartit/rest/attachment/file/' + type + '/get/' + attachment.id;
}
window.location.href(url); //due to proper headers url change does not happen
attachment.loadingDetails = false;
return $q.when(1);
}
};
/**
* Prepares file for upload
*
* @param options
* @returns {{pendingSave: boolean}}
*/
this.prepareFileToUpload = function (options) {
var attachment = prepareFileToUploadInternal(options);
if (attachment && !configurationModel.isFileExtensionAllowed(attachment.fileExt)) {
systemAlertService.error({
text: $filter('i18n')('attachment.fileExtension.error'),
clear: false
});
attachment = null;
}
return attachment;
};
function prepareFileToUploadInternal(options) {
var thumbnailFormats = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tga', 'tif', 'tiff'], fileInput = options.fileInput, fileToUpload = { pendingSave: true };
if (window.FileReader) {
var file;
if (!options.fileToPrepare) {
var inputDOM = angular.element(options.fileInput || '.' + options.inputClass);
file = inputDOM[0].files[0];
}
else {
file = options.fileToPrepare;
}
var dataUrlFileReader = new FileReader(), binaryFileReader = new FileReader();
fileToUpload.name = file.name;
fileToUpload.size = file.size;
fileToUpload.file = file;
var extMatch = fileToUpload.name.match(/\.([^\.]*)$/);
if (extMatch) {
fileToUpload.fileExt = extMatch[1];
if (thumbnailFormats.indexOf(fileToUpload.fileExt.toLowerCase()) !== -1) {
dataUrlFileReader.readAsDataURL(file);
dataUrlFileReader.onload = function (event) {
$timeout(function () {
fileToUpload.thumbnail = event.target.result;
if (fileToUpload.thumbnail) {
var m = fileToUpload.thumbnail.match('data:(.*)?;');
fileToUpload.contentType = m && m[1] || null;
}
});
};
}
else {
$timeout(function () {
fileToUpload.fileGenericIconClass = new AttachmentVO().getFileGenericIconClass(fileToUpload.name);
});
}
}
binaryFileReader.readAsArrayBuffer(file);
binaryFileReader.onload = function (event) {
$timeout(function () {
fileToUpload.binaryData = event.target.result;
});
};
return fileToUpload;
}
else {
if (!fileInput.value) {
return;
}
var filePath = fileInput.value;
fileToUpload.fileInput = angular.element(fileInput);
fileToUpload.name = (filePath.indexOf('/') >= 0) ? filePath.split('/').pop() : filePath.split('\\').pop();
fileToUpload.fileGenericIconClass = new AttachmentVO().getFileGenericIconClass(fileToUpload.name);
$timeout(function () {
fileToUpload.fileInput
.before(fileInput.cloneNode())
.hide();
});
return fileToUpload;
}
}
/**
* Dismiss attachment
*
* @param scope
* @param $event
* @param attachment
* @param context
*/
this.dismissAttachment = function (scope, $event, attachment, context) {
var index = scope.attachments.indexOf(attachment);
if (index >= 0) {
var removed = scope.attachments.splice(index, 1);
if (!attachment.attachmentReference) {
scope.attachmentToUpload.splice(scope.attachmentToUpload.indexOf(attachment), 1);
}
else {
if (context && context === 'detail') {
scope.attachmentToDelete.push(removed[0]);
}
}
var descField = objectValueMapperService.getFieldByName('desc');
if (descField) {
// process attachments to delete
descField.value.attachmentToDelete = scope.attachmentToDelete;
descField.value.attachmentToUpload = scope.attachmentToUpload;
}
}
$event.stopImmediatePropagation();
};
/**
* Upload attachment
*
* @param profileType
* @param id
* @param attachments
* @returns {*}
*/
this.uploadAttachment = function (profileType, id, attachments) {
if (window.FileReader) {
return resource.uploadAttachment({ type: profileType, id: id }, attachments).$promise
.then(function (response) {
if (!response[0]) {
return [];
}
attachments.pendingSave = false;
var normalizedResp = normalizeAttachments(response);
_.each(normalizedResp, function (attachInfo) {
var attachFile = _.findWhere(attachments, { name: attachInfo.name });
if (attachFile) {
// SW00547633 - For task, we are passing an array here and line 493 is working
// differently when compared with passing an object for other ticket types and this
// is causing issues with deep cloning of ticket. So, this is a hack to fix the
// issue with deep cloning and to keep the changes minimal, need to be addressed later
attachFile.binaryData = undefined;
angular.extend(attachInfo, attachFile);
}
attachInfo.pendingSave = false;
});
return normalizedResp;
})
.catch(function (err) {
systemAlertService.error({
text: err.data.error,
clear: false
});
return $q.reject(err);
});
}
else {
var config = prepareIframeTransportSettings('attachments', {
type: profileType,
id: id
}, attachments);
return this.uploadUsingIframeTransport(config);
}
};
/**
* Upload using iframe transport
* @param config
* @param noDataNormalization
* @returns {ng.IPromise<T>|promise}
*/
this.uploadUsingIframeTransport = function (config, noDataNormalization) {
var uploadDefer = $q.defer();
$.ajax(config).success(function (resp) {
console.log(resp);
var respJSON = resp ? JSON.parse(resp) : [];
var respData = noDataNormalization ? respJSON : normalizeAttachments(respJSON);
uploadDefer.resolve(respData);
});
return uploadDefer.promise;
};
/**
* Delete attachment
*
* @param type
* @param params
* @returns {ng.IPromise<TResult>|*}
*/
this.deleteAttachment = function (type, params) {
return $http({
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
url: '/smartit/rest/attachment/' + type,
data: params
})
.catch(function (err) {
systemAlertService.error({
text: err.data.error,
clear: false
});
return $q.reject(err);
});
};
/**
* Upload profile thumbnail
*
* @param id
* @param type
* @param fileInput
* @param query
* @returns {*}
*/
this.uploadProfileThumbnail = function (id, type, fileInput, query) {
var profileImage = this.prepareFileToUpload({ fileInput: fileInput });
if (profileImage) {
if (window.FileReader) {
return resource.uploadProfileThumbnail({
type: type,
id: id,
query: query
}, profileImage).$promise;
}
else {
var config = prepareIframeTransportSettings('thumbnail', {
type: type,
id: id,
query: query
}, profileImage), uploadDefer = $q.defer();
$.ajax(config).success(function (resp) {
console.log(resp);
uploadDefer.resolve({ thumbnail: resp });
});
return uploadDefer.promise;
}
}
return $q.when({});
};
/**
* Add worknote with attachment
*
* @param params
* @param worknote
* @returns {*}
*/
this.addWorknoteWithAttachment = function (params, worknote) {
if (window.FileReader) {
return resource.addWorknoteWithAttachment(params, worknote).$promise;
}
else {
var data = [
{ name: 'text', value: worknote.noteText },
{ name: 'access', value: worknote.access },
{ name: 'type', value: worknote.workInfoType }
];
var config = prepareIframeTransportSettings('worknoteCreate', {
type: params.type,
id: params.id,
classId: params.classId
}, worknote.attachments, data);
return this.uploadUsingIframeTransport(config, true);
}
};
this.addWorknoteWithAttachmentBulk = function (worknote) {
if (window.FileReader) {
return resource.addWorknoteWithAttachmentBulk(worknote).$promise;
}
else {
var data = [
{ name: 'text', value: worknote.noteText || worknote.worknote },
{ name: 'access', value: worknote.access }
];
worknote.locked && data.push({ name: 'locked', value: worknote.locked });
worknote['Email.Subject'] && data.push({ name: 'Email.Subject', value: worknote['Email.Subject'] });
worknote['Email.Body'] && data.push({ name: 'Email.Body', value: worknote['Email.Body'] });
worknote['Email.From.Person'] && data.push({ name: 'Email.From.Person', value: JSON.stringify(worknote['Email.From.Person']) });
worknote['Email.To.Person'] && data.push({ name: 'Email.To.Person', value: JSON.stringify(worknote['Email.To.Person']) });
worknote['Email.To.InternetEmail'] && data.push({ name: 'Email.To.InternetEmail', value: worknote['Email.To.InternetEmail'] });
worknote.ticketList && data.push({ name: 'ticketList', value: JSON.stringify(worknote.ticketList) });
var config = prepareIframeTransportSettings('worknoteCreateBulk', undefined, worknote.attachments, data);
return this.uploadUsingIframeTransport(config, true);
}
};
/**
* Add attachment to worknote
*
* @param type
* @param id
* @param attachment
* @param classId
* @returns {*}
*/
this.addAttachmentToWorknote = function (type, id, attachment, classId) {
if (window.FileReader) {
return resource.addAttachmentToWorknote({ type: type, id: id }, attachment).$promise;
}
else {
var config = prepareIframeTransportSettings('worknoteUpdate', {
type: type,
id: id,
classId: classId
}, attachment);
return this.uploadUsingIframeTransport(config);
}
};
this.createChangePlan = function (id, type, plan) {
return resource.createChangePlan({ id: id, type: type }, plan).$promise.then(function (response) {
if (!response[0] || !response[0].items || !response[0].items[0]) {
return [];
}
var plans = response[0].items;
_.each(plans, function (plan) {
if (plan.workNote.attachmentCount > 0) {
plan.attachmentInfos = normalizeAttachments(plan);
}
});
return { data: plans, action: 'created' };
});
};
this.updateChangePlan = function (params, request) {
return resource.updateChangePlan(params, request).$promise.then(function (response) {
if (!response[0] || !response[0].items || !response[0].items[0]) {
return [];
}
var plans = response[0].items;
_.each(plans, function (plan) {
if (plan.workNote.attachmentCount > 0) {
plan.attachmentInfos = normalizeAttachments(plan);
}
});
return { data: plans, action: 'updated' };
}).catch(function (err) {
systemAlertService.error({
text: err.data.error,
clear: false
});
return $q.reject(err);
});
};
this.deletePlan = function (parentId, type, planId) {
return resource.deletePlan({ parentId: parentId, type: type, planId: planId }).$promise
.then(function () {
return { data: [planId], action: 'deleted' };
});
};
this.normalizeAttachments = function (data) {
return normalizeAttachments(data);
};
this.showAttachmentPreviewDialog = function (planData) {
return $modal.open({
template: '<attachments-previewer plan="plan"></attachments-previewer>',
windowClass: 'attachments-previewer-modal',
backdropClass: 'attachments-previewer-backdrop',
controller: ['$scope', function ($scope) {
$scope.plan = planData;
}]
});
};
function prepareIframeTransportSettings(reqType, urlParams, attachments, data) {
var defaultConfig = {
url: '',
files: '',
iframe: true,
dataType: 'text'
};
switch (reqType) {
case 'thumbnail':
defaultConfig.url = '/smartit/rest/' + urlParams.type + '/' + urlParams.id + '/thumbnail' + (urlParams.query ? '?' + urlParams.query : '');
break;
case 'attachments':
defaultConfig.url = '/smartit/rest/attachment/file/' + urlParams.type + '/' + urlParams.id;
break;
case 'worknoteCreate':
defaultConfig.url = '/smartit/rest/attachment/file/' + urlParams.type + '/' + urlParams.id + '/' + (urlParams.classId ? urlParams.classId + '/' : '') + 'worknote';
break;
case 'worknoteCreateBulk':
defaultConfig.url = '/smartit/rest/attachment/file/bulk/worknote';
break;
case 'worknoteUpdate':
defaultConfig.url = '/smartit/rest/attachment/file/worknote/' + urlParams.type + '/' + urlParams.id + (urlParams.classId ? '/' + urlParams.classId : '');
}
var fileInput;
if (_.isArray(attachments)) {
fileInput = [];
_.each(attachments, function (item, index) {
item.fileInput.attr({ name: 'file[]', multiple: 'true', id: 'attachmentFile_' + index });
item.fileInput.prop('value', 'sdfasdfasdfasd');
item.fileInput.prop('disabled', null);
fileInput.push(item.fileInput[0]);
});
}
else {
fileInput = attachments.fileInput;
fileInput.prop('disabled', null);
}
if (data) {
defaultConfig.data = data;
defaultConfig.processData = false;
}
defaultConfig.files = fileInput;
return defaultConfig;
}
function normalizeAttachments(data) {
return (data[0] ? (data[0].items || []) : (data.attachmentInfos || [])).map(function (attachment) {
return new AttachmentVO().build(attachment);
});
}
function prepareFormDataForPlans(data) {
var formData = new FormData();
formData.append('text', data.text);
formData.append('type', data.type);
!_.isUndefined(data.access) && formData.append('access', data.access);
!_.isUndefined(data.locked) && formData.append('locked', data.locked);
if (data.attachmentInfos.length > 0) {
formData.append('attachmentInfos', JSON.stringify(data.attachmentInfos));
for (var i = 0, l = data.attachments.length; i < l; i++) {
formData.append('file', data.attachments[i].file);
}
}
return formData;
}
}
]);
})();