diff --git a/appsscript.json b/appsscript.json index b0cf53c..1f98df4 100644 --- a/appsscript.json +++ b/appsscript.json @@ -24,7 +24,7 @@ "selectActions": [ { "text": "Add documents from Nuxeo", - "runFunction": "getContextualAddOn" + "runFunction": "attachDocToComposeUI" } ], "draftAccess": "METADATA" @@ -47,7 +47,7 @@ "primaryColor": "#315df6" }, "urlFetchWhitelist": [ - "https://nightly.nuxeo.com/", + "https://*.nuxeo.com/", "https://*.nuxeocloud.com/", "https://*.cloud.nuxeo.com/" ] diff --git a/src/ActionHandlers.js b/src/ActionHandlers.js index e050080..c1aca30 100644 --- a/src/ActionHandlers.js +++ b/src/ActionHandlers.js @@ -18,8 +18,13 @@ var PUSH_NOTE_WS = "pushNoteWS"; var PUSH_ATTACHMENT = "pushAttachment"; var PUSH_ATTACHMENT_WS = "pushAttachmentWS"; var CHILD_NAVIGATE = "childNavigate"; +var ASSET_NAVIGATE = "assetNavigate"; var SAVE_CREDS = "saveCreds"; var SAVE_ATTACHMENTS = "saveAttachments"; +var DISPLAY_WORKFLOW = "displayWF"; +var EXECUTE_WF = "executeWF"; +var ATTACH_DOCUMENT = "attachDocument"; +var SEARCH_DOCUMENTS = "searchDocuments"; /** * Collection of functions to handle user interactions with the add-on. @@ -109,6 +114,15 @@ var ActionHandlers = { return buildChildrenCard(children, action, param.parameters); }, + assetNavigate: function(param) { + var parentId = param.parameters.parentId; + var children = nuxeoClientWrapper().children(parentId); + if (_.isEmpty(children)) { + return showSimpleCard("Nothing here!", "There is no other folders here."); + } + return buildPickUpCard(children, param.parameters); + }, + /** * Handle the push of attachment(s) to Nuxeo from a Gmail email. */ @@ -167,7 +181,8 @@ var ActionHandlers = { return showResultDoc( "Success!", "You have successfully created the document", - document.contextParameters.documentURL + document.contextParameters.documentURL, + document.uid ); }, @@ -179,7 +194,8 @@ var ActionHandlers = { return showResultDoc( "Success!", "You have successfully created the document", - document.contextParameters.documentURL + document.contextParameters.documentURL, + document.uid ); }, @@ -191,7 +207,8 @@ var ActionHandlers = { return showResultDoc( "Success!", "You have successfully created the document", - document.contextParameters.documentURL + document.contextParameters.documentURL, + document.uid ); }, @@ -203,8 +220,45 @@ var ActionHandlers = { return showResultDoc( "Success!", "You have successfully created the document", - document.contextParameters.documentURL + document.contextParameters.documentURL, + document.uid ); + }, + + /** + * Display workflow card. + */ + displayWF: function(e) { + return displayWFCard(e.parameters.docId); + }, + + /** + * Execute a workflow for a given user on content + */ + executeWF: function(e) { + // TODO + }, + + attachDocument: function(e) { + var url = e.parameters.url; + var title = e.parameters.title; + var linkToAdd = '" ' + title + '"'; + return (build = CardService.newUpdateDraftActionResponseBuilder() + .setUpdateDraftBodyAction( + CardService.newUpdateDraftBodyAction() + .addUpdateContent(linkToAdd, CardService.ContentType.IMMUTABLE_HTML) + .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT) + ) + .build()); + }, + + searchDocuments: function(e) { + var fulltext = e.formInput.suggestion; + var assets = nuxeoClientWrapper().assets(fulltext); + if (_.isEmpty(assets)) { + return showSimpleCardForPickup("Nothing here!", "There is no documents."); + } + return buildPickUpCard(assets, {}); } }; diff --git a/src/Main.js b/src/Main.js index b83ef97..86a0380 100644 --- a/src/Main.js +++ b/src/Main.js @@ -21,6 +21,19 @@ function getContextualAddOn(event) { return dispatchActionInternal_(event, addOnErrorHandler); } +/** + * Entry point for selecting documents to insert into gmail message. + */ + +function attachDocToComposeUI(e) { + // List assets + var assets = nuxeoClientWrapper().assets(""); + if (_.isEmpty(assets)) { + return [showSimpleCardForPickup("Nothing here!", "There is no documents.")]; + } + return [buildPickUpCard(assets, {})]; +} + /** * Returning the card of disconnect info. */ diff --git a/src/NuxeoClientWrapper.js b/src/NuxeoClientWrapper.js index 100f7cc..3b013dc 100644 --- a/src/NuxeoClientWrapper.js +++ b/src/NuxeoClientWrapper.js @@ -8,6 +8,7 @@ */ var MAIN_PP = "tree_children"; +var SUGGESTION_PP = "default_document_suggestion"; /** * Exception to raise when authorization is required. @@ -81,7 +82,8 @@ var NuxeoClientPrototype = { throw new AuthorizationRequiredException(); } var headers = { - Authorization: Utilities.formatString("Bearer %s", this.oauthService.getAccessToken()) + Authorization: Utilities.formatString("Bearer %s", this.oauthService.getAccessToken()), + "enrichers.document": "documentURL" }; var url = this.apiEndpoint + "/search/pp/" + MAIN_PP + "/execute?queryParams=" + id; var response = UrlFetchApp.fetch(url, { @@ -97,6 +99,28 @@ var NuxeoClientPrototype = { return parsedResponse.entries; }, + assets: function(fulltext) { + if (!this.oauthService.hasAccess()) { + throw new AuthorizationRequiredException(); + } + var headers = { + Authorization: Utilities.formatString("Bearer %s", this.oauthService.getAccessToken()), + "enrichers.document": "documentURL" + }; + var url = this.apiEndpoint + "/search/pp/" + SUGGESTION_PP + "/execute?queryParams=" + fulltext; + var response = UrlFetchApp.fetch(url, { + method: "get", + headers: headers, + muteHttpExceptions: true + }); + var raw = response.getContentText(); + var parsedResponse = JSON.parse(raw); + if (parsedResponse.status && parsedResponse.status === 500) { + throw new Error(parsedResponse.message); + } + return parsedResponse.entries; + }, + /** * Push a note as a file into the current user workspace. * @param {Object} params diff --git a/src/Views.js b/src/Views.js index feb90af..c791b1b 100644 --- a/src/Views.js +++ b/src/Views.js @@ -244,10 +244,23 @@ function showSimpleCard(title, message) { .build(); } +/** + * show simple card for pickup. + */ +function showSimpleCardForPickup(title, message) { + var card = CardService.newCardBuilder(); + var header = CardService.newCardHeader().setTitle(title); + var section = CardService.newCardSection().addWidget(CardService.newTextParagraph().setText(message)); + return card + .setHeader(header) + .addSection(section) + .build(); +} + /** * show doc creation result. */ -function showResultDoc(title, message, link) { +function showResultDoc(title, message, link, docId) { var card = CardService.newCardBuilder(); var header = CardService.newCardHeader().setTitle(title); var section = CardService.newCardSection() @@ -257,11 +270,22 @@ function showResultDoc(title, message, link) { .setText("Access to the document") .setOpenLink(createExternalLink(link)) ); - var build = card + var params = { + docId: docId + }; + var sectionTask = CardService.newCardSection(); + sectionTask.addWidget( + CardService.newKeyValue() + .setIcon(CardService.Icon.INVITE) + .setMultiline(true) + .setContent("Execute a workflow on this content") + .setOnClickAction(createAction_(DISPLAY_WORKFLOW, params)) + ); + return card .setHeader(header) .addSection(section) + .addSection(sectionTask) .build(); - return build; } /** @@ -319,6 +343,61 @@ function buildChildrenCard(children, action, params) { .build(); } +/** + * Create the children docs tree card for pickup. + */ +function buildPickUpCard(children, params) { + var card = CardService.newCardBuilder(); + var sectionLogo = CardService.newCardSection().addWidget( + CardService.newKeyValue() + .setIconUrl(NUXEO_ICON) + .setMultiline(true) + .setContent("Please choose the document to attach:") + ); + var inputSection = CardService.newCardSection() + .addWidget( + CardService.newTextInput() + .setFieldName("suggestion") + .setTitle("Search for...") + ) + .addWidget( + CardService.newButtonSet().addButton( + CardService.newTextButton() + .setText("Search") + .setOnClickAction(createAction_(SEARCH_DOCUMENTS)) + ) + ); + var sectionChildren = []; + for (var i = 0; i < children.length; i++) { + var sectionChild = CardService.newCardSection(); + params = _.extend({}, params); + params.parentId = children[i].uid; + params.title = children[i].title; + params.url = children[i].contextParameters.documentURL; + sectionChild + .addWidget( + CardService.newKeyValue() + .setIcon(CardService.Icon.MEMBERSHIP) + .setMultiline(true) + .setContent(children[i].title) + .setOnClickAction(createAction_(ASSET_NAVIGATE, params)) + ) + .addWidget( + CardService.newButtonSet().addButton( + CardService.newTextButton() + .setText('' + SPACES + "> Attach") + .setOnClickAction(createAction_(ATTACH_DOCUMENT, params)) + ) + ); + sectionChildren.push(sectionChild); + } + var card = card.addSection(sectionLogo).addSection(inputSection); + for (var i = 0; i < sectionChildren.length; i++) { + card.addSection(sectionChildren[i]); + } + return card.build(); +} + /** * Display attachments to select. */ @@ -363,3 +442,22 @@ function buildAttachCard(attachments) { .setNavigation(CardService.newNavigation().pushCard(build)) .build(); } + +function displayWFCard(docId) { + var card = CardService.newCardBuilder(); + var sectionLogo = CardService.newCardSection().addWidget( + CardService.newKeyValue() + .setIconUrl(NUXEO_ICON) + .setMultiline(true) + .setContent("Workflow") + ); + var sectionAction = CardService.newCardSection(); + sectionAction.addWidget( + CardService.newButtonSet().addButton( + CardService.newTextButton() + .setText('Execute') + .setOnClickAction(createAction_(EXECUTE_WF)) + ) + ); + var card = card.addSection(sectionLogo); +}