@samyx/preview-stacks-ui 0.35.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{ActionButton.vue_vue_type_script_setup_true_lang-pLJQfFvY.js → ActionButton.vue_vue_type_script_setup_true_lang-CB94t3xm.js} +2 -2
- package/dist/assets/{ActionButton.vue_vue_type_script_setup_true_lang-pLJQfFvY.js.map → ActionButton.vue_vue_type_script_setup_true_lang-CB94t3xm.js.map} +1 -1
- package/dist/assets/{AxesTab-Bb8UjmaR.js → AxesTab-C0OeAG-v.js} +2 -2
- package/dist/assets/{AxesTab-Bb8UjmaR.js.map → AxesTab-C0OeAG-v.js.map} +1 -1
- package/dist/assets/{ConfigTab-DLjvLYzj.js → ConfigTab-CqQK7vQl.js} +2 -2
- package/dist/assets/{ConfigTab-DLjvLYzj.js.map → ConfigTab-CqQK7vQl.js.map} +1 -1
- package/dist/assets/{ConfigView-BO_yZHja.js → ConfigView-D6Ourc5o.js} +2 -2
- package/dist/assets/{ConfigView-BO_yZHja.js.map → ConfigView-D6Ourc5o.js.map} +1 -1
- package/dist/assets/{ConflictNote.vue_vue_type_script_setup_true_lang-Bjozh4Jr.js → ConflictNote.vue_vue_type_script_setup_true_lang-BtSm_ZhU.js} +2 -2
- package/dist/assets/{ConflictNote.vue_vue_type_script_setup_true_lang-Bjozh4Jr.js.map → ConflictNote.vue_vue_type_script_setup_true_lang-BtSm_ZhU.js.map} +1 -1
- package/dist/assets/ControlView-G6A_-Og_.js +2 -0
- package/dist/assets/ControlView-G6A_-Og_.js.map +1 -0
- package/dist/assets/{DangerTab-DFtbEcU-.js → DangerTab-Cn06aqx9.js} +2 -2
- package/dist/assets/{DangerTab-DFtbEcU-.js.map → DangerTab-Cn06aqx9.js.map} +1 -1
- package/dist/assets/{DashboardView-BWa1V1EI.js → DashboardView-CpJmNcFL.js} +2 -2
- package/dist/assets/{DashboardView-BWa1V1EI.js.map → DashboardView-CpJmNcFL.js.map} +1 -1
- package/dist/assets/{DeploymentDetailView-Cs1sMvRs.js → DeploymentDetailView-CP2ANsF3.js} +2 -2
- package/dist/assets/{DeploymentDetailView-Cs1sMvRs.js.map → DeploymentDetailView-CP2ANsF3.js.map} +1 -1
- package/dist/assets/{DeploymentsView-CD84qmqw.js → DeploymentsView-CXQxjAem.js} +2 -2
- package/dist/assets/{DeploymentsView-CD84qmqw.js.map → DeploymentsView-CXQxjAem.js.map} +1 -1
- package/dist/assets/{DialogTrigger-BKNFZDUU.js → DialogTrigger-BlkbgxBa.js} +2 -2
- package/dist/assets/{DialogTrigger-BKNFZDUU.js.map → DialogTrigger-BlkbgxBa.js.map} +1 -1
- package/dist/assets/{EquivalentCommand-DSNG3Ig1.js → EquivalentCommand-CbJfYQaC.js} +2 -2
- package/dist/assets/{EquivalentCommand-DSNG3Ig1.js.map → EquivalentCommand-CbJfYQaC.js.map} +1 -1
- package/dist/assets/{ErrorNote.vue_vue_type_script_setup_true_lang-BaTXNX-q.js → ErrorNote.vue_vue_type_script_setup_true_lang-Imao12aK.js} +2 -2
- package/dist/assets/{ErrorNote.vue_vue_type_script_setup_true_lang-BaTXNX-q.js.map → ErrorNote.vue_vue_type_script_setup_true_lang-Imao12aK.js.map} +1 -1
- package/dist/assets/{HelpModal.vue_vue_type_script_setup_true_lang-BhdwErsB.js → HelpModal.vue_vue_type_script_setup_true_lang-CjoiZrMf.js} +2 -2
- package/dist/assets/{HelpModal.vue_vue_type_script_setup_true_lang-BhdwErsB.js.map → HelpModal.vue_vue_type_script_setup_true_lang-CjoiZrMf.js.map} +1 -1
- package/dist/assets/{JobDetailView-DeRVlajk.js → JobDetailView-lYBZcOSg.js} +2 -2
- package/dist/assets/{JobDetailView-DeRVlajk.js.map → JobDetailView-lYBZcOSg.js.map} +1 -1
- package/dist/assets/{JobsView-BMWq45ys.js → JobsView-CyZXyEfc.js} +2 -2
- package/dist/assets/{JobsView-BMWq45ys.js.map → JobsView-CyZXyEfc.js.map} +1 -1
- package/dist/assets/{LogViewer.vue_vue_type_script_setup_true_lang-Bj66MDSl.js → LogViewer.vue_vue_type_script_setup_true_lang-CBVTTiPn.js} +2 -2
- package/dist/assets/{LogViewer.vue_vue_type_script_setup_true_lang-Bj66MDSl.js.map → LogViewer.vue_vue_type_script_setup_true_lang-CBVTTiPn.js.map} +1 -1
- package/dist/assets/{LoginView-Docai9d6.js → LoginView-Do6LVtZ6.js} +2 -2
- package/dist/assets/{LoginView-Docai9d6.js.map → LoginView-Do6LVtZ6.js.map} +1 -1
- package/dist/assets/{LogsTab-Cfauurch.js → LogsTab-DMj2p8j8.js} +2 -2
- package/dist/assets/{LogsTab-Cfauurch.js.map → LogsTab-DMj2p8j8.js.map} +1 -1
- package/dist/assets/{NotFoundView-D7OvnAVF.js → NotFoundView-DyiW8m6P.js} +2 -2
- package/dist/assets/{NotFoundView-D7OvnAVF.js.map → NotFoundView-DyiW8m6P.js.map} +1 -1
- package/dist/assets/{NotifiersView-DPXRy0Ml.js → NotifiersView-CIWU3Ohd.js} +2 -2
- package/dist/assets/{NotifiersView-DPXRy0Ml.js.map → NotifiersView-CIWU3Ohd.js.map} +1 -1
- package/dist/assets/{OverviewTab-BKYsu11o.js → OverviewTab-tJGh_KZG.js} +2 -2
- package/dist/assets/{OverviewTab-BKYsu11o.js.map → OverviewTab-tJGh_KZG.js.map} +1 -1
- package/dist/assets/{PublicLogsView-DWtP1KLG.js → PublicLogsView-CwLsI-Nz.js} +2 -2
- package/dist/assets/{PublicLogsView-DWtP1KLG.js.map → PublicLogsView-CwLsI-Nz.js.map} +1 -1
- package/dist/assets/{RefreshButton.vue_vue_type_script_setup_true_lang-zOMuwEGt.js → RefreshButton.vue_vue_type_script_setup_true_lang-C5aXqJdu.js} +2 -2
- package/dist/assets/{RefreshButton.vue_vue_type_script_setup_true_lang-zOMuwEGt.js.map → RefreshButton.vue_vue_type_script_setup_true_lang-C5aXqJdu.js.map} +1 -1
- package/dist/assets/{RegistriesView-CXFrbpKU.js → RegistriesView-399hTPKi.js} +2 -2
- package/dist/assets/{RegistriesView-CXFrbpKU.js.map → RegistriesView-399hTPKi.js.map} +1 -1
- package/dist/assets/{RelativeTime.vue_vue_type_script_setup_true_lang-DmifGQCq.js → RelativeTime.vue_vue_type_script_setup_true_lang-ze6IGxQV.js} +2 -2
- package/dist/assets/{RelativeTime.vue_vue_type_script_setup_true_lang-DmifGQCq.js.map → RelativeTime.vue_vue_type_script_setup_true_lang-ze6IGxQV.js.map} +1 -1
- package/dist/assets/{RequiresTab-DzIjJaLx.js → RequiresTab-B53DZ6Dn.js} +2 -2
- package/dist/assets/{RequiresTab-DzIjJaLx.js.map → RequiresTab-B53DZ6Dn.js.map} +1 -1
- package/dist/assets/{RouteTarget.vue_vue_type_script_setup_true_lang-mCKpGvoV.js → RouteTarget.vue_vue_type_script_setup_true_lang-B1xfCOxN.js} +2 -2
- package/dist/assets/{RouteTarget.vue_vue_type_script_setup_true_lang-mCKpGvoV.js.map → RouteTarget.vue_vue_type_script_setup_true_lang-B1xfCOxN.js.map} +1 -1
- package/dist/assets/{RoutingView-BOH2ypa8.js → RoutingView-B5gwI-1h.js} +2 -2
- package/dist/assets/{RoutingView-BOH2ypa8.js.map → RoutingView-B5gwI-1h.js.map} +1 -1
- package/dist/assets/{RuntimeTab-DZ3MZE_K.js → RuntimeTab-B9lDbflh.js} +2 -2
- package/dist/assets/{RuntimeTab-DZ3MZE_K.js.map → RuntimeTab-B9lDbflh.js.map} +1 -1
- package/dist/assets/{SelectMenu.vue_vue_type_script_setup_true_lang-CEOgxUqO.js → SelectMenu.vue_vue_type_script_setup_true_lang-JY8m6tfk.js} +2 -2
- package/dist/assets/{SelectMenu.vue_vue_type_script_setup_true_lang-CEOgxUqO.js.map → SelectMenu.vue_vue_type_script_setup_true_lang-JY8m6tfk.js.map} +1 -1
- package/dist/assets/{SettingsView-B0DeldbW.js → SettingsView-DGor_LCJ.js} +2 -2
- package/dist/assets/{SettingsView-B0DeldbW.js.map → SettingsView-DGor_LCJ.js.map} +1 -1
- package/dist/assets/{SkeletonList.vue_vue_type_script_setup_true_lang-Veni2uNM.js → SkeletonList.vue_vue_type_script_setup_true_lang-DMvuIcZF.js} +2 -2
- package/dist/assets/{SkeletonList.vue_vue_type_script_setup_true_lang-Veni2uNM.js.map → SkeletonList.vue_vue_type_script_setup_true_lang-DMvuIcZF.js.map} +1 -1
- package/dist/assets/{SpecDetailView-CYTsg3dA.js → SpecDetailView-B0IAuWzl.js} +2 -2
- package/dist/assets/{SpecDetailView-CYTsg3dA.js.map → SpecDetailView-B0IAuWzl.js.map} +1 -1
- package/dist/assets/{SpecsView-DioO-zqq.js → SpecsView-BTD2qo9l.js} +2 -2
- package/dist/assets/{SpecsView-DioO-zqq.js.map → SpecsView-BTD2qo9l.js.map} +1 -1
- package/dist/assets/{SsoMark.vue_vue_type_script_setup_true_lang-DYn0Yyze.js → SsoMark.vue_vue_type_script_setup_true_lang-BXhQGdjJ.js} +2 -2
- package/dist/assets/{SsoMark.vue_vue_type_script_setup_true_lang-DYn0Yyze.js.map → SsoMark.vue_vue_type_script_setup_true_lang-BXhQGdjJ.js.map} +1 -1
- package/dist/assets/{SsoView-B_gXfZwB.js → SsoView-B_GrAR_X.js} +2 -2
- package/dist/assets/{SsoView-B_gXfZwB.js.map → SsoView-B_GrAR_X.js.map} +1 -1
- package/dist/assets/{StateBadge.vue_vue_type_script_setup_true_lang-DABjKwrU.js → StateBadge.vue_vue_type_script_setup_true_lang-jkd_ejVw.js} +2 -2
- package/dist/assets/{StateBadge.vue_vue_type_script_setup_true_lang-DABjKwrU.js.map → StateBadge.vue_vue_type_script_setup_true_lang-jkd_ejVw.js.map} +1 -1
- package/dist/assets/{SubmitView-D3dRZ8OV.js → SubmitView-D5UffFTS.js} +2 -2
- package/dist/assets/{SubmitView-D3dRZ8OV.js.map → SubmitView-D5UffFTS.js.map} +1 -1
- package/dist/assets/{SwarmView-_n42sP13.js → SwarmView-BG2DN4OG.js} +2 -2
- package/dist/assets/{SwarmView-_n42sP13.js.map → SwarmView-BG2DN4OG.js.map} +1 -1
- package/dist/assets/{Teleport-Cy-A7RhK.js → Teleport-DwPgOPS3.js} +3 -3
- package/dist/assets/{Teleport-Cy-A7RhK.js.map → Teleport-DwPgOPS3.js.map} +1 -1
- package/dist/assets/{TerminalTab-DdbwvvIy.js → TerminalTab-BLjzwPsG.js} +2 -2
- package/dist/assets/{TerminalTab-DdbwvvIy.js.map → TerminalTab-BLjzwPsG.js.map} +1 -1
- package/dist/assets/{UsersView-Dn9cLJCI.js → UsersView-BOGuCj7S.js} +2 -2
- package/dist/assets/{UsersView-Dn9cLJCI.js.map → UsersView-BOGuCj7S.js.map} +1 -1
- package/dist/assets/{VarEditor.vue_vue_type_script_setup_true_lang-Dyb8Lmxc.js → VarEditor.vue_vue_type_script_setup_true_lang-uS04X_Kj.js} +2 -2
- package/dist/assets/{VarEditor.vue_vue_type_script_setup_true_lang-Dyb8Lmxc.js.map → VarEditor.vue_vue_type_script_setup_true_lang-uS04X_Kj.js.map} +1 -1
- package/dist/assets/{VarIO-D7bwBO4U.js → VarIO-DkbGdmrU.js} +2 -2
- package/dist/assets/{VarIO-D7bwBO4U.js.map → VarIO-DkbGdmrU.js.map} +1 -1
- package/dist/assets/{VariablesView-CH3Ktrp1.js → VariablesView-C5XVfRcx.js} +3 -3
- package/dist/assets/{VariablesView-CH3Ktrp1.js.map → VariablesView-C5XVfRcx.js.map} +1 -1
- package/dist/assets/{index-ChQCta5r.js → index-BzdU0RNE.js} +4 -4
- package/dist/assets/{index-ChQCta5r.js.map → index-BzdU0RNE.js.map} +1 -1
- package/dist/assets/{useDeployment-DiChk3VG.js → useDeployment-D3f7oVQg.js} +2 -2
- package/dist/assets/{useDeployment-DiChk3VG.js.map → useDeployment-D3f7oVQg.js.map} +1 -1
- package/dist/index.html +4 -1
- package/package.json +1 -1
- package/dist/assets/ControlView-D-akBm65.js +0 -2
- package/dist/assets/ControlView-D-akBm65.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a0 as l,k as i,p as n,C as d,V as p,a1 as u}from"./index-
|
|
2
|
-
//# sourceMappingURL=useDeployment-
|
|
1
|
+
import{a0 as l,k as i,p as n,C as d,V as p,a1 as u}from"./index-BzdU0RNE.js";import{w as c,r as y}from"./useVars-VN9gYdR6.js";const e=l({id:"",detail:null,error:"",loading:!1,vars:[]}),f=i(()=>p(e.vars)),k=i(()=>u(e.id)),h=i(()=>{var a;return((a=e.detail)==null?void 0:a.kind)==="shared"}),b=i(()=>{var a;return(((a=e.detail)==null?void 0:a.axes)??[]).filter(s=>!s.verifiable).map(s=>s.name)});async function t(){const a=e.id;e.loading=!0;const s=await n.get(`/api/deployments/${encodeURIComponent(a)}${f.value}`);if(e.id!==a)return;if(e.loading=!1,!s.ok){e.detail=null,e.error=d(s,`GET /api/deployments/${a}`);return}e.error="";const r=s.body;e.detail={id:r.id??a,kind:r.kind==="shared"?"shared":"isolated",createdAt:r.createdAt,updatedAt:r.updatedAt,stack:typeof r.stack=="string"?r.stack:"",busy:r.busy??null,orchestrator:r.orchestrator??null,sleep:r.sleep??null,asleep:r.asleep??null,compose:r.compose?{file:r.compose.file??"?",profiles:r.compose.profiles??[],overlays:r.compose.overlays??[]}:null,requires:Array.isArray(r.requires)?r.requires:[],axes:(Array.isArray(r.axes)?r.axes:[]).map(o=>({name:o.name,hooks:Array.isArray(o.hooks)?o.hooks:[],verifiable:o.verifiable??(Array.isArray(o.hooks)&&o.hooks.includes("assert_gone"))})),env:Array.isArray(r.env)?r.env:[]}}function g(a){e.id===a&&(e.detail||e.error)||(e.id=a,e.detail=null,e.error="",e.vars=y(a),t())}function m(){c(e.id,e.vars)}function x(){m(),t()}export{x as a,e as d,h as i,t as l,g as o,m as p,k as r,b as u,f as v};
|
|
2
|
+
//# sourceMappingURL=useDeployment-D3f7oVQg.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeployment-
|
|
1
|
+
{"version":3,"file":"useDeployment-D3f7oVQg.js","sources":["../../src/composables/useDeployment.ts"],"sourcesContent":["/**\n * The deployment currently open in the detail view.\n *\n * A module singleton rather than provide/inject, because the six tabs are CHILD ROUTES: they are\n * siblings of each other and are mounted and unmounted independently, so passing the loaded\n * deployment down as a prop would mean re-fetching it on every tab change. Switching tabs must not\n * re-fetch or blank the panel — only opening a DIFFERENT deployment does.\n *\n * `vars` here are REQUEST-TIME variables, sent as `?query` on every route that resolves this\n * deployment. See `useVars.ts` for why they matter and what they can get wrong.\n */\n\nimport { computed, reactive } from 'vue';\nimport { api, problem, query } from '../api/client';\nimport type { Deployment, VarPair } from '../api/types';\nimport { readVars, writeVars } from './useVars';\nimport { rowFor } from './useControlPlane';\n\nexport const dep = reactive({\n id: '',\n detail: null as Deployment | null,\n /** The resolve failure, verbatim. It is a 400 that NAMES the missing variable. */\n error: '',\n loading: false,\n vars: [] as VarPair[],\n});\n\nexport const varsQuery = computed(() => query(dep.vars));\n\n/** The list row, which is the only place the server exposes stored `vars` and `specName` today. */\nexport const row = computed(() => rowFor(dep.id));\n\nexport const isShared = computed(() => dep.detail?.kind === 'shared');\n\nexport const unverifiableAxes = computed(() =>\n (dep.detail?.axes ?? []).filter((a) => !a.verifiable).map((a) => a.name),\n);\n\nexport async function loadDetail(): Promise<void> {\n const id = dep.id;\n dep.loading = true;\n const r = await api.get<Deployment>(`/api/deployments/${encodeURIComponent(id)}${varsQuery.value}`);\n // Navigated to another deployment while this was in flight: drop the answer rather than render\n // one deployment's spec under another's id.\n if (dep.id !== id) return;\n dep.loading = false;\n\n if (!r.ok) {\n dep.detail = null;\n dep.error = problem(r, `GET /api/deployments/${id}`);\n return;\n }\n dep.error = '';\n const b = r.body;\n dep.detail = {\n id: b.id ?? id,\n kind: b.kind === 'shared' ? 'shared' : 'isolated',\n createdAt: b.createdAt,\n updatedAt: b.updatedAt,\n stack: typeof b.stack === 'string' ? b.stack : '',\n busy: b.busy ?? null,\n orchestrator: b.orchestrator ?? null,\n sleep: b.sleep ?? null,\n asleep: b.asleep ?? null,\n compose: b.compose\n ? {\n file: b.compose.file ?? '?',\n profiles: b.compose.profiles ?? [],\n overlays: b.compose.overlays ?? [],\n }\n : null,\n requires: Array.isArray(b.requires) ? b.requires : [],\n axes: (Array.isArray(b.axes) ? b.axes : []).map((a) => ({\n name: a.name,\n hooks: Array.isArray(a.hooks) ? a.hooks : [],\n // Derive it if an older build omits the field. Defaulting to `false` would claim an axis is\n // unverifiable when it may define a perfectly good `assert_gone`.\n verifiable: a.verifiable ?? (Array.isArray(a.hooks) && a.hooks.includes('assert_gone')),\n })),\n env: Array.isArray(b.env) ? b.env : [],\n };\n}\n\n/** Point the singleton at a deployment. Resets everything a stale id could leak into the new one. */\nexport function openDeployment(id: string): void {\n if (dep.id === id && (dep.detail || dep.error)) return; // a tab change, not a navigation\n dep.id = id;\n dep.detail = null;\n dep.error = '';\n dep.vars = readVars(id);\n void loadDetail();\n}\n\nexport function persistVars(): void {\n writeVars(dep.id, dep.vars);\n}\n\nexport function applyVars(): void {\n persistVars();\n void loadDetail();\n}\n"],"names":["dep","reactive","varsQuery","computed","query","row","rowFor","isShared","_a","unverifiableAxes","a","loadDetail","id","r","api","problem","b","openDeployment","readVars","persistVars","writeVars","applyVars"],"mappings":"8HAkBO,MAAMA,EAAMC,EAAS,CAC1B,GAAI,GACJ,OAAQ,KAER,MAAO,GACP,QAAS,GACT,KAAM,CAAA,CACR,CAAC,EAEYC,EAAYC,EAAS,IAAMC,EAAMJ,EAAI,IAAI,CAAC,EAG1CK,EAAMF,EAAS,IAAMG,EAAON,EAAI,EAAE,CAAC,EAEnCO,EAAWJ,EAAS,IAAA,OAAM,QAAAK,EAAAR,EAAI,SAAJ,YAAAQ,EAAY,QAAS,SAAQ,EAEvDC,EAAmBN,EAAS,IAAA,OACtC,SAAAK,EAAAR,EAAI,SAAJ,YAAAQ,EAAY,OAAQ,CAAA,GAAI,OAAQE,GAAM,CAACA,EAAE,UAAU,EAAE,IAAKA,GAAMA,EAAE,IAAI,EACzE,EAEA,eAAsBC,GAA4B,CAChD,MAAMC,EAAKZ,EAAI,GACfA,EAAI,QAAU,GACd,MAAMa,EAAI,MAAMC,EAAI,IAAgB,oBAAoB,mBAAmBF,CAAE,CAAC,GAAGV,EAAU,KAAK,EAAE,EAGlG,GAAIF,EAAI,KAAOY,EAAI,OAGnB,GAFAZ,EAAI,QAAU,GAEV,CAACa,EAAE,GAAI,CACTb,EAAI,OAAS,KACbA,EAAI,MAAQe,EAAQF,EAAG,wBAAwBD,CAAE,EAAE,EACnD,MACF,CACAZ,EAAI,MAAQ,GACZ,MAAMgB,EAAIH,EAAE,KACZb,EAAI,OAAS,CACX,GAAIgB,EAAE,IAAMJ,EACZ,KAAMI,EAAE,OAAS,SAAW,SAAW,WACvC,UAAWA,EAAE,UACb,UAAWA,EAAE,UACb,MAAO,OAAOA,EAAE,OAAU,SAAWA,EAAE,MAAQ,GAC/C,KAAMA,EAAE,MAAQ,KAChB,aAAcA,EAAE,cAAgB,KAChC,MAAOA,EAAE,OAAS,KAClB,OAAQA,EAAE,QAAU,KACpB,QAASA,EAAE,QACP,CACE,KAAMA,EAAE,QAAQ,MAAQ,IACxB,SAAUA,EAAE,QAAQ,UAAY,CAAA,EAChC,SAAUA,EAAE,QAAQ,UAAY,CAAA,CAAC,EAEnC,KACJ,SAAU,MAAM,QAAQA,EAAE,QAAQ,EAAIA,EAAE,SAAW,CAAA,EACnD,MAAO,MAAM,QAAQA,EAAE,IAAI,EAAIA,EAAE,KAAO,CAAA,GAAI,IAAKN,IAAO,CACtD,KAAMA,EAAE,KACR,MAAO,MAAM,QAAQA,EAAE,KAAK,EAAIA,EAAE,MAAQ,CAAA,EAG1C,WAAYA,EAAE,aAAe,MAAM,QAAQA,EAAE,KAAK,GAAKA,EAAE,MAAM,SAAS,aAAa,EAAA,EACrF,EACF,IAAK,MAAM,QAAQM,EAAE,GAAG,EAAIA,EAAE,IAAM,CAAA,CAAC,CAEzC,CAGO,SAASC,EAAeL,EAAkB,CAC3CZ,EAAI,KAAOY,IAAOZ,EAAI,QAAUA,EAAI,SACxCA,EAAI,GAAKY,EACTZ,EAAI,OAAS,KACbA,EAAI,MAAQ,GACZA,EAAI,KAAOkB,EAASN,CAAE,EACjBD,EAAA,EACP,CAEO,SAASQ,GAAoB,CAClCC,EAAUpB,EAAI,GAAIA,EAAI,IAAI,CAC5B,CAEO,SAASqB,GAAkB,CAChCF,EAAA,EACKR,EAAA,CACP"}
|
package/dist/index.html
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
<!-- Matches --bg per scheme, so the browser chrome (tab bar, overscroll) agrees with the page. -->
|
|
9
9
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#0e1116" />
|
|
10
10
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f5f6f8" />
|
|
11
|
+
<meta name="description" content="pstack — the operations console for one preview host: deployments, jobs, routing and the control stack." />
|
|
12
|
+
<meta name="color-scheme" content="dark light" />
|
|
13
|
+
<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2032%2032'%3E%3Crect%20width='32'%20height='32'%20rx='7'%20fill='%230e1116'/%3E%3Crect%20x='7'%20y='7'%20width='18'%20height='4.6'%20rx='2.3'%20fill='%234a9dff'/%3E%3Crect%20x='7'%20y='13.7'%20width='18'%20height='4.6'%20rx='2.3'%20fill='%237c8798'/%3E%3Crect%20x='7'%20y='20.4'%20width='18'%20height='4.6'%20rx='2.3'%20fill='%2349525f'/%3E%3C/svg%3E">
|
|
11
14
|
<title>pstack</title>
|
|
12
15
|
<script>
|
|
13
16
|
/**
|
|
@@ -27,7 +30,7 @@
|
|
|
27
30
|
/* private mode: fall through to the OS preference */
|
|
28
31
|
}
|
|
29
32
|
</script>
|
|
30
|
-
<script type="module" crossorigin src="/assets/index-
|
|
33
|
+
<script type="module" crossorigin src="/assets/index-BzdU0RNE.js"></script>
|
|
31
34
|
<link rel="stylesheet" crossorigin href="/assets/index-B1ONXQzZ.css">
|
|
32
35
|
</head>
|
|
33
36
|
<body>
|
package/package.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as q,x as N,c as o,a as e,f as l,e as v,w as m,_ as G,z as S,g as d,F as h,r as U,E as A,t as r,u as b,R as K,a2 as P,i as V,v as z,j as u,k as H,o as n,D as J,M as Y,H as Q,p as k,C as _,U as p}from"./index-ChQCta5r.js";import{_ as x}from"./ActionButton.vue_vue_type_script_setup_true_lang-pLJQfFvY.js";import{_ as X}from"./ErrorNote.vue_vue_type_script_setup_true_lang-BaTXNX-q.js";import{_ as Z}from"./HelpModal.vue_vue_type_script_setup_true_lang-BhdwErsB.js";import{_ as ee}from"./RefreshButton.vue_vue_type_script_setup_true_lang-zOMuwEGt.js";import{_ as te}from"./SkeletonList.vue_vue_type_script_setup_true_lang-Veni2uNM.js";import"./DialogTrigger-BKNFZDUU.js";import"./Teleport-Cy-A7RhK.js";const se={class:"page-head"},ae={class:"sub"},ne={key:2,class:"panel"},le={key:0,class:"banner warn"},oe={key:1,class:"cards"},re={class:"stagger"},ie={class:"name","data-label":"service"},de={key:0,class:"badge info",title:"the container answering this page"},ue={"data-label":"image",class:"mono mute"},ce={"data-label":"state"},pe={key:0,class:"mute",style:{"font-size":"var(--t-sm)"}},ve={"data-label":"restarts"},me={key:0,class:"badge failed",title:"The kernel killed it for exceeding its memory limit. Its last restart was not a crash — it was this."},he={"data-label":"memory",class:"mono mute"},ke={"data-label":"started",class:"mute"},fe={"data-label":""},ye={key:1,class:"mute",style:{"font-size":"var(--t-sm)"},title:"The server refuses to restart the container answering this request. Restart it from the host."},ge={key:2,class:"mute",style:{"font-size":"var(--t-sm)"},title:"No compose service label, so the restart API cannot address it."},we={key:2,class:"mute"},be={key:3,class:"panel"},_e={class:"phead"},Ce={class:"dim"},Re={class:"kvlist",style:{margin:"var(--s3) 0"}},Te={class:"v mono"},$e={class:"v"},Ae={class:"v"},xe={key:0,class:"badge warn"},Ee={key:0,class:"row"},Ie={class:"dim",style:{"margin-top":"var(--s3)"}},Me={class:"field"},Se={class:"field"},Be={key:2,class:"mute"},Ne={class:"row",style:{"margin-top":"var(--s4)","align-items":"center"}},Pe={key:3,class:"mute",style:{"margin-top":"var(--s2)"}},Ue=q({__name:"ControlView",setup(Ve){const f=u(null),y=u(""),B=u(!1);async function E(){const s=await k.get("/api/control/runtime");if(B.value=!0,!s.ok){y.value=_(s,"read the control stack");return}y.value="",f.value={...s.body,containers:s.body.containers??[]}}N(E,1e4);const C=u("");async function D(s){C.value=s;const t=await k.post("/api/control/restart",{service:s});if(C.value="",!t.ok){p("error",_(t,`restart ${s}`));return}p("ok",`Restarting ${t.body.container} — back in a few seconds.`),await E()}function O(s){return s===null?"unlimited":s>=1024*1024*1024?`${(s/(1024*1024*1024)).toFixed(1)} GiB`:`${Math.round(s/(1024*1024))} MiB`}const i=u(null);async function I(){const s=await k.get("/api/tls");s.ok&&(i.value=s.body)}N(I,3e4);const M=H(()=>{var s;return(s=i.value)!=null&&s.wildcard?Math.floor((i.value.wildcard.notAfter-Date.now())/864e5):null}),g=u(""),w=u(""),R=u(!1);async function j(){R.value=!0;const s=await k.put("/api/tls/wildcard",{cert:g.value,key:w.value});if(R.value=!1,!s.ok){p("error",_(s,"store the wildcard"));return}g.value="",w.value="",p("ok","Wildcard stored — new deploys inherit it now. Redeploy the rest below."),c.value=null,await I()}const T=u(!1);async function F(){T.value=!0;const s=await k.del("/api/tls/wildcard");if(T.value=!1,!s.ok){p("error",_(s,"remove the wildcard"));return}p("ok","Removed — back to Traefik-native resolution. Redeploy the stacks below."),c.value=null,await I()}const $=u(!1),c=u(null);async function L(){$.value=!0;const s=await k.post("/api/tls/redeploy",{});if($.value=!1,!s.ok){p("error",_(s,"redeploy the stacks"));return}c.value=s.body,p("ok",`Redeploying ${s.body.started.length} stack${s.body.started.length===1?"":"s"}; ${s.body.skipped.length} skipped.`)}return(s,t)=>(n(),o("div",null,[e("div",se,[e("div",null,[e("h1",null,[t[3]||(t[3]=l(" Control stack ",-1)),v(Z,{title:"Why restarts are the headline here"},{default:m(()=>[...t[2]||(t[2]=[e("p",null,[e("b",null,"A restarting Traefik quietly breaks TLS issuance."),l(" Its certificate challenges live in process memory, so every restart abandons whatever was mid-flight — the failed attempts still count against Let's Encrypt's weekly limits, and every container on this page keeps reporting "),e("code",null,"running"),l(". A climbing restart count with an "),e("b",null,"OOM"),l(" badge is that story told in two cells. ")],-1),e("p",null,[e("b",null,"Restart is the only action, and never for pstack."),l(" The server refuses to restart its own container — it is the process answering the request, and if its image were broken, the thing that could repair this host would die with it. From the host: "),e("code",null,"docker compose -p pstack-control restart pstack"),l(". ")],-1),e("p",null,[e("b",null,"Restarting traefik drops every connection for a few seconds"),l(" — every preview, this page included. The containers themselves keep running; only routing blinks. ")],-1)])]),_:1})]),e("div",ae,[t[5]||(t[5]=l(" The machinery previews run behind, with the counters that catch it misbehaving ",-1)),v(G,{label:"where this comes from"},{default:m(()=>[...t[4]||(t[4]=[e("code",null,"docker inspect",-1),l(" over the control project's containers, every ten seconds. Restart counts and OOM flags are docker's own, since this process last recreated nothing. ",-1)])]),_:1})])]),t[6]||(t[6]=e("span",{class:"grow"},null,-1)),v(ee,{run:E})]),y.value?(n(),S(X,{key:0,text:y.value,title:"Could not read the control stack."},null,8,["text"])):d("",!0),!B.value&&!y.value?(n(),S(te,{key:1,rows:3})):f.value?(n(),o("section",ne,[t[10]||(t[10]=e("div",{class:"phead"},[e("h2",{class:"section"},"Containers")],-1)),f.value.reachable?f.value.containers.length?(n(),o("table",oe,[t[9]||(t[9]=e("thead",null,[e("tr",null,[e("th",null,"Service"),e("th",null,"Image"),e("th",null,"State"),e("th",null,"Restarts"),e("th",null,"Memory limit"),e("th",null,"Started"),e("th")])],-1)),e("tbody",re,[(n(!0),o(h,null,U(f.value.containers,(a,W)=>(n(),o("tr",{key:a.id,style:J({"--i":W})},[e("td",ie,[l(r(a.service||a.name)+" ",1),a.service==="pstack"?(n(),o("span",de,"this API")):d("",!0)]),e("td",ue,r(a.image),1),e("td",ce,[e("span",{class:A(a.state==="running"?"s-ok":"s-failed")},r(b(Y)(a.state)),3),a.health?(n(),o("span",pe," · "+r(a.health),1)):d("",!0)]),e("td",ve,[e("span",{class:A(a.restartCount>0?"badge warn":"mute")},r(a.restartCount),3),a.oomKilled?(n(),o("span",me,"OOM")):d("",!0)]),e("td",he,r(O(a.memLimitBytes)),1),e("td",ke,r(a.startedAt?b(Q)(a.startedAt):"—"),1),e("td",fe,[a.service&&a.service!=="pstack"?(n(),S(x,{key:0,variant:"ghost",pending:C.value===a.service,disabled:C.value!=="",onClick:ze=>D(a.service)},{default:m(()=>[...t[8]||(t[8]=[l(" Restart ",-1)])]),_:1},8,["pending","disabled","onClick"])):a.service==="pstack"?(n(),o("span",ye," host-only ")):(n(),o("span",ge," — "))])],4))),128))])])):(n(),o("p",we," Docker lists no control containers — on a host serving this page, that means the project label changed, not that nothing runs. ")):(n(),o("div",le,[...t[7]||(t[7]=[e("b",null,"Docker did not answer.",-1),e("p",null,"Nothing about the control stack is known right now — which is not the same as it being down.",-1)])]))])):d("",!0),i.value?(n(),o("section",be,[e("div",_e,[t[11]||(t[11]=e("h2",{class:"section"},"Certificates",-1)),t[12]||(t[12]=e("span",{class:"grow"},null,-1)),e("span",{class:A(["badge",i.value.mode==="dns-persist-01"?"ok":"info"])},r(i.value.mode),3)]),e("p",Ce,r(i.value.note),1),i.value.wildcard?(n(),o(h,{key:0},[e("ul",Re,[e("li",null,[t[13]||(t[13]=e("span",{class:"k"},"Covers",-1)),e("span",Te,r(i.value.wildcard.domains.join(", ")),1)]),e("li",null,[t[14]||(t[14]=e("span",{class:"k"},"Valid until",-1)),e("span",$e,[l(r(b(K)(i.value.wildcard.notAfter))+" ",1),e("span",{class:A(M.value!==null&&M.value<21?"badge failed":"mute")},r(M.value)+" days left",3)])]),e("li",null,[t[15]||(t[15]=e("span",{class:"k"},"Issuer",-1)),e("span",Ae,[l(r(i.value.wildcard.issuer||"unnamed")+" ",1),i.value.wildcard.selfSigned?(n(),o("span",xe,"self-signed — browsers will warn")):d("",!0)])])]),b(P)("admin")?(n(),o("div",Ee,[v(x,{variant:"danger",pending:T.value,disabled:T.value,onClick:F},{default:m(()=>[...t[16]||(t[16]=[l(" Remove wildcard ",-1)])]),_:1},8,["pending","disabled"]),t[17]||(t[17]=e("span",{class:"mute",style:{"font-size":"var(--t-sm)"}}," Stacks deployed under it then have no certificate until redeployed. ",-1))])):d("",!0)],64)):d("",!0),b(P)("admin")?(n(),o(h,{key:1},[e("p",Ie,[i.value.wildcard?(n(),o(h,{key:0},[t[18]||(t[18]=e("b",null,"Renew or replace it.",-1)),t[19]||(t[19]=l(" Paste the new pair — it overwrites both halves in place and Traefik picks it up immediately. Nothing needs redeploying for a renewal: the router labels do not change, only the certificate behind them. ",-1))],64)):(n(),o(h,{key:1},[t[20]||(t[20]=e("b",null,"Bring your own wildcard.",-1)),t[21]||(t[21]=l(" Paste a certificate for ",-1)),t[22]||(t[22]=e("span",{class:"mono"},"*.your-domain",-1)),t[23]||(t[23]=l(" and its key — previews stop ordering per-hostname certificates the moment it lands, with no re-init and no Traefik restart. ",-1))],64)),t[24]||(t[24]=l(" The key is stored 0600 and nothing ever returns it. ",-1))]),e("div",Me,[t[25]||(t[25]=e("label",{for:"tls-cert"},"Certificate (PEM, leaf first, chain after)",-1)),V(e("textarea",{id:"tls-cert","onUpdate:modelValue":t[0]||(t[0]=a=>g.value=a),rows:"5",class:"mono",spellcheck:"false",placeholder:"-----BEGIN CERTIFICATE-----"},null,512),[[z,g.value]])]),e("div",Se,[t[26]||(t[26]=e("label",{for:"tls-key"},"Private key (PEM)",-1)),V(e("textarea",{id:"tls-key","onUpdate:modelValue":t[1]||(t[1]=a=>w.value=a),rows:"4",class:"mono",spellcheck:"false",placeholder:"-----BEGIN PRIVATE KEY-----"},null,512),[[z,w.value]])]),v(x,{variant:"primary",pending:R.value,disabled:R.value||!g.value||!w.value,onClick:j},{default:m(()=>[l(r(i.value.wildcard?"Replace wildcard":"Store wildcard"),1)]),_:1},8,["pending","disabled"])],64)):i.value.wildcard?d("",!0):(n(),o("p",Be," Storing a wildcard is an admin's: it changes what every hostname on this host presents. ")),e("div",Ne,[v(x,{pending:$.value,disabled:$.value,onClick:L},{default:m(()=>[...t[27]||(t[27]=[l(" Redeploy all stacks ",-1)])]),_:1},8,["pending","disabled"]),t[28]||(t[28]=e("span",{class:"mute",style:{"font-size":"var(--t-sm)"}}," Router labels are stamped at deploy time — run this once after changing the mode. Asleep stacks are skipped; they pick the new labels up when they wake. ",-1))]),c.value?(n(),o("p",Pe,[l(" Started "+r(c.value.started.length)+" · skipped "+r(c.value.skipped.length),1),c.value.skipped.length?(n(),o(h,{key:0},[l(" ("+r(c.value.skipped.map(a=>`${a.id}: ${a.reason}`).join("; "))+")",1)],64)):d("",!0),t[29]||(t[29]=l(" — watch them under Jobs. ",-1))])):d("",!0)])):d("",!0)]))}});export{Ue as default};
|
|
2
|
-
//# sourceMappingURL=ControlView-D-akBm65.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ControlView-D-akBm65.js","sources":["../../src/views/ControlView.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The control stack as an operator debugs it — traefik, pstack, the optional advanced UI.\n *\n * The dashboard's card answers \"is it up\"; this page answers \"why did it restart\". The two columns\n * that earn it are RESTARTS and OOM: a Traefik restart silently wipes its in-memory certificate\n * challenges, so TLS stops issuing while every state here still reads `running`. That incident was\n * once diagnosed from a default certificate's timestamp; now it is a red badge on this table.\n *\n * One action, one refusal: any control service can be restarted except `pstack` itself — the\n * server refuses its own container by name, whoever asks, and this page does not offer it.\n */\nimport { computed, ref } from 'vue';\nimport { api, problem } from '../api/client';\nimport type { ControlRuntime, TlsRedeploy, TlsStatus } from '../api/types';\nimport { usePolling } from '../composables/usePolling';\nimport { can } from '../composables/useAuth';\nimport { ago, sentence, stamp } from '../composables/useFormat';\nimport { toast } from '../composables/useToasts';\nimport ActionButton from '../components/ActionButton.vue';\nimport ErrorNote from '../components/ErrorNote.vue';\nimport HelpModal from '../components/HelpModal.vue';\nimport InfoHint from '../components/InfoHint.vue';\nimport RefreshButton from '../components/RefreshButton.vue';\nimport SkeletonList from '../components/SkeletonList.vue';\n\nconst view = ref<ControlRuntime | null>(null);\nconst error = ref('');\nconst loaded = ref(false);\n\nasync function load(): Promise<void> {\n const r = await api.get<ControlRuntime>('/api/control/runtime');\n loaded.value = true;\n if (!r.ok) {\n error.value = problem(r, 'read the control stack');\n return;\n }\n error.value = '';\n view.value = { ...r.body, containers: r.body.containers ?? [] };\n}\nusePolling(load, 10_000);\n\nconst restarting = ref('');\nasync function restart(service: string): Promise<void> {\n restarting.value = service;\n const r = await api.post<{ container: string }>('/api/control/restart', { service });\n restarting.value = '';\n if (!r.ok) {\n toast('error', problem(r, `restart ${service}`));\n return;\n }\n toast('ok', `Restarting ${r.body.container} — back in a few seconds.`);\n await load();\n}\n\n/** 268435456 → \"256 MiB\"; null → \"unlimited\" (the server normalizes docker's 0 to null). */\nfunction mem(bytes: number | null): string {\n if (bytes === null) return 'unlimited';\n if (bytes >= 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GiB`;\n return `${Math.round(bytes / (1024 * 1024))} MiB`;\n}\n\n// ── the certificate mode ──────────────────────────────────────────────────────────────────────────\nconst tls = ref<TlsStatus | null>(null);\nasync function loadTls(): Promise<void> {\n const r = await api.get<TlsStatus>('/api/tls');\n if (r.ok) tls.value = r.body;\n}\nusePolling(loadTls, 30_000);\n\nconst daysLeft = computed(() => {\n if (!tls.value?.wildcard) return null;\n return Math.floor((tls.value.wildcard.notAfter - Date.now()) / 86_400_000);\n});\n\nconst certDraft = ref('');\nconst keyDraft = ref('');\nconst storing = ref(false);\nasync function storeWildcard(): Promise<void> {\n storing.value = true;\n const r = await api.put<{ wildcard: TlsWildcardShape; note: string }>('/api/tls/wildcard', {\n cert: certDraft.value,\n key: keyDraft.value,\n });\n storing.value = false;\n if (!r.ok) {\n toast('error', problem(r, 'store the wildcard'));\n return;\n }\n certDraft.value = '';\n keyDraft.value = '';\n toast('ok', 'Wildcard stored — new deploys inherit it now. Redeploy the rest below.');\n redeployed.value = null; // that summary described a run under the previous mode\n await loadTls();\n}\ntype TlsWildcardShape = NonNullable<TlsStatus['wildcard']>;\n\nconst removing = ref(false);\nasync function removeWildcard(): Promise<void> {\n removing.value = true;\n const r = await api.del<{ note: string }>('/api/tls/wildcard');\n removing.value = false;\n if (!r.ok) {\n toast('error', problem(r, 'remove the wildcard'));\n return;\n }\n toast('ok', 'Removed — back to Traefik-native resolution. Redeploy the stacks below.');\n redeployed.value = null;\n await loadTls();\n}\n\nconst redeploying = ref(false);\nconst redeployed = ref<TlsRedeploy | null>(null);\nasync function redeployAll(): Promise<void> {\n redeploying.value = true;\n const r = await api.post<TlsRedeploy>('/api/tls/redeploy', {});\n redeploying.value = false;\n if (!r.ok) {\n toast('error', problem(r, 'redeploy the stacks'));\n return;\n }\n redeployed.value = r.body;\n toast('ok', `Redeploying ${r.body.started.length} stack${r.body.started.length === 1 ? '' : 's'}; ${r.body.skipped.length} skipped.`);\n}\n</script>\n\n<template>\n <div>\n <div class=\"page-head\">\n <div>\n <h1>\n Control stack\n <HelpModal title=\"Why restarts are the headline here\">\n <p>\n <b>A restarting Traefik quietly breaks TLS issuance.</b> Its certificate challenges\n live in process memory, so every restart abandons whatever was mid-flight — the failed\n attempts still count against Let's Encrypt's weekly limits, and every container on\n this page keeps reporting <code>running</code>. A climbing restart count with an\n <b>OOM</b> badge is that story told in two cells.\n </p>\n <p>\n <b>Restart is the only action, and never for pstack.</b> The server refuses to restart\n its own container — it is the process answering the request, and if its image were\n broken, the thing that could repair this host would die with it. From the host:\n <code>docker compose -p pstack-control restart pstack</code>.\n </p>\n <p>\n <b>Restarting traefik drops every connection for a few seconds</b> — every preview,\n this page included. The containers themselves keep running; only routing blinks.\n </p>\n </HelpModal>\n </h1>\n <div class=\"sub\">\n The machinery previews run behind, with the counters that catch it misbehaving\n <InfoHint label=\"where this comes from\">\n <code>docker inspect</code> over the control project's containers, every ten seconds.\n Restart counts and OOM flags are docker's own, since this process last recreated nothing.\n </InfoHint>\n </div>\n </div>\n <span class=\"grow\" />\n <RefreshButton :run=\"load\" />\n </div>\n\n <ErrorNote v-if=\"error\" :text=\"error\" title=\"Could not read the control stack.\" />\n\n <SkeletonList v-if=\"!loaded && !error\" :rows=\"3\" />\n\n <section v-else-if=\"view\" class=\"panel\">\n <div class=\"phead\">\n <h2 class=\"section\">Containers</h2>\n </div>\n\n <!-- Unknown is not \"empty\": a dead docker means NOTHING here is known. -->\n <div v-if=\"!view.reachable\" class=\"banner warn\">\n <b>Docker did not answer.</b>\n <p>Nothing about the control stack is known right now — which is not the same as it being down.</p>\n </div>\n <table v-else-if=\"view.containers.length\" class=\"cards\">\n <thead>\n <tr>\n <th>Service</th>\n <th>Image</th>\n <th>State</th>\n <th>Restarts</th>\n <th>Memory limit</th>\n <th>Started</th>\n <th></th>\n </tr>\n </thead>\n <tbody class=\"stagger\">\n <tr v-for=\"(c, i) in view.containers\" :key=\"c.id\" :style=\"{ '--i': i }\">\n <td class=\"name\" data-label=\"service\">\n {{ c.service || c.name }}\n <span v-if=\"c.service === 'pstack'\" class=\"badge info\" title=\"the container answering this page\">this API</span>\n </td>\n <td data-label=\"image\" class=\"mono mute\">{{ c.image }}</td>\n <td data-label=\"state\">\n <span :class=\"c.state === 'running' ? 's-ok' : 's-failed'\">{{ sentence(c.state) }}</span>\n <span v-if=\"c.health\" class=\"mute\" style=\"font-size: var(--t-sm)\"> · {{ c.health }}</span>\n </td>\n <td data-label=\"restarts\">\n <span :class=\"c.restartCount > 0 ? 'badge warn' : 'mute'\">{{ c.restartCount }}</span>\n <span\n v-if=\"c.oomKilled\"\n class=\"badge failed\"\n title=\"The kernel killed it for exceeding its memory limit. Its last restart was not a crash — it was this.\"\n >OOM</span\n >\n </td>\n <td data-label=\"memory\" class=\"mono mute\">{{ mem(c.memLimitBytes) }}</td>\n <td data-label=\"started\" class=\"mute\">{{ c.startedAt ? ago(c.startedAt) : '—' }}</td>\n <td data-label=\"\">\n <ActionButton\n v-if=\"c.service && c.service !== 'pstack'\"\n variant=\"ghost\"\n :pending=\"restarting === c.service\"\n :disabled=\"restarting !== ''\"\n @click=\"restart(c.service)\"\n >\n Restart\n </ActionButton>\n <span\n v-else-if=\"c.service === 'pstack'\"\n class=\"mute\"\n style=\"font-size: var(--t-sm)\"\n title=\"The server refuses to restart the container answering this request. Restart it from the host.\"\n >\n host-only\n </span>\n <span\n v-else\n class=\"mute\"\n style=\"font-size: var(--t-sm)\"\n title=\"No compose service label, so the restart API cannot address it.\"\n >\n —\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n <p v-else class=\"mute\">\n Docker lists no control containers — on a host serving this page, that means the project\n label changed, not that nothing runs.\n </p>\n </section>\n\n <!-- ============================ the certificate mode ============================ -->\n <section v-if=\"tls\" class=\"panel\">\n <div class=\"phead\">\n <h2 class=\"section\">Certificates</h2>\n <span class=\"grow\" />\n <span class=\"badge\" :class=\"tls.mode === 'dns-persist-01' ? 'ok' : 'info'\">{{ tls.mode }}</span>\n </div>\n\n <p class=\"dim\">{{ tls.note }}</p>\n\n <template v-if=\"tls.wildcard\">\n <ul class=\"kvlist\" style=\"margin: var(--s3) 0\">\n <li>\n <span class=\"k\">Covers</span>\n <span class=\"v mono\">{{ tls.wildcard.domains.join(', ') }}</span>\n </li>\n <li>\n <span class=\"k\">Valid until</span>\n <span class=\"v\">\n {{ stamp(tls.wildcard.notAfter) }}\n <span :class=\"daysLeft !== null && daysLeft < 21 ? 'badge failed' : 'mute'\"> {{ daysLeft }} days left</span>\n </span>\n </li>\n <li>\n <span class=\"k\">Issuer</span>\n <span class=\"v\">\n {{ tls.wildcard.issuer || 'unnamed' }}\n <span v-if=\"tls.wildcard.selfSigned\" class=\"badge warn\">self-signed — browsers will warn</span>\n </span>\n </li>\n </ul>\n <div v-if=\"can('admin')\" class=\"row\">\n <ActionButton variant=\"danger\" :pending=\"removing\" :disabled=\"removing\" @click=\"removeWildcard\">\n Remove wildcard\n </ActionButton>\n <span class=\"mute\" style=\"font-size: var(--t-sm)\">\n Stacks deployed under it then have no certificate until redeployed.\n </span>\n </div>\n </template>\n\n <template v-if=\"can('admin')\">\n <p class=\"dim\" style=\"margin-top: var(--s3)\">\n <template v-if=\"tls.wildcard\">\n <b>Renew or replace it.</b> Paste the new pair — it overwrites both halves in place and\n Traefik picks it up immediately. Nothing needs redeploying for a renewal: the router\n labels do not change, only the certificate behind them.\n </template>\n <template v-else>\n <b>Bring your own wildcard.</b> Paste a certificate for <span class=\"mono\">*.your-domain</span>\n and its key — previews stop ordering per-hostname certificates the moment it lands, with no\n re-init and no Traefik restart.\n </template>\n The key is stored 0600 and nothing ever returns it.\n </p>\n <div class=\"field\">\n <label for=\"tls-cert\">Certificate (PEM, leaf first, chain after)</label>\n <textarea id=\"tls-cert\" v-model=\"certDraft\" rows=\"5\" class=\"mono\" spellcheck=\"false\" placeholder=\"-----BEGIN CERTIFICATE-----\"></textarea>\n </div>\n <div class=\"field\">\n <label for=\"tls-key\">Private key (PEM)</label>\n <textarea id=\"tls-key\" v-model=\"keyDraft\" rows=\"4\" class=\"mono\" spellcheck=\"false\" placeholder=\"-----BEGIN PRIVATE KEY-----\"></textarea>\n </div>\n <ActionButton variant=\"primary\" :pending=\"storing\" :disabled=\"storing || !certDraft || !keyDraft\" @click=\"storeWildcard\">\n {{ tls.wildcard ? 'Replace wildcard' : 'Store wildcard' }}\n </ActionButton>\n </template>\n <p v-else-if=\"!tls.wildcard\" class=\"mute\">\n Storing a wildcard is an admin's: it changes what every hostname on this host presents.\n </p>\n\n <div class=\"row\" style=\"margin-top: var(--s4); align-items: center\">\n <ActionButton :pending=\"redeploying\" :disabled=\"redeploying\" @click=\"redeployAll\">\n Redeploy all stacks\n </ActionButton>\n <span class=\"mute\" style=\"font-size: var(--t-sm)\">\n Router labels are stamped at deploy time — run this once after changing the mode. Asleep\n stacks are skipped; they pick the new labels up when they wake.\n </span>\n </div>\n <p v-if=\"redeployed\" class=\"mute\" style=\"margin-top: var(--s2)\">\n Started {{ redeployed.started.length }} · skipped {{ redeployed.skipped.length\n }}<template v-if=\"redeployed.skipped.length\"> ({{ redeployed.skipped.map((x) => `${x.id}: ${x.reason}`).join('; ') }})</template>\n — watch them under Jobs.\n </p>\n </section>\n </div>\n</template>\n"],"names":["view","ref","error","loaded","load","r","api","problem","usePolling","restarting","restart","service","toast","mem","bytes","tls","loadTls","daysLeft","computed","_a","certDraft","keyDraft","storing","storeWildcard","redeployed","removing","removeWildcard","redeploying","redeployAll","_createElementBlock","_createElementVNode","_hoisted_1","_createVNode","HelpModal","_cache","_hoisted_2","InfoHint","RefreshButton","_createBlock","ErrorNote","SkeletonList","_openBlock","_hoisted_3","_hoisted_5","_hoisted_6","_Fragment","c","i","_hoisted_7","_createTextVNode","_toDisplayString","_hoisted_8","_hoisted_9","_hoisted_10","_normalizeClass","_unref","sentence","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","ago","_hoisted_16","ActionButton","$event","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_4","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","stamp","_hoisted_26","_hoisted_27","can","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_hoisted_32","_hoisted_33","_hoisted_34","x"],"mappings":"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"}
|