Usage examples
These examples use an authenticated sdk from Getting started. Run Kotlin calls in a coroutine and TypeScript calls in an async function. React hooks require SoliboProvider inside QueryClientProvider.
List the homes and residents of a housing community
A housing community (API: company) has sections (its homes and commercial units) and residents (the people and organisations with a role in it).
import no.solibo.oss.sdk.api.gen.models.OrganizationResident
import no.solibo.oss.sdk.api.gen.models.PersonResident
val sections = sdk.api.sections.indexSection(companyId = companyId).body()
sections.items.forEach { println("${it.hNr} ${it.identifier}") }
val residents = sdk.api.residents.indexResident(companyId = companyId).body()
residents.items.forEach { resident ->
val name = when (resident) {
is PersonResident -> resident.name.complete
is OrganizationResident -> resident.name
}
println("$name: ${resident.roles?.map { it.type }}")
}
const sections = await sdk.api.sections.indexSection({ companyId })
sections.items.forEach(section => console.log(section.hNr, section.identifier))
const residents = await sdk.api.residents.indexResident({ companyId })
residents.items.forEach(resident => {
const name = resident.type === 'solibo.residents.query.domain.PersonResident'
? resident.name.complete
: resident.name
console.log(name, resident.roles?.map(role => role.type.name))
})
In React, useSections({ companyId }) and useResidents({ companyId }) return the same lists as paged hooks.
hNr is the official dwelling number (bolignummer), for example H0301 (floor 03, unit 01); identifier is the housing community’s own display label. Each call returns the first page; see Paged lists for the rest.
Update a section
Pass the company ID in both the request and the command. The update field is hnr; create commands and responses use hNr.
import no.solibo.oss.sdk.api.gen.models.SectionType
import no.solibo.oss.sdk.api.gen.models.UpdateSectionCommand
sdk.api.sections.updateSection(
companyId = companyId,
sectionId = sectionId,
updateSectionCommand = UpdateSectionCommand(
companyId = companyId,
sectionType = SectionType.BOLIG,
hnr = "H0301",
identifier = "A-301",
),
)
import { SectionType } from '@solibo/solibo-sdk'
await sdk.api.sections.updateSection({
companyId,
sectionId,
input: { companyId, sectionType: SectionType.BOLIG, hnr: 'H0301', identifier: 'A-301' },
})
In React, the mutation hook takes the command as cmd:
import { SectionType, type Id } from '@solibo/solibo-sdk'
import { useUpdateSection } from '@solibo/solibo-react'
function UpdateSection({ companyId, sectionId }: { companyId: Id; sectionId: Id }) {
const updateSection = useUpdateSection()
return (
<>
<button
disabled={updateSection.isPending}
onClick={() => updateSection.mutate({
companyId,
sectionId,
cmd: {
companyId,
sectionType: SectionType.BOLIG,
hnr: 'H0301',
identifier: 'A-301',
},
})}
>
Save section
</button>
{updateSection.isError && <p>Could not save the section.</p>}
</>
)
}
The hook refreshes related query caches after a successful change.
Document uploads
Uploading a document with progress (Kotlin)
Pass bytes and an optional progress callback:
import no.solibo.oss.sdk.SoliboSDK
import no.solibo.oss.sdk.api.UploadDocumentRequest
import no.solibo.oss.sdk.api.UploadProgress
import no.solibo.oss.sdk.api.gen.models.DocumentType
suspend fun uploadMeetingMinutes(
sdk: SoliboSDK,
companyId: Long,
fileName: String,
bytes: ByteArray,
) {
val document =
sdk.api.documents.uploadDocument(
request = UploadDocumentRequest(
companyId = companyId,
documentType = DocumentType.MEETING,
fileName = fileName,
bytes = bytes,
contentType = "application/pdf",
),
) { progress: UploadProgress ->
println("Upload progress: ${(progress.fraction * 100).toInt()}%")
}
println("Uploaded document ${document.id} -> ${document.fileName}")
}
Uploading a private company document with the SDK facade (TypeScript)
For direct SDK calls, read the file into bytes:
import {
DocumentType,
SoliboClient,
} from '@solibo/solibo-sdk'
async function uploadMeetingMinutes(
sdk: SoliboClient,
companyId: number,
file: File,
) {
const bytes = new Int8Array(await file.arrayBuffer())
const document = await sdk.api.documents.uploadDocument({
request: {
companyId,
documentType: DocumentType.MEETING,
fileName: file.name,
bytes,
contentType: file.type || undefined,
},
onUploadProgress: (progress) => {
console.log(
`Upload ${Math.round(progress.fraction * 100)}% (${progress.loaded}/${progress.total})`,
)
},
})
console.log(`Uploaded document ${document.id}`)
return document
}
Uploading a file in React
import { useState } from 'react'
import { useUploadDocument } from '@solibo/solibo-react'
import { DocumentType } from '@solibo/solibo-sdk'
function UploadButton({ companyId, file }: { companyId: number; file: File }) {
const uploadDocument = useUploadDocument()
const [progress, setProgress] = useState(0)
const handleUpload = async () => {
await uploadDocument.mutateAsync({
companyId,
documentType: DocumentType.OTHER,
file,
onUploadProgress: ({ fraction }) => setProgress(Math.round(fraction * 100)),
})
}
return (
<>
<button onClick={handleUpload} disabled={uploadDocument.isPending}>Upload document</button>
<progress max={100} value={progress} />
{uploadDocument.isError && <p>Upload failed. Try again.</p>}
</>
)
}
Upload multiple attachments in React
Use useMultiUploadDocument() with belongsToId for resource attachments, or with parentId for a document directory.
import { DocumentType } from '@solibo/solibo-sdk'
import { useMultiUploadDocument } from '@solibo/solibo-react'
function UploadAttachments(props: {
companyId: number
conversationId: number
files: FileList
}) {
const uploadDocuments = useMultiUploadDocument()
const handleUpload = async () => {
const files = Array.from(props.files)
const results = await uploadDocuments.mutateAsync({
companyId: props.companyId,
documentType: DocumentType.CONVERSATION,
belongsToId: props.conversationId,
fileList: files,
onUploadProgress: ({ file, fraction }) => {
console.log(file.name, Math.round(fraction * 100))
},
})
const failedFiles = results.flatMap((result, index) =>
result.status === 'rejected' ? [files[index].name] : [],
)
console.log('Failed files:', failedFiles)
}
return <button onClick={handleUpload}>Upload attachments</button>
}
For an internal (board-only) conversation message, add visibility: 'INTERNAL'; otherwise the files are attached to the public conversation.
Results stay in file order; check each result’s status as described in Choosing a multi-file helper. For public conversations, use useMultiUploadPublicDocumentToConversation() with companySlug, conversationId, and fileList.
Query options without React
Use @solibo/solibo-query when your framework manages TanStack Query directly:
import { QueryClient } from '@tanstack/query-core'
import { companyByIdQueryOptions } from '@solibo/solibo-query'
const queryClient = new QueryClient()
const company = await queryClient.fetchQuery(
companyByIdQueryOptions(sdk, { id: companyId }),
)