@micacms/editor-ui 0.5.0-rc.1 → 0.5.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/{ChangesView-CSjnT0fh.js → ChangesView-DVLSWguI.js} +2 -2
- package/dist/assets/{ChangesView-CSjnT0fh.js.map → ChangesView-DVLSWguI.js.map} +1 -1
- package/dist/assets/CollectionView-Dm0AZ-4T.js +2 -0
- package/dist/assets/CollectionView-Dm0AZ-4T.js.map +1 -0
- package/dist/assets/ConfirmDialog.vue_vue_type_script_setup_true_lang-BY6pag2U.js +2 -0
- package/dist/assets/{ConfirmDialog.vue_vue_type_script_setup_true_lang-C073kW3p.js.map → ConfirmDialog.vue_vue_type_script_setup_true_lang-BY6pag2U.js.map} +1 -1
- package/dist/assets/{DashboardView-BpelkVGe.js → DashboardView-DHf6CKvk.js} +2 -2
- package/dist/assets/{DashboardView-BpelkVGe.js.map → DashboardView-DHf6CKvk.js.map} +1 -1
- package/dist/assets/EntryView-DX4MCIIz.js +2 -0
- package/dist/assets/EntryView-DX4MCIIz.js.map +1 -0
- package/dist/assets/{LoginView-BmnX2zOD.js → LoginView-D3ztIdgO.js} +2 -2
- package/dist/assets/{LoginView-BmnX2zOD.js.map → LoginView-D3ztIdgO.js.map} +1 -1
- package/dist/assets/{MediaView-Dp2botAQ.js → MediaView-CeF4DCQR.js} +2 -2
- package/dist/assets/{MediaView-Dp2botAQ.js.map → MediaView-CeF4DCQR.js.map} +1 -1
- package/dist/assets/{NotFoundView-ByEOgkxm.js → NotFoundView-DvofX918.js} +2 -2
- package/dist/assets/{NotFoundView-ByEOgkxm.js.map → NotFoundView-DvofX918.js.map} +1 -1
- package/dist/assets/ObjectField--_IMDLHp.js +2 -0
- package/dist/assets/{ObjectField-BSITpnGH.js.map → ObjectField--_IMDLHp.js.map} +1 -1
- package/dist/assets/{PageHeader.vue_vue_type_script_setup_true_lang-DJWhe1Ye.js → PageHeader.vue_vue_type_script_setup_true_lang-Cr0v1G7O.js} +2 -2
- package/dist/assets/{PageHeader.vue_vue_type_script_setup_true_lang-DJWhe1Ye.js.map → PageHeader.vue_vue_type_script_setup_true_lang-Cr0v1G7O.js.map} +1 -1
- package/dist/assets/ReadOnlyNotice.vue_vue_type_script_setup_true_lang-BtfQSv1l.js +7 -0
- package/dist/assets/ReadOnlyNotice.vue_vue_type_script_setup_true_lang-BtfQSv1l.js.map +1 -0
- package/dist/assets/{RepeaterField-BnXDf3wL.js → RepeaterField-CRo8CLz6.js} +2 -2
- package/dist/assets/{RepeaterField-BnXDf3wL.js.map → RepeaterField-CRo8CLz6.js.map} +1 -1
- package/dist/assets/SingletonView-C1VhZ6Vv.js +2 -0
- package/dist/assets/SingletonView-C1VhZ6Vv.js.map +1 -0
- package/dist/assets/{SystemView-C6RAZvd2.js → SystemView-Bc2he_Af.js} +2 -2
- package/dist/assets/{SystemView-C6RAZvd2.js.map → SystemView-Bc2he_Af.js.map} +1 -1
- package/dist/assets/{arrow-right-DD5BWXHV.js → arrow-right-D8-sqdXS.js} +2 -2
- package/dist/assets/{arrow-right-DD5BWXHV.js.map → arrow-right-D8-sqdXS.js.map} +1 -1
- package/dist/assets/{arrow-up-Bdxg9_RJ.js → arrow-up-Bg3MuXmP.js} +2 -2
- package/dist/assets/{arrow-up-Bdxg9_RJ.js.map → arrow-up-Bg3MuXmP.js.map} +1 -1
- package/dist/assets/{chevron-down-CcJtiSTR.js → chevron-down-CnhoXsgY.js} +2 -2
- package/dist/assets/{chevron-down-CcJtiSTR.js.map → chevron-down-CnhoXsgY.js.map} +1 -1
- package/dist/assets/{index-BsOOwFCf.js → index-BHBq4-Io.js} +3 -3
- package/dist/assets/{index-BsOOwFCf.js.map → index-BHBq4-Io.js.map} +1 -1
- package/dist/assets/{useField-BxptRsz_.js → useField-vKkdSfn7.js} +2 -2
- package/dist/assets/{useField-BxptRsz_.js.map → useField-vKkdSfn7.js.map} +1 -1
- package/dist/assets/{useUnsavedChanges-FB5XcFfI.js → useUnsavedChanges-FKPfUHdo.js} +17 -17
- package/dist/assets/useUnsavedChanges-FKPfUHdo.js.map +1 -0
- package/dist/index.html +1 -1
- package/package.json +2 -2
- package/dist/assets/CollectionView-BlLAhVVi.js +0 -2
- package/dist/assets/CollectionView-BlLAhVVi.js.map +0 -1
- package/dist/assets/ConfirmDialog.vue_vue_type_script_setup_true_lang-C073kW3p.js +0 -2
- package/dist/assets/EntryView-DZuhqJnd.js +0 -2
- package/dist/assets/EntryView-DZuhqJnd.js.map +0 -1
- package/dist/assets/ObjectField-BSITpnGH.js +0 -2
- package/dist/assets/SingletonView-Cb8Qq_gr.js +0 -2
- package/dist/assets/SingletonView-Cb8Qq_gr.js.map +0 -1
- package/dist/assets/plus-CgaTSYYb.js +0 -7
- package/dist/assets/plus-CgaTSYYb.js.map +0 -1
- package/dist/assets/useUnsavedChanges-FB5XcFfI.js.map +0 -1
package/dist/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<link rel="icon" href="/admin/brand/favicon.ico" sizes="48x48" />
|
|
11
11
|
<link rel="icon" href="/admin/brand/micacms-favicon.svg" type="image/svg+xml" />
|
|
12
12
|
<link rel="apple-touch-icon" href="/admin/brand/apple-touch-icon.png" />
|
|
13
|
-
<script type="module" crossorigin src="/admin/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/admin/assets/index-BHBq4-Io.js"></script>
|
|
14
14
|
<link rel="stylesheet" crossorigin href="/admin/assets/index-bRiiEobC.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body class="h-full">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@micacms/editor-ui",
|
|
3
|
-
"version": "0.5.0
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Mica editor SPA — identity-neutral Vue administration UI, shipped as built assets and mounted by a composing app.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"vue": "^3.5.13",
|
|
38
38
|
"vue-router": "^4.5.0",
|
|
39
39
|
"vue-tsc": "^2.2.0",
|
|
40
|
-
"@micacms/core": "0.5.0
|
|
40
|
+
"@micacms/core": "0.5.0"
|
|
41
41
|
},
|
|
42
42
|
"engines": {
|
|
43
43
|
"node": ">=22.12.0"
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as R,o as z,q as D,c as o,j as p,w as _,a as s,s as j,v as E,t as r,x as P,b as L,F as y,k as $,r as x,g as b,i as B,A as F,p as U,n as q,h as a,l as g,e as N,y as J}from"./index-BsOOwFCf.js";import{_ as O}from"./PageHeader.vue_vue_type_script_setup_true_lang-DJWhe1Ye.js";import{p as G}from"./format-Cpnr2As6.js";import{P as H}from"./plus-CgaTSYYb.js";import{A as I,a as K}from"./arrow-up-Bdxg9_RJ.js";const Q={class:"mx-auto max-w-5xl px-4 py-5 sm:px-6"},W={class:"mb-3 flex flex-wrap items-center gap-2"},X=["placeholder","aria-label"],Y={class:"card overflow-hidden"},Z={key:0,class:"px-4 py-8 text-center text-sm text-muted"},ee={key:1,class:"px-4 py-12 text-center"},te={class:"text-sm font-medium"},se={key:2,class:"w-full text-sm"},le={class:"sr-only"},ae={class:"border-b border-line text-left text-xs text-muted"},oe={key:0,scope:"col",class:"px-2 py-2"},ne={class:"divide-y divide-line"},ie={class:"px-4 py-2.5"},re={class:"block font-mono text-xs text-muted"},ce={key:0,class:"px-2 py-2.5"},ue={class:"flex justify-end gap-0.5"},de=["disabled","onClick"],pe={class:"sr-only"},me=["disabled","onClick"],ve={class:"sr-only"},he={key:1,class:"p-8 text-center text-sm text-muted"},ge=R({__name:"CollectionView",props:{collection:{}},setup(m){const v=m,M=J(),S=q(),c=x([]),w=x(!0),d=x(""),h=x(!1),n=b(()=>M.collection(v.collection)),V=b(()=>{const t=n.value;return t?t.listedFields.filter(l=>l!==t.titleField):[]}),k=b(()=>{const t=d.value.trim().toLowerCase();return t?c.value.filter(l=>l.title.toLowerCase().includes(t)||l.slug.includes(t)||JSON.stringify(l.data).toLowerCase().includes(t)):c.value});async function C(){w.value=!0;try{c.value=(await B.entries.list(v.collection)).items}catch(t){S.error(t instanceof F?t.message:"Could not load the entries.")}finally{w.value=!1}}z(C),D(()=>v.collection,C);async function A(t,l){const u=t+l;if(u<0||u>=c.value.length)return;const e=[...c.value];[e[t],e[u]]=[e[u],e[t]],c.value=e,h.value=!0;try{await B.entries.reorder(v.collection,e.map(i=>i.slug))}catch(i){S.error(i instanceof F?i.message:"Could not save the new order."),await C()}finally{h.value=!1}}const T=b(()=>{var t;return(((t=n.value)==null?void 0:t.sortable)??!1)&&!d.value});return(t,l)=>{const u=U("RouterLink");return n.value?(a(),o(y,{key:0},[p(O,{title:n.value.label,subtitle:n.value.description??`${c.value.length} ${c.value.length===1?"entry":"entries"}`},{default:_(()=>[p(u,{to:{name:"entry-new",params:{collection:m.collection}},class:"btn-primary"},{default:_(()=>[p(g(H),{size:16,"aria-hidden":"true"}),N(" New "+r(n.value.labelSingular.toLowerCase()),1)]),_:1},8,["to"])]),_:1},8,["title","subtitle"]),s("div",Q,[s("div",W,[j(s("input",{"onUpdate:modelValue":l[0]||(l[0]=e=>d.value=e),type:"search",placeholder:`Search ${n.value.label.toLowerCase()}…`,class:"input max-w-64","aria-label":`Search ${n.value.label}`},null,8,X),[[E,d.value]])]),s("div",Y,[w.value?(a(),o("p",Z,"Loading…")):k.value.length===0?(a(),o("div",ee,[s("p",te,r(d.value?`Nothing matches "${d.value}".`:`No ${n.value.label.toLowerCase()} yet.`),1),d.value?L("",!0):(a(),P(u,{key:0,to:{name:"entry-new",params:{collection:m.collection}},class:"btn-primary mt-4"},{default:_(()=>[N(" Create the first "+r(n.value.labelSingular.toLowerCase()),1)]),_:1},8,["to"]))])):(a(),o("table",se,[s("caption",le,r(n.value.label),1),s("thead",null,[s("tr",ae,[l[2]||(l[2]=s("th",{scope:"col",class:"px-4 py-2 font-medium"},"Title",-1)),(a(!0),o(y,null,$(V.value,e=>{var i;return a(),o("th",{key:e,scope:"col",class:"hidden px-4 py-2 font-medium md:table-cell"},r(((i=n.value.fields[e])==null?void 0:i.label)??e),1)}),128)),T.value?(a(),o("th",oe,[...l[1]||(l[1]=[s("span",{class:"sr-only"},"Reorder",-1)])])):L("",!0)])]),s("tbody",ne,[(a(!0),o(y,null,$(k.value,(e,i)=>(a(),o("tr",{key:e.slug,class:"transition hover:bg-canvas"},[s("td",ie,[p(u,{to:{name:"entry",params:{collection:m.collection,slug:e.slug}},class:"font-medium hover:underline"},{default:_(()=>[N(r(e.title),1)]),_:2},1032,["to"]),s("span",re,"/"+r(e.slug),1)]),(a(!0),o(y,null,$(V.value,f=>(a(),o("td",{key:f,class:"hidden px-4 py-2.5 text-muted md:table-cell"},r(g(G)(e.data[f])),1))),128)),T.value?(a(),o("td",ce,[s("div",ue,[s("button",{type:"button",class:"btn-ghost px-1 py-0.5",disabled:i===0||h.value,onClick:f=>A(i,-1)},[p(g(I),{size:16,"aria-hidden":"true"}),s("span",pe,'Move "'+r(e.title)+'" up',1)],8,de),s("button",{type:"button",class:"btn-ghost px-1 py-0.5",disabled:i===k.value.length-1||h.value,onClick:f=>A(i,1)},[p(g(K),{size:16,"aria-hidden":"true"}),s("span",ve,'Move "'+r(e.title)+'" down',1)],8,me)])])):L("",!0)]))),128))])]))])])],64)):(a(),o("div",he,' There is no collection called "'+r(m.collection)+'". ',1))}}});export{ge as default};
|
|
2
|
-
//# sourceMappingURL=CollectionView-BlLAhVVi.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CollectionView-BlLAhVVi.js","sources":["../../src/views/CollectionView.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Collection overview: a filterable list of entries.\n * Columns come from fields marked `listed` in the model.\n *\n * The status column and its filter are gone: an entry in the repository is\n * saved, and saved is published. The \"Updated\" column went with them — the\n * honest answer is the last commit that touched the file, which is the\n * repository's to give, not a timestamp Mica writes into the entry.\n */\n\nimport { computed, onMounted, ref, watch } from \"vue\";\nimport { ArrowDown, ArrowUp, Plus } from \"@lucide/vue\";\n\nimport { api, ApiError, type EntrySummary } from \"@/api\";\nimport PageHeader from \"@/components/PageHeader.vue\";\nimport { previewValue } from \"@/lib/format\";\nimport { useSchema } from \"@/stores/schema\";\nimport { useToast } from \"@/stores/toast\";\n\nconst props = defineProps<{ collection: string }>();\n\nconst schema = useSchema();\nconst toast = useToast();\n\nconst entries = ref<EntrySummary[]>([]);\nconst loading = ref(true);\nconst search = ref(\"\");\nconst reordering = ref(false);\n\nconst definition = computed(() => schema.collection(props.collection));\nconst columns = computed(() => {\n const def = definition.value;\n if (!def) return [];\n // The title already has its own column, so do not repeat it.\n return def.listedFields.filter((key) => key !== def.titleField);\n});\n\nconst matching = computed(() => {\n const term = search.value.trim().toLowerCase();\n if (!term) return entries.value;\n\n // In the browser: the whole collection is already here, and a round trip per\n // keystroke would only add latency.\n return entries.value.filter(\n (entry) =>\n entry.title.toLowerCase().includes(term) ||\n entry.slug.includes(term) ||\n JSON.stringify(entry.data).toLowerCase().includes(term),\n );\n});\n\nasync function load(): Promise<void> {\n loading.value = true;\n try {\n entries.value = (await api.entries.list(props.collection)).items;\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : \"Could not load the entries.\");\n } finally {\n loading.value = false;\n }\n}\n\nonMounted(load);\nwatch(() => props.collection, load);\n\n/**\n * Manual ordering.\n *\n * The order is a `_order.json` file listing slugs, so moving one entry is a\n * one-line diff rather than a rewrite of every entry in the collection.\n */\nasync function move(index: number, direction: -1 | 1): Promise<void> {\n const target = index + direction;\n if (target < 0 || target >= entries.value.length) return;\n\n const next = [...entries.value];\n [next[index], next[target]] = [next[target]!, next[index]!];\n entries.value = next;\n\n reordering.value = true;\n try {\n await api.entries.reorder(\n props.collection,\n next.map((entry) => entry.slug),\n );\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : \"Could not save the new order.\");\n await load();\n } finally {\n reordering.value = false;\n }\n}\n\n// Reordering a filtered list would move the wrong neighbours.\nconst canReorder = computed(() => (definition.value?.sortable ?? false) && !search.value);\n</script>\n\n<template>\n <template v-if=\"definition\">\n <PageHeader\n :title=\"definition.label\"\n :subtitle=\"\n definition.description ??\n `${entries.length} ${entries.length === 1 ? 'entry' : 'entries'}`\n \"\n >\n <RouterLink :to=\"{ name: 'entry-new', params: { collection } }\" class=\"btn-primary\">\n <Plus :size=\"16\" aria-hidden=\"true\" />\n New {{ definition.labelSingular.toLowerCase() }}\n </RouterLink>\n </PageHeader>\n\n <div class=\"mx-auto max-w-5xl px-4 py-5 sm:px-6\">\n <div class=\"mb-3 flex flex-wrap items-center gap-2\">\n <input\n v-model=\"search\"\n type=\"search\"\n :placeholder=\"`Search ${definition.label.toLowerCase()}…`\"\n class=\"input max-w-64\"\n :aria-label=\"`Search ${definition.label}`\"\n />\n </div>\n\n <div class=\"card overflow-hidden\">\n <p v-if=\"loading\" class=\"px-4 py-8 text-center text-sm text-muted\">Loading…</p>\n\n <div v-else-if=\"matching.length === 0\" class=\"px-4 py-12 text-center\">\n <p class=\"text-sm font-medium\">\n {{ search ? `Nothing matches \"${search}\".` : `No ${definition.label.toLowerCase()} yet.` }}\n </p>\n <RouterLink\n v-if=\"!search\"\n :to=\"{ name: 'entry-new', params: { collection } }\"\n class=\"btn-primary mt-4\"\n >\n Create the first {{ definition.labelSingular.toLowerCase() }}\n </RouterLink>\n </div>\n\n <table v-else class=\"w-full text-sm\">\n <caption class=\"sr-only\">{{ definition.label }}</caption>\n <thead>\n <tr class=\"border-b border-line text-left text-xs text-muted\">\n <th scope=\"col\" class=\"px-4 py-2 font-medium\">Title</th>\n <th\n v-for=\"column in columns\"\n :key=\"column\"\n scope=\"col\"\n class=\"hidden px-4 py-2 font-medium md:table-cell\"\n >\n {{ definition.fields[column]?.label ?? column }}\n </th>\n <th v-if=\"canReorder\" scope=\"col\" class=\"px-2 py-2\">\n <span class=\"sr-only\">Reorder</span>\n </th>\n </tr>\n </thead>\n\n <tbody class=\"divide-y divide-line\">\n <tr v-for=\"(entry, index) in matching\" :key=\"entry.slug\" class=\"transition hover:bg-canvas\">\n <td class=\"px-4 py-2.5\">\n <RouterLink\n :to=\"{ name: 'entry', params: { collection, slug: entry.slug } }\"\n class=\"font-medium hover:underline\"\n >\n {{ entry.title }}\n </RouterLink>\n <span class=\"block font-mono text-xs text-muted\">/{{ entry.slug }}</span>\n </td>\n\n <td\n v-for=\"column in columns\"\n :key=\"column\"\n class=\"hidden px-4 py-2.5 text-muted md:table-cell\"\n >\n {{ previewValue(entry.data[column]) }}\n </td>\n\n <td v-if=\"canReorder\" class=\"px-2 py-2.5\">\n <div class=\"flex justify-end gap-0.5\">\n <button\n type=\"button\"\n class=\"btn-ghost px-1 py-0.5\"\n :disabled=\"index === 0 || reordering\"\n @click=\"move(index, -1)\"\n >\n <ArrowUp :size=\"16\" aria-hidden=\"true\" />\n <span class=\"sr-only\">Move \"{{ entry.title }}\" up</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-ghost px-1 py-0.5\"\n :disabled=\"index === matching.length - 1 || reordering\"\n @click=\"move(index, 1)\"\n >\n <ArrowDown :size=\"16\" aria-hidden=\"true\" />\n <span class=\"sr-only\">Move \"{{ entry.title }}\" down</span>\n </button>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </template>\n\n <div v-else class=\"p-8 text-center text-sm text-muted\">\n There is no collection called \"{{ collection }}\".\n </div>\n</template>\n"],"names":["props","__props","schema","useSchema","toast","useToast","entries","ref","loading","search","reordering","definition","computed","columns","def","key","matching","term","entry","load","api","error","ApiError","onMounted","watch","move","index","direction","target","next","canReorder","_a","_createElementBlock","_Fragment","_createVNode","PageHeader","_component_RouterLink","_unref","Plus","_createTextVNode","_toDisplayString","_createElementVNode","_hoisted_1","_hoisted_2","$event","_hoisted_4","_hoisted_5","_openBlock","_hoisted_6","_hoisted_7","_createBlock","_hoisted_8","_hoisted_9","_hoisted_10","_renderList","column","_hoisted_11","_cache","_hoisted_12","_hoisted_13","_hoisted_14","previewValue","_hoisted_15","_hoisted_16","ArrowUp","_hoisted_18","ArrowDown","_hoisted_20","_hoisted_21"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as k,q as v,x,c as g,z as p,a as l,t as d,E as C,C as B,b as h,T as w,r as u,h as b,H as E}from"./index-BsOOwFCf.js";const D={id:"confirm-title",class:"text-base font-semibold"},L={id:"confirm-body",class:"mt-2 text-sm text-muted"},T={class:"mt-5 flex justify-end gap-2"},$=["disabled"],z=["disabled"],S=k({__name:"ConfirmDialog",props:{open:{type:Boolean},title:{},confirmLabel:{default:"Confirm"},cancelLabel:{default:"Cancel"},destructive:{type:Boolean,default:!1},busy:{type:Boolean,default:!1}},emits:["confirm","cancel"],setup(t,{emit:m}){const r=t,s=m,i=u(null),f=u(null);let o=null;v(()=>r.open,async n=>{var e;if(!n){o==null||o.focus();return}o=document.activeElement,await E(),(e=f.value)==null||e.focus()});function y(n){if(n.key==="Escape"&&!r.busy&&s("cancel"),n.key!=="Tab"||!i.value)return;const e=i.value.querySelectorAll("button:not([disabled])"),a=e[0],c=e[e.length-1];!a||!c||(n.shiftKey&&document.activeElement===a?(n.preventDefault(),c.focus()):!n.shiftKey&&document.activeElement===c&&(n.preventDefault(),a.focus()))}return(n,e)=>(b(),x(w,{to:"body"},[t.open?(b(),g("div",{key:0,class:"fixed inset-0 z-50 grid place-items-center bg-ink/40 p-4",onClick:e[2]||(e[2]=p(a=>!t.busy&&s("cancel"),["self"])),onKeydown:y},[l("div",{ref_key:"panel",ref:i,role:"alertdialog","aria-modal":"true","aria-labelledby":"confirm-title","aria-describedby":"confirm-body",class:"w-full max-w-md rounded-xl border border-line bg-raised p-5 shadow-2xl"},[l("h2",D,d(t.title),1),l("div",L,[C(n.$slots,"default")]),l("div",T,[l("button",{ref_key:"cancelButton",ref:f,type:"button",class:"btn-secondary",disabled:t.busy,onClick:e[0]||(e[0]=a=>s("cancel"))},d(t.cancelLabel),9,$),l("button",{type:"button",class:B(t.destructive?"btn-danger":"btn-primary"),disabled:t.busy,onClick:e[1]||(e[1]=a=>s("confirm"))},d(t.busy?"Working…":t.confirmLabel),11,z)])],512)],32)):h("",!0)]))}});export{S as _};
|
|
2
|
-
//# sourceMappingURL=ConfirmDialog.vue_vue_type_script_setup_true_lang-C073kW3p.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as K,o as O,A as f,c as l,j as C,w as E,a as n,F as _,b,t as o,k as M,z as Q,B as W,n as X,g as w,r as c,i as x,p as Z,y as ee,h as a,e as S,l as F,C as te,m as se}from"./index-BsOOwFCf.js";import{_ as ne}from"./ConfirmDialog.vue_vue_type_script_setup_true_lang-C073kW3p.js";import{u as le,d as ae,_ as oe}from"./useUnsavedChanges-FB5XcFfI.js";import{_ as re}from"./PageHeader.vue_vue_type_script_setup_true_lang-DJWhe1Ye.js";import"./useField-BxptRsz_.js";import"./arrow-right-DD5BWXHV.js";import"./plus-CgaTSYYb.js";const ie=["disabled"],ue={class:"mx-auto max-w-3xl px-4 py-6 sm:px-6"},ce={key:0,class:"text-sm text-muted"},de={key:0,role:"alert",class:"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4"},me={key:1,role:"alert",class:"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4"},ve={key:2,role:"alert",class:"mb-5 rounded-md border border-danger/15 bg-danger-soft p-4"},ge={class:"text-sm font-medium text-danger"},fe={class:"mt-1.5 space-y-0.5 text-xs text-danger"},ye={key:3,class:"mt-10 border-t border-line pt-5"},pe={key:0,class:"mt-3 rounded-md border border-warning/15 bg-warning-soft p-4"},he={class:"text-sm font-medium text-warning"},be={class:"mt-1 list-inside list-disc text-xs"},we={key:1,class:"p-8 text-center text-sm text-muted"},$e=K({__name:"EntryView",props:{collection:{},slug:{}},setup(y){const s=y,V=W(),R=ee(),D=se(),u=X(),v=w(()=>R.collection(s.collection)),U=c(null),m=c({}),d=c([]),$=c(!0),p=c(!1),L=c(!1),k=c(!1),Y=w(()=>{var t,e;return(((e=(t=D.status.value)==null?void 0:t.sync)==null?void 0:e.conflicts)??[]).some(r=>{var i;return((i=r.target)==null?void 0:i.kind)==="entry"&&r.target.collection===s.collection&&r.target.slug===s.slug})}),g=c([]),N=c(null),h=le(m),T=h.dirty,A=w(()=>!s.slug),j=w(()=>{const t=v.value;if(!t)return"Entry";const e=m.value[t.titleField];return typeof e=="string"&&e.trim()?e.trim():A.value?`New ${t.labelSingular.toLowerCase()}`:"Untitled"}),q=w(()=>{var t;return((t=U.value)==null?void 0:t.path)??"Not saved yet"});function I(t){U.value=t,m.value=structuredClone(t.data),N.value=t.revision,d.value=[],L.value=!1,h.markClean()}async function B(t){I(await x.entries.get(s.collection,t))}O(async()=>{const t=v.value;if(!t){$.value=!1;return}try{s.slug?await B(s.slug):(m.value=ae(t.fields),N.value=null,h.markClean())}catch(e){u.error(e instanceof f?e.message:"Could not open this entry."),await V.replace({name:"collection",params:{collection:s.collection}})}finally{$.value=!1}});async function z(){p.value=!0,d.value=[];const t={data:m.value,revision:N.value};try{const e=s.slug?await x.entries.update(s.collection,s.slug,t):await x.entries.create(s.collection,t);if(h.markClean(),u.success(e.renamed?`Saved as “${e.slug}”.`:"Saved."),D.refresh(),e.slug!==s.slug){await V.replace({name:"entry",params:{collection:s.collection,slug:e.slug}});return}await B(e.slug)}catch(e){e instanceof f&&e.status===409?(L.value=!0,u.error("This entry was changed while you were editing it — by a colleague or on the website.")):e instanceof f&&e.issues.length>0?(d.value=e.issues,u.error(e.message,`${e.issues.length} field(s) need attention.`),requestAnimationFrame(()=>{var r;(r=document.querySelector('[aria-invalid="true"], .field-error'))==null||r.scrollIntoView({behavior:"smooth",block:"center"})})):u.error(e instanceof f?e.message:"Could not save this entry.")}finally{p.value=!1}}async function P(){if(s.slug)try{await B(s.slug),u.success("Reloaded from the repository.")}catch(t){u.error(t instanceof f?t.message:"Could not reload this entry.")}}async function G(){if(g.value=[],s.slug)try{const{references:t}=await x.entries.references(s.collection,s.slug);g.value=t.map(e=>{var r;return{collection:((r=R.collection(e.collection))==null?void 0:r.label)??e.collection,title:e.title}})}catch{}k.value=!0}async function H(){if(s.slug)try{await x.entries.remove(s.collection,s.slug),h.release(),u.success("Deleted."),D.refresh(),await V.replace({name:"collection",params:{collection:s.collection}})}catch(t){u.error(t instanceof f?t.message:"Could not delete this entry.")}finally{k.value=!1}}return(t,e)=>{const r=Z("RouterLink");return v.value?(a(),l(_,{key:0},[C(re,{title:j.value,subtitle:q.value,back:{name:"collection",params:{collection:y.collection}},"back-label":v.value.label},{default:E(()=>[n("span",{class:te(["badge",F(T)?"border-accent bg-accent-soft text-accent":"text-success"])},[e[2]||(e[2]=n("span",{class:"h-1.5 w-1.5 rounded-full bg-current","aria-hidden":"true"},null,-1)),S(" "+o(F(T)?"Unsaved":"Saved"),1)],2),n("button",{type:"button",class:"btn-primary",disabled:p.value||!F(T),onClick:z},o(p.value?"Saving…":"Save changes"),9,ie)]),_:1},8,["title","subtitle","back","back-label"]),n("div",ue,[$.value?(a(),l("p",ce,"Loading…")):(a(),l(_,{key:1},[Y.value?(a(),l("div",de,[e[4]||(e[4]=n("p",{class:"text-sm font-medium text-warning"},"This entry was changed on the website while you edited",-1)),e[5]||(e[5]=n("p",{class:"mt-1 text-xs text-muted"}," Your saved version is kept. Choose which version to publish on the Publish page. ",-1)),C(r,{to:{name:"changes"},class:"btn-secondary mt-2.5 inline-flex"},{default:E(()=>[...e[3]||(e[3]=[S("Choose a version",-1)])]),_:1})])):b("",!0),L.value?(a(),l("div",me,[e[6]||(e[6]=n("p",{class:"text-sm font-medium text-warning"},"This entry changed while you were editing",-1)),e[7]||(e[7]=n("p",{class:"mt-1 text-xs text-muted"}," Your changes are still here and have not been saved. Copy anything you need, then load the current version — or open the repository to see what changed. ",-1)),n("button",{type:"button",class:"btn-secondary mt-2.5",onClick:P}," Discard mine and reload ")])):b("",!0),d.value.length?(a(),l("div",ve,[n("p",ge,o(d.value.length)+" field"+o(d.value.length===1?"":"s")+" need attention ",1),n("ul",fe,[(a(!0),l(_,null,M(d.value,i=>(a(),l("li",{key:i.path},o(i.message),1))),128))])])):b("",!0),n("form",{novalidate:"",onSubmit:Q(z,["prevent"])},[C(oe,{modelValue:m.value,"onUpdate:modelValue":e[0]||(e[0]=i=>m.value=i),fields:v.value.fields,issues:d.value,disabled:p.value,collection:y.collection,"entry-slug":y.slug},null,8,["modelValue","fields","issues","disabled","collection","entry-slug"]),e[8]||(e[8]=n("button",{type:"submit",class:"sr-only"},"Save",-1))],32),A.value?b("",!0):(a(),l("div",ye,[n("button",{type:"button",class:"btn-danger",onClick:G}," Delete this "+o(v.value.labelSingular.toLowerCase()),1)]))],64))]),C(ne,{open:k.value,title:`Delete “${j.value}”?`,"confirm-label":"Delete",destructive:"",onCancel:e[1]||(e[1]=i=>k.value=!1),onConfirm:H},{default:E(()=>[n("p",null,[e[9]||(e[9]=S(" This removes ",-1)),n("code",null,o(q.value),1),e[10]||(e[10]=S(". Like any edit, the removal joins the pending changes and reaches the repository when they are published. ",-1))]),g.value.length?(a(),l("div",pe,[n("p",he,o(g.value.length)+" other entr"+o(g.value.length===1?"y":"ies")+" link to this one: ",1),n("ul",be,[(a(!0),l(_,null,M(g.value,(i,J)=>(a(),l("li",{key:J},o(i.title)+" ("+o(i.collection)+") ",1))),128))])])):b("",!0)]),_:1},8,["open","title"])],64)):(a(),l("div",we,' There is no collection called "'+o(y.collection)+'". ',1))}}});export{$e as default};
|
|
2
|
-
//# sourceMappingURL=EntryView-DZuhqJnd.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EntryView-DZuhqJnd.js","sources":["../../src/views/EntryView.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Entry editor. Saved is not Published: a save joins the pending changes, and\n * unsaved work stays in the form. `revision` goes back with the save, so a\n * concurrent save gets a 409 instead of an overwrite. The slug is the address:\n * changing it moves the entry, and the route follows.\n */\n\nimport { computed, onMounted, ref } from \"vue\";\nimport { useRouter } from \"vue-router\";\n\nimport { defaultValues, type FieldIssue } from \"@micacms/core\";\n\nimport { api, ApiError, type EntryDetail } from \"@/api\";\nimport ConfirmDialog from \"@/components/ConfirmDialog.vue\";\nimport FieldList from \"@/components/fields/FieldList.vue\";\nimport PageHeader from \"@/components/PageHeader.vue\";\nimport { useUnsavedChanges } from \"@/composables/useUnsavedChanges\";\nimport { useSchema } from \"@/stores/schema\";\nimport { useStaging } from \"@/stores/staging\";\nimport { useToast } from \"@/stores/toast\";\n\nconst props = defineProps<{ collection: string; slug?: string }>();\n\nconst router = useRouter();\nconst schema = useSchema();\nconst staging = useStaging();\nconst toast = useToast();\n\nconst definition = computed(() => schema.collection(props.collection));\n\nconst entry = ref<EntryDetail | null>(null);\nconst values = ref<Record<string, unknown>>({});\nconst issues = ref<FieldIssue[]>([]);\nconst loading = ref(true);\nconst saving = ref(false);\nconst conflict = ref(false);\nconst confirmDelete = ref(false);\n\n/** This entry was changed on the website while it has a draft here: Mica's own clone only. */\nconst websiteConflict = computed(() =>\n (staging.status.value?.sync?.conflicts ?? []).some(\n (item) =>\n item.target?.kind === \"entry\" && item.target.collection === props.collection && item.target.slug === props.slug,\n ),\n);\nconst references = ref<Array<{ collection: string; title: string }>>([]);\n\n/**\n * The version this form was opened against; `null` on a new entry, so a\n * duplicate slug is a conflict.\n */\nconst revision = ref<string | null>(null);\n\nconst unsaved = useUnsavedChanges(values);\nconst dirty = unsaved.dirty;\n\nconst isNew = computed(() => !props.slug);\n\nconst title = computed(() => {\n const def = definition.value;\n if (!def) return \"Entry\";\n const value = values.value[def.titleField];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n return isNew.value ? `New ${def.labelSingular.toLowerCase()}` : \"Untitled\";\n});\n\n/**\n * Where this entry lives, from the server: a directory with rich text or media,\n * else one `.json` file.\n */\nconst location = computed(() => entry.value?.path ?? \"Not saved yet\");\n\nfunction setBaseline(detail: EntryDetail): void {\n entry.value = detail;\n values.value = structuredClone(detail.data);\n revision.value = detail.revision;\n issues.value = [];\n conflict.value = false;\n unsaved.markClean();\n}\n\nasync function open(slug: string): Promise<void> {\n setBaseline(await api.entries.get(props.collection, slug));\n}\n\nonMounted(async () => {\n const def = definition.value;\n if (!def) {\n loading.value = false;\n return;\n }\n\n try {\n if (props.slug) {\n await open(props.slug);\n } else {\n // A fresh entry starts as a full skeleton so every input is bound. The\n // skeleton itself is not an edit, so it becomes the baseline.\n values.value = defaultValues(def.fields);\n revision.value = null;\n unsaved.markClean();\n }\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : \"Could not open this entry.\");\n await router.replace({ name: \"collection\", params: { collection: props.collection } });\n } finally {\n loading.value = false;\n }\n});\n\nasync function save(): Promise<void> {\n saving.value = true;\n issues.value = [];\n\n const payload = { data: values.value, revision: revision.value };\n\n try {\n const saved = props.slug\n ? await api.entries.update(props.collection, props.slug, payload)\n : await api.entries.create(props.collection, payload);\n\n // The server derives and de-duplicates the slug and can move the entry:\n // re-open at what it decided.\n unsaved.markClean();\n toast.success(saved.renamed ? `Saved as “${saved.slug}”.` : \"Saved.\");\n void staging.refresh();\n\n if (saved.slug !== props.slug) {\n await router.replace({\n name: \"entry\",\n params: { collection: props.collection, slug: saved.slug },\n });\n return;\n }\n\n await open(saved.slug);\n } catch (error) {\n if (error instanceof ApiError && error.status === 409) {\n // The form keeps the editor's work; a reload is their decision.\n conflict.value = true;\n toast.error(\"This entry was changed while you were editing it — by a colleague or on the website.\");\n } else if (error instanceof ApiError && error.issues.length > 0) {\n issues.value = error.issues;\n toast.error(error.message, `${error.issues.length} field(s) need attention.`);\n requestAnimationFrame(() => {\n document\n .querySelector('[aria-invalid=\"true\"], .field-error')\n ?.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n });\n } else {\n toast.error(error instanceof ApiError ? error.message : \"Could not save this entry.\");\n }\n } finally {\n saving.value = false;\n }\n}\n\n/** Takes the version now in the repository, discarding this form's edits. */\nasync function reload(): Promise<void> {\n if (!props.slug) return;\n try {\n await open(props.slug);\n toast.success(\"Reloaded from the repository.\");\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : \"Could not reload this entry.\");\n }\n}\n\nasync function askDelete(): Promise<void> {\n references.value = [];\n if (props.slug) {\n try {\n const { references: found } = await api.entries.references(props.collection, props.slug);\n references.value = found.map((item) => ({\n collection: schema.collection(item.collection)?.label ?? item.collection,\n title: item.title,\n }));\n } catch {\n // The warning is a courtesy; a failure to fetch it must not block deletion.\n }\n }\n confirmDelete.value = true;\n}\n\nasync function remove(): Promise<void> {\n if (!props.slug) return;\n try {\n await api.entries.remove(props.collection, props.slug);\n unsaved.release();\n toast.success(\"Deleted.\");\n void staging.refresh();\n await router.replace({ name: \"collection\", params: { collection: props.collection } });\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : \"Could not delete this entry.\");\n } finally {\n confirmDelete.value = false;\n }\n}\n</script>\n\n<template>\n <template v-if=\"definition\">\n <PageHeader\n :title=\"title\"\n :subtitle=\"location\"\n :back=\"{ name: 'collection', params: { collection } }\"\n :back-label=\"definition.label\"\n >\n <span :class=\"['badge', dirty ? 'border-accent bg-accent-soft text-accent' : 'text-success']\">\n <span class=\"h-1.5 w-1.5 rounded-full bg-current\" aria-hidden=\"true\" />\n {{ dirty ? \"Unsaved\" : \"Saved\" }}\n </span>\n <button type=\"button\" class=\"btn-primary\" :disabled=\"saving || !dirty\" @click=\"save\">\n {{ saving ? \"Saving…\" : \"Save changes\" }}\n </button>\n </PageHeader>\n\n <div class=\"mx-auto max-w-3xl px-4 py-6 sm:px-6\">\n <p v-if=\"loading\" class=\"text-sm text-muted\">Loading…</p>\n\n <template v-else>\n <div\n v-if=\"websiteConflict\"\n role=\"alert\"\n class=\"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4\"\n >\n <p class=\"text-sm font-medium text-warning\">This entry was changed on the website while you edited</p>\n <p class=\"mt-1 text-xs text-muted\">\n Your saved version is kept. Choose which version to publish on the Publish page.\n </p>\n <RouterLink :to=\"{ name: 'changes' }\" class=\"btn-secondary mt-2.5 inline-flex\">Choose a version</RouterLink>\n </div>\n\n <div\n v-if=\"conflict\"\n role=\"alert\"\n class=\"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4\"\n >\n <p class=\"text-sm font-medium text-warning\">This entry changed while you were editing</p>\n <p class=\"mt-1 text-xs text-muted\">\n Your changes are still here and have not been saved. Copy anything you need, then load\n the current version — or open the repository to see what changed.\n </p>\n <button type=\"button\" class=\"btn-secondary mt-2.5\" @click=\"reload\">\n Discard mine and reload\n </button>\n </div>\n\n <div\n v-if=\"issues.length\"\n role=\"alert\"\n class=\"mb-5 rounded-md border border-danger/15 bg-danger-soft p-4\"\n >\n <p class=\"text-sm font-medium text-danger\">\n {{ issues.length }} field{{ issues.length === 1 ? \"\" : \"s\" }} need attention\n </p>\n <ul class=\"mt-1.5 space-y-0.5 text-xs text-danger\">\n <li v-for=\"issue in issues\" :key=\"issue.path\">{{ issue.message }}</li>\n </ul>\n </div>\n\n <form novalidate @submit.prevent=\"save\">\n <FieldList\n v-model=\"values\"\n :fields=\"definition.fields\"\n :issues=\"issues\"\n :disabled=\"saving\"\n :collection=\"collection\"\n :entry-slug=\"slug\"\n />\n\n <!-- Enter in a text input should save, not do nothing. -->\n <button type=\"submit\" class=\"sr-only\">Save</button>\n </form>\n\n <div v-if=\"!isNew\" class=\"mt-10 border-t border-line pt-5\">\n <button type=\"button\" class=\"btn-danger\" @click=\"askDelete\">\n Delete this {{ definition.labelSingular.toLowerCase() }}\n </button>\n </div>\n </template>\n </div>\n\n <ConfirmDialog\n :open=\"confirmDelete\"\n :title=\"`Delete “${title}”?`\"\n confirm-label=\"Delete\"\n destructive\n @cancel=\"confirmDelete = false\"\n @confirm=\"remove\"\n >\n <p>\n This removes <code>{{ location }}</code>. Like any edit, the removal joins the pending\n changes and reaches the repository when they are published.\n </p>\n\n <div v-if=\"references.length\" class=\"mt-3 rounded-md border border-warning/15 bg-warning-soft p-4\">\n <p class=\"text-sm font-medium text-warning\">\n {{ references.length }} other entr{{ references.length === 1 ? \"y\" : \"ies\" }} link to this\n one:\n </p>\n <ul class=\"mt-1 list-inside list-disc text-xs\">\n <li v-for=\"(item, index) in references\" :key=\"index\">\n {{ item.title }} ({{ item.collection }})\n </li>\n </ul>\n </div>\n </ConfirmDialog>\n </template>\n\n <div v-else class=\"p-8 text-center text-sm text-muted\">\n There is no collection called \"{{ collection }}\".\n </div>\n</template>\n"],"names":["props","__props","router","useRouter","schema","useSchema","staging","useStaging","toast","useToast","definition","computed","entry","ref","values","issues","loading","saving","conflict","confirmDelete","websiteConflict","_b","_a","item","references","revision","unsaved","useUnsavedChanges","dirty","isNew","title","def","value","location","setBaseline","detail","open","slug","api","onMounted","defaultValues","error","ApiError","save","payload","saved","reload","askDelete","found","remove","_createElementBlock","_Fragment","_createVNode","PageHeader","_createElementVNode","_unref","_createTextVNode","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_hoisted_4","_cache","_component_RouterLink","_hoisted_5","_hoisted_6","_hoisted_7","_toDisplayString","_hoisted_8","_renderList","issue","FieldList","$event","_hoisted_9","ConfirmDialog","_hoisted_10","_hoisted_11","_hoisted_12","index","_hoisted_13"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as C,r as k,h as a,c as d,a as m,t as n,l as o,x,w,b as u,C as y,S as B,s as S,Z as D,j as N,g as c}from"./index-BsOOwFCf.js";import{_ as j}from"./useUnsavedChanges-FB5XcFfI.js";import{u as $}from"./useField-BxptRsz_.js";import{C as z}from"./chevron-down-CcJtiSTR.js";import"./arrow-right-DD5BWXHV.js";import"./plus-CgaTSYYb.js";const F={class:"card overflow-hidden"},I={class:"sr-only"},E={class:"text-sm font-semibold"},O={key:0,class:"badge bg-danger-soft text-danger"},U={class:"border-t border-line p-4 sm:p-5"},W={key:0,class:"mb-4 text-xs text-muted"},Z={key:0,class:"px-4 pb-3 text-xs font-medium text-danger"},L=C({__name:"ObjectField",props:{field:{},path:{},issues:{},disabled:{type:Boolean},modelValue:{},collection:{},entrySlug:{}},emits:["update:modelValue"],setup(t,{emit:g}){const s=t,V=g,e=c(()=>s.field),{label:p,error:v}=$(s),f=k(!e.value.collapsed),_=c(()=>s.modelValue&&typeof s.modelValue=="object"?s.modelValue:{}),b=c(()=>{var r;return((r=s.issues)==null?void 0:r.some(l=>l.path.startsWith(`${s.path}.`)))??!1}),i=c(()=>f.value||b.value);return(r,l)=>(a(),d("fieldset",F,[m("legend",I,n(o(p)),1),(a(),x(B(e.value.collapsible?"button":"div"),{type:e.value.collapsible?"button":void 0,"aria-expanded":e.value.collapsible?i.value:void 0,class:y(["flex w-full items-center gap-2 px-4 py-3 text-left",e.value.collapsible&&"hover:bg-canvas"]),onClick:l[0]||(l[0]=h=>e.value.collapsible?f.value=!i.value:void 0)},{default:w(()=>[m("span",E,n(o(p)),1),b.value?(a(),d("span",O," Needs attention ")):u("",!0),e.value.collapsible?(a(),x(o(z),{key:1,size:16,class:y(["ml-auto h-4 w-4 text-muted transition",i.value&&"rotate-180"]),"aria-hidden":"true"},null,8,["class"])):u("",!0)]),_:1},8,["type","aria-expanded","class"])),S(m("div",U,[e.value.description?(a(),d("p",W,n(e.value.description),1)):u("",!0),N(j,{fields:e.value.fields,"model-value":_.value,path:t.path,issues:t.issues,disabled:t.disabled||e.value.readonly,collection:t.collection,"entry-slug":t.entrySlug,"onUpdate:modelValue":l[1]||(l[1]=h=>V("update:modelValue",h))},null,8,["fields","model-value","path","issues","disabled","collection","entry-slug"])],512),[[D,i.value]]),o(v)?(a(),d("p",Z,n(o(v)),1)):u("",!0)]))}});export{L as default};
|
|
2
|
-
//# sourceMappingURL=ObjectField-BSITpnGH.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{d as E,o as F,q as M,c as a,j as _,w as B,a as s,F as C,t as i,b as h,k as R,z as j,g as D,r,i as U,A as b,p as q,n as P,h as n,e as $,l as y,C as Y,m as G,y as H}from"./index-BsOOwFCf.js";import{u as I,_ as J,w as K}from"./useUnsavedChanges-FB5XcFfI.js";import{_ as O}from"./PageHeader.vue_vue_type_script_setup_true_lang-DJWhe1Ye.js";import"./useField-BxptRsz_.js";import"./arrow-right-DD5BWXHV.js";import"./plus-CgaTSYYb.js";const Q=["disabled"],W={class:"mx-auto max-w-3xl px-4 py-6 sm:px-6"},X={key:0,class:"text-sm text-muted"},Z={key:0,class:"mb-5 text-sm text-muted"},ee={key:1,role:"alert",class:"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4"},te={key:2,role:"alert",class:"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4"},se={key:3,role:"alert",class:"mb-5 rounded-md border border-danger/15 bg-danger-soft p-4"},ae={class:"text-sm font-medium text-danger"},ne={class:"mt-1.5 space-y-0.5 text-xs text-danger"},oe={key:1,class:"p-8 text-center text-sm text-muted"},me=E({__name:"SingletonView",props:{name:{}},setup(S){const d=S,z=H(),V=G(),c=P(),u=D(()=>z.singleton(d.name)),m=r({}),o=r([]),x=r(null),w=r(!0),v=r(!1),g=r(!1),A=D(()=>{var t,e;return(((e=(t=V.status.value)==null?void 0:t.sync)==null?void 0:e.conflicts)??[]).some(p=>{var l;return((l=p.target)==null?void 0:l.kind)==="singleton"&&p.target.name===d.name})}),T=r(""),{dirty:f,markClean:N}=I(m);async function k(){var t;w.value=!0;try{const e=await U.singletons.get(d.name);m.value=structuredClone(K(((t=u.value)==null?void 0:t.fields)??{},e.data)),x.value=e.revision,T.value=e.path,o.value=[],g.value=!1,N()}catch(e){c.error(e instanceof b?e.message:"Could not load these settings.")}finally{w.value=!1}}F(k),M(()=>d.name,k);async function L(){v.value=!0,o.value=[];try{const t=await U.singletons.save(d.name,m.value,x.value);x.value=t.revision,g.value=!1,N(),c.success("Settings saved."),V.refresh()}catch(t){t instanceof b&&t.status===409?(g.value=!0,c.error("These settings were changed while you were editing them — by a colleague or on the website.")):t instanceof b&&t.issues.length>0?(o.value=t.issues,c.error(t.message,`${t.issues.length} field(s) need attention.`)):c.error(t instanceof b?t.message:"Could not save these settings.")}finally{v.value=!1}}return(t,e)=>{const p=q("RouterLink");return u.value?(n(),a(C,{key:0},[_(O,{title:u.value.label,subtitle:T.value},{default:B(()=>[s("span",{class:Y(["badge",y(f)?"border-accent bg-accent-soft text-accent":"text-success"])},[e[1]||(e[1]=s("span",{class:"h-1.5 w-1.5 rounded-full bg-current","aria-hidden":"true"},null,-1)),$(" "+i(y(f)?"Unsaved":"Saved"),1)],2),s("button",{type:"button",class:"btn-primary",disabled:v.value||!y(f),onClick:L},i(v.value?"Saving…":y(f)?"Save changes":"Saved"),9,Q)]),_:1},8,["title","subtitle"]),s("div",W,[w.value?(n(),a("p",X,"Loading…")):(n(),a(C,{key:1},[u.value.description?(n(),a("p",Z,i(u.value.description),1)):h("",!0),A.value?(n(),a("div",ee,[e[3]||(e[3]=s("p",{class:"text-sm font-medium text-warning"},"These settings was changed on the website while you edited",-1)),e[4]||(e[4]=s("p",{class:"mt-1 text-xs text-muted"}," Your saved version is kept. Choose which version to publish on the Publish page. ",-1)),_(p,{to:{name:"changes"},class:"btn-secondary mt-2.5 inline-flex"},{default:B(()=>[...e[2]||(e[2]=[$("Choose a version",-1)])]),_:1})])):h("",!0),g.value?(n(),a("div",te,[e[5]||(e[5]=s("p",{class:"text-sm font-medium text-warning"},"These settings changed while you were editing",-1)),e[6]||(e[6]=s("p",{class:"mt-1 text-xs text-muted"}," Nothing has been saved. Copy anything you need, then load the current version. ",-1)),s("button",{type:"button",class:"btn-secondary mt-2.5",onClick:k}," Discard mine and reload ")])):h("",!0),o.value.length?(n(),a("div",se,[s("p",ae,i(o.value.length)+" field"+i(o.value.length===1?"":"s")+" need attention ",1),s("ul",ne,[(n(!0),a(C,null,R(o.value,l=>(n(),a("li",{key:l.path},i(l.message),1))),128))])])):h("",!0),s("form",{novalidate:"",onSubmit:j(L,["prevent"])},[_(J,{modelValue:m.value,"onUpdate:modelValue":e[0]||(e[0]=l=>m.value=l),fields:u.value.fields,issues:o.value,disabled:v.value},null,8,["modelValue","fields","issues","disabled"]),e[7]||(e[7]=s("button",{type:"submit",class:"sr-only"},"Save",-1))],32)],64))])],64)):(n(),a("div",oe,' There are no settings called "'+i(S.name)+'". ',1))}}});export{me as default};
|
|
2
|
-
//# sourceMappingURL=SingletonView-Cb8Qq_gr.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SingletonView-Cb8Qq_gr.js","sources":["../../src/views/SingletonView.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Singleton editor: the entry editor without the parts that need a slug (no\n * rename, no delete, no list). `revision` goes back with the save, so a second\n * editor cannot be overwritten in silence.\n */\n\nimport { computed, onMounted, ref, watch } from \"vue\";\n\nimport { withDefaults as fillDefaults, type FieldIssue } from \"@micacms/core\";\n\nimport { api, ApiError } from \"@/api\";\nimport FieldList from \"@/components/fields/FieldList.vue\";\nimport PageHeader from \"@/components/PageHeader.vue\";\nimport { useUnsavedChanges } from \"@/composables/useUnsavedChanges\";\nimport { useSchema } from \"@/stores/schema\";\nimport { useStaging } from \"@/stores/staging\";\nimport { useToast } from \"@/stores/toast\";\n\nconst props = defineProps<{ name: string }>();\n\nconst schema = useSchema();\nconst staging = useStaging();\nconst toast = useToast();\n\nconst definition = computed(() => schema.singleton(props.name));\n\nconst values = ref<Record<string, unknown>>({});\nconst issues = ref<FieldIssue[]>([]);\nconst revision = ref<string | null>(null);\nconst loading = ref(true);\nconst saving = ref(false);\nconst conflict = ref(false);\n\n/**\n * These settings were changed on the website while they have a draft here:\n * Mica's own clone only.\n */\nconst websiteConflict = computed(() =>\n (staging.status.value?.sync?.conflicts ?? []).some(\n (item) => item.target?.kind === \"singleton\" && item.target.name === props.name,\n ),\n);\n\n/** Where these settings live, as the server reports it. */\nconst location = ref(\"\");\n\nconst { dirty, markClean } = useUnsavedChanges(values);\n\nasync function load(): Promise<void> {\n loading.value = true;\n try {\n const detail = await api.singletons.get(props.name);\n // Defaults fill in fields added to the model since the file was written.\n values.value = structuredClone(fillDefaults(definition.value?.fields ?? {}, detail.data));\n revision.value = detail.revision;\n location.value = detail.path;\n issues.value = [];\n conflict.value = false;\n markClean();\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : \"Could not load these settings.\");\n } finally {\n loading.value = false;\n }\n}\n\nonMounted(load);\nwatch(() => props.name, load);\n\nasync function save(): Promise<void> {\n saving.value = true;\n issues.value = [];\n\n try {\n const saved = await api.singletons.save(props.name, values.value, revision.value);\n revision.value = saved.revision;\n conflict.value = false;\n markClean();\n toast.success(\"Settings saved.\");\n void staging.refresh();\n } catch (error) {\n if (error instanceof ApiError && error.status === 409) {\n conflict.value = true;\n toast.error(\"These settings were changed while you were editing them — by a colleague or on the website.\");\n } else if (error instanceof ApiError && error.issues.length > 0) {\n issues.value = error.issues;\n toast.error(error.message, `${error.issues.length} field(s) need attention.`);\n } else {\n toast.error(error instanceof ApiError ? error.message : \"Could not save these settings.\");\n }\n } finally {\n saving.value = false;\n }\n}\n</script>\n\n<template>\n <template v-if=\"definition\">\n <PageHeader :title=\"definition.label\" :subtitle=\"location\">\n <span :class=\"['badge', dirty ? 'border-accent bg-accent-soft text-accent' : 'text-success']\">\n <span class=\"h-1.5 w-1.5 rounded-full bg-current\" aria-hidden=\"true\" />\n {{ dirty ? \"Unsaved\" : \"Saved\" }}\n </span>\n <button type=\"button\" class=\"btn-primary\" :disabled=\"saving || !dirty\" @click=\"save\">\n {{ saving ? \"Saving…\" : dirty ? \"Save changes\" : \"Saved\" }}\n </button>\n </PageHeader>\n\n <div class=\"mx-auto max-w-3xl px-4 py-6 sm:px-6\">\n <p v-if=\"loading\" class=\"text-sm text-muted\">Loading…</p>\n\n <template v-else>\n <p v-if=\"definition.description\" class=\"mb-5 text-sm text-muted\">\n {{ definition.description }}\n </p>\n\n <div\n v-if=\"websiteConflict\"\n role=\"alert\"\n class=\"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4\"\n >\n <p class=\"text-sm font-medium text-warning\">These settings was changed on the website while you edited</p>\n <p class=\"mt-1 text-xs text-muted\">\n Your saved version is kept. Choose which version to publish on the Publish page.\n </p>\n <RouterLink :to=\"{ name: 'changes' }\" class=\"btn-secondary mt-2.5 inline-flex\">Choose a version</RouterLink>\n </div>\n\n <div\n v-if=\"conflict\"\n role=\"alert\"\n class=\"mb-5 rounded-md border border-warning/15 bg-warning-soft p-4\"\n >\n <p class=\"text-sm font-medium text-warning\">These settings changed while you were editing</p>\n <p class=\"mt-1 text-xs text-muted\">\n Nothing has been saved. Copy anything you need, then load the current version.\n </p>\n <button type=\"button\" class=\"btn-secondary mt-2.5\" @click=\"load\">\n Discard mine and reload\n </button>\n </div>\n\n <div\n v-if=\"issues.length\"\n role=\"alert\"\n class=\"mb-5 rounded-md border border-danger/15 bg-danger-soft p-4\"\n >\n <p class=\"text-sm font-medium text-danger\">\n {{ issues.length }} field{{ issues.length === 1 ? \"\" : \"s\" }} need attention\n </p>\n <ul class=\"mt-1.5 space-y-0.5 text-xs text-danger\">\n <li v-for=\"issue in issues\" :key=\"issue.path\">{{ issue.message }}</li>\n </ul>\n </div>\n\n <form novalidate @submit.prevent=\"save\">\n <FieldList\n v-model=\"values\"\n :fields=\"definition.fields\"\n :issues=\"issues\"\n :disabled=\"saving\"\n />\n <button type=\"submit\" class=\"sr-only\">Save</button>\n </form>\n </template>\n </div>\n </template>\n\n <div v-else class=\"p-8 text-center text-sm text-muted\">\n There are no settings called \"{{ name }}\".\n </div>\n</template>\n"],"names":["props","__props","schema","useSchema","staging","useStaging","toast","useToast","definition","computed","values","ref","issues","revision","loading","saving","conflict","websiteConflict","_b","_a","item","location","dirty","markClean","useUnsavedChanges","load","detail","api","fillDefaults","error","ApiError","onMounted","watch","save","saved","_createElementBlock","_Fragment","_createVNode","PageHeader","_createElementVNode","_unref","_createTextVNode","_toDisplayString","_hoisted_1","_hoisted_2","_hoisted_3","_openBlock","_hoisted_4","_hoisted_5","_cache","_component_RouterLink","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_renderList","issue","FieldList","$event","_hoisted_10"],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{D as e}from"./index-BsOOwFCf.js";/**
|
|
2
|
-
* @license @lucide/vue v1.37.0 - ISC
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the ISC license.
|
|
5
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const o=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],t=e("plus",o);export{t as P};
|
|
7
|
-
//# sourceMappingURL=plus-CgaTSYYb.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plus-CgaTSYYb.js","sources":["../../../../common/temp/node_modules/.pnpm/@lucide+vue@1.37.0_vue@3.5.42_typescript@5.9.3_/node_modules/@lucide/vue/dist/esm/icons/plus.mjs"],"sourcesContent":["/**\n * @license @lucide/vue v1.37.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n];\nconst Plus = createLucideIcon(\"plus\", __iconNode);\n\nexport { __iconNode, Plus as default };\n//# sourceMappingURL=plus.mjs.map\n"],"names":["__iconNode","Plus","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAa,CACjB,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,EACMC,EAAOC,EAAiB,OAAQF,CAAU","x_google_ignoreList":[0]}
|