|
|
|
|
@ -52,6 +52,9 @@ export function ClientDetail() {
|
|
|
|
|
const id = useParams()['id'] ?? ''
|
|
|
|
|
const nav = useNavigate()
|
|
|
|
|
const [sp, setSp] = useSearchParams()
|
|
|
|
|
const rawTab = sp.get('tab') ?? 'overview'
|
|
|
|
|
const tab: TabKey = (TAB_KEYS as readonly string[]).includes(rawTab) ? (rawTab as TabKey) : 'overview'
|
|
|
|
|
const setTab = (k: string) => setSp(k === 'overview' ? {} : { tab: k }, { replace: true })
|
|
|
|
|
const client = useData(() => getClient(id), [id])
|
|
|
|
|
const modules = useData(getModules, [])
|
|
|
|
|
const cms = useData(() => getClientModules(id), [id])
|
|
|
|
|
@ -66,7 +69,9 @@ export function ClientDetail() {
|
|
|
|
|
const [ticketPage, setTicketPage] = useState(1)
|
|
|
|
|
const tickets = useData(() => getTickets({ clientId: id, page: ticketPage, pageSize: 50 }), [id, ticketPage])
|
|
|
|
|
// Same classification list the Tickets desk uses, so the Type column reads identically here.
|
|
|
|
|
const ticketTypes = useData(getTicketTypes, [])
|
|
|
|
|
// Only needed for that column, so only fetch it once the tickets tab is actually open —
|
|
|
|
|
// NewTicketDialog fetches its own copy for the new-ticket type picker, independent of this.
|
|
|
|
|
const ticketTypes = useData(() => (tab === 'tickets' ? getTicketTypes() : Promise.resolve(TICKET_TYPE_FALLBACK)), [tab === 'tickets'])
|
|
|
|
|
const ticketTypeOptions = ticketTypes.data ?? TICKET_TYPE_FALLBACK
|
|
|
|
|
// Undefined = closed. `moduleCode` pre-fills the module when the ticket is raised from
|
|
|
|
|
// a module block ("Raise ticket for this module") rather than the Tickets tab button.
|
|
|
|
|
@ -99,10 +104,6 @@ export function ClientDetail() {
|
|
|
|
|
const [linkingDoc, setLinkingDoc] = useState(false)
|
|
|
|
|
const [docLinkError, setDocLinkError] = useState<string | undefined>()
|
|
|
|
|
|
|
|
|
|
const rawTab = sp.get('tab') ?? 'overview'
|
|
|
|
|
const tab: TabKey = (TAB_KEYS as readonly string[]).includes(rawTab) ? (rawTab as TabKey) : 'overview'
|
|
|
|
|
const setTab = (k: string) => setSp(k === 'overview' ? {} : { tab: k }, { replace: true })
|
|
|
|
|
|
|
|
|
|
const c = client.data
|
|
|
|
|
if (client.error !== undefined) return <ErrorState message={client.error} onRetry={client.reload} />
|
|
|
|
|
if (c === undefined) return <div className="wf-page"><Skeleton rows={6} /></div>
|
|
|
|
|
|