initial
This commit is contained in:
173
ts_web/pages/upladmin-app/upladmin-app.demo.ts
Normal file
173
ts_web/pages/upladmin-app/upladmin-app.demo.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import { html } from '@design.estate/dees-element';
|
||||
import { adminState } from '../../services/admin-state.js';
|
||||
import type { IServiceStatus, IIncidentDetails, IStatusPageConfig } from '../../interfaces/index.js';
|
||||
import './upladmin-app.js';
|
||||
|
||||
// Initialize demo data
|
||||
const initDemoData = () => {
|
||||
const now = Date.now();
|
||||
|
||||
// Demo monitors
|
||||
const monitors: IServiceStatus[] = [
|
||||
{
|
||||
id: 'api-server',
|
||||
name: 'api-server',
|
||||
displayName: 'API Server',
|
||||
description: 'Main REST API backend',
|
||||
category: 'Core Services',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: now,
|
||||
uptime30d: 99.98,
|
||||
uptime90d: 99.95,
|
||||
responseTime: 45,
|
||||
dependencies: [],
|
||||
},
|
||||
{
|
||||
id: 'web-app',
|
||||
name: 'web-app',
|
||||
displayName: 'Web Application',
|
||||
description: 'Frontend web application',
|
||||
category: 'Core Services',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: now,
|
||||
uptime30d: 99.95,
|
||||
uptime90d: 99.90,
|
||||
responseTime: 120,
|
||||
dependencies: ['api-server'],
|
||||
},
|
||||
{
|
||||
id: 'database',
|
||||
name: 'database',
|
||||
displayName: 'Database',
|
||||
description: 'Primary PostgreSQL database',
|
||||
category: 'Infrastructure',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: now,
|
||||
uptime30d: 99.99,
|
||||
uptime90d: 99.98,
|
||||
responseTime: 5,
|
||||
dependencies: [],
|
||||
},
|
||||
{
|
||||
id: 'cdn',
|
||||
name: 'cdn',
|
||||
displayName: 'CDN',
|
||||
description: 'Content delivery network',
|
||||
category: 'Infrastructure',
|
||||
currentStatus: 'degraded',
|
||||
lastChecked: now,
|
||||
uptime30d: 99.85,
|
||||
uptime90d: 99.80,
|
||||
responseTime: 25,
|
||||
dependencies: [],
|
||||
},
|
||||
{
|
||||
id: 'email-service',
|
||||
name: 'email-service',
|
||||
displayName: 'Email Service',
|
||||
description: 'Transactional email delivery',
|
||||
category: 'External Services',
|
||||
currentStatus: 'operational',
|
||||
lastChecked: now,
|
||||
uptime30d: 99.90,
|
||||
uptime90d: 99.85,
|
||||
responseTime: 200,
|
||||
dependencies: [],
|
||||
},
|
||||
];
|
||||
|
||||
// Demo incidents
|
||||
const incidents: IIncidentDetails[] = [
|
||||
{
|
||||
id: 'incident-1',
|
||||
title: 'CDN Performance Degradation',
|
||||
impact: 'We are experiencing slower than normal response times from our CDN provider.',
|
||||
severity: 'minor',
|
||||
status: 'monitoring',
|
||||
affectedServices: ['cdn'],
|
||||
startTime: now - 2 * 60 * 60 * 1000, // 2 hours ago
|
||||
updates: [
|
||||
{
|
||||
id: 'update-1-1',
|
||||
status: 'investigating',
|
||||
message: 'We are investigating reports of slow load times.',
|
||||
timestamp: now - 2 * 60 * 60 * 1000,
|
||||
},
|
||||
{
|
||||
id: 'update-1-2',
|
||||
status: 'identified',
|
||||
message: 'The issue has been identified as a CDN edge node problem.',
|
||||
timestamp: now - 1 * 60 * 60 * 1000,
|
||||
},
|
||||
{
|
||||
id: 'update-1-3',
|
||||
status: 'monitoring',
|
||||
message: 'A fix has been deployed. We are monitoring the situation.',
|
||||
timestamp: now - 30 * 60 * 1000,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'incident-2',
|
||||
title: 'Scheduled Database Maintenance',
|
||||
impact: 'Routine database maintenance window.',
|
||||
severity: 'maintenance',
|
||||
status: 'resolved',
|
||||
affectedServices: ['database'],
|
||||
startTime: now - 24 * 60 * 60 * 1000,
|
||||
endTime: now - 23 * 60 * 60 * 1000,
|
||||
updates: [
|
||||
{
|
||||
id: 'update-2-1',
|
||||
status: 'investigating',
|
||||
message: 'Maintenance has begun.',
|
||||
timestamp: now - 24 * 60 * 60 * 1000,
|
||||
},
|
||||
{
|
||||
id: 'update-2-2',
|
||||
status: 'resolved',
|
||||
message: 'Maintenance completed successfully.',
|
||||
timestamp: now - 23 * 60 * 60 * 1000,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// Demo config
|
||||
const config: IStatusPageConfig = {
|
||||
theme: 'dark',
|
||||
companyName: 'uptime.link',
|
||||
companyLogo: '',
|
||||
supportEmail: 'support@uptime.link',
|
||||
showHistoricalDays: 90,
|
||||
timeZone: 'UTC',
|
||||
};
|
||||
|
||||
// Set demo data in state
|
||||
adminState.monitors = monitors;
|
||||
adminState.incidents = incidents;
|
||||
adminState.config = config;
|
||||
};
|
||||
|
||||
export const demoFunc = () => {
|
||||
// Initialize demo data
|
||||
initDemoData();
|
||||
|
||||
return html`
|
||||
<dees-demowrapper>
|
||||
<style>
|
||||
.demo-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<div class="demo-container">
|
||||
<upladmin-app></upladmin-app>
|
||||
</div>
|
||||
</dees-demowrapper>
|
||||
`;
|
||||
};
|
||||
283
ts_web/pages/upladmin-app/upladmin-app.ts
Normal file
283
ts_web/pages/upladmin-app/upladmin-app.ts
Normal file
@@ -0,0 +1,283 @@
|
||||
import {
|
||||
DeesElement,
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
cssManager,
|
||||
state,
|
||||
type TemplateResult,
|
||||
} from '@design.estate/dees-element';
|
||||
import type { DeesAppuiBase } from '@design.estate/dees-catalog';
|
||||
import { adminState } from '../../services/admin-state.js';
|
||||
import { demoFunc } from './upladmin-app.demo.js';
|
||||
|
||||
// Import components directly
|
||||
import '../../elements/upladmin-dashboard/upladmin-dashboard.js';
|
||||
import '../../elements/upladmin-monitor-list/upladmin-monitor-list.js';
|
||||
import '../../elements/upladmin-monitor-form/upladmin-monitor-form.js';
|
||||
import '../../elements/upladmin-incident-list/upladmin-incident-list.js';
|
||||
import '../../elements/upladmin-incident-form/upladmin-incident-form.js';
|
||||
import '../../elements/upladmin-incident-update/upladmin-incident-update.js';
|
||||
import '../../elements/upladmin-statuspage-config/upladmin-statuspage-config.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'upladmin-app': UpladminApp;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('upladmin-app')
|
||||
export class UpladminApp extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@state()
|
||||
accessor appuiBase: DeesAppuiBase | null = null;
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
async firstUpdated() {
|
||||
await this.updateComplete;
|
||||
this.appuiBase = this.shadowRoot!.querySelector('dees-appui-base') as DeesAppuiBase;
|
||||
|
||||
if (this.appuiBase) {
|
||||
await this.appuiBase.updateComplete;
|
||||
this.configureApp();
|
||||
}
|
||||
}
|
||||
|
||||
private configureApp() {
|
||||
if (!this.appuiBase) return;
|
||||
|
||||
const appConfig = {
|
||||
branding: {
|
||||
logoIcon: 'lucide:activity',
|
||||
logoText: 'uptime.link',
|
||||
},
|
||||
|
||||
appBar: {
|
||||
menuItems: [
|
||||
{
|
||||
name: 'File',
|
||||
action: async () => {},
|
||||
submenu: [
|
||||
{
|
||||
name: 'New Monitor',
|
||||
shortcut: 'Cmd+N',
|
||||
iconName: 'plus',
|
||||
action: async () => (window.location.hash = 'monitors/create'),
|
||||
},
|
||||
{
|
||||
name: 'New Incident',
|
||||
shortcut: 'Cmd+I',
|
||||
iconName: 'alertTriangle',
|
||||
action: async () => (window.location.hash = 'incidents/create'),
|
||||
},
|
||||
{ divider: true },
|
||||
{
|
||||
name: 'Reload Data',
|
||||
shortcut: 'Cmd+R',
|
||||
iconName: 'refreshCw',
|
||||
action: async () => this.reloadData(),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'View',
|
||||
action: async () => {},
|
||||
submenu: [
|
||||
{
|
||||
name: 'Dashboard',
|
||||
iconName: 'layoutDashboard',
|
||||
action: async () => (window.location.hash = 'dashboard'),
|
||||
},
|
||||
{
|
||||
name: 'Monitors',
|
||||
iconName: 'activity',
|
||||
action: async () => (window.location.hash = 'monitors'),
|
||||
},
|
||||
{
|
||||
name: 'Incidents',
|
||||
iconName: 'alertCircle',
|
||||
action: async () => (window.location.hash = 'incidents'),
|
||||
},
|
||||
{ divider: true },
|
||||
{
|
||||
name: 'Settings',
|
||||
iconName: 'settings',
|
||||
action: async () => (window.location.hash = 'config'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Help',
|
||||
action: async () => {},
|
||||
submenu: [
|
||||
{
|
||||
name: 'Documentation',
|
||||
iconName: 'book',
|
||||
action: async () => window.open('https://uptime.link/docs', '_blank'),
|
||||
},
|
||||
{
|
||||
name: 'API Reference',
|
||||
iconName: 'code',
|
||||
action: async () => window.open('https://uptime.link/api', '_blank'),
|
||||
},
|
||||
{ divider: true },
|
||||
{
|
||||
name: 'About uptime.link',
|
||||
iconName: 'info',
|
||||
action: async () => console.log('About'),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
breadcrumbs: 'Dashboard',
|
||||
showWindowControls: false,
|
||||
showSearch: true,
|
||||
user: {
|
||||
name: 'Admin User',
|
||||
email: 'admin@uptime.link',
|
||||
status: 'online',
|
||||
},
|
||||
profileMenuItems: [
|
||||
{
|
||||
name: 'Profile',
|
||||
iconName: 'user',
|
||||
action: async () => console.log('Profile'),
|
||||
},
|
||||
{
|
||||
name: 'Account Settings',
|
||||
iconName: 'settings',
|
||||
action: async () => (window.location.hash = 'config'),
|
||||
},
|
||||
{ divider: true },
|
||||
{
|
||||
name: 'Sign Out',
|
||||
iconName: 'logOut',
|
||||
action: async () => console.log('Sign out'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
views: [
|
||||
{
|
||||
id: 'dashboard',
|
||||
name: 'Dashboard',
|
||||
iconName: 'lucide:layoutDashboard',
|
||||
content: 'upladmin-dashboard',
|
||||
route: 'dashboard',
|
||||
},
|
||||
{
|
||||
id: 'monitors',
|
||||
name: 'Monitors',
|
||||
iconName: 'lucide:activity',
|
||||
content: 'upladmin-monitor-list',
|
||||
route: 'monitors',
|
||||
badge: adminState.monitors.length,
|
||||
},
|
||||
{
|
||||
id: 'monitor-form',
|
||||
name: 'Monitor',
|
||||
iconName: 'lucide:activity',
|
||||
content: 'upladmin-monitor-form',
|
||||
route: 'monitors/:id',
|
||||
cache: false,
|
||||
},
|
||||
{
|
||||
id: 'incidents',
|
||||
name: 'Incidents',
|
||||
iconName: 'lucide:alertCircle',
|
||||
content: 'upladmin-incident-list',
|
||||
route: 'incidents',
|
||||
badge: adminState.getActiveIncidents().length,
|
||||
badgeVariant: adminState.getActiveIncidents().length > 0 ? 'warning' : 'default',
|
||||
},
|
||||
{
|
||||
id: 'incident-form',
|
||||
name: 'Incident',
|
||||
iconName: 'lucide:alertCircle',
|
||||
content: 'upladmin-incident-form',
|
||||
route: 'incidents/:id',
|
||||
cache: false,
|
||||
},
|
||||
{
|
||||
id: 'incident-update',
|
||||
name: 'Post Update',
|
||||
iconName: 'lucide:messageSquarePlus',
|
||||
content: 'upladmin-incident-update',
|
||||
route: 'incidents/:id/update',
|
||||
cache: false,
|
||||
},
|
||||
{
|
||||
id: 'config',
|
||||
name: 'Settings',
|
||||
iconName: 'lucide:settings',
|
||||
content: 'upladmin-statuspage-config',
|
||||
route: 'config',
|
||||
},
|
||||
],
|
||||
|
||||
mainMenu: {
|
||||
sections: [
|
||||
{ name: 'Overview', views: ['dashboard'] },
|
||||
{ name: 'Management', views: ['monitors', 'incidents'] },
|
||||
],
|
||||
bottomItems: ['config'],
|
||||
},
|
||||
|
||||
defaultView: 'dashboard',
|
||||
|
||||
onViewChange: (viewId, view) => {
|
||||
console.log(`View changed to: ${viewId} (${view.name})`);
|
||||
},
|
||||
|
||||
onSearch: (query) => {
|
||||
console.log('Search query:', query);
|
||||
// Implement search functionality
|
||||
},
|
||||
};
|
||||
|
||||
this.appuiBase.configure(appConfig as any);
|
||||
|
||||
// Update badges when state changes
|
||||
this.setupStateSubscriptions();
|
||||
}
|
||||
|
||||
private setupStateSubscriptions() {
|
||||
if (!this.appuiBase) return;
|
||||
|
||||
const appui = this.appuiBase;
|
||||
|
||||
adminState.monitors$.subscribe((monitors) => {
|
||||
appui.setMainMenuBadge('monitors', monitors.length);
|
||||
});
|
||||
|
||||
adminState.incidents$.subscribe((incidents) => {
|
||||
const activeCount = incidents.filter(
|
||||
(i) => !['resolved', 'postmortem'].includes(i.status)
|
||||
).length;
|
||||
appui.setMainMenuBadge('incidents', activeCount);
|
||||
});
|
||||
}
|
||||
|
||||
private async reloadData() {
|
||||
console.log('Reloading data...');
|
||||
// Implement data reload
|
||||
}
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`<dees-appui-base></dees-appui-base>`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user