Repository: temporalio/ui
Pull request #219 (2022-01-11 22:25:34)

Add event IDs to list
![image](https://user-images.githubusercontent.com/251000/149031153-3b4c14d0-a66c-44fb-adca-02a429311514.png)


Patch:
diff --git a/src/lib/components/event.svelte b/src/lib/components/event.svelte
index 415b67d7..27bd086b 100644
--- a/src/lib/components/event.svelte
+++ b/src/lib/components/event.svelte
@@ -12,7 +12,7 @@
 
   export let event: HistoryEventWithId | PendingActivity | Activity;
 
-  let { routeFor, pending, timeStamp, name, tag, classification } =
+  let { routeFor, pending, timeStamp, name, tag, classification, id } =
     formatEvent(event);
 
   let { namespace, workflow: workflowId, run: runId } = $page.params;
@@ -27,20 +27,23 @@
   class:pending
   class:active={$page.path.includes(href)}
 >
-  <article class="p-4 w-full">
-    <h2 class="mb-2 {tag}">
-      <EventLabel color={classification}>
-        {name}
-      </EventLabel>
-    </h2>
-    <p class="text-sm">
-      <Icon icon={faCalendar} class="inline" />
-      {formatDate(timeStamp)}
-    </p>
+  <article class="flex gap-4 items-center p-4">
+    <p class="w-5 text-center text-gray-500">{id}</p>
+    <div class="w-full">
+      <h2 class="mb-2 {tag}">
+        <EventLabel color={classification}>
+          {name}
+        </EventLabel>
+      </h2>
+      <p class="text-sm">
+        <Icon icon={faCalendar} class="inline" />
+        {formatDate(timeStamp)}
+      </p>
+    </div>
+    {#if pending}
+      <div class="mx-8 text-orange-600 italic">Pending</div>
+    {/if}
   </article>
-  {#if pending}
-    <div class="mx-8 text-orange-600 italic">Pending</div>
-  {/if}
 </a>
 
 <style lang="postcss">
diff --git a/src/lib/components/workers-row.svelte b/src/lib/components/workers-row.svelte
index 53944000..1dd4438f 100644
--- a/src/lib/components/workers-row.svelte
+++ b/src/lib/components/workers-row.svelte
@@ -6,7 +6,9 @@
   export let poller;
 </script>
 
-<article class="w-full h-full flex flex-row border-b-2 no-underline p-2">
+<article
+  class="w-full h-full flex flex-row border-b-2 last:border-b-0 no-underline p-2"
+>
   <div class="links w-3/12 text-left">
     {poller.identity}
   </div>
diff --git a/src/lib/stores/refreshable.ts b/src/lib/stores/refreshable.ts
index 3de7f665..20689997 100644
--- a/src/lib/stores/refreshable.ts
+++ b/src/lib/stores/refreshable.ts
@@ -1,5 +1,3 @@
-import { onDestroy, onMount } from 'svelte';
-
 import { writable } from 'svelte/store';
 import type { Writable } from 'svelte/store';
 
@@ -12,16 +10,17 @@ export const refreshable = <T>(
   initialData: PromiseLike<T> | T = callback(),
   timeout: Timeout = 10000,
 ): Writable<PromiseLike<T>> => {
-  const store = writable<PromiseLike<T>>(Promise.resolve(initialData));
   let interval: Timer;
 
-  onMount(() => {
+  const cleanUp = () => clearInterval(interval);
+  const setUp = () => {
     interval = setInterval(() => {
       callback().then((data: T) => store.set(Promise.resolve(data)));
     }, timeout);
-  });
+    return cleanUp;
+  };
 
-  onDestroy(() => clearInterval(interval));
+  const store = writable<PromiseLike<T>>(Promise.resolve(initialData), setUp);
 
   return store;
 };
diff --git a/src/lib/utilities/convert-to-json.ts b/src/lib/utilities/create-data-url.ts
similarity index 87%
rename from src/lib/utilities/convert-to-json.ts
rename to src/lib/utilities/create-data-url.ts
index db126028..b506a4b7 100644
--- a/src/lib/utilities/convert-to-json.ts
+++ b/src/lib/utilities/create-data-url.ts
@@ -1,4 +1,4 @@
-export const convertToJSON = (
+export const createDataUrl = (
   events: Parameters<typeof JSON.stringify>[0],
 ): string => {
   const data = JSON.stringify(events);
diff --git a/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/history/__layout.svelte b/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/history/__layout.svelte
index e8afa144..67a32f1e 100644
--- a/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/history/__layout.svelte
+++ b/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/history/__layout.svelte
@@ -26,12 +26,13 @@
     faStream,
   } from '@fortawesome/free-solid-svg-icons';
 
+  import { routeFor } from '$lib/utilities/route-for';
+  import { createDataUrl } from '$lib/utilities/create-data-url';
+  import { fetchEvents } from '$lib/services/events-service';
   import { refreshable } from '$lib/stores/refreshable';
 
   import ToggleButton from '$lib/components/toggle-button.svelte';
   import ToggleButtons from '$lib/components/toggle-buttons.svelte';
-  import { routeFor } from '$lib/utilities/route-for';
-  import { fetchEvents } from '$lib/services/events-service';
 
   export let workflow: WorkflowParameters;
   export let parameters: Parameters<typeof fetchEvents>[0];
@@ -58,7 +59,7 @@
           href={routeFor('workflow.events.json', workflow)}
         />
       </ToggleButtons>
-      <ToggleButton icon={faDownload} href="#no-implemented" />
+      <ToggleButton icon={faDownload} href={createDataUrl(events)} />
     </div>
   </nav>
 </section>
diff --git a/src/routes/namespaces/[namespace]/workflows/index.svelte b/src/routes/namespaces/[namespace]/workflows/index.svelte
index c46a3f16..655f5762 100644
--- a/src/routes/namespaces/[namespace]/workflows/index.svelte
+++ b/src/routes/namespaces/[namespace]/workflows/index.svelte
@@ -42,7 +42,7 @@
 
   let timeFormat: TimeFormat = 'UTC';
 
-  let data = refreshable(
+  $: data = refreshable(
     () => fetchAllWorkflows(namespace, { timeRange }),
     initialData,
   );


Test patch:
diff --git a/src/lib/utilities/convert-to-json.test.ts b/src/lib/utilities/create-data-url.test.ts
similarity index 60%
rename from src/lib/utilities/convert-to-json.test.ts
rename to src/lib/utilities/create-data-url.test.ts
index f8f42135..52b17437 100644
--- a/src/lib/utilities/convert-to-json.test.ts
+++ b/src/lib/utilities/create-data-url.test.ts
@@ -1,9 +1,9 @@
-import { convertToJSON } from './convert-to-json';
+import { createDataUrl } from './create-data-url';
 
-describe(convertToJSON, () => {
+describe(createDataUrl, () => {
   it('should return a data-encoded URI based on an object', () => {
     const example = { hello: 123 };
-    expect(convertToJSON(example)).toBe(
+    expect(createDataUrl(example)).toBe(
       'data:application/json;charset=utf-8,%7B%22hello%22%3A123%7D',
     );
   });