/**
* Copyright (C) 2005-2016 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* This handles publications requesting to perform actions on documents. It instantiates a "legacy" YUI2 based
* Alfresco.DocListToolbar widget which is delegated any actions that aren't explicitly handled by the service.
* Over time this service should handle more and more of the core document actions as the old YUI2 code is phased
* out. However, currently it just aliases those actions as well as any custom actions that are registered by
* extensions.
*
* Custom actions prior to 4.2 were provided via the YAHOO.Bubbling.fire("registerAction" ...) event
* where the target function accepted a single argument of the file to work with.
*
* "action.js" handles the registering of these functions.
* "toolbar.js" augments its prototype with that of "action.js" to get all of the default action handlers
* and in turn will be able to register additional handlers.
*
* Custom actions only supported single files in versions prior to 4.2
*
* @module alfresco/services/ActionService
* @extends module:alfresco/services/BaseService
* @mixes module:alfresco/core/CoreXhr
* @mixes module:alfresco/documentlibrary/_AlfDocumentListTopicMixin
* @mixes module:alfresco/services/_NavigationServiceTopicMixin
* @mixes module:alfresco/core/UrlUtilsMixin
* @mixes module:alfresco/core/NotificationUtils
* @author Dave Draper & David Webster
*/
define(["dojo/_base/declare",
"alfresco/services/BaseService",
"alfresco/core/CoreXhr",
"alfresco/core/topics",
"alfresco/enums/urlTypes",
"service/constants/Default",
"alfresco/documentlibrary/_AlfDocumentListTopicMixin",
"alfresco/services/_NavigationServiceTopicMixin",
"alfresco/core/UrlUtilsMixin",
"alfresco/core/ArrayUtils",
"alfresco/core/ObjectTypeUtils",
"alfresco/core/JsNode",
"alfresco/core/NotificationUtils",
"dojo/_base/lang"],
function(declare, BaseService, AlfCoreXhr, topics, urlTypes, AlfConstants, _AlfDocumentListTopicMixin, _NavigationServiceTopicMixin,
UrlUtilsMixin, ArrayUtils, ObjectTypeUtils, JsNode, NotificationUtils, lang) {
// TODO: L18N sweep - lots of widgets defined with hard coded labels...
return declare([BaseService, AlfCoreXhr, _AlfDocumentListTopicMixin, _NavigationServiceTopicMixin, UrlUtilsMixin, NotificationUtils], {
/**
* An array of the i18n files to use with this widget.
*
* @instance
* @type {object[]}
* @default [{i18nFile: "./i18n/ActionService.properties"}]
*/
i18nRequirements: [{i18nFile: "./i18n/ActionService.properties"}],
/**
* This should be set when the current context is a site.
*
* @instance
* @type {string}
* @default
*/
siteId: null,
/**
* This should be set when the current context is a site, typically this will be set to "documentlibrary"
*
* @instance
* @type {string}
* @default
*/
containerId: null,
/**
* This can be set to either "NEW" or "CURRENT" to indicate whether or not a linked page is displayed
* in the current or a new window/tab. This setting is only honoured if an action is not explicitly
* configured with a target.
*
* @instance
* @type {string}
* @default
*/
currentTarget: "CURRENT",
/**
* This should be set if "siteId" is not set.
*
* @instance
* @type {string}
* @default
*/
rootNode: null,
/**
* Sets up the subscriptions for the Action Service
*
* @instance
* @since 1.0.32
*
* @listens module:alfresco/core/topics#MULTIPLE_ITEM_ACTION_REQUEST
*/
registerSubscriptions: function alfresco_services_ActionService__registerSubscriptions() {
// Normal processing...
this.currentlySelectedDocuments = {};
this.alfSubscribe(this.documentsLoadedTopic, lang.hitch(this, this.onDocumentsLoaded));
this.alfSubscribe(this.metadataChangeTopic, lang.hitch(this, this.handleCurrentNodeChange));
this.alfSubscribe(this.documentSelectedTopic, lang.hitch(this, this.onDocumentSelected));
this.alfSubscribe(this.documentDeselectedTopic, lang.hitch(this, this.onDocumentDeselected));
this.alfSubscribe(this.singleDocumentActionTopic, lang.hitch(this, this.handleSingleDocAction));
this.alfSubscribe(this.syncLocationTopic, lang.hitch(this, this.onSyncLocation));
this.alfSubscribe(this.unsyncLocationTopic, lang.hitch(this, this.onUnsyncLocation));
this.alfSubscribe(topics.MULTIPLE_ITEM_ACTION_REQUEST, lang.hitch(this, this.handleMultiDocLegacyAction));
this.alfSubscribe("ALF_CREATE_CONTENT", lang.hitch(this, this.processActionObject));
// Non-legacy action handlers...
this.alfSubscribe("ALF_MOVE_DOCUMENTS", lang.hitch(this, this.onMoveDocuments));
// Response handlers...
this.alfSubscribe("ALF_ON_ACTION_EDIT_INLINE_SUCCESS", lang.hitch(this, this.onActionEditInlineSucess));
},
/**
* Generic file action event handler
*
* @instance
* @param layer {object} Event fired
* @param args {array} Event parameters (depends on event type)
*/
onFileAction: function alfresco_services_ActionService__onFileAction(layer, args) {
var obj = args[1];
if (obj)
{
if (!obj.multiple)
{
this.requestRefresh();
}
}
},
/**
* @instance
*/
requestRefresh: function alfresco_services_ActionService__requestRefresh() {
this.alfPublish(this.reloadDataTopic, {});
},
/**
* The primary purpose of this function is to reset the 'currentlySelectedDocuments' attribute.
*
* @instance
* @param {object} payload The details of the documents loaded
*/
onDocumentsLoaded: function alfresco_services_ActionService__onDocumentsLoaded(payload) {
this.alfLog("log", "New Documents Loaded", payload);
this.currentlySelectedDocuments = {};
this.onSelectedItemsChanged();
},
/**
* The current Node that content will be worked relative to.
* @instance
* @type {object}
* @default
*/
_currentNode: null,
/**
*
* @instance
*/
handleCurrentNodeChange: function alfresco_services_ActionService__handleCurrentNodeRefChange(payload) {
if (payload && payload.node)
{
this.alfLog("log", "Updating current nodeRef to: ", payload.node);
this._currentNode = payload.node;
}
else
{
this.alfLog("error", "A request was made to update the current NodeRef, but no 'node' property was provided in the payload: ", payload);
}
},
/**
* This function handles requests to perform an action on a single document. The action will be handled by the legacy action handler.
*
* @instance
* @param payload
*/
handleSingleDocAction: function alfresco_services_ActionService__handleSingleDocAction(payload) {
this.alfLog("log", "Single document action request:", payload);
if (payload &&
payload.document &&
payload.action)
{
if (typeof payload.action === "string")
{
if (typeof this[payload.action] === "function")
{
// Then check the actions provided by this service...
this[payload.action](payload);
}
else
{
this.alfLog("warn", "No handler implemented to handle this function", this);
}
}
else if (typeof payload.action === "object")
{
// If the action is an object then it is assumed to contain information for processing
// via the legacy toolbar.
this.processActionObject(payload);
}
}
},
/**
* This function is called when handling actions for the currently selected items. If the
* payload provided does not include a "documents" attribute then one will be created and
* populated with the selected items that have been tracked by this service. Ideally this
* will not be necessary as the payload should include the items populated by the
* [AlfSelectedItemsMenuBarPopup]{@link module:alfresco/documentlibrary/AlfSelectedItemsMenuBarPopup}.
*
* @instance
* @param {object} payload The data passed in the request to perform the action.
* @since 1.0.38
*/
addSelectedItems: function alfresco_services_ActionService__addSelectedItems(payload) {
if (!payload.documents)
{
payload.documents = [];
for (var nodeRef in this.currentlySelectedDocuments)
{
if (this.currentlySelectedDocuments.hasOwnProperty(nodeRef))
{
payload.documents.push(this.currentlySelectedDocuments[nodeRef]);
}
}
}
// NOTE: We also want to add the selected items to a "nodes" attribute as that is the attribute
// that some of the services will be expecting. This is regrettable but until the next major
// release we won't be able to remove these inconsistencies. By including the selected items
// as "nodes" it allows us to forward to "actionTopics" without the need to create individual
// actions to alias all the capabilities provided by other services.
payload.nodes = payload.documents;
},
/**
*
* @instance
* @param {object} payload The data passed in the request to perform the action.
*/
handleMultiDocLegacyAction: function alfresco_services_ActionService__handleMultiDocLegacyAction(payload) {
this.alfLog("log", "Multiple document action request:", payload);
if (typeof this[payload.action] === "function")
{
this.addSelectedItems(payload);
this[payload.action].call(this, payload);
}
else if (payload.actionTopic)
{
// If an "actionTopic" attribute has been defined then it will be used to "forward" on the
// provided payload to the topic defined. This was added in 1.0.38 as a way in which to make
// it easier to process custom menu items added to a AlfSelectedItemsMenuBarPopup.
this.addSelectedItems(payload);
this.alfServicePublish(payload.actionTopic, payload);
}
},
/**
* This is used to keep track of the documents that are currently selected. It is initialised to an empty
* array in the constructor, the onDocumentSelected function adds elements and the onDocumentDeselected
* function removes them.
*
* @instance
* @type {object}
* @default
*/
currentlySelectedDocuments: null,
/**
* This is used to keep a reference to a timeout that is started on the publication of a selected document
* topic. It is important that multiple selection events can be captured so that only one publication of
* selected items occurs. Otherwise the responsiveness ot the UI is degraded as each individual selection
* event is processed (e.g. by [AlfDocumentActionMenuItems]{@link module:alfresco/documentlibrary/AlfDocumentActionMenuItem})
*
* @instance
* @type {timeout}
* @default
*/
selectionTimeout: null,
/**
* Updates the aray of documents that are currently selected.
* @instance
* @param {object} payload The details of the document selected
*/
onDocumentSelected: function alfresco_services_ActionService__onDocumentSelected(payload) {
var payloadNoderef = payload && payload.value && payload.value.node && payload.value.node.nodeRef;
if (payloadNoderef)
{
this.currentlySelectedDocuments[payloadNoderef] = payload.value;
if (this.selectionTimeout)
{
clearTimeout(this.selectionTimeout);
}
this.selectionTimeout = setTimeout(lang.hitch(this, this.deferredSelectionHandler), 50);
}
},
/**
* This is called from [onDocumentSelected]{@link module:alfresco/services/ActionService#onDocumentSelected}
* when the [selectionTimeout]{@link module:alfresco/services/ActionService#selectionTimeout} times out. It
* rests the [selectionTimeout]{@link module:alfresco/services/ActionService#selectionTimeout} to null and
* calls [onSelectedItemsChanged]{@link module:alfresco/services/ActionService#deselectionTimeout}
*
* @instance
*/
deferredSelectionHandler: function alfresco_services_ActionService__deferredSelectionHandler() {
this.onSelectedItemsChanged();
this.selectionTimeout = null;
},
/**
* Updates the array of documents that are currently selected.
*
* @instance
* @param {object} payload The details of the document selected
*/
onDocumentDeselected: function alfresco_services_ActionService__onDocumentDeselected(payload) {
var payloadNoderef = payload && payload.value && payload.value.node && payload.value.node.nodeRef;
if (payloadNoderef)
{
delete this.currentlySelectedDocuments[payloadNoderef];
if (this.selectionTimeout)
{
clearTimeout(this.selectionTimeout);
}
this.selectionTimeout = setTimeout(lang.hitch(this, this.deferredSelectionHandler), 50);
}
},
/**
* Converts the currently selected documents object into an array for easier iteration.
*
* @instance
*/
getSelectedDocumentArray: function alfresco_services_ActionService__getSelectedDocumentArray() {
var a = [];
for (var key in this.currentlySelectedDocuments)
{
if (this.currentlySelectedDocuments.hasOwnProperty(key))
{
a.push(this.currentlySelectedDocuments[key]);
}
}
return a;
},
/**
* Handle changes in file selection by updating the ActionService 'currentlySelectedDocuments' attribute
* so that other handlers can apply actions to the appropriate files and then evaluates the permissions
* and aspects on the selected files and publishes the details on the 'selectedDocumentsChangeTopic' attribute
* topic to allow menus to filter actions appropriately.
*
* @instance
*/
onSelectedItemsChanged: function alfresco_services_ActionService__onSelectedItemsChanged() {
/*jshint maxcomplexity:false*/
var files = this.getSelectedDocumentArray(), fileTypes = [], file,
fileType, userAccess = {}, fileAccess, index,
commonAspects = [], allAspects = [],
i, ii, j, jj;
var fnFileType = function(_file) {
return (_file.node.isContainer ? "folder" : "document");
};
// Check each file for user permissions
for (i = 0, ii = files.length; i < ii; i++)
{
file = files[i];
// Required user access level - logical AND of each file's permissions
fileAccess = file.node.permissions.user;
for (index in fileAccess)
{
if (fileAccess.hasOwnProperty(index))
{
userAccess[index] = (userAccess[index] === undefined ? fileAccess[index] : userAccess[index] && fileAccess[index]);
}
}
// Make a note of all selected file types Using a hybrid array/object so we can use both array.length and "x in object"
fileType = fnFileType(file);
if (!(fileType in fileTypes))
{
fileTypes[fileType] = true;
fileTypes.push(fileType);
}
// Build a list of common aspects
if (i === 0)
{
// first time around fill with aspects from first node -
// NOTE copy so we don't remove aspects from file node.
commonAspects = lang.clone(file.node.aspects);
} else
{
// every time after that remove aspect if it isn't present on the current node.
for (j = 0, jj = commonAspects.length; j < jj; j++)
{
if (!ArrayUtils.arrayContains(file.node.aspects, commonAspects[j]))
{
ArrayUtils.arrayRemove(commonAspects, commonAspects[j]);
}
}
}
// Build a list of all aspects
for (j = 0, jj = file.node.aspects.length; j < jj; j++)
{
if (!ArrayUtils.arrayContains(allAspects, file.node.aspects[j]))
{
allAspects.push(file.node.aspects[j]);
}
}
}
// Publish the information about the actions so that menu items can be filtered...
this.alfPublish(this.selectedDocumentsChangeTopic, {
selectedItems: files,
userAccess: userAccess,
commonAspects: commonAspects,
allAspects: allAspects,
fileTypes: fileTypes
});
},
/**
* This function handles requests to create new content. It handles content creation of 4 different types:
* - pagelink (a link to another page within the application)
* - link (a link to an external page)
* - javascript (calls a JavaScript action handler)
* - template (creates templated content)
*
* @instance
* @param {object} payload The original payload requesting the action
*/
processActionObject: function alfresco_services_ActionService__processActionObject(payload) {
/*jshint maxcomplexity:false*/
var action = payload.action;
var document = payload.document;
if (action && action.type)
{
if (action.type === "pagelink")
{
if (action.params.page)
{
this.createPageLinkContent(action, document);
}
else
{
this.alfLog("error", "A request was made to perform an action. The 'pagelink' type was requested, but no 'page' attribute was provided: ", action);
}
}
else if (action.type === "link")
{
if (action.params.href)
{
this.createLinkContent(action, document);
}
else
{
this.alfLog("error", "A request was made to perform an action. The 'link' type was requested, but no 'href' attribute was provided: ", action);
}
}
else if (action.type === "javascript")
{
if (action.params["function"])
{
this.createJavaScriptContent(payload);
}
else
{
this.alfLog("error", "A request was made to perform an action. The 'javascript' type was requested, but no 'function' attribute was provided: ", action);
}
}
else if (action.type === "template")
{
if (action.params.sourceNodeRef)
{
this.alfPublish("ALF_CREATE_TEMPLATE_CONTENT", {
sourceNodeRef: action.params.sourceNodeRef,
targetNodeRef: action.params.targetNodeRef,
templateType: action.params.templateType || "node",
name: action.params.name || "",
title: action.params.title || "",
description: action.params.description || "",
responseScope: payload.alfResponseScope
});
}
else
{
this.alfLog("error", "A request was made to perform an action. The 'template' type was requested, but no 'nodeRef' attribute was provided: ", action);
}
}
else
{
this.alfLog("error", "A request was made to perform an action, but an unknown 'type' was provided: ", action);
}
}
else
{
this.alfLog("error", "A request was made to perform an action, but no 'type' was provided in the payload: ", action);
}
},
/**
* Links to another page within Share to handle the content creation.
*
* @instance
* @param {object} payload
* @param {object} document The document to perform the action using.
*/
createPageLinkContent: function alfresco_services_ActionService__createPageLinkContent(payload, document) {
var url = payload.params.page;
if (document)
{
// TODO: Need to check other substitution points...
url = lang.replace(url, document);
}
else if (this._currentNode)
{
url = lang.replace(url, { nodeRef: this._currentNode.parent.nodeRef});
}
var publishPayload = {
type: urlTypes.PAGE_RELATIVE,
url: url,
target: this.currentTarget
},
site = lang.getObject("location.site.name", false, document);
if (site)
{
publishPayload.site = site;
}
// Make a request to navigation to a the URL (relative to the Share page content) within the current window...
this.alfPublish(this.navigateToPageTopic, publishPayload);
},
/**
* Links to an external page to handle content creation.
*
* @instance
* @param {object} payload The payload published on the requesting topic
* @param {object} document The document to perform the action on.
*/
createLinkContent: function alfresco_services_ActionService__createLinkContent(payload, document) {
// Make a request to navigation to a the URL defined within the current window...
var url = lang.replace(payload.params.href, this.getActionUrls(document, this.siteId, this.repositoryUrl, this.replicationUrlMapping));
var indexOfTarget = url.indexOf("\" target=\"_blank");
var target = "CURRENT";
if (indexOfTarget !== -1)
{
url = url.substring(0, indexOfTarget);
target = "NEW";
}
else if (this.currentTarget === "NEW")
{
target = "NEW";
}
this.alfPublish(this.navigateToPageTopic, {
type: urlTypes.FULL_PATH,
url: url,
target: target
});
},
/**
* Calls a JavaScript function to handle content creation.
*
* @instance
* @param {object} payload The payload published on the requesting topic
*/
createJavaScriptContent: function alfresco_services_ActionService__createJavaScriptContent(payload) {
if (!payload.document)
{
// NOTE: Ideally we want to be avoid using a contextual _currentNode, we should be providing
// all the data required by the service in the request, but this remains for legacy support
var node = lang.clone(this._currentNode.parent);
payload.document = {
nodeRef: node.nodeRef,
node: node,
jsNode: new JsNode(node)
};
}
// See if the requested function is provided by this service and if not delegate to the Alfresco.DocLibToolbar widget.
var f = this[payload.action.params["function"]];
if (typeof f === "function")
{
f.call(this, payload);
}
else
{
this.alfLog("warn", "Could not find action handler", this, payload);
}
},
/**
* Handles requests to edit the basic metadata of the node provided.
*
* @instance
* @param {object} payload The response from the request
*/
onActionDetails: function alfresco_services_ActionService__onActionDetails(payload) {
// Sometimes the node might be an array of nodes, can only edit the first...
if (payload.document)
{
this.alfPublish("ALF_EDIT_BASIC_METADATA_REQUEST", payload);
}
else
{
this.alfLog("warn", "A request was made to edit the properties of a node but no node was provided", payload, this);
}
},
/**
* Handles requests to upload a new version of the supplied document.
*
* @instance
* @param {object} payload The payload supplied on the original request
*/
onActionUploadNewVersion: function alfresco_services_ActionService__onActionUploadNewVersion(payload) {
// jshint unused:false
// Call dialog service to open dialog with upload widget in.
this.alfPublish("ALF_SHOW_UPLOADER", payload);
},
/**
* Cancels Editing for checked out documents.
*
* @param {object} payload The payload supplied on the original request
*/
onActionCancelEditing: function alfresco_services_ActionService__onActionCancelEditing(payload) {
this.alfPublish("ALF_DOC_CANCEL_EDITING", payload);
},
/**
* Handles requests to edit a document inline.
*
* @instance
* @param {object} payload The response from the request
* @param {object} document The document to edit.
*/
onActionEditInline: function alfresco_services_ActionService__onActionEditInline(payload, document) {
if (!document || !document.nodeRef)
{
this.alfLog("warn", "A request was made to edit the properties of a document but no document or 'nodeRef' attribute was provided", document, this);
}
else
{
// TODO: We're not yet setting up a failure response handler, this is just working on the golden path at the moment...
this.alfPublish("ALF_RETRIEVE_SINGLE_DOCUMENT_REQUEST", {
alfResponseTopic: "ALF_ON_ACTION_EDIT_INLINE",
nodeRef: document.nodeRef,
includeContent: true
});
}
},
/**
* This function will be called in response to a documents details being successfully retrieved.
*
* @instance
* @param {object} payload
*
* @fires ALF_CREATE_FORM_DIALOG_REQUEST
*/
onActionEditInlineSucess: function alfresco_services_ActionService__onActionEditInlineSucess(payload) {
if (!lang.exists("response.item.node", payload))
{
this.alfLog("warn", "When processing a request to display document properties, the expected 'response.item.node' attribute was not found", payload, this);
}
else
{
var node = lang.getObject("response.item.node", false, payload);
var content = lang.getObject("response.itemContent", false, payload);
this.alfPublish("ALF_CREATE_FORM_DIALOG_REQUEST", {
dialogTitle: "Edit: " + node.properties["cm:name"],
dialogConfirmationButtonTitle: "Save",
dialogCancellationButtonTitle: "Cancel",
formSubmissionTopic: "ALF_UPDATE_CONTENT_REQUEST",
widgets: [
{
name: "alfresco/forms/controls/DojoValidationTextBox",
config: {
name: "nodeRef",
value: node.nodeRef,
visibilityConfig: {
initialValue: false
}
}
},
{
name: "alfresco/forms/controls/DojoValidationTextBox",
config: {
name: "prop_mimetype",
value: node.mimetype,
visibilityConfig: {
initialValue: false
}
}
},
{
name: "alfresco/forms/controls/DojoValidationTextBox",
config: {
name: "prop_app_editInline",
value: true,
visibilityConfig: {
initialValue: false
}
}
},
{
name: "alfresco/forms/controls/DojoValidationTextBox",
config: {
label: "Name",
description: "The name to give the new document",
name: "prop_cm_name",
value: node.properties["cm:name"],
requirementConfig: {
initialValue: true
}
}
},
{
name: "alfresco/forms/controls/DojoValidationTextBox",
config: {
label: "Title",
description: "The title to give to the new document",
name: "prop_cm_title",
value: node.properties["cm:title"]
}
},
{
name: "alfresco/forms/controls/TextArea",
config: {
label: "Description",
description: "A description of the folder",
name: "prop_cm_description",
value: node.properties["cm:description"]
}
},
{
name: "alfresco/forms/controls/AceEditor",
config: {
mimeType: node.mimetype,
label: "Content",
description: "The content for the document",
name: "prop_cm_content",
value: content
}
}
]
});
}
},
/**
* Handles requests to edit the supplied document offline. This posts a request to the
* "/slingshot/doclib/action/checkout/node/{store_type}/{store_id}" repository WebScript to
* checkout the document. Successful requests are handled by the
* [onActionEditOfflineSuccess]{@link module:alfresco/services/ActionsService#onActionEditOfflineSuccess} function
* and failed requests are handled by the [onActionEditOfflineFailure]{@link module:alfresco/services/ActionsService#onActionEditOfflineFailure}
* function.
*
* @instance
* @param {object} payload The payload from the original action request
*/
onActionEditOffline: function alfresco_services_ActionService__onActionEditOffline(payload) {
// Document might be an array.
var document = (ObjectTypeUtils.isArray(payload.document))? payload.document[0] : payload.document;
if (document && document.node && document.node.nodeRef)
{
var data = {
nodeRef: document.node.nodeRef,
displayName: lang.getObject("node.properties.cm:title", false, document) || lang.getObject("node.properties.cm:name", false, document)
};
var config = {
url: AlfConstants.PROXY_URI + "slingshot/doclib/action/checkout/node/" + data.nodeRef.replace("://", "/"),
method: "POST",
responseScope: payload.alfResponseScope,
data: data,
successCallback: this.onActionEditOfflineSuccess,
failureCallback: this.onActionEditOfflineFailure,
callbackScope: this
};
this.serviceXhr(config);
}
else
{
this.alfLog("error", "A request was made to edit a document offline, but the document supplied does not contain enough information", document);
}
},
/**
* This is the success callback handler from the XHR request made by [onActionEditOffline]{@link module:alfresco/services/ActionsService#onActionEditOffline}.
* The success response should contain a download URL for the checked out document which is then passed to the browser
* to automatically trigger a download of the document. A request is then published to reload the document list data.
*
* @instance
* @param {object} response The response from the request
* @param {object} originalRequestConfig The configuration passed on the original request
*/
onActionEditOfflineSuccess: function alfresco_services_ActionService__onActionEditOfflineSuccess(response, originalRequestConfig) {
this.alfLog("log", "Edit offline request success", response, originalRequestConfig);
if (response &&
response.results &&
response.results.length > 0 &&
response.results[0].downloadUrl)
{
this.displayMessage(this.message("message.edit-offline.success", {"0": response.results[0].id}));
this.alfPublish(this.navigateToPageTopic, {
url: AlfConstants.PROXY_URI + response.results[0].downloadUrl,
type: urlTypes.FULL_PATH
});
this.alfPublish(topics.RELOAD_DATA_TOPIC, {}, false, false, originalRequestConfig.responseScope);
}
else
{
this.alfLog("error", "A request to edit a document offline returned a successful response but did not provide a 'downloadUrl' attribute", response, originalRequestConfig);
}
},
/**
* This is the failure callback handler from the XHR request made by [onActionEditOffline]{@link module:alfresco/services/ActionsService#onActionEditOffline}.
* It prompts the user with a message indicating that the document could not be checked out.
*
* @instance
* @param {object} response The response from the request
* @param {object} originalRequestConfig The configuration passed on the original request
*/
onActionEditOfflineFailure: function alfresco_services_ActionService__onActionEditOfflineFailure(response, originalRequestConfig) {
this.alfLog("error", "Edit offline request failure", response, originalRequestConfig);
this.displayMessage(this.message("message.edit-offline.failure", {"0": originalRequestConfig.data.displayName}));
},
/**
* Handles requests to copy the supplied documents to another location.
*
* @instance
* @param {object} payload The payload from the original request
* @fires module:alfresco/core/topics#COPY_OR_MOVE
*/
onActionCopyTo: function alfresco_services_ActionService__onActionCopyTo(payload) {
var nodes = payload.documents || (payload.document ? [payload.document] : [payload]);
this.alfServicePublish(topics.COPY_OR_MOVE, {
documents: nodes,
copy: true,
responseScope: payload.alfResponseScope
});
},
/**
* Handles requests to move the supplied documents to another location.
*
* @instance
* @param {object} payload The payload from the original request
* @fires module:alfresco/core/topics#COPY_OR_MOVE
*/
onActionMoveTo: function alfresco_services_ActionService__onActionMoveTo(payload) {
var nodes = payload.documents || (payload.document ? [payload.document] : [payload]);
this.alfServicePublish(topics.COPY_OR_MOVE, {
documents: nodes,
copy: false,
responseScope: payload.alfResponseScope
});
},
/**
* Handles requests to delete the supplied document.
*
* @instance
* @param {object} payload The payload from the original request
* @fires module:alfresco/core/topics#DELETE_CONTENT
*/
onActionDelete: function alfresco_services_ActionService__onActionDelete(payload) {
this.alfPublish(topics.DELETE_CONTENT, payload);
},
/**
* Used by action handlers. Deletes subscription handle and reloads doclist.
*
* @instance
* @param {object} payload
*/
onActionCompleteSuccess: function alfresco_services_ActionService__onActionCompleteSuccess(payload) {
var subscriptionHandle = lang.getObject("requestConfig.subscriptionHandle", false, payload);
if (subscriptionHandle)
{
this.alfUnsubscribe(subscriptionHandle);
}
this.alfPublish("ALF_DOCLIST_RELOAD_DATA", {});
},
/**
* Assign workflow.
*
* @instance
* @param {object} payload The payload from the original request
* @fires module:alfresco/core/topics#ASSIGN_WORKFLOW
*/
onActionAssignWorkflow: function alfresco_services_ActionService__onActionAssignWorkflow(payload) {
this.alfPublish(topics.ASSIGN_WORKFLOW, {
nodes: payload.documents || [payload.document],
currentTarget: this.currentTarget
});
},
/**
* Handles requests to change the type of a node.
*
* @instance
* @param {object} payload The payload from the original request
* @since 1.0.58
* @fires module:alfresco/core/topics#CHANGE_TYPE_REQUEST
*/
onActionChangeType: function alfresco_services_ActionService__onActionChangeType(payload) {
this.alfPublish(topics.CHANGE_TYPE_REQUEST, payload.document);
},
/**
* Handles requests to sync content to the cloud.
*
* @instance
* @param {object} payload The payload from the original request
* @since 1.0.94
* @fires module:alfresco/core/topics#INIT_CLOUD_SYNC
*/
onActionCloudSync: function alfresco_services_ActionService__onActionCloudSync(payload) {
this.alfPublish(topics.INIT_CLOUD_SYNC, payload);
},
/**
* Handles requests to download multiple items as a single archive file. This is only expected to
* be called as a multiple item selection action
*
* @instance
* @param {object} payload The payload from the original request
* @since 1.0.33
* @fires module:alfresco/core/topics#DOWNLOAD_AS_ZIP
*/
onActionDownload: function alfresco_services_ActionService__onActionDownload(payload) {
this.alfPublish(topics.DOWNLOAD_AS_ZIP, payload);
},
/**
* Handles requests to start a folder download.
*
* @instance
* @param {object} payload The payload from the original request
* @fires module:alfresco/core/topics#DOWNLOAD_AS_ZIP
*/
onActionFolderDownload: function alfresco_services_ActionService__onActionFolderDownload(payload) {
this.alfPublish(topics.DOWNLOAD_AS_ZIP, payload);
},
/**
*
* @instance
* @param {object} payload The payload from the original request
*/
onActionManageAspects: function alfresco_services_ActionService__onActionManageAspects(payload) {
this.alfPublish("ALF_MANAGE_ASPECTS_REQUEST", payload.document);
},
/**
* Handles the "onActionSimpleRepoAction" that is used by multiple configured actions within Alfresco Share.
* The publication that mapped to the "action" attribute is called. Currently this is only supporting the
* "document-approve" and "document-reject" actions which are delegated to the
* [SimpleWorkflowService]{@link module:alfresco/services/actions/SimpleWorkflowService}.
*
* @instance
* @param {object} payload The payload from the original request
*/
onActionSimpleRepoAction: function alfresco_services_ActionService__onActionSimpleRepoAction(payload) {
switch (payload.action.id) {
case "document-approve":
this.alfPublish("ALF_APPROVE_SIMPLE_WORKFLOW", {
items: [payload.document],
action: payload.action.params.action,
responseScope: payload.alfResponseScope
});
break;
case "document-reject":
this.alfPublish("ALF_REJECT_SIMPLE_WORKFLOW", {
items: [payload.document],
action: payload.action.params.action,
responseScope: payload.alfResponseScope
});
break;
default:
this.alfLog("warn", "A simple repo action request was made but the action is unsupported", payload, this);
}
},
/**
*
* @param {object} item The item to perform the action on
*/
onActionLocate: function alfresco_services_ActionService__onActionLocate(payload) {
this.alfPublish("ALF_LOCATE_DOCUMENT", {
node: payload.document
});
}
});
});