diff --git a/app/assets/javascripts/discourse/app/components/directory-table.js b/app/assets/javascripts/discourse/app/components/directory-table.js index f1b819310eb..f9c03ba08f2 100644 --- a/app/assets/javascripts/discourse/app/components/directory-table.js +++ b/app/assets/javascripts/discourse/app/components/directory-table.js @@ -2,16 +2,103 @@ import Component from "@ember/component"; import { action } from "@ember/object"; export default Component.extend({ - classNames: ["directory-table-container"], + lastScrollPosition: 0, + ticking: false, + _topHorizontalScrollBar: null, + _tableContainer: null, + _table: null, + _fakeScrollContent: null, + + didInsertElement() { + this._super(...arguments); + this.setProperties({ + _tableContainer: this.element.querySelector(".directory-table-container"), + _topHorizontalScrollBar: this.element.querySelector( + ".directory-table-top-scroll" + ), + _fakeScrollContent: this.element.querySelector( + ".directory-table-top-scroll-fake-content" + ), + _table: this.element.querySelector(".directory-table"), + }); + + this._tableContainer.addEventListener("scroll", this.onBottomScroll); + this._topHorizontalScrollBar.addEventListener("scroll", this.onTopScroll); + + // Set active header might have already scrolled the _tableContainer. + // Call onHorizontalScroll manually to scroll the _topHorizontalScrollBar + this.onResize(); + this.onHorizontalScroll(this._tableContainer, this._topHorizontalScrollBar); + window.addEventListener("resize", this.onResize); + }, + + @action + onResize() { + if ( + this._tableContainer.getBoundingClientRect().bottom < window.innerHeight + ) { + // Bottom of the table is visible. Hide the scrollbar + this._fakeScrollContent.style.height = 0; + } else { + this._fakeScrollContent.style.width = `${this._table.offsetWidth}px`; + this._fakeScrollContent.style.height = "1px"; + } + }, + + @action + onTopScroll() { + this.onHorizontalScroll(this._topHorizontalScrollBar, this._tableContainer); + }, + + @action + onBottomScroll() { + this.onHorizontalScroll(this._tableContainer, this._topHorizontalScrollBar); + }, + + @action + onHorizontalScroll(primary, replica) { + if (this.lastScrollPosition === primary.scrollLeft) { + return; + } + + this.set("lastScrollPosition", primary.scrollLeft); + + if (!this.ticking) { + window.requestAnimationFrame(() => { + replica.scrollLeft = this.lastScrollPosition; + this.set("ticking", false); + }); + + this.set("ticking", true); + } + }, + + willDestoryElement() { + this._tableContainer.removeEventListener("scroll", this.onBottomScroll); + this._topHorizontalScrollBar.removeEventListener( + "scroll", + this.onTopScroll + ); + window.removeEventListener("resize", this.onResize); + }, @action setActiveHeader(header) { // After render, scroll table left to ensure the order by column is visible + if (!this._tableContainer) { + this.set( + "_tableContainer", + document.querySelector(".directory-table-container") + ); + } const scrollPixels = - header.offsetLeft + header.offsetWidth + 10 - this.element.offsetWidth; + header.offsetLeft + + header.offsetWidth + + 10 - + this._tableContainer.offsetWidth; if (scrollPixels > 0) { - this.element.scrollLeft = scrollPixels; + this._tableContainer.scrollLeft = scrollPixels; } }, }); diff --git a/app/assets/javascripts/discourse/app/templates/components/directory-table.hbs b/app/assets/javascripts/discourse/app/templates/components/directory-table.hbs index a646d794db6..5864d038390 100644 --- a/app/assets/javascripts/discourse/app/templates/components/directory-table.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/directory-table.hbs @@ -1,25 +1,31 @@ - - - {{table-header-toggle field="username" order=order asc=asc}} - {{#each columns as |column|}} - {{table-header-toggle - field=column.name - icon=column.icon - order=order - asc=asc - automatic=(directory-column-is-automatic column=column) - translated=column.user_field_id - onActiveRender=setActiveHeader - }} - {{/each}} +
+
+
- {{#if showTimeRead}} - - {{/if}} - - - {{#each items as |item|}} - {{directory-item item=item columns=columns showTimeRead=showTimeRead}} - {{/each}} - -
{{i18n "directory.time_read"}}
+
+ + + {{table-header-toggle field="username" order=order asc=asc}} + {{#each columns as |column|}} + {{table-header-toggle + field=column.name + icon=column.icon + order=order + asc=asc + automatic=(directory-column-is-automatic column=column) + translated=column.user_field_id + onActiveRender=setActiveHeader + }} + {{/each}} + + {{#if showTimeRead}} + + {{/if}} + + + {{#each items as |item|}} + {{directory-item item=item columns=columns showTimeRead=showTimeRead}} + {{/each}} + +
{{i18n "directory.time_read"}}
+
diff --git a/app/assets/stylesheets/common/base/directory.scss b/app/assets/stylesheets/common/base/directory.scss index 2a8e82b0d43..ffbd1a51449 100644 --- a/app/assets/stylesheets/common/base/directory.scss +++ b/app/assets/stylesheets/common/base/directory.scss @@ -6,6 +6,11 @@ overflow-x: auto; } + .directory-table-top-scroll { + width: 100%; + overflow-x: auto; + } + .open-edit-columns-btn { vertical-align: top; padding: 0.45em 0.8em;