From b28a85c486216f72931de3f1c4ddcd2f24afffb5 Mon Sep 17 00:00:00 2001 From: robyngit Date: Thu, 12 Sep 2024 12:44:15 -0400 Subject: [PATCH 1/3] Create a button to open modal & view data object Issue #1758 --- src/css/metacatui-common.css | 53 ++++++++++-- src/js/views/ViewObjectButtonView.js | 121 +++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 src/js/views/ViewObjectButtonView.js diff --git a/src/css/metacatui-common.css b/src/css/metacatui-common.css index cc769a9b7..1530b5f47 100644 --- a/src/css/metacatui-common.css +++ b/src/css/metacatui-common.css @@ -3509,8 +3509,22 @@ add font awesome close icon */ * Table Editor View ********************************************/ +.table-editor { + height: 100%; + overflow: hidden; + box-sizing: border-box; + padding: 1rem; +} + .table-editor .spreadsheet { - margin: 1rem 2rem 2rem 0.5rem; + margin: 1rem 0 0.5rem 0; + width: 100%; + max-width: 90vw; + height: 100%; + overflow: scroll; + border: 1px solid #ddd; + box-sizing: border-box; + border-radius: 5px; } .table-editor .table { @@ -3624,10 +3638,6 @@ add font awesome close icon */ color: #555; } -.table-editor .spreadsheet-controls { - margin-left: 0.5rem; -} - /****************************************** ** AccessPolicy editor view *** ******************************************/ @@ -9609,3 +9619,36 @@ body > #extension-is-installed { top: 3px; } } + +/****************************************** +** Full screen modal ** +******************************************/ +/* used for the DataObjectView in the ViewObjectButton View */ + +.modal.full-screen { + display: flex; + flex-direction: column; + width: 90vw; + height: 90vh; + /* important needed to override the top: 10% from bootstrap */ + top: 50% !important; + left: 50%; + transform: translate(-50%, -50%); + /* to unset the absolute left margin from bootstrap */ + margin-left: unset; + + .modal-body { + /* Body takes up remaining space and allows scrolling */ + flex: 1 1 auto; + /* bootstrap overwrite */ + max-height: unset; + } +} + + +/****************************************** +** Data Object View ** +******************************************/ +.object-view { + height: 100%; +} \ No newline at end of file diff --git a/src/js/views/ViewObjectButtonView.js b/src/js/views/ViewObjectButtonView.js new file mode 100644 index 000000000..167208a52 --- /dev/null +++ b/src/js/views/ViewObjectButtonView.js @@ -0,0 +1,121 @@ +"use strict"; + +define(["jquery", "backbone", "views/DataObjectView"], ( + $, + Backbone, + DataObjectView, +) => { + // The base class for the view + const BASE_CLASS = "view-data-button"; + const CLASS_NAMES = { + button: [BASE_CLASS, "btn"], + icon: ["icon", "icon-eye-open"], + modal: ["modal", "hide", "fade", "full-screen"], + header: ["modal-header"], + closeButton: ["close"], + body: ["modal-body"], + footer: ["modal-footer"], + }; + const BUTTON_TEXT = "View"; + + /** + * @class ViewDataButtonView + * @classdesc Creates a button that opens a modal to view a DataONE object + * (using the DataObjectView). + * @classcategory Views + * @augments Backbone.View + * @class + * @since 0.0.0 + * @screenshot views/ViewDataButtonView.png //TODO + */ + const ViewDataButtonView = Backbone.View.extend( + /** @lends ViewDataButtonView.prototype */ + { + /** @inheritdoc */ + type: "ViewDataButtonView", + + /** @inheritdoc */ + className: CLASS_NAMES.button.join(" "), + + /** @inheritdoc */ + tagName: "a", + + /** @inheritdoc */ + events: { + click: "openModal", + }, + + /** + * A template for the modal that will be displayed when the button is + * clicked. The modal will contain a DataObjectView. + * @param {object} options - Options for the modal + * @param {string} options.title - The title of the modal + * @returns {string} The HTML for the modal + */ + modalTemplate({ title = "Data" } = {}) { + const id = `modal-${this.model.cid}`; + return `
+
+ +

${title}

+
+
+

loading...

+
+
+
`; + }, + + /** + * Initializes the ViewDataButtonView + * @param {object} options - Options for the view + */ + initialize(options) { + this.model = options.model; + this.modalContainer = options.modalContainer || document.body; + }, + + /** @inheritdoc */ + render() { + this.el.innerHTML = BUTTON_TEXT; + const icon = document.createElement("i"); + icon.classList.add(...CLASS_NAMES.icon); + this.el.appendChild(icon); + return this; + }, + + /** + * Renders the modal & DataObjectView + * @returns {JQuery} The modal + */ + renderModal() { + const modalHTML = this.modalTemplate({ + title: this.model.get("title") || "Data", + }); + const modal = $(modalHTML).modal(); + const modalBody = modal.find(`.${CLASS_NAMES.body.join(".")}`); + const objectView = new DataObjectView({ + model: this.model, + }); + modalBody.empty(); + modalBody.append(objectView.render().el); + $(this.modalContainer).append(modal); + return modal; + }, + + /** + * Opens the modal. Called when the button is clicked. + * @param {Event} e - The click event + */ + openModal(e) { + e.preventDefault(); + if (!this.modal) { + this.modal = this.renderModal(); + } + this.modal.modal("show"); + }, + }, + ); + + return ViewDataButtonView; +}); From 04a3c8be846183cf8f7edbf106693692298c78aa Mon Sep 17 00:00:00 2001 From: robyngit Date: Thu, 12 Sep 2024 15:46:49 -0400 Subject: [PATCH 2/3] Render the view data button in the metadata view - Move rendering of the download button & view data button to a new method - Render both buttons in a container div Issue #1758 --- src/css/metacatui-common.css | 10 ++++++-- src/js/views/MetadataView.js | 50 +++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/css/metacatui-common.css b/src/css/metacatui-common.css index 1530b5f47..3a3899ca5 100644 --- a/src/css/metacatui-common.css +++ b/src/css/metacatui-common.css @@ -2619,9 +2619,15 @@ section#user-citations { .entitydetails > .control-group { clear: both; } -.entitydetails a.download { + +.data-interaction-buttons { margin-left: 180px; - margin-bottom: 20px; + display: flex; + flex-wrap: wrap; + + >a:not(:first-child) { + margin-left: 0.7rem; + } } .form-horizontal .entitydetails > label { text-align: left; diff --git a/src/js/views/MetadataView.js b/src/js/views/MetadataView.js index 599abd610..1bcbed1b4 100644 --- a/src/js/views/MetadataView.js +++ b/src/js/views/MetadataView.js @@ -21,6 +21,7 @@ define([ "views/citations/CitationModalView", "views/AnnotationView", "views/MarkdownView", + "views/ViewObjectButtonView", "text!templates/metadata/metadata.html", "text!templates/dataSource.html", "text!templates/publishDOI.html", @@ -57,6 +58,7 @@ define([ CitationModalView, AnnotationView, MarkdownView, + ViewObjectButtonView, MetadataTemplate, DataSourceTemplate, PublishDoiTemplate, @@ -2711,11 +2713,6 @@ define([ ); const container = viewRef.findEntityDetailsContainer(objID); - const downloadButton = new DownloadButtonView({ - model: solrResult, - }); - downloadButton.render(); - // Insert the data display HTML and the anchor tag to mark this spot // on the page if (container) { @@ -2763,14 +2760,9 @@ define([ } $(container).prepend(anchor); - - const nameLabel = $(container).find( - "label:contains('Entity Name')", - ); - if (nameLabel.length) { - $(nameLabel).parent().after(downloadButton.el); - } } + + this.renderDataInteractionButtons(solrResult, container); }); //= === Initialize the fancybox images ===== We will be checking every @@ -2840,6 +2832,40 @@ define([ }); }, + /** + * Insert the buttons to download and view the data object + * @param {SolrResult} solrResult - The SolrResult model for the object + * @param {Element} container - The DOM element that contains the object's + * metadata + * @since 0.0.0 + */ + renderDataInteractionButtons(solrResult, container) { + if (!solrResult || !container) return; + const buttonsContainer = document.createElement("div"); + buttonsContainer.classList.add( + "control-group", + "data-interaction-buttons", + ); + const nameLabel = $(container).find("label:contains('Entity Name')"); + // Create a button to download the data object + const downloadButton = new DownloadButtonView({ + model: solrResult, + }); + downloadButton.render(); + const viewButton = new ViewObjectButtonView({ + model: solrResult, + modalContainer: this.$el, + }); + viewButton.render(); + + $(buttonsContainer).append(downloadButton.el, viewButton.el); + if (nameLabel.length) { + $(nameLabel).parent().after(buttonsContainer); + } else { + $(container).prepend(buttonsContainer); + } + }, + /** Remove ecogrid links and replace them with workable links */ replaceEcoGridLinks() { // Find the element in the DOM housing the ecogrid link From 4b0ed2e51d007bf8aa5eac29a661fa6c04475113 Mon Sep 17 00:00:00 2001 From: Rushiraj Nenuji Date: Wed, 25 Sep 2024 12:44:39 -0700 Subject: [PATCH 3/3] Run formatting Run formatting --- src/css/metacatui-common.css | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/css/metacatui-common.css b/src/css/metacatui-common.css index 3a3899ca5..ff98c8648 100644 --- a/src/css/metacatui-common.css +++ b/src/css/metacatui-common.css @@ -2625,7 +2625,7 @@ section#user-citations { display: flex; flex-wrap: wrap; - >a:not(:first-child) { + > a:not(:first-child) { margin-left: 0.7rem; } } @@ -9651,10 +9651,9 @@ body > #extension-is-installed { } } - /****************************************** ** Data Object View ** ******************************************/ .object-view { height: 100%; -} \ No newline at end of file +}