From 89d0a7baedc5effdc4cc6545bdfd0bc552f6fa25 Mon Sep 17 00:00:00 2001 From: Jacob Mischka Date: Wed, 8 Mar 2023 12:38:29 -0600 Subject: [PATCH 1/3] Change (back) title -> label in ctx.loading APIs --- src/classes/TransactionLoadingState.ts | 16 ++++++++-------- src/examples/basic/index.ts | 8 ++++---- src/internalRpcSchema.ts | 23 ++++++++++++++++------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/classes/TransactionLoadingState.ts b/src/classes/TransactionLoadingState.ts index 8970e6f..e47c328 100644 --- a/src/classes/TransactionLoadingState.ts +++ b/src/classes/TransactionLoadingState.ts @@ -37,21 +37,21 @@ export default class TransactionLoadingState { } /** - * Kicks off a loading spinner to provide context during any long-running action work. Can also be called with a single string argument as the title, or with no arguments to display only a spinner. + * Kicks off a loading spinner to provide context during any long-running action work. Can also be called with a single string argument as the label, or with no arguments to display only a spinner. * * **Usage:** * *```typescript * await ctx.loading.start({ - * title: "Reticulating splines...", + * label: "Reticulating splines...", * }); * - * await ctx.loading.start("Title only shorthand"); + * await ctx.loading.start("Label only shorthand"); *``` */ async start(options?: string | LoadingOptions) { if (typeof options === 'string') { - options = { title: options } + options = { label: options } } else if (options === undefined) { options = {} } @@ -71,12 +71,12 @@ export default class TransactionLoadingState { * *```typescript * await ctx.loading.start({ - * title: "Something is loading", + * label: "Something is loading", * description: "Mapping all the things", * }); * * await ctx.loading.update({ - * title: "Something is loading", + * label: "Something is loading", * description: "Now reducing all the things", * }); *``` @@ -88,7 +88,7 @@ export default class TransactionLoadingState { } if (typeof options === 'string') { - options = { title: options } + options = { label: options } } else if (options === undefined) { options = {} } @@ -109,7 +109,7 @@ export default class TransactionLoadingState { * *```typescript * await ctx.loading.start({ - * title: "Migrating users", + * label: "Migrating users", * description: "Enabling edit button for selected users", * itemsInQueue: 100, * }); diff --git a/src/examples/basic/index.ts b/src/examples/basic/index.ts index fbbc55b..306df4f 100644 --- a/src/examples/basic/index.ts +++ b/src/examples/basic/index.ts @@ -391,7 +391,7 @@ const interval = new Interval({ handler: async () => { await io.display.heading('Hello from display') await ctx.loading.start({ - title: 'Waiting for external system', + label: 'Waiting for external system', }) await sleep(2000) @@ -1130,7 +1130,7 @@ const interval = new Interval({ } await ctx.loading.start({ - title: 'Fetching users...', + label: 'Fetching users...', description: 'This may take a while...', }) await sleep(1500) @@ -1479,7 +1479,7 @@ const interval = new Interval({ } await ctx.loading.start({ - title: 'Updating users', + label: 'Updating users', itemsInQueue: users.length, }) for (const _ of users) { @@ -1495,7 +1495,7 @@ const interval = new Interval({ loading_dos: async () => { const itemsInQueue = 100_000 await ctx.loading.start({ - title: 'Migrating users', + label: 'Migrating users', description: 'There are a lot, but they are very fast', itemsInQueue, }) diff --git a/src/internalRpcSchema.ts b/src/internalRpcSchema.ts index 86e595b..617097d 100644 --- a/src/internalRpcSchema.ts +++ b/src/internalRpcSchema.ts @@ -37,18 +37,25 @@ export const actionEnvironment = z.enum(['live', 'development']) export type ActionEnvironment = z.infer export const LOADING_OPTIONS = z.object({ - title: z.string().optional(), + label: z.string().optional(), description: z.string().optional(), itemsInQueue: z.number().int().optional(), }) const LOADING_STATE = z.object({ - title: z.string().optional(), + label: z.string().optional(), description: z.string().optional(), itemsInQueue: z.number().int().optional(), itemsCompleted: z.number().int().optional(), }) +const BACKWARD_COMPATIBLE_LOADING_STATE = LOADING_STATE.merge( + z.object({ + // @deprecated in favor of `label` (for real this time) + title: z.string().optional(), + }) +) + const SDK_ALERT = z.object({ minSdkVersion: z.string(), severity: z.enum(['INFO', 'WARNING', 'ERROR']), @@ -59,6 +66,9 @@ export type SdkAlert = z.infer export type LoadingOptions = z.input export type LoadingState = z.input +export type BackwardCompatibleLoadingState = z.input< + typeof BACKWARD_COMPATIBLE_LOADING_STATE +> export const ACCESS_CONTROL_DEFINITION = z.union([ z.literal('entire-organization'), @@ -308,10 +318,9 @@ export const wsServerSchema = { }, SEND_LOADING_CALL: { inputs: z.intersection( - LOADING_STATE, + BACKWARD_COMPATIBLE_LOADING_STATE, z.object({ transactionId: z.string(), - label: z.string().optional(), skipClientCall: z.boolean().optional(), }) ), @@ -466,7 +475,7 @@ export const clientSchema = { .object({ transactionId: z.string(), }) - .merge(LOADING_STATE), + .merge(BACKWARD_COMPATIBLE_LOADING_STATE), returns: z.boolean(), }, LOG: { @@ -585,5 +594,5 @@ export const hostSchema = { export type HostSchema = typeof hostSchema export type PeerConnectionInitializer = ( - inputs: z.infer -) => Promise> + inputs: z.infer<(typeof INITIALIZE_PEER_CONNECTION)['inputs']> +) => Promise> From 3e3b30f9be0959006281d8c34a9922b3f1fcf69d Mon Sep 17 00:00:00 2001 From: Jacob Mischka Date: Wed, 8 Mar 2023 13:15:54 -0600 Subject: [PATCH 2/3] Change title -> label for io.display.grid --- src/classes/IOClient.ts | 4 ++-- src/examples/basic/grid.ts | 18 +++++++++--------- src/ioSchema.ts | 16 +++++++++++++--- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/classes/IOClient.ts b/src/classes/IOClient.ts index bee18d3..523ddbd 100644 --- a/src/classes/IOClient.ts +++ b/src/classes/IOClient.ts @@ -1047,7 +1047,7 @@ export class IOClient { /** * Displays data in a grid layout. * - * Grid items can include a title, description, image, and options menu, and can optionally link to another page, action, or external URL. + * Grid items can include a label, description, image, and options menu, and can optionally link to another page, action, or external URL. * * Grid item size can be controlled using the idealColumnWidth property. Interval will calculate a column width that is as close as possible to that number while factoring in gutter size and window width. * @@ -1082,7 +1082,7 @@ export class IOClient { * }, * ], * renderItem: row => ({ - * title: row.album, + * label: row.album, * description: row.artist, * image: { * url: row.imageUrl, diff --git a/src/examples/basic/grid.ts b/src/examples/basic/grid.ts index b817bc9..66e634d 100644 --- a/src/examples/basic/grid.ts +++ b/src/examples/basic/grid.ts @@ -24,7 +24,7 @@ export const dogs = new Action({ data, idealColumnWidth: 200, renderItem: row => ({ - title: row.name, + label: row.name, description: row.description, route: 'tables/display_table', image: { @@ -49,7 +49,7 @@ export const tiktoks = new Action({ .fill(null) .map((_, i) => ({ id: i, - title: `video from ${faker.internet.userName()}`, + label: `video from ${faker.internet.userName()}`, description: faker.date.past().toLocaleString(), image: faker.image.animals(1080 / 4, 1920 / 4, true), })) @@ -58,7 +58,7 @@ export const tiktoks = new Action({ data, idealColumnWidth: 220, renderItem: row => ({ - title: row.title, + label: row.label, description: row.description, image: { url: row.image, @@ -86,7 +86,7 @@ export const no_images: IntervalActionHandler = async io => { .fill(null) .map((_, i) => ({ id: i, - title: faker.commerce.productName(), + label: faker.commerce.productName(), description: faker.commerce.price(100, 200, 0, '$'), })) @@ -156,7 +156,7 @@ export const music = new Action({ data, idealColumnWidth: 240, renderItem: row => ({ - title: row.name, + label: row.name, description: row.artists, image: { url: row.image, @@ -206,7 +206,7 @@ export const long_descriptions = new Action({ data, idealColumnWidth: 300, renderItem: row => ({ - title: row.name, + label: row.name, description: row.description, image: { url: row.image, @@ -231,7 +231,7 @@ export const empty_state = new Action({ data: data.slice(0, 0), idealColumnWidth: 300, renderItem: row => ({ - title: row.name, + label: row.name, }), }) }, @@ -248,9 +248,9 @@ export const async_grid: IntervalActionHandler = async io => { image: i % 5 === 0 ? null : faker.image.imageUrl(600, 300, 'dog', true), })) - await io.display.grid('Display users', { + await io.display.grid<(typeof allData)[0]>('Display users', { renderItem: row => ({ - title: row.name, + label: row.name, description: row.description, image: { url: row.image, diff --git a/src/ioSchema.ts b/src/ioSchema.ts index 6e0fd02..37a3a29 100644 --- a/src/ioSchema.ts +++ b/src/ioSchema.ts @@ -310,7 +310,7 @@ export const internalTableColumn = z.object({ }) export const gridItem = z.object({ - title: z.string().nullable().optional(), + label: z.string().nullable().optional(), description: z.string().nullable().optional(), image: z .object({ @@ -327,13 +327,23 @@ export const gridItem = z.object({ params: serializableRecord.optional(), }) +export const backwardCompatibleGridItem = gridItem.merge( + z.object({ + // @deprecated in favor of label + title: z.string().nullable().optional(), + }) +) + export const internalGridItem = z.object({ - data: gridItem, + data: backwardCompatibleGridItem, key: z.string(), filterValue: z.string().optional(), }) -export type GridItem = z.infer +export type GridItem = z.input +export type BackwardCompatibleGridItem = z.input< + typeof backwardCompatibleGridItem +> export type InternalGridItem = z.infer const searchResult = z.object({ From 96a618b7fa6d449a22259fd5cf311e771a16c548 Mon Sep 17 00:00:00 2001 From: Jacob Mischka Date: Fri, 10 Mar 2023 12:24:09 -0600 Subject: [PATCH 3/3] Still accept title instead of label for now, mark as deprecated --- src/classes/TransactionLoadingState.ts | 13 ++++++++----- src/components/displayGrid.ts | 5 ++++- src/internalRpcSchema.ts | 6 +++++- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/classes/TransactionLoadingState.ts b/src/classes/TransactionLoadingState.ts index e47c328..1d49645 100644 --- a/src/classes/TransactionLoadingState.ts +++ b/src/classes/TransactionLoadingState.ts @@ -1,15 +1,18 @@ -import { LoadingOptions, LoadingState } from '../internalRpcSchema' +import { + BackwardCompatibleLoadingOptions, + BackwardCompatibleLoadingState, +} from '../internalRpcSchema' import Logger from './Logger' export interface TransactionLoadingStateConfig { logger: Logger - send: (loadingState: LoadingState) => Promise + send: (loadingState: BackwardCompatibleLoadingState) => Promise } export default class TransactionLoadingState { #logger: Logger #sender: TransactionLoadingStateConfig['send'] - #state: LoadingState | undefined + #state: BackwardCompatibleLoadingState | undefined #sendTimeout: NodeJS.Timeout | null = null #sendTimeoutMs = 100 @@ -49,7 +52,7 @@ export default class TransactionLoadingState { * await ctx.loading.start("Label only shorthand"); *``` */ - async start(options?: string | LoadingOptions) { + async start(options?: string | BackwardCompatibleLoadingOptions) { if (typeof options === 'string') { options = { label: options } } else if (options === undefined) { @@ -81,7 +84,7 @@ export default class TransactionLoadingState { * }); *``` */ - async update(options?: string | LoadingOptions) { + async update(options?: string | BackwardCompatibleLoadingOptions) { if (!this.#state) { this.#logger.warn('Please call `loading.start` before `loading.update`') return this.start(options) diff --git a/src/components/displayGrid.ts b/src/components/displayGrid.ts index a0a379f..ac78f7d 100644 --- a/src/components/displayGrid.ts +++ b/src/components/displayGrid.ts @@ -6,7 +6,10 @@ type PublicProps = Omit< T_IO_PROPS<'DISPLAY_GRID'>, 'data' | 'totalRecords' | 'isAsync' > & { - renderItem: (row: Row) => GridItem + renderItem: (row: Row) => GridItem & { + /** @deprecated Please use `label` instead. */ + title?: string | null + } } & ( | { data: Row[] diff --git a/src/internalRpcSchema.ts b/src/internalRpcSchema.ts index 617097d..88ec5c4 100644 --- a/src/internalRpcSchema.ts +++ b/src/internalRpcSchema.ts @@ -51,7 +51,7 @@ const LOADING_STATE = z.object({ const BACKWARD_COMPATIBLE_LOADING_STATE = LOADING_STATE.merge( z.object({ - // @deprecated in favor of `label` (for real this time) + /** @deprecated in favor of `label` (for real this time) */ title: z.string().optional(), }) ) @@ -65,6 +65,10 @@ const SDK_ALERT = z.object({ export type SdkAlert = z.infer export type LoadingOptions = z.input +export type BackwardCompatibleLoadingOptions = LoadingOptions & { + /** @deprecated Please use `label` instead. */ + title?: string +} export type LoadingState = z.input export type BackwardCompatibleLoadingState = z.input< typeof BACKWARD_COMPATIBLE_LOADING_STATE