Add ability to save and view a list of workflows

This CL introduces the following functionality:

- Introduces some logic to handle the persistence of workflows in the
  browser storage.
- Lets the user save created workflows in the "create workflow" dialog.
- Shows a list of workflows. If the user hasn't added any workflow, a
  placeholder image is shown alongside a text which invites the user to
  create a new workflow.

Bug: twpowertools:74

Change-Id: Icba09d20468bafc1415b802a3c935e22669546e6
diff --git a/src/workflows/manager/components/AddDialog.js b/src/workflows/manager/components/AddDialog.js
index 8bf63db..32a2cae 100644
--- a/src/workflows/manager/components/AddDialog.js
+++ b/src/workflows/manager/components/AddDialog.js
@@ -1,6 +1,6 @@
 import '@material/mwc-dialog/mwc-dialog.js';
 import '@material/web/button/text-button.js';
-import '@material/web/button/tonal-button.js';
+import '@material/web/button/filled-button.js';
 import './WorkflowEditor.js';
 
 import {css, html, LitElement} from 'lit';
@@ -35,11 +35,11 @@
           @closed=${this._closedDialog}>
         <wf-workflow-editor ${ref(this.workflowEditorRef)}>
         </wf-workflow-editor>
-        <md-tonal-button
+        <md-filled-button
             slot="primaryAction"
             label="Add"
             @click=${this._save}>
-        </md-tonal-button>
+        </md-filled-button>
         <md-text-button
             slot="secondaryAction"
             dialogAction="cancel"
diff --git a/src/workflows/manager/components/List.js b/src/workflows/manager/components/List.js
index 09220b1..a7851ee 100644
--- a/src/workflows/manager/components/List.js
+++ b/src/workflows/manager/components/List.js
@@ -1,8 +1,77 @@
-import {html, LitElement} from 'lit';
+import '@material/web/list/list.js';
+import '@material/web/list/list-item.js';
+import '@material/web/iconbutton/standard-icon-button.js';
+
+import {css, html, LitElement, nothing} from 'lit';
+import {map} from 'lit/directives/map.js';
 
 export default class WFList extends LitElement {
+  static properties = {
+    workflows: {type: Object},
+  };
+
+  static styles = css`
+    .noworkflows {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      margin: 32px 0;
+    }
+
+    .noworkflows--image {
+      margin-bottom: 16px;
+      max-width: 500px;
+    }
+
+    .noworkflows--helper {
+      color: #555;
+    }
+  `;
+
+  renderListItems() {
+    return map(this.workflows, w => html`
+      <md-list-item
+          headline=${w.proto?.getName?.()}
+          @click=${() => this._show(w.uuid)}>
+        <div slot="end" class="end">
+          <md-standard-icon-button
+              icon="edit"
+              @click=${e => this._showEdit(w.uuid, e)}>
+          </md-standard-icon-button>
+          <md-standard-icon-button
+              icon="delete"
+              @click=${e => this._showDelete(w.uuid, e)}>
+          </md-standard-icon-button>
+        </div>
+      </md-list-item>
+    `);
+  }
+
   render() {
-    return html`<p>Temporary placeholder where the workflows list will exist.</p>`;
+    if (!this.workflows) return nothing;
+    if (this.workflows?.length === 0)
+      return html`
+      <div class="noworkflows">
+        <img class="noworkflows--image" src="/img/undraw_insert.svg">
+        <span class="noworkflows--helper">You haven't created any workflow yet! Create one by clicking the button in the bottom-right corner.</span>
+      </div>
+    `;
+
+    return html`
+      <md-list>
+        ${this.renderListItems()}
+      </md-list>
+    `;
+  }
+
+  _show(uuid) {}
+
+  _showEdit(uuid, e) {
+    e.stopPropagation();
+  }
+
+  _showDelete(uuid, e) {
+    e.stopPropagation();
   }
 }
 window.customElements.define('wf-list', WFList);
diff --git a/src/workflows/manager/components/WorkflowEditor.js b/src/workflows/manager/components/WorkflowEditor.js
index 4a8ab90..dcd38cd 100644
--- a/src/workflows/manager/components/WorkflowEditor.js
+++ b/src/workflows/manager/components/WorkflowEditor.js
@@ -7,6 +7,7 @@
 import {repeat} from 'lit/directives/repeat.js';
 
 import * as pb from '../../proto/main_pb.js';
+import WorkflowsStorage from '../../workflowsStorage.js';
 
 export default class WFWorkflowEditor extends LitElement {
   static properties = {
@@ -82,7 +83,8 @@
     const actionEditors = this.renderRoot.querySelectorAll('wf-action-editor');
     for (const editor of actionEditors) allValid &&= editor.checkValidity();
 
-    // @TODO: Save if allValid === true
+    // Save the workflow if the validation checks passed
+    if (allValid) WorkflowsStorage.add(this.workflow);
 
     return allValid;
   }