fix: remove site picker, hardcode Commercial site for SHAPE import browser

This commit is contained in:
lorentz 2026-04-08 13:43:02 +00:00
parent e954a8f78e
commit 1d01c3fb3d
2 changed files with 23 additions and 70 deletions

View file

@ -25,6 +25,14 @@ async function graphGet(token: string, url: string) {
return res.json()
}
// Fixed to the Seubert Commercial SharePoint site
const COMMERCIAL_SITE_URL = 'seubert365.sharepoint.com:/sites/Commercial'
async function getCommercialSiteId(token: string): Promise<string> {
const data = await graphGet(token, `https://graph.microsoft.com/v1.0/sites/${COMMERCIAL_SITE_URL}?$select=id`)
return data.id
}
export async function GET(req: NextRequest) {
const session = await getServerSession(authOptions)
if (!session?.user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
@ -32,27 +40,15 @@ export async function GET(req: NextRequest) {
if (!roles.includes('Admin')) return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
const { searchParams } = req.nextUrl
const level = searchParams.get('level') ?? 'sites' // sites | drives | folders
const siteId = searchParams.get('siteId') ?? ''
const level = searchParams.get('level') ?? 'drives' // drives | folders
const driveId = searchParams.get('driveId') ?? ''
const itemId = searchParams.get('itemId') ?? '' // folder item id, empty = root
try {
const token = await getGraphToken()
if (level === 'sites') {
// List all SharePoint sites the app has access to
const data = await graphGet(token, 'https://graph.microsoft.com/v1.0/sites?search=*&$top=50&$select=id,displayName,webUrl')
const sites = (data.value ?? []).map((s: any) => ({
id: s.id,
name: s.displayName,
url: s.webUrl,
}))
return NextResponse.json({ sites })
}
if (level === 'drives') {
if (!siteId) return NextResponse.json({ error: 'siteId required' }, { status: 400 })
const siteId = await getCommercialSiteId(token)
const data = await graphGet(token, `https://graph.microsoft.com/v1.0/sites/${siteId}/drives?$select=id,name,driveType`)
const drives = (data.value ?? []).map((d: any) => ({
id: d.id,

View file

@ -35,7 +35,6 @@ import {
const DEFAULT_DRIVE_ID = 'b!OYuzIexQkkOvfEPyMJPzzZHfzTrOCOdPhTWgTlzKs6M0ZWVrAc6LR4LjWl4QFEzm'
const DEFAULT_FOLDER_PATH = 'Claims/SHAPE Accounts'
interface SpSite { id: string; name: string; url: string }
interface SpDrive { id: string; name: string; type: string }
interface SpFolder { id: string; name: string }
@ -75,14 +74,11 @@ export function ShapeImportPanel({ initialRuns }: { initialRuns: Run[] }) {
const [runs, setRuns] = useState<Run[]>(initialRuns)
// SharePoint picker state
const [sites, setSites] = useState<SpSite[]>([])
const [drives, setDrives] = useState<SpDrive[]>([])
const [folders, setFolders] = useState<SpFolder[]>([])
const [selectedSiteId, setSelectedSiteId] = useState<string>('')
const [selectedDriveId, setSelectedDriveId] = useState<string>(DEFAULT_DRIVE_ID)
const [selectedFolderId, setSelectedFolderId] = useState<string>('')
const [folderPath, setFolderPath] = useState<string>(DEFAULT_FOLDER_PATH)
const [loadingSites, setLoadingSites] = useState(false)
const [loadingDrives, setLoadingDrives] = useState(false)
const [loadingFolders, setLoadingFolders] = useState(false)
const [pickerError, setPickerError] = useState<string | null>(null)
@ -170,34 +166,16 @@ export function ShapeImportPanel({ initialRuns }: { initialRuns: Run[] }) {
useEffect(() => () => stopPolling(), [stopPolling])
// Load sites on mount
// Load document libraries on mount (site is fixed to Commercial)
useEffect(() => {
setLoadingSites(true)
setPickerError(null)
fetch('/api/admin/shape-import/browse?level=sites')
.then((r) => r.json())
.then((d) => { if (d.sites) setSites(d.sites); else setPickerError(d.error ?? 'Failed to load sites') })
.catch((e) => setPickerError(e.message))
.finally(() => setLoadingSites(false))
}, [])
const handleSiteChange = async (siteId: string) => {
setSelectedSiteId(siteId)
setSelectedDriveId('')
setSelectedFolderId('')
setFolderPath(DEFAULT_FOLDER_PATH)
setDrives([])
setFolders([])
setLoadingDrives(true)
setPickerError(null)
try {
const res = await fetch(`/api/admin/shape-import/browse?level=drives&siteId=${encodeURIComponent(siteId)}`)
const d = await res.json()
if (d.drives) setDrives(d.drives)
else setPickerError(d.error ?? 'Failed to load drives')
} catch (e: any) { setPickerError(e.message) }
finally { setLoadingDrives(false) }
}
fetch('/api/admin/shape-import/browse?level=drives')
.then((r) => r.json())
.then((d) => { if (d.drives) setDrives(d.drives); else setPickerError(d.error ?? 'Failed to load document libraries') })
.catch((e) => setPickerError(e.message))
.finally(() => setLoadingDrives(false))
}, [])
const handleDriveChange = async (driveId: string) => {
setSelectedDriveId(driveId)
@ -301,29 +279,8 @@ export function ShapeImportPanel({ initialRuns }: { initialRuns: Run[] }) {
)}
</div>
{/* Site */}
<div className="space-y-1">
<Label className="text-xs">Site</Label>
<Select
value={selectedSiteId}
onValueChange={handleSiteChange}
disabled={isRunning || loadingSites}
>
<SelectTrigger className="h-8 text-sm">
{loadingSites ? (
<span className="flex items-center gap-2 text-muted-foreground">
<Loader2 className="h-3 w-3 animate-spin" /> Loading sites
</span>
) : (
<SelectValue placeholder="Select a site…" />
)}
</SelectTrigger>
<SelectContent>
{sites.map((s) => (
<SelectItem key={s.id} value={s.id}>{s.name}</SelectItem>
))}
</SelectContent>
</Select>
<div className="text-xs text-muted-foreground">
Site: <span className="font-medium text-foreground">seubert365.sharepoint.com/sites/Commercial</span>
</div>
{/* Document library (drive) */}
@ -332,7 +289,7 @@ export function ShapeImportPanel({ initialRuns }: { initialRuns: Run[] }) {
<Select
value={selectedDriveId}
onValueChange={handleDriveChange}
disabled={isRunning || loadingDrives || (!selectedSiteId && drives.length === 0)}
disabled={isRunning || loadingDrives}
>
<SelectTrigger className="h-8 text-sm">
{loadingDrives ? (
@ -340,7 +297,7 @@ export function ShapeImportPanel({ initialRuns }: { initialRuns: Run[] }) {
<Loader2 className="h-3 w-3 animate-spin" /> Loading libraries
</span>
) : (
<SelectValue placeholder={selectedSiteId ? 'Select a document library…' : 'Select a site first'} />
<SelectValue placeholder="Select a document library…" />
)}
</SelectTrigger>
<SelectContent>
@ -388,9 +345,9 @@ export function ShapeImportPanel({ initialRuns }: { initialRuns: Run[] }) {
size="sm"
className="h-6 text-xs gap-1"
onClick={() => {
setSelectedSiteId(''); setSelectedDriveId(DEFAULT_DRIVE_ID)
setSelectedDriveId(DEFAULT_DRIVE_ID)
setSelectedFolderId(''); setFolderPath(DEFAULT_FOLDER_PATH)
setDrives([]); setFolders([])
setFolders([])
}}
disabled={isRunning}
>