agent ui components
This commit is contained in:
parent
a9c7f92687
commit
1ced6ece4c
|
|
@ -17,3 +17,5 @@ appmap.log
|
||||||
/vsc/node_modules
|
/vsc/node_modules
|
||||||
/vsc/dist
|
/vsc/dist
|
||||||
node_modules/
|
node_modules/
|
||||||
|
/frontend/common/dist
|
||||||
|
/frontend/web/dist/
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
export * from './button';
|
export * from './button';
|
||||||
export * from './card';
|
export * from './card';
|
||||||
|
export * from './collapsible';
|
||||||
export * from './input';
|
export * from './input';
|
||||||
|
export * from './sheet';
|
||||||
export * from './switch';
|
export * from './switch';
|
||||||
|
export * from './scroll-area';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
export * from './button';
|
export * from './button';
|
||||||
export * from './card';
|
export * from './card';
|
||||||
|
export * from './collapsible';
|
||||||
export * from './input';
|
export * from './input';
|
||||||
|
export * from './sheet';
|
||||||
export * from './switch';
|
export * from './switch';
|
||||||
|
export * from './scroll-area';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import './styles/global.css';
|
import './styles/global.css';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
export * from './components/ui';
|
export * from './components/ui';
|
||||||
|
export * from './components/TimelineStep';
|
||||||
|
export * from './components/TimelineFeed';
|
||||||
|
export * from './components/SessionDrawer';
|
||||||
|
export * from './components/SessionSidebar';
|
||||||
export declare const hello: () => void;
|
export declare const hello: () => void;
|
||||||
|
export { getSampleAgentSteps, getSampleAgentSessions, type AgentStep, type AgentSession } from './utils/sample-data';
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,18 @@
|
||||||
// Entry point for @ra-aid/common package
|
// Entry point for @ra-aid/common package
|
||||||
import './styles/global.css';
|
import './styles/global.css';
|
||||||
// Export utility functions
|
// Export utility functions (excluding sample data to avoid circular references)
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
// Export all UI components
|
// Export all UI components
|
||||||
export * from './components/ui';
|
export * from './components/ui';
|
||||||
|
// Export timeline components
|
||||||
|
export * from './components/TimelineStep';
|
||||||
|
export * from './components/TimelineFeed';
|
||||||
|
// Export session navigation components
|
||||||
|
export * from './components/SessionDrawer';
|
||||||
|
export * from './components/SessionSidebar';
|
||||||
// Export the hello function (temporary example)
|
// Export the hello function (temporary example)
|
||||||
export const hello = () => {
|
export const hello = () => {
|
||||||
console.log("Hello from @ra-aid/common");
|
console.log("Hello from @ra-aid/common");
|
||||||
};
|
};
|
||||||
|
// Directly export sample data functions and types to avoid circular references
|
||||||
|
export { getSampleAgentSteps, getSampleAgentSessions } from './utils/sample-data';
|
||||||
|
|
|
||||||
|
|
@ -539,9 +539,85 @@ video {
|
||||||
color: hsl(var(--foreground));
|
color: hsl(var(--foreground));
|
||||||
font-feature-settings: "rlig" 1, "calt" 1;
|
font-feature-settings: "rlig" 1, "calt" 1;
|
||||||
}
|
}
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
.pointer-events-none {
|
.pointer-events-none {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.fixed {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
.absolute {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.relative {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.inset-0 {
|
||||||
|
inset: 0px;
|
||||||
|
}
|
||||||
|
.inset-x-0 {
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
.inset-y-0 {
|
||||||
|
top: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
.bottom-0 {
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
.left-0 {
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
.right-0 {
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
.right-4 {
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
.top-0 {
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
|
.top-4 {
|
||||||
|
top: 1rem;
|
||||||
|
}
|
||||||
|
.z-50 {
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.mr-2 {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
.mr-3 {
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
}
|
||||||
|
.mt-1 {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
.mt-1\.5 {
|
||||||
|
margin-top: 0.375rem;
|
||||||
|
}
|
||||||
|
.mt-3 {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
}
|
||||||
|
.mt-6 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
@ -551,9 +627,18 @@ video {
|
||||||
.inline-flex {
|
.inline-flex {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.h-10 {
|
.h-10 {
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
}
|
}
|
||||||
|
.h-2\.5 {
|
||||||
|
height: 0.625rem;
|
||||||
|
}
|
||||||
|
.h-3 {
|
||||||
|
height: 0.75rem;
|
||||||
|
}
|
||||||
.h-4 {
|
.h-4 {
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
}
|
}
|
||||||
|
|
@ -566,44 +651,142 @@ video {
|
||||||
.h-9 {
|
.h-9 {
|
||||||
height: 2.25rem;
|
height: 2.25rem;
|
||||||
}
|
}
|
||||||
|
.h-\[calc\(100vh-5rem\)\] {
|
||||||
|
height: calc(100vh - 5rem);
|
||||||
|
}
|
||||||
|
.h-full {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.h-screen {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
.w-2\.5 {
|
||||||
|
width: 0.625rem;
|
||||||
|
}
|
||||||
|
.w-3 {
|
||||||
|
width: 0.75rem;
|
||||||
|
}
|
||||||
|
.w-3\/4 {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
.w-4 {
|
.w-4 {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
}
|
}
|
||||||
|
.w-5 {
|
||||||
|
width: 1.25rem;
|
||||||
|
}
|
||||||
.w-9 {
|
.w-9 {
|
||||||
width: 2.25rem;
|
width: 2.25rem;
|
||||||
}
|
}
|
||||||
|
.w-\[250px\] {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
.w-\[85\%\] {
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.min-w-0 {
|
||||||
|
min-width: 0px;
|
||||||
|
}
|
||||||
|
.max-w-xs {
|
||||||
|
max-width: 20rem;
|
||||||
|
}
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
}
|
||||||
|
.flex-shrink-0 {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
.shrink-0 {
|
.shrink-0 {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.cursor-pointer {
|
.cursor-pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.touch-none {
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
.select-none {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
.flex-col {
|
.flex-col {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
.flex-col-reverse {
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
.items-start {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.items-end {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
.items-center {
|
.items-center {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.justify-center {
|
.justify-center {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
.justify-between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.gap-2 {
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.gap-4 {
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
|
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-y-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
|
margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
|
margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
|
||||||
}
|
}
|
||||||
|
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
.overflow-hidden {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.overflow-x-auto {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
.truncate {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
.whitespace-nowrap {
|
.whitespace-nowrap {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.whitespace-pre-wrap {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
.rounded {
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
.rounded-\[inherit\] {
|
||||||
|
border-radius: inherit;
|
||||||
|
}
|
||||||
.rounded-full {
|
.rounded-full {
|
||||||
border-radius: 9999px;
|
border-radius: 9999px;
|
||||||
}
|
}
|
||||||
.rounded-md {
|
.rounded-md {
|
||||||
border-radius: calc(var(--radius) - 2px);
|
border-radius: calc(var(--radius) - 2px);
|
||||||
}
|
}
|
||||||
|
.rounded-sm {
|
||||||
|
border-radius: calc(var(--radius) - 4px);
|
||||||
|
}
|
||||||
.rounded-xl {
|
.rounded-xl {
|
||||||
border-radius: 0.75rem;
|
border-radius: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
@ -613,30 +796,96 @@ video {
|
||||||
.border-2 {
|
.border-2 {
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
.border-b {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
.border-l {
|
||||||
|
border-left-width: 1px;
|
||||||
|
}
|
||||||
|
.border-r {
|
||||||
|
border-right-width: 1px;
|
||||||
|
}
|
||||||
|
.border-t {
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
.border-border {
|
||||||
|
border-color: hsl(var(--border));
|
||||||
|
}
|
||||||
.border-input {
|
.border-input {
|
||||||
border-color: hsl(var(--input));
|
border-color: hsl(var(--input));
|
||||||
}
|
}
|
||||||
.border-transparent {
|
.border-transparent {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
.border-l-transparent {
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
.border-t-transparent {
|
||||||
|
border-top-color: transparent;
|
||||||
|
}
|
||||||
|
.bg-accent {
|
||||||
|
background-color: hsl(var(--accent));
|
||||||
|
}
|
||||||
.bg-background {
|
.bg-background {
|
||||||
background-color: hsl(var(--background));
|
background-color: hsl(var(--background));
|
||||||
}
|
}
|
||||||
|
.bg-background\/80 {
|
||||||
|
background-color: hsl(var(--background) / 0.8);
|
||||||
|
}
|
||||||
|
.bg-blue-500 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
.bg-border {
|
||||||
|
background-color: hsl(var(--border));
|
||||||
|
}
|
||||||
.bg-card {
|
.bg-card {
|
||||||
background-color: hsl(var(--card));
|
background-color: hsl(var(--card));
|
||||||
}
|
}
|
||||||
.bg-destructive {
|
.bg-destructive {
|
||||||
background-color: hsl(var(--destructive));
|
background-color: hsl(var(--destructive));
|
||||||
}
|
}
|
||||||
|
.bg-gray-500 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(107 114 128 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
.bg-green-500 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
.bg-primary {
|
.bg-primary {
|
||||||
background-color: hsl(var(--primary));
|
background-color: hsl(var(--primary));
|
||||||
}
|
}
|
||||||
|
.bg-red-500 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
.bg-secondary {
|
.bg-secondary {
|
||||||
background-color: hsl(var(--secondary));
|
background-color: hsl(var(--secondary));
|
||||||
}
|
}
|
||||||
|
.bg-secondary\/50 {
|
||||||
|
background-color: hsl(var(--secondary) / 0.5);
|
||||||
|
}
|
||||||
|
.bg-yellow-500 {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(234 179 8 / var(--tw-bg-opacity, 1));
|
||||||
|
}
|
||||||
|
.p-3 {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
.p-4 {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
.p-6 {
|
.p-6 {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
}
|
}
|
||||||
|
.p-\[1px\] {
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
.px-2 {
|
||||||
|
padding-left: 0.5rem;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
}
|
||||||
.px-3 {
|
.px-3 {
|
||||||
padding-left: 0.75rem;
|
padding-left: 0.75rem;
|
||||||
padding-right: 0.75rem;
|
padding-right: 0.75rem;
|
||||||
|
|
@ -657,9 +906,29 @@ video {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.py-8 {
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.pb-2 {
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
.pt-0 {
|
.pt-0 {
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
|
.pt-3 {
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
}
|
||||||
|
.text-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.text-lg {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
line-height: 1.75rem;
|
||||||
|
}
|
||||||
.text-sm {
|
.text-sm {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
|
|
@ -674,6 +943,9 @@ video {
|
||||||
.font-semibold {
|
.font-semibold {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
.capitalize {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
.leading-none {
|
.leading-none {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
@ -686,6 +958,9 @@ video {
|
||||||
.text-destructive-foreground {
|
.text-destructive-foreground {
|
||||||
color: hsl(var(--destructive-foreground));
|
color: hsl(var(--destructive-foreground));
|
||||||
}
|
}
|
||||||
|
.text-foreground {
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
}
|
||||||
.text-muted-foreground {
|
.text-muted-foreground {
|
||||||
color: hsl(var(--muted-foreground));
|
color: hsl(var(--muted-foreground));
|
||||||
}
|
}
|
||||||
|
|
@ -701,6 +976,9 @@ video {
|
||||||
.underline-offset-4 {
|
.underline-offset-4 {
|
||||||
text-underline-offset: 4px;
|
text-underline-offset: 4px;
|
||||||
}
|
}
|
||||||
|
.opacity-70 {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
.shadow {
|
.shadow {
|
||||||
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
||||||
|
|
@ -724,16 +1002,50 @@ video {
|
||||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||||
}
|
}
|
||||||
|
.ring-offset-background {
|
||||||
|
--tw-ring-offset-color: hsl(var(--background));
|
||||||
|
}
|
||||||
|
.filter {
|
||||||
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||||
|
}
|
||||||
|
.backdrop-blur-sm {
|
||||||
|
--tw-backdrop-blur: blur(4px);
|
||||||
|
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||||
|
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||||
|
}
|
||||||
|
.transition {
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
||||||
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 150ms;
|
||||||
|
}
|
||||||
|
.transition-all {
|
||||||
|
transition-property: all;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 150ms;
|
||||||
|
}
|
||||||
.transition-colors {
|
.transition-colors {
|
||||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
||||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
transition-duration: 150ms;
|
transition-duration: 150ms;
|
||||||
}
|
}
|
||||||
|
.transition-opacity {
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
transition-duration: 150ms;
|
||||||
|
}
|
||||||
.transition-transform {
|
.transition-transform {
|
||||||
transition-property: transform;
|
transition-property: transform;
|
||||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
transition-duration: 150ms;
|
transition-duration: 150ms;
|
||||||
}
|
}
|
||||||
|
.duration-200 {
|
||||||
|
transition-duration: 200ms;
|
||||||
|
}
|
||||||
|
.ease-in-out {
|
||||||
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
@keyframes enter {
|
@keyframes enter {
|
||||||
|
|
||||||
from {
|
from {
|
||||||
|
|
@ -748,6 +1060,12 @@ video {
|
||||||
transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));
|
transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.duration-200 {
|
||||||
|
animation-duration: 200ms;
|
||||||
|
}
|
||||||
|
.ease-in-out {
|
||||||
|
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
.file\:border-0::file-selector-button {
|
.file\:border-0::file-selector-button {
|
||||||
border-width: 0px;
|
border-width: 0px;
|
||||||
}
|
}
|
||||||
|
|
@ -770,6 +1088,9 @@ video {
|
||||||
.hover\:bg-accent:hover {
|
.hover\:bg-accent:hover {
|
||||||
background-color: hsl(var(--accent));
|
background-color: hsl(var(--accent));
|
||||||
}
|
}
|
||||||
|
.hover\:bg-accent\/50:hover {
|
||||||
|
background-color: hsl(var(--accent) / 0.5);
|
||||||
|
}
|
||||||
.hover\:bg-destructive\/90:hover {
|
.hover\:bg-destructive\/90:hover {
|
||||||
background-color: hsl(var(--destructive) / 0.9);
|
background-color: hsl(var(--destructive) / 0.9);
|
||||||
}
|
}
|
||||||
|
|
@ -785,6 +1106,24 @@ video {
|
||||||
.hover\:underline:hover {
|
.hover\:underline:hover {
|
||||||
text-decoration-line: underline;
|
text-decoration-line: underline;
|
||||||
}
|
}
|
||||||
|
.hover\:opacity-100:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.focus\:outline-none:focus {
|
||||||
|
outline: 2px solid transparent;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
.focus\:ring-2:focus {
|
||||||
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||||
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||||
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||||
|
}
|
||||||
|
.focus\:ring-ring:focus {
|
||||||
|
--tw-ring-color: hsl(var(--ring));
|
||||||
|
}
|
||||||
|
.focus\:ring-offset-2:focus {
|
||||||
|
--tw-ring-offset-width: 2px;
|
||||||
|
}
|
||||||
.focus-visible\:outline-none:focus-visible {
|
.focus-visible\:outline-none:focus-visible {
|
||||||
outline: 2px solid transparent;
|
outline: 2px solid transparent;
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
|
|
@ -825,9 +1164,142 @@ video {
|
||||||
--tw-translate-x: 0px;
|
--tw-translate-x: 0px;
|
||||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||||
}
|
}
|
||||||
|
@keyframes accordion-up {
|
||||||
|
|
||||||
|
from {
|
||||||
|
height: var(--radix-accordion-content-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:animate-accordion-up[data-state="closed"] {
|
||||||
|
animation: accordion-up 0.2s ease-out;
|
||||||
|
}
|
||||||
|
@keyframes accordion-down {
|
||||||
|
|
||||||
|
from {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
height: var(--radix-accordion-content-height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:animate-accordion-down[data-state="open"] {
|
||||||
|
animation: accordion-down 0.2s ease-out;
|
||||||
|
}
|
||||||
.data-\[state\=checked\]\:bg-primary[data-state="checked"] {
|
.data-\[state\=checked\]\:bg-primary[data-state="checked"] {
|
||||||
background-color: hsl(var(--primary));
|
background-color: hsl(var(--primary));
|
||||||
}
|
}
|
||||||
|
.data-\[state\=open\]\:bg-secondary[data-state="open"] {
|
||||||
|
background-color: hsl(var(--secondary));
|
||||||
|
}
|
||||||
.data-\[state\=unchecked\]\:bg-input[data-state="unchecked"] {
|
.data-\[state\=unchecked\]\:bg-input[data-state="unchecked"] {
|
||||||
background-color: hsl(var(--input));
|
background-color: hsl(var(--input));
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:duration-300[data-state="closed"] {
|
||||||
|
transition-duration: 300ms;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:duration-500[data-state="open"] {
|
||||||
|
transition-duration: 500ms;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:animate-in[data-state="open"] {
|
||||||
|
animation-name: enter;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
--tw-enter-opacity: initial;
|
||||||
|
--tw-enter-scale: initial;
|
||||||
|
--tw-enter-rotate: initial;
|
||||||
|
--tw-enter-translate-x: initial;
|
||||||
|
--tw-enter-translate-y: initial;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:animate-out[data-state="closed"] {
|
||||||
|
animation-name: exit;
|
||||||
|
animation-duration: 150ms;
|
||||||
|
--tw-exit-opacity: initial;
|
||||||
|
--tw-exit-scale: initial;
|
||||||
|
--tw-exit-rotate: initial;
|
||||||
|
--tw-exit-translate-x: initial;
|
||||||
|
--tw-exit-translate-y: initial;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:fade-out-0[data-state="closed"] {
|
||||||
|
--tw-exit-opacity: 0;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:fade-in-0[data-state="open"] {
|
||||||
|
--tw-enter-opacity: 0;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:slide-out-to-bottom[data-state="closed"] {
|
||||||
|
--tw-exit-translate-y: 100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:slide-out-to-left[data-state="closed"] {
|
||||||
|
--tw-exit-translate-x: -100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:slide-out-to-right[data-state="closed"] {
|
||||||
|
--tw-exit-translate-x: 100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:slide-out-to-top[data-state="closed"] {
|
||||||
|
--tw-exit-translate-y: -100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:slide-in-from-bottom[data-state="open"] {
|
||||||
|
--tw-enter-translate-y: 100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:slide-in-from-left[data-state="open"] {
|
||||||
|
--tw-enter-translate-x: -100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:slide-in-from-right[data-state="open"] {
|
||||||
|
--tw-enter-translate-x: 100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:slide-in-from-top[data-state="open"] {
|
||||||
|
--tw-enter-translate-y: -100%;
|
||||||
|
}
|
||||||
|
.data-\[state\=closed\]\:duration-300[data-state="closed"] {
|
||||||
|
animation-duration: 300ms;
|
||||||
|
}
|
||||||
|
.data-\[state\=open\]\:duration-500[data-state="open"] {
|
||||||
|
animation-duration: 500ms;
|
||||||
|
}
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
|
||||||
|
.sm\:max-w-md {
|
||||||
|
max-width: 28rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:max-w-sm {
|
||||||
|
max-width: 24rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:flex-row {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:justify-end {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-x-reverse: 0;
|
||||||
|
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||||
|
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm\:text-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
|
||||||
|
.md\:block {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md\:hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
|
||||||
|
.lg\:w-\[300px\] {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,3 +4,4 @@ import { type ClassValue } from "clsx";
|
||||||
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
|
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
|
||||||
*/
|
*/
|
||||||
export declare function cn(...inputs: ClassValue[]): string;
|
export declare function cn(...inputs: ClassValue[]): string;
|
||||||
|
export * from './utils';
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,5 @@ import { twMerge } from "tailwind-merge";
|
||||||
export function cn(...inputs) {
|
export function cn(...inputs) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
}
|
}
|
||||||
|
// Re-export everything from utils directory
|
||||||
|
export * from './utils';
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,11 @@
|
||||||
"dev": "concurrently \"tsc --watch\" \"postcss src/styles/global.css -o dist/styles/global.css --watch\""
|
"dev": "concurrently \"tsc --watch\" \"postcss src/styles/global.css -o dist/styles/global.css --watch\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@radix-ui/react-collapsible": "^1.1.3",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-popover": "^1.0.7",
|
"@radix-ui/react-popover": "^1.0.7",
|
||||||
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||||
"@radix-ui/react-select": "^2.0.0",
|
"@radix-ui/react-select": "^2.0.0",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
"@radix-ui/react-switch": "^1.1.3",
|
"@radix-ui/react-switch": "^1.1.3",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.SessionDrawer = void 0;
|
||||||
|
var react_1 = require("react");
|
||||||
|
var lucide_react_1 = require("lucide-react");
|
||||||
|
var sheet_1 = require("./ui/sheet");
|
||||||
|
var button_1 = require("./ui/button");
|
||||||
|
var scroll_area_1 = require("./ui/scroll-area");
|
||||||
|
var sample_data_1 = require("../utils/sample-data");
|
||||||
|
var SessionDrawer = function (_a) {
|
||||||
|
var onSelectSession = _a.onSelectSession, currentSessionId = _a.currentSessionId, _b = _a.sessions, sessions = _b === void 0 ? (0, sample_data_1.getSampleAgentSessions)() : _b;
|
||||||
|
// Get status color
|
||||||
|
var getStatusColor = function (status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'active':
|
||||||
|
return 'bg-blue-500';
|
||||||
|
case 'completed':
|
||||||
|
return 'bg-green-500';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-500';
|
||||||
|
default:
|
||||||
|
return 'bg-gray-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Format timestamp
|
||||||
|
var formatDate = function (date) {
|
||||||
|
return date.toLocaleDateString([], {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (<sheet_1.Sheet>
|
||||||
|
<sheet_1.SheetTrigger asChild>
|
||||||
|
<button_1.Button variant="ghost" size="icon" className="md:hidden">
|
||||||
|
<lucide_react_1.Menu className="h-5 w-5"/>
|
||||||
|
<span className="sr-only">Toggle navigation</span>
|
||||||
|
</button_1.Button>
|
||||||
|
</sheet_1.SheetTrigger>
|
||||||
|
<sheet_1.SheetContent side="left" className="w-[85%] sm:max-w-md">
|
||||||
|
<sheet_1.SheetHeader>
|
||||||
|
<sheet_1.SheetTitle>Sessions</sheet_1.SheetTitle>
|
||||||
|
</sheet_1.SheetHeader>
|
||||||
|
<scroll_area_1.ScrollArea className="h-[calc(100vh-5rem)] mt-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
{sessions.map(function (session) { return (<sheet_1.SheetClose key={session.id} asChild>
|
||||||
|
<button onClick={function () { return onSelectSession === null || onSelectSession === void 0 ? void 0 : onSelectSession(session.id); }} className={"w-full flex items-start p-3 text-left rounded-md transition-colors hover:bg-accent/50 ".concat(currentSessionId === session.id ? 'bg-accent' : '')}>
|
||||||
|
<div className={"w-3 h-3 rounded-full ".concat(getStatusColor(session.status), " mt-1.5 mr-3 flex-shrink-0")}/>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="font-medium truncate">{session.name}</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
{session.steps.length} steps • {formatDate(session.updated)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
<span className="capitalize">{session.status}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</sheet_1.SheetClose>); })}
|
||||||
|
</div>
|
||||||
|
</scroll_area_1.ScrollArea>
|
||||||
|
</sheet_1.SheetContent>
|
||||||
|
</sheet_1.Sheet>);
|
||||||
|
};
|
||||||
|
exports.SessionDrawer = SessionDrawer;
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Menu } from 'lucide-react';
|
||||||
|
import {
|
||||||
|
Sheet,
|
||||||
|
SheetTrigger,
|
||||||
|
SheetContent,
|
||||||
|
SheetHeader,
|
||||||
|
SheetTitle,
|
||||||
|
SheetClose
|
||||||
|
} from './ui/sheet';
|
||||||
|
import { Button } from './ui/button';
|
||||||
|
import { ScrollArea } from './ui/scroll-area';
|
||||||
|
import { AgentSession, getSampleAgentSessions } from '../utils/sample-data';
|
||||||
|
|
||||||
|
interface SessionDrawerProps {
|
||||||
|
onSelectSession?: (sessionId: string) => void;
|
||||||
|
currentSessionId?: string;
|
||||||
|
sessions?: AgentSession[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SessionDrawer: React.FC<SessionDrawerProps> = ({
|
||||||
|
onSelectSession,
|
||||||
|
currentSessionId,
|
||||||
|
sessions = getSampleAgentSessions()
|
||||||
|
}) => {
|
||||||
|
// Get status color
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'active':
|
||||||
|
return 'bg-blue-500';
|
||||||
|
case 'completed':
|
||||||
|
return 'bg-green-500';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-500';
|
||||||
|
default:
|
||||||
|
return 'bg-gray-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format timestamp
|
||||||
|
const formatDate = (date: Date) => {
|
||||||
|
return date.toLocaleDateString([], {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Sheet>
|
||||||
|
<SheetTrigger asChild>
|
||||||
|
<Button variant="ghost" size="icon" className="md:hidden">
|
||||||
|
<Menu className="h-5 w-5" />
|
||||||
|
<span className="sr-only">Toggle navigation</span>
|
||||||
|
</Button>
|
||||||
|
</SheetTrigger>
|
||||||
|
<SheetContent side="left" className="w-[85%] sm:max-w-md">
|
||||||
|
<SheetHeader>
|
||||||
|
<SheetTitle>Sessions</SheetTitle>
|
||||||
|
</SheetHeader>
|
||||||
|
<ScrollArea className="h-[calc(100vh-5rem)] mt-6">
|
||||||
|
<div className="space-y-4">
|
||||||
|
{sessions.map((session) => (
|
||||||
|
<SheetClose key={session.id} asChild>
|
||||||
|
<button
|
||||||
|
onClick={() => onSelectSession?.(session.id)}
|
||||||
|
className={`w-full flex items-start p-3 text-left rounded-md transition-colors hover:bg-accent/50 ${
|
||||||
|
currentSessionId === session.id ? 'bg-accent' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className={`w-3 h-3 rounded-full ${getStatusColor(session.status)} mt-1.5 mr-3 flex-shrink-0`} />
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="font-medium truncate">{session.name}</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
{session.steps.length} steps • {formatDate(session.updated)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
<span className="capitalize">{session.status}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</SheetClose>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</SheetContent>
|
||||||
|
</Sheet>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.SessionSidebar = void 0;
|
||||||
|
var react_1 = require("react");
|
||||||
|
var scroll_area_1 = require("./ui/scroll-area");
|
||||||
|
var sample_data_1 = require("../utils/sample-data");
|
||||||
|
var SessionSidebar = function (_a) {
|
||||||
|
var onSelectSession = _a.onSelectSession, currentSessionId = _a.currentSessionId, _b = _a.sessions, sessions = _b === void 0 ? (0, sample_data_1.getSampleAgentSessions)() : _b, _c = _a.className, className = _c === void 0 ? '' : _c;
|
||||||
|
// Get status color
|
||||||
|
var getStatusColor = function (status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'active':
|
||||||
|
return 'bg-blue-500';
|
||||||
|
case 'completed':
|
||||||
|
return 'bg-green-500';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-500';
|
||||||
|
default:
|
||||||
|
return 'bg-gray-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Format timestamp
|
||||||
|
var formatDate = function (date) {
|
||||||
|
return date.toLocaleDateString([], {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (<div className={"hidden md:block w-[250px] lg:w-[300px] h-screen border-r border-border ".concat(className)}>
|
||||||
|
<div className="p-4 border-b border-border">
|
||||||
|
<h3 className="font-medium text-lg">Sessions</h3>
|
||||||
|
</div>
|
||||||
|
<scroll_area_1.ScrollArea className="h-[calc(100vh-5rem)]">
|
||||||
|
<div className="p-4 space-y-4">
|
||||||
|
{sessions.map(function (session) { return (<button key={session.id} onClick={function () { return onSelectSession === null || onSelectSession === void 0 ? void 0 : onSelectSession(session.id); }} className={"w-full flex items-start p-3 text-left rounded-md transition-colors hover:bg-accent/50 ".concat(currentSessionId === session.id ? 'bg-accent' : '')}>
|
||||||
|
<div className={"w-3 h-3 rounded-full ".concat(getStatusColor(session.status), " mt-1.5 mr-3 flex-shrink-0")}/>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="font-medium truncate">{session.name}</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
{session.steps.length} steps • {formatDate(session.updated)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
<span className="capitalize">{session.status}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>); })}
|
||||||
|
</div>
|
||||||
|
</scroll_area_1.ScrollArea>
|
||||||
|
</div>);
|
||||||
|
};
|
||||||
|
exports.SessionSidebar = SessionSidebar;
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { ScrollArea } from './ui/scroll-area';
|
||||||
|
import { AgentSession, getSampleAgentSessions } from '../utils/sample-data';
|
||||||
|
|
||||||
|
interface SessionSidebarProps {
|
||||||
|
onSelectSession?: (sessionId: string) => void;
|
||||||
|
currentSessionId?: string;
|
||||||
|
sessions?: AgentSession[];
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||||
|
onSelectSession,
|
||||||
|
currentSessionId,
|
||||||
|
sessions = getSampleAgentSessions(),
|
||||||
|
className = ''
|
||||||
|
}) => {
|
||||||
|
// Get status color
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'active':
|
||||||
|
return 'bg-blue-500';
|
||||||
|
case 'completed':
|
||||||
|
return 'bg-green-500';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-500';
|
||||||
|
default:
|
||||||
|
return 'bg-gray-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format timestamp
|
||||||
|
const formatDate = (date: Date) => {
|
||||||
|
return date.toLocaleDateString([], {
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`hidden md:block w-[250px] lg:w-[300px] h-screen border-r border-border ${className}`}>
|
||||||
|
<div className="p-4 border-b border-border">
|
||||||
|
<h3 className="font-medium text-lg">Sessions</h3>
|
||||||
|
</div>
|
||||||
|
<ScrollArea className="h-[calc(100vh-5rem)]">
|
||||||
|
<div className="p-4 space-y-4">
|
||||||
|
{sessions.map((session) => (
|
||||||
|
<button
|
||||||
|
key={session.id}
|
||||||
|
onClick={() => onSelectSession?.(session.id)}
|
||||||
|
className={`w-full flex items-start p-3 text-left rounded-md transition-colors hover:bg-accent/50 ${
|
||||||
|
currentSessionId === session.id ? 'bg-accent' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className={`w-3 h-3 rounded-full ${getStatusColor(session.status)} mt-1.5 mr-3 flex-shrink-0`} />
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<div className="font-medium truncate">{session.name}</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
{session.steps.length} steps • {formatDate(session.updated)}
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground mt-1">
|
||||||
|
<span className="capitalize">{session.status}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
"use strict";
|
||||||
|
var __assign = (this && this.__assign) || function () {
|
||||||
|
__assign = Object.assign || function(t) {
|
||||||
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||||
|
s = arguments[i];
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||||
|
t[p] = s[p];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
return __assign.apply(this, arguments);
|
||||||
|
};
|
||||||
|
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
||||||
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||||
|
if (ar || !(i in from)) {
|
||||||
|
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||||
|
ar[i] = from[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return to.concat(ar || Array.prototype.slice.call(from));
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.TimelineFeed = void 0;
|
||||||
|
var react_1 = require("react");
|
||||||
|
var scroll_area_1 = require("./ui/scroll-area");
|
||||||
|
var TimelineStep_1 = require("./TimelineStep");
|
||||||
|
var TimelineFeed = function (_a) {
|
||||||
|
var steps = _a.steps, _b = _a.maxHeight, maxHeight = _b === void 0 ? '500px' : _b, filter = _a.filter, _c = _a.sortOrder, sortOrder = _c === void 0 ? 'desc' : _c;
|
||||||
|
// State for filtered and sorted steps
|
||||||
|
var _d = (0, react_1.useState)(filter), activeFilter = _d[0], setActiveFilter = _d[1];
|
||||||
|
var _e = (0, react_1.useState)(sortOrder), activeSortOrder = _e[0], setActiveSortOrder = _e[1];
|
||||||
|
// Apply filters and sorting
|
||||||
|
var filteredSteps = steps.filter(function (step) {
|
||||||
|
if (!activeFilter)
|
||||||
|
return true;
|
||||||
|
var typeMatch = !activeFilter.types || activeFilter.types.length === 0 ||
|
||||||
|
activeFilter.types.includes(step.type);
|
||||||
|
var statusMatch = !activeFilter.status || activeFilter.status.length === 0 ||
|
||||||
|
activeFilter.status.includes(step.status);
|
||||||
|
return typeMatch && statusMatch;
|
||||||
|
});
|
||||||
|
// Sort steps
|
||||||
|
var sortedSteps = __spreadArray([], filteredSteps, true).sort(function (a, b) {
|
||||||
|
if (activeSortOrder === 'asc') {
|
||||||
|
return a.timestamp.getTime() - b.timestamp.getTime();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return b.timestamp.getTime() - a.timestamp.getTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Toggle sort order
|
||||||
|
var toggleSortOrder = function () {
|
||||||
|
setActiveSortOrder(function (prevOrder) { return prevOrder === 'asc' ? 'desc' : 'asc'; });
|
||||||
|
};
|
||||||
|
// Filter by type
|
||||||
|
var filterTypes = [
|
||||||
|
'all',
|
||||||
|
'tool-execution',
|
||||||
|
'thinking',
|
||||||
|
'planning',
|
||||||
|
'implementation',
|
||||||
|
'user-input'
|
||||||
|
];
|
||||||
|
var handleFilterChange = function (type) {
|
||||||
|
if (type === 'all') {
|
||||||
|
setActiveFilter(__assign(__assign({}, activeFilter), { types: [] }));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setActiveFilter(__assign(__assign({}, activeFilter), { types: [type] }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (<div className="w-full border border-border rounded-md bg-background">
|
||||||
|
<div className="p-3 border-b border-border">
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<h3 className="font-medium">Timeline Feed</h3>
|
||||||
|
<button onClick={toggleSortOrder} className="text-xs bg-secondary hover:bg-secondary/80 text-secondary-foreground px-2 py-1 rounded">
|
||||||
|
{activeSortOrder === 'asc' ? '⬆️ Oldest first' : '⬇️ Newest first'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex gap-2 overflow-x-auto pb-2 text-xs">
|
||||||
|
{filterTypes.map(function (type) {
|
||||||
|
var _a;
|
||||||
|
return (<button key={type} onClick={function () { return handleFilterChange(type); }} className={"px-2 py-1 rounded whitespace-nowrap ".concat(type === 'all' && (!(activeFilter === null || activeFilter === void 0 ? void 0 : activeFilter.types) || activeFilter.types.length === 0) ||
|
||||||
|
((_a = activeFilter === null || activeFilter === void 0 ? void 0 : activeFilter.types) === null || _a === void 0 ? void 0 : _a.includes(type))
|
||||||
|
? 'bg-primary text-primary-foreground'
|
||||||
|
: 'bg-secondary/50 text-secondary-foreground hover:bg-secondary/80')}>
|
||||||
|
{type === 'all' ? 'All types' : type}
|
||||||
|
</button>);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<scroll_area_1.ScrollArea className="h-full" style={{ maxHeight: maxHeight }}>
|
||||||
|
<div className="p-3">
|
||||||
|
{sortedSteps.length > 0 ? (sortedSteps.map(function (step) { return (<TimelineStep_1.TimelineStep key={step.id} step={step}/>); })) : (<div className="text-center text-muted-foreground py-8">
|
||||||
|
No steps to display
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</scroll_area_1.ScrollArea>
|
||||||
|
</div>);
|
||||||
|
};
|
||||||
|
exports.TimelineFeed = TimelineFeed;
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { ScrollArea } from './ui/scroll-area';
|
||||||
|
import { TimelineStep } from './TimelineStep';
|
||||||
|
import { AgentStep } from '../utils/sample-data';
|
||||||
|
|
||||||
|
interface TimelineFeedProps {
|
||||||
|
steps: AgentStep[];
|
||||||
|
maxHeight?: string;
|
||||||
|
filter?: {
|
||||||
|
types?: string[];
|
||||||
|
status?: string[];
|
||||||
|
};
|
||||||
|
sortOrder?: 'asc' | 'desc';
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TimelineFeed: React.FC<TimelineFeedProps> = ({
|
||||||
|
steps,
|
||||||
|
maxHeight = '500px',
|
||||||
|
filter,
|
||||||
|
sortOrder = 'desc'
|
||||||
|
}) => {
|
||||||
|
// State for filtered and sorted steps
|
||||||
|
const [activeFilter, setActiveFilter] = useState(filter);
|
||||||
|
const [activeSortOrder, setActiveSortOrder] = useState<'asc' | 'desc'>(sortOrder);
|
||||||
|
|
||||||
|
// Apply filters and sorting
|
||||||
|
const filteredSteps = steps.filter(step => {
|
||||||
|
if (!activeFilter) return true;
|
||||||
|
|
||||||
|
const typeMatch = !activeFilter.types || activeFilter.types.length === 0 ||
|
||||||
|
activeFilter.types.includes(step.type);
|
||||||
|
|
||||||
|
const statusMatch = !activeFilter.status || activeFilter.status.length === 0 ||
|
||||||
|
activeFilter.status.includes(step.status);
|
||||||
|
|
||||||
|
return typeMatch && statusMatch;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort steps
|
||||||
|
const sortedSteps = [...filteredSteps].sort((a, b) => {
|
||||||
|
if (activeSortOrder === 'asc') {
|
||||||
|
return a.timestamp.getTime() - b.timestamp.getTime();
|
||||||
|
} else {
|
||||||
|
return b.timestamp.getTime() - a.timestamp.getTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toggle sort order
|
||||||
|
const toggleSortOrder = () => {
|
||||||
|
setActiveSortOrder(prevOrder => prevOrder === 'asc' ? 'desc' : 'asc');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filter by type
|
||||||
|
const filterTypes = [
|
||||||
|
'all',
|
||||||
|
'tool-execution',
|
||||||
|
'thinking',
|
||||||
|
'planning',
|
||||||
|
'implementation',
|
||||||
|
'user-input'
|
||||||
|
];
|
||||||
|
|
||||||
|
const handleFilterChange = (type: string) => {
|
||||||
|
if (type === 'all') {
|
||||||
|
setActiveFilter({
|
||||||
|
...activeFilter,
|
||||||
|
types: []
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setActiveFilter({
|
||||||
|
...activeFilter,
|
||||||
|
types: [type]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full border border-border rounded-md bg-background">
|
||||||
|
<div className="p-3 border-b border-border">
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<h3 className="font-medium">Timeline Feed</h3>
|
||||||
|
<button
|
||||||
|
onClick={toggleSortOrder}
|
||||||
|
className="text-xs bg-secondary hover:bg-secondary/80 text-secondary-foreground px-2 py-1 rounded"
|
||||||
|
>
|
||||||
|
{activeSortOrder === 'asc' ? '⬆️ Oldest first' : '⬇️ Newest first'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex gap-2 overflow-x-auto pb-2 text-xs">
|
||||||
|
{filterTypes.map(type => (
|
||||||
|
<button
|
||||||
|
key={type}
|
||||||
|
onClick={() => handleFilterChange(type)}
|
||||||
|
className={`px-2 py-1 rounded whitespace-nowrap ${
|
||||||
|
type === 'all' && (!activeFilter?.types || activeFilter.types.length === 0) ||
|
||||||
|
activeFilter?.types?.includes(type)
|
||||||
|
? 'bg-primary text-primary-foreground'
|
||||||
|
: 'bg-secondary/50 text-secondary-foreground hover:bg-secondary/80'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{type === 'all' ? 'All types' : type}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ScrollArea className="h-full" style={{ maxHeight }}>
|
||||||
|
<div className="p-3">
|
||||||
|
{sortedSteps.length > 0 ? (
|
||||||
|
sortedSteps.map((step) => (
|
||||||
|
<TimelineStep key={step.id} step={step} />
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="text-center text-muted-foreground py-8">
|
||||||
|
No steps to display
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</ScrollArea>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.TimelineStep = void 0;
|
||||||
|
var react_1 = require("react");
|
||||||
|
var collapsible_1 = require("./ui/collapsible");
|
||||||
|
var TimelineStep = function (_a) {
|
||||||
|
var step = _a.step;
|
||||||
|
// Get status color
|
||||||
|
var getStatusColor = function (status) {
|
||||||
|
switch (status) {
|
||||||
|
case 'completed':
|
||||||
|
return 'bg-green-500';
|
||||||
|
case 'in-progress':
|
||||||
|
return 'bg-blue-500';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-500';
|
||||||
|
case 'pending':
|
||||||
|
return 'bg-yellow-500';
|
||||||
|
default:
|
||||||
|
return 'bg-gray-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Get icon based on step type
|
||||||
|
var getTypeIcon = function (type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'tool-execution':
|
||||||
|
return '🛠️';
|
||||||
|
case 'thinking':
|
||||||
|
return '💭';
|
||||||
|
case 'planning':
|
||||||
|
return '📝';
|
||||||
|
case 'implementation':
|
||||||
|
return '💻';
|
||||||
|
case 'user-input':
|
||||||
|
return '👤';
|
||||||
|
default:
|
||||||
|
return '▶️';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Format timestamp
|
||||||
|
var formatTime = function (timestamp) {
|
||||||
|
return timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||||
|
};
|
||||||
|
return (<collapsible_1.Collapsible className="w-full mb-4 border border-border rounded-md overflow-hidden transition-all duration-200">
|
||||||
|
<collapsible_1.CollapsibleTrigger className="w-full flex items-center justify-between p-3 text-left hover:bg-accent/50 cursor-pointer">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className={"w-3 h-3 rounded-full ".concat(getStatusColor(step.status), " mr-3")}/>
|
||||||
|
<div className="mr-2">{getTypeIcon(step.type)}</div>
|
||||||
|
<div>
|
||||||
|
<div className="font-medium">{step.title}</div>
|
||||||
|
<div className="text-sm text-muted-foreground truncate max-w-xs">
|
||||||
|
{step.type === 'tool-execution' ? 'Run tool' : step.content.substring(0, 60)}
|
||||||
|
{step.content.length > 60 ? '...' : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground flex flex-col items-end">
|
||||||
|
<span>{formatTime(step.timestamp)}</span>
|
||||||
|
{step.duration && (<span className="mt-1">{(step.duration / 1000).toFixed(1)}s</span>)}
|
||||||
|
</div>
|
||||||
|
</collapsible_1.CollapsibleTrigger>
|
||||||
|
<collapsible_1.CollapsibleContent>
|
||||||
|
<div className="p-4 bg-card border-t border-border">
|
||||||
|
<div className="text-sm whitespace-pre-wrap">
|
||||||
|
{step.content}
|
||||||
|
</div>
|
||||||
|
{step.duration && (<div className="mt-3 pt-3 border-t border-border">
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
Duration: {(step.duration / 1000).toFixed(1)} seconds
|
||||||
|
</div>
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</collapsible_1.CollapsibleContent>
|
||||||
|
</collapsible_1.Collapsible>);
|
||||||
|
};
|
||||||
|
exports.TimelineStep = TimelineStep;
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible';
|
||||||
|
import { AgentStep } from '../utils/sample-data';
|
||||||
|
|
||||||
|
interface TimelineStepProps {
|
||||||
|
step: AgentStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TimelineStep: React.FC<TimelineStepProps> = ({ step }) => {
|
||||||
|
// Get status color
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'completed':
|
||||||
|
return 'bg-green-500';
|
||||||
|
case 'in-progress':
|
||||||
|
return 'bg-blue-500';
|
||||||
|
case 'error':
|
||||||
|
return 'bg-red-500';
|
||||||
|
case 'pending':
|
||||||
|
return 'bg-yellow-500';
|
||||||
|
default:
|
||||||
|
return 'bg-gray-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get icon based on step type
|
||||||
|
const getTypeIcon = (type: string) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'tool-execution':
|
||||||
|
return '🛠️';
|
||||||
|
case 'thinking':
|
||||||
|
return '💭';
|
||||||
|
case 'planning':
|
||||||
|
return '📝';
|
||||||
|
case 'implementation':
|
||||||
|
return '💻';
|
||||||
|
case 'user-input':
|
||||||
|
return '👤';
|
||||||
|
default:
|
||||||
|
return '▶️';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Format timestamp
|
||||||
|
const formatTime = (timestamp: Date) => {
|
||||||
|
return timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Collapsible className="w-full mb-4 border border-border rounded-md overflow-hidden transition-all duration-200">
|
||||||
|
<CollapsibleTrigger className="w-full flex items-center justify-between p-3 text-left hover:bg-accent/50 cursor-pointer">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className={`w-3 h-3 rounded-full ${getStatusColor(step.status)} mr-3`} />
|
||||||
|
<div className="mr-2">{getTypeIcon(step.type)}</div>
|
||||||
|
<div>
|
||||||
|
<div className="font-medium">{step.title}</div>
|
||||||
|
<div className="text-sm text-muted-foreground truncate max-w-xs">
|
||||||
|
{step.type === 'tool-execution' ? 'Run tool' : step.content.substring(0, 60)}
|
||||||
|
{step.content.length > 60 ? '...' : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="text-xs text-muted-foreground flex flex-col items-end">
|
||||||
|
<span>{formatTime(step.timestamp)}</span>
|
||||||
|
{step.duration && (
|
||||||
|
<span className="mt-1">{(step.duration / 1000).toFixed(1)}s</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
<CollapsibleContent>
|
||||||
|
<div className="p-4 bg-card border-t border-border">
|
||||||
|
<div className="text-sm whitespace-pre-wrap">
|
||||||
|
{step.content}
|
||||||
|
</div>
|
||||||
|
{step.duration && (
|
||||||
|
<div className="mt-3 pt-3 border-t border-border">
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
Duration: {(step.duration / 1000).toFixed(1)} seconds
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CollapsibleContent>
|
||||||
|
</Collapsible>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.buttonVariants = exports.Button = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var react_slot_1 = require("@radix-ui/react-slot");
|
||||||
|
var class_variance_authority_1 = require("class-variance-authority");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var buttonVariants = (0, class_variance_authority_1.cva)("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", {
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||||
|
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||||
|
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||||
|
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||||
|
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||||
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: "h-9 px-4 py-2",
|
||||||
|
sm: "h-8 rounded-md px-3 text-xs",
|
||||||
|
lg: "h-10 rounded-md px-8",
|
||||||
|
icon: "h-9 w-9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
size: "default",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
exports.buttonVariants = buttonVariants;
|
||||||
|
var Button = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, variant = _a.variant, size = _a.size, _b = _a.asChild, asChild = _b === void 0 ? false : _b, props = __rest(_a, ["className", "variant", "size", "asChild"]);
|
||||||
|
var Comp = asChild ? react_slot_1.Slot : "button";
|
||||||
|
return (<Comp className={(0, utils_1.cn)(buttonVariants({ variant: variant, size: size, className: className }))} ref={ref} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.Button = Button;
|
||||||
|
Button.displayName = "Button";
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.CardContent = exports.CardDescription = exports.CardTitle = exports.CardFooter = exports.CardHeader = exports.Card = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var Card = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<div ref={ref} className={(0, utils_1.cn)("rounded-xl border bg-card text-card-foreground shadow", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.Card = Card;
|
||||||
|
Card.displayName = "Card";
|
||||||
|
var CardHeader = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<div ref={ref} className={(0, utils_1.cn)("flex flex-col space-y-1.5 p-6", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.CardHeader = CardHeader;
|
||||||
|
CardHeader.displayName = "CardHeader";
|
||||||
|
var CardTitle = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<h3 ref={ref} className={(0, utils_1.cn)("font-semibold leading-none tracking-tight", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.CardTitle = CardTitle;
|
||||||
|
CardTitle.displayName = "CardTitle";
|
||||||
|
var CardDescription = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<p ref={ref} className={(0, utils_1.cn)("text-sm text-muted-foreground", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.CardDescription = CardDescription;
|
||||||
|
CardDescription.displayName = "CardDescription";
|
||||||
|
var CardContent = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<div ref={ref} className={(0, utils_1.cn)("p-6 pt-0", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.CardContent = CardContent;
|
||||||
|
CardContent.displayName = "CardContent";
|
||||||
|
var CardFooter = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<div ref={ref} className={(0, utils_1.cn)("flex items-center p-6 pt-0", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.CardFooter = CardFooter;
|
||||||
|
CardFooter.displayName = "CardFooter";
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.CollapsibleContent = exports.CollapsibleTrigger = exports.Collapsible = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var CollapsiblePrimitive = require("@radix-ui/react-collapsible");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var Collapsible = CollapsiblePrimitive.Root;
|
||||||
|
exports.Collapsible = Collapsible;
|
||||||
|
var CollapsibleTrigger = CollapsiblePrimitive.Trigger;
|
||||||
|
exports.CollapsibleTrigger = CollapsibleTrigger;
|
||||||
|
var CollapsibleContent = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, children = _a.children, props = __rest(_a, ["className", "children"]);
|
||||||
|
return (<CollapsiblePrimitive.Content ref={ref} className={(0, utils_1.cn)("overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down", className)} {...props}>
|
||||||
|
{children}
|
||||||
|
</CollapsiblePrimitive.Content>);
|
||||||
|
});
|
||||||
|
exports.CollapsibleContent = CollapsibleContent;
|
||||||
|
CollapsibleContent.displayName = "CollapsibleContent";
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
|
||||||
|
|
||||||
|
import { cn } from "../../utils"
|
||||||
|
|
||||||
|
const Collapsible = CollapsiblePrimitive.Root
|
||||||
|
|
||||||
|
const CollapsibleTrigger = CollapsiblePrimitive.Trigger
|
||||||
|
|
||||||
|
const CollapsibleContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof CollapsiblePrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Content>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<CollapsiblePrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
"overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</CollapsiblePrimitive.Content>
|
||||||
|
))
|
||||||
|
CollapsibleContent.displayName = "CollapsibleContent"
|
||||||
|
|
||||||
|
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
__exportStar(require("./button"), exports);
|
||||||
|
__exportStar(require("./card"), exports);
|
||||||
|
__exportStar(require("./collapsible"), exports);
|
||||||
|
__exportStar(require("./input"), exports);
|
||||||
|
__exportStar(require("./sheet"), exports);
|
||||||
|
__exportStar(require("./switch"), exports);
|
||||||
|
__exportStar(require("./scroll-area"), exports);
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
export * from './button';
|
export * from './button';
|
||||||
export * from './card';
|
export * from './card';
|
||||||
|
export * from './collapsible';
|
||||||
export * from './input';
|
export * from './input';
|
||||||
export * from './switch';
|
export * from './sheet';
|
||||||
|
export * from './switch';
|
||||||
|
export * from './scroll-area';
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.Input = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var Input = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, type = _a.type, props = __rest(_a, ["className", "type"]);
|
||||||
|
return (<input type={type} className={(0, utils_1.cn)("flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", className)} ref={ref} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.Input = Input;
|
||||||
|
Input.displayName = "Input";
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ScrollBar = exports.ScrollArea = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var ScrollAreaPrimitive = require("@radix-ui/react-scroll-area");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var ScrollArea = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, children = _a.children, props = __rest(_a, ["className", "children"]);
|
||||||
|
return (<ScrollAreaPrimitive.Root ref={ref} className={(0, utils_1.cn)("relative overflow-hidden", className)} {...props}>
|
||||||
|
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
||||||
|
{children}
|
||||||
|
</ScrollAreaPrimitive.Viewport>
|
||||||
|
<ScrollBar />
|
||||||
|
<ScrollBar orientation="horizontal"/>
|
||||||
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
</ScrollAreaPrimitive.Root>);
|
||||||
|
});
|
||||||
|
exports.ScrollArea = ScrollArea;
|
||||||
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
||||||
|
var ScrollBar = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, _b = _a.orientation, orientation = _b === void 0 ? "vertical" : _b, props = __rest(_a, ["className", "orientation"]);
|
||||||
|
return (<ScrollAreaPrimitive.ScrollAreaScrollbar ref={ref} orientation={orientation} className={(0, utils_1.cn)("flex touch-none select-none transition-colors", orientation === "vertical" &&
|
||||||
|
"h-full w-2.5 border-l border-l-transparent p-[1px]", orientation === "horizontal" &&
|
||||||
|
"h-2.5 border-t border-t-transparent p-[1px]", className)} {...props}>
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border"/>
|
||||||
|
</ScrollAreaPrimitive.ScrollAreaScrollbar>);
|
||||||
|
});
|
||||||
|
exports.ScrollBar = ScrollBar;
|
||||||
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||||
|
|
||||||
|
import { cn } from "../../utils"
|
||||||
|
|
||||||
|
const ScrollArea = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn("relative overflow-hidden", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
||||||
|
{children}
|
||||||
|
</ScrollAreaPrimitive.Viewport>
|
||||||
|
<ScrollBar />
|
||||||
|
<ScrollBar orientation="horizontal" />
|
||||||
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
</ScrollAreaPrimitive.Root>
|
||||||
|
))
|
||||||
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
||||||
|
|
||||||
|
const ScrollBar = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
>(({ className, orientation = "vertical", ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||||
|
ref={ref}
|
||||||
|
orientation={orientation}
|
||||||
|
className={cn(
|
||||||
|
"flex touch-none select-none transition-colors",
|
||||||
|
orientation === "vertical" &&
|
||||||
|
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
||||||
|
orientation === "horizontal" &&
|
||||||
|
"h-2.5 border-t border-t-transparent p-[1px]",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
||||||
|
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
))
|
||||||
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
||||||
|
|
||||||
|
export { ScrollArea, ScrollBar }
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.SheetDescription = exports.SheetTitle = exports.SheetFooter = exports.SheetHeader = exports.SheetContent = exports.SheetClose = exports.SheetTrigger = exports.Sheet = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var SheetPrimitive = require("@radix-ui/react-dialog");
|
||||||
|
var class_variance_authority_1 = require("class-variance-authority");
|
||||||
|
var lucide_react_1 = require("lucide-react");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var Sheet = SheetPrimitive.Root;
|
||||||
|
exports.Sheet = Sheet;
|
||||||
|
var SheetTrigger = SheetPrimitive.Trigger;
|
||||||
|
exports.SheetTrigger = SheetTrigger;
|
||||||
|
var SheetClose = SheetPrimitive.Close;
|
||||||
|
exports.SheetClose = SheetClose;
|
||||||
|
var SheetPortal = SheetPrimitive.Portal;
|
||||||
|
var SheetOverlay = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<SheetPrimitive.Overlay className={(0, utils_1.cn)("fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className)} {...props} ref={ref}/>);
|
||||||
|
});
|
||||||
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
||||||
|
var sheetVariants = (0, class_variance_authority_1.cva)("fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", {
|
||||||
|
variants: {
|
||||||
|
side: {
|
||||||
|
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
||||||
|
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
||||||
|
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
||||||
|
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
side: "right",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
var SheetContent = React.forwardRef(function (_a, ref) {
|
||||||
|
var _b = _a.side, side = _b === void 0 ? "right" : _b, className = _a.className, children = _a.children, props = __rest(_a, ["side", "className", "children"]);
|
||||||
|
return (<SheetPortal>
|
||||||
|
<SheetOverlay />
|
||||||
|
<SheetPrimitive.Content ref={ref} className={(0, utils_1.cn)(sheetVariants({ side: side }), className)} {...props}>
|
||||||
|
{children}
|
||||||
|
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||||||
|
<lucide_react_1.X className="h-4 w-4"/>
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</SheetPrimitive.Close>
|
||||||
|
</SheetPrimitive.Content>
|
||||||
|
</SheetPortal>);
|
||||||
|
});
|
||||||
|
exports.SheetContent = SheetContent;
|
||||||
|
SheetContent.displayName = SheetPrimitive.Content.displayName;
|
||||||
|
var SheetHeader = function (_a) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<div className={(0, utils_1.cn)("flex flex-col space-y-2 text-center sm:text-left", className)} {...props}/>);
|
||||||
|
};
|
||||||
|
exports.SheetHeader = SheetHeader;
|
||||||
|
SheetHeader.displayName = "SheetHeader";
|
||||||
|
var SheetFooter = function (_a) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<div className={(0, utils_1.cn)("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...props}/>);
|
||||||
|
};
|
||||||
|
exports.SheetFooter = SheetFooter;
|
||||||
|
SheetFooter.displayName = "SheetFooter";
|
||||||
|
var SheetTitle = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<SheetPrimitive.Title ref={ref} className={(0, utils_1.cn)("text-lg font-semibold text-foreground", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.SheetTitle = SheetTitle;
|
||||||
|
SheetTitle.displayName = SheetPrimitive.Title.displayName;
|
||||||
|
var SheetDescription = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<SheetPrimitive.Description ref={ref} className={(0, utils_1.cn)("text-sm text-muted-foreground", className)} {...props}/>);
|
||||||
|
});
|
||||||
|
exports.SheetDescription = SheetDescription;
|
||||||
|
SheetDescription.displayName = SheetPrimitive.Description.displayName;
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
import * as React from "react"
|
||||||
|
import * as SheetPrimitive from "@radix-ui/react-dialog"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
import { X } from "lucide-react"
|
||||||
|
|
||||||
|
import { cn } from "../../utils"
|
||||||
|
|
||||||
|
const Sheet = SheetPrimitive.Root
|
||||||
|
|
||||||
|
const SheetTrigger = SheetPrimitive.Trigger
|
||||||
|
|
||||||
|
const SheetClose = SheetPrimitive.Close
|
||||||
|
|
||||||
|
const SheetPortal = SheetPrimitive.Portal
|
||||||
|
|
||||||
|
const SheetOverlay = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Overlay>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Overlay
|
||||||
|
className={cn(
|
||||||
|
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
|
||||||
|
|
||||||
|
const sheetVariants = cva(
|
||||||
|
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
side: {
|
||||||
|
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
||||||
|
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
||||||
|
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
||||||
|
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
side: "right",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
interface SheetContentProps
|
||||||
|
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
||||||
|
VariantProps<typeof sheetVariants> {}
|
||||||
|
|
||||||
|
const SheetContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Content>,
|
||||||
|
SheetContentProps
|
||||||
|
>(({ side = "right", className, children, ...props }, ref) => (
|
||||||
|
<SheetPortal>
|
||||||
|
<SheetOverlay />
|
||||||
|
<SheetPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
className={cn(sheetVariants({ side }), className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</SheetPrimitive.Close>
|
||||||
|
</SheetPrimitive.Content>
|
||||||
|
</SheetPortal>
|
||||||
|
))
|
||||||
|
SheetContent.displayName = SheetPrimitive.Content.displayName
|
||||||
|
|
||||||
|
const SheetHeader = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col space-y-2 text-center sm:text-left",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
SheetHeader.displayName = "SheetHeader"
|
||||||
|
|
||||||
|
const SheetFooter = ({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
SheetFooter.displayName = "SheetFooter"
|
||||||
|
|
||||||
|
const SheetTitle = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Title>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Title
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-lg font-semibold text-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SheetTitle.displayName = SheetPrimitive.Title.displayName
|
||||||
|
|
||||||
|
const SheetDescription = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SheetPrimitive.Description>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SheetPrimitive.Description
|
||||||
|
ref={ref}
|
||||||
|
className={cn("text-sm text-muted-foreground", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
SheetDescription.displayName = SheetPrimitive.Description.displayName
|
||||||
|
|
||||||
|
export {
|
||||||
|
Sheet,
|
||||||
|
SheetTrigger,
|
||||||
|
SheetClose,
|
||||||
|
SheetContent,
|
||||||
|
SheetHeader,
|
||||||
|
SheetFooter,
|
||||||
|
SheetTitle,
|
||||||
|
SheetDescription,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
"use strict";
|
||||||
|
var __rest = (this && this.__rest) || function (s, e) {
|
||||||
|
var t = {};
|
||||||
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||||
|
t[p] = s[p];
|
||||||
|
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||||
|
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||||
|
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||||
|
t[p[i]] = s[p[i]];
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.Switch = void 0;
|
||||||
|
var React = require("react");
|
||||||
|
var SwitchPrimitives = require("@radix-ui/react-switch");
|
||||||
|
var utils_1 = require("../../utils");
|
||||||
|
var Switch = React.forwardRef(function (_a, ref) {
|
||||||
|
var className = _a.className, props = __rest(_a, ["className"]);
|
||||||
|
return (<SwitchPrimitives.Root className={(0, utils_1.cn)("peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input", className)} {...props} ref={ref}>
|
||||||
|
<SwitchPrimitives.Thumb className={(0, utils_1.cn)("pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0")}/>
|
||||||
|
</SwitchPrimitives.Root>);
|
||||||
|
});
|
||||||
|
exports.Switch = Switch;
|
||||||
|
Switch.displayName = SwitchPrimitives.Root.displayName;
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.hello = exports.getSampleAgentSteps = exports.getSampleAgentSessions = void 0;
|
||||||
|
// Entry point for @ra-aid/common package
|
||||||
|
require("./styles/global.css");
|
||||||
|
// Direct imports from sample-data
|
||||||
|
var sample_data_1 = require("./utils/sample-data");
|
||||||
|
Object.defineProperty(exports, "getSampleAgentSessions", { enumerable: true, get: function () { return sample_data_1.getSampleAgentSessions; } });
|
||||||
|
Object.defineProperty(exports, "getSampleAgentSteps", { enumerable: true, get: function () { return sample_data_1.getSampleAgentSteps; } });
|
||||||
|
// Export utility functions
|
||||||
|
__exportStar(require("./utils"), exports);
|
||||||
|
// Export all UI components
|
||||||
|
__exportStar(require("./components/ui"), exports);
|
||||||
|
// Export timeline components
|
||||||
|
__exportStar(require("./components/TimelineStep"), exports);
|
||||||
|
__exportStar(require("./components/TimelineFeed"), exports);
|
||||||
|
// Export session navigation components
|
||||||
|
__exportStar(require("./components/SessionDrawer"), exports);
|
||||||
|
__exportStar(require("./components/SessionSidebar"), exports);
|
||||||
|
// Export the hello function (temporary example)
|
||||||
|
var hello = function () {
|
||||||
|
console.log("Hello from @ra-aid/common");
|
||||||
|
};
|
||||||
|
exports.hello = hello;
|
||||||
|
|
@ -1,13 +1,29 @@
|
||||||
// Entry point for @ra-aid/common package
|
// Entry point for @ra-aid/common package
|
||||||
import './styles/global.css';
|
import './styles/global.css';
|
||||||
|
|
||||||
// Export utility functions
|
// Export utility functions (excluding sample data to avoid circular references)
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
|
||||||
// Export all UI components
|
// Export all UI components
|
||||||
export * from './components/ui';
|
export * from './components/ui';
|
||||||
|
|
||||||
|
// Export timeline components
|
||||||
|
export * from './components/TimelineStep';
|
||||||
|
export * from './components/TimelineFeed';
|
||||||
|
|
||||||
|
// Export session navigation components
|
||||||
|
export * from './components/SessionDrawer';
|
||||||
|
export * from './components/SessionSidebar';
|
||||||
|
|
||||||
// Export the hello function (temporary example)
|
// Export the hello function (temporary example)
|
||||||
export const hello = (): void => {
|
export const hello = (): void => {
|
||||||
console.log("Hello from @ra-aid/common");
|
console.log("Hello from @ra-aid/common");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Directly export sample data functions and types to avoid circular references
|
||||||
|
export {
|
||||||
|
getSampleAgentSteps,
|
||||||
|
getSampleAgentSessions,
|
||||||
|
type AgentStep,
|
||||||
|
type AgentSession
|
||||||
|
} from './utils/sample-data';
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.cn = cn;
|
||||||
|
var clsx_1 = require("clsx");
|
||||||
|
var tailwind_merge_1 = require("tailwind-merge");
|
||||||
|
/**
|
||||||
|
* Merges class names with Tailwind CSS classes
|
||||||
|
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
|
||||||
|
*/
|
||||||
|
function cn() {
|
||||||
|
var inputs = [];
|
||||||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||||||
|
inputs[_i] = arguments[_i];
|
||||||
|
}
|
||||||
|
return (0, tailwind_merge_1.twMerge)((0, clsx_1.clsx)(inputs));
|
||||||
|
}
|
||||||
|
// Re-export everything from utils directory
|
||||||
|
__exportStar(require("./utils"), exports);
|
||||||
|
|
@ -7,4 +7,7 @@ import { twMerge } from "tailwind-merge";
|
||||||
*/
|
*/
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-export everything from utils directory
|
||||||
|
export * from './utils';
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||||
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.cn = cn;
|
||||||
|
var clsx_1 = require("clsx");
|
||||||
|
var tailwind_merge_1 = require("tailwind-merge");
|
||||||
|
/**
|
||||||
|
* Merges class names with Tailwind CSS classes
|
||||||
|
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
|
||||||
|
*/
|
||||||
|
function cn() {
|
||||||
|
var inputs = [];
|
||||||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||||||
|
inputs[_i] = arguments[_i];
|
||||||
|
}
|
||||||
|
return (0, tailwind_merge_1.twMerge)((0, clsx_1.clsx)(inputs));
|
||||||
|
}
|
||||||
|
// Export sample data utilities
|
||||||
|
__exportStar(require("./sample-data"), exports);
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { clsx, type ClassValue } from "clsx";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges class names with Tailwind CSS classes
|
||||||
|
* Combines clsx for conditional logic and tailwind-merge for handling conflicting tailwind classes
|
||||||
|
*/
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Sample data functions and types are now exported directly from the root index.ts
|
||||||
|
// to avoid circular references
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
"use strict";
|
||||||
|
/**
|
||||||
|
* Sample data utility for agent UI components demonstration
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getSampleAgentSteps = getSampleAgentSteps;
|
||||||
|
exports.getSampleAgentSessions = getSampleAgentSessions;
|
||||||
|
/**
|
||||||
|
* Returns an array of sample agent steps
|
||||||
|
*/
|
||||||
|
function getSampleAgentSteps() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "step-1",
|
||||||
|
timestamp: new Date(Date.now() - 30 * 60000), // 30 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'Initial Planning',
|
||||||
|
content: 'I need to analyze the codebase structure to understand the existing components and their relationships.',
|
||||||
|
duration: 5200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-2",
|
||||||
|
timestamp: new Date(Date.now() - 25 * 60000), // 25 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'List Directory Structure',
|
||||||
|
content: 'Executing: list_directory_tree(path="src/", max_depth=2)\n\n📁 /project/src/\n├── 📁 components/\n│ ├── 📁 ui/\n│ └── App.tsx\n├── 📁 utils/\n└── index.tsx',
|
||||||
|
duration: 1800
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-3",
|
||||||
|
timestamp: new Date(Date.now() - 20 * 60000), // 20 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'thinking',
|
||||||
|
title: 'Component Analysis',
|
||||||
|
content: 'Based on the directory structure, I see that the UI components are organized in a dedicated folder. I should examine the existing component patterns before implementing new ones.',
|
||||||
|
duration: 3500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-4",
|
||||||
|
timestamp: new Date(Date.now() - 15 * 60000), // 15 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'Read Component Code',
|
||||||
|
content: 'Executing: read_file_tool(filepath="src/components/ui/Button.tsx")\n\n```tsx\nimport { cn } from "../../utils";\n\nexport interface ButtonProps {\n // Component props...\n}\n\nexport function Button({ children, ...props }: ButtonProps) {\n // Component implementation...\n}\n```',
|
||||||
|
duration: 2100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-5",
|
||||||
|
timestamp: new Date(Date.now() - 10 * 60000), // 10 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Creating NavBar Component',
|
||||||
|
content: 'I\'m creating a NavBar component following the design system patterns:\n\n```tsx\nimport { cn } from "../../utils";\n\nexport interface NavBarProps {\n // New component props...\n}\n\nexport function NavBar({ ...props }: NavBarProps) {\n // New component implementation...\n}\n```',
|
||||||
|
duration: 6800
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-6",
|
||||||
|
timestamp: new Date(Date.now() - 5 * 60000), // 5 minutes ago
|
||||||
|
status: 'in-progress',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Styling Timeline Component',
|
||||||
|
content: 'Currently working on styling the Timeline component to match the design system:\n\n```tsx\n// Work in progress...\nexport function Timeline({ steps, ...props }: TimelineProps) {\n // Current implementation...\n}\n```',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-7",
|
||||||
|
timestamp: new Date(Date.now() - 2 * 60000), // 2 minutes ago
|
||||||
|
status: 'error',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'Running Tests',
|
||||||
|
content: 'Error executing: run_shell_command(command="npm test")\n\nTest failed: TypeError: Cannot read property \'steps\' of undefined',
|
||||||
|
duration: 3200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-8",
|
||||||
|
timestamp: new Date(), // Now
|
||||||
|
status: 'pending',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'Next Steps',
|
||||||
|
content: 'Need to plan the implementation of the SessionDrawer component...',
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns an array of sample agent sessions
|
||||||
|
*/
|
||||||
|
function getSampleAgentSessions() {
|
||||||
|
var steps = getSampleAgentSteps();
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "session-1",
|
||||||
|
name: "UI Component Implementation",
|
||||||
|
created: new Date(Date.now() - 35 * 60000), // 35 minutes ago
|
||||||
|
updated: new Date(), // Now
|
||||||
|
status: 'active',
|
||||||
|
steps: steps
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "session-2",
|
||||||
|
name: "API Integration",
|
||||||
|
created: new Date(Date.now() - 2 * 3600000), // 2 hours ago
|
||||||
|
updated: new Date(Date.now() - 30 * 60000), // 30 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
id: "other-step-1",
|
||||||
|
timestamp: new Date(Date.now() - 2 * 3600000), // 2 hours ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'API Integration Planning',
|
||||||
|
content: 'Planning the integration with the backend API...',
|
||||||
|
duration: 4500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "other-step-2",
|
||||||
|
timestamp: new Date(Date.now() - 1.5 * 3600000), // 1.5 hours ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Implementing API Client',
|
||||||
|
content: 'Creating API client with fetch utilities...',
|
||||||
|
duration: 7200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "other-step-3",
|
||||||
|
timestamp: new Date(Date.now() - 1 * 3600000), // 1 hour ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'Testing API Endpoints',
|
||||||
|
content: 'Running tests against API endpoints...',
|
||||||
|
duration: 5000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "session-3",
|
||||||
|
name: "Bug Fixes",
|
||||||
|
created: new Date(Date.now() - 5 * 3600000), // 5 hours ago
|
||||||
|
updated: new Date(Date.now() - 4 * 3600000), // 4 hours ago
|
||||||
|
status: 'error',
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
id: "bug-step-1",
|
||||||
|
timestamp: new Date(Date.now() - 5 * 3600000), // 5 hours ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'Bug Analysis',
|
||||||
|
content: 'Analyzing reported bugs from issue tracker...',
|
||||||
|
duration: 3600
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "bug-step-2",
|
||||||
|
timestamp: new Date(Date.now() - 4.5 * 3600000), // 4.5 hours ago
|
||||||
|
status: 'error',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Fixing Authentication Bug',
|
||||||
|
content: 'Error: Unable to resolve dependency conflict with auth package',
|
||||||
|
duration: 2500
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,187 @@
|
||||||
|
/**
|
||||||
|
* Sample data utility for agent UI components demonstration
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single step in the agent process
|
||||||
|
*/
|
||||||
|
export interface AgentStep {
|
||||||
|
id: string;
|
||||||
|
timestamp: Date;
|
||||||
|
status: 'completed' | 'in-progress' | 'error' | 'pending';
|
||||||
|
type: 'tool-execution' | 'thinking' | 'planning' | 'implementation' | 'user-input';
|
||||||
|
title: string;
|
||||||
|
content: string;
|
||||||
|
duration?: number; // in milliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a session with multiple steps
|
||||||
|
*/
|
||||||
|
export interface AgentSession {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
created: Date;
|
||||||
|
updated: Date;
|
||||||
|
status: 'active' | 'completed' | 'error';
|
||||||
|
steps: AgentStep[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of sample agent steps
|
||||||
|
*/
|
||||||
|
export function getSampleAgentSteps(): AgentStep[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "step-1",
|
||||||
|
timestamp: new Date(Date.now() - 30 * 60000), // 30 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'Initial Planning',
|
||||||
|
content: 'I need to analyze the codebase structure to understand the existing components and their relationships.',
|
||||||
|
duration: 5200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-2",
|
||||||
|
timestamp: new Date(Date.now() - 25 * 60000), // 25 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'List Directory Structure',
|
||||||
|
content: 'Executing: list_directory_tree(path="src/", max_depth=2)\n\n📁 /project/src/\n├── 📁 components/\n│ ├── 📁 ui/\n│ └── App.tsx\n├── 📁 utils/\n└── index.tsx',
|
||||||
|
duration: 1800
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-3",
|
||||||
|
timestamp: new Date(Date.now() - 20 * 60000), // 20 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'thinking',
|
||||||
|
title: 'Component Analysis',
|
||||||
|
content: 'Based on the directory structure, I see that the UI components are organized in a dedicated folder. I should examine the existing component patterns before implementing new ones.',
|
||||||
|
duration: 3500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-4",
|
||||||
|
timestamp: new Date(Date.now() - 15 * 60000), // 15 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'Read Component Code',
|
||||||
|
content: 'Executing: read_file_tool(filepath="src/components/ui/Button.tsx")\n\n```tsx\nimport { cn } from "../../utils";\n\nexport interface ButtonProps {\n // Component props...\n}\n\nexport function Button({ children, ...props }: ButtonProps) {\n // Component implementation...\n}\n```',
|
||||||
|
duration: 2100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-5",
|
||||||
|
timestamp: new Date(Date.now() - 10 * 60000), // 10 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Creating NavBar Component',
|
||||||
|
content: 'I\'m creating a NavBar component following the design system patterns:\n\n```tsx\nimport { cn } from "../../utils";\n\nexport interface NavBarProps {\n // New component props...\n}\n\nexport function NavBar({ ...props }: NavBarProps) {\n // New component implementation...\n}\n```',
|
||||||
|
duration: 6800
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-6",
|
||||||
|
timestamp: new Date(Date.now() - 5 * 60000), // 5 minutes ago
|
||||||
|
status: 'in-progress',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Styling Timeline Component',
|
||||||
|
content: 'Currently working on styling the Timeline component to match the design system:\n\n```tsx\n// Work in progress...\nexport function Timeline({ steps, ...props }: TimelineProps) {\n // Current implementation...\n}\n```',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-7",
|
||||||
|
timestamp: new Date(Date.now() - 2 * 60000), // 2 minutes ago
|
||||||
|
status: 'error',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'Running Tests',
|
||||||
|
content: 'Error executing: run_shell_command(command="npm test")\n\nTest failed: TypeError: Cannot read property \'steps\' of undefined',
|
||||||
|
duration: 3200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "step-8",
|
||||||
|
timestamp: new Date(), // Now
|
||||||
|
status: 'pending',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'Next Steps',
|
||||||
|
content: 'Need to plan the implementation of the SessionDrawer component...',
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of sample agent sessions
|
||||||
|
*/
|
||||||
|
export function getSampleAgentSessions(): AgentSession[] {
|
||||||
|
const steps = getSampleAgentSteps();
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "session-1",
|
||||||
|
name: "UI Component Implementation",
|
||||||
|
created: new Date(Date.now() - 35 * 60000), // 35 minutes ago
|
||||||
|
updated: new Date(), // Now
|
||||||
|
status: 'active',
|
||||||
|
steps: steps
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "session-2",
|
||||||
|
name: "API Integration",
|
||||||
|
created: new Date(Date.now() - 2 * 3600000), // 2 hours ago
|
||||||
|
updated: new Date(Date.now() - 30 * 60000), // 30 minutes ago
|
||||||
|
status: 'completed',
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
id: "other-step-1",
|
||||||
|
timestamp: new Date(Date.now() - 2 * 3600000), // 2 hours ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'API Integration Planning',
|
||||||
|
content: 'Planning the integration with the backend API...',
|
||||||
|
duration: 4500
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "other-step-2",
|
||||||
|
timestamp: new Date(Date.now() - 1.5 * 3600000), // 1.5 hours ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Implementing API Client',
|
||||||
|
content: 'Creating API client with fetch utilities...',
|
||||||
|
duration: 7200
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "other-step-3",
|
||||||
|
timestamp: new Date(Date.now() - 1 * 3600000), // 1 hour ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'tool-execution',
|
||||||
|
title: 'Testing API Endpoints',
|
||||||
|
content: 'Running tests against API endpoints...',
|
||||||
|
duration: 5000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "session-3",
|
||||||
|
name: "Bug Fixes",
|
||||||
|
created: new Date(Date.now() - 5 * 3600000), // 5 hours ago
|
||||||
|
updated: new Date(Date.now() - 4 * 3600000), // 4 hours ago
|
||||||
|
status: 'error',
|
||||||
|
steps: [
|
||||||
|
{
|
||||||
|
id: "bug-step-1",
|
||||||
|
timestamp: new Date(Date.now() - 5 * 3600000), // 5 hours ago
|
||||||
|
status: 'completed',
|
||||||
|
type: 'planning',
|
||||||
|
title: 'Bug Analysis',
|
||||||
|
content: 'Analyzing reported bugs from issue tracker...',
|
||||||
|
duration: 3600
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "bug-step-2",
|
||||||
|
timestamp: new Date(Date.now() - 4.5 * 3600000), // 4.5 hours ago
|
||||||
|
status: 'error',
|
||||||
|
type: 'implementation',
|
||||||
|
title: 'Fixing Authentication Bug',
|
||||||
|
content: 'Error: Unable to resolve dependency conflict with auth package',
|
||||||
|
duration: 2500
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"rootDir": "src"
|
"rootDir": "src",
|
||||||
|
"lib": ["DOM", "DOM.Iterable", "ESNext", "ES2016"]
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,170 +1,114 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import {
|
import {
|
||||||
hello,
|
Button,
|
||||||
Button,
|
SessionDrawer,
|
||||||
Card,
|
SessionSidebar,
|
||||||
CardHeader,
|
TimelineFeed,
|
||||||
CardTitle,
|
getSampleAgentSessions,
|
||||||
CardDescription,
|
getSampleAgentSteps
|
||||||
CardContent,
|
|
||||||
CardFooter,
|
|
||||||
Input,
|
|
||||||
Switch
|
|
||||||
} from '@ra-aid/common';
|
} from '@ra-aid/common';
|
||||||
// The CSS import happens through the common package's index.ts
|
// The CSS import happens through the common package's index.ts
|
||||||
|
|
||||||
hello();
|
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [inputValue, setInputValue] = useState('');
|
// State for drawer open/close
|
||||||
const [switchState, setSwitchState] = useState(false);
|
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
|
// State for selected session
|
||||||
const handleLoadingClick = () => {
|
const [selectedSessionId, setSelectedSessionId] = useState<string | null>(null);
|
||||||
setLoading(true);
|
|
||||||
setTimeout(() => setLoading(false), 2000);
|
// Get sample data
|
||||||
|
const sessions = getSampleAgentSessions();
|
||||||
|
const allSteps = getSampleAgentSteps();
|
||||||
|
|
||||||
|
// Set initial selected session if none selected
|
||||||
|
useEffect(() => {
|
||||||
|
if (!selectedSessionId && sessions.length > 0) {
|
||||||
|
setSelectedSessionId(sessions[0].id);
|
||||||
|
}
|
||||||
|
}, [sessions, selectedSessionId]);
|
||||||
|
|
||||||
|
// Filter steps for selected session
|
||||||
|
const selectedSessionSteps = selectedSessionId
|
||||||
|
? allSteps.filter(step => sessions.find(s => s.id === selectedSessionId)?.steps.some(s => s.id === step.id))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
// Handle session selection
|
||||||
|
const handleSessionSelect = (sessionId: string) => {
|
||||||
|
setSelectedSessionId(sessionId);
|
||||||
|
setIsDrawerOpen(false); // Close drawer on selection (mobile)
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-background text-foreground dark">
|
<div className="min-h-screen bg-background text-foreground flex flex-col dark">
|
||||||
<div className="container mx-auto py-10 px-4">
|
{/* Header */}
|
||||||
<header className="mb-10">
|
<header className="border-b border-border py-4 px-4 sticky top-0 z-10 bg-background">
|
||||||
<h1 className="text-4xl font-bold mb-2 bg-gradient-to-r from-blue-400 to-purple-500 inline-block text-transparent bg-clip-text">shadcn/ui Components Demo</h1>
|
<div className="flex justify-between items-center">
|
||||||
<p className="text-muted-foreground">A showcase of UI components from the common package</p>
|
<h1 className="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-500 inline-block text-transparent bg-clip-text">
|
||||||
</header>
|
RA-Aid
|
||||||
|
</h1>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
<Card className="border-border bg-card">
|
{/* Mobile drawer toggle - show only on small screens */}
|
||||||
<CardHeader>
|
<div className="md:hidden">
|
||||||
<CardTitle>Button Component</CardTitle>
|
<Button
|
||||||
<CardDescription>Various button variants from shadcn/ui</CardDescription>
|
variant="ghost"
|
||||||
</CardHeader>
|
size="icon"
|
||||||
<CardContent className="space-y-4">
|
onClick={() => setIsDrawerOpen(true)}
|
||||||
<div className="grid grid-cols-2 gap-2">
|
aria-label="Open menu"
|
||||||
<Button variant="default">Default</Button>
|
>
|
||||||
<Button variant="secondary">Secondary</Button>
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-menu"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
|
||||||
<Button variant="destructive">Destructive</Button>
|
</Button>
|
||||||
<Button variant="outline">Outline</Button>
|
</div>
|
||||||
<Button variant="ghost">Ghost</Button>
|
|
||||||
<Button variant="link">Link</Button>
|
|
||||||
</div>
|
|
||||||
<div className="pt-2">
|
|
||||||
<h3 className="text-sm font-medium mb-2">Button Sizes</h3>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Button size="sm">Small</Button>
|
|
||||||
<Button>Default</Button>
|
|
||||||
<Button size="lg">Large</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="pt-2">
|
|
||||||
<h3 className="text-sm font-medium mb-2">Button States</h3>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Button disabled>Disabled</Button>
|
|
||||||
<Button onClick={handleLoadingClick} disabled={loading}>
|
|
||||||
{loading ? 'Loading...' : 'Click to Load'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="border-border bg-card">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Input Component</CardTitle>
|
|
||||||
<CardDescription>Text input with various states</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent className="space-y-4">
|
|
||||||
<div>
|
|
||||||
<label className="text-sm font-medium block mb-1">Standard Input</label>
|
|
||||||
<Input
|
|
||||||
placeholder="Type something..."
|
|
||||||
value={inputValue}
|
|
||||||
onChange={(e) => setInputValue(e.target.value)}
|
|
||||||
/>
|
|
||||||
{inputValue && (
|
|
||||||
<p className="text-sm mt-1 text-muted-foreground">You typed: {inputValue}</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="text-sm font-medium block mb-1">Disabled Input</label>
|
|
||||||
<Input disabled placeholder="Disabled input" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label className="text-sm font-medium block mb-1">With Icon</label>
|
|
||||||
<div className="relative">
|
|
||||||
<Input placeholder="Search..." />
|
|
||||||
<div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-muted-foreground">
|
|
||||||
<circle cx="11" cy="11" r="8"></circle>
|
|
||||||
<path d="m21 21-4.3-4.3"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="border-border bg-card">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Switch Component</CardTitle>
|
|
||||||
<CardDescription>Toggle switch with controlled state</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent className="space-y-4">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<label className="text-sm font-medium">Toggle theme</label>
|
|
||||||
<Switch
|
|
||||||
checked={switchState}
|
|
||||||
onCheckedChange={setSwitchState}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p className="text-sm text-muted-foreground">
|
|
||||||
Current theme: <span className="font-medium">{switchState ? 'Dark' : 'Light'}</span>
|
|
||||||
</p>
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<label className="text-sm font-medium">Disabled switch</label>
|
|
||||||
<Switch disabled />
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter>
|
|
||||||
<p className="text-xs text-muted-foreground">Click the switch to toggle its state</p>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
|
|
||||||
<Card className="border-border bg-card">
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Card Component</CardTitle>
|
|
||||||
<CardDescription>Card with header, content, and footer sections</CardDescription>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<p className="text-card-foreground">Cards are versatile containers that group related content and actions.</p>
|
|
||||||
<div className="mt-4 p-3 bg-muted rounded-md">
|
|
||||||
<code className="text-xs text-pink-400">
|
|
||||||
{'<Card>'}<br/>
|
|
||||||
{' <CardHeader>'}<br/>
|
|
||||||
{' <CardTitle>Title</CardTitle>'}<br/>
|
|
||||||
{' <CardDescription>Description</CardDescription>'}<br/>
|
|
||||||
{' </CardHeader>'}<br/>
|
|
||||||
{' <CardContent>Content</CardContent>'}<br/>
|
|
||||||
{' <CardFooter>Footer</CardFooter>'}<br/>
|
|
||||||
{'</Card>'}
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
<CardFooter className="flex justify-between border-t border-border pt-4">
|
|
||||||
<Button variant="outline" size="sm">Cancel</Button>
|
|
||||||
<Button size="sm">Save</Button>
|
|
||||||
</CardFooter>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
|
</header>
|
||||||
<footer className="mt-12 text-center text-muted-foreground text-sm">
|
|
||||||
<p>Built with shadcn/ui components from the RA-Aid common package</p>
|
{/* Main content */}
|
||||||
</footer>
|
<div className="flex flex-1 overflow-hidden">
|
||||||
|
{/* Desktop sidebar - hidden on mobile */}
|
||||||
|
<SessionSidebar
|
||||||
|
sessions={sessions}
|
||||||
|
currentSessionId={selectedSessionId || undefined}
|
||||||
|
onSelectSession={handleSessionSelect}
|
||||||
|
className="shrink-0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Mobile drawer */}
|
||||||
|
<SessionDrawer
|
||||||
|
sessions={sessions}
|
||||||
|
currentSessionId={selectedSessionId || undefined}
|
||||||
|
onSelectSession={handleSessionSelect}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Main content area */}
|
||||||
|
<main className="flex-1 overflow-auto p-4">
|
||||||
|
{selectedSessionId ? (
|
||||||
|
<>
|
||||||
|
<h2 className="text-xl font-semibold mb-4">
|
||||||
|
Session: {sessions.find(s => s.id === selectedSessionId)?.name || 'Unknown'}
|
||||||
|
</h2>
|
||||||
|
<TimelineFeed
|
||||||
|
steps={selectedSessionSteps}
|
||||||
|
maxHeight="calc(100vh - 14rem)"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<div className="flex items-center justify-center h-full">
|
||||||
|
<p className="text-muted-foreground">Select a session to view details</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<footer className="border-t border-border py-4 px-4 text-center text-muted-foreground text-sm">
|
||||||
|
<p>Built with shadcn/ui components from the RA-Aid common package</p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root')!);
|
const root = ReactDOM.createRoot(document.getElementById('root')!);
|
||||||
root.render(<App />);
|
root.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
|
|
@ -7,14 +7,14 @@ export default defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
// Ensure that Vite treats symlinked packages as local, so HMR works correctly.
|
// Ensure that Vite treats symlinked packages as local, so HMR works correctly.
|
||||||
alias: {
|
alias: {
|
||||||
'@ra-aid/common': path.resolve(__dirname, '../common/src')
|
'@ra-aid/common': path.resolve(__dirname, '../common/dist')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
watch: {
|
watch: {
|
||||||
// Watch for changes in the common package.
|
// Watch for changes in the common package.
|
||||||
// This pattern forces Vite to notice file changes in the shared library.
|
// This pattern forces Vite to notice file changes in the shared library.
|
||||||
paths: ['../common/src/**']
|
paths: ['../common/src/**', '../common/dist/**']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue