feat: YAML import on authoring page + bulk import on admin profile
Authoring page: - 'Import YAML' button next to Save/Cancel on the create form - Opens file picker for .yaml/.yml files - Imports the YAML via API, then loads it into the form for editing - Bad YAML is rejected by the API with an error message shown via toast Admin profile (own profile page): - 'Load Seed Protocols' button (loads 100 built-in seeds) - 'Import YAML Files' button (multi-file picker) - Bulk imports each file, reports count of imported vs failed - Failed files are listed with error reasons in the toast - Profile refreshes after import to show new protocols Password change: - 'Change Password' button on own profile for all users - Modal with current/new/confirm password fields - New API endpoint POST /api/auth/password All imports validate format — incorrectly formatted files are discarded and the user is informed which files failed and why.
This commit is contained in:
+30
-10
@@ -4,22 +4,15 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Protocol Droid</title>
|
||||
<link rel="icon" type="image/svg+xml" href="frontend/logo.svg">
|
||||
<link rel="icon" type="image/x-icon" href="frontend/favicon.ico">
|
||||
<link rel="apple-touch-icon" href="frontend/icon-192.png">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" href="frontend/style.css">
|
||||
<link rel="stylesheet" href="/frontend/style.css">
|
||||
<meta name="theme-color" content="#0a1929">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<div class="breadcrumb" onclick="navigate('library')">
|
||||
<img src="frontend/logo.svg" class="header-logo" alt="">
|
||||
<div class="crumb-text">
|
||||
<span><span class="prompt">$</span> protocol-droid</span>
|
||||
<span class="crumb-path" id="crumbPath"></span>
|
||||
</div>
|
||||
<span><span class="prompt">$</span> protocol-droid</span>
|
||||
<span class="crumb-path" id="crumbPath"></span>
|
||||
</div>
|
||||
<nav id="navBar">
|
||||
<a href="#library" class="active" data-view="library">PROTOCOLS</a>
|
||||
@@ -150,6 +143,8 @@
|
||||
<div class="actions">
|
||||
<button type="submit" class="btn primary">Save Protocol</button>
|
||||
<button type="button" class="btn" onclick="navigate('library')">Cancel</button>
|
||||
<button type="button" class="btn" onclick="document.getElementById('yamlImportFile').click()">Import YAML</button>
|
||||
<input type="file" id="yamlImportFile" accept=".yaml,.yml" style="display:none" onchange="importYamlToForm(event)">
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
@@ -237,6 +232,31 @@
|
||||
<!-- TOAST -->
|
||||
<div class="toast" id="toast" style="display:none"></div>
|
||||
|
||||
<!-- PASSWORD CHANGE MODAL -->
|
||||
<div class="modal-overlay" id="pwModal" style="display:none">
|
||||
<div class="modal">
|
||||
<h2>Change Password</h2>
|
||||
<form id="pwForm" onsubmit="handleChangePassword(event)">
|
||||
<div class="form-group">
|
||||
<label>Current Password</label>
|
||||
<input type="password" id="pwCurrent" required placeholder="••••••••">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>New Password</label>
|
||||
<input type="password" id="pwNew" required minlength="8" placeholder="••••••••">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Confirm New Password</label>
|
||||
<input type="password" id="pwConfirm" required minlength="8" placeholder="••••••••">
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button type="submit" class="btn primary">Change Password</button>
|
||||
<button type="button" class="btn" onclick="closePwModal()">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<script src="/frontend/app.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user