feat: add "Choose from Server" attachment picker to claim/preauth forms and chatbot
Native file inputs can't be pointed at a default server folder for security reasons, so instead the Browse buttons on the Claim/PreAuth/Select Procedures forms and the AI chatbot's attach button now also offer picking from previously saved Cloud Storage attachments (e.g. Copy Agent screenshots) via a new server-side picker modal, scoped per-patient on the claim forms and unscoped (recent across all patients) in the chatbot. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import { Upload, X, FilePlus } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ServerAttachmentsPickerModal } from "@/components/file-upload/server-attachments-picker-modal";
|
||||
|
||||
export type MultipleFileUploadZoneHandle = {
|
||||
getFiles: () => File[];
|
||||
@@ -25,6 +26,9 @@ interface FileUploadZoneProps {
|
||||
maxFileSizeMB?: number;
|
||||
//OPTIONAL: per-mime (or wildcard) map in MB: { "application/pdf": 10, "image/*": 2 }
|
||||
maxFileSizeByType?: Record<string, number>;
|
||||
// OPTIONAL: when set, shows a "Choose from Server" option listing this patient's
|
||||
// previously saved Cloud Storage attachments (e.g. Copy Agent screenshots)
|
||||
patientId?: number;
|
||||
}
|
||||
|
||||
export const MultipleFileUploadZone = forwardRef<
|
||||
@@ -39,12 +43,14 @@ export const MultipleFileUploadZone = forwardRef<
|
||||
maxFiles = 10,
|
||||
maxFileSizeMB = 10, // default fallback per-file size (MB)
|
||||
maxFileSizeByType, // optional per-type overrides, e.g. { "application/pdf": 10, "image/*": 2 }
|
||||
patientId,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const { toast } = useToast();
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);
|
||||
const [isServerPickerOpen, setIsServerPickerOpen] = useState(false);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const parsedAccept = acceptedFileTypes
|
||||
@@ -222,7 +228,7 @@ export const MultipleFileUploadZone = forwardRef<
|
||||
[onFilesChange]
|
||||
);
|
||||
|
||||
const handleFiles = (files: FileList | null) => {
|
||||
const handleFiles = (files: FileList | File[] | null) => {
|
||||
if (!files) return;
|
||||
|
||||
const newFiles = Array.from(files).filter(validateFile);
|
||||
@@ -439,19 +445,42 @@ export const MultipleFileUploadZone = forwardRef<
|
||||
Or click to browse files
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="default"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleBrowseClick();
|
||||
}}
|
||||
>
|
||||
Browse files
|
||||
</Button>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
variant="default"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleBrowseClick();
|
||||
}}
|
||||
>
|
||||
Choose from This Computer
|
||||
</Button>
|
||||
{patientId ? (
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setIsServerPickerOpen(true);
|
||||
}}
|
||||
>
|
||||
Choose from Server
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{patientId ? (
|
||||
<ServerAttachmentsPickerModal
|
||||
open={isServerPickerOpen}
|
||||
onClose={() => setIsServerPickerOpen(false)}
|
||||
patientId={patientId}
|
||||
onFilesSelected={(files) => handleFiles(files)}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user