A complete example tool for Power Platform Tool Box built with Vue 3, Composition API, Vite, and TypeScript.
This sample demonstrates:
-
✅ Vue 3 with Composition API and
<script setup>syntax -
✅ TypeScript with full type safety
-
✅ Vite for fast development and optimized builds
-
✅ ToolBox API Integration
- Connection management with real-time updates
- Notifications system
- Clipboard operations
- File save dialogs
- Theme detection
- Event subscription and handling
-
✅ Dataverse API Usage
- FetchXML queries
- CRUD operations (Create, Read, Update, Delete)
- Entity metadata retrieval
- Error handling
-
✅ Best Practices
- Composables (Vue's equivalent to React hooks) for API integration
- Component-based architecture with Single File Components
- Reactive state management with
refandreactive - Event-driven architecture with
emit - Clean, modern UI design
- Responsive layout
- Node.js 18 or higher
- Power Platform Tool Box desktop application
npm installnpm run buildThis compiles the TypeScript and Vue code, and outputs to the dist/ directory.
For local development with hot module replacement:
npm run devNote: The dev server will run, but ToolBox APIs will only be available when loaded within Power Platform Tool Box.
vue-sample/
├── src/
│ ├── components/
│ │ ├── ConnectionStatus.vue # Connection display component
│ │ ├── ToolboxAPIDemo.vue # ToolBox API examples
│ │ ├── DataverseAPIDemo.vue # Dataverse API examples
│ │ └── EventLog.vue # Event logging component
│ ├── composables/
│ │ └── useToolboxAPI.ts # Composables for APIs
│ ├── App.vue # Main app component
│ ├── main.ts # Vue entry point
│ ├── style.css # Global styles
│ └── vite-env.d.ts # Type definitions
├── index.html # HTML entry point
├── vite.config.ts # Vite configuration
├── tsconfig.json # TypeScript configuration
├── tsconfig.node.json # Node TypeScript configuration
├── package.json # Package configuration
└── README.md # This file
The sample includes reusable composables for API integration:
const { connection, isLoading, refreshConnection } = useConnection();- Manages Dataverse connection state with reactivity
- Automatically loads on mount
- Provides refresh function
useToolboxEvents((event, data) => {
console.log('Event:', event, data);
});- Subscribes to platform events
- Automatic setup on mount
const { logs, addLog, clearLogs } = useEventLog();- Manages event log state reactively
- Keeps last 50 entries
- Console integration
Each component is a Single File Component (SFC) with <script setup> syntax:
- ConnectionStatus.vue: Displays current Dataverse connection
- ToolboxAPIDemo.vue: Demonstrates ToolBox API features
- DataverseAPIDemo.vue: Demonstrates Dataverse CRUD and queries
- EventLog.vue: Real-time event logging with filtering
- Open Power Platform Tool Box
- Go to Tools section
- Click "Install Tool"
- Enter the path to this directory or publish to npm and use the package name
- Real-time connection information with reactive updates
- Environment type badges
- Automatic updates on connection changes
Notifications:
await window.toolboxAPI.utils.showNotification({
title: 'Success',
body: 'Operation completed',
type: 'success',
duration: 3000
});Utilities:
- Copy data to clipboard
- Get current theme (light/dark)
- Save data to file with native dialog
Query with FetchXML:
const result = await window.dataverseAPI.fetchXmlQuery(fetchXml);CRUD Operations:
// Create
const account = await window.dataverseAPI.create('account', { name: 'Test' });
// Update
await window.dataverseAPI.update('account', id, { telephone1: '555-0100' });
// Delete
await window.dataverseAPI.delete('account', id);Metadata:
const metadata = await window.dataverseAPI.getEntityMetadata('account');- Create
.vuecomponent insrc/components/ - Import and use in
App.vue - Use composables for API access
- Create composable in
src/composables/ - Follow naming convention:
use[Feature].ts - Export functions that return reactive values
This tool uses TypeScript with the @pptb/types package:
/// <reference types="@pptb/types" />
// Full type safety for APIs
const toolbox = window.toolboxAPI;
const dataverse = window.dataverseAPI;Vue components use props and emits for communication:
<script setup lang="ts">
// Receive data
const props = defineProps<{
connection: ToolBoxAPI.DataverseConnection | null;
}>();
// Send events
const emit = defineEmits<{
log: [message: string, type: string];
}>();
emit('log', 'Message', 'info');
</script>Global styles are in src/style.css. Components can include scoped styles:
<style scoped>
.component-class {
color: blue;
}
</style>npm run buildOutput goes to dist/ directory with:
- Optimized and minified JavaScript
- CSS extraction and minification
- Asset optimization
- Source maps for debugging
If you encounter TypeScript errors:
- Ensure all dependencies are installed:
npm install - Check TypeScript version:
tsc --version - Clean and rebuild:
rm -rf dist && npm run build
If reactive values don't update:
- Ensure you're using
ref()orreactive() - Access ref values with
.valuein script - No need for
.valuein template
If toolboxAPI or dataverseAPI is undefined:
- The tool must be loaded within Power Platform Tool Box
- These APIs are injected by the platform
- They are not available in standalone dev mode
If connection is null:
- Open Power Platform Tool Box
- Create a connection to a Dataverse environment
- The tool will automatically detect the connection via events
The vite.config.ts is configured for Power Platform Tool Box compatibility:
export default defineConfig({
plugins: [vue(), fixHtmlForPPTB()],
base: './', // Relative paths for embedded usage
build: {
outDir: 'dist',
assetsDir: 'assets',
rollupOptions: {
output: {
// Use IIFE format for compatibility with iframe + file:// URLs
format: 'iife',
// Bundle everything into a single file
inlineDynamicImports: true,
manualChunks: undefined,
},
},
}
});Key Configurations for PPTB:
- IIFE Format: Uses Immediately Invoked Function Expression instead of ES modules for compatibility with PPTB's iframe loading mechanism
- Single Bundle: All code and CSS bundled into one file to avoid module loading issues
- HTML Plugin: Custom plugin that:
- Removes
type="module"andcrossoriginattributes for proper loading withfile://URLs - Moves script tags from
<head>to end of<body>so DOM elements are available when IIFE executes
- Removes
This sample uses Vue 3's Composition API with <script setup>:
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
// Reactive state
const count = ref(0);
// Computed values
const doubled = computed(() => count.value * 2);
// Lifecycle hooks
onMounted(() => {
console.log('Component mounted');
});
</script>- Vue 3 Documentation
- Composition API Guide
- Vite Documentation
- TypeScript Documentation
- Tool Development Guide
- API Reference
- Power Platform Tool Box Repository
GPL-3.0 - See LICENSE file in repository root