Frank 4 months ago
parent
commit
aba94c658f

+ 132 - 128
packages/console/app/src/routes/workspace/[id]/graph-section.module.css

@@ -1,141 +1,145 @@
-[data-component="empty-state"] {
-  padding: var(--space-20) var(--space-6);
-  text-align: center;
-  border: 1px dashed var(--color-border);
-  border-radius: var(--border-radius-sm);
-  height: 400px;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-[data-component="empty-state"] p {
-  font-size: var(--font-size-sm);
-  color: var(--color-text-muted);
-}
-
-[data-slot="filter-container"] {
-  margin-bottom: 0;
-  display: flex;
-  align-items: center;
-  gap: var(--space-3);
-}
-
-[data-slot="month-picker"] {
-  display: flex;
-  align-items: center;
-  background-color: var(--color-bg);
-  border: 1px solid var(--color-border);
-  border-radius: var(--border-radius-sm);
-  padding: 0;
-}
-
-[data-slot="month-button"] {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  background: none;
-  border: none !important;
-  color: var(--color-text);
-  cursor: pointer;
-  padding: var(--space-2) var(--space-3);
-  border-radius: var(--border-radius-xs);
-  transition: background-color 0.2s;
-  line-height: 1;
-}
-
-[data-slot="month-button"]:hover {
-  background-color: var(--color-bg-hover);
-}
-
-[data-slot="month-button"] svg {
-  display: block;
-  width: 16px;
-  height: 16px;
-  stroke-width: 2;
-}
-
-[data-slot="month-label"] {
-  font-size: var(--font-size-sm);
-  font-weight: 500;
-  color: var(--color-text);
-  line-height: 1.5;
-  min-width: 140px;
-  text-align: center;
-  white-space: nowrap;
-}
-
-[data-slot="filter-container"] [data-component="dropdown"] [data-slot="trigger"] {
-  border: 1px solid var(--color-border);
-  background-color: var(--color-bg);
-  padding: var(--space-2) var(--space-3);
-  border-radius: var(--border-radius-sm);
-  color: var(--color-text);
-  font-size: var(--font-size-sm);
-  line-height: 1.5;
-
-  &:hover {
-    border-color: var(--color-accent);
+.root {
+  [data-component="empty-state"] {
+    padding: var(--space-20) var(--space-6);
+    text-align: center;
+    border: 1px dashed var(--color-border);
+    border-radius: var(--border-radius-sm);
+    height: 400px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    p {
+      font-size: var(--font-size-sm);
+      color: var(--color-text-muted);
+    }
   }
 
-  &:focus {
-    outline: none;
-    border-color: var(--color-accent);
-    box-shadow: 0 0 0 3px var(--color-accent-alpha);
+  [data-slot="filter-container"] {
+    margin-bottom: 0;
+    display: flex;
+    align-items: center;
+    gap: var(--space-3);
+
+    [data-component="dropdown"] {
+      [data-slot="trigger"] {
+        border: 1px solid var(--color-border);
+        background-color: var(--color-bg);
+        padding: var(--space-2) var(--space-3);
+        border-radius: var(--border-radius-sm);
+        color: var(--color-text);
+        font-size: var(--font-size-sm);
+        line-height: 1.5;
+
+        &:hover {
+          border-color: var(--color-accent);
+        }
+
+        &:focus {
+          outline: none;
+          border-color: var(--color-accent);
+          box-shadow: 0 0 0 3px var(--color-accent-alpha);
+        }
+      }
+
+      [data-slot="chevron"] {
+        opacity: 0.6;
+      }
+
+      [data-slot="dropdown"] {
+        min-width: 200px;
+        max-height: 300px;
+        overflow-y: auto;
+        padding: var(--space-1);
+      }
+    }
   }
-}
-
-[data-slot="filter-container"] [data-component="dropdown"] [data-slot="chevron"] {
-  opacity: 0.6;
-}
 
-[data-slot="filter-container"] [data-component="dropdown"] [data-slot="dropdown"] {
-  min-width: 200px;
-  max-height: 300px;
-  overflow-y: auto;
-  padding: var(--space-1);
-}
-
-[data-slot="model-item"] {
-  display: flex;
-  align-items: center;
-  gap: var(--space-2);
-  padding: var(--space-2) var(--space-3);
-  cursor: pointer;
-  transition: background-color 0.2s;
-  font-size: var(--font-size-sm);
-  color: var(--color-text);
-  border: none !important;
-  background: none;
-  width: 100%;
-  text-align: left;
-  white-space: nowrap;
-}
+  [data-slot="month-picker"] {
+    display: flex;
+    align-items: center;
+    background-color: var(--color-bg);
+    border: 1px solid var(--color-border);
+    border-radius: var(--border-radius-sm);
+    padding: 0;
+  }
 
-[data-slot="model-item"]:hover {
-  background: var(--color-bg-hover);
-}
+  [data-slot="month-button"] {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: none;
+    border: none !important;
+    color: var(--color-text);
+    cursor: pointer;
+    padding: var(--space-2) var(--space-3);
+    border-radius: var(--border-radius-xs);
+    transition: background-color 0.2s;
+    line-height: 1;
+
+    &:hover {
+      background-color: var(--color-bg-hover);
+    }
+
+    svg {
+      display: block;
+      width: 16px;
+      height: 16px;
+      stroke-width: 2;
+    }
+  }
 
-[data-slot="model-item"] span {
-  flex: 1;
-  user-select: none;
-}
+  [data-slot="month-label"] {
+    font-size: var(--font-size-sm);
+    font-weight: 500;
+    color: var(--color-text);
+    line-height: 1.5;
+    min-width: 140px;
+    text-align: center;
+    white-space: nowrap;
+  }
 
-[data-slot="chart-container"] {
-  padding: var(--space-6);
-  background: var(--color-bg-secondary);
-  border: 1px solid var(--color-border);
-  border-radius: var(--border-radius-sm);
-  height: 400px;
-}
+  [data-slot="model-item"] {
+    display: flex;
+    align-items: center;
+    gap: var(--space-2);
+    padding: var(--space-2) var(--space-3);
+    cursor: pointer;
+    transition: background-color 0.2s;
+    font-size: var(--font-size-sm);
+    color: var(--color-text);
+    border: none !important;
+    background: none;
+    width: 100%;
+    text-align: left;
+    white-space: nowrap;
+
+    &:hover {
+      background: var(--color-bg-hover);
+    }
+
+    span {
+      flex: 1;
+      user-select: none;
+    }
+  }
 
-@media (max-width: 40rem) {
   [data-slot="chart-container"] {
-    height: 300px;
-    padding: var(--space-4);
+    padding: var(--space-6);
+    background: var(--color-bg-secondary);
+    border: 1px solid var(--color-border);
+    border-radius: var(--border-radius-sm);
+    height: 400px;
   }
 
-  [data-component="empty-state"] {
-    height: 300px;
+  @media (max-width: 40rem) {
+    [data-slot="chart-container"] {
+      height: 300px;
+      padding: var(--space-4);
+    }
+
+    [data-component="empty-state"] {
+      height: 300px;
+    }
   }
 }

+ 2 - 2
packages/console/app/src/routes/workspace/[id]/graph-section.tsx

@@ -9,7 +9,7 @@ import { createStore } from "solid-js/store"
 import { withActor } from "~/context/auth.withActor"
 import { Dropdown } from "~/component/dropdown"
 import { IconChevronLeft, IconChevronRight } from "~/component/icon"
-import "./graph-section.module.css"
+import styles from "./graph-section.module.css"
 import {
   Chart,
   BarController,
@@ -346,7 +346,7 @@ export function GraphSection() {
   onCleanup(() => chartInstance?.destroy())
 
   return (
-    <section>
+    <section class={styles.root}>
       <div data-slot="section-title">
         <h2>Cost</h2>
         <p>Usage costs broken down by model.</p>

+ 99 - 97
packages/console/app/src/routes/workspace/[id]/usage-section.module.css

@@ -1,117 +1,119 @@
-/* Empty state */
-[data-component="empty-state"] {
-  padding: var(--space-20) var(--space-6);
-  text-align: center;
-  border: 1px dashed var(--color-border);
-  border-radius: var(--border-radius-sm);
-
-  p {
-    font-size: var(--font-size-sm);
-    color: var(--color-text-muted);
-  }
-}
-
-/* Table container */
-[data-slot="usage-table"] {
-  overflow-x: auto;
-}
-
-/* Table element */
-[data-slot="usage-table-element"] {
-  width: 100%;
-  border-collapse: collapse;
-  font-size: var(--font-size-sm);
-
-  thead {
-    border-bottom: 1px solid var(--color-border);
-  }
-
-  th {
-    padding: var(--space-3) var(--space-4);
-    text-align: left;
-    font-weight: normal;
-    color: var(--color-text-muted);
-    text-transform: uppercase;
-  }
-
-  td {
-    padding: var(--space-3) var(--space-4);
-    border-bottom: 1px solid var(--color-border-muted);
-    color: var(--color-text-muted);
-    font-family: var(--font-mono);
-
-    &[data-slot="usage-date"] {
-      color: var(--color-text);
-    }
-
-    &[data-slot="usage-model"] {
-      font-family: var(--font-sans);
-      color: var(--color-text-secondary);
-      max-width: 200px;
-      word-break: break-word;
-    }
+.root {
+  /* Empty state */
+  [data-component="empty-state"] {
+    padding: var(--space-20) var(--space-6);
+    text-align: center;
+    border: 1px dashed var(--color-border);
+    border-radius: var(--border-radius-sm);
 
-    &[data-slot="usage-cost"] {
-      color: var(--color-text);
-      font-weight: 500;
+    p {
+      font-size: var(--font-size-sm);
+      color: var(--color-text-muted);
     }
   }
 
-  tbody tr:last-child td {
-    border-bottom: none;
+  /* Table container */
+  [data-slot="usage-table"] {
+    overflow-x: auto;
   }
-}
 
-/* Pagination */
-[data-slot="pagination"] {
-  display: flex;
-  justify-content: flex-end;
-  gap: var(--space-2);
-  padding: var(--space-4) 0;
-  border-top: 1px solid var(--color-border-muted);
-  margin-top: var(--space-2);
-
-  button {
-    padding: var(--space-2) var(--space-4);
-    background: var(--color-bg-secondary);
-    border: 1px solid var(--color-border);
-    border-radius: var(--border-radius-sm);
-    color: var(--color-text);
+  /* Table element */
+  [data-slot="usage-table-element"] {
+    width: 100%;
+    border-collapse: collapse;
     font-size: var(--font-size-sm);
-    cursor: pointer;
-    transition: all 0.15s ease;
 
-    svg {
-      width: 16px;
-      height: 16px;
-      stroke-width: 2;
+    thead {
+      border-bottom: 1px solid var(--color-border);
+    }
+
+    th {
+      padding: var(--space-3) var(--space-4);
+      text-align: left;
+      font-weight: normal;
+      color: var(--color-text-muted);
+      text-transform: uppercase;
     }
 
-    &:hover:not(:disabled) {
-      background: var(--color-bg-tertiary);
-      border-color: var(--color-border-hover);
+    td {
+      padding: var(--space-3) var(--space-4);
+      border-bottom: 1px solid var(--color-border-muted);
+      color: var(--color-text-muted);
+      font-family: var(--font-mono);
+
+      &[data-slot="usage-date"] {
+        color: var(--color-text);
+      }
+
+      &[data-slot="usage-model"] {
+        font-family: var(--font-sans);
+        color: var(--color-text-secondary);
+        max-width: 200px;
+        word-break: break-word;
+      }
+
+      &[data-slot="usage-cost"] {
+        color: var(--color-text);
+        font-weight: 500;
+      }
     }
 
-    &:disabled {
-      opacity: 0.5;
-      cursor: not-allowed;
+    tbody tr:last-child td {
+      border-bottom: none;
     }
   }
-}
 
-/* Mobile responsive */
-@media (max-width: 40rem) {
-  [data-slot="usage-table-element"] {
-    th,
-    td {
-      padding: var(--space-2) var(--space-3);
-      font-size: var(--font-size-xs);
+  /* Pagination */
+  [data-slot="pagination"] {
+    display: flex;
+    justify-content: flex-end;
+    gap: var(--space-2);
+    padding: var(--space-4) 0;
+    border-top: 1px solid var(--color-border-muted);
+    margin-top: var(--space-2);
+
+    button {
+      padding: var(--space-2) var(--space-4);
+      background: var(--color-bg-secondary);
+      border: 1px solid var(--color-border);
+      border-radius: var(--border-radius-sm);
+      color: var(--color-text);
+      font-size: var(--font-size-sm);
+      cursor: pointer;
+      transition: all 0.15s ease;
+
+      svg {
+        width: 16px;
+        height: 16px;
+        stroke-width: 2;
+      }
+
+      &:hover:not(:disabled) {
+        background: var(--color-bg-tertiary);
+        border-color: var(--color-border-hover);
+      }
+
+      &:disabled {
+        opacity: 0.5;
+        cursor: not-allowed;
+      }
     }
+  }
 
-    /* Hide Model column on mobile */
-    th:nth-child(2),
-    td:nth-child(2) {
-      display: none;
+  /* Mobile responsive */
+  @media (max-width: 40rem) {
+    [data-slot="usage-table-element"] {
+      th,
+      td {
+        padding: var(--space-2) var(--space-3);
+        font-size: var(--font-size-xs);
+      }
+
+      /* Hide Model column on mobile */
+      th:nth-child(2),
+      td:nth-child(2) {
+        display: none;
+      }
     }
   }
 }

+ 2 - 2
packages/console/app/src/routes/workspace/[id]/usage-section.tsx

@@ -4,7 +4,7 @@ import { createMemo, For, Show, createEffect } from "solid-js"
 import { formatDateUTC, formatDateForTable } from "../common"
 import { withActor } from "~/context/auth.withActor"
 import { IconChevronLeft, IconChevronRight } from "~/component/icon"
-import "./usage-section.module.css"
+import styles from "./usage-section.module.css"
 import { createStore } from "solid-js/store"
 
 const PAGE_SIZE = 50
@@ -47,7 +47,7 @@ export function UsageSection() {
   }
 
   return (
-    <section>
+    <section class={styles.root}>
       <div data-slot="section-title">
         <h2>Usage History</h2>
         <p>Recent API usage and costs.</p>