[resultui] improve resultdb integration hint

1. Add ResultDB integration hints (with an option to hide it) to the
bottom of the test results tab.
2. Mention luci-eng@ in integration hints.
3. Do not display "no associated invocation" when the invocation ID is
not initialised yet.

R=nqmtuan@google.com, orodley@google.com

Change-Id: Idf47b0ad424c90348d57c0eaf5426674e455f49a
Bug: 1128852
Reviewed-on: https://chromium-review.googlesource.com/c/infra/luci/luci-go/+/2418774
Reviewed-by: Quang Minh Tuan Nguyen <nqmtuan@google.com>
Commit-Queue: Weiwei Lin <weiweilin@google.com>
diff --git a/milo/frontend/resultui/src/context/app_state/user_configs.ts b/milo/frontend/resultui/src/context/app_state/user_configs.ts
index 127168f..0d4d8f3 100644
--- a/milo/frontend/resultui/src/context/app_state/user_configs.ts
+++ b/milo/frontend/resultui/src/context/app_state/user_configs.ts
@@ -19,6 +19,9 @@
 
 // Backward incompatible changes are not allowed.
 export interface UserConfigs {
+  hints: {
+    showResultDbIntegrationHint: boolean;
+  };
   steps: {
     showSucceededSteps: boolean;
     showDebugLogs: boolean;
@@ -31,6 +34,9 @@
 }
 
 export const DEFAULT_USER_CONFIGS = Object.freeze<UserConfigs>({
+  hints: {
+    showResultDbIntegrationHint: true,
+  },
   steps: Object.freeze({
     showSucceededSteps: true,
     showDebugLogs: false,
diff --git a/milo/frontend/resultui/src/context/invocation_state/invocation_state.ts b/milo/frontend/resultui/src/context/invocation_state/invocation_state.ts
index 96fe150..7fc3809 100644
--- a/milo/frontend/resultui/src/context/invocation_state/invocation_state.ts
+++ b/milo/frontend/resultui/src/context/invocation_state/invocation_state.ts
@@ -29,6 +29,7 @@
  */
 export class InvocationState {
   @observable.ref invocationId = '';
+  @observable.ref initialized = false;
 
   constructor(private appState: AppState, private userConfigs: UserConfigs) {}
 
diff --git a/milo/frontend/resultui/src/pages/build_page/index.ts b/milo/frontend/resultui/src/pages/build_page/index.ts
index ca2a2d1..d5e0da8 100644
--- a/milo/frontend/resultui/src/pages/build_page/index.ts
+++ b/milo/frontend/resultui/src/pages/build_page/index.ts
@@ -69,10 +69,15 @@
     this.buildState.builder = this.builder;
     this.buildState.buildNumOrId = this.buildNumOrId;
 
-    this.disposers.push(autorun(
-      () => this.invocationState.invocationId = this.buildState.buildPageData
-        ?.infra?.resultdb.invocation?.slice('invocations/'.length) || '',
-    ));
+    this.disposers.push(autorun(() => {
+      const bpd = this.buildState.buildPageData;
+      if (!bpd) {
+        return;
+      }
+      this.invocationState.invocationId = bpd.infra?.resultdb.invocation
+        ?.slice('invocations/'.length) || '';
+      this.invocationState.initialized = true;
+    }));
   }
 
   disconnectedCallback() {
diff --git a/milo/frontend/resultui/src/pages/invocation_page/index.ts b/milo/frontend/resultui/src/pages/invocation_page/index.ts
index 2e1a6b7..9bf1613 100644
--- a/milo/frontend/resultui/src/pages/invocation_page/index.ts
+++ b/milo/frontend/resultui/src/pages/invocation_page/index.ts
@@ -50,6 +50,7 @@
   connectedCallback() {
     super.connectedCallback();
     this.invocationState.invocationId = this.invocationId;
+    this.invocationState.initialized = true;
   }
 
   private renderInvocationState() {
diff --git a/milo/frontend/resultui/src/pages/test_results_tab.ts b/milo/frontend/resultui/src/pages/test_results_tab.ts
index 4ca9e77..719f9be 100644
--- a/milo/frontend/resultui/src/pages/test_results_tab.ts
+++ b/milo/frontend/resultui/src/pages/test_results_tab.ts
@@ -145,12 +145,13 @@
   private renderMain() {
     const state = this.invocationState;
 
-    if (!state.invocation) {
+    if (state.initialized && !state.invocationId) {
       return html`
         <div id="no-invocation">
           No associated invocation.<br>
           You need to integrate with ResultDB to see the test results.<br>
-          <a href="http://go/resultdb" target="_blank">go/resultdb</a>
+          See <a href="http://go/resultdb" target="_blank">go/resultdb</a>
+          or ask <a href="mailto: luci-eng@google.com" target="_blank">luci-eng@</a> for help.
         </div>
       `;
     }
@@ -182,9 +183,21 @@
             >
               Loading <milo-dot-spinner></milo-dot-spinner>
             </span>
-            <mwc-icon id="load-info" title="Newly loaded entries might be inserted into the list.">info</mwc-icon>
+            <mwc-icon class="inline-icon" title="Newly loaded entries might be inserted into the list.">info</mwc-icon>
           </span>
         </div>
+        <span
+          class="list-entry"
+          style=${styleMap({'display': this.userConfigs.hints.showResultDbIntegrationHint && !state.testLoader.isLoading ? '' : 'none'})}
+        >
+          Don't see results of your test framework here?
+          This might be because they are not integrated with ResultDB yet.
+          Please ask <a href="mailto: luci-eng@google.com" target="_blank">luci-eng@</a> for help.
+          <span
+            id="hide-hint"
+            @click=${() => this.userConfigs.hints.showResultDbIntegrationHint = false}
+          >Don't show again</span>
+        </span>
       </div>
     `;
   }
@@ -194,12 +207,10 @@
       <div id="header">
         <milo-test-filter></milo-test-filter>
         <mwc-button
-          class="action-button"
           dense unelevated
           @click=${() => this.toggleAllVariants(true)}
         >Expand All</mwc-button>
         <mwc-button
-          class="action-button"
           dense unelevated
           @click=${() => this.toggleAllVariants(false)}
         >Collapse All</mwc-button>
@@ -264,11 +275,16 @@
       color: var(--active-text-color);
       cursor: pointer;
     }
-    #load-info {
+    .inline-icon {
       color: var(--default-text-color);
       --mdc-icon-size: 1.2em;
       vertical-align: bottom;
     }
+    #hide-hint {
+      margin-left: 5px;
+      color: var(--active-text-color);
+      cursor: pointer;
+    }
   `;
 }