@aerogel/core 0.0.0-next.b85327579d32f21c6a9fa21142f0165cdd320d7e → 0.0.0-next.f16bd1d894543c5303039c49f6f33488a1ffe931
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/aerogel-core.cjs.js +1 -1
- package/dist/aerogel-core.cjs.js.map +1 -1
- package/dist/aerogel-core.d.ts +304 -47
- package/dist/aerogel-core.esm.js +1 -1
- package/dist/aerogel-core.esm.js.map +1 -1
- package/dist/virtual.d.ts +11 -0
- package/noeldemartin.config.js +4 -1
- package/package.json +2 -2
- package/src/components/AGAppModals.vue +15 -0
- package/src/components/AGAppOverlays.vue +5 -7
- package/src/components/AGAppSnackbars.vue +13 -0
- package/src/components/basic/AGMarkdown.vue +7 -2
- package/src/components/constants.ts +8 -0
- package/src/components/forms/AGButton.vue +25 -15
- package/src/components/headless/index.ts +1 -0
- package/src/components/headless/snackbars/AGHeadlessSnackbar.vue +10 -0
- package/src/components/headless/snackbars/index.ts +25 -0
- package/src/components/index.ts +2 -0
- package/src/components/modals/AGConfirmModal.vue +1 -1
- package/src/components/modals/AGErrorReportModal.ts +20 -0
- package/src/components/modals/AGErrorReportModal.vue +62 -0
- package/src/components/modals/AGErrorReportModalButtons.vue +106 -0
- package/src/components/modals/AGErrorReportModalTitle.vue +25 -0
- package/src/components/modals/AGModal.vue +1 -1
- package/src/components/modals/index.ts +15 -2
- package/src/components/snackbars/AGSnackbar.vue +42 -0
- package/src/components/snackbars/index.ts +3 -0
- package/src/directives/index.ts +16 -3
- package/src/errors/Errors.ts +36 -7
- package/src/errors/index.ts +39 -1
- package/src/main.ts +0 -2
- package/src/services/App.state.ts +4 -1
- package/src/types/virtual.d.ts +11 -0
- package/src/ui/UI.state.ts +10 -1
- package/src/ui/UI.ts +37 -6
- package/src/ui/index.ts +4 -0
- package/src/utils/vue.ts +2 -0
- package/tsconfig.json +1 -0
- package/vite.config.ts +2 -1
- package/src/globals.ts +0 -6
package/dist/aerogel-core.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"core-js/modules/esnext.async-iterator.map.js";import"core-js/modules/esnext.iterator.map.js";import{ref as e,inject as t,reactive as s,markRaw as r,nextTick as o,onUnmounted as a,useAttrs as n,computed as l,onMounted as i,defineComponent as u,toRef as d,openBlock as c,createBlock as m,unref as p,withCtx as f,renderSlot as h,provide as v,resolveDynamicComponent as _,normalizeProps as g,guardReactiveProps as b,createElementBlock as y,Fragment as x,createVNode as A,createCommentVNode as j,createElementVNode as w,h as G,normalizeClass as S,createTextVNode as k,toDisplayString as M,createApp as E,readonly as $,mergeProps as C,withModifiers as I}from"vue";import"core-js/modules/esnext.async-iterator.for-each.js";import"core-js/modules/esnext.iterator.constructor.js";import"core-js/modules/esnext.iterator.for-each.js";import{fail as H,JSError as O,MagicObject as P,PromisedValue as q,objectOnly as L,isEmpty as B,Storage as D,objectDeepClone as R,facade as F,arr as N,tap as V,uuid as z,toString as T,isObject as K,objectWithout as U,noop as Q,objectWithoutEmpty as W}from"@noeldemartin/utils";import J from"@babel/runtime/helpers/esm/defineProperty";import"core-js/modules/esnext.set.add-all.js";import"core-js/modules/esnext.set.delete-all.js";import"core-js/modules/esnext.set.difference.js";import"core-js/modules/esnext.set.every.js";import"core-js/modules/esnext.set.filter.js";import"core-js/modules/esnext.set.find.js";import"core-js/modules/esnext.set.intersection.js";import"core-js/modules/esnext.set.is-disjoint-from.js";import"core-js/modules/esnext.set.is-subset-of.js";import"core-js/modules/esnext.set.is-superset-of.js";import"core-js/modules/esnext.set.join.js";import"core-js/modules/esnext.set.map.js";import"core-js/modules/esnext.set.reduce.js";import"core-js/modules/esnext.set.some.js";import"core-js/modules/esnext.set.symmetric-difference.js";import"core-js/modules/esnext.set.union.js";import{defineStore as X,createPinia as Y,setActivePinia as Z}from"pinia";import"core-js/modules/esnext.string.at.js";import"core-js/modules/esnext.async-iterator.filter.js";import"core-js/modules/esnext.iterator.filter.js";import"core-js/modules/esnext.async-iterator.reduce.js";import"core-js/modules/esnext.iterator.reduce.js";import"core-js/modules/esnext.async-iterator.some.js";import"core-js/modules/esnext.iterator.some.js";import{Dialog as ee,DialogPanel as te,DialogTitle as se}from"@headlessui/vue";import re from"dompurify";import{marked as oe}from"marked";function ae(e){return e}function ne(e){return{type:Array,default:e??(()=>[])}}function le(){return{type:Boolean,default:arguments.length>0&&void 0!==arguments[0]&&arguments[0]}}function ie(){return e()}function ue(e){return e}function de(e,t){const s=Object.values(e);return{type:String,default:t??s[0]??null,validator:e=>s.includes(e)}}function ce(e){const r=t(e);return r?s(r):void 0}function me(e,t){return ce(e)??H(t??`Could not resolve '${e}' injection key`)}function pe(e,s){return t(e)??H(s??`Could not resolve '${e}' injection key`)}function fe(e){return{type:e,default:null}}function he(){return{type:Number,default:arguments.length>0&&void 0!==arguments[0]?arguments[0]:null}}function ve(){return{type:Object,default:arguments.length>0&&void 0!==arguments[0]?arguments[0]:null}}function _e(){return{type:Array,required:!0}}function ge(e){const t=Object.values(e);return{type:String,required:!0,validator:e=>t.includes(e)}}function be(e){return{type:e,required:!0}}function ye(){return{type:Number,required:!0}}function xe(){return{type:Object,required:!0}}function Ae(){return{type:String,required:!0}}function je(){return{type:String,default:arguments.length>0&&void 0!==arguments[0]?arguments[0]:null}}const we={"initial-focus":{mounted(e,t){let{value:s}=t;!1!==s&&e.focus()}}};var Ge={install(e){Object.entries(we).forEach((t=>{let[s,r]=t;return e.directive(s,r)}))}};class ServiceBootError extends O{constructor(e,t){super(`Service '${e}' failed booting`,{cause:t})}}let Se=null;function ke(){return Se||(Se=Y(),Z(Se)),Se}function Me(e){var t;return J(t=class extends Ee{usesStore(){return!0}getName(){return e.name??null}getInitialState(){return e.initialState}getComputedStateDefinition(){return e.computed??{}}serializePersistedState(t){return e.serialize?.(t)??t}},"persist",e.persist??[]),t}class Ee extends P{constructor(){super(),J(this,"_name",void 0),J(this,"_booted",void 0),J(this,"_computedStateKeys",void 0),J(this,"_store",void 0);const e=this.getComputedStateDefinition();var t,s;this._name=this.getName()??new.target.name,this._booted=new q,this._computedStateKeys=new Set(Object.keys(e)),this._store=this.usesStore()&&(t=this._name,s={state:()=>this.getInitialState(),getters:e},ke(),X(t,s)())}get booted(){return this._booted}launch(){const handleError=e=>this._booted.reject(new ServiceBootError(this._name,e));try{this.boot().then((()=>this._booted.resolve())).catch(handleError)}catch(e){handleError(e)}return this._booted}hasState(e){return!!this._store&&(e in this._store.$state||this._computedStateKeys.has(e))}getState(e){const t=this._store;return e?t?t[e]:void 0:t||{}}setState(e,t){if(!this._store)return;const s="string"==typeof e?{[e]:t}:e;Object.assign(this._store.$state,s),this.onStateUpdated(s)}__get(e){return this.hasState(e)?this.getState(e):super.__get(e)}__set(e,t){this.setState({[e]:t})}onStateUpdated(e){const t=this.constructor.persist,s=L(e,t);if(B(s))return;const r=D.require(this._name);D.set(this._name,{...r,...this.serializePersistedState(R(s))})}usesStore(){return!1}getName(){return null}getInitialState(){return{}}getComputedStateDefinition(){return{}}serializePersistedState(e){return e}async boot(){this.restorePersistedState()}restorePersistedState(){const e=this.constructor.persist;if(this.usesStore()&&!B(e))if(D.has(this._name)){const e=D.require(this._name);this.setState(e)}else D.set(this._name,L(this.getState(),e))}}J(Ee,"persist",[]);class $e extends Ee{constructor(){super(...arguments),J(this,"listeners",{})}async emit(e,t){const s=[...this.listeners[e]??[]];await Promise.all(s.map((e=>e(t)))??[])}on(e,t){return(this.listeners[e]??=N([])).push(t),()=>this.off(e,t)}once(e,t){let s=null;return V((()=>s&&this.off(e,s)),(r=>{(this.listeners[e]??=N([])).push(s=function(){return r(),t(...arguments)})}))}off(e,t){const s=this.listeners[e];s&&(s.remove(t),s.isEmpty()&&delete this.listeners[e])}}var Ce=F(new $e),Ie=Me({name:"app",initialState:{environment:__AG_ENV,isMounted:!1},computed:{isDevelopment:e=>"development"===e.environment,isTesting:e=>"testing"===e.environment}});class He extends Ie{async boot(){await super.boot(),Ce.once("application-mounted",(()=>this.setState({isMounted:!0})))}}var Oe=F(new He);const Pe={$app:Oe,$events:Ce};async function qe(e,t){await Promise.all(Object.entries(t).map((async e=>{let[t,s]=e;await s.launch().catch((e=>console.error(e)))}))),Object.assign(e.config.globalProperties,t)}var Le={async install(e,t){const s={...Pe,...t.services};e.use(Se??ke()),await qe(e,s)}},Be=Me({name:"ui",initialState:{modals:[]}});const De={AlertModal:"alert-modal",ConfirmModal:"confirm-modal",LoadingModal:"loading-modal"};var Re=F(new class extends Be{constructor(){super(...arguments),J(this,"modalCallbacks",{}),J(this,"components",{})}alert(e,t){const s="string"==typeof t?{title:e,message:t}:{message:e};this.openModal(this.requireComponent(De.AlertModal),s)}async confirm(e,t){const s="string"==typeof t?{title:e,message:t}:{message:e},r=await this.openModal(this.requireComponent(De.ConfirmModal),s);return await r.beforeClose??!1}async loading(e,t){t="string"==typeof e?t:e;const s="string"==typeof e?e:void 0,r=await this.openModal(this.requireComponent(De.LoadingModal),{message:s}),o=await t;return await this.closeModal(r.id),o}registerComponent(e,t){this.components[e]=t}async openModal(e,t){const s=z(),a={},n={id:s,properties:t??{},component:r(e),beforeClose:new Promise((e=>a.willClose=e)),afterClose:new Promise((e=>a.closed=e))},l=this.modals.at(-1),i=this.modals.concat(n);return this.modalCallbacks[n.id]=a,this.setState({modals:i}),await o(),await(l&&Ce.emit("hide-modal",{id:l.id})),await Promise.all([l||Ce.emit("show-overlays-backdrop"),Ce.emit("show-modal",{id:n.id})]),n}async closeModal(e,t){await Ce.emit("close-modal",{id:e,result:t})}async boot(){await super.boot(),this.watchModalEvents()}requireComponent(e){return this.components[e]??H(`UI Component '${e}' is not defined!`)}watchModalEvents(){Ce.on("modal-will-close",(e=>{let{modal:t,result:s}=e;this.modalCallbacks[t.id]?.willClose?.(s),1===this.modals.length&&Ce.emit("hide-overlays-backdrop")})),Ce.on("modal-closed",(async e=>{let{modal:t,result:s}=e;this.setState({modals:this.modals.filter((e=>e.id!==t.id))}),this.modalCallbacks[t.id]?.closed?.(s),delete this.modalCallbacks[t.id];const r=this.modals.at(-1);await(r&&Ce.emit("show-modal",{id:r.id}))}))}});var Fe=F(new class extends Ee{constructor(){super(),J(this,"provider",void 0),this.provider={translate:e=>(Oe.isDevelopment&&console.warn("Lang provider is missing"),e)}}setProvider(e){this.provider=e}translate(e,t){return this.provider.translate(e,t)??e}translateWithDefault(e,t,s){s??=t;const r="string"==typeof t?{}:t??{},o=this.provider.translate(e,r)??e;return o===e?Object.entries(r).reduce(((e,t)=>{let[s,r]=t;return e.replace(new RegExp(`\\{\\s*${s}\\s*\\}`,"g"),T(r))}),s):o}});const Ne=Fe.translate.bind(Fe),Ve=Fe.translateWithDefault.bind(Fe);var ze=Me({name:"errors",initialState:{logs:[],startupErrors:[]},computed:{hasErrors:e=>{let{logs:t}=e;return t.length>0},hasNewErrors:e=>{let{logs:t}=e;return t.some((e=>!e.seen))},hasStartupErrors:e=>{let{startupErrors:t}=e;return t.length>0}}});var Te=F(new class extends ze{constructor(){super(...arguments),J(this,"forceReporting",!1),J(this,"enabled",!0)}enable(){this.enabled=!0}disable(){this.enabled=!1}async inspect(e){Array.isArray(e)||await this.createErrorReport(e)}async report(e,t){if((Oe.isDevelopment||Oe.isTesting)&&this.logError(e),!this.enabled)throw e;if(!Oe.isMounted){const t=await this.createStartupErrorReport(e);return void(t&&this.setState({startupErrors:this.startupErrors.concat(t)}))}const s={report:await this.createErrorReport(e),seen:!1,date:new Date};Re.alert(t??"Something went wrong, but it's not your fault! (look at the console for details)"),this.setState({logs:[s].concat(this.logs)})}see(e){this.setState({logs:this.logs.map((t=>t.report!==e?t:{...t,seen:!0}))})}seeAll(){this.setState({logs:this.logs.map((e=>({...e,seen:!0})))})}logError(e){console.error(e),K(e)&&e.cause&&this.logError(e.cause)}async createErrorReport(e){return"string"==typeof e?{title:e}:e instanceof Error||e instanceof O?this.createErrorReportFromError(e):{title:Ne("errors.unknown"),error:e}}async createStartupErrorReport(e){return e instanceof ServiceBootError?e.cause instanceof ServiceBootError?null:this.createErrorReport(e.cause):this.createErrorReport(e)}createErrorReportFromError(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return{title:e.name,description:e.message,details:e.stack,error:e,...t}}});const Ke={$errors:Te};var Ue={async install(e){await qe(e,Ke)}};const Qe={$lang:Fe};var We={async install(e){e.config.globalProperties.$t??=Ne,e.config.globalProperties.$td=Ve,await qe(e,Qe)}};function Je(e,t){const s=Ce.on(e,t);a((()=>s()))}function Xe(){const e=n(),t=l((()=>e.class));return[l((()=>U(e,"class"))),t]}function Ye(e){let t=Q;i((()=>t=e())),a((()=>t()))}var Ze=u({__name:"AGHeadlessModal",props:{cancellable:le(!0)},setup(t,{expose:s}){const r=t,o=e(null),a=e(!0),n=e(!1),{modal:l}=me("modal","could not obtain modal reference from <AGHeadlessModal>, did you render this component manually? Show it using $ui.openModal() instead");async function i(){o.value?.$el&&(a.value=!0)}async function u(e){n.value||(Ce.emit("modal-will-close",{modal:l,result:e}),await i(),n.value=!0,Ce.emit("modal-closed",{modal:l,result:e}))}return Je("close-modal",(async({id:e,result:t})=>{e===l.id&&await u(t)})),Je("hide-modal",(async({id:e})=>{e===l.id&&await i()})),Je("show-modal",(async({id:e})=>{e===l.id&&await async function(){o.value?.$el&&(a.value=!1)}()})),s({close:u,cancellable:d(r,"cancellable")}),(e,s)=>(c(),m(p(ee),{ref_key:"$root",ref:o,open:!0,onClose:s[0]||(s[0]=e=>t.cancellable&&u())},{default:f((()=>[h(e.$slots,"default",{close:u})])),_:3},512))}});Ze.__file="src/components/headless/modals/AGHeadlessModal.vue";var et=u({__name:"AGModalContext",props:{modal:xe(),childIndex:ye()},setup(e){const t=e;return v("modal",{modal:d(t,"modal"),childIndex:d(t,"childIndex")}),(t,s)=>(c(),m(_(e.modal.component),g(b(e.modal.properties)),null,16))}});et.__file="src/components/modals/AGModalContext.vue";const tt=w("div",{class:"pointer-events-none fixed inset-0 z-50 bg-black/30"},null,-1);var st=u({__name:"AGHeadlessModalPanel",setup(e){const t=me("modal","could not obtain modal reference from <AGHeadlessModalPanel>, did you render this component manually? Show it using $ui.openModal() instead"),s=l((()=>Re.modals[t.childIndex]??null));return(e,r)=>(c(),m(p(te),null,{default:f((()=>[h(e.$slots,"default"),s.value?(c(),y(x,{key:0},[tt,A(et,{"child-index":p(t).childIndex+1,modal:s.value},null,8,["child-index","modal"])],64)):j("v-if",!0)])),_:3}))}});st.__file="src/components/headless/modals/AGHeadlessModalPanel.vue";const rt={class:"fixed inset-0 flex items-center justify-center"},ot={class:"flex max-h-full flex-col overflow-auto p-4"};var at=u({__name:"AGModal",props:{cancellable:le(!0)},setup(t,{expose:s}){const r=e();return s({close:async()=>r.value?.close(),cancellable:l((()=>!!r.value?.cancellable))}),(e,s)=>(c(),m(Ze,{ref_key:"$headlessModal",ref:r,cancellable:t.cancellable,class:"relative z-50"},{default:f((({close:t})=>[w("div",rt,[A(st,{class:"flex max-h-full max-w-full flex-col overflow-hidden bg-white"},{default:f((()=>[w("div",ot,[h(e.$slots,"default",{close:t})])])),_:2},1024)])])),_:3},8,["cancellable"]))}});function nt(e){return t=oe(e,{mangle:!1,headerIds:!1}),re.sanitize(t,{ADD_ATTR:["target"]});var t}at.__file="src/components/modals/AGModal.vue";var lt=u({__name:"AGMarkdown",props:{as:je("div"),langKey:je(),text:je(),inline:le(),raw:le()},setup(e){const t=e,s=l((()=>t.text??(t.langKey&&Ne(t.langKey)))),r=l((()=>{if(!s.value)return null;let e=nt(s.value);return t.inline&&(e=e.replace("<p>","<span>").replace("</p>","</span>")),e})),o=()=>G(t.as,{class:t.raw?"":"prose",innerHTML:r.value});return(e,t)=>(c(),m(o))}});lt.__file="src/components/basic/AGMarkdown.vue";var it=u({__name:"AGAlertModal",props:{title:je(),message:Ae()},setup:e=>(t,s)=>(c(),m(at,null,{default:f((()=>[e.title?(c(),m(lt,{key:0,text:e.title,as:"h2",class:"font-semibold",raw:"",inline:""},null,8,["text"])):j("v-if",!0),A(lt,{text:e.message},null,8,["text"])])),_:1}))});it.__file="src/components/modals/AGAlertModal.vue";var ut=u({__name:"AGHeadlessButton",props:{url:je(),route:je(),routeParams:ve((()=>({}))),routeQuery:ve((()=>({}))),submit:le()},setup(e){const{url:t,route:s,routeParams:r,routeQuery:o,submit:a}=e,n=l((()=>s?{tag:"router-link",props:{to:W({name:s,params:r,query:o})}}:t?{tag:"a",props:{target:"_blank",href:t}}:{tag:"button",props:{type:a?"submit":"button"}}));return(e,t)=>(c(),m(_(n.value.tag),g(b(n.value.props)),{default:f((()=>[h(e.$slots,"default")])),_:3},16))}});ut.__file="src/components/headless/forms/AGHeadlessButton.vue";var dt=u({__name:"AGButton",props:{clear:le(),secondary:le()},setup(e){const t=e,s=l((()=>t.secondary?"text-white bg-gray-600 hover:bg-gray-500 focus-visible:outline-offset-2 focus-visible:outline-gray-600":t.clear?"hover:bg-gray-500/20 focus-visible:outline-gray-500/60":["text-white bg-indigo-600","hover:bg-indigo-500","focus-visible:outline-offset-2 focus-visible:outline-indigo-600"].join(" ")));return(e,t)=>(c(),m(ut,{class:S(["px-2.5 py-1.5 focus-visible:outline focus-visible:outline-2",s.value])},{default:f((()=>[h(e.$slots,"default")])),_:3},8,["class"]))}});dt.__file="src/components/forms/AGButton.vue";const ct={class:"mt-2 flex flex-row-reverse gap-2"};var mt=u({__name:"AGConfirmModal",props:{title:je(),message:Ae()},setup:e=>(t,s)=>(c(),m(at,{cancellable:!1},{default:f((({close:s})=>[e.title?(c(),m(lt,{key:0,text:e.title,as:"h1"},null,8,["text"])):j("v-if",!0),A(lt,{text:e.message},null,8,["text"]),w("div",ct,[A(dt,{onClick:e=>s(!0)},{default:f((()=>[k(M(t.$td("ui.ok","OK")),1)])),_:2},1032,["onClick"]),A(dt,{secondary:"",onClick:e=>s()},{default:f((()=>[k(M(t.$td("ui.cancel","Cancel")),1)])),_:2},1032,["onClick"])])])),_:1}))});mt.__file="src/components/modals/AGConfirmModal.vue";var pt=u({__name:"AGLoadingModal",props:{message:je()},setup(e){const t=e,s=l((()=>t.message??Ve("ui.loading","Loading...")));return(e,t)=>(c(),m(at,{cancellable:!1},{default:f((()=>[A(lt,{text:s.value},null,8,["text"])])),_:1}))}});pt.__file="src/components/modals/AGLoadingModal.vue";const ft={$ui:Re};var ht={async install(e,t){const s={[De.AlertModal]:it,[De.ConfirmModal]:mt,[De.LoadingModal]:pt};Object.entries({...s,...t.components}).forEach((e=>{let[t,s]=e;return Re.registerComponent(t,s)})),await qe(e,ft)}};async function vt(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=[Ge,Ue,We,Le,ht,...t.plugins??[]],r=E(e);await Promise.all(s.map((e=>e.install(r,t)))??[]),r.mount("#app"),Ce.emit("application-mounted")}const _t={key:0};var gt=u({__name:"AGAppOverlays",setup(t){const s=e(null),r=e(!0),o=l((()=>Re.modals[0]??null));return Je("show-overlays-backdrop",(async()=>{s.value&&r.value&&(r.value=!1,s.value.classList.remove("opacity-0"))})),Je("hide-overlays-backdrop",(async()=>{s.value&&!r.value&&(r.value=!0,s.value.classList.add("opacity-0"))})),(e,t)=>(c(),y(x,null,[w("div",{ref_key:"$backdrop",ref:s,class:"pointer-events-none fixed inset-0 z-50 bg-black/30 opacity-0"},null,512),o.value?(c(),y("aside",_t,[A(et,{"child-index":1,modal:o.value},null,8,["modal"])])):j("v-if",!0)],64))}});gt.__file="src/components/AGAppOverlays.vue";const bt={class:"flex h-full flex-col text-base font-normal leading-tight text-gray-900 antialiased"};var yt=u({__name:"AGAppLayout",setup:e=>(e,t)=>(c(),y("div",bt,[h(e.$slots,"default"),A(gt)]))});yt.__file="src/components/AGAppLayout.vue";var xt=u({__name:"AGHeadlessInput",props:{as:je("div"),name:je(),modelValue:fe([String,Number,Boolean])},emits:["update:modelValue"],setup(e,{expose:s,emit:r}){const o=e,a=l((()=>n&&o.name?n.errors[o.name]??null:null)),n=t("form",null),i={id:`input-${z()}`,value:l((()=>n&&o.name?n.getFieldValue(o.name):o.modelValue)),errors:$(a),update(e){n&&o.name?n.setFieldValue(o.name,e):r("update:modelValue",e)}};return v("input",i),s(i),(t,s)=>e.as?(c(),m(_(e.as),{key:0},{default:f((()=>[h(t.$slots,"default")])),_:3})):h(t.$slots,"default",{key:1})}});xt.__file="src/components/headless/forms/AGHeadlessInput.vue";const At=["id"];var jt=u({__name:"AGHeadlessInputError",setup(e){const t=me("input","<AGHeadlessInputError> must be a child of a <AGHeadlessInput>"),s=l((()=>t.errors?Ve(`errors.${t.errors[0]}`,`Error: ${t.errors[0]}`):null));return(e,r)=>s.value?(c(),y("p",{key:0,id:`${p(t).id}-error`},M(s.value),9,At)):j("v-if",!0)}});jt.__file="src/components/headless/forms/AGHeadlessInputError.vue";const wt=["id","type","value","aria-invalid","aria-describedby","checked"];var Gt=u({__name:"AGHeadlessInputInput",props:{type:je("text")},setup(t){const s=t,r=e(),o=me("input","<AGHeadlessInputInput> must be a child of a <AGHeadlessInput>"),a=l((()=>o.value)),n=l((()=>{if("checkbox"===s.type)return!!a.value}));function i(){r.value&&o.update("checkbox"===s.type?r.value.checked:r.value.value)}return(e,s)=>(c(),y("input",{id:p(o).id,ref_key:"$input",ref:r,type:t.type,value:a.value,"aria-invalid":p(o).errors?"true":"false","aria-describedby":p(o).errors?`${p(o).id}-error`:void 0,checked:n.value,onInput:i},null,40,wt))}});Gt.__file="src/components/headless/forms/AGHeadlessInputInput.vue";const St=["for"];var kt=u({__name:"AGHeadlessInputLabel",setup(e){const t=me("input","<AGHeadlessInputLabel> must be a child of a <AGHeadlessInput>");return(e,s)=>(c(),y("label",{for:p(t).id},[h(e.$slots,"default")],8,St))}});kt.__file="src/components/headless/forms/AGHeadlessInputLabel.vue";const Mt={class:"ml-2"};var Et=u({inheritAttrs:!1,__name:"AGCheckbox",props:{name:je()},setup(e){const t=ie();return(s,r)=>(c(),m(xt,{ref_key:"$input",ref:t,name:e.name,class:"flex"},{default:f((()=>[A(Gt,C(s.$attrs,{type:"checkbox",class:{"text-indigo-600 focus:ring-indigo-600":!p(t)?.errors,"border-red-200 text-red-600 focus:ring-red-600":p(t)?.errors}}),null,16,["class"]),w("div",Mt,[s.$slots.default?(c(),m(kt,{key:0},{default:f((()=>[h(s.$slots,"default")])),_:3})):j("v-if",!0),A(jt,{class:"text-sm text-red-600"})])])),_:3},8,["name"]))}});Et.__file="src/components/forms/AGCheckbox.vue";const $t=["onSubmit"];var Ct=u({__name:"AGForm",props:{form:ve()},emits:["submit"],setup(e,{emit:t}){const s=e;function r(){s.form&&!s.form.submit()||t("submit")}return v("form",s.form),(e,t)=>(c(),y("form",{onSubmit:I(r,["prevent"])},[h(e.$slots,"default")],40,$t))}});Ct.__file="src/components/forms/AGForm.vue";const It={class:"absolute bottom-0 left-0 translate-y-full"};var Ht=u({inheritAttrs:!1,__name:"AGInput",props:{name:je()},setup(e){const t=ie(),[s,r]=Xe();return(o,a)=>(c(),m(xt,{ref_key:"$input",ref:t,class:S(["relative flex flex-col items-center",p(r)]),name:e.name},{default:f((()=>[A(Gt,C(p(s),{class:["block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600",{"ring-1 ring-red-500":p(t)?.errors}]}),null,16,["class"]),w("div",It,[A(jt,{class:"mt-1 text-sm text-red-500"})])])),_:1},8,["class","name"]))}});Ht.__file="src/components/forms/AGInput.vue";var Ot=u({__name:"AGHeadlessModalTitle",props:{as:je("h2")},setup:e=>(t,s)=>(c(),m(p(se),{as:e.as},{default:f((()=>[h(t.$slots,"default")])),_:3},8,["as"]))});Ot.__file="src/components/headless/modals/AGHeadlessModalTitle.vue";const Pt={String:"string",Number:"number",Boolean:"boolean"};class qt extends P{constructor(t){super(),J(this,"errors",void 0),J(this,"_fields",void 0),J(this,"_data",void 0),J(this,"_valid",void 0),J(this,"_submitted",void 0),J(this,"_errors",void 0),this._fields=t,this._submitted=e(!1),this._data=this.getInitialData(t),this._errors=this.getInitialErrors(t),this._valid=l((()=>!Object.values(this._errors).some((e=>null!==e)))),this.errors=$(this._errors)}get valid(){return this._valid.value}get submitted(){return this._submitted.value}setFieldValue(e,t){this._data[e]=t,this._submitted.value&&this.validate()}getFieldValue(e){return this._data[e]}validate(){const e=Object.entries(this._fields).reduce(((e,t)=>{let[s,r]=t;return e[s]=this.getFieldErrors(s,r),e}),{});return this.resetErrors(e),this.valid}reset(){this._submitted.value=!1,this.resetData(),this.resetErrors()}submit(){return this._submitted.value=!0,this.validate()}__get(e){return e in this._fields?this._data[e]:super.__get(e)}__set(e,t){e in this._fields?Object.assign(this._data,{[e]:t}):super.__set(e,t)}getFieldErrors(e,t){const s=[];return t.rules?.includes("required")&&!this._data[e]&&s.push("required"),s.length>0?s:null}getInitialData(e){if(this.static().isConjuring())return{};const t=Object.entries(e).reduce(((e,t)=>{let[s,r]=t;return e[s]=r.default??null,e}),{});return s(t)}getInitialErrors(e){if(this.static().isConjuring())return{};const t=Object.keys(e).reduce(((e,t)=>(e[t]=null,e)),{});return s(t)}resetData(){for(const[e,t]of Object.entries(this._fields))this._data[e]=t.default??null}resetErrors(e){Object.keys(this._errors).forEach((e=>delete this._errors[e])),e&&Object.assign(this._errors,e)}}function Lt(e){return new qt(e)}function Bt(e){return{default:e,type:Pt.Boolean}}function Dt(e){return{default:e,type:Pt.Boolean,rules:"required"}}function Rt(e){return{default:e,type:Pt.Number,rules:"required"}}function Ft(e){return{default:e,type:Pt.String,rules:"required"}}function Nt(e){return{default:e,type:Pt.Number}}function Vt(e){return{default:e,type:Pt.String}}export{it as AGAlertModal,yt as AGAppLayout,gt as AGAppOverlays,dt as AGButton,Et as AGCheckbox,mt as AGConfirmModal,Ct as AGForm,ut as AGHeadlessButton,xt as AGHeadlessInput,jt as AGHeadlessInputError,Gt as AGHeadlessInputInput,kt as AGHeadlessInputLabel,Ze as AGHeadlessModal,st as AGHeadlessModalPanel,Ot as AGHeadlessModalTitle,Ht as AGInput,pt as AGLoadingModal,lt as AGMarkdown,at as AGModal,et as AGModalContext,Oe as App,He as AppService,Te as Errors,Ce as Events,$e as EventsService,Pt as FormFieldTypes,Fe as Lang,Ee as Service,Re as UI,De as UIComponents,ne as arrayProp,Bt as booleanInput,le as booleanProp,qe as bootServices,vt as bootstrapApplication,ie as componentRef,ue as defineDirective,ae as definePlugin,Me as defineServiceState,de as enumProp,pe as injectOrFail,ce as injectReactive,me as injectReactiveOrFail,fe as mixedProp,Nt as numberInput,he as numberProp,ve as objectProp,Ye as onCleanMounted,_e as requiredArrayProp,Dt as requiredBooleanInput,ge as requiredEnumProp,be as requiredMixedProp,Rt as requiredNumberInput,ye as requiredNumberProp,xe as requiredObjectProp,Ft as requiredStringInput,Ae as requiredStringProp,Vt as stringInput,je as stringProp,Ne as translate,Ve as translateWithDefault,Je as useEvent,Lt as useForm,Xe as useInputAttrs};
|
|
1
|
+
import"core-js/modules/esnext.async-iterator.map.js";import"core-js/modules/esnext.iterator.map.js";import{ref as e,inject as t,reactive as r,markRaw as s,nextTick as o,onUnmounted as n,useAttrs as a,computed as l,onMounted as i,defineComponent as u,toRef as c,openBlock as d,createBlock as p,unref as m,withCtx as f,renderSlot as h,provide as v,resolveDynamicComponent as g,normalizeProps as _,guardReactiveProps as b,createElementBlock as y,Fragment as x,createVNode as w,createCommentVNode as A,createElementVNode as k,h as j,normalizeClass as S,createTextVNode as G,toDisplayString as M,renderList as C,mergeProps as $,readonly as E,createApp as H,withModifiers as I}from"vue";import{fail as R,JSError as L,MagicObject as P,PromisedValue as B,objectOnly as O,isEmpty as D,Storage as q,objectDeepClone as T,facade as z,arr as V,tap as F,uuid as N,toString as U,isObject as K,objectWithoutEmpty as Q,objectWithout as W,noop as Z,stringExcerpt as Y}from"@noeldemartin/utils";import J from"@babel/runtime/helpers/esm/defineProperty";import"core-js/modules/esnext.set.add-all.js";import"core-js/modules/esnext.set.delete-all.js";import"core-js/modules/esnext.set.difference.js";import"core-js/modules/esnext.set.every.js";import"core-js/modules/esnext.set.filter.js";import"core-js/modules/esnext.set.find.js";import"core-js/modules/esnext.set.intersection.js";import"core-js/modules/esnext.set.is-disjoint-from.js";import"core-js/modules/esnext.set.is-subset-of.js";import"core-js/modules/esnext.set.is-superset-of.js";import"core-js/modules/esnext.set.join.js";import"core-js/modules/esnext.set.map.js";import"core-js/modules/esnext.set.reduce.js";import"core-js/modules/esnext.set.some.js";import"core-js/modules/esnext.set.symmetric-difference.js";import"core-js/modules/esnext.set.union.js";import{defineStore as X,createPinia as ee,setActivePinia as te}from"pinia";import re from"virtual:aerogel";import"core-js/modules/esnext.async-iterator.filter.js";import"core-js/modules/esnext.iterator.constructor.js";import"core-js/modules/esnext.iterator.filter.js";import"core-js/modules/esnext.string.at.js";import"core-js/modules/esnext.async-iterator.reduce.js";import"core-js/modules/esnext.iterator.reduce.js";import"core-js/modules/esnext.async-iterator.some.js";import"core-js/modules/esnext.iterator.some.js";import"core-js/modules/esnext.async-iterator.for-each.js";import"core-js/modules/esnext.iterator.for-each.js";import{Dialog as se,DialogPanel as oe,DialogTitle as ne}from"@headlessui/vue";import ae from"dompurify";import{marked as le}from"marked";function ie(e){return e}function ue(e){return{type:Array,default:e??(()=>[])}}function ce(){return{type:Boolean,default:arguments.length>0&&void 0!==arguments[0]&&arguments[0]}}function de(){return e()}function pe(e){return e}function me(e,t){const r=Object.values(e);return{type:String,default:t??r[0]??null,validator:e=>r.includes(e)}}function fe(e){const s=t(e);return s?r(s):void 0}function he(e,t){return fe(e)??R(t??`Could not resolve '${e}' injection key`)}function ve(e,r){return t(e)??R(r??`Could not resolve '${e}' injection key`)}function ge(e){return{type:e,default:null}}function _e(){return{type:Number,default:arguments.length>0&&void 0!==arguments[0]?arguments[0]:null}}function be(){return{type:Object,default:arguments.length>0&&void 0!==arguments[0]?arguments[0]:null}}function ye(){return{type:Array,required:!0}}function xe(e){const t=Object.values(e);return{type:String,required:!0,validator:e=>t.includes(e)}}function we(e){return{type:e,required:!0}}function Ae(){return{type:Number,required:!0}}function ke(){return{type:Object,required:!0}}function je(){return{type:String,required:!0}}function Se(){return{type:String,default:arguments.length>0&&void 0!==arguments[0]?arguments[0]:null}}const Ge={"initial-focus":{mounted(e,t){let{value:r}=t;!1!==r&&e.focus()}}};var Me={install(e,t){const r={...Ge,...t.directives};for(const[t,s]of Object.entries(r))e.directive(t,s)}};class ServiceBootError extends L{constructor(e,t){super(`Service '${e}' failed booting`,{cause:t})}}let Ce=null;function $e(){return Ce||(Ce=ee(),te(Ce)),Ce}function Ee(e){var t;return J(t=class extends He{usesStore(){return!0}getName(){return e.name??null}getInitialState(){return e.initialState}getComputedStateDefinition(){return e.computed??{}}serializePersistedState(t){return e.serialize?.(t)??t}},"persist",e.persist??[]),t}class He extends P{constructor(){super(),J(this,"_name",void 0),J(this,"_booted",void 0),J(this,"_computedStateKeys",void 0),J(this,"_store",void 0);const e=this.getComputedStateDefinition();var t,r;this._name=this.getName()??new.target.name,this._booted=new B,this._computedStateKeys=new Set(Object.keys(e)),this._store=this.usesStore()&&(t=this._name,r={state:()=>this.getInitialState(),getters:e},$e(),X(t,r)())}get booted(){return this._booted}launch(){const handleError=e=>this._booted.reject(new ServiceBootError(this._name,e));try{this.boot().then((()=>this._booted.resolve())).catch(handleError)}catch(e){handleError(e)}return this._booted}hasState(e){return!!this._store&&(e in this._store.$state||this._computedStateKeys.has(e))}getState(e){const t=this._store;return e?t?t[e]:void 0:t||{}}setState(e,t){if(!this._store)return;const r="string"==typeof e?{[e]:t}:e;Object.assign(this._store.$state,r),this.onStateUpdated(r)}__get(e){return this.hasState(e)?this.getState(e):super.__get(e)}__set(e,t){this.setState({[e]:t})}onStateUpdated(e){const t=this.constructor.persist,r=O(e,t);if(D(r))return;const s=q.require(this._name);q.set(this._name,{...s,...this.serializePersistedState(T(r))})}usesStore(){return!1}getName(){return null}getInitialState(){return{}}getComputedStateDefinition(){return{}}serializePersistedState(e){return e}async boot(){this.restorePersistedState()}restorePersistedState(){const e=this.constructor.persist;if(this.usesStore()&&!D(e))if(q.has(this._name)){const e=q.require(this._name);this.setState(e)}else q.set(this._name,O(this.getState(),e))}}J(He,"persist",[]);class Ie extends He{constructor(){super(...arguments),J(this,"listeners",{})}async emit(e,t){const r=[...this.listeners[e]??[]];await Promise.all(r.map((e=>e(t)))??[])}on(e,t){return(this.listeners[e]??=V([])).push(t),()=>this.off(e,t)}once(e,t){let r=null;return F((()=>r&&this.off(e,r)),(s=>{(this.listeners[e]??=V([])).push(r=function(){return s(),t(...arguments)})}))}off(e,t){const r=this.listeners[e];r&&(r.remove(t),r.isEmpty()&&delete this.listeners[e])}}var Re=z(new Ie),Le=Ee({name:"app",initialState:{environment:re.environment,sourceUrl:re.sourceUrl,isMounted:!1},computed:{isDevelopment:e=>"development"===e.environment,isTesting:e=>"testing"===e.environment}});class Pe extends Le{async boot(){await super.boot(),Re.once("application-mounted",(()=>this.setState({isMounted:!0})))}}var Be=z(new Pe);const Oe={$app:Be,$events:Re};async function De(e,t){await Promise.all(Object.entries(t).map((async e=>{let[t,r]=e;await r.launch().catch((e=>console.error(e)))}))),Object.assign(e.config.globalProperties,t)}var qe={async install(e,t){const r={...Oe,...t.services};e.use(Ce??$e()),await De(e,r)}},Te=Ee({name:"ui",initialState:{modals:[],snackbars:[]}});const ze={AlertModal:"alert-modal",ConfirmModal:"confirm-modal",ErrorReportModal:"error-report-modal",LoadingModal:"loading-modal",Snackbar:"snackbar"};var Ve=z(new class extends Te{constructor(){super(...arguments),J(this,"modalCallbacks",{}),J(this,"components",{})}requireComponent(e){return this.components[e]??R(`UI Component '${e}' is not defined!`)}alert(e,t){const r="string"==typeof t?{title:e,message:t}:{message:e};this.openModal(this.requireComponent(ze.AlertModal),r)}async confirm(e,t){const r="string"==typeof t?{title:e,message:t}:{message:e},s=await this.openModal(this.requireComponent(ze.ConfirmModal),r);return await s.beforeClose??!1}async loading(e,t){t="string"==typeof e?t:e;const r="string"==typeof e?e:void 0,s=await this.openModal(this.requireComponent(ze.LoadingModal),{message:r}),o=await t;return await this.closeModal(s.id),o}showSnackbar(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r={id:N(),properties:{message:e,...t},component:t.component??s(this.requireComponent(ze.Snackbar))};this.setState("snackbars",this.snackbars.concat(r)),setTimeout((()=>this.hideSnackbar(r.id)),5e3)}hideSnackbar(e){this.setState("snackbars",this.snackbars.filter((t=>t.id!==e)))}registerComponent(e,t){this.components[e]=t}async openModal(e,t){const r=N(),n={},a={id:r,properties:t??{},component:s(e),beforeClose:new Promise((e=>n.willClose=e)),afterClose:new Promise((e=>n.closed=e))},l=this.modals.at(-1),i=this.modals.concat(a);return this.modalCallbacks[a.id]=n,this.setState({modals:i}),await o(),await(l&&Re.emit("hide-modal",{id:l.id})),await Promise.all([l||Re.emit("show-overlays-backdrop"),Re.emit("show-modal",{id:a.id})]),a}async closeModal(e,t){await Re.emit("close-modal",{id:e,result:t})}async boot(){await super.boot(),this.watchModalEvents()}watchModalEvents(){Re.on("modal-will-close",(e=>{let{modal:t,result:r}=e;this.modalCallbacks[t.id]?.willClose?.(r),1===this.modals.length&&Re.emit("hide-overlays-backdrop")})),Re.on("modal-closed",(async e=>{let{modal:t,result:r}=e;this.setState("modals",this.modals.filter((e=>e.id!==t.id))),this.modalCallbacks[t.id]?.closed?.(r),delete this.modalCallbacks[t.id];const s=this.modals.at(-1);await(s&&Re.emit("show-modal",{id:s.id}))}))}});var Fe=z(new class extends He{constructor(){super(),J(this,"provider",void 0),this.provider={translate:e=>(Be.isDevelopment&&console.warn("Lang provider is missing"),e)}}setProvider(e){this.provider=e}translate(e,t){return this.provider.translate(e,t)??e}translateWithDefault(e,t,r){r??=t;const s="string"==typeof t?{}:t??{},o=this.provider.translate(e,s)??e;return o===e?Object.entries(s).reduce(((e,t)=>{let[r,s]=t;return e.replace(new RegExp(`\\{\\s*${r}\\s*\\}`,"g"),U(s))}),r):o}});const Ne=Fe.translate.bind(Fe),Ue=Fe.translateWithDefault.bind(Fe);var Ke=Ee({name:"errors",initialState:{logs:[],startupErrors:[]},computed:{hasErrors:e=>{let{logs:t}=e;return t.length>0},hasNewErrors:e=>{let{logs:t}=e;return t.some((e=>!e.seen))},hasStartupErrors:e=>{let{startupErrors:t}=e;return t.length>0}}});const Qe={Primary:"primary",Secondary:"secondary",Danger:"danger",Clear:"clear"};var We=z(new class extends Ke{constructor(){super(...arguments),J(this,"forceReporting",!1),J(this,"enabled",!0)}enable(){this.enabled=!0}disable(){this.enabled=!1}async inspect(e){const t=Array.isArray(e)?e:[await this.createErrorReport(e)];0!==t.length?Ve.openModal(Ve.requireComponent(ze.ErrorReportModal),{reports:t}):Ve.alert(Ue("errors.inspectEmpty","Nothing to inspect!"))}async report(e,t){if((Be.isDevelopment||Be.isTesting)&&this.logError(e),!this.enabled)throw e;if(!Be.isMounted){const t=await this.createStartupErrorReport(e);return void(t&&this.setState({startupErrors:this.startupErrors.concat(t)}))}const r=await this.createErrorReport(e),s={report:r,seen:!1,date:new Date};Ve.showSnackbar(t??Ue("errors.notice","Something went wrong, but it's not your fault. Try again!"),{color:Qe.Danger,actions:[{text:Ue("errors.viewDetails","View details"),dismiss:!0,handler:()=>Ve.openModal(Ve.requireComponent(ze.ErrorReportModal),{reports:[r]})}]}),this.setState({logs:[s].concat(this.logs)})}see(e){this.setState({logs:this.logs.map((t=>t.report!==e?t:{...t,seen:!0}))})}seeAll(){this.setState({logs:this.logs.map((e=>({...e,seen:!0})))})}logError(e){console.error(e),K(e)&&e.cause&&this.logError(e.cause)}async createErrorReport(e){return"string"==typeof e?{title:e}:e instanceof Error||e instanceof L?this.createErrorReportFromError(e):K(e)?Q({title:U(e.name??e.title??Ne("errors.unknown")),description:U(e.message??e.description??""),error:e}):{title:Ne("errors.unknown"),error:e}}async createStartupErrorReport(e){return e instanceof ServiceBootError?e.cause instanceof ServiceBootError?null:this.createErrorReport(e.cause):this.createErrorReport(e)}createErrorReportFromError(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return{title:e.name,description:e.message,details:e.stack,error:e,...t}}});const Ze={$errors:We};function Ye(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:()=>!1;return F((t=>e(t)||(e=>We.instance?(We.report(e),!0):(console.warn("Errors service hasn't been initialized properly!"),console.error(e),!0))(t)),(e=>{globalThis.onerror=(t,r,s,o,n)=>e(n??t),globalThis.onunhandledrejection=t=>e(t.reason)}))}var Je={async install(e,t){const r=Ye(t.handleError);e.config.errorHandler=r,await De(e,Ze)}};const Xe={$lang:Fe};var et={async install(e){e.config.globalProperties.$t??=Ne,e.config.globalProperties.$td=Ue,await De(e,Xe)}};function tt(e,t){const r=Re.on(e,t);n((()=>r()))}function rt(){const e=a(),t=l((()=>e.class));return[l((()=>W(e,"class"))),t]}function st(e){let t=Z;i((()=>t=e())),n((()=>t()))}var ot=u({__name:"AGHeadlessModal",props:{cancellable:ce(!0)},setup(t,{expose:r}){const s=t,o=e(null),n=e(!0),a=e(!1),{modal:l}=he("modal","could not obtain modal reference from <AGHeadlessModal>, did you render this component manually? Show it using $ui.openModal() instead");async function i(){o.value?.$el&&(n.value=!0)}async function u(e){a.value||(Re.emit("modal-will-close",{modal:l,result:e}),await i(),a.value=!0,Re.emit("modal-closed",{modal:l,result:e}))}return tt("close-modal",(async({id:e,result:t})=>{e===l.id&&await u(t)})),tt("hide-modal",(async({id:e})=>{e===l.id&&await i()})),tt("show-modal",(async({id:e})=>{e===l.id&&await async function(){o.value?.$el&&(n.value=!1)}()})),r({close:u,cancellable:c(s,"cancellable")}),(e,r)=>(d(),p(m(se),{ref_key:"$root",ref:o,open:!0,onClose:r[0]||(r[0]=e=>t.cancellable&&u())},{default:f((()=>[h(e.$slots,"default",{close:u})])),_:3},512))}});ot.__file="src/components/headless/modals/AGHeadlessModal.vue";var nt=u({__name:"AGModalContext",props:{modal:ke(),childIndex:Ae()},setup(e){const t=e;return v("modal",{modal:c(t,"modal"),childIndex:c(t,"childIndex")}),(t,r)=>(d(),p(g(e.modal.component),_(b(e.modal.properties)),null,16))}});nt.__file="src/components/modals/AGModalContext.vue";const at=k("div",{class:"pointer-events-none fixed inset-0 z-50 bg-black/30"},null,-1);var lt=u({__name:"AGHeadlessModalPanel",setup(e){const t=he("modal","could not obtain modal reference from <AGHeadlessModalPanel>, did you render this component manually? Show it using $ui.openModal() instead"),r=l((()=>Ve.modals[t.childIndex]??null));return(e,s)=>(d(),p(m(oe),null,{default:f((()=>[h(e.$slots,"default"),r.value?(d(),y(x,{key:0},[at,w(nt,{"child-index":m(t).childIndex+1,modal:r.value},null,8,["child-index","modal"])],64)):A("v-if",!0)])),_:3}))}});lt.__file="src/components/headless/modals/AGHeadlessModalPanel.vue";const it={class:"fixed inset-0 flex items-center justify-center p-8"},ut={class:"flex max-h-full flex-col overflow-auto p-4"};var ct=u({__name:"AGModal",props:{cancellable:ce(!0)},setup(t,{expose:r}){const s=e();return r({close:async()=>s.value?.close(),cancellable:l((()=>!!s.value?.cancellable))}),(e,r)=>(d(),p(ot,{ref_key:"$headlessModal",ref:s,cancellable:t.cancellable,class:"relative z-50"},{default:f((({close:t})=>[k("div",it,[w(lt,{class:"flex max-h-full max-w-full flex-col overflow-hidden bg-white"},{default:f((()=>[k("div",ut,[h(e.$slots,"default",{close:t})])])),_:2},1024)])])),_:3},8,["cancellable"]))}});function dt(e){return t=le(e,{mangle:!1,headerIds:!1}),ae.sanitize(t,{ADD_ATTR:["target"]});var t}ct.__file="src/components/modals/AGModal.vue";var pt=u({__name:"AGMarkdown",props:{as:Se("div"),heading:ce(),inline:ce(),langKey:Se(),raw:ce(),text:Se()},setup(e){const t=e,r=l((()=>t.text??(t.langKey&&Ne(t.langKey)))),s=l((()=>{if(!r.value)return null;let e=dt(r.value);return t.heading&&(e=e.replace("<p>","<span>").replace("</p>","</span>")),t.inline&&(e=e.replace("<p>","<span>").replace("</p>","</span>")),e})),o=()=>j(t.as,{class:t.raw?"":"prose",innerHTML:s.value});return(e,t)=>(d(),p(o))}});pt.__file="src/components/basic/AGMarkdown.vue";var mt=u({__name:"AGAlertModal",props:{title:Se(),message:je()},setup:e=>(t,r)=>(d(),p(ct,null,{default:f((()=>[e.title?(d(),p(pt,{key:0,text:e.title,as:"h2",class:"font-semibold",raw:"",inline:""},null,8,["text"])):A("v-if",!0),w(pt,{text:e.message},null,8,["text"])])),_:1}))});mt.__file="src/components/modals/AGAlertModal.vue";var ft=u({__name:"AGHeadlessButton",props:{url:Se(),route:Se(),routeParams:be((()=>({}))),routeQuery:be((()=>({}))),submit:ce()},setup(e){const{url:t,route:r,routeParams:s,routeQuery:o,submit:n}=e,a=l((()=>r?{tag:"router-link",props:{to:Q({name:r,params:s,query:o})}}:t?{tag:"a",props:{target:"_blank",href:t}}:{tag:"button",props:{type:n?"submit":"button"}}));return(e,t)=>(d(),p(g(a.value.tag),_(b(a.value.props)),{default:f((()=>[h(e.$slots,"default")])),_:3},16))}});ft.__file="src/components/headless/forms/AGHeadlessButton.vue";var ht=u({__name:"AGButton",props:{color:me(Qe,Qe.Primary)},setup(e){const t=e,r=l((()=>{switch(t.color){case Qe.Secondary:return["text-white bg-gray-600","hover:bg-gray-500","focus-visible:outline-offset-2 focus-visible:outline-gray-600"].join(" ");case Qe.Clear:return"hover:bg-gray-500/20 focus-visible:outline-gray-500/60";case Qe.Danger:return["text-white bg-red-600","hover:bg-red-500","focus-visible:outline-offset-2 focus-visible:outline-red-600"].join(" ");default:return["text-white bg-indigo-600","hover:bg-indigo-500","focus-visible:outline-offset-2 focus-visible:outline-indigo-600"].join(" ")}}));return(e,t)=>(d(),p(ft,{class:S(["px-2.5 py-1.5 focus-visible:outline focus-visible:outline-2",r.value])},{default:f((()=>[h(e.$slots,"default")])),_:3},8,["class"]))}});ht.__file="src/components/forms/AGButton.vue";const vt={class:"mt-2 flex flex-row-reverse gap-2"};var gt=u({__name:"AGConfirmModal",props:{title:Se(),message:je()},setup:e=>(t,r)=>(d(),p(ct,{cancellable:!1},{default:f((({close:r})=>[e.title?(d(),p(pt,{key:0,text:e.title,as:"h1"},null,8,["text"])):A("v-if",!0),w(pt,{text:e.message},null,8,["text"]),k("div",vt,[w(ht,{onClick:e=>r(!0)},{default:f((()=>[G(M(t.$td("ui.ok","OK")),1)])),_:2},1032,["onClick"]),w(ht,{color:"secondary",onClick:e=>r()},{default:f((()=>[G(M(t.$td("ui.cancel","Cancel")),1)])),_:2},1032,["onClick"])])])),_:1}))});gt.__file="src/components/modals/AGConfirmModal.vue";const _t={viewBox:"0 0 20 20",width:"1.2em",height:"1.2em"},bt=[k("path",{fill:"currentColor",d:"m12.95 10.707l.707-.707L8 4.343L6.586 5.757L10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"},null,-1)];var yt={name:"zondicons-cheveron-right",render:function(e,t){return d(),y("svg",_t,bt)}};const xt={viewBox:"0 0 20 20",width:"1.2em",height:"1.2em"},wt=[k("path",{fill:"currentColor",d:"M7.05 9.293L6.343 10L12 15.657l1.414-1.414L9.172 10l4.242-4.243L12 4.343z"},null,-1)];var At={name:"zondicons-cheveron-left",render:function(e,t){return d(),y("svg",xt,wt)}};const kt={reports:ye()};function jt(){return kt}const St={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"},Gt=[k("path",{fill:"currentColor",d:"M20 19V7H4v12h16m0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16m-7 14v-2h5v2h-5m-3.42-4L5.57 9H8.4l3.3 3.3c.39.39.39 1.03 0 1.42L8.42 17H5.59l3.99-4Z"},null,-1)];var Mt={name:"mdi-console",render:function(e,t){return d(),y("svg",St,Gt)}};const Ct={viewBox:"0 0 20 20",width:"1.2em",height:"1.2em"},$t=[k("path",{fill:"currentColor",d:"M6 6V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h4zm2 0h4a2 2 0 0 1 2 2v4h4V2H8v4zM2 8v10h10V8H2z"},null,-1)];var Et={name:"zondicons-copy",render:function(e,t){return d(),y("svg",Ct,$t)}};const Ht={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"},It=[k("path",{fill:"currentColor",d:"M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33c.85 0 1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2Z"},null,-1)];var Rt={name:"mdi-github",render:function(e,t){return d(),y("svg",Ht,It)}};const Lt={class:"flex"};var Pt=u({__name:"AGErrorReportModalButtons",props:{report:ke()},setup(e){const t=e,r=l((()=>t.report.description?`${t.report.title}: ${t.report.description}`:t.report.title)),s=l((()=>{if(!Be.sourceUrl)return!1;const e=encodeURIComponent(r.value),s=encodeURIComponent(["[Please, explain here what you were trying to do when this error appeared]","","Error details:","```",Y(t.report.details??"Details missing from report",1800-e.length-Be.sourceUrl.length).trim(),"```"].join("\n"));return`${Be.sourceUrl}/issues/new?title=${e}&body=${s}`})),o=l((()=>F([{id:"clipboard",description:"Copy to clipboard",iconComponent:Et,async handler(){await navigator.clipboard.writeText(`${r.value}\n\n${t.report.details}`),Ve.showSnackbar(Ue("errors.copiedToClipboard","Debug information copied to clipboard"))}},{id:"console",description:"Log to console",iconComponent:Mt,handler(){window.error=t.report.error,Ve.showSnackbar(Ue("errors.addedToConsole","You can now use the **error** variable in the console"))}}],(e=>{s.value&&e.push({id:"github",description:"Report in GitHub",iconComponent:Rt,url:s.value})}))));return(e,t)=>(d(),y("div",Lt,[(d(!0),y(x,null,C(o.value,((t,r)=>h(e.$slots,"default",$(t,{key:r}),(()=>[w(ht,{color:"clear",url:t.url,title:e.$td(`errors.report_${t.id}`,t.description),"aria-label":e.$td(`errors.report_${t.id}`,t.description),onClick:t.handler},{default:f((()=>[(d(),p(g(t.iconComponent),{class:"h-4 w-4","aria-hidden":"true"}))])),_:2},1032,["url","title","aria-label","onClick"])])))),128))]))}});Pt.__file="src/components/modals/AGErrorReportModalButtons.vue";var Bt=u({__name:"AGErrorReportModalTitle",props:{report:ke(),currentReport:_e(),totalReports:_e()},setup(e){const t=e,r=l((()=>!t.totalReports||t.totalReports<=1?t.report.title:`${t.report.title} (${t.currentReport}/${t.totalReports})`));return(e,t)=>(d(),p(pt,{text:r.value,heading:""},null,8,["text"]))}});Bt.__file="src/components/modals/AGErrorReportModalTitle.vue";const Ot={class:"flex items-center justify-between text-lg font-medium"},Dt={class:"flex items-center"},qt=["textContent"];var Tt=u({__name:"AGErrorReportModal",props:jt(),setup(t){const r=t,s=e(0),o=l((()=>r.reports[s.value]));return(e,t)=>(d(),p(ct,null,{default:f((()=>[k("div",null,[k("h2",Ot,[k("div",Dt,[w(Bt,{report:o.value,"current-report":s.value+1,"total-reports":e.reports.length},null,8,["report","current-report","total-reports"]),e.reports.length>1?(d(),y(x,{key:0},[w(ht,{color:"clear",disabled:0===s.value,title:e.$td("errors.previousReport","Show previous report"),"aria-label":e.$td("errors.previousReport","Show previous report"),onClick:t[0]||(t[0]=e=>s.value--)},{default:f((()=>[w(m(At),{"aria-hidden":"true",class:"h-4 w-4"})])),_:1},8,["disabled","title","aria-label"]),w(ht,{color:"clear",disabled:s.value===e.reports.length-1,title:e.$td("errors.nextReport","Show next report"),"aria-label":e.$td("errors.nextReport","Show next report"),onClick:t[1]||(t[1]=e=>s.value++)},{default:f((()=>[w(m(yt),{"aria-hidden":"true",class:"h-4 w-4"})])),_:1},8,["disabled","title","aria-label"])],64)):A("v-if",!0)]),w(Pt,{report:o.value},null,8,["report"])]),o.value.description?(d(),p(pt,{key:0,text:o.value.description,class:"mt-2"},null,8,["text"])):A("v-if",!0)]),k("pre",{class:"h-full overflow-auto bg-gray-200 p-4 text-xs text-red-900",textContent:M(o.value.details??e.$td("errors.detailsEmpty","This error is missing a stacktrace."))},null,8,qt)])),_:1}))}});Tt.__file="src/components/modals/AGErrorReportModal.vue";var zt=u({__name:"AGLoadingModal",props:{message:Se()},setup(e){const t=e,r=l((()=>t.message??Ue("ui.loading","Loading...")));return(e,t)=>(d(),p(ct,{cancellable:!1},{default:f((()=>[w(pt,{text:r.value},null,8,["text"])])),_:1}))}});zt.__file="src/components/modals/AGLoadingModal.vue";var Vt=u({__name:"AGHeadlessInput",props:{as:Se("div"),name:Se(),modelValue:ge([String,Number,Boolean])},emits:["update:modelValue"],setup(e,{expose:r,emit:s}){const o=e,n=l((()=>a&&o.name?a.errors[o.name]??null:null)),a=t("form",null),i={id:`input-${N()}`,value:l((()=>a&&o.name?a.getFieldValue(o.name):o.modelValue)),errors:E(n),update(e){a&&o.name?a.setFieldValue(o.name,e):s("update:modelValue",e)}};return v("input",i),r(i),(t,r)=>e.as?(d(),p(g(e.as),{key:0},{default:f((()=>[h(t.$slots,"default")])),_:3})):h(t.$slots,"default",{key:1})}});Vt.__file="src/components/headless/forms/AGHeadlessInput.vue";const Ft=["id"];var Nt=u({__name:"AGHeadlessInputError",setup(e){const t=he("input","<AGHeadlessInputError> must be a child of a <AGHeadlessInput>"),r=l((()=>t.errors?Ue(`errors.${t.errors[0]}`,`Error: ${t.errors[0]}`):null));return(e,s)=>r.value?(d(),y("p",{key:0,id:`${m(t).id}-error`},M(r.value),9,Ft)):A("v-if",!0)}});Nt.__file="src/components/headless/forms/AGHeadlessInputError.vue";const Ut=["id","type","value","aria-invalid","aria-describedby","checked"];var Kt=u({__name:"AGHeadlessInputInput",props:{type:Se("text")},setup(t){const r=t,s=e(),o=he("input","<AGHeadlessInputInput> must be a child of a <AGHeadlessInput>"),n=l((()=>o.value)),a=l((()=>{if("checkbox"===r.type)return!!n.value}));function i(){s.value&&o.update("checkbox"===r.type?s.value.checked:s.value.value)}return(e,r)=>(d(),y("input",{id:m(o).id,ref_key:"$input",ref:s,type:t.type,value:n.value,"aria-invalid":m(o).errors?"true":"false","aria-describedby":m(o).errors?`${m(o).id}-error`:void 0,checked:a.value,onInput:i},null,40,Ut))}});Kt.__file="src/components/headless/forms/AGHeadlessInputInput.vue";const Qt=["for"];var Wt=u({__name:"AGHeadlessInputLabel",setup(e){const t=he("input","<AGHeadlessInputLabel> must be a child of a <AGHeadlessInput>");return(e,r)=>(d(),y("label",{for:m(t).id},[h(e.$slots,"default")],8,Qt))}});Wt.__file="src/components/headless/forms/AGHeadlessInputLabel.vue";var Zt=u({__name:"AGHeadlessModalTitle",props:{as:Se("h2")},setup:e=>(t,r)=>(d(),p(m(ne),{as:e.as},{default:f((()=>[h(t.$slots,"default")])),_:3},8,["as"]))});Zt.__file="src/components/headless/modals/AGHeadlessModalTitle.vue";const Yt={class:"pointer-events-auto"};var Jt=u({__name:"AGHeadlessSnackbar",setup:e=>(e,t)=>(d(),y("div",Yt,[h(e.$slots,"default")]))});Jt.__file="src/components/headless/snackbars/AGHeadlessSnackbar.vue";const Xt=W(Qe,["Primary","Clear"]),er={id:je(),message:je(),actions:ue((()=>[])),color:me(Xt,Qe.Secondary)};function tr(){return er}var rr=u({__name:"AGSnackbar",props:tr(),setup(e){const t=e,r=l((()=>t.color===Qe.Danger?"bg-red-200 text-red-900":"bg-gray-900 text-white"));return(e,s)=>(d(),p(Jt,{class:S(["flex flex-row items-center justify-center gap-3 p-4",r.value])},{default:f((()=>[w(pt,{text:e.message,raw:""},null,8,["text"]),(d(!0),y(x,null,C(e.actions,((r,s)=>(d(),p(ht,{key:s,color:e.color,onClick:e=>function(e){e.handler?.(),e.dismiss&&Ve.hideSnackbar(t.id)}(r)},{default:f((()=>[G(M(r.text),1)])),_:2},1032,["color","onClick"])))),128))])),_:1},8,["class"]))}});rr.__file="src/components/snackbars/AGSnackbar.vue";const sr={$ui:Ve};var or={async install(e,t){const r={[ze.AlertModal]:mt,[ze.ConfirmModal]:gt,[ze.ErrorReportModal]:Tt,[ze.LoadingModal]:zt,[ze.Snackbar]:rr};Object.entries({...r,...t.components}).forEach((e=>{let[t,r]=e;return Ve.registerComponent(t,r)})),await De(e,sr)}};async function nr(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=[Me,Je,et,qe,or,...t.plugins??[]],s=H(e);await Promise.all(r.map((e=>e.install(s,t)))??[]),s.mount("#app"),Re.emit("application-mounted")}const ar={key:0};var lr=u({__name:"AGAppModals",setup(e){const t=l((()=>Ve.modals[0]??null));return(e,r)=>t.value?(d(),y("aside",ar,[w(nt,{"child-index":1,modal:t.value},null,8,["modal"])])):A("v-if",!0)}});lr.__file="src/components/AGAppModals.vue";const ir={"aria-live":"assertive",class:"z-60 pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:p-6"},ur={class:"flex w-full flex-col items-center space-y-4 sm:items-end"};const cr={render:function(e,t){return d(),y("div",ir,[k("div",ur,[(d(!0),y(x,null,C(e.$ui.snackbars,(e=>(d(),p(g(e.component),$({id:e.id,key:e.id},e.properties),null,16,["id"])))),128))])])},__file:"src/components/AGAppSnackbars.vue"};var dr=cr,pr=u({__name:"AGAppOverlays",setup(t){const r=e(null),s=e(!0);return tt("show-overlays-backdrop",(async()=>{r.value&&s.value&&(s.value=!1,r.value.classList.remove("opacity-0"))})),tt("hide-overlays-backdrop",(async()=>{r.value&&!s.value&&(s.value=!0,r.value.classList.add("opacity-0"))})),(e,t)=>(d(),y(x,null,[k("div",{ref_key:"$backdrop",ref:r,class:"pointer-events-none fixed inset-0 z-50 bg-black/30 opacity-0"},null,512),w(lr),w(dr)],64))}});pr.__file="src/components/AGAppOverlays.vue";const mr={class:"flex h-full flex-col text-base font-normal leading-tight text-gray-900 antialiased"};var fr=u({__name:"AGAppLayout",setup:e=>(e,t)=>(d(),y("div",mr,[h(e.$slots,"default"),w(pr)]))});fr.__file="src/components/AGAppLayout.vue";const hr={class:"ml-2"};var vr=u({inheritAttrs:!1,__name:"AGCheckbox",props:{name:Se()},setup(e){const t=de();return(r,s)=>(d(),p(Vt,{ref_key:"$input",ref:t,name:e.name,class:"flex"},{default:f((()=>[w(Kt,$(r.$attrs,{type:"checkbox",class:{"text-indigo-600 focus:ring-indigo-600":!m(t)?.errors,"border-red-200 text-red-600 focus:ring-red-600":m(t)?.errors}}),null,16,["class"]),k("div",hr,[r.$slots.default?(d(),p(Wt,{key:0},{default:f((()=>[h(r.$slots,"default")])),_:3})):A("v-if",!0),w(Nt,{class:"text-sm text-red-600"})])])),_:3},8,["name"]))}});vr.__file="src/components/forms/AGCheckbox.vue";const gr=["onSubmit"];var _r=u({__name:"AGForm",props:{form:be()},emits:["submit"],setup(e,{emit:t}){const r=e;function s(){r.form&&!r.form.submit()||t("submit")}return v("form",r.form),(e,t)=>(d(),y("form",{onSubmit:I(s,["prevent"])},[h(e.$slots,"default")],40,gr))}});_r.__file="src/components/forms/AGForm.vue";const br={class:"absolute bottom-0 left-0 translate-y-full"};var yr=u({inheritAttrs:!1,__name:"AGInput",props:{name:Se()},setup(e){const t=de(),[r,s]=rt();return(o,n)=>(d(),p(Vt,{ref_key:"$input",ref:t,class:S(["relative flex flex-col items-center",m(s)]),name:e.name},{default:f((()=>[w(Kt,$(m(r),{class:["block w-full border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600",{"ring-1 ring-red-500":m(t)?.errors}]}),null,16,["class"]),k("div",br,[w(Nt,{class:"mt-1 text-sm text-red-500"})])])),_:1},8,["class","name"]))}});yr.__file="src/components/forms/AGInput.vue";const xr={String:"string",Number:"number",Boolean:"boolean"};class wr extends P{constructor(t){super(),J(this,"errors",void 0),J(this,"_fields",void 0),J(this,"_data",void 0),J(this,"_valid",void 0),J(this,"_submitted",void 0),J(this,"_errors",void 0),this._fields=t,this._submitted=e(!1),this._data=this.getInitialData(t),this._errors=this.getInitialErrors(t),this._valid=l((()=>!Object.values(this._errors).some((e=>null!==e)))),this.errors=E(this._errors)}get valid(){return this._valid.value}get submitted(){return this._submitted.value}setFieldValue(e,t){this._data[e]=t,this._submitted.value&&this.validate()}getFieldValue(e){return this._data[e]}validate(){const e=Object.entries(this._fields).reduce(((e,t)=>{let[r,s]=t;return e[r]=this.getFieldErrors(r,s),e}),{});return this.resetErrors(e),this.valid}reset(){this._submitted.value=!1,this.resetData(),this.resetErrors()}submit(){return this._submitted.value=!0,this.validate()}__get(e){return e in this._fields?this._data[e]:super.__get(e)}__set(e,t){e in this._fields?Object.assign(this._data,{[e]:t}):super.__set(e,t)}getFieldErrors(e,t){const r=[];return t.rules?.includes("required")&&!this._data[e]&&r.push("required"),r.length>0?r:null}getInitialData(e){if(this.static().isConjuring())return{};const t=Object.entries(e).reduce(((e,t)=>{let[r,s]=t;return e[r]=s.default??null,e}),{});return r(t)}getInitialErrors(e){if(this.static().isConjuring())return{};const t=Object.keys(e).reduce(((e,t)=>(e[t]=null,e)),{});return r(t)}resetData(){for(const[e,t]of Object.entries(this._fields))this._data[e]=t.default??null}resetErrors(e){Object.keys(this._errors).forEach((e=>delete this._errors[e])),e&&Object.assign(this._errors,e)}}function Ar(e){return new wr(e)}function kr(e){return{default:e,type:xr.Boolean}}function jr(e){return{default:e,type:xr.Boolean,rules:"required"}}function Sr(e){return{default:e,type:xr.Number,rules:"required"}}function Gr(e){return{default:e,type:xr.String,rules:"required"}}function Mr(e){return{default:e,type:xr.Number}}function Cr(e){return{default:e,type:xr.String}}export{mt as AGAlertModal,fr as AGAppLayout,pr as AGAppOverlays,ht as AGButton,vr as AGCheckbox,gt as AGConfirmModal,Pt as AGErrorReportModalButtons,Bt as AGErrorReportModalTitle,_r as AGForm,ft as AGHeadlessButton,Vt as AGHeadlessInput,Nt as AGHeadlessInputError,Kt as AGHeadlessInputInput,Wt as AGHeadlessInputLabel,ot as AGHeadlessModal,lt as AGHeadlessModalPanel,Zt as AGHeadlessModalTitle,Jt as AGHeadlessSnackbar,yr as AGInput,zt as AGLoadingModal,pt as AGMarkdown,ct as AGModal,nt as AGModalContext,rr as AGSnackbar,Be as App,Pe as AppService,Qe as Colors,We as Errors,Re as Events,Ie as EventsService,xr as FormFieldTypes,Fe as Lang,He as Service,Xt as SnackbarColors,Ve as UI,ze as UIComponents,ue as arrayProp,kr as booleanInput,ce as booleanProp,De as bootServices,nr as bootstrapApplication,de as componentRef,pe as defineDirective,ie as definePlugin,Ee as defineServiceState,me as enumProp,kt as errorReportModalProps,ve as injectOrFail,fe as injectReactive,he as injectReactiveOrFail,ge as mixedProp,Mr as numberInput,_e as numberProp,be as objectProp,st as onCleanMounted,ye as requiredArrayProp,jr as requiredBooleanInput,xe as requiredEnumProp,we as requiredMixedProp,Sr as requiredNumberInput,Ae as requiredNumberProp,ke as requiredObjectProp,Gr as requiredStringInput,je as requiredStringProp,er as snackbarProps,Cr as stringInput,Se as stringProp,Ne as translate,Ue as translateWithDefault,jt as useErrorReportModalProps,tt as useEvent,Ar as useForm,rt as useInputAttrs,tr as useSnackbarProps};
|
|
2
2
|
//# sourceMappingURL=aerogel-core.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aerogel-core.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"aerogel-core.esm.js","sources":["../src/components/AGAppSnackbars.vue?vue&type=template&id=7942f27a&lang.js"],"sourcesContent":["<template>\n <div aria-live=\"assertive\" class=\"z-60 pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:p-6\">\n <div class=\"flex w-full flex-col items-center space-y-4 sm:items-end\">\n <component\n :is=\"snackbar.component\"\n v-for=\"snackbar of $ui.snackbars\"\n :id=\"snackbar.id\"\n :key=\"snackbar.id\"\n v-bind=\"snackbar.properties\"\n />\n </div>\n </div>\n</template>\n"],"names":["class","_hoisted_2","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_Fragment","_renderList","_ctx","$ui","snackbars","snackbar","_createBlock","_resolveDynamicComponent","component","_mergeProps","id","key","properties"],"mappings":"i52BACS,YAAU,YAAYA,MAAM,0EACxBC,GAAA,CAAAD,MAAM,2FADf,OAAAE,IAAAC,EAUK,MAVLC,GAUK,CATDC,EAQK,MARLJ,GAQK,EAPDC,GAAA,GAAAC,EAMCG,EAJsB,KAAAC,EAAAC,EAAAC,IAAIC,WAAhBC,IAFXT,IAAAU,EAMCC,EALQF,EAASG,WADlBC,EAMC,CAHIC,GAAIL,EAASK,GACbC,IAAKN,EAASK,IACPL,EAASO,YAAU,KAAA,GAAA,CAAA"}
|
package/noeldemartin.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aerogel/core",
|
|
3
3
|
"description": "The Lightest Solid",
|
|
4
|
-
"version": "0.0.0-next.
|
|
4
|
+
"version": "0.0.0-next.f16bd1d894543c5303039c49f6f33488a1ffe931",
|
|
5
5
|
"main": "dist/aerogel-core.cjs.js",
|
|
6
6
|
"module": "dist/aerogel-core.esm.js",
|
|
7
7
|
"types": "dist/aerogel-core.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "rm dist -rf && npm run build:js && npm run build:types",
|
|
11
11
|
"build:js": "noeldemartin-build-javascript",
|
|
12
|
-
"build:types": "noeldemartin-build-types",
|
|
12
|
+
"build:types": "noeldemartin-build-types && cp src/types/virtual.d.ts dist",
|
|
13
13
|
"lint": "noeldemartin-lint src",
|
|
14
14
|
"publish-next": "noeldemartin-publish-next",
|
|
15
15
|
"test": "vitest --run"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<aside v-if="modal">
|
|
3
|
+
<AGModalContext :child-index="1" :modal="modal" />
|
|
4
|
+
</aside>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { computed } from 'vue';
|
|
9
|
+
|
|
10
|
+
import UI from '@/ui/UI';
|
|
11
|
+
|
|
12
|
+
import AGModalContext from './modals/AGModalContext.vue';
|
|
13
|
+
|
|
14
|
+
const modal = computed(() => UI.modals[0] ?? null);
|
|
15
|
+
</script>
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="$backdrop" class="pointer-events-none fixed inset-0 z-50 bg-black/30 opacity-0" />
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
</aside>
|
|
3
|
+
<AGAppModals />
|
|
4
|
+
<AGAppSnackbars />
|
|
6
5
|
</template>
|
|
7
6
|
|
|
8
7
|
<script setup lang="ts">
|
|
9
|
-
import {
|
|
8
|
+
import { ref } from 'vue';
|
|
10
9
|
|
|
11
|
-
import UI from '@/ui/UI';
|
|
12
10
|
import { useEvent } from '@/utils/composition/events';
|
|
13
11
|
|
|
14
|
-
import
|
|
12
|
+
import AGAppModals from './AGAppModals.vue';
|
|
13
|
+
import AGAppSnackbars from './AGAppSnackbars.vue';
|
|
15
14
|
|
|
16
15
|
const $backdrop = ref<HTMLElement | null>(null);
|
|
17
16
|
const backdropHidden = ref(true);
|
|
18
|
-
const modal = computed(() => UI.modals[0] ?? null);
|
|
19
17
|
|
|
20
18
|
useEvent('show-overlays-backdrop', async () => {
|
|
21
19
|
if (!$backdrop.value || !backdropHidden.value) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div aria-live="assertive" class="z-60 pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:p-6">
|
|
3
|
+
<div class="flex w-full flex-col items-center space-y-4 sm:items-end">
|
|
4
|
+
<component
|
|
5
|
+
:is="snackbar.component"
|
|
6
|
+
v-for="snackbar of $ui.snackbars"
|
|
7
|
+
:id="snackbar.id"
|
|
8
|
+
:key="snackbar.id"
|
|
9
|
+
v-bind="snackbar.properties"
|
|
10
|
+
/>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
@@ -11,10 +11,11 @@ import { translate } from '@/lang';
|
|
|
11
11
|
|
|
12
12
|
const props = defineProps({
|
|
13
13
|
as: stringProp('div'),
|
|
14
|
-
|
|
15
|
-
text: stringProp(),
|
|
14
|
+
heading: booleanProp(),
|
|
16
15
|
inline: booleanProp(),
|
|
16
|
+
langKey: stringProp(),
|
|
17
17
|
raw: booleanProp(),
|
|
18
|
+
text: stringProp(),
|
|
18
19
|
});
|
|
19
20
|
|
|
20
21
|
const markdown = computed(() => props.text ?? (props.langKey && translate(props.langKey)));
|
|
@@ -25,6 +26,10 @@ const html = computed(() => {
|
|
|
25
26
|
|
|
26
27
|
let renderedHtml = renderMarkdown(markdown.value);
|
|
27
28
|
|
|
29
|
+
if (props.heading) {
|
|
30
|
+
renderedHtml = renderedHtml.replace('<p>', '<span>').replace('</p>', '</span>');
|
|
31
|
+
}
|
|
32
|
+
|
|
28
33
|
if (props.inline) {
|
|
29
34
|
renderedHtml = renderedHtml.replace('<p>', '<span>').replace('</p>', '</span>');
|
|
30
35
|
}
|
|
@@ -7,28 +7,38 @@
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
8
|
import { computed } from 'vue';
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { enumProp } from '@/utils/vue';
|
|
11
|
+
import { Colors } from '@/components/constants';
|
|
11
12
|
|
|
12
13
|
import AGHeadlessButton from '../headless/forms/AGHeadlessButton.vue';
|
|
13
14
|
|
|
14
15
|
const props = defineProps({
|
|
15
|
-
|
|
16
|
-
secondary: booleanProp(),
|
|
16
|
+
color: enumProp(Colors, Colors.Primary),
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
const colorClasses = computed(() => {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
switch (props.color) {
|
|
21
|
+
case Colors.Secondary:
|
|
22
|
+
return [
|
|
23
|
+
'text-white bg-gray-600',
|
|
24
|
+
'hover:bg-gray-500',
|
|
25
|
+
'focus-visible:outline-offset-2 focus-visible:outline-gray-600',
|
|
26
|
+
].join(' ');
|
|
27
|
+
case Colors.Clear:
|
|
28
|
+
return 'hover:bg-gray-500/20 focus-visible:outline-gray-500/60';
|
|
29
|
+
case Colors.Danger:
|
|
30
|
+
return [
|
|
31
|
+
'text-white bg-red-600',
|
|
32
|
+
'hover:bg-red-500',
|
|
33
|
+
'focus-visible:outline-offset-2 focus-visible:outline-red-600',
|
|
34
|
+
].join(' ');
|
|
35
|
+
case Colors.Primary:
|
|
36
|
+
default:
|
|
37
|
+
return [
|
|
38
|
+
'text-white bg-indigo-600',
|
|
39
|
+
'hover:bg-indigo-500',
|
|
40
|
+
'focus-visible:outline-offset-2 focus-visible:outline-indigo-600',
|
|
41
|
+
].join(' ');
|
|
22
42
|
}
|
|
23
|
-
|
|
24
|
-
if (props.clear) {
|
|
25
|
-
return 'hover:bg-gray-500/20 focus-visible:outline-gray-500/60';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return [
|
|
29
|
-
'text-white bg-indigo-600',
|
|
30
|
-
'hover:bg-indigo-500',
|
|
31
|
-
'focus-visible:outline-offset-2 focus-visible:outline-indigo-600',
|
|
32
|
-
].join(' ');
|
|
33
43
|
});
|
|
34
44
|
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { arrayProp, enumProp, requiredStringProp } from '@/utils/vue';
|
|
2
|
+
import { Colors } from '@/components/constants';
|
|
3
|
+
import { objectWithout } from '@noeldemartin/utils';
|
|
4
|
+
|
|
5
|
+
export { default as AGHeadlessSnackbar } from './AGHeadlessSnackbar.vue';
|
|
6
|
+
|
|
7
|
+
export interface SnackbarAction {
|
|
8
|
+
text: string;
|
|
9
|
+
dismiss?: boolean;
|
|
10
|
+
handler?(): unknown;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type SnackbarColor = (typeof SnackbarColors)[keyof typeof SnackbarColors];
|
|
14
|
+
|
|
15
|
+
export const SnackbarColors = objectWithout(Colors, ['Primary', 'Clear']);
|
|
16
|
+
export const snackbarProps = {
|
|
17
|
+
id: requiredStringProp(),
|
|
18
|
+
message: requiredStringProp(),
|
|
19
|
+
actions: arrayProp<SnackbarAction>(() => []),
|
|
20
|
+
color: enumProp(SnackbarColors, Colors.Secondary),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export function useSnackbarProps(): typeof snackbarProps {
|
|
24
|
+
return snackbarProps;
|
|
25
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Component } from 'vue';
|
|
2
|
+
|
|
3
|
+
import { requiredArrayProp } from '@/utils/vue';
|
|
4
|
+
import type { ErrorReport } from '@/errors';
|
|
5
|
+
|
|
6
|
+
export interface IAGErrorReportModalButtonsDefaultSlotProps {
|
|
7
|
+
id: string;
|
|
8
|
+
description: string;
|
|
9
|
+
iconComponent: Component;
|
|
10
|
+
url?: string;
|
|
11
|
+
handler?(): void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const errorReportModalProps = {
|
|
15
|
+
reports: requiredArrayProp<ErrorReport>(),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function useErrorReportModalProps(): typeof errorReportModalProps {
|
|
19
|
+
return errorReportModalProps;
|
|
20
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<AGModal>
|
|
3
|
+
<div>
|
|
4
|
+
<h2 class="flex items-center justify-between text-lg font-medium">
|
|
5
|
+
<div class="flex items-center">
|
|
6
|
+
<AGErrorReportModalTitle
|
|
7
|
+
:report="report"
|
|
8
|
+
:current-report="activeReportIndex + 1"
|
|
9
|
+
:total-reports="reports.length"
|
|
10
|
+
/>
|
|
11
|
+
<template v-if="reports.length > 1">
|
|
12
|
+
<AGButton
|
|
13
|
+
color="clear"
|
|
14
|
+
:disabled="activeReportIndex === 0"
|
|
15
|
+
:title="$td('errors.previousReport', 'Show previous report')"
|
|
16
|
+
:aria-label="$td('errors.previousReport', 'Show previous report')"
|
|
17
|
+
@click="activeReportIndex--"
|
|
18
|
+
>
|
|
19
|
+
<IconCheveronLeft aria-hidden="true" class="h-4 w-4" />
|
|
20
|
+
</AGButton>
|
|
21
|
+
<AGButton
|
|
22
|
+
color="clear"
|
|
23
|
+
:disabled="activeReportIndex === reports.length - 1"
|
|
24
|
+
:title="$td('errors.nextReport', 'Show next report')"
|
|
25
|
+
:aria-label="$td('errors.nextReport', 'Show next report')"
|
|
26
|
+
@click="activeReportIndex++"
|
|
27
|
+
>
|
|
28
|
+
<IconCheveronRight aria-hidden="true" class="h-4 w-4" />
|
|
29
|
+
</AGButton>
|
|
30
|
+
</template>
|
|
31
|
+
</div>
|
|
32
|
+
<AGErrorReportModalButtons :report="report" />
|
|
33
|
+
</h2>
|
|
34
|
+
<AGMarkdown v-if="report.description" :text="report.description" class="mt-2" />
|
|
35
|
+
</div>
|
|
36
|
+
<pre
|
|
37
|
+
class="h-full overflow-auto bg-gray-200 p-4 text-xs text-red-900"
|
|
38
|
+
v-text="report.details ?? $td('errors.detailsEmpty', 'This error is missing a stacktrace.')"
|
|
39
|
+
/>
|
|
40
|
+
</AGModal>
|
|
41
|
+
</template>
|
|
42
|
+
|
|
43
|
+
<script setup lang="ts">
|
|
44
|
+
import IconCheveronRight from '~icons/zondicons/cheveron-right';
|
|
45
|
+
import IconCheveronLeft from '~icons/zondicons/cheveron-left';
|
|
46
|
+
|
|
47
|
+
import { computed, ref } from 'vue';
|
|
48
|
+
|
|
49
|
+
import type { ErrorReport } from '@/errors';
|
|
50
|
+
|
|
51
|
+
import { useErrorReportModalProps } from './AGErrorReportModal';
|
|
52
|
+
|
|
53
|
+
import AGButton from '../forms/AGButton.vue';
|
|
54
|
+
import AGErrorReportModalButtons from './AGErrorReportModalButtons.vue';
|
|
55
|
+
import AGErrorReportModalTitle from './AGErrorReportModalTitle.vue';
|
|
56
|
+
import AGMarkdown from '../basic/AGMarkdown.vue';
|
|
57
|
+
import AGModal from './AGModal.vue';
|
|
58
|
+
|
|
59
|
+
const props = defineProps(useErrorReportModalProps());
|
|
60
|
+
const activeReportIndex = ref(0);
|
|
61
|
+
const report = computed(() => props.reports[activeReportIndex.value] as ErrorReport);
|
|
62
|
+
</script>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex">
|
|
3
|
+
<slot v-for="(button, i) of buttons" v-bind="(button as unknown as ComponentProps)" :key="i">
|
|
4
|
+
<AGButton
|
|
5
|
+
color="clear"
|
|
6
|
+
:url="button.url"
|
|
7
|
+
:title="$td(`errors.report_${button.id}`, button.description)"
|
|
8
|
+
:aria-label="$td(`errors.report_${button.id}`, button.description)"
|
|
9
|
+
@click="button.handler"
|
|
10
|
+
>
|
|
11
|
+
<component :is="button.iconComponent" class="h-4 w-4" aria-hidden="true" />
|
|
12
|
+
</AGButton>
|
|
13
|
+
</slot>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
import IconConsole from '~icons/mdi/console';
|
|
19
|
+
import IconCopy from '~icons/zondicons/copy';
|
|
20
|
+
import IconGitHub from '~icons/mdi/github';
|
|
21
|
+
|
|
22
|
+
import { computed } from 'vue';
|
|
23
|
+
import { stringExcerpt, tap } from '@noeldemartin/utils';
|
|
24
|
+
|
|
25
|
+
import App from '@/services/App';
|
|
26
|
+
import UI from '@/ui/UI';
|
|
27
|
+
import { requiredObjectProp } from '@/utils/vue';
|
|
28
|
+
import { translateWithDefault } from '@/lang/utils';
|
|
29
|
+
import type { ComponentProps } from '@/utils/vue';
|
|
30
|
+
import type { ErrorReport } from '@/errors';
|
|
31
|
+
|
|
32
|
+
import AGButton from '../forms/AGButton.vue';
|
|
33
|
+
import type { IAGErrorReportModalButtonsDefaultSlotProps } from './AGErrorReportModal';
|
|
34
|
+
|
|
35
|
+
const props = defineProps({
|
|
36
|
+
report: requiredObjectProp<ErrorReport>(),
|
|
37
|
+
});
|
|
38
|
+
const summary = computed(() =>
|
|
39
|
+
props.report.description ? `${props.report.title}: ${props.report.description}` : props.report.title);
|
|
40
|
+
const githubReportUrl = computed(() => {
|
|
41
|
+
if (!App.sourceUrl) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const issueTitle = encodeURIComponent(summary.value);
|
|
46
|
+
const issueBody = encodeURIComponent(
|
|
47
|
+
[
|
|
48
|
+
'[Please, explain here what you were trying to do when this error appeared]',
|
|
49
|
+
'',
|
|
50
|
+
'Error details:',
|
|
51
|
+
'```',
|
|
52
|
+
stringExcerpt(
|
|
53
|
+
props.report.details ?? 'Details missing from report',
|
|
54
|
+
1800 - issueTitle.length - App.sourceUrl.length,
|
|
55
|
+
).trim(),
|
|
56
|
+
'```',
|
|
57
|
+
].join('\n'),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return `${App.sourceUrl}/issues/new?title=${issueTitle}&body=${issueBody}`;
|
|
61
|
+
});
|
|
62
|
+
const buttons = computed(() =>
|
|
63
|
+
tap(
|
|
64
|
+
[
|
|
65
|
+
{
|
|
66
|
+
id: 'clipboard',
|
|
67
|
+
description: 'Copy to clipboard',
|
|
68
|
+
iconComponent: IconCopy,
|
|
69
|
+
async handler() {
|
|
70
|
+
await navigator.clipboard.writeText(`${summary.value}\n\n${props.report.details}`);
|
|
71
|
+
|
|
72
|
+
UI.showSnackbar(
|
|
73
|
+
translateWithDefault('errors.copiedToClipboard', 'Debug information copied to clipboard'),
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: 'console',
|
|
79
|
+
description: 'Log to console',
|
|
80
|
+
iconComponent: IconConsole,
|
|
81
|
+
handler() {
|
|
82
|
+
(window as { error?: unknown }).error = props.report.error;
|
|
83
|
+
|
|
84
|
+
UI.showSnackbar(
|
|
85
|
+
translateWithDefault(
|
|
86
|
+
'errors.addedToConsole',
|
|
87
|
+
'You can now use the **error** variable in the console',
|
|
88
|
+
),
|
|
89
|
+
);
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
(reportButtons: IAGErrorReportModalButtonsDefaultSlotProps[]) => {
|
|
94
|
+
if (!githubReportUrl.value) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
reportButtons.push({
|
|
99
|
+
id: 'github',
|
|
100
|
+
description: 'Report in GitHub',
|
|
101
|
+
iconComponent: IconGitHub,
|
|
102
|
+
url: githubReportUrl.value,
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
));
|
|
106
|
+
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<AGMarkdown :text="text" heading />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { computed } from 'vue';
|
|
7
|
+
|
|
8
|
+
import { numberProp, requiredObjectProp } from '@/utils/vue';
|
|
9
|
+
import type { ErrorReport } from '@/errors';
|
|
10
|
+
|
|
11
|
+
import AGMarkdown from '../basic/AGMarkdown.vue';
|
|
12
|
+
|
|
13
|
+
const props = defineProps({
|
|
14
|
+
report: requiredObjectProp<ErrorReport>(),
|
|
15
|
+
currentReport: numberProp(),
|
|
16
|
+
totalReports: numberProp(),
|
|
17
|
+
});
|
|
18
|
+
const text = computed(() => {
|
|
19
|
+
if (!props.totalReports || props.totalReports <= 1) {
|
|
20
|
+
return props.report.title;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return `${props.report.title} (${props.currentReport}/${props.totalReports})`;
|
|
24
|
+
});
|
|
25
|
+
</script>
|