Repository: temporalio/ui
Pull request #161 (2021-12-08 20:40:15)

Format event labels with normal capitalization
Modifies event types and attribute labels to traditional capitalization.

![image](https://user-images.githubusercontent.com/251000/145281059-25a39f6b-dab9-4c2c-9930-cb6d2f9e0385.png)



Patch:
diff --git a/src/lib/components/code-block.svelte b/src/lib/components/code-block.svelte
index 3e7d8371..b57751c2 100644
--- a/src/lib/components/code-block.svelte
+++ b/src/lib/components/code-block.svelte
@@ -26,39 +26,37 @@
   onMount(() => window.Prism.highlightAll());
 </script>
 
-{#if content}
+{#if inline}
+  <code class="language-json text-xs">
+    {formatJSON(JSON.stringify(content))}
+  </code>
+{:else if content || content === null}
   <div class="relative w-full">
-    {#if !inline}<div id="clipboard" />{/if}
+    <div id="clipboard" />
 
     {#if heading}
       <h3 class="text-lg mb-2 w-full">{heading}</h3>
     {/if}
-    {#if inline}
-      <code class="px-2 block language-json overflow-hidden">
-        {JSON.stringify(content)}
-      </code>
-    {:else}
-      <pre
-        class="p-4">
+
+    <pre
+      class="p-4">
         <code class="language-json">
           {formatJSON(JSON.stringify(content))}
         </code>
       </pre>
-    {/if}
-    {#if !inline}
-      <button on:click={copy}>
-        {#if copied}
-          <Icon
-            src={Check}
-            class="w-8 h-8 text-purple-900 bg-gray-300 border-2 border-gray-200 absolute right-0 top-0 hidden group-hover:block hover:bg-gray-400 hover:border-gray-400"
-          />
-        {:else}
-          <Icon
-            src={Clipboard}
-            class="w-8 h-8 text-purple-900 bg-gray-300 border-2 border-gray-200 absolute right-0 top-0 hidden group-hover:block hover:bg-gray-400 hover:border-gray-400"
-          />
-        {/if}
-      </button>
-    {/if}
+
+    <button on:click={copy}>
+      {#if copied}
+        <Icon
+          src={Check}
+          class="w-8 h-8 text-purple-900 bg-gray-300 border-2 border-gray-200 absolute right-0 top-0 hidden group-hover:block hover:bg-gray-400 hover:border-gray-400"
+        />
+      {:else}
+        <Icon
+          src={Clipboard}
+          class="w-8 h-8 text-purple-900 bg-gray-300 border-2 border-gray-200 absolute right-0 top-0 hidden group-hover:block hover:bg-gray-400 hover:border-gray-400"
+        />
+      {/if}
+    </button>
   </div>
 {/if}
diff --git a/src/lib/utilities/format-camel-case.ts b/src/lib/utilities/format-camel-case.ts
new file mode 100644
index 00000000..8c90f7e0
--- /dev/null
+++ b/src/lib/utilities/format-camel-case.ts
@@ -0,0 +1,38 @@
+const isUpperCase = (label: string, index: number) => {
+  const charCode = label.charCodeAt(index);
+  return charCode >= 65 && charCode <= 90;
+};
+
+export const format = (label: string) => {
+  let result = '';
+  let index = 0;
+
+  while (index < label.length) {
+    const current = label[index];
+    const next = label[index + 1];
+
+    if (index === 0) {
+      result += label[index].toUpperCase();
+      index++;
+      continue;
+    }
+
+    if (current + next === 'Id') {
+      result += ' ID';
+      index += 2;
+      continue;
+    }
+
+    if (isUpperCase(label, index)) {
+      result += ' ';
+      result += current.toUpperCase();
+      index++;
+      continue;
+    }
+
+    result += current;
+    index++;
+  }
+
+  return result;
+};
diff --git a/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/_event.svelte b/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/_event.svelte
index d10b65cc..8c7f8340 100644
--- a/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/_event.svelte
+++ b/src/routes/namespaces/[namespace]/workflows/[workflow]/[run]/_event.svelte
@@ -1,29 +1,32 @@
 <script lang="ts">
-  import type { HistoryEvent } from '$types';
   import { getAttributesFromEvent } from '$lib/utilities/get-attributes-from-event';
   import { getEventClassification } from '$lib/utilities/get-event-classification';
+  import { format } from '$lib/utilities/format-camel-case';
 
   import CodeBlock from '$lib/components/code-block.svelte';
 
   export let event: HistoryEvent;
+
   const summaryEvent = getAttributesFromEvent(event);
 </script>
 
-<article class="flex flex-row items-start event-box border-2 p-4 rounded-lg">
+<article class="flex items-start event-box border-2 p-4 rounded-lg">
   <h2 class="w-1/3 flex-1 {event.eventType}">
-    <span class="label {getEventClassification(event)}">{event.eventType}</span>
+    <span class="label {getEventClassification(event)}">
+      {format(String(event.eventType))}
+    </span>
   </h2>
-  <div class="flex flex-row items-center event gap-4 w-full flex-3">
-    {#each Object.entries(summaryEvent.attributes) as [event, value]}
+  <div class="flex items-center event gap-4 w-full">
+    {#each Object.entries(summaryEvent.attributes) as [attribute, value]}
       {#if typeof value === 'object'}
-        <div class="flex flex-nowrap flex-row gap-2">
-          <h4>{event}</h4>
+        <div class="flex gap-2 flex-nowrap">
+          <h4>{format(attribute)}</h4>
           <CodeBlock content={value} inline={true} />
         </div>
       {:else if value}
-        <div class="flex gap-2">
-          <h4>{event}</h4>
-          <p class="label">{value}</p>
+        <div class="flex gap-2 flex-nowrap">
+          <h4>{format(attribute)}</h4>
+          <p class="w-full label">{value}</p>
         </div>
       {/if}
     {/each}
@@ -31,6 +34,10 @@
 </article>
 
 <style lang="postcss">
+  h4 {
+    @apply whitespace-nowrap;
+  }
+
   .event-box {
     margin: 1rem 0;
   }
@@ -40,7 +47,7 @@
   }
 
   .Scheduled {
-    @apply text-gray-700 bg-gray-100;
+    @apply text-gray-700 bg-gray-300;
   }
 
   .Open,
diff --git a/static/prism/prism.css b/static/prism/prism.css
index 8e377b7d..c7108ec8 100644
--- a/static/prism/prism.css
+++ b/static/prism/prism.css
@@ -28,6 +28,7 @@ pre[class*="language-"] {
 	-ms-hyphens: none;
 	hyphens: none;
 
+	font-size: 0.9em;
 }
 
 /* Code blocks */
@@ -122,4 +123,3 @@ pre[class*="language-"] {
 .token.inserted {
 	color: green;
 }
-


Test patch:
diff --git a/src/lib/utilities/format-camel-case.test.ts b/src/lib/utilities/format-camel-case.test.ts
new file mode 100644
index 00000000..2133eaec
--- /dev/null
+++ b/src/lib/utilities/format-camel-case.test.ts
@@ -0,0 +1,37 @@
+import { format } from './format-camel-case';
+
+describe(format, () => {
+  it('should format WorkflowExecutionStarted as "Workflow Execution Started"', () => {
+    expect(format('WorkflowExecutionStarted')).toBe(
+      'Workflow Execution Started',
+    );
+  });
+
+  it('should format lastCompletionResult as "Last Completion Result"', () => {
+    expect(format('lastCompletionResult')).toBe('Last Completion Result');
+  });
+
+  it('should format attempt as "Workflow Attempt"', () => {
+    expect(format('attempt')).toBe('Attempt');
+  });
+
+  it('should format requestId as "Request ID"', () => {
+    expect(format('requestId')).toBe('Request ID');
+  });
+
+  it('should format startedEventId as "Started Event ID"', () => {
+    expect(format('startedEventId')).toBe('Started Event ID');
+  });
+
+  it('should format identity as "Identity"', () => {
+    expect(format('identity')).toBe('Identity');
+  });
+
+  it('should format identityAnotherWord as "Identity Another Word"', () => {
+    expect(format('identityAnotherWord')).toBe('Identity Another Word');
+  });
+
+  it('should format requestIdSomething as "Request ID Something"', () => {
+    expect(format('requestIdSomething')).toBe('Request ID Something');
+  });
+});