generated from coulomb/repo-seed
Add Service DoM dashboard policy page
Mirror the repo-doi/workstream-dod Observable policy pages for service-dom: read/edit view backed by GET/PUT /policy/service-dom. Add it to the Policies nav section and the State Hub reference doc. Builds clean (62 pages). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,7 @@ export default {
|
|||||||
open: false,
|
open: false,
|
||||||
pages: [
|
pages: [
|
||||||
{ name: "Repository DoI", path: "/policy/repo-doi" },
|
{ name: "Repository DoI", path: "/policy/repo-doi" },
|
||||||
|
{ name: "Service DoM", path: "/policy/service-dom" },
|
||||||
{ name: "Workstream DoD", path: "/policy/workstream-dod" },
|
{ name: "Workstream DoD", path: "/policy/workstream-dod" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -265,5 +265,6 @@ why, even years later.
|
|||||||
- [Connecting to the Hub](/docs/connecting)
|
- [Connecting to the Hub](/docs/connecting)
|
||||||
- [Repo Integration](/docs/repo-integration)
|
- [Repo Integration](/docs/repo-integration)
|
||||||
- [Repository DoI](/policy/repo-doi) — Definition of Integrated
|
- [Repository DoI](/policy/repo-doi) — Definition of Integrated
|
||||||
|
- [Service DoM](/policy/service-dom) — Definition of Mature
|
||||||
- [TPSC](/docs/tpsc) — Third-Party Services Catalog
|
- [TPSC](/docs/tpsc) — Third-Party Services Catalog
|
||||||
- [SBOM](/docs/sbom)
|
- [SBOM](/docs/sbom)
|
||||||
|
|||||||
90
dashboard/src/policy/service-dom.md
Normal file
90
dashboard/src/policy/service-dom.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
title: Service Definition of Mature (DoM)
|
||||||
|
---
|
||||||
|
|
||||||
|
```js
|
||||||
|
import {API} from "../components/config.js";
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
import {marked} from "npm:marked";
|
||||||
|
|
||||||
|
const _resp = await fetch(`${API}/policy/service-dom`);
|
||||||
|
if (!_resp.ok) throw new Error(`Failed to load policy: ${_resp.status}`);
|
||||||
|
const _policy = await _resp.json();
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
let _content = _policy.content;
|
||||||
|
let _editing = false;
|
||||||
|
|
||||||
|
const _root = display(html`<div></div>`);
|
||||||
|
|
||||||
|
async function _save(text) {
|
||||||
|
const r = await fetch(`${API}/policy/service-dom`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {"Content-Type": "application/json"},
|
||||||
|
body: JSON.stringify({content: text}),
|
||||||
|
});
|
||||||
|
if (!r.ok) throw new Error(`Save failed: ${r.status}`);
|
||||||
|
_content = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _toolbar(...nodes) {
|
||||||
|
return html`<div style="display:flex;gap:0.5rem;margin-bottom:1rem">${nodes}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _btn(label, primary = false) {
|
||||||
|
return html`<button style="
|
||||||
|
padding:0.35rem 0.9rem;border-radius:4px;cursor:pointer;font-size:13px;
|
||||||
|
background:${primary ? "#1e293b" : "#f1f5f9"};
|
||||||
|
color:${primary ? "#f8fafc" : "#1e293b"};
|
||||||
|
border:1px solid ${primary ? "#1e293b" : "#cbd5e1"};
|
||||||
|
">${label}</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _render() {
|
||||||
|
_root.innerHTML = "";
|
||||||
|
|
||||||
|
if (_editing) {
|
||||||
|
const area = html`<textarea style="
|
||||||
|
width:100%;box-sizing:border-box;height:520px;
|
||||||
|
font-family:ui-monospace,monospace;font-size:13px;line-height:1.6;
|
||||||
|
padding:0.75rem;border:1px solid #cbd5e1;border-radius:4px;
|
||||||
|
background:#f8fafc;color:#1e293b;resize:vertical;
|
||||||
|
">${_content}</textarea>`;
|
||||||
|
|
||||||
|
const saveBtn = _btn("Save", true);
|
||||||
|
const cancelBtn = _btn("Cancel");
|
||||||
|
|
||||||
|
saveBtn.onclick = async () => {
|
||||||
|
saveBtn.disabled = true;
|
||||||
|
saveBtn.textContent = "Saving…";
|
||||||
|
try {
|
||||||
|
await _save(area.value);
|
||||||
|
_editing = false;
|
||||||
|
_render();
|
||||||
|
} catch (e) {
|
||||||
|
saveBtn.disabled = false;
|
||||||
|
saveBtn.textContent = "Save";
|
||||||
|
alert(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cancelBtn.onclick = () => { _editing = false; _render(); };
|
||||||
|
|
||||||
|
_root.append(_toolbar(saveBtn, cancelBtn), area);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const editBtn = _btn("Edit");
|
||||||
|
editBtn.onclick = () => { _editing = true; _render(); };
|
||||||
|
|
||||||
|
const body = html`<div style="max-width:720px;line-height:1.7;"></div>`;
|
||||||
|
body.innerHTML = marked.parse(_content);
|
||||||
|
|
||||||
|
_root.append(_toolbar(editBtn), body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_render();
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user