').html(QWeb.render('CMISSession.warning', {error: error}))
- }).open();
- } else {
- new Dialog(this, {
- size: 'medium',
- title: _t("CMIS Error"),
- subtitle: error.statusText,
- $content: $('
').html(error.text)
- }).open();
- }
- }
- },
-
- /**
- * Wrap a
- */
- wrap_cmis_object: function (cmisObject) {
- if (_.has(cmisObject, 'object')) {
- cmisObject = cmisObject.object;
- }
- return new CmisObjectWrapper(this, cmisObject, this.cmis_session);
- },
-
- wrap_cmis_objects: function (cmisObjects) {
- var self = this;
- return _.chain(cmisObjects)
- .map(function (item) {
- return self.wrap_cmis_object(item)
- })
- .uniq(function (wrapped) {
- return wrapped.objectId
- })
- .value()
- },
- };
-
- var FieldCmisDocument = basicFields.FieldChar.extend(CmisMixin, {
- template: "FieldCmisDocument", widget_class: 'field_cmis_document',
-
- init: function (parent, name, record, options) {
- this._super.apply(this, arguments);
- CmisMixin.init.call(this);
- this.backend = this.field.backend;
- this.formatType = 'char';
- this.document = {};
-
- this.on('cmis-add-document', this, this.onAddDocument);
- this.on('cmis-link-document', this, this.onLinkDocument);
- this.on('cmis_node_content_updated', this, this.onDocumentUpdated);
- },
-
- willStart: function () {
- var self = this;
- this.load_cmis_config();
- this.init_cmis_session();
- this.cmisSessionReady = Promise.all([
- this.cmis_session_initialized,
- this.load_cmis_repositories()
- ]);
- return new Promise(function(resolve) {
- self.cmisSessionReady.then(function() {
- if (self.value) {
- self._get_document(self.value).catch(function(error) {
- self.value = "__error__";
- resolve({});
- }).then(function (document) {
- if (!!document) {
- self.document = self.wrap_cmis_object(document);
- resolve(document);
- }
- });
- } else {
- resolve({});
- }
- });
- });
- },
-
- _render: function () {
- this._super.apply(this, arguments);
- if (this.value === "__error__") {
- this._renderGetError();
- } else if (this.value && this.value !== "empty" && this.document) {
- this._renderCmisDocument(this.document);
- } else {
- this._renderNoDocument();
- }
-
- this.$el.find('.dropdown-menu').off('mouseleave');
- // hide the dropdown menu on mouseleave
- this.$el.find('.dropdown-menu').on('mouseleave', function (e) {
- if ($(e.target).is(':visible')) {
- $(e.target).closest('.btn-group').find('.dropdown-toggle[aria-expanded="true"]').trigger('click').blur();
- }
- });
- // hide the dropdown menu on link clicked
- this.$el.find('.dropdown-menu a').on('click', function (e) {
- if ($(e.target).is(':visible')) {
- $(e.target).closest('.btn-group').find('.dropdown-toggle[aria-expanded="true"]').trigger('click').blur();
- }
- });
- },
-
- start: function () {
- if (!this.value) {
- // This is a bit of a hack, but there is no hook that allows removing
- // the `o_field_empty` class on a widget with no value.
- this.value = "empty";
- }
- return this._super.apply(this, arguments);
- },
-
- _renderCmisDocument: function (document) {
- var $cmisDoc = QWeb.render("CmisDocumentReadOnly", {object: document});
- this.$el.html($cmisDoc);
- this.register_document_action_events();
- },
-
- _renderNoDocument: function () {
- var $cmisDoc = QWeb.render("CmisNoDocumentActions", {});
- this.$el.html($cmisDoc);
- this.register_no_document();
- },
-
- _renderGetError: function() {
- this.$el.empty();
- this.$el.append($('
').text(_t("Unable to retrieve the document. The resource might have been deleted in the CMIS.")))
- },
-
- _get_document: function (objectId) {
- var self = this;
- return new Promise(function (resolve, reject) {
- self.cmis_session.getObject(objectId, "latest", DEFAULT_CMIS_OPTIONS)
- .ok(function (document) {
- resolve(document);
- }).notOk(function (error) {
- reject(error);
- });
- });
- },
-
- onAddDocument: function (files) {
- var self = this;
- this.cmis_config_loaded
- .then(() => self._getDocumentsFromFiles(files))
- .then((documents) => self._uploadDocumentsToCreate(documents))
- .catch((error) => false)
- .then((result) => result ? self.trigger_up('reload') : false);
- },
-
- onLinkDocument: function(objectId) {
- var self = this;
- this.cmis_config_loaded
- .then(() => self.update_document_field(objectId));
- },
-
- onDocumentUpdated: function (document) {
- this.value = document.objectId;
- this.trigger_up('reload');
- },
-
- _uploadDocumentsToCreate: function (documents) {
- return this._rpc({
- route: '/web/cmis/field/create_document_value', params: {
- 'model_name': this.model, 'res_id': this.res_id, 'field_name': this.name, 'documents': documents
- }
- });
- },
-
- _getDocumentsFromFiles: function (files) {
- return Promise.all(_.map(files, function (file) {
- return new Promise(function (resolve, reject) {
- var reader = new FileReader();
- reader.readAsDataURL(file);
- reader.onload = function () {
- resolve({
- name: file.name, mimetype: file.type, data: reader.result
- });
- };
- reader.onerror = error => reject(error);
- });
- }));
- },
-
- onClickAddDocument: function () {
- var dialog = new CmisAddDocumentDialog(this);
- dialog.open();
- },
-
- onClickLinkDocument: function () {
- var dialog = new CmisLinkDocumentDialog(this);
- dialog.open();
- },
-
- on_click_preview: function () {
- var documentViewer = new DocumentViewer(this, this.document);
- documentViewer.appendTo($('body'));
- },
-
- update_document_field: function (objectId) {
- var re = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
- var ok = re.exec(objectId);
- if (!ok) {
- return {"error": "invalid_object_id"};
- };
- var changes = {};
- changes[this.name] = objectId;
- this.trigger_up('field_changed', {
- dataPointID: this.dataPointID, changes: changes,
- });
- },
-
- on_click_download: function () {
- this.do_download(this.document);
- },
-
- do_download: function (cmisObjectWrapped) {
- window.open(cmisObjectWrapped.url);
- },
-
- on_click_rename: function () {
- var dialog = new CmisRenameContentDialog(this, this.document);
- dialog.open();
- dialog.opened().then(function (result) {
- dialog.$el.find('[autofocus]').focus();
- });
- },
-
- on_click_import_new_version: function () {
- var self = this;
- this.cmis_session.checkOut(self.document.objectId)
- .ok(function(data) {
- var dialog = new CmisCheckinDialog(self, self.wrap_cmis_object(data), true);
- dialog.onDestroy(function() {
- self.verify_is_checked_out()
- .then(function (isCheckedOut) {
- if (isCheckedOut) {
- return self._cancel_checkout.bind(self)();
- }
- })
- .catch((error) => console.log("error"))
- .finally(() => self.trigger_up("reload"));
- });
- dialog.open();
- })
- .notOk(function() {
- self._cancel_checkout.bind(self);
- });
-
- },
-
- on_click_show_history: function () {
- var self = this;
- // without the objectId in the options, this returns a "versionSeriesId does not exist" error.
- // Exactly why it does is anyone's guess...
- var options = {includeAllowableActions: true, objectId: this.value};
- this.cmis_session.getAllVersions(this.value, options)
- .ok(function (versions) {
- var wrapped_versions = self.wrap_cmis_objects(versions);
- var dialog = new CmisVersionsHistoryDialog(self, wrapped_versions);
- dialog.open();
- });
-
- },
-
- on_click_toggle_details: function () {
- var self = this;
- var $documentDetails = this.$el.find(".document-details");
- this.$el.find('.toggle-document-details').toggleClass('fa-minus fa-plus-circle');
- if ($documentDetails.is(":empty")) {
- $documentDetails.append(QWeb.render("cmisDocumentContentDetails", {object: this.document}));
- this.$el.find('.toggle-document-details').on('click', function (e) {
- e.preventDefault();
- e.stopPropagation();
- self.on_click_toggle_details();
- });
- } else {
- $documentDetails.empty();
- }
- },
-
- on_click_delete_link: function () {
- let self = this;
- let values = {};
- values[this.name] = false;
- this._rpc({
- model: this.model,
- method: "write",
- args: [this.res_id, values],
- }).then(function() {
- self.value = "empty";
- self._render();
- });
- },
-
- on_cancel_checkout: function (e) {
- var self = this;
- this._cancel_checkout().finally(() => self.trigger_up('reload'));
- },
-
- _cancel_checkout: function () {
- var self = this;
- return new Promise(function(resolve, reject) {
- self.cmis_session.cancelCheckOut(self.document.objectId)
- .ok((data) => resolve(data))
- .notOk((error) => reject(error));
- });
- },
-
- verify_is_checked_out: function() {
- var self = this;
- return new Promise(function (resolve) {
- self.cmis_session.getObject(self.document.objectId)
- .ok(function (doc) {
- resolve(self.wrap_cmis_object(doc).isCheckedOut);
- })
- .notOk(function (doc) {
- // safer to assume the doc is checked out
- resolve(true);
- });
- });
- },
-
- toggle_more_action: function name() {
- var element = this.$el[0];
- if (!element || element.disabled || $(element).hasClass("disabled")) {
- return;
- }
- var menu = this.$el.find('ul')[0];
- var isActive = $(element).hasClass("show");
- if (isActive) {
- $(element).focus();
- element.setAttribute('aria-expanded', true);
- }else{
- $(element).focus();
- element.setAttribute('aria-expanded', false);
-
- }
- $(menu).toggleClass("show");
- $(element).toggleClass("show");
- },
-
- register_document_action_events: function () {
- var self = this;
- var $el_actions = this.$el.find('.field_cmis_document_actions');
- var more_action = $el_actions.find('.cmis-dropdown-more-actions');
- more_action.on('click', function (e) {
- e.stopPropagation() ;
- self.toggle_more_action();
- });
- $el_actions.find('.content-action-preview').on('click', function (e) {
- self.stopEvent(e);
- self.on_click_preview();
- });
- $el_actions.find('.content-action-download').on('click', function (e) {
- self.stopEvent(e);
- self.on_click_download();
- });
- $el_actions.find('.content-action-rename').on('click', function (e) {
- self.stopEvent(e);
- self.on_click_rename();
- });
- $el_actions.find('.content-action-checkin').on('click', function (e) {
- self.stopEvent(e);
- self.on_click_import_new_version();
- });
- $el_actions.find('.content-action-history').on('click', function (e) {
- self.stopEvent(e);
- self.on_click_show_history();
- });
- $el_actions.find('.content-action-get-properties').on('click', function (e) {
- self.stopEvent(e);
- self.on_click_toggle_details();
- });
- $el_actions.find('.content-action-cancel-checkout').on('click', function (e) {
- self.stopEvent(e);
- self.on_cancel_checkout();
- });
- $el_actions.find('.content-action-delete-link').on('click', function(e) {
- self.stopEvent(e);
- self.on_click_delete_link();
- })
- },
-
- register_no_document: function () {
- var self = this;
- this.$el.find('.content-action-add').on('click', function (e) {
- self.stopEvent(e);
- self.onClickAddDocument();
- });
-
- this.$el.find('.content-action-link').on('click', function (e) {
- self.stopEvent(e);
- self.onClickLinkDocument();
- });
- },
-
- stopEvent: function (e) {
- e.preventDefault();
- e.stopPropagation();
- },
- });
-
- var FieldCmisFolder = basicFields.FieldChar.extend(CmisMixin, {
- template: "FieldCmisFolder",
-
- widget_class: 'field_cmis_folder',
- datatable: null,
- displayed_folder_id: null,
-
- events: {
- 'change input': 'store_dom_value',
- 'click td.details-control': 'on_click_details_control',
- 'click button.cmis-create-root': 'on_click_create_root',
- },
-
- /*
- * Override base methods
- */
-
- init: function () {
- this._super.apply(this, arguments);
- CmisMixin.init.call(this);
- this.id_for_table = _.uniqueId('field_cmis_folder_widgets_table');
- this.table_rendered = $.Deferred();
- this.on('cmis_node_created', this, this.on_cmis_node_created);
- this.on('cmis_node_deleted', this, this.on_cmis_node_deleted);
- this.on('cmis_node_updated', this, this.on_cmis_node_updated);
- this.on('cmis_node_content_updated', this, this.on_cmis_node_content_updated);
- this.on('wrapped_cmis_node_reloaded', this, this.on_wrapped_cmis_node_reloaded);
- this.backend = this.field.backend;
- this.formatType = 'char';
- this.clipboardAction = undefined;
- this.clipboardObject = undefined;
- },
-
- reset_widget: function () {
- if (this.datatable) {
- this.table_rendered = $.Deferred();
- this.datatable.destroy();
- this.datatable = null;
- this.root_folder_id = null;
- this.displayed_folder_id = null;
- }
- },
-
- destroy: function () {
- this.reset_widget();
- this._super.apply(this, arguments);
- },
-
- _render: function () {
- this._super.apply(this, arguments);
- this.states = [];
- this.load_cmis_config();
- this.init_cmis_session();
- var value = this.value;
- if (this.$input) {
- this.$input.val(value);
- }
- if (!this.res_id) {
- // hide the widget if the record is not yet created
- this.$el.hide();
- }
- this.$el.find('button.cmis-create-root').addClass('o_hidden');
-
- if (this.$el.is(':visible')) {
- // if the element is visible, we render it. If it's in a tab
- // the rendition will be don on tab activation
- this.render_datatable();
- }
-
- this.set_root_folder_id(value);
- if (!value && this.field.allow_create) {
- var self = this;
- this.$el.find('button.cmis-create-root').removeClass('o_hidden');
- }
- var self = this;
- self.add_tab_listener();
- },
-
- _renderReadonly: function () {
- // in edit mode we need the in
- this._prepareInput(this.$el);
- },
- /**
- * @override
- */
- isSet: function () {
- return true;
- },
-
- /*
- * Cmis content events
- */
- on_cmis_node_created: function (cmisobjects) {
- this.refresh_datatable();
- },
-
- on_cmis_node_deleted: function (cmisobjects) {
- this.refresh_datatable();
- },
-
- on_cmis_node_updated: function (cmisobjects) {
- this.refresh_datatable();
- },
-
- on_wrapped_cmis_node_reloaded: function (oldValue, newValue) {
- this.refresh_datatable();
- },
-
- on_cmis_node_content_updated: function (cmisobjects) {
- this.on_cmis_node_updated(cmisobjects);
- },
-
- /*
- * Specific methods
- */
-
- /**
- * Create a node for the current model into the DMS
- */
- on_click_create_root: function () {
- if (!this.res_id) {
- Dialog.alert(this, _t('Create your object first'));
- return;
- }
- var self = this;
- $.when(this.cmis_config_loaded).done(function () {
- self._rpc({route:'/web/cmis/field/create_value', params:{
- 'model_name': self.model,
- 'res_id': self.res_id,
- 'field_name': self.name
- }}).then(function (vals) {
- var cmis_objectid = vals[self.res_id];
- var changes = {};
- changes[self.name] = cmis_objectid;
- self.trigger_up('field_changed', {
- dataPointID: self.dataPointID,
- changes: changes,
- });
- });
- });
- },
-
- /**
- * Add tab listener to render the table only when the tabe is active
- * if the control is displayed in an inactive tab
- */
- add_tab_listener: function () {
- var self = this;
- $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
- var tab_id = self.id_for_table;
- var active_tab = $(e.target.hash);
- if (active_tab.find('#' + tab_id).length == 1) {
- self.render_datatable();
- return;
- }
- });
- },
-
- get_datatable_config: function () {
- var l10n = _t.database.parameters;
- var self = this;
- var config = {
- searching: false,
- scrollY: '40vh',
- scrollCollapse: true,
- pageLength: 25,
- deferRender: true,
- serverSide: true,
- autoWidth: false,
- responsive: true,
- colReorder: {
- realtime: false,
- },
- stateSave: true,
- ajax: $.proxy(self, 'datatable_query_cmis_data'),
- buttons: [{
- extend: 'collection',
- text: _t('Columns') + '
',
- buttons: ['columnsToggle'],
- }],
- columns: [
- {
- className: 'details-control',
- orderable: false,
- data: 'fDetails()',
- defaultContent: '',
- width: '12px'
- },
- {data: 'fName()'},
- {
- data: 'title',
- visible: false
- },
- {data: 'description'},
- {
- data: 'fLastModificationDate()',
- width: '120px'
- },
- {
- data:'fCreationDate()',
- width:'120px',
- visible: false,
- },
- {
- data: 'lastModifiedBy',
- width: '60px',
- visible: false,
- },
- {
- data: 'fContentActions()',
- defaultContent: '',
- orderable: false,
- width: "80px",
- },
- ],
- select: false,
- rowId: 'objectId',
- language: {
- "decimal": l10n.decimal_point,
- "emptyTable": _t("No data available in table"),
- "info": _t("Showing _START_ to _END_ of _TOTAL_ entries"),
- "infoEmpty": _t("Showing 0 to 0 of 0 entries"),
- "infoFiltered": _t("(filtered from _MAX_ total entries)"),
- "infoPostFix": _t(""),
- "thousands": l10n.thousands_sep,
- "lengthMenu": _t("Show _MENU_ entries"),
- "loadingRecords": _t("Loading..."),
- "processing": _t("Processing..."),
- "search": _t("Search:"),
- "zeroRecords": _t("No matching records found"),
- "paginate": {
- "first": _t("First"),
- "last": _t("Last"),
- "next": _t("Next"),
- "previous": _t("Previous")
- },
- "aria": {
- "sortAscending": _t(": activate to sort column ascending"),
- "sortDescending": _t(": activate to sort column descending")
- }
- },
- dom: "<'row'<'col-sm-6 cmis-root-content-buttons'><'col-sm-6'Blf>>" +
- "<'row'<'col-sm-12'<'cmis-breadcrumb-container'>>>" +
- "<'row'<'col-sm-12'tr>>" +
- "<'row'<'col-sm-5'i><'col-sm-7'p>>",
- "order": [[1, 'asc']]
- };
- return config;
- },
-
- render_datatable: function () {
- if (_.isNull(this.datatable)) {
- var self = this;
- this.$datatable = this.$el.find('#' + this.id_for_table);
- this.$datatable.on('preInit.dt', $.proxy(self, 'on_datatable_preinit'));
- this.$datatable.on('draw.dt', $.proxy(self, 'on_datatable_draw'));
- this.$datatable.on('column-reorder.dt', $.proxy(self, 'on_datatable_column_reorder'));
- var config = this.get_datatable_config();
- this.datatable = this.$datatable.DataTable(config);
- this.table_rendered.resolve();
- } else {
- this.datatable.draw();
- }
- },
-
- /**
- * This method is called by DataTables when a table is being initialised
- * and is about to request data. At the point of being called the table will
- * have its columns and features initialised, but no data will have been
- * loaded (either by Ajax, or reading from the DOM).
- */
- on_datatable_preinit: function (e, settings) {
- this.$breadcrumb = $('
');
- this.$el.find('div.cmis-breadcrumb-container').append(this.$breadcrumb);
- },
-
- /**
- * This method is called whenever the table is redrawn on the page.
- * This function is to use to take actions on newly displayed data. At
- * the point of being called, the table is filled with rows from the last
- * call to the server. It's used to register events handlers to the newly
- * created elements.
- */
- on_datatable_draw: function (e, settings) {
- this.register_content_events();
- },
-
- /**
- * This event is triggered when a column is reordered.
- */
- on_datatable_column_reorder: function (e, settings) {
- this.register_content_events();
- },
-
- /** function called by datatablet to obtain the required data
- *
- * The function is given three parameters and no return is required. The
- * parameters are:
- *
- * 1. _object_ - Data to send to the server
- * 2. _function_ - Callback function that must be executed when the required
- * data has been obtained. That data should be passed into the callback
- * as the only parameter
- * 3. _object_ - DataTables settings object for the table
- */
- datatable_query_cmis_data: function (data, callback, settings) {
- // Get children of the current folder
- var self = this;
- var cmis_session = self.cmis_session;
- if (_.isNull(self.displayed_folder_id) || !self.displayed_folder_id) {
- callback({
- 'data': [],
- 'recordsTotal': 0,
- 'recordsFiltered': 0
- });
- return;
- }
- var lang = settings.oLanguage;
- var start = settings._iDisplayStart;
- var max = settings._iDisplayLength;
- var orderBy = this.prepare_order_by(settings.aaSorting);
- var options = _.defaults({
- skipCount: start,
- maxItems: max,
- orderBy: orderBy,
- }, DEFAULT_CMIS_OPTIONS);
- cmis_session
- .getChildren(self.displayed_folder_id, options)
- .ok(function (data) {
- callback({
- 'data': _.map(data.objects, self.wrap_cmis_object, self),
- 'recordsTotal': data.numItems,
- 'recordsFiltered': data.numItems
- });
- });
- return;
- },
-
- /**
- * Function called be fore calling cmis to build the oderBy parameters
- * from settings given by datatable aaSorting info
- *
- * _aaSorting_ - aaSorting is an array of array for each column to be sorted
- * initially containing the column's index and a direction string
- * ('asc' or 'desc').
- *
- * The function return a cmis order_by string.
- */
- prepare_order_by: function (aaSorting) {
- var orders_by = [];
- _.each(aaSorting, function (sort_info, index, list) {
- var col_idx = sort_info[0];
- var sort_order = sort_info[1].toUpperCase();
- switch (col_idx) {
- case 1:
- orders_by.push('cmis:baseTypeId DESC,cmis:name ' + sort_order);
- break;
- case 2:
- orders_by.push('cm:title ' + sort_order);
- break;
- case 3:
- orders_by.push('cmis:description ' + sort_order);
- break;
- case 4:
- orders_by.push('cmis:lastModificationDate ' + sort_order);
- break;
- case 5:
- orders_by.push('cmis:creationDate ' + sort_order);
- break;
- case 6:
- orders_by.push('cmis:lastModifiedBy ' + sort_order);
- break;
- }
- });
- return orders_by.join();
- },
-
- /**
- * Method called once all the content has been rendered into the datatable
- */
- register_content_events: function () {
- var self = this;
- var datatable_container = this.$el.find('.dataTables_scrollBody');
- datatable_container.off('dragleave dragend drop dragover dragenter drop');
- if (self.dislayed_folder_cmisobject && self.dislayed_folder_cmisobject.allowableActions['canCreateDocument']) {
- datatable_container.on('dragover dragenter', function (e) {
- datatable_container.addClass('is-dragover');
- e.preventDefault();
- e.stopPropagation();
- });
- datatable_container.on('dragleave dragend drop', function (e) {
- datatable_container.removeClass('is-dragover');
- e.preventDefault();
- e.stopPropagation();
- });
- datatable_container.on('drop', function (e) {
- e.preventDefault();
- e.stopPropagation();
- self.upload_files(e.originalEvent.dataTransfer.files);
-
- });
- }
- /* some UI fixes */
- this.$el.find('.cmis-dropdown-more-actions').off('click');
- this.$el.find('.cmis-dropdown-more-actions').on('click', function (e) {
- self.dropdown_fix_position($(e.target));
- });
-
- this.$el.find('.dropdown-menu').off('mouseleave');
- // hide the dropdown menu on mouseleave
- this.$el.find('.dropdown-menu').on('mouseleave', function (e) {
- if ($(e.target).is(':visible')) {
- $(e.target).closest('.btn-group').find('.dropdown-toggle[aria-expanded="true"]').trigger('click').blur();
- }
- });
- // hide the dropdown menu on link clicked
- this.$el.find('.dropdown-menu a').on('click', function (e) {
- if ($(e.target).is(':visible')) {
- $(e.target).closest('.btn-group').find('.dropdown-toggle[aria-expanded="true"]').trigger('click').blur();
- }
- });
- this.$el.find('.cmis-folder').on('click', function (e) {
- e.preventDefault();
- e.stopPropagation();
- var row = self._get_event_row(e);
- self.display_folder(0, row.data().objectId);
- });
- var $el_actions = this.$el.find('.field_cmis_folder_content_actions');
- $el_actions.find('.content-action-download').on('click', function (e) {
- var row = self._get_event_row(e);
- self.on_click_download(row);
- });
- $el_actions.find('.content-action-preview').on('click', function (e) {
- var row = self._get_event_row(e);
- self.on_click_preview(row);
- });
-
- $el_actions.find('.content-action-get-properties').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_get_properties(row);
- });
- $el_actions.find('.content-action-rename').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_rename(row);
- });
- $el_actions.find('.content-action-cut').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_cut(row);
- });
- $el_actions.find('.content-action-copy').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_copy(row);
- });
- $el_actions.find('.content-action-copy-paste').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_copy_paste(row);
- });
- $el_actions.find('.content-action-cut-paste').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_cut_paste(row);
- });
- $el_actions.find('.content-action-set-content-stream').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_set_content_stream(row);
- });
- $el_actions.find('.content-action-delete-object').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_delete_object(row);
- });
- $el_actions.find('.content-action-checkin').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_checkin(row);
- });
- $el_actions.find('.content-action-checkout').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_checkout(row);
- });
- $el_actions.find('.content-action-cancel-checkout').on('click', function (e) {
- self._prevent_on_hashchange(e);
- var row = self._get_event_row(e);
- self.on_click_cancel_checkout(row);
- });
- },
-
- /**
- * Upload files into the current cmis folder
- */
- upload_files: function (files) {
- var self = this;
- var numFiles = files.length;
- var processedFiles = [];
- if (numFiles > 0) {
- framework.blockUI();
- }
- var cmis_session = this.cmis_session;
- _.each(files, function (file, index, list) {
- cmis_session
- .createDocument(this.displayed_folder_id, file, {'cmis:name': file.name}, file.mimeType)
- .ok(function (data) {
- processedFiles.push(data);
- if (processedFiles.length == numFiles) {
- framework.unblockUI();
- self.trigger('cmis_node_created', [processedFiles]);
- }
- })
- .notOk(function (error) {
- if (error) {
- console.error(error.text);
- if (error.type == 'application/json') {
- var jerror = JSON.parse(error.text);
- if (jerror.exception === 'contentAlreadyExists') {
- var dialog = new CmisDuplicateDocumentResolver(self, self.dislayed_folder_cmisobject, file);
- dialog.open();
- framework.unblockUI();
- return;
- }
- }
- }
- self.on_cmis_error(error);
- });
- }, this);
- },
-
- _prevent_on_hashchange: function (e) {
- /**
- * Odoo register a global handler when the hash change on the current window
- * $(window).bind('hashchange', self.on_hashchange);
- * To avoid thah events triggered by a click on items into a dropdown-menu
- * are handled by the main handler we must stop the propagations.
- * This is required since dropdown menu designed with bootstrat are
- * a list of '
0) {
- deferred.resolve(true);
- } else {
- deferred.resolve(false);
- }
- })
- .notOk(function (error) {
- deferred.reject(error);
- });
- return deferred;
- },
-
- /**
- * Method returning a deferred with the new_filename for a copy or cut
- */
- get_new_filename: function (filename, folder) {
- var self = this;
- return self.filename_already_exists(filename, folder).then(function (result) {
- if (result) {
- var new_filename = undefined;
- var re = /(?:\.([^.]+))?$/;
- var parts = re.exec(filename);
- var name_without_ext = filename.slice(0, -parts[1].length - 1);
- var ext = parts[1];
- var deferred = $.Deferred();
- self.cmis_session.query('' +
- "SELECT cmis:name FROM cmis:document WHERE " +
- "IN_FOLDER('" + folder +
- "') AND cmis:name like '" + name_without_ext.replace(new RegExp("'", "g"), "\\'") + "-%." + ext + "'"
- ).ok(function (data) {
- var cpt = data.results.length;
- var filenames = _.map(
- data.results,
- function (item) {
- return item.succinctProperties['cmis:name'][0];
- });
- while (true) {
- new_filename = name_without_ext + '-' +
- cpt + '.' + ext;
- if (_.contains(filenames, new_filename)) {
- cpt += 1;
- } else {
- break;
- }
- }
- deferred.resolve(new_filename);
- }).notOk(function (error) {
- deferred.reject(error);
- });
- return deferred;
- } else {
- return filename;
- }
- })
- },
-
- /**
- * Return the DataTable row on which the event has occured
- */
- _get_event_row: function (e) {
- return this.datatable.row($(e.target).closest('tr'));
- },
-
- on_click_download: function (row) {
- row.data().refresh().done(
- $.proxy(this.do_download, this)
- );
- },
-
- do_download: function (cmisObjectWrapped) {
- window.open(cmisObjectWrapped.url);
- },
-
- on_click_preview: function (row) {
- var cmisObjectWrapped = row.data();
- var documentViewer = new DocumentViewer(this, cmisObjectWrapped, this.datatable.data());
- documentViewer.appendTo($('body'));
- },
-
- on_click_get_properties: function (row) {
- this.display_row_details(row);
- },
-
- on_click_rename: function (row) {
- var dialog = new CmisRenameContentDialog(this, row.data());
- dialog.open();
- dialog.opened().then(function (result) {
- dialog.$el.find('[autofocus]').focus();
- });
- },
-
- on_click_copy: function (row) {
- this.clipboardAction = 'copy';
- this.clipboardObject = row.data();
- this.reload_displayed_folder();
- },
-
- on_click_cut: function (row) {
- this.clipboardAction = 'cut';
- this.clipboardObject = row.data();
- this.clipboardFolder = this.displayed_folder_id;
- this.reload_displayed_folder();
- },
-
- on_click_copy_paste: function (row) {
- var self = this;
- var data = row.data();
- self.get_new_filename(self.clipboardObject.name, data.objectId
- ).done(function (result) {
- self.cmis_session.createDocumentFromSource(
- data.objectId, self.clipboardObject.objectId,
- undefined, result
- ).ok(function (result) {
- self.clear_clipboard();
- self.reload_displayed_folder();
- }).notOk(function (error) {
- self.clear_clipboard();
- self.reload_displayed_folder();
- });
- });
- },
-
- on_click_cut_paste: function (row) {
- var self = this;
- var data = row.data();
- self.get_new_filename(self.clipboardObject.name, data.objectId
- ).done(function (result) {
- self.cmis_session.moveObject(
- self.clipboardObject.objectId,
- self.clipboardFolder,
- data.objectId
- ).ok(function (result) {
- self.clear_clipboard();
- self.reload_displayed_folder();
- }).notOk(function (error) {
- if (error.body.message.startsWith("Duplicate child name not allowed")) {
- Dialog.alert(self, _t('A document with the same name already exists.'));
- } else {
- crash_manager.show_error({
- type: _t("Alfresco Error"),
- message: error.body.message,
- data: {debug: JSON.stringify(error)},
- });
- }
- });
- });
- },
-
- on_click_details_control: function (e) {
- var row = this._get_event_row(e);
- this.display_row_details(row);
- },
-
- on_click_delete_object: function (row) {
- var data = row.data();
- var self = this;
- Dialog.confirm(
- self, _t('Confirm deletion of ') + data.name,
- {
- confirm_callback: function () {
- var all_versions = true;
- self.cmis_session.deleteObject(data.objectId, all_versions).ok(function () {
- self.trigger('cmis_node_deleted', [data.cmis_object]);
- });
- }
- });
- },
-
- on_click_set_content_stream: function (row) {
- var dialog = new CmisUpdateContentStreamDialog(this, row.data());
- dialog.open();
- },
-
- on_click_checkin: function (row) {
- var dialog = new CmisCheckinDialog(this, row.data());
- dialog.open();
- },
-
- on_click_checkout: function (row) {
- var self = this;
- row.data().refresh().done(
- function (data) {
- self.cmis_session.checkOut(data.objectId)
- .ok(function (data) {
- self.refresh_datatable();
- self.do_download(self.wrap_cmis_object(data));
- });
- });
- },
-
- on_click_cancel_checkout: function (row) {
- var cmisObjectWrapped = row.data();
- var self = this;
- this.cmis_session.cancelCheckOut(cmisObjectWrapped.objectId)
- .ok(function (data) {
- self.refresh_datatable();
- });
- },
-
- /**
- * fix for dropdowns that are inside a container with "overflow: scroll"
- * This fix is required in order to have the dropdown to be displayed
- * on top of the table without scrolling. Without this fix, the menu will
- * appears into the table container but at the same time, scrollbars will
- * appear for the parts of the menu thaht overflows the initial div
- * container
- * see also http://www.datatables.net/forums/discussion/18529/bootstrap-dropdown-issue-with-datatables
- * and https://github.com/twbs/bootstrap/issues/7160#issuecomment-28180085
- */
- dropdown_fix_position: function (button) {
- var dropdown = $(button.parent()).find('.dropdown-menu');
- var offset = button.offset();
- var dropDownTop = offset.top + button.outerHeight();
- dropdown.css('top', dropDownTop + "px");
-
- // For the left position we need to take care of the available space
- // on the right and the width of the dropdown to display according to
- // its content.
- // see http://codereview.stackexchange.com/questions/31501/adjust-bootstrap-dropdown-menu-based-on-page-width/39580
- var offsetLeft = offset.left;
- var dropdownWidth = dropdown.width();
- var docWidth = $(window).width();
- var formWidth = $('.o_form_sheet_bg').width();
- var subDropdown = dropdown.eq(1);
- var subDropdownWidth = subDropdown.width();
- var isDropdownVisible = (offsetLeft + dropdownWidth <= formWidth);
- var isSubDropdownVisible = (offsetLeft + dropdownWidth + subDropdownWidth <= formWidth);
- var finalWidth = dropdownWidth + subDropdownWidth;
- dropdown.addClass('pull-right');
- dropdown.css('width', finalWidth + 'px');
- if (!isDropdownVisible || !isSubDropdownVisible) {
- var leftPosition = formWidth - dropdownWidth - subDropdownWidth;
- dropdown.css('left', leftPosition + 'px');
-
- } else {
- dropdown.removeClass('pull-right');
- dropdown.css('left', button.offset().left + "px");
- }
- },
-
-
- /**
- * Set a new Root
- */
- set_root_folder_id: function (folderId) {
- var self = this;
- if (self.root_folder_id === folderId) {
- return;
- }
- self.root_folder_id = folderId;
- $.when(self.cmis_session_initialized, self.table_rendered).done(function () {
- self.load_cmis_repositories().done(function () {
- self.reset_breadcrumb();
- self.display_folder(0, self.root_folder_id);
- });
- });
- },
-
- /**
- * Empty the breadcrumb
- */
- reset_breadcrumb: function () {
- this.$breadcrumb.empty();
- },
-
- reload_displayed_folder: function () {
- if (!this.displayed_folder_id) {
- return;
- }
- var page_index = this.page_index;
- this.page_index = -1; // force reload
- this.display_folder(page_index, this.displayed_folder_id);
- },
-
- /**
- * Display folder content.
- * Add a link to the folder in the breadcrumb and display children
- */
- display_folder: function (pageIndex, folderId) {
- if (this.displayed_folder_id === folderId &&
- this.page_index === pageIndex) {
- return;
- }
- var self = this;
- this.displayed_folder_id = folderId;
- this.page_index = pageIndex;
- this.$el.find('.cmis-root-content-buttons').empty();
- if (folderId) {
- this.cmis_session.getObject(folderId, "latest", {
- includeAllowableActions: true
- })
- .ok(function (cmisobject) {
- self.dislayed_folder_cmisobject = new CmisObjectWrapper(this, cmisobject, self.cmis_session);
- self.render_folder_actions();
- });
- this.display_folder_in_breadcrumb(folderId);
- this.datatable.rows().clear();
- this.datatable.ajax.reload(null, true);
- } else {
- self.datatable.clear().draw();
- }
- },
-
- /**
- * Display the folder into the breadcrumb.
- */
- display_folder_in_breadcrumb: function (folderId) {
- if (this.$breadcrumb.find('a[data-cmis-folder-id = "' + folderId + '"]').length === 0) {
- var self = this;
- // Get properties of this object and add link to the breadcrumb
- this.cmis_session
- .getObject(folderId, "latest", {includeAllowableActions: false})
- .ok(function (cmisobject) {
- var wrapped_cmisobject = new CmisObjectWrapper(this, cmisobject, self.cmis_session);
- var name = (folderId == self.root_folder_id) ? _t('Root') : wrapped_cmisobject.name;
- var link = $('').attr('href', '#').attr('data-cmis-folder-id', folderId).append(name);
- self.$breadcrumb.append($('').append(link));
- link.click(function (e) {
- e.preventDefault();
- var current_id = self.dislayed_folder_cmisobject.objectId;
- var selectedForlderId = $(e.target).attr('data-cmis-folder-id');
- if (selectedForlderId !== current_id) {
- $(e.target.parentNode).nextAll().remove();
- self.display_folder(0, selectedForlderId);
- }
- });
- });
- }
- },
-
- render_folder_actions: function () {
- var ctx = {object: this};
- _.map(this.dislayed_folder_cmisobject.allowableActions, function (value, actionName) {
- ctx[actionName] = value;
- });
- this.$el.find('.cmis-root-content-buttons').html(QWeb.render("CmisRootContentActions", ctx));
- this.register_root_content_events();
- },
-
- /**
- * Display the details of the selected row
- * This method is triggered when the user click on the details icon
- */
- display_row_details: function (row) {
- var tr = $(row.node());
- tr.find('td.details-control div').toggleClass('fa-minus fa-plus-circle');
- if (row.child.isShown()) {
- // This row is already open - close it
- row.child.hide();
- }
- else {
- // Open this row
- row.child(QWeb.render("CmisContentDetails", {object: row.data()})).show();
- }
- },
- });
-
- registry.add('cmis_folder', FieldCmisFolder);
- registry.add('cmis_document', FieldCmisDocument);
-
- return {
- CmisUpdateContentStreamDialog: CmisUpdateContentStreamDialog,
- CmisCheckinDialog: CmisCheckinDialog,
- CmisObjectWrapper: CmisObjectWrapper,
- CmisMixin: CmisMixin,
- FieldCmisFolder: FieldCmisFolder,
- FieldCmisDocument: FieldCmisDocument,
- CmisCreateFolderDialog: CmisCreateFolderDialog,
- CmisCreateDocumentDialog: CmisCreateDocumentDialog,
- CmisVersionsHistoryDialog: CmisVersionsHistoryDialog,
- CmisDuplicateDocumentResolver: CmisDuplicateDocumentResolver,
- DEFAULT_CMIS_OPTIONS: DEFAULT_CMIS_OPTIONS,
- };
-
-});
diff --git a/cmis_web/static/src/xml/document_viewer.xml b/cmis_web/static/src/xml/document_viewer.xml
deleted file mode 100644
index 28ee7910..00000000
--- a/cmis_web/static/src/xml/document_viewer.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/cmis_web/static/src/xml/form_widgets.xml b/cmis_web/static/src/xml/form_widgets.xml
deleted file mode 100644
index 1e3a4507..00000000
--- a/cmis_web/static/src/xml/form_widgets.xml
+++ /dev/null
@@ -1,612 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- |
- Name |
- Title |
- Description |
- Modified |
- Created |
- Modifier |
- |
-
-
-
-
- |
- Name |
- Title |
- Description |
- Modified |
- Created |
- Modifier |
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name |
- Description |
- Created |
-
- Modified |
-
- Version |
- |
-
-
-
-
- |
- |
- |
-
- |
-
- |
- |
-
-
-
- No document found.
- |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Version
-
Name
-
Actions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Loading cmis document...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Link with an existing document
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/cmis_web_alf/__manifest__.py b/cmis_web_alf/__manifest__.py
index a828eddb..c68b0e76 100644
--- a/cmis_web_alf/__manifest__.py
+++ b/cmis_web_alf/__manifest__.py
@@ -21,6 +21,7 @@
"assets": {
"web.assets_backend": [
"/cmis_web_alf/static/src/images/images.scss",
+ "/cmis_web_alf/static/src/cmis_document/cmis_document.js",
"/cmis_web_alf/static/src/cmis_folder/cmis_folder.js",
"/cmis_web_alf/static/src/cmis_folder/cmis_folder.xml",
"/cmis_web_alf/static/src/cmis_table/cmis_table.js",
diff --git a/cmis_web_alf/static/src/cmis_document/cmis_document.js b/cmis_web_alf/static/src/cmis_document/cmis_document.js
new file mode 100644
index 00000000..32b9dc15
--- /dev/null
+++ b/cmis_web_alf/static/src/cmis_document/cmis_document.js
@@ -0,0 +1,40 @@
+/** @odoo-module **/
+
+/* ---------------------------------------------------------
++ * Odoo cmis_web
++ * Authors Laurent Mignon 2016, Quentin Groulard 2023 Acsone SA/NV
++ * License in __openerp__.py at root level of the module
++ *---------------------------------------------------------
++*/
+
+import {CmisDocumentField} from "@cmis_web/cmis_document/cmis_document";
+import {patch} from "@web/core/utils/patch";
+
+patch(CmisDocumentField.prototype, "open_in_alfresco", {
+ get dynamicActionsProps() {
+ const props = this._super(...arguments);
+ props.openInAlf = this.openInAlf.bind(this);
+ return props;
+ },
+
+ onClickOpenInAlf() {
+ this.openInAlf(this.displayDocumentId);
+ },
+
+ async openInAlf(cmisObjectId) {
+ const url = await this.rpc("/web/cmis/content_details_url", {
+ backend_id: this.backend.id,
+ cmis_objectid: cmisObjectId,
+ });
+ window.open(url);
+ },
+
+ getCmisObjectWrapperParams() {
+ const params = this._super(...arguments);
+ params.alfrescoApiLocation = this.backend.alfresco_api_location;
+ return params;
+ },
+});
+
+CmisDocumentField.props.backend[0].shape.share_location = String;
+CmisDocumentField.props.backend[0].shape.alfresco_api_location = String;
diff --git a/cmis_web_alf/static/src/cmis_table/cmis_table.js b/cmis_web_alf/static/src/cmis_table/cmis_table.js
index b6ad48c4..3cb7ccd3 100644
--- a/cmis_web_alf/static/src/cmis_table/cmis_table.js
+++ b/cmis_web_alf/static/src/cmis_table/cmis_table.js
@@ -7,6 +7,15 @@
+ *---------------------------------------------------------
+*/
-import {cmisTableProps} from "@cmis_web/cmis_table/cmis_table";
+import {CmisTable, cmisTableProps} from "@cmis_web/cmis_table/cmis_table";
+import {patch} from "@web/core/utils/patch";
+
+patch(CmisTable.prototype, "open_in_alfresco", {
+ get dynamicActionsProps() {
+ const props = this._super(...arguments);
+ props.openInAlf = this.props.openInAlf;
+ return props;
+ },
+});
cmisTableProps.openInAlf = Function;
diff --git a/cmis_web_proxy/__manifest__.py b/cmis_web_proxy/__manifest__.py
index d525c9b6..809dac21 100644
--- a/cmis_web_proxy/__manifest__.py
+++ b/cmis_web_proxy/__manifest__.py
@@ -16,6 +16,7 @@
"images": ["static/description/main_icon.png"],
"assets": {
"web.assets_backend": [
+ "/cmis_web_proxy/static/src/cmis_document/cmis_document.js",
"/cmis_web_proxy/static/src/cmis_folder/cmis_folder.js",
"/cmis_web_proxy/static/src/cmis_object_wrapper_service.js",
],
diff --git a/cmis_web_proxy/static/src/cmis_document/cmis_document.js b/cmis_web_proxy/static/src/cmis_document/cmis_document.js
new file mode 100644
index 00000000..51f071da
--- /dev/null
+++ b/cmis_web_proxy/static/src/cmis_document/cmis_document.js
@@ -0,0 +1,52 @@
+/** @odoo-module **/
+
+/* ---------------------------------------------------------
++ * Odoo cmis_web
++ * Authors Laurent Mignon 2016, Maxime Franco 2023 Acsone SA/NV
++ * License in __openerp__.py at root level of the module
++ *---------------------------------------------------------
++*/
+
+import {CmisDocumentField} from "@cmis_web/cmis_document/cmis_document";
+import {patch} from "@web/core/utils/patch";
+
+patch(CmisDocumentField.prototype, "open_with_proxy", {
+ getCmisObjectWrapperParams() {
+ const params = this._super(...arguments);
+ params.applyOdooSecurity = this.backend.apply_odoo_security;
+ return params;
+ },
+
+ genCmisSessionToken() {
+ return JSON.stringify({
+ model: this.props.record.resModel,
+ res_id: this.props.record.resId,
+ field_name: this.props.name,
+ });
+ },
+
+ setCmisSessionToken() {
+ if (this.backend.apply_odoo_security) {
+ this.cmisSession.setToken(this.genCmisSessionToken());
+ }
+ },
+
+ async setDocumentId() {
+ var self = this;
+ self.setCmisSessionToken();
+ this._super(...arguments);
+ },
+
+ getPreviewUrlParams() {
+ // Pas sur de l'utilité de la méthode je n'ia trouvé aucun appel à cette fonction
+ var params = this._super(...arguments);
+ if (this.backend.apply_odoo_security) {
+ // Add the token as parameter and into the http headers
+ var token = this.genCmisSessionToken();
+ params.token = token;
+ }
+ return params;
+ },
+});
+
+CmisDocumentField.props.backend[0].shape.apply_odoo_security = Boolean;
diff --git a/cmis_web_proxy_alf/__manifest__.py b/cmis_web_proxy_alf/__manifest__.py
index a02a62fa..b170f7ff 100644
--- a/cmis_web_proxy_alf/__manifest__.py
+++ b/cmis_web_proxy_alf/__manifest__.py
@@ -15,6 +15,7 @@
"images": ["static/description/main_icon.png"],
"assets": {
"web.assets_backend": [
+ "/cmis_web_proxy_alf/static/src/cmis_document/cmis_document.js",
"/cmis_web_proxy_alf/static/src/cmis_folder/cmis_folder.js",
"/cmis_web_proxy_alf/static/src/cmis_object_wrapper_service.js",
],
diff --git a/cmis_web_proxy_alf/static/src/cmis_document/cmis_document.js b/cmis_web_proxy_alf/static/src/cmis_document/cmis_document.js
new file mode 100644
index 00000000..2c5f9508
--- /dev/null
+++ b/cmis_web_proxy_alf/static/src/cmis_document/cmis_document.js
@@ -0,0 +1,21 @@
+/** @odoo-module **/
+
+/* ---------------------------------------------------------
++ * Odoo cmis_web
++ * Authors Laurent Mignon 2016, Maxime Franco 2023 Acsone SA/NV
++ * License in __openerp__.py at root level of the module
++ *---------------------------------------------------------
++*/
+
+import {CmisDocumentField} from "@cmis_web/cmis_document/cmis_document";
+import {patch} from "@web/core/utils/patch";
+
+patch(CmisDocumentField.prototype, "open_with_proxy_alf", {
+ getCmisObjectWrapperParams() {
+ const params = this._super(...arguments);
+ params.alfrescoApiLocation = this.backend.alfresco_api_location;
+ return params;
+ },
+});
+
+CmisDocumentField.props.backend[0].shape.alfresco_api_location = String;