Files
klz-cables.com/scripts/rebuild-dashboards.ts

177 lines
5.4 KiB
TypeScript

import { createDirectus, rest, authentication, readDashboards, deleteDashboard, createDashboard, createPanel } from '@directus/sdk';
async function rebuildDashboards() {
const url = 'http://localhost:8059';
const email = 'marc@mintel.me';
const password = 'Tim300493.';
console.log(`🚀 Rebuilding Dashboards: ${url}`);
const client = createDirectus(url).with(authentication('json')).with(rest());
try {
await client.login(email, password);
console.log('✅ Authenticated');
// 1. Delete existing dashboard
const oldDashboards = await client.request(readDashboards());
for (const db of oldDashboards) {
console.log(`Deleting dashboard: ${db.name} (${db.id})`);
await client.request(deleteDashboard(db.id));
}
// 2. Create the "Intelligence" Dashboard
const dashboard = await client.request(createDashboard({
name: 'Feedback Operational Intelligence',
note: 'High-fidelity overview of user feedback and system status.',
icon: 'analytics',
color: '#000000'
}));
console.log(`Created Dashboard: ${dashboard.id}`);
// 3. Add Panels (Grid is 24 units wide)
// --- Row 1: Key Metrics ---
// Total
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Total Submissions',
type: 'metric',
width: 6,
height: 4,
position_x: 0,
position_y: 0,
options: {
collection: 'visual_feedback',
function: 'count',
field: 'id',
color: '#666666',
icon: 'all_inbox'
}
}));
// Open
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Pending Action',
type: 'metric',
width: 6,
height: 4,
position_x: 6,
position_y: 0,
options: {
collection: 'visual_feedback',
function: 'count',
field: 'id',
filter: { status: { _eq: 'open' } },
color: '#FF0000',
icon: 'warning'
}
}));
// Type: Bug
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Bugs Reported',
type: 'metric',
width: 6,
height: 4,
position_x: 12,
position_y: 0,
options: {
collection: 'visual_feedback',
function: 'count',
field: 'id',
filter: { type: { _eq: 'bug' } },
color: '#E91E63',
icon: 'bug_report'
}
}));
// Type: Feature
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Feature Requests',
type: 'metric',
width: 6,
height: 4,
position_x: 18,
position_y: 0,
options: {
collection: 'visual_feedback',
function: 'count',
field: 'id',
filter: { type: { _eq: 'feature' } },
color: '#4CAF50',
icon: 'lightbulb'
}
}));
// --- Row 2: Trends and Distribution ---
// Time series (Volume)
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Feedback Volume (Last 30 Days)',
type: 'chart-timeseries',
width: 16,
height: 10,
position_x: 0,
position_y: 4,
options: {
collection: 'visual_feedback',
function: 'count',
field: 'id',
group: 'date_created',
interval: 'day',
show_marker: true,
color: '#000000'
}
}));
// Category distribution (Pie)
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Type Distribution',
type: 'chart-pie',
width: 8,
height: 10,
position_x: 16,
position_y: 4,
options: {
collection: 'visual_feedback',
function: 'count',
field: 'id',
group: 'type',
donut: true,
show_labels: true
}
}));
// --- Row 3: Details ---
// Detailed List
await client.request(createPanel({
dashboard: dashboard.id as string,
name: 'Recent Feedback (High Priority)',
type: 'list',
width: 24,
height: 10,
position_x: 0,
position_y: 14,
options: {
collection: 'visual_feedback',
fields: ['user_name', 'type', 'text', 'status', 'date_created'],
sort: ['-date_created'],
limit: 10
}
}));
console.log('✅ Dashboard rebuilt successfully');
} catch (e: any) {
console.error('❌ Rebuild failed:');
console.error(e.message);
if (e.errors) console.error(JSON.stringify(e.errors, null, 2));
}
}
rebuildDashboards();