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}}
- {{i18n "directory.time_read"}} |
- {{/if}}
-
-
- {{#each items as |item|}}
- {{directory-item item=item columns=columns showTimeRead=showTimeRead}}
- {{/each}}
-
-
+
+
+
+ {{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}}
+ {{i18n "directory.time_read"}} |
+ {{/if}}
+
+
+ {{#each items as |item|}}
+ {{directory-item item=item columns=columns showTimeRead=showTimeRead}}
+ {{/each}}
+
+
+
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;