monolayer Docs
monolayer Docs
Introduction

Getting Started

Overview and setupMain Page UIImplementing TodosBuilding the Documents FeatureReports UISending realtime updatesLifecycle HooksNext Steps
Install monolayer in your AWS accountAdd a git connectorDeploy your app in monolayer

Platform

Other

Feedbackmonolayer SDK Docsmonolayer.devFAQs
Your first app

Reports UI

The final tab, Reports, introduces a new workload type: a task — background code that runs independently of the web server.

The Reports tab will have a button that triggers a background task to generate a report, upload it, and make it appear in the Documents tab.

Generate a task workload

Let's start by defining a task workload, monolayer's abstraction for asynchronous background tasks

npx monolayer add task --name upload-report

Update task code

Now, open workloads/generate-report.task.ts and replace the contents with:

workloads/upload-report.ts
import { PutObjectCommand } from "@aws-sdk/client-s3"; 
import { Task } from "@monolayer/sdk";
import documents from "./documents"; 
import { publisher } from "@/lib/broadcast/publisher"; 
import { s3Client } from "@/lib/bucket/client"; 

export type UploadReportData = {
	message: string; 
	report: { message: string }; 
};

const uploadReport = new Task<UploadReportData>(
	"upload-report",
	async ({ data }) => {
		console.log("message", data.message); 
		const key = `Report-${new Date().toISOString()}`; 
		const command = new PutObjectCommand({
			Bucket: documents.name, 
			Key: key, 
			Body: Buffer.from(data.report.message), 
		}); 
		await s3Client.send(command); 
	},
);

export default uploadReport;

Add components and actions

actions/generate-report.ts
"use server";

import uploadReport from "@/workloads/upload-report";

export async function generateReport() {
	await uploadReport.performLater({ report: { message: "hello" } });
	return true;
}
components/generate-report.tsx
"use client";

import { generateReport } from "@/actions/generate-report";
import { Button } from "./ui/button";

export function GenerateReport() {
	return (
		<Button
			variant="default"
			className="hover:cursor-pointer"
			onClick={generateReport}
		>
			Generate Report
		</Button>
	);
}

Show Generate Report in home

Finally, connect your report button to the Reports tab in your app's main page.

app/page.tsx
import { Documents } from "@/components/documents";
import DocumentsProvider from "@/components/documents/provider";
import { Upload } from "@/components/documents/upload";
import { GenerateReport } from "@/components/generate-report"; 
import { AddTodo } from "@/components/todo-list/add";
import TodosProvider from "@/components/todo-list/provider";
import { Todos } from "@/components/todo-list/todos";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { allDocuments } from "@/lib/documents";
import { allTodos } from "@/lib/todos";

export default function Home() {
	return (
		<TodosProvider todos={allTodos()}>
			<DocumentsProvider items={allDocuments()}>
				<main className="min-h-screen dark text-primary bg-slate-950 p-6">
					<div className="flex flex-col gap-10">
						<h1 className="text-2xl font-bold text-center">
							monolayer Starter
						</h1>
						<Tabs defaultValue="todos" className="items-center w-full">
							<TabsList className="w-2xs">
								<TabsTrigger value="todos">Todos</TabsTrigger>
								<TabsTrigger value="documents">Documents</TabsTrigger>
								<TabsTrigger value="reports">Reports</TabsTrigger>
							</TabsList>
							<TabsContent value="todos" className="w-full align-start">
								<div className="py-4 max-w-2xl mx-auto">
									<AddTodo />
									<Todos />
								</div>
							</TabsContent>
							<TabsContent value="documents" className="w-full align-start">
								<div className="py-4 max-w-2xl mx-auto">
									<Upload />
									<Documents />
								</div>
							</TabsContent>
							<TabsContent value="reports" className="w-full align-start">
								<div className="py-4 max-w-2xl mx-auto">
									<GenerateReport />
								</div>
							</TabsContent>
						</Tabs>
					</div>
				</main>
			</DocumentsProvider>
		</TodosProvider>
	);
}

Now, open your app and click Generate Report.

Reports tab

After a few seconds, refresh the Documents tab — you'll see a new file listed, automatically uploaded by the background task.

Reports in Documents

Building the Documents Feature

Previous Page

Sending realtime updates

Next Page

On this page

Generate a task workloadUpdate task codeAdd components and actionsShow Generate Report in home