Appearance
Data Persistence
Apps can store data in different ways. The choice of storage depends on the use case and the requirements of the app.
Canvas context
For storing data that is specific to a given canvas, the context
object can be used. Context is a JSON object that can be manipulated by the app components. The context object is persisted in the canvas and is publicly available to all components and apps to read and write.
Since context is part of the canvas, any changes to it must be persisted on the server through a request. This means it can take a while to persist.
Summary: Access context via the useCanvas
composable, which provides the activeCanvas
property and saveCanvasContext
method. Apps can read and modify specific sections of the context object using their own namespaces.
Apps DB
Apps DB is a simple key-value store that is either instance specific or user-instance specific. Each Apps DB entry is scoped to:
instance_id
: the id of CatalogIQ instance the entry belongs tostore_name
: arbitrary name of the store that can be used to group entrieskey
: the key of the entryuser_id
: the id of the user the entry belongs to (only used for user-instance specific entries)
For the full specification, check out the Apps DB REST API documentation.
Summary: Use the useAppsDb
composable to interact with Apps DB. This gives you access to methods like upsertEntry
, getEntry
, and deleteEntry
for storing and retrieving data.
Browser storage
For storing data that is specific to the user and the browser, the localStorage
can be used. localStorage
is a key-value store that is persisted in the browser and is available to the app even after the page is reloaded.
Due to its nature you can use the localStorage
object to instantly share data between different apps that are running on the page without burdening the server.
Keep in mind that localStorage
can be removed at any time, has a size limit that depends on the browser and that it is not shared between different browsers or devices.
Other browser storage mechanisms like sessionStorage
or IndexedDB
can also be used.
Summary: The Canvas UI system primarily uses VueUse's useLocalStorage
and useSessionStorage
composables for reactive browser storage. For larger datasets, IndexedDB implementation is available in some components.
External storage
Since apps are web pages, they can use any external server as a storage mechanism. Please note that in this case the app is responsible for the security and availability of the data.
Summary: Implement HTTP requests to external servers using the Fetch API or Axios. Ensure proper authentication and error handling when connecting to external services.
Implementation Examples
Canvas Context
typescript
// Access canvas context
import { useCanvas } from '@canvas-builder/composables/useCanvas'
const { saveCanvasContext, activeCanvas } = useCanvas()
// Read order data from context
const submittedOrders = computed(() =>
activeCanvas.value?.context?.omAppData?.submittedOrders || []
)
const orderReference = activeCanvas.value?.context?.omAppData?.draftOrder?.custRef || ''
// Save data to context
async function saveOrderData(draftOrder) {
await saveCanvasContext({
omAppData: {
draftOrder,
lastUpdated: new Date().toISOString()
}
})
}
Apps DB
typescript
import { useAppsDb } from '@lib/composables/appsDb.use'
import { APPS_DB } from '@lib/constants/appsDb.const'
const appsDb = useAppsDb({ pitcherInfo, restApiAxios })
// Save block overrides
async function saveBlockOverrides(blockId, overrides) {
await appsDb.upsertEntry({
store_name: APPS_DB.STORES.BLOCK_OVERRIDES,
user_id: myUser.value.id,
entry_key: `${APPS_DB.ENTRIES.BLOCK_OVERRIDES}_${blockId.toLowerCase()}`,
data: overrides,
})
}
// Get agenda items
async function getAgenda() {
const result = await appsDb.getEntry({
store_name: APPS_DB.STORES.PITCH_MASTER,
user_id: myUser.value.id,
entry_key: APPS_DB.ENTRIES.AGENDA,
})
return result?.data
}
Browser Storage
typescript
// Using VueUse for reactive localStorage
import { useLocalStorage } from '@vueuse/core'
// Smart folders path storage
const currentPath = useLocalStorage('canvas_smart-folders_current_path', [], {
serializer: {
read: (v) => JSON.parse(v || '[]'),
write: (v) => JSON.stringify(v),
},
})
// Using sessionStorage for pagination
import { useSessionStorage } from '@vueuse/core'
const pageSize = useSessionStorage('canvases-pageSize', 10)
const currentFilters = useSessionStorage('canvases-filters', {})
External Storage
typescript
// Call Pitcher API to store data
async function savePitcherData(data) {
const response = await restApiAxios.post('/api/v2/data/store', {
data_type: 'canvas_external_data',
content: JSON.stringify(data),
instance_id: pitcherInfo.instanceId
})
return response.data
}