feat: command palette, PSA ticket context, session-to-flow converter #108
@@ -30,6 +30,8 @@ import { TicketLinkIndicator } from '@/components/session/TicketLinkIndicator'
|
|||||||
import { UpdateTicketModal } from '@/components/session/UpdateTicketModal'
|
import { UpdateTicketModal } from '@/components/session/UpdateTicketModal'
|
||||||
import type { PSATicketInfo } from '@/types/integrations'
|
import type { PSATicketInfo } from '@/types/integrations'
|
||||||
import { addRecentFlow } from '@/lib/recentFlows'
|
import { addRecentFlow } from '@/lib/recentFlows'
|
||||||
|
import { useTicketContext } from '@/hooks/useTicketContext'
|
||||||
|
import { TicketContextPanel } from '@/components/session/TicketContextPanel'
|
||||||
|
|
||||||
interface StepState {
|
interface StepState {
|
||||||
notes: string
|
notes: string
|
||||||
@@ -92,6 +94,12 @@ export function ProceduralNavigationPage() {
|
|||||||
const [isSavingStep, setIsSavingStep] = useState(false)
|
const [isSavingStep, setIsSavingStep] = useState(false)
|
||||||
const [copilotOpen, setCopilotOpen] = useState(false)
|
const [copilotOpen, setCopilotOpen] = useState(false)
|
||||||
|
|
||||||
|
// PSA ticket context
|
||||||
|
const { context: ticketContext, loading: ticketContextLoading, error: ticketContextError, refresh: refreshTicketContext } = useTicketContext(
|
||||||
|
session?.psa_ticket_id,
|
||||||
|
session?.psa_connection_id
|
||||||
|
)
|
||||||
|
|
||||||
// PSA ticket link state
|
// PSA ticket link state
|
||||||
const [hasConnection, setHasConnection] = useState(false)
|
const [hasConnection, setHasConnection] = useState(false)
|
||||||
const [showTicketPicker, setShowTicketPicker] = useState(false)
|
const [showTicketPicker, setShowTicketPicker] = useState(false)
|
||||||
@@ -673,6 +681,18 @@ export function ProceduralNavigationPage() {
|
|||||||
onStepClick={setCurrentStepIndex}
|
onStepClick={setCurrentStepIndex}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* PSA Ticket Context Panel */}
|
||||||
|
{session?.psa_ticket_id && (
|
||||||
|
<div className="mt-3 border-t border-border pt-3">
|
||||||
|
<TicketContextPanel
|
||||||
|
context={ticketContext}
|
||||||
|
loading={ticketContextLoading}
|
||||||
|
error={ticketContextError}
|
||||||
|
onRefresh={refreshTicketContext}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Session Variables button */}
|
{/* Session Variables button */}
|
||||||
{intakeFields.length > 0 && (
|
{intakeFields.length > 0 && (
|
||||||
<div className="mt-3 border-t border-border pt-3">
|
<div className="mt-3 border-t border-border pt-3">
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import { TicketLinkIndicator } from '@/components/session/TicketLinkIndicator'
|
|||||||
import { UpdateTicketModal } from '@/components/session/UpdateTicketModal'
|
import { UpdateTicketModal } from '@/components/session/UpdateTicketModal'
|
||||||
import type { PSATicketInfo } from '@/types/integrations'
|
import type { PSATicketInfo } from '@/types/integrations'
|
||||||
import { addRecentFlow } from '@/lib/recentFlows'
|
import { addRecentFlow } from '@/lib/recentFlows'
|
||||||
|
import { useTicketContext } from '@/hooks/useTicketContext'
|
||||||
|
import { TicketContextPanel } from '@/components/session/TicketContextPanel'
|
||||||
|
|
||||||
interface LocationState {
|
interface LocationState {
|
||||||
sessionId?: string
|
sessionId?: string
|
||||||
@@ -77,6 +79,12 @@ export function TreeNavigationPage() {
|
|||||||
const [showUpdateModal, setShowUpdateModal] = useState(false)
|
const [showUpdateModal, setShowUpdateModal] = useState(false)
|
||||||
const [ticketInfo, setTicketInfo] = useState<PSATicketInfo | null>(null)
|
const [ticketInfo, setTicketInfo] = useState<PSATicketInfo | null>(null)
|
||||||
|
|
||||||
|
// PSA ticket context
|
||||||
|
const { context: ticketContext, loading: ticketContextLoading, error: ticketContextError, refresh: refreshTicketContext } = useTicketContext(
|
||||||
|
session?.psa_ticket_id,
|
||||||
|
session?.psa_connection_id
|
||||||
|
)
|
||||||
|
|
||||||
const handleCopyCommand = (text: string) => {
|
const handleCopyCommand = (text: string) => {
|
||||||
navigator.clipboard.writeText(text)
|
navigator.clipboard.writeText(text)
|
||||||
setCopiedCommand(text)
|
setCopiedCommand(text)
|
||||||
@@ -780,6 +788,18 @@ export function TreeNavigationPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* PSA Ticket Context Panel */}
|
||||||
|
{session?.psa_ticket_id && (
|
||||||
|
<div className="mb-6">
|
||||||
|
<TicketContextPanel
|
||||||
|
context={ticketContext}
|
||||||
|
loading={ticketContextLoading}
|
||||||
|
error={ticketContextError}
|
||||||
|
onRefresh={refreshTicketContext}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Breadcrumb */}
|
{/* Breadcrumb */}
|
||||||
<div className="mb-6 flex items-center gap-2 overflow-x-auto text-sm">
|
<div className="mb-6 flex items-center gap-2 overflow-x-auto text-sm">
|
||||||
{pathTaken.map((nodeId, index) => {
|
{pathTaken.map((nodeId, index) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user