@shapio/cms 0.5.7 → 0.5.8
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/admin/assets/{AssetTile-H0hABhB2.js → AssetTile-BrMzsUZD.js} +2 -2
- package/dist/admin/assets/{AssetTile-H0hABhB2.js.map → AssetTile-BrMzsUZD.js.map} +1 -1
- package/dist/admin/assets/{AssistError-1s3PuY0X.js → AssistError-Cs-r9Ssc.js} +2 -2
- package/dist/admin/assets/{AssistError-1s3PuY0X.js.map → AssistError-Cs-r9Ssc.js.map} +1 -1
- package/dist/admin/assets/{BlockMenuItems-a8zXdfcF.js → BlockMenuItems-DsccXMc_.js} +2 -2
- package/dist/admin/assets/{BlockMenuItems-a8zXdfcF.js.map → BlockMenuItems-DsccXMc_.js.map} +1 -1
- package/dist/admin/assets/{Builder-60jO_nbS.js → Builder-DW-GJA_q.js} +2 -2
- package/dist/admin/assets/{Builder-60jO_nbS.js.map → Builder-DW-GJA_q.js.map} +1 -1
- package/dist/admin/assets/{CodeEditor-BLbJZE9v.js → CodeEditor-CBCR73Wd.js} +2 -2
- package/dist/admin/assets/{CodeEditor-BLbJZE9v.js.map → CodeEditor-CBCR73Wd.js.map} +1 -1
- package/dist/admin/assets/{CopyButton-BOtR_h1H.js → CopyButton-CxFsBHfF.js} +2 -2
- package/dist/admin/assets/{CopyButton-BOtR_h1H.js.map → CopyButton-CxFsBHfF.js.map} +1 -1
- package/dist/admin/assets/{CursorPager-DwLW13ov.js → CursorPager-BW2U3v6l.js} +2 -2
- package/dist/admin/assets/{CursorPager-DwLW13ov.js.map → CursorPager-BW2U3v6l.js.map} +1 -1
- package/dist/admin/assets/{FocalPoint-n-a_AXKN.js → FocalPoint-CpZTve1E.js} +2 -2
- package/dist/admin/assets/{FocalPoint-n-a_AXKN.js.map → FocalPoint-CpZTve1E.js.map} +1 -1
- package/dist/admin/assets/{Form-D_4fhOy0.js → Form-lNrRHc0I.js} +2 -2
- package/dist/admin/assets/{Form-D_4fhOy0.js.map → Form-lNrRHc0I.js.map} +1 -1
- package/dist/admin/assets/{FormCheckboxGroup-1fYisXrr.js → FormCheckboxGroup-DeeaYnzB.js} +2 -2
- package/dist/admin/assets/{FormCheckboxGroup-1fYisXrr.js.map → FormCheckboxGroup-DeeaYnzB.js.map} +1 -1
- package/dist/admin/assets/{FormRadioGroup-B0VZyb1t.js → FormRadioGroup-Cfx5pvzU.js} +2 -2
- package/dist/admin/assets/{FormRadioGroup-B0VZyb1t.js.map → FormRadioGroup-Cfx5pvzU.js.map} +1 -1
- package/dist/admin/assets/{FormSelectField-Br8bkwRF.js → FormSelectField-BzE9Lq9i.js} +2 -2
- package/dist/admin/assets/{FormSelectField-Br8bkwRF.js.map → FormSelectField-BzE9Lq9i.js.map} +1 -1
- package/dist/admin/assets/{FormSwitchField-d8G-YCSX.js → FormSwitchField-BLOh7qei.js} +2 -2
- package/dist/admin/assets/{FormSwitchField-d8G-YCSX.js.map → FormSwitchField-BLOh7qei.js.map} +1 -1
- package/dist/admin/assets/{FormTextareaField-BSKNeTPW.js → FormTextareaField-CO115n_u.js} +2 -2
- package/dist/admin/assets/{FormTextareaField-BSKNeTPW.js.map → FormTextareaField-CO115n_u.js.map} +1 -1
- package/dist/admin/assets/{HintedLabel-CiTDE112.js → HintedLabel-DzHnEdIK.js} +2 -2
- package/dist/admin/assets/{HintedLabel-CiTDE112.js.map → HintedLabel-DzHnEdIK.js.map} +1 -1
- package/dist/admin/assets/{InfoHint-B3XcXtiN.js → InfoHint-CSEtcHjL.js} +2 -2
- package/dist/admin/assets/{InfoHint-B3XcXtiN.js.map → InfoHint-CSEtcHjL.js.map} +1 -1
- package/dist/admin/assets/{InlineConfirm-BfsNH5S_.js → InlineConfirm-yW-iUKFC.js} +2 -2
- package/dist/admin/assets/{InlineConfirm-BfsNH5S_.js.map → InlineConfirm-yW-iUKFC.js.map} +1 -1
- package/dist/admin/assets/{InsertMenuItem-BGwDW_Lu.js → InsertMenuItem-CCr9e0qY.js} +2 -2
- package/dist/admin/assets/{InsertMenuItem-BGwDW_Lu.js.map → InsertMenuItem-CCr9e0qY.js.map} +1 -1
- package/dist/admin/assets/{Match-Dc8bXsKo.js → Match-CcD9KxHH.js} +2 -2
- package/dist/admin/assets/{Match-Dc8bXsKo.js.map → Match-CcD9KxHH.js.map} +1 -1
- package/dist/admin/assets/{NoAccess-CKEKPmqD.js → NoAccess-C8RLPN0I.js} +2 -2
- package/dist/admin/assets/{NoAccess-CKEKPmqD.js.map → NoAccess-C8RLPN0I.js.map} +1 -1
- package/dist/admin/assets/{QueryView-KFtwko9F.js → QueryView-xMP_uJ_t.js} +2 -2
- package/dist/admin/assets/{QueryView-KFtwko9F.js.map → QueryView-xMP_uJ_t.js.map} +1 -1
- package/dist/admin/assets/{RadioTile-CzfxWgHx.js → RadioTile-DQFmni5A.js} +2 -2
- package/dist/admin/assets/{RadioTile-CzfxWgHx.js.map → RadioTile-DQFmni5A.js.map} +1 -1
- package/dist/admin/assets/{RichTextField-BsBoOAP-.js → RichTextField-CVHRIbnu.js} +2 -2
- package/dist/admin/assets/{RichTextField-BsBoOAP-.js.map → RichTextField-CVHRIbnu.js.map} +1 -1
- package/dist/admin/assets/{RowTitle-Cn5mAU58.js → RowTitle-Bqt6evG9.js} +2 -2
- package/dist/admin/assets/{RowTitle-Cn5mAU58.js.map → RowTitle-Bqt6evG9.js.map} +1 -1
- package/dist/admin/assets/{SecretReveal-BCOJAisI.js → SecretReveal-Bm6nYg5J.js} +2 -2
- package/dist/admin/assets/{SecretReveal-BCOJAisI.js.map → SecretReveal-Bm6nYg5J.js.map} +1 -1
- package/dist/admin/assets/{SharedGlyph-CA8tb7UH.js → SharedGlyph-cUmTh0_C.js} +2 -2
- package/dist/admin/assets/{SharedGlyph-CA8tb7UH.js.map → SharedGlyph-cUmTh0_C.js.map} +1 -1
- package/dist/admin/assets/{StepList-sriwGP1e.js → StepList-BXGYD9eJ.js} +2 -2
- package/dist/admin/assets/{StepList-sriwGP1e.js.map → StepList-BXGYD9eJ.js.map} +1 -1
- package/dist/admin/assets/Structure-D8csgrIt.js +2 -0
- package/dist/admin/assets/{Structure-B2HZ9UZu.js.map → Structure-D8csgrIt.js.map} +1 -1
- package/dist/admin/assets/{SuggestAltButton-CqDLAuoa.js → SuggestAltButton-CvIoirnz.js} +2 -2
- package/dist/admin/assets/{SuggestAltButton-CqDLAuoa.js.map → SuggestAltButton-CvIoirnz.js.map} +1 -1
- package/dist/admin/assets/{Thumbnail-mFfESZiW.js → Thumbnail-DNj5TRBI.js} +2 -2
- package/dist/admin/assets/{Thumbnail-mFfESZiW.js.map → Thumbnail-DNj5TRBI.js.map} +1 -1
- package/dist/admin/assets/{UnsavedChangesGuard-C8cDQGEA.js → UnsavedChangesGuard-CUiuMklN.js} +2 -2
- package/dist/admin/assets/{UnsavedChangesGuard-C8cDQGEA.js.map → UnsavedChangesGuard-CUiuMklN.js.map} +1 -1
- package/dist/admin/assets/{UserAvatar-BItYDTyH.js → UserAvatar-p-jV-LoD.js} +2 -2
- package/dist/admin/assets/{UserAvatar-BItYDTyH.js.map → UserAvatar-p-jV-LoD.js.map} +1 -1
- package/dist/admin/assets/{badge-DNQwGXBl.js → badge-CqKF1pwz.js} +2 -2
- package/dist/admin/assets/{badge-DNQwGXBl.js.map → badge-CqKF1pwz.js.map} +1 -1
- package/dist/admin/assets/{changeSets-EMTUJT0M.js → changeSets-8EburmT0.js} +2 -2
- package/dist/admin/assets/{changeSets-EMTUJT0M.js.map → changeSets-8EburmT0.js.map} +1 -1
- package/dist/admin/assets/{constants-miV4q1ur.js → constants-a_15vqOh.js} +2 -2
- package/dist/admin/assets/{constants-miV4q1ur.js.map → constants-a_15vqOh.js.map} +1 -1
- package/dist/admin/assets/{content-CgZS_S7P.js → content-CAjkbZEY.js} +3 -3
- package/dist/admin/assets/content-CAjkbZEY.js.map +1 -0
- package/dist/admin/assets/{contentTypes-CQsHL657.js → contentTypes-84uc0bjR.js} +2 -2
- package/dist/admin/assets/{contentTypes-CQsHL657.js.map → contentTypes-84uc0bjR.js.map} +1 -1
- package/dist/admin/assets/{develop-9ZeAjSIw.js → develop-BOqvnlgt.js} +2 -2
- package/dist/admin/assets/{develop-9ZeAjSIw.js.map → develop-BOqvnlgt.js.map} +1 -1
- package/dist/admin/assets/{dropdown-menu-0dyAtBEd.js → dropdown-menu-_xfaEp5C.js} +2 -2
- package/dist/admin/assets/{dropdown-menu-0dyAtBEd.js.map → dropdown-menu-_xfaEp5C.js.map} +1 -1
- package/dist/admin/assets/{es2015-BJge4oQL.js → es2015-BHmI7wjK.js} +2 -2
- package/dist/admin/assets/es2015-BHmI7wjK.js.map +1 -0
- package/dist/admin/assets/{field-C6NmRYUN.js → field-COOzRptX.js} +2 -2
- package/dist/admin/assets/{field-C6NmRYUN.js.map → field-COOzRptX.js.map} +1 -1
- package/dist/admin/assets/{fileRoute-Bm90K4UY.js → fileRoute-s7mCMYUJ.js} +2 -2
- package/dist/admin/assets/{fileRoute-Bm90K4UY.js.map → fileRoute-s7mCMYUJ.js.map} +1 -1
- package/dist/admin/assets/{followPlural-DEr2kxEc.js → followPlural-Cm7v_Udv.js} +2 -2
- package/dist/admin/assets/{followPlural-DEr2kxEc.js.map → followPlural-Cm7v_Udv.js.map} +1 -1
- package/dist/admin/assets/{inbox-B8XZ8L6s.js → inbox-DGO2D8fa.js} +2 -2
- package/dist/admin/assets/{inbox-B8XZ8L6s.js.map → inbox-DGO2D8fa.js.map} +1 -1
- package/dist/admin/assets/{index-DoJsnLI1.js → index-BIIU9ZI6.js} +4 -4
- package/dist/admin/assets/{index-DoJsnLI1.js.map → index-BIIU9ZI6.js.map} +1 -1
- package/dist/admin/assets/{labels-B2HIVxXg.js → labels-DQckbLGW.js} +2 -2
- package/dist/admin/assets/{labels-B2HIVxXg.js.map → labels-DQckbLGW.js.map} +1 -1
- package/dist/admin/assets/{media-CtbfNgc-.js → media-CURizGns.js} +2 -2
- package/dist/admin/assets/{media-CtbfNgc-.js.map → media-CURizGns.js.map} +1 -1
- package/dist/admin/assets/{network--5X46kWN.js → network-BixABr0o.js} +2 -2
- package/dist/admin/assets/{network--5X46kWN.js.map → network-BixABr0o.js.map} +1 -1
- package/dist/admin/assets/{publishing-DdmWXRaM.js → publishing-Dke9bSKp.js} +2 -2
- package/dist/admin/assets/{publishing-DdmWXRaM.js.map → publishing-Dke9bSKp.js.map} +1 -1
- package/dist/admin/assets/{radio-group-BoN9R_3K.js → radio-group-4ok5evXq.js} +2 -2
- package/dist/admin/assets/{radio-group-BoN9R_3K.js.map → radio-group-4ok5evXq.js.map} +1 -1
- package/dist/admin/assets/{searchSchemas-DNjfDxmj.js → searchSchemas-CSScloG8.js} +2 -2
- package/dist/admin/assets/{searchSchemas-DNjfDxmj.js.map → searchSchemas-CSScloG8.js.map} +1 -1
- package/dist/admin/assets/{sections-BfxPwK0u.js → sections-DqBzSKMP.js} +2 -2
- package/dist/admin/assets/{sections-BfxPwK0u.js.map → sections-DqBzSKMP.js.map} +1 -1
- package/dist/admin/assets/{select-Bp8kO5Ko.js → select-C0USI-Ox.js} +2 -2
- package/dist/admin/assets/{select-Bp8kO5Ko.js.map → select-C0USI-Ox.js.map} +1 -1
- package/dist/admin/assets/{settings-TEbLvC-v.js → settings-B60vHpZd.js} +2 -2
- package/dist/admin/assets/{settings-TEbLvC-v.js.map → settings-B60vHpZd.js.map} +1 -1
- package/dist/admin/assets/{shapes-WrYO9Spf.js → shapes-B5twqZcp.js} +4 -4
- package/dist/admin/assets/{shapes-WrYO9Spf.js.map → shapes-B5twqZcp.js.map} +1 -1
- package/dist/admin/assets/{skeleton-vXOCdnJv.js → skeleton-B5MP72Kw.js} +2 -2
- package/dist/admin/assets/{skeleton-vXOCdnJv.js.map → skeleton-B5MP72Kw.js.map} +1 -1
- package/dist/admin/assets/{switch-B1xClhNG.js → switch-Dp6WYNam.js} +2 -2
- package/dist/admin/assets/{switch-B1xClhNG.js.map → switch-Dp6WYNam.js.map} +1 -1
- package/dist/admin/assets/{tooltip-CS_8cJu2.js → tooltip-BGP1DVBt.js} +2 -2
- package/dist/admin/assets/{tooltip-CS_8cJu2.js.map → tooltip-BGP1DVBt.js.map} +1 -1
- package/dist/admin/assets/{useDiscardGuard-CMMJgkI2.js → useDiscardGuard-BskWSlbT.js} +2 -2
- package/dist/admin/assets/{useDiscardGuard-CMMJgkI2.js.map → useDiscardGuard-BskWSlbT.js.map} +1 -1
- package/dist/admin/assets/{useMediaPickerDialog-xvQ8cofO.js → useMediaPickerDialog-CU-ekPqX.js} +2 -2
- package/dist/admin/assets/{useMediaPickerDialog-xvQ8cofO.js.map → useMediaPickerDialog-CU-ekPqX.js.map} +1 -1
- package/dist/admin/assets/{useMediaUploader-BVNTeSAU.js → useMediaUploader-CBcq1ICg.js} +2 -2
- package/dist/admin/assets/{useMediaUploader-BVNTeSAU.js.map → useMediaUploader-CBcq1ICg.js.map} +1 -1
- package/dist/admin/assets/{useResolvedScheme-CScQpr-P.js → useResolvedScheme-C8vcQVko.js} +2 -2
- package/dist/admin/assets/{useResolvedScheme-CScQpr-P.js.map → useResolvedScheme-C8vcQVko.js.map} +1 -1
- package/dist/admin/assets/{zod-hUh5nXnX.js → zod-Cry7YvLY.js} +2 -2
- package/dist/admin/assets/{zod-hUh5nXnX.js.map → zod-Cry7YvLY.js.map} +1 -1
- package/dist/admin/index.html +25 -25
- package/dist/cli.js +1 -1
- package/dist/{cliMain-D08HeAd_.js → cliMain-papyXJDd.js} +2 -2
- package/dist/{cliMain-D08HeAd_.js.map → cliMain-papyXJDd.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/{worker-jspgh10V.js → worker-B-sC-eY2.js} +2 -2
- package/dist/{worker-jspgh10V.js.map → worker-B-sC-eY2.js.map} +1 -1
- package/package.json +5 -5
- package/dist/admin/assets/Structure-B2HZ9UZu.js +0 -2
- package/dist/admin/assets/content-CgZS_S7P.js.map +0 -1
- package/dist/admin/assets/es2015-BJge4oQL.js.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./dist-jDxVK91P.js","./dist-Di89fgee.js","./dist-Cfu6KUZc.js","./w3c-keyname-BOAvb0qz.js","./dist-HPrLaCdJ.js","./dist-fd2QE3bn.js","./dist-DwkwzYJW.js","./dist-BhQ65Acq.js","./dist-D2B8BMRO.js","./dist-BfNf0WNB.js","./dist-D84PCcMJ.js","./dist-Bj80Zlqp.js","./dist-BPSNVOQB.js","./dist-ACUwt7Zp.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{n as r}from"./createLucideIcon-CLmh7Go-.js";import{t as i,w as a}from"./InfoHint-
|
|
3
|
-
//# sourceMappingURL=CodeEditor-
|
|
2
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{n as r}from"./createLucideIcon-CLmh7Go-.js";import{t as i,w as a}from"./InfoHint-CSEtcHjL.js";import{t as o}from"./cn-DVhJ55Mo.js";import{t as s}from"./useShortcutLabel-BJMslX8p.js";import{t as c}from"./preload-helper-BaNbYf_w.js";import{i as l,n as u}from"./props-SeFhTMCi.js";import{r as d}from"./labels-DQckbLGW.js";import{n as f,t as p}from"./baseExtensions-TVKN1UwW.js";var m=e(t(),1),h={plain:()=>Promise.resolve([]),html:()=>c(async()=>{let{html:e}=await import(`./dist-jDxVK91P.js`);return{html:e}},__vite__mapDeps([0,1,2,3,4,5,6,7]),import.meta.url).then(({html:e})=>e({autoCloseTags:!1})),css:()=>c(async()=>{let{css:e}=await import(`./dist-D2B8BMRO.js`);return{css:e}},__vite__mapDeps([8,5,2,3,4]),import.meta.url).then(({css:e})=>e()),javascript:()=>c(async()=>{let{javascript:e}=await import(`./dist-BfNf0WNB.js`);return{javascript:e}},__vite__mapDeps([9,6,2,3,7,4]),import.meta.url).then(({javascript:e})=>e()),json:()=>c(async()=>{let{json:e}=await import(`./dist-D84PCcMJ.js`);return{json:e}},__vite__mapDeps([10,11,2,3,4]),import.meta.url).then(({json:e})=>e()),yaml:()=>c(async()=>{let{yaml:e}=await import(`./dist-BPSNVOQB.js`);return{yaml:e}},__vite__mapDeps([12,2,3,4]),import.meta.url).then(({yaml:e})=>e()),markdown:()=>c(async()=>{let{markdown:e}=await import(`./dist-ACUwt7Zp.js`);return{markdown:e}},__vite__mapDeps([13,2,3,7,1,4,5,6]),import.meta.url).then(({markdown:e})=>e())},g=e=>h[e](),_=[],v=e=>{let[t,n]=(0,m.useState)();return(0,m.useEffect)(()=>{let t=!0;return g(e).then(r=>{t&&n({language:e,extension:r})},t=>a(t,`Loading ${e} highlighting`)),()=>{t=!1}},[e]),t?.language===e?t.extension:_},y=e(n(),1),b=12,x=e=>{let{t}=r(),{inputId:n,labelId:a,describedBy:c,value:h,onChange:g,onBlur:_,readOnly:x,disabled:S,validation:C,field:w}=e,T=e.definition.type===`code`?e.definition.settings.language:`plain`,E=u(e,`rows`)??b,D=`${n}-keys`,O=s(`]`),k=s(`[`),A=v(T),j=x||S,M=(0,m.useMemo)(()=>[...p({id:n,labelledBy:a,describedBy:[c,D].filter(Boolean).join(` `),invalid:C.invalid,readOnly:j}),A],[n,a,c,D,C.invalid,j,A]),N=(0,m.useCallback)(e=>g(e===``?null:e),[g]);return(0,y.jsxs)(`div`,{className:`space-y-1`,children:[(0,y.jsx)(`div`,{onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||_()},style:{"--code-rows":E},className:o(`h-[calc(var(--code-rows)*1.3rem+1rem+2px)] overflow-hidden rounded-lg border border-input bg-card focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50`,C.invalid&&`border-destructive ring-destructive/20 dark:ring-destructive/40`,S&&`opacity-50`),children:(0,y.jsx)(f,{value:l(h),onChange:N,extensions:M})}),(0,y.jsxs)(`div`,{className:`flex items-center gap-1 text-meta text-muted-foreground`,children:[(0,y.jsx)(`span`,{children:d(T)}),(0,y.jsx)(i,{about:w.label,id:D,children:t(`content.fields.code.keys`,{indent:O,outdent:k})})]})]})};export{x as CodeEditor};
|
|
3
|
+
//# sourceMappingURL=CodeEditor-CBCR73Wd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"mappings":"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","names":["LOADERS","__vitePreload","html","css","javascript","json","yaml","markdown","languageExtension","language","NONE","useLanguageExtension","loaded","setLoaded","useState","import_react","current","reportError","error","DEFAULT_ROWS","CodeEditor","useTranslation","props","rows","numberOption","hintId","inputId","indent","useShortcutLabel","outdent","languageSupport","locked","readOnly","disabled","extensions","useMemo","baseExtensions","labelId","describedBy","validation","handleChange","useCallback","onChange","text","import_jsx_runtime","event","onBlur","cn","CodeMirror","textValue","value","valueLabel","InfoHint","field"],"ignoreList":[],"sources":["../../src/components/CodeMirror/helpers/languages.ts","../../src/fields/CodeEditor/hooks/useLanguageExtension.ts","../../src/fields/CodeEditor/index.tsx"],"sourcesContent":["import type { Extension } from '@codemirror/state';\nimport type { CodeLanguage } from '@shapio/schema';\n\n/**\n * Language support per code language, each pack its own chunk: loaded only when an editor for that language\n * opens. HTML closes no tags on its own (no editor here inserts text the person did not type).\n */\nconst LOADERS: Readonly<Record<CodeLanguage, () => Promise<Extension>>> = {\n plain: () => Promise.resolve([]),\n html: () => import('@codemirror/lang-html').then(({ html }) => html({ autoCloseTags: false })),\n css: () => import('@codemirror/lang-css').then(({ css }) => css()),\n javascript: () => import('@codemirror/lang-javascript').then(({ javascript }) => javascript()),\n json: () => import('@codemirror/lang-json').then(({ json }) => json()),\n yaml: () => import('@codemirror/lang-yaml').then(({ yaml }) => yaml()),\n markdown: () => import('@codemirror/lang-markdown').then(({ markdown }) => markdown()),\n};\n\nexport const languageExtension = (language: CodeLanguage): Promise<Extension> => LOADERS[language]();\n","import type { Extension } from '@codemirror/state';\nimport type { CodeLanguage } from '@shapio/schema';\nimport { useEffect, useState } from 'react';\nimport { languageExtension } from '@/components/CodeMirror/helpers/languages';\nimport { reportError } from '@/helpers/reportError';\n\nconst NONE: Extension = [];\n\n/**\n * The language support for a code field, loaded on demand. Until its pack arrives (and if it fails to load)\n * the editor shows plain text; the editor reconfigures when it lands.\n */\nexport const useLanguageExtension = (language: CodeLanguage): Extension => {\n const [loaded, setLoaded] = useState<{ language: CodeLanguage; extension: Extension }>();\n useEffect(() => {\n let current = true;\n languageExtension(language).then(\n (extension) => {\n if (current) {\n setLoaded({ language, extension });\n }\n },\n (error: unknown) => reportError(error, `Loading ${language} highlighting`),\n );\n return () => {\n current = false;\n };\n }, [language]);\n return loaded?.language === language ? loaded.extension : NONE;\n};\n","import type { CSSProperties, FocusEvent } from 'react';\nimport { useCallback, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CodeMirror } from '@/components/CodeMirror';\nimport { baseExtensions } from '@/components/CodeMirror/helpers/baseExtensions';\nimport { InfoHint } from '@/components/InfoHint';\nimport { valueLabel } from '@/features/Models/helpers/labels';\nimport { useShortcutLabel } from '@/features/Shell/hooks/useShortcutLabel';\nimport { cn } from '@/helpers/cn';\nimport { numberOption, textValue } from '../helpers/props';\nimport type { BuiltInEditorProps } from '../types';\nimport { useLanguageExtension } from './hooks/useLanguageExtension';\n\nconst DEFAULT_ROWS = 12;\n\n/**\n * `codeEditor`: a `code` field's text in CodeMirror, highlighted for the field's language (its pack loads on\n * demand). Shapio never changes the code: the text is the value, and an empty editor is `null`. Tab moves on,\n * as everywhere in the admin; the hint says how to indent. Loaded lazily with its own chunk.\n */\nexport const CodeEditor = (props: BuiltInEditorProps) => {\n const { t } = useTranslation();\n const { inputId, labelId, describedBy, value, onChange, onBlur, readOnly, disabled, validation, field } =\n props;\n const language = props.definition.type === 'code' ? props.definition.settings.language : 'plain';\n const rows = numberOption(props, 'rows') ?? DEFAULT_ROWS;\n const hintId = `${inputId}-keys`;\n const indent = useShortcutLabel(']');\n const outdent = useShortcutLabel('[');\n const languageSupport = useLanguageExtension(language);\n const locked = readOnly || disabled;\n const extensions = useMemo(\n () => [\n ...baseExtensions({\n id: inputId,\n labelledBy: labelId,\n describedBy: [describedBy, hintId].filter(Boolean).join(' '),\n invalid: validation.invalid,\n readOnly: locked,\n }),\n languageSupport,\n ],\n [inputId, labelId, describedBy, hintId, validation.invalid, locked, languageSupport],\n );\n const handleChange = useCallback((text: string) => onChange(text === '' ? null : text), [onChange]);\n const handleBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n onBlur();\n }\n };\n return (\n <div className=\"space-y-1\">\n <div\n onBlur={handleBlur}\n style={{ '--code-rows': rows } as CSSProperties}\n className={cn(\n 'h-[calc(var(--code-rows)*1.3rem+1rem+2px)] overflow-hidden rounded-lg border border-input bg-card focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50',\n validation.invalid && 'border-destructive ring-destructive/20 dark:ring-destructive/40',\n disabled && 'opacity-50',\n )}\n >\n <CodeMirror value={textValue(value)} onChange={handleChange} extensions={extensions} />\n </div>\n <div className=\"flex items-center gap-1 text-meta text-muted-foreground\">\n <span>{valueLabel(language)}</span>\n <InfoHint about={field.label} id={hintId}>\n {t('content.fields.code.keys', { indent, outdent })}\n </InfoHint>\n </div>\n </div>\n );\n};\n"],"file":"CodeEditor-
|
|
1
|
+
{"version":3,"mappings":"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","names":["LOADERS","__vitePreload","html","css","javascript","json","yaml","markdown","languageExtension","language","NONE","useLanguageExtension","loaded","setLoaded","useState","import_react","current","reportError","error","DEFAULT_ROWS","CodeEditor","useTranslation","props","rows","numberOption","hintId","inputId","indent","useShortcutLabel","outdent","languageSupport","locked","readOnly","disabled","extensions","useMemo","baseExtensions","labelId","describedBy","validation","handleChange","useCallback","onChange","text","import_jsx_runtime","event","onBlur","cn","CodeMirror","textValue","value","valueLabel","InfoHint","field"],"ignoreList":[],"sources":["../../src/components/CodeMirror/helpers/languages.ts","../../src/fields/CodeEditor/hooks/useLanguageExtension.ts","../../src/fields/CodeEditor/index.tsx"],"sourcesContent":["import type { Extension } from '@codemirror/state';\nimport type { CodeLanguage } from '@shapio/schema';\n\n/**\n * Language support per code language, each pack its own chunk: loaded only when an editor for that language\n * opens. HTML closes no tags on its own (no editor here inserts text the person did not type).\n */\nconst LOADERS: Readonly<Record<CodeLanguage, () => Promise<Extension>>> = {\n plain: () => Promise.resolve([]),\n html: () => import('@codemirror/lang-html').then(({ html }) => html({ autoCloseTags: false })),\n css: () => import('@codemirror/lang-css').then(({ css }) => css()),\n javascript: () => import('@codemirror/lang-javascript').then(({ javascript }) => javascript()),\n json: () => import('@codemirror/lang-json').then(({ json }) => json()),\n yaml: () => import('@codemirror/lang-yaml').then(({ yaml }) => yaml()),\n markdown: () => import('@codemirror/lang-markdown').then(({ markdown }) => markdown()),\n};\n\nexport const languageExtension = (language: CodeLanguage): Promise<Extension> => LOADERS[language]();\n","import type { Extension } from '@codemirror/state';\nimport type { CodeLanguage } from '@shapio/schema';\nimport { useEffect, useState } from 'react';\nimport { languageExtension } from '@/components/CodeMirror/helpers/languages';\nimport { reportError } from '@/helpers/reportError';\n\nconst NONE: Extension = [];\n\n/**\n * The language support for a code field, loaded on demand. Until its pack arrives (and if it fails to load)\n * the editor shows plain text; the editor reconfigures when it lands.\n */\nexport const useLanguageExtension = (language: CodeLanguage): Extension => {\n const [loaded, setLoaded] = useState<{ language: CodeLanguage; extension: Extension }>();\n useEffect(() => {\n let current = true;\n languageExtension(language).then(\n (extension) => {\n if (current) {\n setLoaded({ language, extension });\n }\n },\n (error: unknown) => reportError(error, `Loading ${language} highlighting`),\n );\n return () => {\n current = false;\n };\n }, [language]);\n return loaded?.language === language ? loaded.extension : NONE;\n};\n","import type { CSSProperties, FocusEvent } from 'react';\nimport { useCallback, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CodeMirror } from '@/components/CodeMirror';\nimport { baseExtensions } from '@/components/CodeMirror/helpers/baseExtensions';\nimport { InfoHint } from '@/components/InfoHint';\nimport { valueLabel } from '@/features/Models/helpers/labels';\nimport { useShortcutLabel } from '@/features/Shell/hooks/useShortcutLabel';\nimport { cn } from '@/helpers/cn';\nimport { numberOption, textValue } from '../helpers/props';\nimport type { BuiltInEditorProps } from '../types';\nimport { useLanguageExtension } from './hooks/useLanguageExtension';\n\nconst DEFAULT_ROWS = 12;\n\n/**\n * `codeEditor`: a `code` field's text in CodeMirror, highlighted for the field's language (its pack loads on\n * demand). Shapio never changes the code: the text is the value, and an empty editor is `null`. Tab moves on,\n * as everywhere in the admin; the hint says how to indent. Loaded lazily with its own chunk.\n */\nexport const CodeEditor = (props: BuiltInEditorProps) => {\n const { t } = useTranslation();\n const { inputId, labelId, describedBy, value, onChange, onBlur, readOnly, disabled, validation, field } =\n props;\n const language = props.definition.type === 'code' ? props.definition.settings.language : 'plain';\n const rows = numberOption(props, 'rows') ?? DEFAULT_ROWS;\n const hintId = `${inputId}-keys`;\n const indent = useShortcutLabel(']');\n const outdent = useShortcutLabel('[');\n const languageSupport = useLanguageExtension(language);\n const locked = readOnly || disabled;\n const extensions = useMemo(\n () => [\n ...baseExtensions({\n id: inputId,\n labelledBy: labelId,\n describedBy: [describedBy, hintId].filter(Boolean).join(' '),\n invalid: validation.invalid,\n readOnly: locked,\n }),\n languageSupport,\n ],\n [inputId, labelId, describedBy, hintId, validation.invalid, locked, languageSupport],\n );\n const handleChange = useCallback((text: string) => onChange(text === '' ? null : text), [onChange]);\n const handleBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n onBlur();\n }\n };\n return (\n <div className=\"space-y-1\">\n <div\n onBlur={handleBlur}\n style={{ '--code-rows': rows } as CSSProperties}\n className={cn(\n 'h-[calc(var(--code-rows)*1.3rem+1rem+2px)] overflow-hidden rounded-lg border border-input bg-card focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50',\n validation.invalid && 'border-destructive ring-destructive/20 dark:ring-destructive/40',\n disabled && 'opacity-50',\n )}\n >\n <CodeMirror value={textValue(value)} onChange={handleChange} extensions={extensions} />\n </div>\n <div className=\"flex items-center gap-1 text-meta text-muted-foreground\">\n <span>{valueLabel(language)}</span>\n <InfoHint about={field.label} id={hintId}>\n {t('content.fields.code.keys', { indent, outdent })}\n </InfoHint>\n </div>\n </div>\n );\n};\n"],"file":"CodeEditor-CBCR73Wd.js"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{n as r}from"./createLucideIcon-CLmh7Go-.js";import{w as i}from"./InfoHint-
|
|
2
|
-
//# sourceMappingURL=CopyButton-
|
|
1
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{n as r}from"./createLucideIcon-CLmh7Go-.js";import{w as i}from"./InfoHint-CSEtcHjL.js";import{c as a,i as o}from"./skeleton-B5MP72Kw.js";import{t as s}from"./copy-CsSRHgKZ.js";var c=e(t(),1),l=e(n(),1),u=2e3,d=({value:e,ref:t})=>{let{t:n}=r(),[d,f]=(0,c.useState)(!1),p=async()=>{try{await navigator.clipboard.writeText(e),f(!0),setTimeout(()=>f(!1),u)}catch(e){i(e,`copy to clipboard`)}};return(0,l.jsxs)(o,{ref:t,type:`button`,variant:`outline`,onClick:()=>void p(),children:[d?(0,l.jsx)(a,{"aria-hidden":`true`}):(0,l.jsx)(s,{"aria-hidden":`true`}),(0,l.jsx)(`span`,{"aria-live":`polite`,children:n(d?`common.copied`:`common.copy`)})]})};export{d as t};
|
|
2
|
+
//# sourceMappingURL=CopyButton-CxFsBHfF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyButton-
|
|
1
|
+
{"version":3,"file":"CopyButton-CxFsBHfF.js","names":["useState","__toESM","require_jsx_runtime","useTranslation","reportError","Check","Button","Copy","import_react","require_react","import_jsx_runtime","COPIED_RESET_MS","CopyButton","copied","setCopied","copy","value","error","t"],"sources":["../../src/components/CopyButton/index.tsx"],"sourcesContent":["import { Check, Copy } from 'lucide-react';\nimport { useState, type Ref } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { reportError } from '@/helpers/reportError';\n\ntype CopyButtonProps = {\n value: string;\n /** For a caller that moves focus to the button (SecretReveal on mount). */\n ref?: Ref<HTMLButtonElement>;\n};\n\nconst COPIED_RESET_MS = 2000;\n\nexport const CopyButton = ({ value, ref }: CopyButtonProps) => {\n const { t } = useTranslation();\n const [copied, setCopied] = useState(false);\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n setTimeout(() => setCopied(false), COPIED_RESET_MS);\n } catch (error) {\n reportError(error, 'copy to clipboard');\n }\n };\n return (\n <Button ref={ref} type=\"button\" variant=\"outline\" onClick={() => void copy()}>\n {copied ? <Check aria-hidden=\"true\" /> : <Copy aria-hidden=\"true\" />}\n <span aria-live=\"polite\">{copied ? t('common.copied') : t('common.copy')}</span>\n </Button>\n );\n};\n"],"mappings":"qVAYMW,EAAkB,IAEXC,GAAc,CAAE,QAAO,SAA2B,CAC7D,GAAM,CAAE,KAAMT,EAAe,EACvB,CAACU,EAAQC,IAAA,EAAad,EAAAA,SAAAA,CAAS,EAAK,EACpCe,EAAO,SAAY,CACvB,GAAI,CACF,MAAM,UAAU,UAAU,UAAUC,CAAK,EACzCF,EAAU,EAAI,EACd,eAAiBA,EAAU,EAAK,EAAGH,CAAe,CACpD,OAASM,EAAO,CACdb,EAAYa,EAAO,mBAAmB,CACxC,CACF,EACA,OACE,EAAAP,EAAA,KAAA,CAACJ,EAAD,CAAa,MAAK,KAAK,SAAS,QAAQ,UAAU,YAAe,KAAKS,EAAK,EAA3E,SAAA,CACGF,GAAS,EAAAH,EAAA,IAAA,CAACL,EAAD,CAAO,cAAY,MAAQ,CAAA,GAAI,EAAAK,EAAA,IAAA,CAACH,EAAD,CAAM,cAAY,MAAQ,CAAA,GACnE,EAAAG,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,SAAU,SAASQ,EAATL,EAAW,gBAAqB,aAAa,CAAQ,CAAA,CACzE,GAEZ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./jsx-runtime-DREnUpxT.js";import{n,t as r}from"./createLucideIcon-CLmh7Go-.js";import{i,s as a}from"./skeleton-
|
|
2
|
-
//# sourceMappingURL=CursorPager-
|
|
1
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./jsx-runtime-DREnUpxT.js";import{n,t as r}from"./createLucideIcon-CLmh7Go-.js";import{i,s as a}from"./skeleton-B5MP72Kw.js";import{t as o}from"./chevron-left-DGU3HGYG.js";import{t as s}from"./cn-DVhJ55Mo.js";var c={name:`chevrons-left`,size:24,node:[[`path`,{d:`m11 17-5-5 5-5`,key:`13zhaf`}],[`path`,{d:`m18 17-5-5 5-5`,key:`h8a8et`}]]};c.node;var l=r(c),u=e(t(),1),d=({onFirst:e,onPrevious:t,onNext:r,className:c})=>{let{t:d}=n();return(0,u.jsxs)(`nav`,{"aria-label":d(`common.pagination`),className:s(`flex items-center justify-end gap-2`,c),children:[(0,u.jsx)(i,{variant:`outline`,size:`icon-sm`,"aria-label":d(`common.first`),disabled:!e,onClick:e,children:(0,u.jsx)(l,{"aria-hidden":`true`})}),(0,u.jsx)(i,{variant:`outline`,size:`icon-sm`,"aria-label":d(`common.previous`),disabled:!t,onClick:t,children:(0,u.jsx)(o,{"aria-hidden":`true`})}),(0,u.jsx)(i,{variant:`outline`,size:`icon-sm`,"aria-label":d(`common.next`),disabled:!r,onClick:r,children:(0,u.jsx)(a,{"aria-hidden":`true`})})]})};export{d as t};
|
|
2
|
+
//# sourceMappingURL=CursorPager-BW2U3v6l.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CursorPager-
|
|
1
|
+
{"version":3,"file":"CursorPager-BW2U3v6l.js","names":["__toESM","createLucideIcon","ChevronRight","ChevronLeft","cn","__iconData","ChevronsLeft","import_jsx_runtime","require_jsx_runtime","CursorPager","useTranslation","t","className","Button","onFirst","onPrevious","onNext"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/chevrons-left.mjs","../../src/components/CursorPager/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.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 __iconData = {\n name: \"chevrons-left\",\n size: 24,\n node: [\n [\"path\", { d: \"m11 17-5-5 5-5\", key: \"13zhaf\" }],\n [\"path\", { d: \"m18 17-5-5 5-5\", key: \"h8a8et\" }]\n ]\n};\n__iconData.node;\nconst ChevronsLeft = createLucideIcon(__iconData);\n\nexport { __iconData, ChevronsLeft as default };\n//# sourceMappingURL=chevrons-left.mjs.map\n","import { ChevronLeft, ChevronRight, ChevronsLeft } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/helpers/cn';\n\ntype CursorPagerProps = {\n /** Undefined when already on the first page. */\n onFirst: (() => void) | undefined;\n onPrevious: (() => void) | undefined;\n /** Undefined when there is no further page. */\n onNext: (() => void) | undefined;\n className?: string;\n};\n\n/** Paging for cursor-paginated lists (newest first, no total): Newest, Previous, Next as icon buttons. */\nexport const CursorPager = ({ onFirst, onPrevious, onNext, className }: CursorPagerProps) => {\n const { t } = useTranslation();\n return (\n <nav aria-label={t('common.pagination')} className={cn('flex items-center justify-end gap-2', className)}>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={t('common.first')}\n disabled={!onFirst}\n onClick={onFirst}\n >\n <ChevronsLeft aria-hidden=\"true\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={t('common.previous')}\n disabled={!onPrevious}\n onClick={onPrevious}\n >\n <ChevronLeft aria-hidden=\"true\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n aria-label={t('common.next')}\n disabled={!onNext}\n onClick={onNext}\n >\n <ChevronRight aria-hidden=\"true\" />\n </Button>\n </nav>\n );\n};\n"],"ignoreList":[0],"mappings":"kRASA,IAAMK,EAAa,CACjB,KAAM,gBACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAS,CAAC,EAC/C,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAS,CAAC,CACjD,CACF,EACAA,EAAW,KACX,IAAMC,EAAeL,EAAiBI,CAAU,aCHnCI,GAAe,CAAE,UAAS,aAAY,SAAQ,eAAkC,CAC3F,GAAM,CAAE,KAAMC,EAAe,EAC7B,OACE,EAAAH,EAAA,KAAA,CAAC,MAAD,CAAK,aAAYI,EAAE,mBAAmB,EAAG,UAAWP,EAAG,sCAAuCQ,CAAS,EAAvG,SAAA,EACE,EAAAL,EAAA,IAAA,CAACM,EAAD,CACE,QAAQ,UACR,KAAK,UACL,aAAYF,EAAE,cAAc,EAC5B,SAAU,CAACG,EACX,QAASA,EAET,UAAA,EAAAP,EAAA,IAAA,CAACD,EAAD,CAAc,cAAY,MAAQ,CAAA,CAC5B,CAAA,GACR,EAAAC,EAAA,IAAA,CAACM,EAAD,CACE,QAAQ,UACR,KAAK,UACL,aAAYF,EAAE,iBAAiB,EAC/B,SAAU,CAACI,EACX,QAASA,EAET,UAAA,EAAAR,EAAA,IAAA,CAACJ,EAAD,CAAa,cAAY,MAAQ,CAAA,CAC3B,CAAA,GACR,EAAAI,EAAA,IAAA,CAACM,EAAD,CACE,QAAQ,UACR,KAAK,UACL,aAAYF,EAAE,aAAa,EAC3B,SAAU,CAACK,EACX,QAASA,EAET,UAAA,EAAAT,EAAA,IAAA,CAACL,EAAD,CAAc,cAAY,MAAQ,CAAA,CAC5B,CAAA,CACL,GAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{n as r,t as i}from"./createLucideIcon-CLmh7Go-.js";import{t as a}from"./InfoHint-
|
|
2
|
-
//# sourceMappingURL=FocalPoint-
|
|
1
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{n as r,t as i}from"./createLucideIcon-CLmh7Go-.js";import{t as a}from"./InfoHint-CSEtcHjL.js";import{i as o,n as s}from"./skeleton-B5MP72Kw.js";import{c,o as l,s as u,t as d}from"./field-COOzRptX.js";var f={name:`crosshair`,size:24,node:[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`22`,x2:`18`,y1:`12`,y2:`12`,key:`l9bcsi`}],[`line`,{x1:`6`,x2:`2`,y1:`12`,y2:`12`,key:`13hhkx`}],[`line`,{x1:`12`,x2:`12`,y1:`6`,y2:`2`,key:`10w3f3`}],[`line`,{x1:`12`,x2:`12`,y1:`22`,y2:`18`,key:`15g9kq`}]]};f.node;var p=i(f),m=e(t(),1),h=e(n(),1),g=100,_={x:.5,y:.5},v=e=>Math.min(1,Math.max(0,e)),y=({imageUrl:e,value:t,onChange:n})=>{let{t:i}=r(),f=(0,m.useId)(),y=t??_,b=e=>{let t=e.currentTarget.getBoundingClientRect();n({x:v((e.clientX-t.left)/t.width),y:v((e.clientY-t.top)/t.height)})},x=(e,t)=>{let r=Number(t);t!==``&&Number.isFinite(r)&&n({...y,[e]:v(r/g)})};return(0,h.jsxs)(c,{"aria-labelledby":`${f}-title`,children:[(0,h.jsxs)(u,{variant:`label`,className:`flex items-center gap-1`,children:[(0,h.jsx)(`span`,{id:`${f}-title`,children:i(`media.focal.title`)}),(0,h.jsx)(a,{about:i(`media.focal.title`),children:i(`media.focal.hint`)})]}),(0,h.jsxs)(`div`,{"aria-hidden":`true`,onClick:b,className:`relative w-fit max-w-full cursor-crosshair overflow-hidden rounded-lg border`,style:{"--focal-x":`${y.x*g}%`,"--focal-y":`${y.y*g}%`},children:[(0,h.jsx)(`img`,{src:e,alt:``,className:`block max-h-64 w-auto`,draggable:!1}),t?(0,h.jsx)(`span`,{className:`absolute top-[var(--focal-y)] left-[var(--focal-x)] flex size-6 -translate-1/2 items-center justify-center rounded-full border-2 border-background bg-primary text-primary-foreground shadow`,children:(0,h.jsx)(p,{className:`size-3.5`})}):null]}),(0,h.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,h.jsxs)(d,{className:`w-28`,children:[(0,h.jsx)(l,{htmlFor:`${f}-x`,children:i(`media.focal.x`)}),(0,h.jsx)(s,{id:`${f}-x`,type:`number`,min:0,max:g,step:1,value:t?Math.round(t.x*g):``,placeholder:i(`media.focal.unset`),onChange:e=>x(`x`,e.target.value)})]}),(0,h.jsxs)(d,{className:`w-28`,children:[(0,h.jsx)(l,{htmlFor:`${f}-y`,children:i(`media.focal.y`)}),(0,h.jsx)(s,{id:`${f}-y`,type:`number`,min:0,max:g,step:1,value:t?Math.round(t.y*g):``,placeholder:i(`media.focal.unset`),onChange:e=>x(`y`,e.target.value)})]}),(0,h.jsx)(o,{type:`button`,variant:`ghost`,size:`sm`,disabled:!t,onClick:()=>n(null),children:i(`media.focal.clear`)})]})]})};export{p as n,y as t};
|
|
2
|
+
//# sourceMappingURL=FocalPoint-CpZTve1E.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocalPoint-
|
|
1
|
+
{"version":3,"file":"FocalPoint-CpZTve1E.js","names":["useId","__toESM","require_jsx_runtime","useTranslation","createLucideIcon","InfoHint","Button","Input","FieldLabel","FieldLegend","Field","__iconData","Crosshair","import_react","require_react","import_jsx_runtime","PERCENT","CENTRE","clamp","value","FocalPoint","id","point","place","box","event","onChange","setAxis","number","text","axis","FieldSet","t","imageUrl"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/crosshair.mjs","../../src/components/FocalPoint/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.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 __iconData = {\n name: \"crosshair\",\n size: 24,\n node: [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"22\", x2: \"18\", y1: \"12\", y2: \"12\", key: \"l9bcsi\" }],\n [\"line\", { x1: \"6\", x2: \"2\", y1: \"12\", y2: \"12\", key: \"13hhkx\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"6\", y2: \"2\", key: \"10w3f3\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"22\", y2: \"18\", key: \"15g9kq\" }]\n ]\n};\n__iconData.node;\nconst Crosshair = createLucideIcon(__iconData);\n\nexport { __iconData, Crosshair as default };\n//# sourceMappingURL=crosshair.mjs.map\n","import type { MediaFocalPoint } from '@shapio/client';\nimport { Crosshair } from 'lucide-react';\nimport { useId, type CSSProperties, type MouseEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InfoHint } from '@/components/InfoHint';\nimport { Button } from '@/components/ui/button';\nimport { Field, FieldLabel, FieldLegend, FieldSet } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\n\ntype FocalPointProps = {\n imageUrl: string;\n value: MediaFocalPoint | null;\n onChange: (value: MediaFocalPoint | null) => void;\n};\n\nconst PERCENT = 100;\nconst CENTRE: MediaFocalPoint = { x: 0.5, y: 0.5 };\n\nconst clamp = (value: number) => Math.min(1, Math.max(0, value));\n\n/**\n * The point crops keep in view. Click the image to place it; the percentage inputs are the keyboard path\n * (the image itself is a pointer shortcut and hidden from assistive technology).\n */\nexport const FocalPoint = ({ imageUrl, value, onChange }: FocalPointProps) => {\n const { t } = useTranslation();\n // Unique per instance: the media details sheet and the entry's settings drawer can both show one.\n const id = useId();\n const point = value ?? CENTRE;\n const place = (event: MouseEvent<HTMLDivElement>) => {\n const box = event.currentTarget.getBoundingClientRect();\n onChange({\n x: clamp((event.clientX - box.left) / box.width),\n y: clamp((event.clientY - box.top) / box.height),\n });\n };\n const setAxis = (axis: 'x' | 'y', text: string) => {\n const number = Number(text);\n if (text !== '' && Number.isFinite(number)) {\n onChange({ ...point, [axis]: clamp(number / PERCENT) });\n }\n };\n return (\n <FieldSet aria-labelledby={`${id}-title`}>\n <FieldLegend variant=\"label\" className=\"flex items-center gap-1\">\n <span id={`${id}-title`}>{t('media.focal.title')}</span>\n <InfoHint about={t('media.focal.title')}>{t('media.focal.hint')}</InfoHint>\n </FieldLegend>\n <div\n aria-hidden=\"true\"\n onClick={place}\n className=\"relative w-fit max-w-full cursor-crosshair overflow-hidden rounded-lg border\"\n style={\n { '--focal-x': `${point.x * PERCENT}%`, '--focal-y': `${point.y * PERCENT}%` } as CSSProperties\n }\n >\n <img src={imageUrl} alt=\"\" className=\"block max-h-64 w-auto\" draggable={false} />\n {value ? (\n <span className=\"absolute top-[var(--focal-y)] left-[var(--focal-x)] flex size-6 -translate-1/2 items-center justify-center rounded-full border-2 border-background bg-primary text-primary-foreground shadow\">\n <Crosshair className=\"size-3.5\" />\n </span>\n ) : null}\n </div>\n <div className=\"flex flex-wrap items-end gap-3\">\n <Field className=\"w-28\">\n <FieldLabel htmlFor={`${id}-x`}>{t('media.focal.x')}</FieldLabel>\n <Input\n id={`${id}-x`}\n type=\"number\"\n min={0}\n max={PERCENT}\n step={1}\n value={value ? Math.round(value.x * PERCENT) : ''}\n placeholder={t('media.focal.unset')}\n onChange={(event) => setAxis('x', event.target.value)}\n />\n </Field>\n <Field className=\"w-28\">\n <FieldLabel htmlFor={`${id}-y`}>{t('media.focal.y')}</FieldLabel>\n <Input\n id={`${id}-y`}\n type=\"number\"\n min={0}\n max={PERCENT}\n step={1}\n value={value ? Math.round(value.y * PERCENT) : ''}\n placeholder={t('media.focal.unset')}\n onChange={(event) => setAxis('y', event.target.value)}\n />\n </Field>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" disabled={!value} onClick={() => onChange(null)}>\n {t('media.focal.clear')}\n </Button>\n </div>\n </FieldSet>\n );\n};\n"],"ignoreList":[0],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{$ as r,Pt as i,b as a,bn as o,g as s,x as c,y as l}from"./src-ndgTSYLX.js";import{E as u,S as d,o as ee,u as f,x as p}from"./auth-CQO4MBUj.js";import{_ as te,a as m,i as h,n as g}from"./badge-DNQwGXBl.js";import{n as _,t as v}from"./createLucideIcon-CLmh7Go-.js";import{i as y,n as b,t as x}from"./RowTitle-Cn5mAU58.js";import{t as ne}from"./UnsavedChangesGuard-C8cDQGEA.js";import{E as S,t as C}from"./InfoHint-B3XcXtiN.js";import{T as w}from"./es2015-BJge4oQL.js";import{a as T,i as re,l as E,r as D,u as ie}from"./constants-miV4q1ur.js";import{t as O}from"./useSchemaScopeAccess-ByrxIdKM.js";import{i as ae}from"./skeleton-vXOCdnJv.js";import{a as oe}from"./InlineConfirm-BfsNH5S_.js";import{a as k,c as A,s as j}from"./field-C6NmRYUN.js";import{t as M}from"./cn-DVhJ55Mo.js";import{t as N}from"./radio-group-BoN9R_3K.js";import{c as P,f as F,n as I,o as se,t as ce,u as le}from"./zod-hUh5nXnX.js";import{t as ue}from"./settle-CFU6YpQ0.js";import{a as de,d as fe,g as L,i as R,l as z,n as B,o as V,r as H,s as pe,t as me,v as U}from"./table-zG68ipQc.js";import{t as he}from"./SharedGlyph-CA8tb7UH.js";import{a as ge,p as _e,s as ve,v as ye}from"./schema-D-qo7XSF.js";import{t as be}from"./Panel-Bcl09TtM.js";import{t as W}from"./NoAccess-CKEKPmqD.js";import{a as xe,i as Se,n as Ce,r as G,t as we}from"./followPlural-DEr2kxEc.js";import{t as K}from"./RadioTile-CzfxWgHx.js";import{t as Te}from"./FormSwitchField-d8G-YCSX.js";import{t as Ee}from"./FormTextareaField-BSKNeTPW.js";var q={name:`app-window`,size:24,node:[[`rect`,{x:`2`,y:`4`,width:`20`,height:`16`,rx:`2`,key:`izxlao`}],[`path`,{d:`M10 4v4`,key:`pp8u80`}],[`path`,{d:`M2 8h20`,key:`d11cs7`}],[`path`,{d:`M6 4v4`,key:`1svtjw`}]]};q.node;var De=v(q),J=e(n(),1),Oe=({definition:e})=>(0,J.jsx)(x,{asChild:!0,children:e.kind===`component`?(0,J.jsx)(d,{to:`/models/components/$componentId`,params:{componentId:e.id},children:e.label}):(0,J.jsx)(d,{to:`/models/$modelId`,params:{modelId:e.id},children:e.label})}),Y=e(t(),1),ke=({changeId:e})=>{let{t}=_(),n=_e(e),r=o(),a=n.data?.status,s=a!==void 0&&ye.has(a);return(0,Y.useEffect)(()=>{s&&r.invalidateQueries({queryKey:i.schema.all})},[s,r]),s||n.isError?null:(0,J.jsx)(g,{tone:`progress`,size:`sm`,label:t(`models.pendingChange`)})},Ae=e=>e.kind===`collection`?`${e.apiKey} · ${s(e)}`:e.apiKey,je=({items:e,showKind:t=!1,markShared:n=!0})=>{let{t:r}=_(),{multiSite:i}=O(),a=n&&i;return(0,J.jsx)(pe,{children:(0,J.jsxs)(me,{children:[(0,J.jsx)(de,{children:(0,J.jsxs)(V,{children:[(0,J.jsx)(R,{children:r(`models.columns.label`)}),t?(0,J.jsx)(R,{children:r(`models.columns.kind`)}):null,(0,J.jsx)(R,{children:r(`models.columns.apiKey`)}),(0,J.jsx)(R,{className:`text-right`,children:r(`models.columns.fields`)}),(0,J.jsx)(R,{className:`text-right`,children:r(`models.columns.version`)}),(0,J.jsx)(R,{children:r(`models.columns.activated`)})]})}),(0,J.jsx)(B,{children:e.map(({definition:e,scope:n,version:i,activatedAt:o,pendingChange:s})=>(0,J.jsxs)(V,{children:[(0,J.jsx)(H,{children:(0,J.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,J.jsx)(Oe,{definition:e}),a&&n===`network`?(0,J.jsx)(he,{}):null,s?(0,J.jsx)(ke,{changeId:s.id}):null]})}),t?(0,J.jsx)(H,{className:`text-muted-foreground`,children:r(T[e.kind])}):null,(0,J.jsx)(H,{className:`font-mono text-meta text-muted-foreground`,children:Ae(e)}),(0,J.jsx)(H,{className:`text-right tabular-nums`,children:e.fields.length}),(0,J.jsx)(H,{className:`text-right text-muted-foreground tabular-nums`,children:r(`models.versionNumber`,{version:i})}),(0,J.jsx)(H,{className:`text-muted-foreground`,title:b(o),children:y(o)})]},e.id))})]})})},Me={API_KEY_INVALID:`validation.apiKeyInvalid`,API_KEY_TOO_LONG:`validation.apiKeyTooLong`,API_KEY_RESERVED_PREFIX:`validation.apiKeyReservedPrefix`},X=e=>{let t=a(e);return t?Me[t.code]??`validation.apiKeyInvalid`:null},Ne=()=>U().trim().min(1,`validation.required`).superRefine((e,t)=>{let n=X(e);n&&t.addIssue({code:`custom`,message:n})}),Pe=(e,t)=>X(e)?null:t===``?`validation.required`:c(t)===c(e)?`validation.pluralApiKeySameAsSingular`:X(t),Z=(e,t,n,r,i=!0)=>{let a=(0,Y.useRef)(e);(0,Y.useEffect)(()=>{if(!i){a.current=e;return}let o=t();(o===``||o===r(a.current))&&n(r(e)),a.current=e},[e,t,n,r,i])},Fe=(e,t,n)=>Z(e,t,n,Ce),Ie=(e,t,n)=>{let r=(0,Y.useRef)(e);(0,Y.useEffect)(()=>{let i=t(),a=we(r.current,e,i);a!==i&&n(a),r.current=e},[e,t,n])},Le=L({kind:z([`collection`,`singleton`,`component`]),label:se(),apiKey:Ne(),pluralApiKey:U().trim(),description:U().trim(),localized:fe(),scope:z([`site`,`network`])}).superRefine((e,t)=>{let n=e.kind===`collection`?Pe(e.apiKey,e.pluralApiKey):null;n&&t.addIssue({code:`custom`,path:[`pluralApiKey`],message:n})}),Re=(e,t)=>({kind:e,label:``,apiKey:``,pluralApiKey:``,description:``,localized:!1,scope:t}),ze=({kind:e,label:t,apiKey:n,pluralApiKey:r,description:i,localized:a})=>e===`component`?{kind:e,label:t,apiKey:n,description:i,fields:[]}:e===`collection`?{kind:e,label:t,apiKey:n,pluralApiKey:r,description:i,localized:a,fields:[]}:{kind:e,label:t,apiKey:n,description:i,localized:a,fields:[]},Be=e=>new Set((e??[]).flatMap(({definition:e})=>[e.apiKey,...r(e)?[s(e)]:[]].map(c))),Q=[`label`,`apiKey`,`pluralApiKey`],Ve=new Set(Q.map(e=>`/${e}`)),He=e=>{let t=p(e);if(!(t.length===0||t.some(e=>Ve.has(e.path))))return t.map(G).join(` `)},Ue=(e,t=`site`)=>{let n=ve(),{definitions:r}=ge(),i=u(),a=le({resolver:ce(Le),defaultValues:Re(e,t)}),{setValue:o,setError:s,getValues:l}=a;return Fe(F({control:a.control,name:`label`}),(0,Y.useCallback)(()=>l(`apiKey`),[l]),(0,Y.useCallback)(e=>o(`apiKey`,e,{shouldValidate:!1}),[o])),Ie(F({control:a.control,name:`apiKey`}),(0,Y.useCallback)(()=>l(`pluralApiKey`),[l]),(0,Y.useCallback)(e=>o(`pluralApiKey`,e,{shouldValidate:!1}),[o])),{form:a,onSubmit:a.handleSubmit(async e=>{let t=Be(r);if(t.has(c(e.apiKey))){s(`apiKey`,{message:`validation.apiKeyTaken`});return}if(e.kind===`collection`&&t.has(c(e.pluralApiKey))){s(`pluralApiKey`,{message:`validation.apiKeyTaken`});return}let a=E(e.kind),o=await ue(n.mutateAsync({category:a,input:{definition:ze(e),scope:e.scope}}));if(!o.ok){let e=p(o.error);for(let t of Q){let n=e.find(e=>e.path===`/${t}`);n&&s(t,{message:G(n)})}return}S.success(w.t(`models.created`));let l=o.value.definitionId;await i(a===`component`?{to:`/models/components/$componentId`,params:{componentId:l},ignoreBlocker:!0}:{to:`/models/$modelId`,params:{modelId:l},ignoreBlocker:!0})}),pending:n.isPending,error:n.error,errorMessage:He(n.error)}},$=({label:e,names:t})=>(0,J.jsxs)(`div`,{className:`flex min-w-0 items-baseline gap-2`,children:[(0,J.jsx)(`dt`,{className:`w-14 shrink-0`,children:e}),(0,J.jsx)(`dd`,{className:`flex min-w-0 flex-wrap gap-1.5`,children:t.map(e=>(0,J.jsx)(`code`,{className:`max-w-full truncate rounded bg-muted px-1.5 py-0.5 font-mono text-foreground/80`,children:e},e))})]}),We=({apiKey:e,pluralApiKey:t,kind:n})=>{let{t:r}=_(),i=e.trim();if(i===``||n===`component`)return null;let a=t.trim()||l(i),o=n===`collection`?a:i,s=n===`collection`?[i,a]:[i];return(0,J.jsxs)(`dl`,{className:`flex flex-col gap-1 text-xs text-muted-foreground`,children:[(0,J.jsx)($,{label:r(`models.restLabel`),names:[r(`models.endpointPath`,{routeKey:o})]}),(0,J.jsx)($,{label:r(`models.graphqlLabel`),names:s})]})},Ge=({control:e,kinds:t})=>{let{t:n}=_(),{field:{ref:r,value:i,onChange:a}}=P({control:e,name:`kind`});return(0,J.jsxs)(A,{className:`gap-3`,children:[(0,J.jsx)(j,{variant:`label`,className:`mb-0`,children:n(`models.kind`)}),(0,J.jsx)(N,{ref:r,value:i,onValueChange:a,className:M(`gap-3 sm:grid-cols-2`,t.length>2&&`sm:grid-cols-3`),children:t.map(e=>(0,J.jsx)(K,{value:e,icon:re[e],label:n(T[e]),description:n(D[e])},e))})]})},Ke=({control:e,canShare:t})=>{let{t:n}=_(),r=f().data?.site,{field:{ref:i,value:a,onChange:o}}=P({control:e,name:`scope`});return(0,J.jsxs)(A,{className:`gap-3`,children:[(0,J.jsxs)(j,{variant:`label`,className:`mb-0 flex items-center gap-1`,children:[n(`contentTypes.availableOn`),t?null:(0,J.jsx)(C,{about:n(`contentTypes.allSites`),children:n(`contentTypes.allSitesNeedsNetwork`)})]}),(0,J.jsxs)(N,{ref:i,value:a,onValueChange:o,className:`gap-3 sm:grid-cols-2`,children:[(0,J.jsx)(K,{value:`site`,icon:De,label:n(`contentTypes.thisSite`),description:n(`contentTypes.thisSiteDescription`,{site:r?.name??``})}),(0,J.jsx)(K,{value:`network`,icon:ie,label:n(`contentTypes.allSites`),description:n(`contentTypes.allSitesDescription`),disabled:!t})]})]})},qe=({title:e,kinds:t,back:n,backLabel:r,intro:i,scope:a})=>{let{t:o}=_(),s=ee(`schema.create`),{locked:c,reason:l}=xe(),{multiSite:u,canShare:f}=O(),{form:p,onSubmit:g,pending:v,error:y,errorMessage:b}=Ue(t[0],a),[x,S,C]=F({control:p.control,name:[`kind`,`apiKey`,`pluralApiKey`]}),w=x===`collection`;return s?(0,J.jsxs)(m,{width:`narrow`,children:[(0,J.jsx)(ne,{when:p.formState.isDirty}),(0,J.jsx)(h,{breadcrumb:[{label:r,link:n}],title:e}),c?(0,J.jsx)(Se,{reason:l}):null,i,(0,J.jsx)(be,{children:(0,J.jsx)(`form`,{noValidate:!0,onSubmit:e=>void g(e),children:(0,J.jsxs)(k,{className:`gap-5`,children:[t.length>1?(0,J.jsx)(Ge,{control:p.control,kinds:t}):null,a===void 0&&u?(0,J.jsx)(Ke,{control:p.control,canShare:f}):null,(0,J.jsx)(I,{control:p.control,name:`label`,label:o(`models.label`),autoComplete:`off`}),(0,J.jsxs)(`div`,{className:M(`grid items-start gap-5`,w&&`sm:grid-cols-2`),children:[(0,J.jsx)(I,{control:p.control,name:`apiKey`,label:o(`models.apiKey`),hint:o(`models.apiKeyHint`),autoComplete:`off`,spellCheck:!1,className:`font-mono`}),w?(0,J.jsx)(I,{control:p.control,name:`pluralApiKey`,label:o(`models.pluralApiKey`),hint:o(`models.pluralApiKeyHint`),autoComplete:`off`,spellCheck:!1,className:`font-mono`}):null]}),(0,J.jsx)(We,{apiKey:S,pluralApiKey:C,kind:x}),(0,J.jsx)(Ee,{control:p.control,name:`description`,label:o(`common.optionalLabel`,{label:o(`models.descriptionLabel`)}),rows:2}),x===`component`?null:(0,J.jsx)(Te,{control:p.control,name:`localized`,label:o(`models.localized`),hint:o(`models.localizedHint`),variant:`bordered`}),(0,J.jsx)(oe,{error:y,message:b}),(0,J.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,J.jsx)(ae,{variant:`outline`,asChild:!0,children:(0,J.jsx)(d,{...n,children:o(`common.cancel`)})}),(0,J.jsx)(te,{pending:v,pendingLabel:o(`models.creating`),disabled:c,children:o(`common.create`)})]})]})})})]}):(0,J.jsxs)(m,{width:`narrow`,children:[(0,J.jsx)(h,{breadcrumb:[{label:r,link:n}],title:e}),(0,J.jsx)(W,{})]})};export{Z as n,je as r,qe as t};
|
|
2
|
-
//# sourceMappingURL=Form-
|
|
1
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./react-CQOZoUwg.js";import{t as n}from"./jsx-runtime-DREnUpxT.js";import{$ as r,Pt as i,b as a,bn as o,g as s,x as c,y as l}from"./src-ndgTSYLX.js";import{E as u,S as d,o as ee,u as f,x as p}from"./auth-CQO4MBUj.js";import{_ as te,a as m,i as h,n as g}from"./badge-CqKF1pwz.js";import{n as _,t as v}from"./createLucideIcon-CLmh7Go-.js";import{i as y,n as b,t as x}from"./RowTitle-Bqt6evG9.js";import{t as ne}from"./UnsavedChangesGuard-CUiuMklN.js";import{E as S,t as C}from"./InfoHint-CSEtcHjL.js";import{T as w}from"./es2015-BHmI7wjK.js";import{a as T,i as re,l as E,r as D,u as ie}from"./constants-a_15vqOh.js";import{t as O}from"./useSchemaScopeAccess-ByrxIdKM.js";import{i as ae}from"./skeleton-B5MP72Kw.js";import{a as oe}from"./InlineConfirm-yW-iUKFC.js";import{a as k,c as A,s as j}from"./field-COOzRptX.js";import{t as M}from"./cn-DVhJ55Mo.js";import{t as N}from"./radio-group-4ok5evXq.js";import{c as P,f as F,n as I,o as se,t as ce,u as le}from"./zod-Cry7YvLY.js";import{t as ue}from"./settle-CFU6YpQ0.js";import{a as de,d as fe,g as L,i as R,l as z,n as B,o as V,r as H,s as pe,t as me,v as U}from"./table-zG68ipQc.js";import{t as he}from"./SharedGlyph-cUmTh0_C.js";import{a as ge,p as _e,s as ve,v as ye}from"./schema-D-qo7XSF.js";import{t as be}from"./Panel-Bcl09TtM.js";import{t as W}from"./NoAccess-C8RLPN0I.js";import{a as xe,i as Se,n as Ce,r as G,t as we}from"./followPlural-Cm7v_Udv.js";import{t as K}from"./RadioTile-DQFmni5A.js";import{t as Te}from"./FormSwitchField-BLOh7qei.js";import{t as Ee}from"./FormTextareaField-CO115n_u.js";var q={name:`app-window`,size:24,node:[[`rect`,{x:`2`,y:`4`,width:`20`,height:`16`,rx:`2`,key:`izxlao`}],[`path`,{d:`M10 4v4`,key:`pp8u80`}],[`path`,{d:`M2 8h20`,key:`d11cs7`}],[`path`,{d:`M6 4v4`,key:`1svtjw`}]]};q.node;var De=v(q),J=e(n(),1),Oe=({definition:e})=>(0,J.jsx)(x,{asChild:!0,children:e.kind===`component`?(0,J.jsx)(d,{to:`/models/components/$componentId`,params:{componentId:e.id},children:e.label}):(0,J.jsx)(d,{to:`/models/$modelId`,params:{modelId:e.id},children:e.label})}),Y=e(t(),1),ke=({changeId:e})=>{let{t}=_(),n=_e(e),r=o(),a=n.data?.status,s=a!==void 0&&ye.has(a);return(0,Y.useEffect)(()=>{s&&r.invalidateQueries({queryKey:i.schema.all})},[s,r]),s||n.isError?null:(0,J.jsx)(g,{tone:`progress`,size:`sm`,label:t(`models.pendingChange`)})},Ae=e=>e.kind===`collection`?`${e.apiKey} · ${s(e)}`:e.apiKey,je=({items:e,showKind:t=!1,markShared:n=!0})=>{let{t:r}=_(),{multiSite:i}=O(),a=n&&i;return(0,J.jsx)(pe,{children:(0,J.jsxs)(me,{children:[(0,J.jsx)(de,{children:(0,J.jsxs)(V,{children:[(0,J.jsx)(R,{children:r(`models.columns.label`)}),t?(0,J.jsx)(R,{children:r(`models.columns.kind`)}):null,(0,J.jsx)(R,{children:r(`models.columns.apiKey`)}),(0,J.jsx)(R,{className:`text-right`,children:r(`models.columns.fields`)}),(0,J.jsx)(R,{className:`text-right`,children:r(`models.columns.version`)}),(0,J.jsx)(R,{children:r(`models.columns.activated`)})]})}),(0,J.jsx)(B,{children:e.map(({definition:e,scope:n,version:i,activatedAt:o,pendingChange:s})=>(0,J.jsxs)(V,{children:[(0,J.jsx)(H,{children:(0,J.jsxs)(`span`,{className:`flex items-center gap-2`,children:[(0,J.jsx)(Oe,{definition:e}),a&&n===`network`?(0,J.jsx)(he,{}):null,s?(0,J.jsx)(ke,{changeId:s.id}):null]})}),t?(0,J.jsx)(H,{className:`text-muted-foreground`,children:r(T[e.kind])}):null,(0,J.jsx)(H,{className:`font-mono text-meta text-muted-foreground`,children:Ae(e)}),(0,J.jsx)(H,{className:`text-right tabular-nums`,children:e.fields.length}),(0,J.jsx)(H,{className:`text-right text-muted-foreground tabular-nums`,children:r(`models.versionNumber`,{version:i})}),(0,J.jsx)(H,{className:`text-muted-foreground`,title:b(o),children:y(o)})]},e.id))})]})})},Me={API_KEY_INVALID:`validation.apiKeyInvalid`,API_KEY_TOO_LONG:`validation.apiKeyTooLong`,API_KEY_RESERVED_PREFIX:`validation.apiKeyReservedPrefix`},X=e=>{let t=a(e);return t?Me[t.code]??`validation.apiKeyInvalid`:null},Ne=()=>U().trim().min(1,`validation.required`).superRefine((e,t)=>{let n=X(e);n&&t.addIssue({code:`custom`,message:n})}),Pe=(e,t)=>X(e)?null:t===``?`validation.required`:c(t)===c(e)?`validation.pluralApiKeySameAsSingular`:X(t),Z=(e,t,n,r,i=!0)=>{let a=(0,Y.useRef)(e);(0,Y.useEffect)(()=>{if(!i){a.current=e;return}let o=t();(o===``||o===r(a.current))&&n(r(e)),a.current=e},[e,t,n,r,i])},Fe=(e,t,n)=>Z(e,t,n,Ce),Ie=(e,t,n)=>{let r=(0,Y.useRef)(e);(0,Y.useEffect)(()=>{let i=t(),a=we(r.current,e,i);a!==i&&n(a),r.current=e},[e,t,n])},Le=L({kind:z([`collection`,`singleton`,`component`]),label:se(),apiKey:Ne(),pluralApiKey:U().trim(),description:U().trim(),localized:fe(),scope:z([`site`,`network`])}).superRefine((e,t)=>{let n=e.kind===`collection`?Pe(e.apiKey,e.pluralApiKey):null;n&&t.addIssue({code:`custom`,path:[`pluralApiKey`],message:n})}),Re=(e,t)=>({kind:e,label:``,apiKey:``,pluralApiKey:``,description:``,localized:!1,scope:t}),ze=({kind:e,label:t,apiKey:n,pluralApiKey:r,description:i,localized:a})=>e===`component`?{kind:e,label:t,apiKey:n,description:i,fields:[]}:e===`collection`?{kind:e,label:t,apiKey:n,pluralApiKey:r,description:i,localized:a,fields:[]}:{kind:e,label:t,apiKey:n,description:i,localized:a,fields:[]},Be=e=>new Set((e??[]).flatMap(({definition:e})=>[e.apiKey,...r(e)?[s(e)]:[]].map(c))),Q=[`label`,`apiKey`,`pluralApiKey`],Ve=new Set(Q.map(e=>`/${e}`)),He=e=>{let t=p(e);if(!(t.length===0||t.some(e=>Ve.has(e.path))))return t.map(G).join(` `)},Ue=(e,t=`site`)=>{let n=ve(),{definitions:r}=ge(),i=u(),a=le({resolver:ce(Le),defaultValues:Re(e,t)}),{setValue:o,setError:s,getValues:l}=a;return Fe(F({control:a.control,name:`label`}),(0,Y.useCallback)(()=>l(`apiKey`),[l]),(0,Y.useCallback)(e=>o(`apiKey`,e,{shouldValidate:!1}),[o])),Ie(F({control:a.control,name:`apiKey`}),(0,Y.useCallback)(()=>l(`pluralApiKey`),[l]),(0,Y.useCallback)(e=>o(`pluralApiKey`,e,{shouldValidate:!1}),[o])),{form:a,onSubmit:a.handleSubmit(async e=>{let t=Be(r);if(t.has(c(e.apiKey))){s(`apiKey`,{message:`validation.apiKeyTaken`});return}if(e.kind===`collection`&&t.has(c(e.pluralApiKey))){s(`pluralApiKey`,{message:`validation.apiKeyTaken`});return}let a=E(e.kind),o=await ue(n.mutateAsync({category:a,input:{definition:ze(e),scope:e.scope}}));if(!o.ok){let e=p(o.error);for(let t of Q){let n=e.find(e=>e.path===`/${t}`);n&&s(t,{message:G(n)})}return}S.success(w.t(`models.created`));let l=o.value.definitionId;await i(a===`component`?{to:`/models/components/$componentId`,params:{componentId:l},ignoreBlocker:!0}:{to:`/models/$modelId`,params:{modelId:l},ignoreBlocker:!0})}),pending:n.isPending,error:n.error,errorMessage:He(n.error)}},$=({label:e,names:t})=>(0,J.jsxs)(`div`,{className:`flex min-w-0 items-baseline gap-2`,children:[(0,J.jsx)(`dt`,{className:`w-14 shrink-0`,children:e}),(0,J.jsx)(`dd`,{className:`flex min-w-0 flex-wrap gap-1.5`,children:t.map(e=>(0,J.jsx)(`code`,{className:`max-w-full truncate rounded bg-muted px-1.5 py-0.5 font-mono text-foreground/80`,children:e},e))})]}),We=({apiKey:e,pluralApiKey:t,kind:n})=>{let{t:r}=_(),i=e.trim();if(i===``||n===`component`)return null;let a=t.trim()||l(i),o=n===`collection`?a:i,s=n===`collection`?[i,a]:[i];return(0,J.jsxs)(`dl`,{className:`flex flex-col gap-1 text-xs text-muted-foreground`,children:[(0,J.jsx)($,{label:r(`models.restLabel`),names:[r(`models.endpointPath`,{routeKey:o})]}),(0,J.jsx)($,{label:r(`models.graphqlLabel`),names:s})]})},Ge=({control:e,kinds:t})=>{let{t:n}=_(),{field:{ref:r,value:i,onChange:a}}=P({control:e,name:`kind`});return(0,J.jsxs)(A,{className:`gap-3`,children:[(0,J.jsx)(j,{variant:`label`,className:`mb-0`,children:n(`models.kind`)}),(0,J.jsx)(N,{ref:r,value:i,onValueChange:a,className:M(`gap-3 sm:grid-cols-2`,t.length>2&&`sm:grid-cols-3`),children:t.map(e=>(0,J.jsx)(K,{value:e,icon:re[e],label:n(T[e]),description:n(D[e])},e))})]})},Ke=({control:e,canShare:t})=>{let{t:n}=_(),r=f().data?.site,{field:{ref:i,value:a,onChange:o}}=P({control:e,name:`scope`});return(0,J.jsxs)(A,{className:`gap-3`,children:[(0,J.jsxs)(j,{variant:`label`,className:`mb-0 flex items-center gap-1`,children:[n(`contentTypes.availableOn`),t?null:(0,J.jsx)(C,{about:n(`contentTypes.allSites`),children:n(`contentTypes.allSitesNeedsNetwork`)})]}),(0,J.jsxs)(N,{ref:i,value:a,onValueChange:o,className:`gap-3 sm:grid-cols-2`,children:[(0,J.jsx)(K,{value:`site`,icon:De,label:n(`contentTypes.thisSite`),description:n(`contentTypes.thisSiteDescription`,{site:r?.name??``})}),(0,J.jsx)(K,{value:`network`,icon:ie,label:n(`contentTypes.allSites`),description:n(`contentTypes.allSitesDescription`),disabled:!t})]})]})},qe=({title:e,kinds:t,back:n,backLabel:r,intro:i,scope:a})=>{let{t:o}=_(),s=ee(`schema.create`),{locked:c,reason:l}=xe(),{multiSite:u,canShare:f}=O(),{form:p,onSubmit:g,pending:v,error:y,errorMessage:b}=Ue(t[0],a),[x,S,C]=F({control:p.control,name:[`kind`,`apiKey`,`pluralApiKey`]}),w=x===`collection`;return s?(0,J.jsxs)(m,{width:`narrow`,children:[(0,J.jsx)(ne,{when:p.formState.isDirty}),(0,J.jsx)(h,{breadcrumb:[{label:r,link:n}],title:e}),c?(0,J.jsx)(Se,{reason:l}):null,i,(0,J.jsx)(be,{children:(0,J.jsx)(`form`,{noValidate:!0,onSubmit:e=>void g(e),children:(0,J.jsxs)(k,{className:`gap-5`,children:[t.length>1?(0,J.jsx)(Ge,{control:p.control,kinds:t}):null,a===void 0&&u?(0,J.jsx)(Ke,{control:p.control,canShare:f}):null,(0,J.jsx)(I,{control:p.control,name:`label`,label:o(`models.label`),autoComplete:`off`}),(0,J.jsxs)(`div`,{className:M(`grid items-start gap-5`,w&&`sm:grid-cols-2`),children:[(0,J.jsx)(I,{control:p.control,name:`apiKey`,label:o(`models.apiKey`),hint:o(`models.apiKeyHint`),autoComplete:`off`,spellCheck:!1,className:`font-mono`}),w?(0,J.jsx)(I,{control:p.control,name:`pluralApiKey`,label:o(`models.pluralApiKey`),hint:o(`models.pluralApiKeyHint`),autoComplete:`off`,spellCheck:!1,className:`font-mono`}):null]}),(0,J.jsx)(We,{apiKey:S,pluralApiKey:C,kind:x}),(0,J.jsx)(Ee,{control:p.control,name:`description`,label:o(`common.optionalLabel`,{label:o(`models.descriptionLabel`)}),rows:2}),x===`component`?null:(0,J.jsx)(Te,{control:p.control,name:`localized`,label:o(`models.localized`),hint:o(`models.localizedHint`),variant:`bordered`}),(0,J.jsx)(oe,{error:y,message:b}),(0,J.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-2`,children:[(0,J.jsx)(ae,{variant:`outline`,asChild:!0,children:(0,J.jsx)(d,{...n,children:o(`common.cancel`)})}),(0,J.jsx)(te,{pending:v,pendingLabel:o(`models.creating`),disabled:c,children:o(`common.create`)})]})]})})})]}):(0,J.jsxs)(m,{width:`narrow`,children:[(0,J.jsx)(h,{breadcrumb:[{label:r,link:n}],title:e}),(0,J.jsx)(W,{})]})};export{Z as n,je as r,qe as t};
|
|
2
|
+
//# sourceMappingURL=Form-lNrRHc0I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Form-D_4fhOy0.js","names":["TableRoot","z.string","useRef","useRef","z.object","z.enum","z.string","z.boolean","zodResolver","useCallback","i18next","Globe2","__toESM","require_jsx_runtime","isModelDefinition","queryKeys","checkApiKeySyntax","useQueryClient","routeKeyOf","foldApiKey","suggestPlural","useNavigate","Link","useHasGlobalPermission","useMe","schemaIssuesOf","SubmitButton","Page","PageHeader","StatusChip","useTranslation","createLucideIcon","formatRelativeTime","formatDateTime","RowTitle","UnsavedChangesGuard","toast","InfoHint","instance","KIND_LABEL_KEYS","KIND_ICONS","categoryOfKind","KIND_DESCRIPTION_KEYS","Earth","useSchemaScopeAccess","Button","FormError","FieldGroup","FieldSet","FieldLegend","cn","RadioGroup","useController","useWatch","FormTextField","requiredText","u","useForm","settle","TableHeader","boolean","object","TableHead","_enum","TableBody","TableRow","TableCell","TableCard","Table","string","SharedGlyph","useAllDefinitions","useSchemaChange","useCreateDefinition","FINAL_CHANGE_STATUSES","Panel","NoAccess","useSchemaLock","LockNotice","deriveApiKey","describeIssue","followPlural","RadioTile","FormSwitchField","FormTextareaField","__iconData","AppWindow","import_jsx_runtime","DefinitionLink","definition","import_react","require_react","PendingChip","change","changeId","queryClient","status","finished","apiIdsOf","List","showShared","markShared","multiSite","t","showKind","items","scope","pendingChange","activatedAt","API_KEY_MESSAGES","syntaxMessage","problem","value","apiKeyField","message","context","pluralApiKeyMessage","apiKey","plural","useValueFromSource","previousSource","source","enabled","current","getValue","derive","setValue","useApiKeyFromLabel","label","getApiKey","setApiKey","usePluralFromApiKey","previousApiKey","getPlural","next","setPlural","createSchema","values","blank","toDefinition","kind","takenKeys","definitions","ISSUE_FIELDS","ISSUE_PATHS","name","unplacedIssuesMessage","issues","error","issue","useCreateDefinitionForm","createDefinition","navigate","form","initialKind","initialScope","getValues","taken","setError","category","created","found","candidate","id","PreviewRow","names","EndpointPreview","pluralApiKey","routeKey","graphqlNames","KindPicker","onChange","kinds","ScopePicker","site","canShare","Form","canCreate","isCollection","backLabel","back","locked","intro","onSubmit","event","errorMessage"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/app-window.mjs","../../src/features/Models/DefinitionLink/index.tsx","../../src/features/Models/PendingChip/index.tsx","../../src/features/Models/List/index.tsx","../../src/features/Models/helpers/apiKeyField.ts","../../src/hooks/useValueFromSource.ts","../../src/features/Models/hooks/useApiKeyFromLabel.ts","../../src/features/Models/hooks/usePluralFromApiKey.ts","../../src/features/Models/hooks/useCreateDefinitionForm.ts","../../src/features/Content/New/EndpointPreview/index.tsx","../../src/features/Content/New/KindPicker/index.tsx","../../src/features/Content/New/ScopePicker/index.tsx","../../src/features/Content/New/Form/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.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 __iconData = {\n name: \"app-window\",\n size: 24,\n node: [\n [\"rect\", { x: \"2\", y: \"4\", width: \"20\", height: \"16\", rx: \"2\", key: \"izxlao\" }],\n [\"path\", { d: \"M10 4v4\", key: \"pp8u80\" }],\n [\"path\", { d: \"M2 8h20\", key: \"d11cs7\" }],\n [\"path\", { d: \"M6 4v4\", key: \"1svtjw\" }]\n ]\n};\n__iconData.node;\nconst AppWindow = createLucideIcon(__iconData);\n\nexport { __iconData, AppWindow as default };\n//# sourceMappingURL=app-window.mjs.map\n","import type { SchemaDefinition } from '@shapio/schema';\nimport { Link } from '@tanstack/react-router';\nimport { RowTitle } from '@/components/RowTitle';\n\ntype DefinitionLinkProps = { definition: Pick<SchemaDefinition, 'id' | 'kind' | 'label'> };\n\n/** A definition's name as a list row title, linking to its builder (models and components differ). */\nexport const DefinitionLink = ({ definition }: DefinitionLinkProps) => (\n <RowTitle asChild>\n {definition.kind === 'component' ? (\n <Link to=\"/models/components/$componentId\" params={{ componentId: definition.id }}>\n {definition.label}\n </Link>\n ) : (\n <Link to=\"/models/$modelId\" params={{ modelId: definition.id }}>\n {definition.label}\n </Link>\n )}\n </RowTitle>\n);\n","import { useQueryClient } from '@tanstack/react-query';\nimport { useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { queryKeys } from '@/api/queryKeys';\nimport { useSchemaChange } from '@/api/schema';\nimport { StatusChip } from '@/components/StatusChip';\nimport { FINAL_CHANGE_STATUSES } from '@/constants/schema';\n\ntype PendingChipProps = { changeId: string };\n\n/** \"Change in progress\" while a planned change runs; refreshes the schema and disappears when it ends. */\nexport const PendingChip = ({ changeId }: PendingChipProps) => {\n const { t } = useTranslation();\n const change = useSchemaChange(changeId);\n const queryClient = useQueryClient();\n const status = change.data?.status;\n const finished = status !== undefined && FINAL_CHANGE_STATUSES.has(status);\n useEffect(() => {\n if (finished) {\n void queryClient.invalidateQueries({ queryKey: queryKeys.schema.all });\n }\n }, [finished, queryClient]);\n if (finished || change.isError) {\n return null;\n }\n return <StatusChip tone=\"progress\" size=\"sm\" label={t('models.pendingChange')} />;\n};\n","import type { DefinitionListItem } from '@shapio/client';\nimport { routeKeyOf } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { SharedGlyph } from '@/components/SharedGlyph';\nimport { TableCard } from '@/components/TableCard';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { KIND_LABEL_KEYS } from '../constants';\nimport { DefinitionLink } from '../DefinitionLink';\nimport { PendingChip } from '../PendingChip';\n\ntype ListProps = {\n items: DefinitionListItem[];\n /** A Kind column, for lists that mix content types and components. */\n showKind?: boolean;\n /** Mark shared definitions with a globe (where there is more than one site); off where all are shared. */\n markShared?: boolean;\n};\n\n/** \"article · articles\" for a collection (singular and list names), the API ID alone otherwise. */\nconst apiIdsOf = (definition: DefinitionListItem['definition']) =>\n definition.kind === 'collection' ? `${definition.apiKey} · ${routeKeyOf(definition)}` : definition.apiKey;\n\nexport const List = ({ items, showKind = false, markShared = true }: ListProps) => {\n const { t } = useTranslation();\n const { multiSite } = useSchemaScopeAccess();\n const showShared = markShared && multiSite;\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('models.columns.label')}</TableHead>\n {showKind ? <TableHead>{t('models.columns.kind')}</TableHead> : null}\n <TableHead>{t('models.columns.apiKey')}</TableHead>\n <TableHead className=\"text-right\">{t('models.columns.fields')}</TableHead>\n <TableHead className=\"text-right\">{t('models.columns.version')}</TableHead>\n <TableHead>{t('models.columns.activated')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map(({ definition, scope, version, activatedAt, pendingChange }) => (\n <TableRow key={definition.id}>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n <DefinitionLink definition={definition} />\n {showShared && scope === 'network' ? <SharedGlyph /> : null}\n {pendingChange ? <PendingChip changeId={pendingChange.id} /> : null}\n </span>\n </TableCell>\n {showKind ? (\n <TableCell className=\"text-muted-foreground\">{t(KIND_LABEL_KEYS[definition.kind])}</TableCell>\n ) : null}\n <TableCell className=\"font-mono text-meta text-muted-foreground\">\n {apiIdsOf(definition)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">{definition.fields.length}</TableCell>\n <TableCell className=\"text-right text-muted-foreground tabular-nums\">\n {t('models.versionNumber', { version })}\n </TableCell>\n <TableCell className=\"text-muted-foreground\" title={formatDateTime(activatedAt)}>\n {formatRelativeTime(activatedAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import { checkApiKeySyntax, foldApiKey } from '@shapio/schema';\nimport { z } from 'zod';\nimport type { ValidationMessageKey } from '@/helpers/validation';\n\nconst API_KEY_MESSAGES: Readonly<Record<string, ValidationMessageKey>> = {\n API_KEY_INVALID: 'validation.apiKeyInvalid',\n API_KEY_TOO_LONG: 'validation.apiKeyTooLong',\n API_KEY_RESERVED_PREFIX: 'validation.apiKeyReservedPrefix',\n};\n\n/** The message for an API key's syntax problem (`checkApiKeySyntax`), or null when it is valid. */\nconst syntaxMessage = (value: string): ValidationMessageKey | null => {\n const problem = checkApiKeySyntax(value);\n return problem ? (API_KEY_MESSAGES[problem.code] ?? 'validation.apiKeyInvalid') : null;\n};\n\n/** An API key: GraphQL-name syntax, checked by @shapio/schema's own `checkApiKeySyntax`. */\nexport const apiKeyField = () =>\n z\n .string()\n .trim()\n .min(1, 'validation.required')\n .superRefine((value, context) => {\n const message = syntaxMessage(value);\n if (message) {\n context.addIssue({ code: 'custom', message });\n }\n });\n\n/**\n * What is wrong with a collection's plural API ID, or null: required, API-key syntax, not the singular.\n * Nothing while the singular itself is invalid (same rule as the server's validator).\n */\nexport const pluralApiKeyMessage = (apiKey: string, plural: string): ValidationMessageKey | null => {\n // A plural derived from an invalid API ID is invalid too; the API ID's own message says it once.\n if (syntaxMessage(apiKey)) {\n return null;\n }\n if (plural === '') {\n return 'validation.required';\n }\n if (foldApiKey(plural) === foldApiKey(apiKey)) {\n return 'validation.pluralApiKeySameAsSingular';\n }\n return syntaxMessage(plural);\n};\n","import { useEffect, useRef } from 'react';\n\n/**\n * A value that follows another one (an API ID its label, a key its name) until the user types one of their\n * own: it is replaced only while it is empty or still what `derive` made of the previous source. (React Hook\n * Form's dirty state cannot tell: it marks the derived value dirty as soon as the source changes again, so\n * typing the source key by key stopped the value after its first letter.)\n */\nexport const useValueFromSource = (\n source: string,\n getValue: () => string,\n setValue: (value: string) => void,\n derive: (source: string) => string,\n /** False while the value is fixed (an existing role's key): it never follows then. */\n enabled = true,\n) => {\n const previousSource = useRef(source);\n useEffect(() => {\n if (!enabled) {\n previousSource.current = source;\n return;\n }\n const current = getValue();\n if (current === '' || current === derive(previousSource.current)) {\n setValue(derive(source));\n }\n previousSource.current = source;\n }, [source, getValue, setValue, derive, enabled]);\n};\n","import { useValueFromSource } from '@/hooks/useValueFromSource';\nimport { deriveApiKey } from '../helpers/deriveApiKey';\n\n/** The API key follows the label until the user types a key of their own (see useValueFromSource). */\nexport const useApiKeyFromLabel = (\n label: string,\n getApiKey: () => string,\n setApiKey: (apiKey: string) => void,\n) => useValueFromSource(label, getApiKey, setApiKey, deriveApiKey);\n","import { useEffect, useRef } from 'react';\nimport { followPlural } from '../helpers/followPlural';\n\n/**\n * The plural API ID follows the singular API ID until the user types one of their own (same rule as the\n * API ID following the label, see `useApiKeyFromLabel`).\n */\nexport const usePluralFromApiKey = (\n apiKey: string,\n getPlural: () => string,\n setPlural: (plural: string) => void,\n) => {\n const previousApiKey = useRef(apiKey);\n useEffect(() => {\n const current = getPlural();\n const next = followPlural(previousApiKey.current, apiKey, current);\n if (next !== current) {\n setPlural(next);\n }\n previousApiKey.current = apiKey;\n }, [apiKey, getPlural, setPlural]);\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { DefinitionScope } from '@shapio/client';\nimport {\n foldApiKey,\n isModelDefinition,\n routeKeyOf,\n type DefinitionInput,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { useForm, useWatch } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { schemaIssuesOf } from '@/api/errors';\nimport { useAllDefinitions, useCreateDefinition } from '@/api/schema';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\nimport { categoryOfKind } from '../constants';\nimport { apiKeyField, pluralApiKeyMessage } from '../helpers/apiKeyField';\nimport { describeIssue } from '../helpers/describeIssue';\nimport { useApiKeyFromLabel } from './useApiKeyFromLabel';\nimport { usePluralFromApiKey } from './usePluralFromApiKey';\n\nconst createSchema = z\n .object({\n kind: z.enum(['collection', 'singleton', 'component']),\n label: requiredText(),\n apiKey: apiKeyField(),\n /** Collections only (hidden and ignored for the other kinds). */\n pluralApiKey: z.string().trim(),\n description: z.string().trim(),\n localized: z.boolean(),\n /** Where it lives: this site (the default) or shared with all sites. */\n scope: z.enum(['site', 'network']),\n })\n .superRefine((values, context) => {\n const message =\n values.kind === 'collection' ? pluralApiKeyMessage(values.apiKey, values.pluralApiKey) : null;\n if (message) {\n context.addIssue({ code: 'custom', path: ['pluralApiKey'], message });\n }\n });\n\nexport type CreateDefinitionValues = z.infer<typeof createSchema>;\n\nconst blank = (kind: CreateDefinitionValues['kind'], scope: DefinitionScope): CreateDefinitionValues => ({\n kind,\n label: '',\n apiKey: '',\n pluralApiKey: '',\n description: '',\n localized: false,\n scope,\n});\n\nconst toDefinition = ({\n kind,\n label,\n apiKey,\n pluralApiKey,\n description,\n localized,\n}: CreateDefinitionValues): DefinitionInput => {\n if (kind === 'component') {\n return { kind, label, apiKey, description, fields: [] };\n }\n return kind === 'collection'\n ? { kind, label, apiKey, pluralApiKey, description, localized, fields: [] }\n : { kind, label, apiKey, description, localized, fields: [] };\n};\n\n/** API IDs already claimed (case-folded): every definition's API ID and every collection's plural. */\nconst takenKeys = (definitions: ReadonlyArray<{ definition: SchemaDefinition }> | undefined) =>\n new Set(\n (definitions ?? []).flatMap(({ definition }) =>\n [definition.apiKey, ...(isModelDefinition(definition) ? [routeKeyOf(definition)] : [])].map(foldApiKey),\n ),\n );\n\n/** Server issues shown on a form field, by the definition property they point at. */\nconst ISSUE_FIELDS = ['label', 'apiKey', 'pluralApiKey'] as const;\n\nconst ISSUE_PATHS: ReadonlySet<string> = new Set(ISSUE_FIELDS.map((name) => `/${name}`));\n\n/**\n * The message for a refusal whose issues point at no field on this form (the generic \"fix the highlighted\n * settings\" would highlight nothing), or undefined when the form error can describe it itself.\n */\nconst unplacedIssuesMessage = (error: unknown): string | undefined => {\n const issues = schemaIssuesOf(error);\n if (issues.length === 0 || issues.some((issue) => ISSUE_PATHS.has(issue.path))) {\n return undefined;\n }\n return issues.map(describeIssue).join(' ');\n};\n\n/**\n * Creates an empty model or component, live (a new definition has no content, so it activates at once),\n * then opens it in the builder. The API key follows the label, and a collection's plural API ID follows\n * the API key, until the user edits them. It belongs to this site unless `scope` says otherwise (the\n * network view creates shared definitions only).\n */\nexport const useCreateDefinitionForm = (\n initialKind: CreateDefinitionValues['kind'],\n initialScope: DefinitionScope = 'site',\n) => {\n const createDefinition = useCreateDefinition();\n const { definitions } = useAllDefinitions();\n const navigate = useNavigate();\n const form = useForm<CreateDefinitionValues>({\n resolver: zodResolver(createSchema),\n defaultValues: blank(initialKind, initialScope),\n });\n const { setValue, setError, getValues } = form;\n const label = useWatch({ control: form.control, name: 'label' });\n useApiKeyFromLabel(\n label,\n useCallback(() => getValues('apiKey'), [getValues]),\n useCallback((apiKey: string) => setValue('apiKey', apiKey, { shouldValidate: false }), [setValue]),\n );\n const apiKey = useWatch({ control: form.control, name: 'apiKey' });\n usePluralFromApiKey(\n apiKey,\n useCallback(() => getValues('pluralApiKey'), [getValues]),\n useCallback((plural: string) => setValue('pluralApiKey', plural, { shouldValidate: false }), [setValue]),\n );\n\n const onSubmit = form.handleSubmit(async (values) => {\n const taken = takenKeys(definitions);\n if (taken.has(foldApiKey(values.apiKey))) {\n setError('apiKey', { message: 'validation.apiKeyTaken' });\n return;\n }\n if (values.kind === 'collection' && taken.has(foldApiKey(values.pluralApiKey))) {\n setError('pluralApiKey', { message: 'validation.apiKeyTaken' });\n return;\n }\n const category = categoryOfKind(values.kind);\n const created = await settle(\n createDefinition.mutateAsync({\n category,\n input: { definition: toDefinition(values), scope: values.scope },\n }),\n );\n if (!created.ok) {\n const issues = schemaIssuesOf(created.error);\n for (const name of ISSUE_FIELDS) {\n const found = issues.find((candidate) => candidate.path === `/${name}`);\n if (found) {\n setError(name, { message: describeIssue(found) });\n }\n }\n return;\n }\n toast.success(i18next.t('models.created'));\n const id = created.value.definitionId;\n // The form is still dirty: the unsaved-changes guard must not ask about what was just created.\n await (category === 'component'\n ? navigate({ to: '/models/components/$componentId', params: { componentId: id }, ignoreBlocker: true })\n : navigate({ to: '/models/$modelId', params: { modelId: id }, ignoreBlocker: true }));\n });\n return {\n form,\n onSubmit,\n pending: createDefinition.isPending,\n error: createDefinition.error,\n errorMessage: unplacedIssuesMessage(createDefinition.error),\n };\n};\n","import { suggestPlural, type DefinitionKind } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\n\ntype EndpointPreviewProps = { apiKey: string; pluralApiKey: string; kind: DefinitionKind };\n\ntype PreviewRowProps = { label: string; names: string[] };\n\nconst PreviewRow = ({ label, names }: PreviewRowProps) => (\n <div className=\"flex min-w-0 items-baseline gap-2\">\n <dt className=\"w-14 shrink-0\">{label}</dt>\n <dd className=\"flex min-w-0 flex-wrap gap-1.5\">\n {names.map((name) => (\n <code\n key={name}\n className=\"max-w-full truncate rounded bg-muted px-1.5 py-0.5 font-mono text-foreground/80\"\n >\n {name}\n </code>\n ))}\n </dd>\n </div>\n);\n\n/**\n * Every API name a model's API IDs produce (REST path, GraphQL queries), updated as they are typed, so it\n * is clear there is nothing else to configure. A collection is listed under its plural API ID\n * (`/api/content/articles`, `articles`) and read one by one under the singular (`article`). Nothing for\n * components or while the ID is empty.\n */\nexport const EndpointPreview = ({ apiKey, pluralApiKey, kind }: EndpointPreviewProps) => {\n const { t } = useTranslation();\n const id = apiKey.trim();\n if (id === '' || kind === 'component') {\n return null;\n }\n const plural = pluralApiKey.trim() || suggestPlural(id);\n const routeKey = kind === 'collection' ? plural : id;\n const graphqlNames = kind === 'collection' ? [id, plural] : [id];\n return (\n <dl className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n <PreviewRow label={t('models.restLabel')} names={[t('models.endpointPath', { routeKey })]} />\n <PreviewRow label={t('models.graphqlLabel')} names={graphqlNames} />\n </dl>\n );\n};\n","import type { DefinitionKind } from '@shapio/schema';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { RadioTile } from '@/components/RadioTile';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { RadioGroup } from '@/components/ui/radio-group';\nimport { KIND_DESCRIPTION_KEYS, KIND_ICONS, KIND_LABEL_KEYS } from '@/features/Models/constants';\nimport type { CreateDefinitionValues } from '@/features/Models/hooks/useCreateDefinitionForm';\nimport { cn } from '@/helpers/cn';\n\ntype KindPickerProps = { control: Control<CreateDefinitionValues>; kinds: readonly DefinitionKind[] };\n\n/** The kinds offered here as cards (a radio group: arrow keys move between them). */\nexport const KindPicker = ({ control, kinds }: KindPickerProps) => {\n const { t } = useTranslation();\n const {\n field: { ref, value, onChange },\n } = useController({ control, name: 'kind' });\n return (\n <FieldSet className=\"gap-3\">\n <FieldLegend variant=\"label\" className=\"mb-0\">\n {t('models.kind')}\n </FieldLegend>\n <RadioGroup\n ref={ref}\n value={value}\n onValueChange={onChange}\n className={cn('gap-3 sm:grid-cols-2', kinds.length > 2 && 'sm:grid-cols-3')}\n >\n {kinds.map((kind) => (\n <RadioTile\n key={kind}\n value={kind}\n icon={KIND_ICONS[kind]}\n label={t(KIND_LABEL_KEYS[kind])}\n description={t(KIND_DESCRIPTION_KEYS[kind])}\n />\n ))}\n </RadioGroup>\n </FieldSet>\n );\n};\n","import { AppWindow, Globe2 } from 'lucide-react';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { InfoHint } from '@/components/InfoHint';\nimport { RadioTile } from '@/components/RadioTile';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { RadioGroup } from '@/components/ui/radio-group';\nimport type { CreateDefinitionValues } from '@/features/Models/hooks/useCreateDefinitionForm';\n\ntype ScopePickerProps = {\n control: Control<CreateDefinitionValues>;\n /** The admin may create shared definitions (`schema.create` on every site); otherwise \"All sites\" is off. */\n canShare: boolean;\n};\n\n/** \"Available on\": this site (the default) or all sites, as cards (a radio group). */\nexport const ScopePicker = ({ control, canShare }: ScopePickerProps) => {\n const { t } = useTranslation();\n const site = useMe().data?.site;\n const {\n field: { ref, value, onChange },\n } = useController({ control, name: 'scope' });\n return (\n <FieldSet className=\"gap-3\">\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n {t('contentTypes.availableOn')}\n {canShare ? null : (\n <InfoHint about={t('contentTypes.allSites')}>{t('contentTypes.allSitesNeedsNetwork')}</InfoHint>\n )}\n </FieldLegend>\n <RadioGroup ref={ref} value={value} onValueChange={onChange} className=\"gap-3 sm:grid-cols-2\">\n <RadioTile\n value=\"site\"\n icon={AppWindow}\n label={t('contentTypes.thisSite')}\n description={t('contentTypes.thisSiteDescription', { site: site?.name ?? '' })}\n />\n <RadioTile\n value=\"network\"\n icon={Globe2}\n label={t('contentTypes.allSites')}\n description={t('contentTypes.allSitesDescription')}\n disabled={!canShare}\n />\n </RadioGroup>\n </FieldSet>\n );\n};\n","import type { DefinitionScope } from '@shapio/client';\nimport type { DefinitionKind } from '@shapio/schema';\nimport { Link, type LinkOptions } from '@tanstack/react-router';\nimport type { ReactNode } from 'react';\nimport { useWatch } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useHasGlobalPermission } from '@/api/auth';\nimport { FormError } from '@/components/FormError';\nimport { FormSwitchField } from '@/components/FormSwitchField';\nimport { FormTextareaField } from '@/components/FormTextareaField';\nimport { FormTextField } from '@/components/FormTextField';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { FieldGroup } from '@/components/ui/field';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { useCreateDefinitionForm } from '@/features/Models/hooks/useCreateDefinitionForm';\nimport { useSchemaLock } from '@/features/Models/hooks/useSchemaLock';\nimport { LockNotice } from '@/features/Models/LockNotice';\nimport { cn } from '@/helpers/cn';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { EndpointPreview } from '../EndpointPreview';\nimport { KindPicker } from '../KindPicker';\nimport { ScopePicker } from '../ScopePicker';\n\ntype FormProps = {\n title: string;\n /** The kinds offered; the picker is hidden when there is only one. */\n kinds: readonly [DefinitionKind, ...DefinitionKind[]];\n /** Where Cancel and the breadcrumb go. */\n back: LinkOptions;\n backLabel: string;\n /** Shown above the form (content types: \"Describe it\", when assist is on). */\n intro?: ReactNode;\n /** A fixed scope hides the \"Available on\" control (the network view creates shared definitions). */\n scope?: DefinitionScope;\n};\n\n/**\n * Creates a content type (collection or single type) or a component, live, then opens it for editing.\n * Shared by `/content/new`, `/develop/components/new` and `/network/content-types/new`. Where there is more\n * than one site, it asks where the definition is available (this site unless \"All sites\" is chosen).\n */\nexport const Form = ({ title, kinds, back, backLabel, intro, scope }: FormProps) => {\n const { t } = useTranslation();\n // Reached by URL or bookmark without the permission: say so before anyone fills in the form.\n const canCreate = useHasGlobalPermission('schema.create');\n const { locked, reason } = useSchemaLock();\n const { multiSite, canShare } = useSchemaScopeAccess();\n const { form, onSubmit, pending, error, errorMessage } = useCreateDefinitionForm(kinds[0], scope);\n const [kind, apiKey, pluralApiKey] = useWatch({\n control: form.control,\n name: ['kind', 'apiKey', 'pluralApiKey'],\n });\n const isCollection = kind === 'collection';\n if (!canCreate) {\n return (\n <Page width=\"narrow\">\n <PageHeader breadcrumb={[{ label: backLabel, link: back }]} title={title} />\n <NoAccess />\n </Page>\n );\n }\n return (\n <Page width=\"narrow\">\n <UnsavedChangesGuard when={form.formState.isDirty} />\n <PageHeader breadcrumb={[{ label: backLabel, link: back }]} title={title} />\n {locked ? <LockNotice reason={reason} /> : null}\n {intro}\n <Panel>\n <form noValidate onSubmit={(event) => void onSubmit(event)}>\n <FieldGroup className=\"gap-5\">\n {kinds.length > 1 ? <KindPicker control={form.control} kinds={kinds} /> : null}\n {scope === undefined && multiSite ? (\n <ScopePicker control={form.control} canShare={canShare} />\n ) : null}\n <FormTextField control={form.control} name=\"label\" label={t('models.label')} autoComplete=\"off\" />\n {/* A collection's two API IDs sit side by side, with the names they produce below both. */}\n <div className={cn('grid items-start gap-5', isCollection && 'sm:grid-cols-2')}>\n <FormTextField\n control={form.control}\n name=\"apiKey\"\n label={t('models.apiKey')}\n hint={t('models.apiKeyHint')}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"font-mono\"\n />\n {isCollection ? (\n <FormTextField\n control={form.control}\n name=\"pluralApiKey\"\n label={t('models.pluralApiKey')}\n hint={t('models.pluralApiKeyHint')}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"font-mono\"\n />\n ) : null}\n </div>\n <EndpointPreview apiKey={apiKey} pluralApiKey={pluralApiKey} kind={kind} />\n <FormTextareaField\n control={form.control}\n name=\"description\"\n label={t('common.optionalLabel', { label: t('models.descriptionLabel') })}\n rows={2}\n />\n {kind === 'component' ? null : (\n <FormSwitchField\n control={form.control}\n name=\"localized\"\n label={t('models.localized')}\n hint={t('models.localizedHint')}\n variant=\"bordered\"\n />\n )}\n <FormError error={error} message={errorMessage} />\n <div className=\"flex flex-wrap justify-end gap-2\">\n <Button variant=\"outline\" asChild>\n <Link {...back}>{t('common.cancel')}</Link>\n </Button>\n <SubmitButton pending={pending} pendingLabel={t('models.creating')} disabled={locked}>\n {t('common.create')}\n </SubmitButton>\n </div>\n </FieldGroup>\n </form>\n </Panel>\n </Page>\n );\n};\n"],"ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Form-lNrRHc0I.js","names":["TableRoot","z.string","useRef","useRef","z.object","z.enum","z.string","z.boolean","zodResolver","useCallback","i18next","Globe2","__toESM","require_jsx_runtime","isModelDefinition","queryKeys","checkApiKeySyntax","useQueryClient","routeKeyOf","foldApiKey","suggestPlural","useNavigate","Link","useHasGlobalPermission","useMe","schemaIssuesOf","SubmitButton","Page","PageHeader","StatusChip","useTranslation","createLucideIcon","formatRelativeTime","formatDateTime","RowTitle","UnsavedChangesGuard","toast","InfoHint","instance","KIND_LABEL_KEYS","KIND_ICONS","categoryOfKind","KIND_DESCRIPTION_KEYS","Earth","useSchemaScopeAccess","Button","FormError","FieldGroup","FieldSet","FieldLegend","cn","RadioGroup","useController","useWatch","FormTextField","requiredText","u","useForm","settle","TableHeader","boolean","object","TableHead","_enum","TableBody","TableRow","TableCell","TableCard","Table","string","SharedGlyph","useAllDefinitions","useSchemaChange","useCreateDefinition","FINAL_CHANGE_STATUSES","Panel","NoAccess","useSchemaLock","LockNotice","deriveApiKey","describeIssue","followPlural","RadioTile","FormSwitchField","FormTextareaField","__iconData","AppWindow","import_jsx_runtime","DefinitionLink","definition","import_react","require_react","PendingChip","change","changeId","queryClient","status","finished","apiIdsOf","List","showShared","markShared","multiSite","t","showKind","items","scope","pendingChange","activatedAt","API_KEY_MESSAGES","syntaxMessage","problem","value","apiKeyField","message","context","pluralApiKeyMessage","apiKey","plural","useValueFromSource","previousSource","source","enabled","current","getValue","derive","setValue","useApiKeyFromLabel","label","getApiKey","setApiKey","usePluralFromApiKey","previousApiKey","getPlural","next","setPlural","createSchema","values","blank","toDefinition","kind","takenKeys","definitions","ISSUE_FIELDS","ISSUE_PATHS","name","unplacedIssuesMessage","issues","error","issue","useCreateDefinitionForm","createDefinition","navigate","form","initialKind","initialScope","getValues","taken","setError","category","created","found","candidate","id","PreviewRow","names","EndpointPreview","pluralApiKey","routeKey","graphqlNames","KindPicker","onChange","kinds","ScopePicker","site","canShare","Form","canCreate","isCollection","backLabel","back","locked","intro","onSubmit","event","errorMessage"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/app-window.mjs","../../src/features/Models/DefinitionLink/index.tsx","../../src/features/Models/PendingChip/index.tsx","../../src/features/Models/List/index.tsx","../../src/features/Models/helpers/apiKeyField.ts","../../src/hooks/useValueFromSource.ts","../../src/features/Models/hooks/useApiKeyFromLabel.ts","../../src/features/Models/hooks/usePluralFromApiKey.ts","../../src/features/Models/hooks/useCreateDefinitionForm.ts","../../src/features/Content/New/EndpointPreview/index.tsx","../../src/features/Content/New/KindPicker/index.tsx","../../src/features/Content/New/ScopePicker/index.tsx","../../src/features/Content/New/Form/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.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 __iconData = {\n name: \"app-window\",\n size: 24,\n node: [\n [\"rect\", { x: \"2\", y: \"4\", width: \"20\", height: \"16\", rx: \"2\", key: \"izxlao\" }],\n [\"path\", { d: \"M10 4v4\", key: \"pp8u80\" }],\n [\"path\", { d: \"M2 8h20\", key: \"d11cs7\" }],\n [\"path\", { d: \"M6 4v4\", key: \"1svtjw\" }]\n ]\n};\n__iconData.node;\nconst AppWindow = createLucideIcon(__iconData);\n\nexport { __iconData, AppWindow as default };\n//# sourceMappingURL=app-window.mjs.map\n","import type { SchemaDefinition } from '@shapio/schema';\nimport { Link } from '@tanstack/react-router';\nimport { RowTitle } from '@/components/RowTitle';\n\ntype DefinitionLinkProps = { definition: Pick<SchemaDefinition, 'id' | 'kind' | 'label'> };\n\n/** A definition's name as a list row title, linking to its builder (models and components differ). */\nexport const DefinitionLink = ({ definition }: DefinitionLinkProps) => (\n <RowTitle asChild>\n {definition.kind === 'component' ? (\n <Link to=\"/models/components/$componentId\" params={{ componentId: definition.id }}>\n {definition.label}\n </Link>\n ) : (\n <Link to=\"/models/$modelId\" params={{ modelId: definition.id }}>\n {definition.label}\n </Link>\n )}\n </RowTitle>\n);\n","import { useQueryClient } from '@tanstack/react-query';\nimport { useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { queryKeys } from '@/api/queryKeys';\nimport { useSchemaChange } from '@/api/schema';\nimport { StatusChip } from '@/components/StatusChip';\nimport { FINAL_CHANGE_STATUSES } from '@/constants/schema';\n\ntype PendingChipProps = { changeId: string };\n\n/** \"Change in progress\" while a planned change runs; refreshes the schema and disappears when it ends. */\nexport const PendingChip = ({ changeId }: PendingChipProps) => {\n const { t } = useTranslation();\n const change = useSchemaChange(changeId);\n const queryClient = useQueryClient();\n const status = change.data?.status;\n const finished = status !== undefined && FINAL_CHANGE_STATUSES.has(status);\n useEffect(() => {\n if (finished) {\n void queryClient.invalidateQueries({ queryKey: queryKeys.schema.all });\n }\n }, [finished, queryClient]);\n if (finished || change.isError) {\n return null;\n }\n return <StatusChip tone=\"progress\" size=\"sm\" label={t('models.pendingChange')} />;\n};\n","import type { DefinitionListItem } from '@shapio/client';\nimport { routeKeyOf } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { SharedGlyph } from '@/components/SharedGlyph';\nimport { TableCard } from '@/components/TableCard';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { KIND_LABEL_KEYS } from '../constants';\nimport { DefinitionLink } from '../DefinitionLink';\nimport { PendingChip } from '../PendingChip';\n\ntype ListProps = {\n items: DefinitionListItem[];\n /** A Kind column, for lists that mix content types and components. */\n showKind?: boolean;\n /** Mark shared definitions with a globe (where there is more than one site); off where all are shared. */\n markShared?: boolean;\n};\n\n/** \"article · articles\" for a collection (singular and list names), the API ID alone otherwise. */\nconst apiIdsOf = (definition: DefinitionListItem['definition']) =>\n definition.kind === 'collection' ? `${definition.apiKey} · ${routeKeyOf(definition)}` : definition.apiKey;\n\nexport const List = ({ items, showKind = false, markShared = true }: ListProps) => {\n const { t } = useTranslation();\n const { multiSite } = useSchemaScopeAccess();\n const showShared = markShared && multiSite;\n return (\n <TableCard>\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('models.columns.label')}</TableHead>\n {showKind ? <TableHead>{t('models.columns.kind')}</TableHead> : null}\n <TableHead>{t('models.columns.apiKey')}</TableHead>\n <TableHead className=\"text-right\">{t('models.columns.fields')}</TableHead>\n <TableHead className=\"text-right\">{t('models.columns.version')}</TableHead>\n <TableHead>{t('models.columns.activated')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {items.map(({ definition, scope, version, activatedAt, pendingChange }) => (\n <TableRow key={definition.id}>\n <TableCell>\n <span className=\"flex items-center gap-2\">\n <DefinitionLink definition={definition} />\n {showShared && scope === 'network' ? <SharedGlyph /> : null}\n {pendingChange ? <PendingChip changeId={pendingChange.id} /> : null}\n </span>\n </TableCell>\n {showKind ? (\n <TableCell className=\"text-muted-foreground\">{t(KIND_LABEL_KEYS[definition.kind])}</TableCell>\n ) : null}\n <TableCell className=\"font-mono text-meta text-muted-foreground\">\n {apiIdsOf(definition)}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">{definition.fields.length}</TableCell>\n <TableCell className=\"text-right text-muted-foreground tabular-nums\">\n {t('models.versionNumber', { version })}\n </TableCell>\n <TableCell className=\"text-muted-foreground\" title={formatDateTime(activatedAt)}>\n {formatRelativeTime(activatedAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </TableRoot>\n </TableCard>\n );\n};\n","import { checkApiKeySyntax, foldApiKey } from '@shapio/schema';\nimport { z } from 'zod';\nimport type { ValidationMessageKey } from '@/helpers/validation';\n\nconst API_KEY_MESSAGES: Readonly<Record<string, ValidationMessageKey>> = {\n API_KEY_INVALID: 'validation.apiKeyInvalid',\n API_KEY_TOO_LONG: 'validation.apiKeyTooLong',\n API_KEY_RESERVED_PREFIX: 'validation.apiKeyReservedPrefix',\n};\n\n/** The message for an API key's syntax problem (`checkApiKeySyntax`), or null when it is valid. */\nconst syntaxMessage = (value: string): ValidationMessageKey | null => {\n const problem = checkApiKeySyntax(value);\n return problem ? (API_KEY_MESSAGES[problem.code] ?? 'validation.apiKeyInvalid') : null;\n};\n\n/** An API key: GraphQL-name syntax, checked by @shapio/schema's own `checkApiKeySyntax`. */\nexport const apiKeyField = () =>\n z\n .string()\n .trim()\n .min(1, 'validation.required')\n .superRefine((value, context) => {\n const message = syntaxMessage(value);\n if (message) {\n context.addIssue({ code: 'custom', message });\n }\n });\n\n/**\n * What is wrong with a collection's plural API ID, or null: required, API-key syntax, not the singular.\n * Nothing while the singular itself is invalid (same rule as the server's validator).\n */\nexport const pluralApiKeyMessage = (apiKey: string, plural: string): ValidationMessageKey | null => {\n // A plural derived from an invalid API ID is invalid too; the API ID's own message says it once.\n if (syntaxMessage(apiKey)) {\n return null;\n }\n if (plural === '') {\n return 'validation.required';\n }\n if (foldApiKey(plural) === foldApiKey(apiKey)) {\n return 'validation.pluralApiKeySameAsSingular';\n }\n return syntaxMessage(plural);\n};\n","import { useEffect, useRef } from 'react';\n\n/**\n * A value that follows another one (an API ID its label, a key its name) until the user types one of their\n * own: it is replaced only while it is empty or still what `derive` made of the previous source. (React Hook\n * Form's dirty state cannot tell: it marks the derived value dirty as soon as the source changes again, so\n * typing the source key by key stopped the value after its first letter.)\n */\nexport const useValueFromSource = (\n source: string,\n getValue: () => string,\n setValue: (value: string) => void,\n derive: (source: string) => string,\n /** False while the value is fixed (an existing role's key): it never follows then. */\n enabled = true,\n) => {\n const previousSource = useRef(source);\n useEffect(() => {\n if (!enabled) {\n previousSource.current = source;\n return;\n }\n const current = getValue();\n if (current === '' || current === derive(previousSource.current)) {\n setValue(derive(source));\n }\n previousSource.current = source;\n }, [source, getValue, setValue, derive, enabled]);\n};\n","import { useValueFromSource } from '@/hooks/useValueFromSource';\nimport { deriveApiKey } from '../helpers/deriveApiKey';\n\n/** The API key follows the label until the user types a key of their own (see useValueFromSource). */\nexport const useApiKeyFromLabel = (\n label: string,\n getApiKey: () => string,\n setApiKey: (apiKey: string) => void,\n) => useValueFromSource(label, getApiKey, setApiKey, deriveApiKey);\n","import { useEffect, useRef } from 'react';\nimport { followPlural } from '../helpers/followPlural';\n\n/**\n * The plural API ID follows the singular API ID until the user types one of their own (same rule as the\n * API ID following the label, see `useApiKeyFromLabel`).\n */\nexport const usePluralFromApiKey = (\n apiKey: string,\n getPlural: () => string,\n setPlural: (plural: string) => void,\n) => {\n const previousApiKey = useRef(apiKey);\n useEffect(() => {\n const current = getPlural();\n const next = followPlural(previousApiKey.current, apiKey, current);\n if (next !== current) {\n setPlural(next);\n }\n previousApiKey.current = apiKey;\n }, [apiKey, getPlural, setPlural]);\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { DefinitionScope } from '@shapio/client';\nimport {\n foldApiKey,\n isModelDefinition,\n routeKeyOf,\n type DefinitionInput,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { useForm, useWatch } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\nimport { schemaIssuesOf } from '@/api/errors';\nimport { useAllDefinitions, useCreateDefinition } from '@/api/schema';\nimport { i18next } from '@/app/i18n';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\nimport { categoryOfKind } from '../constants';\nimport { apiKeyField, pluralApiKeyMessage } from '../helpers/apiKeyField';\nimport { describeIssue } from '../helpers/describeIssue';\nimport { useApiKeyFromLabel } from './useApiKeyFromLabel';\nimport { usePluralFromApiKey } from './usePluralFromApiKey';\n\nconst createSchema = z\n .object({\n kind: z.enum(['collection', 'singleton', 'component']),\n label: requiredText(),\n apiKey: apiKeyField(),\n /** Collections only (hidden and ignored for the other kinds). */\n pluralApiKey: z.string().trim(),\n description: z.string().trim(),\n localized: z.boolean(),\n /** Where it lives: this site (the default) or shared with all sites. */\n scope: z.enum(['site', 'network']),\n })\n .superRefine((values, context) => {\n const message =\n values.kind === 'collection' ? pluralApiKeyMessage(values.apiKey, values.pluralApiKey) : null;\n if (message) {\n context.addIssue({ code: 'custom', path: ['pluralApiKey'], message });\n }\n });\n\nexport type CreateDefinitionValues = z.infer<typeof createSchema>;\n\nconst blank = (kind: CreateDefinitionValues['kind'], scope: DefinitionScope): CreateDefinitionValues => ({\n kind,\n label: '',\n apiKey: '',\n pluralApiKey: '',\n description: '',\n localized: false,\n scope,\n});\n\nconst toDefinition = ({\n kind,\n label,\n apiKey,\n pluralApiKey,\n description,\n localized,\n}: CreateDefinitionValues): DefinitionInput => {\n if (kind === 'component') {\n return { kind, label, apiKey, description, fields: [] };\n }\n return kind === 'collection'\n ? { kind, label, apiKey, pluralApiKey, description, localized, fields: [] }\n : { kind, label, apiKey, description, localized, fields: [] };\n};\n\n/** API IDs already claimed (case-folded): every definition's API ID and every collection's plural. */\nconst takenKeys = (definitions: ReadonlyArray<{ definition: SchemaDefinition }> | undefined) =>\n new Set(\n (definitions ?? []).flatMap(({ definition }) =>\n [definition.apiKey, ...(isModelDefinition(definition) ? [routeKeyOf(definition)] : [])].map(foldApiKey),\n ),\n );\n\n/** Server issues shown on a form field, by the definition property they point at. */\nconst ISSUE_FIELDS = ['label', 'apiKey', 'pluralApiKey'] as const;\n\nconst ISSUE_PATHS: ReadonlySet<string> = new Set(ISSUE_FIELDS.map((name) => `/${name}`));\n\n/**\n * The message for a refusal whose issues point at no field on this form (the generic \"fix the highlighted\n * settings\" would highlight nothing), or undefined when the form error can describe it itself.\n */\nconst unplacedIssuesMessage = (error: unknown): string | undefined => {\n const issues = schemaIssuesOf(error);\n if (issues.length === 0 || issues.some((issue) => ISSUE_PATHS.has(issue.path))) {\n return undefined;\n }\n return issues.map(describeIssue).join(' ');\n};\n\n/**\n * Creates an empty model or component, live (a new definition has no content, so it activates at once),\n * then opens it in the builder. The API key follows the label, and a collection's plural API ID follows\n * the API key, until the user edits them. It belongs to this site unless `scope` says otherwise (the\n * network view creates shared definitions only).\n */\nexport const useCreateDefinitionForm = (\n initialKind: CreateDefinitionValues['kind'],\n initialScope: DefinitionScope = 'site',\n) => {\n const createDefinition = useCreateDefinition();\n const { definitions } = useAllDefinitions();\n const navigate = useNavigate();\n const form = useForm<CreateDefinitionValues>({\n resolver: zodResolver(createSchema),\n defaultValues: blank(initialKind, initialScope),\n });\n const { setValue, setError, getValues } = form;\n const label = useWatch({ control: form.control, name: 'label' });\n useApiKeyFromLabel(\n label,\n useCallback(() => getValues('apiKey'), [getValues]),\n useCallback((apiKey: string) => setValue('apiKey', apiKey, { shouldValidate: false }), [setValue]),\n );\n const apiKey = useWatch({ control: form.control, name: 'apiKey' });\n usePluralFromApiKey(\n apiKey,\n useCallback(() => getValues('pluralApiKey'), [getValues]),\n useCallback((plural: string) => setValue('pluralApiKey', plural, { shouldValidate: false }), [setValue]),\n );\n\n const onSubmit = form.handleSubmit(async (values) => {\n const taken = takenKeys(definitions);\n if (taken.has(foldApiKey(values.apiKey))) {\n setError('apiKey', { message: 'validation.apiKeyTaken' });\n return;\n }\n if (values.kind === 'collection' && taken.has(foldApiKey(values.pluralApiKey))) {\n setError('pluralApiKey', { message: 'validation.apiKeyTaken' });\n return;\n }\n const category = categoryOfKind(values.kind);\n const created = await settle(\n createDefinition.mutateAsync({\n category,\n input: { definition: toDefinition(values), scope: values.scope },\n }),\n );\n if (!created.ok) {\n const issues = schemaIssuesOf(created.error);\n for (const name of ISSUE_FIELDS) {\n const found = issues.find((candidate) => candidate.path === `/${name}`);\n if (found) {\n setError(name, { message: describeIssue(found) });\n }\n }\n return;\n }\n toast.success(i18next.t('models.created'));\n const id = created.value.definitionId;\n // The form is still dirty: the unsaved-changes guard must not ask about what was just created.\n await (category === 'component'\n ? navigate({ to: '/models/components/$componentId', params: { componentId: id }, ignoreBlocker: true })\n : navigate({ to: '/models/$modelId', params: { modelId: id }, ignoreBlocker: true }));\n });\n return {\n form,\n onSubmit,\n pending: createDefinition.isPending,\n error: createDefinition.error,\n errorMessage: unplacedIssuesMessage(createDefinition.error),\n };\n};\n","import { suggestPlural, type DefinitionKind } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\n\ntype EndpointPreviewProps = { apiKey: string; pluralApiKey: string; kind: DefinitionKind };\n\ntype PreviewRowProps = { label: string; names: string[] };\n\nconst PreviewRow = ({ label, names }: PreviewRowProps) => (\n <div className=\"flex min-w-0 items-baseline gap-2\">\n <dt className=\"w-14 shrink-0\">{label}</dt>\n <dd className=\"flex min-w-0 flex-wrap gap-1.5\">\n {names.map((name) => (\n <code\n key={name}\n className=\"max-w-full truncate rounded bg-muted px-1.5 py-0.5 font-mono text-foreground/80\"\n >\n {name}\n </code>\n ))}\n </dd>\n </div>\n);\n\n/**\n * Every API name a model's API IDs produce (REST path, GraphQL queries), updated as they are typed, so it\n * is clear there is nothing else to configure. A collection is listed under its plural API ID\n * (`/api/content/articles`, `articles`) and read one by one under the singular (`article`). Nothing for\n * components or while the ID is empty.\n */\nexport const EndpointPreview = ({ apiKey, pluralApiKey, kind }: EndpointPreviewProps) => {\n const { t } = useTranslation();\n const id = apiKey.trim();\n if (id === '' || kind === 'component') {\n return null;\n }\n const plural = pluralApiKey.trim() || suggestPlural(id);\n const routeKey = kind === 'collection' ? plural : id;\n const graphqlNames = kind === 'collection' ? [id, plural] : [id];\n return (\n <dl className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n <PreviewRow label={t('models.restLabel')} names={[t('models.endpointPath', { routeKey })]} />\n <PreviewRow label={t('models.graphqlLabel')} names={graphqlNames} />\n </dl>\n );\n};\n","import type { DefinitionKind } from '@shapio/schema';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { RadioTile } from '@/components/RadioTile';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { RadioGroup } from '@/components/ui/radio-group';\nimport { KIND_DESCRIPTION_KEYS, KIND_ICONS, KIND_LABEL_KEYS } from '@/features/Models/constants';\nimport type { CreateDefinitionValues } from '@/features/Models/hooks/useCreateDefinitionForm';\nimport { cn } from '@/helpers/cn';\n\ntype KindPickerProps = { control: Control<CreateDefinitionValues>; kinds: readonly DefinitionKind[] };\n\n/** The kinds offered here as cards (a radio group: arrow keys move between them). */\nexport const KindPicker = ({ control, kinds }: KindPickerProps) => {\n const { t } = useTranslation();\n const {\n field: { ref, value, onChange },\n } = useController({ control, name: 'kind' });\n return (\n <FieldSet className=\"gap-3\">\n <FieldLegend variant=\"label\" className=\"mb-0\">\n {t('models.kind')}\n </FieldLegend>\n <RadioGroup\n ref={ref}\n value={value}\n onValueChange={onChange}\n className={cn('gap-3 sm:grid-cols-2', kinds.length > 2 && 'sm:grid-cols-3')}\n >\n {kinds.map((kind) => (\n <RadioTile\n key={kind}\n value={kind}\n icon={KIND_ICONS[kind]}\n label={t(KIND_LABEL_KEYS[kind])}\n description={t(KIND_DESCRIPTION_KEYS[kind])}\n />\n ))}\n </RadioGroup>\n </FieldSet>\n );\n};\n","import { AppWindow, Globe2 } from 'lucide-react';\nimport { useController, type Control } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { InfoHint } from '@/components/InfoHint';\nimport { RadioTile } from '@/components/RadioTile';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { RadioGroup } from '@/components/ui/radio-group';\nimport type { CreateDefinitionValues } from '@/features/Models/hooks/useCreateDefinitionForm';\n\ntype ScopePickerProps = {\n control: Control<CreateDefinitionValues>;\n /** The admin may create shared definitions (`schema.create` on every site); otherwise \"All sites\" is off. */\n canShare: boolean;\n};\n\n/** \"Available on\": this site (the default) or all sites, as cards (a radio group). */\nexport const ScopePicker = ({ control, canShare }: ScopePickerProps) => {\n const { t } = useTranslation();\n const site = useMe().data?.site;\n const {\n field: { ref, value, onChange },\n } = useController({ control, name: 'scope' });\n return (\n <FieldSet className=\"gap-3\">\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n {t('contentTypes.availableOn')}\n {canShare ? null : (\n <InfoHint about={t('contentTypes.allSites')}>{t('contentTypes.allSitesNeedsNetwork')}</InfoHint>\n )}\n </FieldLegend>\n <RadioGroup ref={ref} value={value} onValueChange={onChange} className=\"gap-3 sm:grid-cols-2\">\n <RadioTile\n value=\"site\"\n icon={AppWindow}\n label={t('contentTypes.thisSite')}\n description={t('contentTypes.thisSiteDescription', { site: site?.name ?? '' })}\n />\n <RadioTile\n value=\"network\"\n icon={Globe2}\n label={t('contentTypes.allSites')}\n description={t('contentTypes.allSitesDescription')}\n disabled={!canShare}\n />\n </RadioGroup>\n </FieldSet>\n );\n};\n","import type { DefinitionScope } from '@shapio/client';\nimport type { DefinitionKind } from '@shapio/schema';\nimport { Link, type LinkOptions } from '@tanstack/react-router';\nimport type { ReactNode } from 'react';\nimport { useWatch } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useHasGlobalPermission } from '@/api/auth';\nimport { FormError } from '@/components/FormError';\nimport { FormSwitchField } from '@/components/FormSwitchField';\nimport { FormTextareaField } from '@/components/FormTextareaField';\nimport { FormTextField } from '@/components/FormTextField';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Panel } from '@/components/Panel';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { FieldGroup } from '@/components/ui/field';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { useCreateDefinitionForm } from '@/features/Models/hooks/useCreateDefinitionForm';\nimport { useSchemaLock } from '@/features/Models/hooks/useSchemaLock';\nimport { LockNotice } from '@/features/Models/LockNotice';\nimport { cn } from '@/helpers/cn';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { EndpointPreview } from '../EndpointPreview';\nimport { KindPicker } from '../KindPicker';\nimport { ScopePicker } from '../ScopePicker';\n\ntype FormProps = {\n title: string;\n /** The kinds offered; the picker is hidden when there is only one. */\n kinds: readonly [DefinitionKind, ...DefinitionKind[]];\n /** Where Cancel and the breadcrumb go. */\n back: LinkOptions;\n backLabel: string;\n /** Shown above the form (content types: \"Describe it\", when assist is on). */\n intro?: ReactNode;\n /** A fixed scope hides the \"Available on\" control (the network view creates shared definitions). */\n scope?: DefinitionScope;\n};\n\n/**\n * Creates a content type (collection or single type) or a component, live, then opens it for editing.\n * Shared by `/content/new`, `/develop/components/new` and `/network/content-types/new`. Where there is more\n * than one site, it asks where the definition is available (this site unless \"All sites\" is chosen).\n */\nexport const Form = ({ title, kinds, back, backLabel, intro, scope }: FormProps) => {\n const { t } = useTranslation();\n // Reached by URL or bookmark without the permission: say so before anyone fills in the form.\n const canCreate = useHasGlobalPermission('schema.create');\n const { locked, reason } = useSchemaLock();\n const { multiSite, canShare } = useSchemaScopeAccess();\n const { form, onSubmit, pending, error, errorMessage } = useCreateDefinitionForm(kinds[0], scope);\n const [kind, apiKey, pluralApiKey] = useWatch({\n control: form.control,\n name: ['kind', 'apiKey', 'pluralApiKey'],\n });\n const isCollection = kind === 'collection';\n if (!canCreate) {\n return (\n <Page width=\"narrow\">\n <PageHeader breadcrumb={[{ label: backLabel, link: back }]} title={title} />\n <NoAccess />\n </Page>\n );\n }\n return (\n <Page width=\"narrow\">\n <UnsavedChangesGuard when={form.formState.isDirty} />\n <PageHeader breadcrumb={[{ label: backLabel, link: back }]} title={title} />\n {locked ? <LockNotice reason={reason} /> : null}\n {intro}\n <Panel>\n <form noValidate onSubmit={(event) => void onSubmit(event)}>\n <FieldGroup className=\"gap-5\">\n {kinds.length > 1 ? <KindPicker control={form.control} kinds={kinds} /> : null}\n {scope === undefined && multiSite ? (\n <ScopePicker control={form.control} canShare={canShare} />\n ) : null}\n <FormTextField control={form.control} name=\"label\" label={t('models.label')} autoComplete=\"off\" />\n {/* A collection's two API IDs sit side by side, with the names they produce below both. */}\n <div className={cn('grid items-start gap-5', isCollection && 'sm:grid-cols-2')}>\n <FormTextField\n control={form.control}\n name=\"apiKey\"\n label={t('models.apiKey')}\n hint={t('models.apiKeyHint')}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"font-mono\"\n />\n {isCollection ? (\n <FormTextField\n control={form.control}\n name=\"pluralApiKey\"\n label={t('models.pluralApiKey')}\n hint={t('models.pluralApiKeyHint')}\n autoComplete=\"off\"\n spellCheck={false}\n className=\"font-mono\"\n />\n ) : null}\n </div>\n <EndpointPreview apiKey={apiKey} pluralApiKey={pluralApiKey} kind={kind} />\n <FormTextareaField\n control={form.control}\n name=\"description\"\n label={t('common.optionalLabel', { label: t('models.descriptionLabel') })}\n rows={2}\n />\n {kind === 'component' ? null : (\n <FormSwitchField\n control={form.control}\n name=\"localized\"\n label={t('models.localized')}\n hint={t('models.localizedHint')}\n variant=\"bordered\"\n />\n )}\n <FormError error={error} message={errorMessage} />\n <div className=\"flex flex-wrap justify-end gap-2\">\n <Button variant=\"outline\" asChild>\n <Link {...back}>{t('common.cancel')}</Link>\n </Button>\n <SubmitButton pending={pending} pendingLabel={t('models.creating')} disabled={locked}>\n {t('common.create')}\n </SubmitButton>\n </div>\n </FieldGroup>\n </form>\n </Panel>\n </Page>\n );\n};\n"],"ignoreList":[0],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./jsx-runtime-DREnUpxT.js";import{t as n}from"./InfoHint-
|
|
2
|
-
//# sourceMappingURL=FormCheckboxGroup-
|
|
1
|
+
import{i as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./jsx-runtime-DREnUpxT.js";import{t as n}from"./InfoHint-CSEtcHjL.js";import{i as r}from"./InlineConfirm-yW-iUKFC.js";import{c as i,o as a,r as o,s,t as c}from"./field-COOzRptX.js";import{c as l,r as u}from"./zod-Cry7YvLY.js";var d=[`publish`,`unpublish`],f=[`scheduled`,`done`,`failed`,`cancelled`],p=[`generic_webhook`,`cloudflare_pages`,`vercel`,`netlify`,`github`],m=[`publish`,`change_set`,`schema`,`manual`],h=e(t(),1),g=({control:e,name:t,legend:d,description:f,options:p,disabled:m})=>{let{field:g,fieldState:_}=l({control:e,name:t}),v=g.value??[],y=(e,t)=>g.onChange(t?[...v,e]:v.filter(t=>t!==e)),b=_.error?.message;return(0,h.jsxs)(i,{"data-invalid":_.invalid||void 0,children:[(0,h.jsx)(s,{variant:`label`,children:d}),f?(0,h.jsx)(o,{children:f}):null,(0,h.jsx)(`div`,{"data-slot":`checkbox-group`,className:`grid gap-3 sm:grid-cols-2`,children:p.map(e=>{let i=`field-${t}-${e.value}`,o=e.hint?`${i}-hint`:void 0;return(0,h.jsxs)(c,{orientation:`horizontal`,children:[(0,h.jsx)(r,{id:i,checked:v.includes(e.value),onCheckedChange:t=>y(e.value,t===!0),onBlur:g.onBlur,disabled:m,"aria-describedby":o}),e.hint?(0,h.jsxs)(`span`,{className:`flex items-center gap-1`,children:[(0,h.jsx)(a,{htmlFor:i,className:`font-normal`,children:e.label}),(0,h.jsx)(n,{about:e.label,id:o,children:e.hint})]}):(0,h.jsx)(a,{htmlFor:i,className:`font-normal`,children:e.label})]},e.value)})}),(0,h.jsx)(u,{message:b})]})};export{f as a,d as i,p as n,m as r,g as t};
|
|
2
|
+
//# sourceMappingURL=FormCheckboxGroup-DeeaYnzB.js.map
|