Add workflow menu to thread lists
This CL adds a MD3 menu button to the bulk actions bar in thread lists.
The menu will display the available workflows, but as of now it just
contains random items, and clicking the items doesn't work (this will be
implemented later).
This implementation has been done using the newly added @material/web
package, so the elix package has been removed from the project. This is
because @material/web also uses Material Design like the Community
Console.
Bug: twpowertools:74
Change-Id: Ifb3712c7afc024e21c7ff83fb77658cd8d08bc8a
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index 95045a4..964a647 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -10,8 +10,9 @@
// #!endif
import InfiniteScroll from './infiniteScroll.js';
import {unifiedProfilesFix} from './unifiedProfiles.js';
+import Workflows from './workflows/workflows.js';
-var mutationObserver, options, avatars, infiniteScroll;
+var mutationObserver, options, avatars, infiniteScroll, workflows;
const watchedNodesSelectors = [
// App container (used to set up the intersection observer and inject the dark
@@ -128,6 +129,12 @@
}
// #!endif
+ // Inject the worflows menu in the thread list if the option is currently
+ // enabled.
+ if (workflows.shouldAddThreadListBtn(node)) {
+ workflows.addThreadListBtnIfEnabled(node);
+ }
+
// Inject the batch lock button in the thread list if the option is
// currently enabled.
if (batchLock.shouldAddButton(node)) {
@@ -227,6 +234,7 @@
// Initialize classes needed by the mutation observer
avatars = new AvatarsHandler();
infiniteScroll = new InfiniteScroll();
+ workflows = new Workflows();
// autoRefresh, extraInfo and threadPageDesignWarning are initialized in
// start.js
@@ -287,4 +295,6 @@
// Extra info
injectStylesheet(chrome.runtime.getURL('css/extrainfo.css'));
injectStylesheet(chrome.runtime.getURL('css/extrainfo_perforumstats.css'));
+ // Workflows
+ injectScript(chrome.runtime.getURL('workflowComponentsInject.bundle.js'));
});
diff --git a/src/contentScripts/communityConsole/utils/common.js b/src/contentScripts/communityConsole/utils/common.js
index 2e33f99..052b580 100644
--- a/src/contentScripts/communityConsole/utils/common.js
+++ b/src/contentScripts/communityConsole/utils/common.js
@@ -31,6 +31,19 @@
return [badge, badgeTooltip];
}
+// Adds an element to the thread list actions bar next to the button given by
+// |originalBtn|.
+export function addElementToThreadListActions(originalBtn, element) {
+ var duplicateBtn =
+ originalBtn.parentNode.querySelector('[debugid="mark-duplicate-button"]');
+ if (duplicateBtn)
+ duplicateBtn.parentNode.insertBefore(
+ element, (duplicateBtn.nextSibling || duplicateBtn));
+ else
+ originalBtn.parentNode.insertBefore(
+ element, (originalBtn.nextSibling || originalBtn));
+}
+
// Adds a button to the thread list actions bar next to the button given by
// |originalBtn|. The button will have icon |icon|, when hovered it will display
// |tooltip|, and will have a debugid attribute with value |debugId|.
@@ -46,14 +59,7 @@
[badge, badgeTooltip] = createExtBadge();
clone.append(badge);
- var duplicateBtn =
- originalBtn.parentNode.querySelector('[debugid="mark-duplicate-button"]');
- if (duplicateBtn)
- duplicateBtn.parentNode.insertBefore(
- clone, (duplicateBtn.nextSibling || duplicateBtn));
- else
- originalBtn.parentNode.insertBefore(
- clone, (originalBtn.nextSibling || originalBtn));
+ addElementToThreadListActions(originalBtn, clone);
createPlainTooltip(clone, tooltip);
new MDCTooltip(badgeTooltip);
diff --git a/src/contentScripts/communityConsole/workflows/components/TwptWorkflowsMenu.js b/src/contentScripts/communityConsole/workflows/components/TwptWorkflowsMenu.js
new file mode 100644
index 0000000..d36e730
--- /dev/null
+++ b/src/contentScripts/communityConsole/workflows/components/TwptWorkflowsMenu.js
@@ -0,0 +1,40 @@
+import '@material/web/iconbutton/standard-icon-button.js';
+import '@material/web/menu/menu-button.js';
+import '@material/web/menu/menu.js';
+import '@material/web/menu/menu-item.js';
+
+import {css, html, LitElement} from 'lit';
+import {map} from 'lit/directives/map.js';
+import {range} from 'lit/directives/range.js';
+
+export default class TwptWorkflowsMenu extends LitElement {
+ static styles = css`
+ .workflow-item {
+ padding-inline: 1em;
+ }
+ `;
+
+ renderMenuItems() {
+ return map(range(8), i => html`
+ <md-menu-item @click="${this._showWorkflow}" data-workflow-id="${i}"><span class="workflow-item" slot="start">Workflow ${i}</span></md-menu-item>
+ `);
+ }
+
+ render() {
+ // The button is based in the button created in the
+ // addButtonToThreadListActions function in file ../../utils/common.js.
+ return html`
+ <md-menu-button>
+ <md-standard-icon-button slot="button" icon="more_vert"></md-standard-icon-button>
+ <md-menu slot="menu">
+ ${this.renderMenuItems()}
+ </md-menu>
+ </md-menu-button>
+ `;
+ }
+
+ _showWorkflow(e) {
+ console.log(`Clicked workflow ${e.target.getAttribute('data-workflow-id')}.`);
+ }
+}
+window.customElements.define('twpt-workflows-menu', TwptWorkflowsMenu);
diff --git a/src/contentScripts/communityConsole/workflows/workflows.js b/src/contentScripts/communityConsole/workflows/workflows.js
new file mode 100644
index 0000000..1c99729
--- /dev/null
+++ b/src/contentScripts/communityConsole/workflows/workflows.js
@@ -0,0 +1,21 @@
+import {isOptionEnabled} from '../../../common/optionsUtils.js';
+import {addElementToThreadListActions, shouldAddBtnToActionBar} from '../utils/common.js';
+
+const wfDebugId = 'twpt-workflows';
+
+export default class Workflows {
+ constructor() {}
+
+ addThreadListBtnIfEnabled(readToggle) {
+ isOptionEnabled('workflows').then(isEnabled => {
+ if (isEnabled) {
+ const menu = document.createElement('twpt-workflows-menu');
+ addElementToThreadListActions(readToggle, menu);
+ }
+ });
+ }
+
+ shouldAddThreadListBtn(node) {
+ return shouldAddBtnToActionBar(wfDebugId, node);
+ }
+};