Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
291 lines
8.2 KiB
HTML
291 lines
8.2 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta
|
|
http-equiv="Content-Security-Policy"
|
|
content="default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' data:; connect-src 'self' https:;"
|
|
/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Dual Portal Demo Extension</title>
|
|
<style>
|
|
:root {
|
|
--bg: #f8fafc;
|
|
--card-bg: #ffffff;
|
|
--fg: #1e293b;
|
|
--fg-muted: #64748b;
|
|
--accent: #6366f1;
|
|
--accent-light: #eef2ff;
|
|
--border: #e2e8f0;
|
|
--success: #059669;
|
|
--success-bg: #ecfdf5;
|
|
--success-border: #a7f3d0;
|
|
--code-bg: #f1f5f9;
|
|
/* Portal-specific colors */
|
|
--msp-accent: #8b5cf6;
|
|
--msp-accent-light: #f5f3ff;
|
|
--client-accent: #0891b2;
|
|
--client-accent-light: #ecfeff;
|
|
}
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
body {
|
|
margin: 0;
|
|
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", "Helvetica Neue", Arial, sans-serif;
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: center;
|
|
padding: 24px;
|
|
}
|
|
body.msp-portal {
|
|
background-image:
|
|
radial-gradient(at 20% 30%, rgba(139, 92, 246, 0.08) 0%, transparent 50%),
|
|
radial-gradient(at 80% 70%, rgba(139, 92, 246, 0.04) 0%, transparent 50%);
|
|
}
|
|
body.client-portal {
|
|
background-image:
|
|
radial-gradient(at 20% 30%, rgba(8, 145, 178, 0.08) 0%, transparent 50%),
|
|
radial-gradient(at 80% 70%, rgba(8, 145, 178, 0.04) 0%, transparent 50%);
|
|
}
|
|
.card {
|
|
background: var(--card-bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 16px;
|
|
padding: 32px 40px;
|
|
max-width: 640px;
|
|
width: 100%;
|
|
box-shadow:
|
|
0 1px 3px rgba(0, 0, 0, 0.04),
|
|
0 4px 12px rgba(0, 0, 0, 0.04);
|
|
}
|
|
.header {
|
|
text-align: center;
|
|
margin-bottom: 24px;
|
|
}
|
|
.badge {
|
|
display: inline-block;
|
|
color: white;
|
|
padding: 5px 14px;
|
|
border-radius: 20px;
|
|
font-size: 11px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.5px;
|
|
text-transform: uppercase;
|
|
margin-bottom: 16px;
|
|
}
|
|
.msp-portal .badge { background: var(--msp-accent); }
|
|
.client-portal .badge { background: var(--client-accent); }
|
|
h1 {
|
|
margin: 0 0 8px;
|
|
font-size: 26px;
|
|
font-weight: 700;
|
|
color: var(--fg);
|
|
}
|
|
.subtitle {
|
|
margin: 0;
|
|
font-size: 15px;
|
|
color: var(--fg-muted);
|
|
line-height: 1.5;
|
|
}
|
|
.portal-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
margin: 20px 0;
|
|
padding: 12px;
|
|
border-radius: 10px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
.msp-portal .portal-indicator {
|
|
background: var(--msp-accent-light);
|
|
color: var(--msp-accent);
|
|
border: 1px solid rgba(139, 92, 246, 0.2);
|
|
}
|
|
.client-portal .portal-indicator {
|
|
background: var(--client-accent-light);
|
|
color: var(--client-accent);
|
|
border: 1px solid rgba(8, 145, 178, 0.2);
|
|
}
|
|
.portal-indicator svg {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
.info-box {
|
|
background: var(--accent-light);
|
|
border: 1px solid rgba(99, 102, 241, 0.2);
|
|
padding: 16px;
|
|
border-radius: 10px;
|
|
margin: 20px 0;
|
|
}
|
|
.msp-portal .info-box {
|
|
background: var(--msp-accent-light);
|
|
border-color: rgba(139, 92, 246, 0.2);
|
|
}
|
|
.client-portal .info-box {
|
|
background: var(--client-accent-light);
|
|
border-color: rgba(8, 145, 178, 0.2);
|
|
}
|
|
.info-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
margin-bottom: 8px;
|
|
font-size: 14px;
|
|
}
|
|
.info-row:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
.info-label {
|
|
color: var(--fg-muted);
|
|
font-weight: 500;
|
|
min-width: 100px;
|
|
}
|
|
.info-value {
|
|
color: var(--fg);
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
font-size: 13px;
|
|
background: var(--code-bg);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
word-break: break-all;
|
|
}
|
|
.section-title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: var(--fg);
|
|
margin: 24px 0 12px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
.feature-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 16px 0;
|
|
}
|
|
.feature-list li {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
padding: 10px 0;
|
|
border-bottom: 1px solid var(--border);
|
|
font-size: 14px;
|
|
}
|
|
.feature-list li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
.feature-list svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
flex-shrink: 0;
|
|
margin-top: 2px;
|
|
}
|
|
.msp-portal .feature-list svg { color: var(--msp-accent); }
|
|
.client-portal .feature-list svg { color: var(--client-accent); }
|
|
.handler-result {
|
|
min-height: 60px;
|
|
}
|
|
.result-box {
|
|
background: var(--success-bg);
|
|
border: 1px solid var(--success-border);
|
|
padding: 16px;
|
|
border-radius: 10px;
|
|
}
|
|
.result-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 12px;
|
|
font-weight: 600;
|
|
color: var(--success);
|
|
}
|
|
.result-header svg {
|
|
width: 18px;
|
|
height: 18px;
|
|
}
|
|
.result-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
margin-bottom: 6px;
|
|
font-size: 13px;
|
|
}
|
|
.result-row:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
.result-label {
|
|
color: var(--fg-muted);
|
|
min-width: 100px;
|
|
}
|
|
.result-value {
|
|
color: var(--fg);
|
|
}
|
|
.result-value code {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
font-size: 12px;
|
|
background: rgba(5, 150, 105, 0.1);
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
.loading {
|
|
color: var(--fg-muted);
|
|
font-style: italic;
|
|
}
|
|
.error {
|
|
color: #dc2626;
|
|
background: #fef2f2;
|
|
border: 1px solid #fecaca;
|
|
padding: 12px 16px;
|
|
border-radius: 10px;
|
|
font-size: 14px;
|
|
}
|
|
code {
|
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
font-size: 13px;
|
|
background: var(--code-bg);
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
.msp-portal code { color: var(--msp-accent); }
|
|
.client-portal code { color: var(--client-accent); }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="card">
|
|
<div class="header">
|
|
<div class="badge" id="badge">Loading...</div>
|
|
<h1>Dual Portal Demo</h1>
|
|
<p class="subtitle">
|
|
This extension works in both the <strong>MSP Portal</strong> and <strong>Client Portal</strong>.
|
|
It detects the context and renders a different UI for each.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="portal-indicator" id="portal-indicator">
|
|
<!-- Filled by JS based on detected portal -->
|
|
</div>
|
|
|
|
<div class="info-box" id="ctx">
|
|
<div class="info-row">
|
|
<span class="info-label">Extension ID</span>
|
|
<span class="info-value">Loading...</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section-title" id="features-title">Features Available</div>
|
|
<ul class="feature-list" id="features">
|
|
<!-- Filled by JS based on detected portal -->
|
|
</ul>
|
|
|
|
<div class="section-title">WASM Handler Response (via Proxy)</div>
|
|
<div class="handler-result" id="handler-result">
|
|
<span class="loading">Calling handler...</span>
|
|
</div>
|
|
</div>
|
|
<script src="./main.js" type="module"></script>
|
|
</body>
|
|
</html>
|