Skip to main content

Powertools

Experience App for Administrators

Latest version:

Changelog

Download

tip

Check this Help Center article for a well-detailed explanation on how to upload custom Experience Apps to Showpad.

  • Analytics Export: A GUI to export the Content Reporting API tables
  • SDM Admin: Structured Data Manager

Analytics Export

Every table of the content reporting API can be easily downloaded to an Excel or CSV.

Events

Other tables

SDM Admin Section

For developers, it is no longer needed to write an admin section to manage the data of the app.

The SDM Admin section provides 1 user interface that can be used for all your apps.

It is where you can define the structure of your data and where you can add / edit / remove records matching the structure you defined.

SDM: Structured Data Manager

SDM stands for Structured Data Manager and it provides a convenient way to manage structured data of your app.

Almost every Experience App uses some kind of structured data. You can store this data in AppsDB. It is not always easy to get structured data in and out of AppsDB and this is where the SDM comes into play.

Behind the scenes, all data is stored in AppsDB, but this is completely transparent to the user. Being backed by AppsDB means all content in the SDM is also available offline.

The SDM is spread over 2 components:

  • SDM Admin section: Part of Powertools: Provides a user interface to manage your data
  • SDM Consumer functions: Part of the SDK. Provides methods to use this data in an Experience App.

Schema

A Schema should be seen as a Content Type in which you can define fields. The SDM allows you to define Schemas and multiple fields per Schema in JSON Schema format.

JSON Schemas

An Article could for example be defined as:

{
"title": "Article",
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "The title for your article",
"minLength": 4,
"default": "A new article"
},
"body": {
"type": "string",
"description": "The body for your article",
"minLength": 4,
"default": "A new article body",
"format": "textarea"
}
},
"required": ["title", "body"]
}

Edit Schema

Content Store

A Content Store holds Content Store Records. You can use it any way you want, but the idea is that 1 Experience App holds 1 Content Store.

Create Content Store

The SDM allows you to define multiple Content Stores. A Content Store can hold Content Store Records of any Schema you have defined on your instance.

Content Stores

Content Store Records

Once you have defined your Schemas, the SDM allows you to create, edit and delete Content Store Records.

Records

Records

It is also possible to import and export Content Store Records in bulk.

Import

Export

SDM Consumer functions

The SDK has methods to easily get the structured content out of the SDM. Developers will love the fact that the data can be type safe. Currently following methods are provided:

SDM Setup

OAuth setup

You will need a configured OAuth client to create data in the SDM. The basics of creating OAuth clients are explained in this article. The following information should suffice:

  • Name: AppsDB Client
  • Redirect URL: https://your-domain.showpad.biz/
  • Description: OAuth client to facilitate Experience App development.
  • Website: https://your-domain.showpad.biz/
  • This client needs to: At least check:
    • AppsDB online integrations

Download, install and configure

  1. Download the Powertools
  2. Upload the Powertools app to the Showpad platform.
tip

Check this Help Center article for a well-detailed explanation on how to upload custom Experience Apps to Showpad.

  1. Fill in the clientId and the clientSecret of the OAuth client you have configured above.

    Also fill in the list of allowedEmails (as a JSON array, using single quotes) of the users that should be able to create content. An empty array means all users to whom the Experience App has been assigned will have access.

    allowedEmails: ['name1@mycompany.com','name2@mycompany.com']
caution

We strongly advice against letting this array empty.

Consume SDM data in your app

The SDK has functions to be used by developers who want to use SDM data in Experience Apps.

Get the TypeScript types of the SDM Schemas

SDM Schemas are defined in JSON Schema format format. The CLI has a function to convert those definitions to TypeScript types and print the output to the console.

npx experience-app-cli generateSdmTypes
tip

Administrators should only provide write access to people who should be able to create Schemas and content.

This can be done by adding their email addresses to the allowedEmails array in the Powertools app configuration.

Everyone who is not in this list will only be able to read content, not write.

Use SDM data in an experience app

We strongly recommend to use getRecords() and getRecordById() as much as possible as the result will immediately be typed correctly.

import { Showpad, Sdm } from '@showpad/experience-app-sdk'

// Created by the experience-app-cli generateSdmTypes
type Article {
title: string
body?: string
}

const main = async (): Promise<void> => {
// Always wait for ShowpadLib to be loaded.
await Showpad.onShowpadLibLoaded()

try {
// Gets all "Article"s from "myAppStore"
const articles = await Sdm.getRecords<Article>('mystore', 'Article')
// Every article will be typed as a "Sdm.SdmRecord<Article>".
// This means it will hold the fields as defined in the "Article" type
// enriched with the technical fields: "id", "sdmStoreId" and "sdmSchemaId".

// Gets the "Article" with id "articleId"
const article = await Sdm.getRecordById<Article>('mystore', 'articleId')
// The article will hold the same fields as above.
} catch (error) {
// Show a native error toast.
Showpad.handleErrorWithToast(error)
}
};

main()

There could be cases where you want to use getStoreRecords(). In this case, you should use type guards to correctly type your records as explained below.

import { Showpad, Sdm } from '@showpad/experience-app-sdk';

// Created by the experience-app-cli generateSdmTypes
type Article = {
title: string;
body?: string;
};

type Car = {
brand: string;
color: string;
};

const main = async (): Promise<void> => {
// Always wait for ShowpadLib to be loaded.
await Showpad.onShowpadLibLoaded();

try {
// Gets all records of a store
const records = await Sdm.getStoreRecords('mystore');
// Every record will be typed as a "Sdm.SdmRecord".
// This means it will hold the original fields as defined in the Schema
// enriched with the technical fields: "id", "sdmStoreId" and "sdmSchemaId".
//
// As a store can hold content of multiple Schemas, type guards should be used to
// know the exact type of a record. Something like:

const isArticle = (
record: Sdm.SdmRecord
): record is Sdm.SdmRecord<Article> => record.sdmSchemaId === 'Article';

const isCar = (record: Sdm.SdmRecord): record is Sdm.SdmRecord<Car> =>
record.sdmSchemaId === 'Car';

records.forEach((record) => {
if (isArticle(record)) {
// From here on record is correctly typed as a Sdm.SdmRecord<Article>
console.log(record.title);
}
if (isCar(record)) {
// From here on record is correctly typed as a Sdm.SdmRecord<Car>
console.log(record.brand);
}
});
} catch (error) {
// Show a native error toast.
Showpad.handleErrorWithToast(error);
}
};

main();