Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,68 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { HttpMethod, httpClient, AuthenticationType } from '@activepieces/pieces-common';
import { PLACID_BASE_URL } from '../common';
import FormData from 'form-data';
export const convertFileToUrl = createAction({
auth: placidAuth,
name: 'convert_file_to_url',
displayName: 'Convert File to URL',
description: 'Convert uploaded file(s) into media URL(s) consumable by Placid templates.',
props: {
file: Property.File({
displayName: 'File',
description: 'The file to convert to a URL.',
required: true,
}),
filename: Property.ShortText({
displayName: 'Filename',
description: 'Optional custom filename for the uploaded file.',
required: false,
}),
},
async run(context) {
const { file, filename } = context.propsValue;
const formData = new FormData();
// Convert base64 to buffer for form-data
const buffer = Buffer.from(file.base64, 'base64');
formData.append('file', buffer, {
filename: filename || file.filename,
contentType: file.extension ? `application/${file.extension}` : 'application/octet-stream',
});
try {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/media`,
body: formData,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: context.auth.secret_text,
},
headers: {
...formData.getHeaders(),
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
'File upload not supported. This feature may not be available for demo accounts or may require a paid Placid plan. Please check your account permissions.',
);
}
if (error.response?.status === 413) {
throw new Error('File too large. Please check Placid file size limits.');
}
if (error.response?.status === 403) {
throw new Error(
'File upload access forbidden. This feature may require additional permissions in your Placid account.',
);
}
throw error;
}
},
});

View File

@@ -0,0 +1,81 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
import {
imageTemplateDropdown,
webhookProperty,
createNowProperty,
passthroughProperty,
templateLayersProperty,
} from '../common/props';
import { isNil } from '@activepieces/shared';
import { PlacidCreateImageRequest } from '../common';
export const createImage = createAction({
auth: placidAuth,
name: 'create_image',
displayName: 'Create Image',
description: 'Generates a dynamic image from a specified template using input data.',
props: {
template: imageTemplateDropdown,
layers: templateLayersProperty('image'),
outputDpi: Property.StaticDropdown({
displayName: 'Output DPI',
required: false,
options: {
disabled: false,
options: [
{ label: '72 DPI', value: 72 },
{ label: '150 DPI', value: 150 },
{ label: '300 DPI', value: 300 },
],
},
}),
outputFilename: Property.ShortText({
displayName: 'Output File Name',
required: false,
}),
webhook_success: webhookProperty,
create_now: createNowProperty,
passthrough: passthroughProperty,
},
async run(context) {
const { template, webhook_success, create_now, passthrough, outputDpi, outputFilename } =
context.propsValue;
const layers = context.propsValue.layers ?? {};
const modifiedLayers: Record<string, any> = {};
for (const [key, value] of Object.entries(layers)) {
if (value === '' || isNil(value)) continue;
const [mainKey, subKey] = key.split(':::');
if (!mainKey || !subKey) continue;
if (!modifiedLayers[mainKey]) {
modifiedLayers[mainKey] = {};
}
modifiedLayers[mainKey][subKey] = value;
}
const client = new PlacidClient(context.auth);
const modifications = {
...(outputFilename && { filename: outputFilename }),
...(outputDpi && { dpi: outputDpi }),
};
const request: PlacidCreateImageRequest = {
template_uuid: template,
...(modifiedLayers && { layers: modifiedLayers }),
...(webhook_success && { webhook_success }),
...(create_now !== undefined && { create_now }),
...(passthrough && { passthrough }),
...(Object.keys(modifications).length && { modifications }),
};
return await client.createImage(request);
},
});

View File

@@ -0,0 +1,86 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
import {
pdfTemplateDropdown,
webhookProperty,
createNowProperty,
passthroughProperty,
templateLayersProperty,
} from '../common/props';
import { isNil } from '@activepieces/shared';
import { PlacidCreatePdfRequest } from '../common';
export const createPdf = createAction({
auth: placidAuth,
name: 'create_pdf',
displayName: 'Create PDF',
description: 'Generates a PDF document from a specified template.',
props: {
template: pdfTemplateDropdown,
layers: templateLayersProperty('pdf'),
outputDpi: Property.StaticDropdown({
displayName: 'Output DPI',
required: false,
options: {
disabled: false,
options: [
{ label: '96 DPI', value: 96 },
{ label: '150 DPI', value: 150 },
{ label: '300 DPI', value: 300 },
],
},
}),
outputFilename: Property.ShortText({
displayName: 'Output File Name',
required: false,
}),
webhook_success: webhookProperty,
create_now: createNowProperty,
passthrough: passthroughProperty,
},
async run(context) {
const { template, outputDpi, outputFilename, webhook_success, create_now, passthrough } =
context.propsValue;
const layers = context.propsValue.layers ?? {};
const modifiedLayers: Record<string, any> = {};
for (const [key, value] of Object.entries(layers)) {
if (value === '' || isNil(value)) continue;
const [mainKey, subKey] = key.split(':::');
if (!mainKey || !subKey) continue;
if (!modifiedLayers[mainKey]) {
modifiedLayers[mainKey] = {};
}
modifiedLayers[mainKey][subKey] = value;
}
const client = new PlacidClient(context.auth);
const modifications = {
...(outputFilename && { filename: outputFilename }),
...(outputDpi && { dpi: outputDpi }),
};
// PDFs require a pages array structure
const request: PlacidCreatePdfRequest = {
pages: [
{
template_uuid: template,
...(modifiedLayers && { layers: modifiedLayers }),
},
],
...(Object.keys(modifications).length && { modifications }),
...(webhook_success && { webhook_success }),
...(create_now !== undefined && { create_now }),
...(passthrough && { passthrough }),
};
return await client.createPdf(request);
},
});

View File

@@ -0,0 +1,79 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
import {
videoTemplateDropdown,
webhookProperty,
createNowProperty,
passthroughProperty,
templateLayersProperty,
} from '../common/props';
import { isNil } from '@activepieces/shared';
import { PlacidCreateVideoRequest } from '../common';
export const createVideo = createAction({
auth: placidAuth,
name: 'create_video',
displayName: 'Create Video',
description: 'Produces a video based on a template.',
props: {
template: videoTemplateDropdown,
layers: templateLayersProperty('video'),
outputFps: Property.Number({
displayName: 'Output FPS',
required: false,
defaultValue: 25,
}),
outputFilename: Property.ShortText({
displayName: 'Output File Name',
required: false,
}),
webhook_success: webhookProperty,
create_now: createNowProperty,
passthrough: passthroughProperty,
},
async run(context) {
const { template, outputFps, outputFilename, webhook_success, create_now, passthrough } =
context.propsValue;
const layers = context.propsValue.layers ?? {};
const modifiedLayers: Record<string, any> = {};
for (const [key, value] of Object.entries(layers)) {
if (value === '' || isNil(value)) continue;
const [mainKey, subKey] = key.split(':::');
if (!mainKey || !subKey) continue;
if (!modifiedLayers[mainKey]) {
modifiedLayers[mainKey] = {};
}
modifiedLayers[mainKey][subKey] = value;
}
const client = new PlacidClient(context.auth);
const modifications = {
...(outputFilename && { filename: outputFilename }),
...(outputFps && { fps: outputFps }),
};
// Videos require a clips array structure
const request: PlacidCreateVideoRequest = {
clips: [
{
template_uuid: template,
...(modifiedLayers && { layers: modifiedLayers }),
},
],
...(Object.keys(modifications).length && { modifications }),
...(webhook_success && { webhook_success }),
...(create_now !== undefined && { create_now }),
...(passthrough && { passthrough }),
};
return await client.createVideo(request);
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
export const getImage = createAction({
auth: placidAuth,
name: 'get_image',
displayName: 'Get Image',
description: 'Retrieves a generated image by its ID.',
props: {
imageId: Property.ShortText({
displayName: 'Image ID',
description: 'The ID of the image to retrieve.',
required: true,
}),
},
async run(context) {
const { imageId } = context.propsValue;
const client = new PlacidClient(context.auth);
return await client.getImage(imageId);
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
export const getPdf = createAction({
auth: placidAuth,
name: 'get_pdf',
displayName: 'Get PDF',
description: 'Retrieves the generated PDF by its ID.',
props: {
pdfId: Property.ShortText({
displayName: 'PDF ID',
description: 'The ID of the PDF to retrieve',
required: true,
}),
},
async run(context) {
const { pdfId } = context.propsValue;
const client = new PlacidClient(context.auth);
return await client.getPdf(pdfId);
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { placidAuth } from '../../index';
import { PlacidClient } from '../common/client';
export const getVideo = createAction({
auth: placidAuth,
name: 'get_video',
displayName: 'Get Video',
description: 'Retrieves the generated video by its ID.',
props: {
videoId: Property.ShortText({
displayName: 'Video ID',
description: 'The ID of the video to retrieve.',
required: true,
}),
},
async run(context) {
const { videoId } = context.propsValue;
const client = new PlacidClient(context.auth);
return await client.getVideo(videoId);
},
});

View File

@@ -0,0 +1,266 @@
import { AuthenticationType, HttpMethod, httpClient } from '@activepieces/pieces-common';
import {
PLACID_BASE_URL,
PlacidTemplate,
PlacidImage,
PlacidCreateImageRequest,
PlacidCreatePdfRequest,
PlacidCreateVideoRequest,
} from './index';
import { AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
import { placidAuth } from '../..';
export class PlacidClient {
constructor(private apiKey: AppConnectionValueForAuthProperty<typeof placidAuth>) {}
async listTemplates(): Promise<PlacidTemplate[]> {
const templates = [];
let nextUrl: string | undefined = `${PLACID_BASE_URL}/templates`;
do {
const response = await httpClient.sendRequest({
method: HttpMethod.GET,
url: nextUrl,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const { data, links } = response.body as { data: PlacidTemplate[]; links: { next?: string } };
templates.push(...data);
nextUrl = links.next;
} while (nextUrl);
return templates;
}
async getTemplate(templateId: string): Promise<PlacidTemplate> {
const response = await httpClient.sendRequest<PlacidTemplate>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/templates/${templateId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
}
async createImage(request: PlacidCreateImageRequest): Promise<PlacidImage> {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/images`,
body: request,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const result = response.body;
// If create_now is true, poll until completion
if (request.create_now && result.status === 'queued') {
return await this.pollForCompletion(result.id, 'image');
}
return result;
}
async getImage(imageId: string): Promise<PlacidImage> {
try {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/images/${imageId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
`Image with ID ${imageId} not found. Please verify the image ID exists in your Placid account.`,
);
}
if (error.response?.status === 403) {
throw new Error(
`Access forbidden for image ID ${imageId}. This image may not belong to your account or may have been deleted.`,
);
}
if (error.response?.status === 500) {
throw new Error(
`Server error while retrieving image ID ${imageId}. Please try again later or contact support.`,
);
}
throw error;
}
}
async deleteImage(imageId: string): Promise<void> {
await httpClient.sendRequest({
method: HttpMethod.DELETE,
url: `${PLACID_BASE_URL}/images/${imageId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
}
async createPdf(request: PlacidCreatePdfRequest): Promise<PlacidImage> {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/pdfs`,
body: request,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const result = response.body;
// If create_now is true, poll until completion
if (request.create_now && result.status === 'queued') {
return await this.pollForCompletion(result.id, 'pdf');
}
return result;
}
async createVideo(request: PlacidCreateVideoRequest): Promise<PlacidImage> {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.POST,
url: `${PLACID_BASE_URL}/videos`,
body: request,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
const result = response.body;
// If create_now is true, poll until completion
if (request.create_now && result.status === 'queued') {
return await this.pollForCompletion(result.id, 'video');
}
return result;
}
async pollForCompletion(id: string, type: 'image' | 'pdf' | 'video'): Promise<PlacidImage> {
const maxAttempts = 30; // 5 minutes max (10 second intervals)
const interval = 10000; // 10 seconds
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
// Wait before polling (except first attempt)
if (attempt > 0) {
await new Promise((resolve) => setTimeout(resolve, interval));
}
// Get current status
let result: PlacidImage;
switch (type) {
case 'image':
result = await this.getImage(id);
break;
case 'pdf':
result = await this.getPdf(id);
break;
case 'video':
result = await this.getVideo(id);
break;
}
// Check if completed
if (result.status === 'finished') {
return result;
}
// Check if failed
if (result.status === 'error') {
throw new Error(`${type} generation failed: ${result.error_message || 'Unknown error'}`);
}
// Continue polling if still queued/processing
} catch (error) {
// If it's the last attempt, throw the error
if (attempt === maxAttempts - 1) {
throw new Error(`Polling timeout: ${type} generation took too long`);
}
// Otherwise, continue polling
}
}
throw new Error(`Polling timeout: ${type} generation took too long`);
}
async getPdf(pdfId: string): Promise<PlacidImage> {
try {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/pdfs/${pdfId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
`PDF with ID ${pdfId} not found. Please verify the PDF ID exists in your Placid account.`,
);
}
if (error.response?.status === 403) {
throw new Error(
`Access forbidden for PDF ID ${pdfId}. This PDF may not belong to your account or may have been deleted.`,
);
}
if (error.response?.status === 500) {
throw new Error(
`Server error while retrieving PDF ID ${pdfId}. Please try again later or contact support.`,
);
}
throw error;
}
}
async getVideo(videoId: string): Promise<PlacidImage> {
try {
const response = await httpClient.sendRequest<PlacidImage>({
method: HttpMethod.GET,
url: `${PLACID_BASE_URL}/videos/${videoId}`,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token: this.apiKey.secret_text,
},
});
return response.body;
} catch (error: any) {
if (error.response?.status === 404) {
throw new Error(
`Video with ID ${videoId} not found. Please verify the video ID exists in your Placid account.`,
);
}
if (error.response?.status === 403) {
throw new Error(
`Access forbidden for video ID ${videoId}. This video may not belong to your account or may have been deleted.`,
);
}
if (error.response?.status === 500) {
throw new Error(
`Server error while retrieving video ID ${videoId}. Please try again later or contact support.`,
);
}
throw error;
}
}
}

View File

@@ -0,0 +1,80 @@
export const PLACID_BASE_URL = 'https://api.placid.app/api/rest';
export interface PlacidTemplate {
uuid: string;
title: string;
thumbnail?: string;
width?: number;
height?: number;
tags?: string[];
custom_data?: any;
collections?: any[];
layers: PlacidLayer[];
}
export interface PlacidLayer {
name: string;
type: 'text' | 'picture' | 'shape' | 'browserframe' | 'subtitle' | 'barcode' | 'rating';
}
export interface PlacidImage {
id: string;
status: 'queued' | 'finished' | 'error';
image_url?: string;
polling_url: string;
error_message?: string;
}
export interface PlacidCreateImageRequest {
template_uuid: string;
layers?: Record<string, any>;
modifications?: {
width?: number;
height?: number;
filename?: string;
dpi?: number;
};
webhook_success?: string;
create_now?: boolean;
passthrough?: Record<string, any> | string;
}
export interface PlacidCreatePdfRequest {
pages: Array<{
template_uuid: string;
layers?: Record<string, any>;
}>;
modifications?: {
filename?: string;
quality?: number;
dpi?: number;
};
webhook_success?: string;
create_now?: boolean;
passthrough?: Record<string, any> | string;
}
export interface PlacidCreateVideoRequest {
clips: Array<{
template_uuid: string;
layers?: Record<string, any>;
}>;
modifications?: {
width?: number;
height?: number;
filename?: string;
canvas_background?: string;
fps?: number;
};
webhook_success?: string;
create_now?: boolean;
passthrough?: Record<string, any> | string;
}
export interface PlacidWebhookPayload {
id: string;
status: string;
image_url?: string;
template_uuid: string;
passthrough?: Record<string, any>;
}

View File

@@ -0,0 +1,232 @@
import { DynamicPropsValue, Property } from '@activepieces/pieces-framework';
import { PlacidClient } from './client';
import { placidAuth } from '../..';
const createTemplateDropdown = (outputType?: 'image' | 'pdf' | 'video') =>
Property.Dropdown({
auth: placidAuth,
displayName: 'Template',
description: `Select a Placid template${outputType ? ` for ${outputType} generation` : ''}`,
required: true,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
options: [],
placeholder: 'Please connect your account first',
};
}
try {
const client = new PlacidClient(auth);
const templates = await client.listTemplates();
if (!templates || templates.length === 0) {
return {
options: [],
placeholder: 'No templates found in your Placid project',
};
}
// Filter templates by tags or naming if outputType is specified
let filteredTemplates = templates;
if (outputType) {
filteredTemplates = templates.filter((template) => {
const title = template.title.toLowerCase();
const tags = template.tags?.map((tag) => tag.toLowerCase()) || [];
// Check if template title or tags indicate it's for this output type
return (
title.includes(outputType) ||
tags.includes(outputType) ||
tags.includes(`${outputType}s`) ||
// For backwards compatibility, if no specific filtering matches, include all
(!title.includes('image') &&
!title.includes('pdf') &&
!title.includes('video') &&
!tags.some((tag) =>
['image', 'pdf', 'video', 'images', 'pdfs', 'videos'].includes(tag),
))
);
});
}
// If filtering resulted in no templates, show all templates with a note
if (outputType && filteredTemplates.length === 0) {
filteredTemplates = templates;
}
return {
options: filteredTemplates.map((template) => {
return {
label: template.title,
value: template.uuid,
};
}),
};
} catch (error) {
return {
disabled: true,
options: [],
placeholder: `Failed to load templates: ${
error instanceof Error ? error.message : 'Unknown error'
}`,
};
}
},
});
// General template dropdown for all types
export const templateDropdown = createTemplateDropdown();
// Specific template dropdowns for each output type
export const imageTemplateDropdown = createTemplateDropdown('image');
export const pdfTemplateDropdown = createTemplateDropdown('pdf');
export const videoTemplateDropdown = createTemplateDropdown('video');
export const modificationsProperty = Property.Object({
displayName: 'Modifications',
description: 'Optional modifications to the generated image (width, height, filename)',
required: false,
});
export const webhookProperty = Property.ShortText({
displayName: 'Webhook URL',
description: 'Optional webhook URL to receive notification when generation is complete.',
required: false,
});
export const createNowProperty = Property.Checkbox({
displayName: 'Create Now',
description: 'Whether to create the image immediately (synchronous) or queue it (asynchronous).',
required: false,
defaultValue: false,
});
export const passthroughProperty = Property.ShortText({
displayName: 'Passthrough Text',
required: false,
});
export const templateLayersProperty = (type: string) =>
Property.DynamicProperties({
auth: placidAuth,
displayName: 'Layers',
refreshers: ['template'],
required: false,
props: async ({ auth, template }) => {
if (!auth || !template) return {};
const props: DynamicPropsValue = {};
const client = new PlacidClient(auth);
const response = await client.getTemplate(template as unknown as string);
for (const layer of response.layers) {
switch (layer.type) {
case 'text': {
props[`${layer.name}:::text`] = Property.ShortText({
displayName: `${layer.name} : Text`,
required: false,
});
props[`${layer.name}:::text_color`] = Property.ShortText({
displayName: `${layer.name} : Text Color`,
required: false,
});
props[`${layer.name}:::font`] = Property.ShortText({
displayName: `${layer.name} : Text Font`,
required: false,
});
props[`${layer.name}:::alt_text_color`] = Property.ShortText({
displayName: `${layer.name} : Alternate Text Color`,
required: false,
});
props[`${layer.name}:::alt_font`] = Property.ShortText({
displayName: `${layer.name} : Alternate Text Font`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'shape': {
props[`${layer.name}:::background_color`] = Property.ShortText({
displayName: `${layer.name} : Background Color`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'picture': {
if (type === 'video') {
props[`${layer.name}:::video`] = Property.ShortText({
displayName: `${layer.name} : Video`,
required: false,
});
}
props[`${layer.name}:::image`] = Property.ShortText({
displayName: `${layer.name} : Image`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'browserframe': {
props[`${layer.name}:::image`] = Property.ShortText({
displayName: `${layer.name} : Image`,
required: false,
});
props[`${layer.name}:::url`] = Property.ShortText({
displayName: `${layer.name} : URL Text`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'barcode': {
props[`${layer.name}:::value`] = Property.ShortText({
displayName: `${layer.name} : Value`,
required: false,
});
props[`${layer.name}:::color`] = Property.ShortText({
displayName: `${layer.name} : Color`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
case 'rating': {
props[`${layer.name}:::value`] = Property.ShortText({
displayName: `${layer.name} : Value`,
required: false,
});
props[`${layer.name}:::hide`] = Property.Checkbox({
displayName: `${layer.name} : Hide Layer`,
required: false,
});
break;
}
default:
break;
}
}
return props;
},
});