Appearance
File Upload Configuration
- File: src/pages/private/admin/uploads/index.svelte
Overview
The File Upload Configuration page allows administrators to manage file upload settings, including file extensions, size limits, and file types. It provides an interface for creating, editing, and deleting upload configurations.
Data Structures
Upload Configuration Interface
ts
interface UploadConfig {
extension: string;
maxSize: string;
fileSize: string;
type: string;
id?: string;
}Core Functions
1. Upload Configuration Management
svelte
// Create upload configuration
async function createUpload(upload) {
const query = `
mutation SendData ($input: [FileUploadConfigInput!]!){
saveFileUploadConfig(
command: {input: $input}
){
success, message, code
}
}
`;
const { data, error } = await mutation<any>(query, { input: upload });
if (error) {
showError(error.message);
}
return data;
}Event Handlers
1. Form Operations
svelte
// Handle form submission
function handleEntry({ detail }: CustomEvent) {
uploads = [{
...detail,
id: uniqueId(detail.extension)
}, ...uploads];
closeForm();
}
// Close form modal
function closeForm() {
showModal = false;
activeUpload = null;
setEdit = false;
}
// Initialize edit mode
function initEdit(role) {
activeUpload = role;
setEdit = true;
showModal = true;
}
// Initialize delete operation
function initDelete(role, index) {
uploads = uploads.filter((_, i) => i !== index);
}2. Save Operations
svelte
async function handleSubmit() {
const data = uploads.map((x) => ({
extension: x.extension,
maxSize: `${x.maxSize}${x.fileSize}`,
type: x.type,
}));
await toast.promise(createUpload(data), {
loading: "Uploading files...",
success: (ret: any) => {
if (!ret?.saveFileUploadConfig?.success) {
return ret.message || "Upload failed";
}
return ret?.saveFileUploadConfig?.message || "Record added";
},
error: (error: any) => {
const errorMessage = error?.message || error;
return `Error: ${errorMessage}`;
},
});
}UI Implementation
1. Main Layout
svelte
<div class="min-w-full px-4 sm:px-6 lg:px-8">
<!-- Header -->
<div class="mb-2 sm:flex sm:items-center">
<h3 class="text-lg leading-6 font-medium text-indigo-900">Uploads</h3>
<button
on:click={(_) => (showModal = true)}
class="inline-flex items-center justify-center rounded-md border border-transparent bg-[#2d4e8c] px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-[#2d4e8c] focus:outline-none sm:w-auto"
>
Add Config
</button>
</div>
<!-- Upload Configurations Table -->
<div class="pt-4 flex flex-col sm:border-t sm:border-gray-200">
{#if busy}
<div class="flex-grow grid place-content-center my-3 py-3">
<Chasing />
</div>
{:else if !uploads.length}
<div class="grid place-content-center">
<div class="alert alert-info max-w-sm mt-3 ml-3">
There are no uploads configs to show
</div>
</div>
{:else}
<table class="min-w-full divide-y divide-gray-300">
<!-- Table Header -->
<thead class="bg-gray-50">
<tr>
<th>#</th>
<th>Extension</th>
<th>Size</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<!-- Table Body -->
<tbody class="divide-y divide-gray-200 bg-white">
{#each uploads as role, i}
<tr>
<td>{i + 1}</td>
<td>{role.extension}</td>
<td>{`${role.maxSize} ${role.fileSize}`}</td>
<td>{role.type}</td>
<td>
<!-- Action Buttons -->
<span use:tip={{ content: "Edit Upload" }}>
<Icon class="h-4 w-4" src={PencilAlt} />
</span>
<span use:tip={{ content: "Delete Upload" }}>
<Icon class="h-4 w-4" src={Trash} />
</span>
</td>
</tr>
{/each}
</tbody>
</table>
<!-- Save Button -->
<div class="flex justify-end pr-8">
<button
on:click={handleSubmit}
class="bg-[#7ab800] hover:bg-[#8cac4c] focus:ring-indigo-500 w-full inline-flex justify-center rounded-md px-4 py-2 text-base font-medium text-white border-transparent border shadow-sm sm:w-auto sm:text-sm mt-3"
>
Save Entries
</button>
</div>
{/if}
</div>
</div>2. Modal Implementation
svelte
{#if showModal}
<SideModal>
<Form
on:cancel={closeForm}
on:submit={handleEntry}
data={activeUpload}
edit={setEdit}
/>
</SideModal>
{/if}Initialization
svelte
onMount(() => {
// Check admin permissions
if (!$userInfo?.isAdmin) {
$goto("/private/dashboard");
return;
}
// Load existing configurations
if ($userInfo?.tenant.fileUploadConfig?.length) {
uploads = $userInfo.tenant.fileUploadConfig.map((x) => {
const maxSize = x.maxSize;
const fileSize = maxSize.slice(-2);
const maxSizeValue = maxSize.slice(0, -2);
return {
extension: x.extension,
type: x.type,
fileSize,
maxSize: maxSizeValue,
};
});
}
});