diff --git a/app/assets/javascripts/discourse/app/initializers/post-decorations.js b/app/assets/javascripts/discourse/app/initializers/post-decorations.js index 8a755608684..5b04730dd0b 100644 --- a/app/assets/javascripts/discourse/app/initializers/post-decorations.js +++ b/app/assets/javascripts/discourse/app/initializers/post-decorations.js @@ -1,11 +1,13 @@ -import { later } from "@ember/runloop"; +import { later, schedule } from "@ember/runloop"; import I18n from "I18n"; import highlightSyntax from "discourse/lib/highlight-syntax"; import lightbox from "discourse/lib/lightbox"; -import { iconHTML } from "discourse-common/lib/icon-library"; +import { iconHTML, iconNode } from "discourse-common/lib/icon-library"; import { setTextDirections } from "discourse/lib/text-direction"; import { nativeLazyLoading } from "discourse/lib/lazy-load-images"; import { withPluginApi } from "discourse/lib/plugin-api"; +import { create } from "virtual-dom"; +import showModal from "discourse/lib/show-modal"; export default { name: "post-decorations", @@ -131,6 +133,61 @@ export default { }, { id: "discourse-video-codecs" } ); + + function _createButton() { + const openPopupBtn = document.createElement("button"); + openPopupBtn.classList.add( + "open-popup-link", + "btn-default", + "btn", + "btn-icon-text" + ); + const expandIcon = create( + iconNode("discourse-expand", { class: "expand-table-icon" }) + ); + const openPopupText = document.createTextNode( + I18n.t("fullscreen_table.expand_btn") + ); + openPopupBtn.append(expandIcon, openPopupText); + return openPopupBtn; + } + + function isOverflown({ clientWidth, scrollWidth }) { + return scrollWidth > clientWidth; + } + + function generateModal(event) { + const table = event.target.parentNode.querySelector("table"); + const tempTable = table.cloneNode(true); + + showModal("fullscreen-table").set("tableHtml", tempTable); + } + + function generatePopups(tables) { + tables.forEach((table) => { + if (!isOverflown(table.parentNode)) { + return; + } + + const popupBtn = _createButton(); + table.parentNode.classList.add("fullscreen-table-wrapper"); + table.parentNode.insertBefore(popupBtn, table); + popupBtn.addEventListener("click", generateModal, false); + }); + } + + api.decorateCookedElement( + (post) => { + schedule("afterRender", () => { + const tables = post.querySelectorAll("table"); + generatePopups(tables); + }); + }, + { + onlyStream: true, + id: "fullscreen-table", + } + ); }); }, }; diff --git a/app/assets/javascripts/discourse/app/templates/modal/fullscreen-table.hbs b/app/assets/javascripts/discourse/app/templates/modal/fullscreen-table.hbs new file mode 100644 index 00000000000..37a0cf25fc8 --- /dev/null +++ b/app/assets/javascripts/discourse/app/templates/modal/fullscreen-table.hbs @@ -0,0 +1,3 @@ +{{#d-modal-body}} + {{tableHtml}} +{{/d-modal-body}} diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss index cbaee44f127..e3b6b1e2fd3 100644 --- a/app/assets/stylesheets/common/base/topic-post.scss +++ b/app/assets/stylesheets/common/base/topic-post.scss @@ -1410,3 +1410,56 @@ a.mention-group { opacity: 0; } } + +.open-popup-link { + position: sticky; + left: 0.5rem; + top: 0.5rem; + opacity: 0%; + white-space: nowrap; + display: block; +} + +.fullscreen-table-wrapper { + transition: all 0.6s cubic-bezier(0.165, 0.84, 0.44, 1); + display: block; +} + +.expand-table-icon { + margin-right: 4px; +} + +.fullscreen-table-modal .modal-inner-container { + width: max-content; + max-width: 90%; + margin: 0 auto; + padding: 10px; + + .modal-body { + padding-top: 0; + } + + thead { + position: sticky; + top: 0; + z-index: 1; + background-color: var(--secondary); + } + + tbody { + overflow-x: hidden; + } + + td { + padding: 0.5rem; + } +} + +html.discourse-no-touch .fullscreen-table-wrapper:hover { + border-radius: 5px; + box-shadow: 0 2px 5px 0 rgba(var(--always-black-rgb), 0.1), + 0 2px 10px 0 rgba(var(--always-black-rgb), 0.1); + .open-popup-link { + opacity: 100%; + } +} diff --git a/app/assets/stylesheets/mobile/topic-post.scss b/app/assets/stylesheets/mobile/topic-post.scss index ebfe9441a4d..b334d8732a8 100644 --- a/app/assets/stylesheets/mobile/topic-post.scss +++ b/app/assets/stylesheets/mobile/topic-post.scss @@ -458,3 +458,8 @@ span.highlighted { } } } + +.open-popup-link { + opacity: 100%; + margin-bottom: 1rem; +} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index d3690731d2a..67b081f45cb 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -3938,6 +3938,9 @@ en: no_group_messages_title: "No group messages found" + fullscreen_table: + expand_btn: "Expand Table" + # This section is exported to the javascript for i18n in the admin section admin_js: type_to_filter: "type to filter..."