@burdenoff/microfe-ggnomad 2026.725.2 → 2026.726.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ggnomad/GGNomadRoot.d.ts.map +1 -1
- package/dist/ggnomad/GGNomadRoot.js +66 -52
- package/dist/ggnomad/GGNomadRoot.js.map +1 -1
- package/dist/ggnomad/GGNomadRoutes.d.ts.map +1 -1
- package/dist/ggnomad/GGNomadRoutes.js +13 -5
- package/dist/ggnomad/GGNomadRoutes.js.map +1 -1
- package/dist/ggnomad/components/AuditTrailDialog.d.ts +17 -0
- package/dist/ggnomad/components/AuditTrailDialog.d.ts.map +1 -0
- package/dist/ggnomad/components/AuditTrailDialog.js +88 -0
- package/dist/ggnomad/components/AuditTrailDialog.js.map +1 -0
- package/dist/ggnomad/components/CreateTravelPolicyDialog.d.ts +14 -0
- package/dist/ggnomad/components/CreateTravelPolicyDialog.d.ts.map +1 -0
- package/dist/ggnomad/components/CreateTravelPolicyDialog.js +192 -0
- package/dist/ggnomad/components/CreateTravelPolicyDialog.js.map +1 -0
- package/dist/ggnomad/components/index.d.ts +2 -0
- package/dist/ggnomad/components/index.d.ts.map +1 -1
- package/dist/ggnomad/components/index.js +2 -0
- package/dist/ggnomad/graphql.d.ts +20 -0
- package/dist/ggnomad/graphql.d.ts.map +1 -1
- package/dist/ggnomad/graphql.js +199 -1
- package/dist/ggnomad/graphql.js.map +1 -1
- package/dist/ggnomad/pages/OperationsQueuePage.d.ts +11 -0
- package/dist/ggnomad/pages/OperationsQueuePage.d.ts.map +1 -0
- package/dist/ggnomad/pages/OperationsQueuePage.js +323 -0
- package/dist/ggnomad/pages/OperationsQueuePage.js.map +1 -0
- package/dist/ggnomad/pages/TravelPolicyPage.d.ts +9 -0
- package/dist/ggnomad/pages/TravelPolicyPage.d.ts.map +1 -0
- package/dist/ggnomad/pages/TravelPolicyPage.js +245 -0
- package/dist/ggnomad/pages/TravelPolicyPage.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TravelPolicyPage.js","names":[],"sources":["../../../src/ggnomad/pages/TravelPolicyPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport type { TypedDocumentNode } from '@apollo/client';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { AlertCircle, Check, DollarSign, Plus, ShieldCheck, Trash2, Wallet, X } from 'lucide-react';\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n CTAOverflowMenu,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n APPROVE_GGNOMAD_BOOKING_APPROVAL_MUTATION,\n DELETE_GGNOMAD_TRAVEL_POLICY_MUTATION,\n GGNOMAD_BOOKING_APPROVALS_QUERY,\n GGNOMAD_SPEND_SUMMARY_QUERY,\n GGNOMAD_TRAVEL_POLICIES_QUERY,\n REJECT_GGNOMAD_BOOKING_APPROVAL_MUTATION,\n} from '../graphql';\nimport { PageShell } from './PageShell';\nimport {\n CreateTravelPolicyDialog,\n EntityCard,\n SectionCard,\n StatCard,\n StatusBadge,\n} from '../components';\nimport { notify } from '../utils/notify';\n\ntype BookingApproval = {\n id: string;\n bookingId: string;\n requestedBy: string;\n costCenter: string | null;\n reasons: string[];\n status: string;\n reviewedBy: string | null;\n reviewedAt: string | null;\n reviewNote: string | null;\n booking: {\n id: string;\n referenceCode: string;\n itemName: string;\n totalPrice: number;\n currency: string;\n status: string;\n paymentStatus: string;\n } | null;\n};\n\ntype TravelPolicy = {\n id: string;\n name: string;\n isActive: boolean;\n costCenter: string | null;\n currency: string;\n maxBookingAmount: number | null;\n maxMonthlyPerTraveler: number | null;\n blockedDestinations: string[];\n allowedTravelClasses: string[];\n requireApprovalAlways: boolean;\n};\n\ntype SpendSummary = {\n totalSpend: number;\n bookingCount: number;\n pendingApprovalCount: number;\n pendingApprovalAmount: number;\n byCostCenter: Record<string, { spend: number; count: number }>;\n};\n\n/**\n * Manager dashboard for corporate travel governance (BOFF-4365): consolidated\n * spend, the pending-approval queue for bookings that violated policy, and\n * the travel policies themselves (budget caps, blocked destinations, class\n * rules). Approve/reject and policy CRUD are gated server-side by the\n * `ggnomad:manage` RBAC action — a traveler or host-operator cannot act here.\n */\nexport function TravelPolicyPage() {\n const { t } = useI18n();\n const [createPolicyOpen, setCreatePolicyOpen] = useState(false);\n const [rejectTarget, setRejectTarget] = useState<BookingApproval | null>(null);\n const [rejectReason, setRejectReason] = useState('');\n const [deleteTarget, setDeleteTarget] = useState<TravelPolicy | null>(null);\n\n const { data: summaryData, refetch: refetchSummary } = useQuery(\n GGNOMAD_SPEND_SUMMARY_QUERY as TypedDocumentNode<\n { ggnomadSpendSummary: SpendSummary },\n { costCenter?: string | null }\n >\n );\n const summary = summaryData?.ggnomadSpendSummary;\n\n const {\n data: approvalsData,\n refetch: refetchApprovals,\n loading: approvalsLoading,\n } = useQuery(\n GGNOMAD_BOOKING_APPROVALS_QUERY as TypedDocumentNode<\n { ggnomadBookingApprovals: BookingApproval[] },\n { status?: string | null; limit?: number; offset?: number }\n >,\n { variables: { status: 'PENDING', limit: 20, offset: 0 } }\n );\n const pendingApprovals = useMemo(\n () => approvalsData?.ggnomadBookingApprovals ?? [],\n [approvalsData?.ggnomadBookingApprovals]\n );\n\n const { data: policiesData, refetch: refetchPolicies } = useQuery(\n GGNOMAD_TRAVEL_POLICIES_QUERY as TypedDocumentNode<\n { ggnomadTravelPolicies: TravelPolicy[] },\n { limit?: number; offset?: number }\n >,\n { variables: { limit: 50, offset: 0 } }\n );\n const policies = useMemo(\n () => policiesData?.ggnomadTravelPolicies ?? [],\n [policiesData?.ggnomadTravelPolicies]\n );\n\n const [approveApproval, { loading: approving }] = useMutation(\n APPROVE_GGNOMAD_BOOKING_APPROVAL_MUTATION as TypedDocumentNode<\n { approveGgnomadBookingApproval: { id: string; status: string } },\n { id: string; note?: string }\n >\n );\n const [rejectApproval, { loading: rejecting }] = useMutation(\n REJECT_GGNOMAD_BOOKING_APPROVAL_MUTATION as TypedDocumentNode<\n { rejectGgnomadBookingApproval: { id: string; status: string } },\n { id: string; reason: string }\n >\n );\n const [deleteTravelPolicy, { loading: deletingPolicy }] = useMutation(\n DELETE_GGNOMAD_TRAVEL_POLICY_MUTATION as TypedDocumentNode<\n { deleteGgnomadTravelPolicy: boolean },\n { id: string }\n >\n );\n\n const refetchAll = async () => {\n await Promise.all([refetchSummary(), refetchApprovals(), refetchPolicies()]);\n };\n\n const handleApprove = async (approval: BookingApproval) => {\n try {\n const result = await approveApproval({ variables: { id: approval.id } });\n if (result.error) {\n notify.error(\n t('ggnomad.travelPolicy.approve.errorTitle', 'Could not approve booking'),\n result.error.message\n );\n return;\n }\n notify.success(\n t('ggnomad.travelPolicy.approve.successTitle', 'Booking approved'),\n approval.booking?.referenceCode ?? approval.bookingId\n );\n await refetchAll();\n } catch (err) {\n notify.error(\n t('ggnomad.travelPolicy.approve.errorTitle', 'Could not approve booking'),\n err instanceof Error ? err.message : String(err)\n );\n }\n };\n\n const confirmReject = async () => {\n if (!rejectTarget) return;\n if (!rejectReason.trim()) {\n notify.warning(\n t('ggnomad.travelPolicy.reject.reasonRequiredTitle', 'A reason is required'),\n t(\n 'ggnomad.travelPolicy.reject.reasonRequiredBody',\n 'Let the traveler know why this was rejected.'\n )\n );\n return;\n }\n try {\n const result = await rejectApproval({\n variables: { id: rejectTarget.id, reason: rejectReason.trim() },\n });\n if (result.error) {\n notify.error(\n t('ggnomad.travelPolicy.reject.errorTitle', 'Could not reject booking'),\n result.error.message\n );\n return;\n }\n notify.success(\n t('ggnomad.travelPolicy.reject.successTitle', 'Booking rejected'),\n rejectTarget.booking?.referenceCode ?? rejectTarget.bookingId\n );\n await refetchAll();\n } catch (err) {\n notify.error(\n t('ggnomad.travelPolicy.reject.errorTitle', 'Could not reject booking'),\n err instanceof Error ? err.message : String(err)\n );\n } finally {\n setRejectTarget(null);\n setRejectReason('');\n }\n };\n\n const confirmDeletePolicy = async () => {\n if (!deleteTarget) return;\n try {\n const result = await deleteTravelPolicy({ variables: { id: deleteTarget.id } });\n if (result.error) {\n notify.error(\n t('ggnomad.travelPolicy.delete.errorTitle', 'Could not remove policy'),\n result.error.message\n );\n return;\n }\n notify.success(\n t('ggnomad.travelPolicy.delete.successTitle', 'Policy removed'),\n deleteTarget.name\n );\n await refetchPolicies();\n } catch (err) {\n notify.error(\n t('ggnomad.travelPolicy.delete.errorTitle', 'Could not remove policy'),\n err instanceof Error ? err.message : String(err)\n );\n } finally {\n setDeleteTarget(null);\n }\n };\n\n return (\n <PageShell\n title={t('ggnomad.travelPolicy.title', 'Travel Policy')}\n titleAccent={t('ggnomad.travelPolicy.title.accent', 'Policy')}\n subtitle={t(\n 'ggnomad.travelPolicy.subtitle',\n 'Corporate travel guardrails: budgets, blocked destinations, class rules, and booking approvals'\n )}\n actions={\n <CTAOverflowMenu\n primary={{\n label: t('ggnomad.travelPolicy.actions.newPolicy', 'New policy'),\n onSelect: () => setCreatePolicyOpen(true),\n icon: <Plus />,\n }}\n actions={[]}\n />\n }\n >\n <PagePurpose icon={<ShieldCheck className=\"size-4\" />}>\n {t(\n 'ggnomad.travelPolicy.purpose',\n 'Managers define budget caps, blocked destinations and class rules here. A booking that violates the applicable policy is held for your approval instead of confirming automatically — travelers and hosts cannot approve their own over-budget bookings.'\n )}\n </PagePurpose>\n\n <section className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n <StatCard\n hero\n label={t('ggnomad.travelPolicy.stats.totalSpend', 'Total spend')}\n value={`$${Number(summary?.totalSpend ?? 0).toLocaleString()}`}\n icon={<DollarSign />}\n />\n <StatCard\n label={t('ggnomad.travelPolicy.stats.bookingCount', 'Bookings')}\n value={Number(summary?.bookingCount ?? 0).toLocaleString()}\n icon={<Wallet />}\n />\n <StatCard\n label={t('ggnomad.travelPolicy.stats.pendingCount', 'Pending approvals')}\n value={Number(summary?.pendingApprovalCount ?? 0).toLocaleString()}\n icon={<AlertCircle />}\n />\n <StatCard\n label={t('ggnomad.travelPolicy.stats.pendingAmount', 'Pending amount')}\n value={`$${Number(summary?.pendingApprovalAmount ?? 0).toLocaleString()}`}\n icon={<ShieldCheck />}\n />\n </section>\n\n <SectionCard title={t('ggnomad.travelPolicy.approvalsTitle', 'Pending approvals')}>\n {!approvalsLoading && pendingApprovals.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.travelPolicy.approvalsEmptyTitle', 'Nothing waiting on you')}\n description={t(\n 'ggnomad.travelPolicy.approvalsEmptyDescription',\n 'Bookings that exceed a travel policy will show up here for your decision.'\n )}\n />\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {pendingApprovals.map((approval) => (\n <EntityCard\n key={approval.id}\n title={approval.booking?.referenceCode ?? approval.bookingId}\n meta={approval.reasons.join(' · ') || approval.booking?.itemName}\n price={\n approval.booking\n ? `${approval.booking.currency} ${Number(approval.booking.totalPrice).toFixed(2)}`\n : undefined\n }\n badge={<StatusBadge status={approval.status} live />}\n footer={\n <CTAOverflowMenu\n align=\"end\"\n actions={[\n {\n label: t('ggnomad.travelPolicy.actions.approve', 'Approve'),\n onSelect: () => void handleApprove(approval),\n disabled: approving,\n icon: <Check />,\n },\n {\n label: t('ggnomad.travelPolicy.actions.reject', 'Reject'),\n onSelect: () => {\n setRejectTarget(approval);\n setRejectReason('');\n },\n intent: 'destructive',\n icon: <X />,\n },\n ]}\n />\n }\n />\n ))}\n </div>\n )}\n </SectionCard>\n\n <SectionCard title={t('ggnomad.travelPolicy.policiesTitle', 'Travel policies')}>\n {policies.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={t('ggnomad.travelPolicy.policiesEmptyTitle', 'No travel policy defined yet')}\n description={t(\n 'ggnomad.travelPolicy.policiesEmptyDescription',\n 'Create one to enforce budget caps, blocked destinations, and class rules on future bookings.'\n )}\n />\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2\">\n {policies.map((policy) => (\n <EntityCard\n key={policy.id}\n title={policy.name}\n meta={\n policy.costCenter\n ? t('ggnomad.travelPolicy.card.costCenter', 'Cost center: {{cc}}').replace(\n '{{cc}}',\n policy.costCenter\n )\n : t('ggnomad.travelPolicy.card.workspaceWide', 'Workspace-wide default')\n }\n price={\n policy.maxBookingAmount != null\n ? `${policy.currency} ${Number(policy.maxBookingAmount).toFixed(2)} / booking`\n : t('ggnomad.travelPolicy.card.noCap', 'No per-booking cap')\n }\n badge={\n <StatusBadge\n status={policy.isActive ? 'ACTIVE' : 'PAUSED'}\n live={policy.isActive}\n />\n }\n footer={\n <CTAOverflowMenu\n align=\"end\"\n actions={[\n {\n label: t('ggnomad.travelPolicy.actions.deletePolicy', 'Remove policy'),\n onSelect: () => setDeleteTarget(policy),\n intent: 'destructive',\n icon: <Trash2 />,\n },\n ]}\n />\n }\n />\n ))}\n </div>\n )}\n </SectionCard>\n\n <CreateTravelPolicyDialog\n open={createPolicyOpen}\n onOpenChange={setCreatePolicyOpen}\n onCreated={() => void refetchPolicies()}\n />\n\n <AlertDialog\n open={rejectTarget !== null}\n onOpenChange={(open) => {\n if (!open) {\n setRejectTarget(null);\n setRejectReason('');\n }\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t('ggnomad.travelPolicy.rejectDialog.title', 'Reject this booking?')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\n 'ggnomad.travelPolicy.rejectDialog.body',\n 'This cancels {{ref}} and revokes any issued ticket. The traveler sees your reason.'\n ).replace(\n '{{ref}}',\n rejectTarget?.booking?.referenceCode ?? rejectTarget?.bookingId ?? ''\n )}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <div>\n <label htmlFor=\"reject-reason\" className=\"block text-sm font-medium text-text-primary\">\n {t('ggnomad.travelPolicy.rejectDialog.reasonLabel', 'Reason')}\n </label>\n <textarea\n id=\"reject-reason\"\n value={rejectReason}\n onChange={(e) => setRejectReason(e.target.value)}\n disabled={rejecting}\n rows={3}\n className=\"mt-1 w-full rounded-md border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder-text-secondary focus:border-action-primary-bg focus:outline-none focus:ring-1 focus:ring-action-primary-bg disabled:opacity-50\"\n placeholder={t(\n 'ggnomad.travelPolicy.rejectDialog.reasonPlaceholder',\n 'e.g. Over quarterly budget'\n )}\n />\n </div>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={rejecting}>\n {t('ggnomad.travelPolicy.rejectDialog.cancel', 'Keep pending')}\n </AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-action-danger-bg text-action-danger-text hover:bg-action-danger-bgHover\"\n disabled={rejecting}\n onClick={(event) => {\n event.preventDefault();\n void confirmReject();\n }}\n >\n {rejecting\n ? t('ggnomad.travelPolicy.rejectDialog.rejecting', 'Rejecting…')\n : t('ggnomad.travelPolicy.rejectDialog.confirm', 'Reject booking')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n <AlertDialog\n open={deleteTarget !== null}\n onOpenChange={(open) => {\n if (!open) setDeleteTarget(null);\n }}\n >\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>\n {t('ggnomad.travelPolicy.deleteDialog.title', 'Remove this policy?')}\n </AlertDialogTitle>\n <AlertDialogDescription>\n {t(\n 'ggnomad.travelPolicy.deleteDialog.body',\n 'Bookings already approved or rejected under {{name}} are unaffected. New bookings stop being checked against it.'\n ).replace('{{name}}', deleteTarget?.name ?? '')}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={deletingPolicy}>\n {t('ggnomad.travelPolicy.deleteDialog.cancel', 'Keep policy')}\n </AlertDialogCancel>\n <AlertDialogAction\n className=\"bg-action-danger-bg text-action-danger-text hover:bg-action-danger-bgHover\"\n disabled={deletingPolicy}\n onClick={(event) => {\n event.preventDefault();\n void confirmDeletePolicy();\n }}\n >\n {deletingPolicy\n ? t('ggnomad.travelPolicy.deleteDialog.removing', 'Removing…')\n : t('ggnomad.travelPolicy.deleteDialog.confirm', 'Remove policy')}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </PageShell>\n );\n}\n"],"mappings":"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"}
|