terms: per-term installer visibility toggles + universal delete (v0.3.4)

- _meta.json: customLabels -> terms.{label,showInInstaller,showInInstallerRp}
- Drop builtin protection; any term kind can be deleted/added/toggled
- New public route /manifest/terms/<pack>/index.json for installer term lists
- Installers fetch terms:list dynamically; skip agreement step if list empty
- Term editor: 2 visibility checkboxes (설치기 / 리소스팩 설치기), multi-select
- Migration from old schema preserves custom labels (default: visible in both)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 10:14:42 +09:00
parent 05dc9d7166
commit 9ba5dc6b7b
14 changed files with 445 additions and 130 deletions

View File

@@ -141,14 +141,36 @@ function renderStep1() {
}
// 약관 동의 페이지: 1단계 직후, 2단계 설치 진입 전에 노출.
// rp 인스톨러는 리소스팩·설치기 두 약관만 확인·동의하면 된다.
// v0.3.4~ : 사이트의 visibility 토글에 따라 표시할 약관이 결정된다. 목록이 비면 단계를 건너뛴다.
function renderAgreement() {
setActiveStep(1)
clearPage()
var KINDS = [
{ id: 'resourcepack', tab: tt('agreement.tabResourcepack') },
{ id: 'installer-rp', tab: tt('agreement.tabInstaller') }
]
var loadingSection = document.createElement('section')
loadingSection.className = 'page'
loadingSection.innerHTML = '<h2>' + escapeHtml(tt('agreement.heading')) + '</h2>' +
'<p class="formMessage">' + escapeHtml(tt('agreement.loading')) + '</p>'
pageHost.appendChild(loadingSection)
api.getTermsList().then(function (res) {
if (!res || !res.ok) {
renderStep2()
return
}
var terms = (res.terms || []).map(function (t) {
return { id: t.kind, tab: t.label }
})
if (terms.length === 0) {
renderStep2()
return
}
clearPage()
renderAgreementWithKinds(terms)
}).catch(function () {
renderStep2()
})
}
function renderAgreementWithKinds(KINDS) {
var section = document.createElement('section')
section.className = 'page'
section.innerHTML =