@tachybase/module-multi-app 0.23.35 → 0.23.41

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.
@@ -4,3 +4,9 @@ export declare const useCreateDatabaseConnectionAction: () => {
4
4
  export declare const useMultiAppUpdateAction: (actionCallback?: (key: string, values: any) => void) => {
5
5
  onClick(): Promise<void>;
6
6
  };
7
+ export declare const useStartAllAction: () => {
8
+ onClick(): Promise<void>;
9
+ };
10
+ export declare const useStopAllAction: () => {
11
+ onClick(): Promise<void>;
12
+ };
@@ -1 +1 @@
1
- (function(n,o){typeof exports=="object"&&typeof module!="undefined"?o(exports,require("react/jsx-runtime"),require("@tachybase/client"),require("@ant-design/icons"),require("react"),require("antd"),require("@tachybase/schema"),require("react-i18next"),require("react-router-dom")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","@tachybase/client","@ant-design/icons","react","antd","@tachybase/schema","react-i18next","react-router-dom"],o):(n=typeof globalThis!="undefined"?globalThis:n||self,o(n["@tachybase/module-multi-app"]={},n.jsxRuntime,n["@tachybase/client"],n["@ant-design/icons"],n.react,n.antd,n["@tachybase/schema"],n["react-i18next"],n["react-router-dom"]))})(this,function(n,o,e,C,f,x,d,h,m){"use strict";var U=Object.defineProperty,K=Object.defineProperties;var G=Object.getOwnPropertyDescriptors;var F=Object.getOwnPropertySymbols;var H=Object.prototype.hasOwnProperty,J=Object.prototype.propertyIsEnumerable;var M=(n,o,e)=>o in n?U(n,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[o]=e,v=(n,o)=>{for(var e in o||(o={}))H.call(o,e)&&M(n,e,o[e]);if(F)for(var e of F(o))J.call(o,e)&&M(n,e,o[e]);return n},b=(n,o)=>K(n,G(o));var g=(n,o,e)=>new Promise((C,f)=>{var x=m=>{try{h(e.next(m))}catch(c){f(c)}},d=m=>{try{h(e.throw(m))}catch(c){f(c)}},h=m=>m.done?C(m.value):Promise.resolve(m.value).then(x,d);h((e=e.apply(n,o)).next())});const c="multi-app",V=()=>{const t=d.useForm(),r=d.useField(),a=e.useActionContext(),l=e.useDataBlockRequest(),p=e.useDataBlockResource();return{onClick(){return g(this,null,function*(){try{yield t.submit(),r.data=r.data||{},r.data.loading=!0,yield p.create({values:t.values}),a.setVisible(!1),yield t.reset(),r.data.loading=!1,l.refresh()}catch(s){r.data&&(r.data.loading=!1)}})}}},B=t=>{const r=d.useField(),a=d.useForm(),l=e.useActionContext(),p=e.useDataBlockRequest(),u=e.useDataBlockResource(),s=e.useCollectionRecordData(),y=s==null?void 0:s.name;return{onClick(){return g(this,null,function*(){var P;yield a.submit(),r.data=r.data||{},r.data.loading=!0;try{const A=yield u.update({filterByTk:y,values:a.values});l.setVisible(!1),yield a.reset(),p.refresh(),t==null||t(y,(P=A==null?void 0:A.data)==null?void 0:P.data)}catch(A){console.error(A)}finally{r.data.loading=!1}})}}},S=()=>{const{t}=h.useTranslation([c,"core"]);return{t}},i=t=>`{{t("${t}", { ns: ["${c}", "client"] })}}`,q={name:"applications",targetKey:"name",fields:[{type:"uid",name:"name",primaryKey:!0,prefix:"a",interface:"input",uiSchema:{type:"string",title:i("App ID"),required:!0,"x-component":"Input","x-validator":"uid"}},{type:"string",name:"displayName",interface:"input",uiSchema:{type:"string",title:i("App display name"),required:!0,"x-component":"Input"}},{type:"string",name:"pinned",interface:"checkbox",uiSchema:{type:"boolean","x-content":i("Pin to menu"),"x-component":"Checkbox"}},{type:"string",name:"status",interface:"radioGroup",defaultValue:"pending",uiSchema:{type:"string",title:i("App status"),enum:[{label:"Initializing",value:"initializing"},{label:"Initialized",value:"initialized"},{label:"Running",value:"running"},{label:"Commanding",value:"commanding"},{label:"Stopped",value:"stopped"},{label:"Error",value:"error"},{label:"Not found",value:"not_found"}],"x-component":"Radio.Group"}},{type:"string",name:"isTemplate",interface:"checkbox",uiSchema:{type:"boolean","x-content":i("Is template"),"x-component":"Checkbox"}}]},I={type:"void","x-component":"div",properties:{displayName:{"x-component":"CollectionField","x-decorator":"FormItem"},name:{"x-component":"CollectionField","x-decorator":"FormItem","x-disabled":"{{ !createOnly }}","x-hidden":"{{ !admin }}"},"options.autoStart":{title:i("Start mode"),"x-component":"Radio.Group","x-decorator":"FormItem",default:!1,enum:[{label:i("Start on first visit"),value:!1},{label:i("Start with main application"),value:!0}],"x-hidden":"{{ !admin }}"},cnamePrefix:{title:i("Custom domain prefix"),"x-component":"Input","x-decorator":"FormItem","x-component-props":{addonAfter:`.${window.location.hostname}`},"x-reactions":{dependencies:["cname"],fulfill:{state:{value:'{{($deps[0] && $deps[0].replace(new RegExp("\\."+window.location.hostname+"$"), "")) || ""}}'}}}},cname:{"x-hidden":!0,"x-component":"Input","x-decorator":"FormItem","x-read-pretty":!0,"x-reactions":{dependencies:["cnamePrefix"],fulfill:{state:{value:`{{$deps[0] ? $deps[0] + ".${window.location.hostname}" : null}}`}}}},tmpl:{title:i("Template"),"x-component":"RemoteSelect","x-component-props":{fieldNames:{label:"displayName",value:"name"},service:{resource:"applications",params:{filter:{$or:[{isTemplate:!0},{createdById:"{{ userId }}"}]}}}},"x-decorator":"FormItem","x-disabled":"{{ !createOnly }}"},"options.startEnvs":{type:"string",title:i("Start environment variables"),"x-component":"Input.TextArea","x-decorator":"FormItem","x-hidden":!0},pinned:{"x-component":"CollectionField","x-decorator":"FormItem","x-hidden":"{{ !admin }}"},isTemplate:{"x-component":"CollectionField","x-decorator":"FormItem","x-hidden":"{{ !admin }}"}}},k={properties:{view:{type:"void","x-component":"AppVisitor","x-component-props":{admin:"{{ admin }}"}},update:{type:"void",title:'{{t("Edit")}}',"x-component":"Action.Link",properties:{drawer:{type:"void","x-component":"Action.Drawer","x-decorator":"Form","x-decorator-props":{useValues:"{{ cm.useValuesFromRecord }}"},title:'{{t("Edit")}}',properties:{formSchema:I,footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-use-component-props":"useCancelActionProps"},submit:{title:'{{t("Submit")}}',"x-action":"submit","x-component":"Action","x-use-component-props":"useMultiAppUpdateAction","x-component-props":{type:"primary"}}}}}}}},delete:{type:"void",title:'{{ t("Delete") }}',"x-component":"Action.Link","x-decorator":"ACLActionProvider","x-use-component-props":"useDestroyActionProps","x-component-props":{confirm:{title:"{{t('Delete')}}",content:"{{t('Are you sure you want to delete it?')}}"}}}}},z={type:"void",properties:{provider:{type:"void","x-decorator":"TableBlockProvider","x-decorator-props":{collection:q,action:"list",params:{pageSize:50,sort:["-createdAt"],appends:[],filter:{createdById:"{{ admin ? undefined : userId }}"}},rowKey:"name"},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{style:{marginBottom:16}},properties:{refresh:{type:"void",title:'{{ t("Refresh") }}',"x-component":"Action","x-use-component-props":"useRefreshActionProps","x-component-props":{icon:"ReloadOutlined"}},delete:{type:"void",title:'{{ t("Delete") }}',"x-action":"destroy","x-component":"Action","x-decorator":"ACLActionProvider","x-use-component-props":"useDestroyActionProps","x-component-props":{icon:"DeleteOutlined",confirm:{title:"{{t('Delete')}}",content:"{{t('Are you sure you want to delete it?')}}"}},"x-hidden":"{{ !admin }}"},create:{type:"void",title:'{{t("Add new")}}',"x-decorator":t=>f.createElement(e.SchemaComponentOptions,b(v({},t),{scope:{createOnly:!0}})),"x-component":"Action","x-component-props":{type:"primary",icon:"PlusOutlined"},properties:{drawer:{type:"void","x-component":"Action.Drawer","x-decorator":"Form","x-decorator-props":{useValues(t){const r=e.useActionContext();return e.useRequest(()=>Promise.resolve({data:{name:`a_${d.uid()}`}}),b(v({},t),{refreshDeps:[r.visible]}))}},title:'{{t("Add new")}}',properties:{formSchema:I,footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-use-component-props":"useCancelActionProps"},submit:{title:'{{ t("Submit") }}',"x-component":"Action","x-use-component-props":"useCreateDatabaseConnectionAction","x-component-props":{type:"primary"}}}}}}}}}},table:{type:"array","x-uid":"input","x-component":"TableV2","x-use-component-props":"useTableBlockProps","x-component-props":{rowKey:"name",rowSelection:{type:"checkbox"}},properties:{displayName:{type:"void","x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{displayName:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},name:{type:"void","x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{name:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},pinned:{type:"void",title:i("Pin to menu"),"x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{pinned:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},isTemplate:{type:"void",title:i("Is template"),"x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{isTemplate:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},status:{type:"void","x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{status:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},actions:{type:"void",title:'{{t("Actions")}}',"x-component":"TableV2.Column",properties:{actions:v({type:"void","x-component":"Space","x-component-props":{split:"|"}},k)}}}}}}}},O=()=>{const t=e.useCollectionRecordData(),r=e.useApp();return t.cname?`//${t.cname}`:r.getRouteUrl(`/apps/${t.name}/admin/`)},N=()=>{const{t}=S(),r=O(),a=e.useCollectionRecordData(),l=e.useAPIClient(),{refresh:p}=e.useDataBlockRequest(),u=f.useMemo(()=>l.resource("applications"),[l]),s=()=>{u.start({filterByTk:a.name}).then(()=>{p()}).catch(j=>{p()})},y=()=>{u.stop({filterByTk:a.name}).then(()=>{p()}).catch(j=>{p()})};return o.jsxs(x.Space,{split:o.jsx(x.Divider,{type:"horizontal"}),children:[o.jsx("a",{href:r,target:"_blank",rel:"noreferrer",children:t("View",{ns:c})}),o.jsx("a",{onClick:()=>s(),children:t("Start",{ns:c})}),o.jsx("a",{onClick:()=>y(),children:t("Stop",{ns:c})})]})},T=t=>{var p,u;const{admin:r=!0}=t,a=e.useCurrentUserContext(),l=(u=(p=a==null?void 0:a.data)==null?void 0:p.data)==null?void 0:u.id;return o.jsx(x.Card,{bordered:!1,children:o.jsx(e.SchemaComponent,{schema:z,scope:{admin:r,userId:l,useCreateDatabaseConnectionAction:V,useMultiAppUpdateAction:B},components:{AppVisitor:N}})})},w=()=>{const{insert:t}=e.useSchemaInitializer();S();const r=e.useSchemaInitializerItem();return o.jsx(e.SchemaInitializerItem,b(v({},r),{onClick:()=>{t({type:"void","x-decorator-props":{},"x-component":"CardItem","x-toolbar":"BlockSchemaToolbar","x-settings":"blockSettings:table",properties:{app:{type:"void","x-component":"AppManager","x-component-props":{admin:!1}}}})}}))},$=t=>{const r=e.useApp(),a=t.value&&o.jsx("a",{target:"_blank",href:r.getRouteUrl(`/apps/${t.value}/admin`),rel:"noreferrer",children:t.value});return o.jsxs("div",{style:t.style,children:[t.addonBefore,t.prefix,a,t.suffix,t.addonAfter]})},E=d.connect(x.Input,d.mapReadPretty($)),R=e.createStyles(({token:t})=>({button:{color:t.colorTextHeaderMenu+" !important"}})),L=()=>{const{styles:t}=R(),{data:r,run:a}=e.useRequest({resource:"applications",action:"listPinned"},{manual:!0}),{t:l}=S(),p=e.useApp(),u=[...((r==null?void 0:r.data)||[]).map(s=>{let y=p.getRouteUrl(`/apps/${s.name}/admin/`);return s.cname&&(y=`//${s.cname}`),{key:s.name,label:o.jsx("a",{href:y,target:"_blank",rel:"noopener noreferrer",children:s.displayName||s.name})}}),{key:".manager",label:o.jsx(m.Link,{to:p.systemSettingsManager.getRoutePath("system-services."+c),children:l("Manage applications")})}];return o.jsx(x.Dropdown,{onOpenChange:s=>{a()},menu:{items:u},children:o.jsx(x.Button,{className:t.button,title:"Apps",icon:o.jsx(e.Icon,{type:"AppstoreOutlined"})})})},_=t=>o.jsx(e.PinnedPluginListProvider,{items:{am:{order:201,component:"MultiAppManager",pin:!0,snippet:"pm.*",belongTo:"pinnedmenu"}},children:o.jsx(e.SchemaComponentOptions,{components:{MultiAppManager:L,AppNameInput:E,MultiAppBlockInitializer:w},children:t.children})});class D extends e.Plugin{load(){return g(this,null,function*(){this.app.addComponents({AppManager:T}),this.app.use(_),this.app.systemSettingsManager.add(`system-services.${c}`,{title:i("Multi-app manager"),icon:"AppstoreOutlined",Component:T,aclSnippet:"pm.multi-app-manager.applications"}),this.app.schemaInitializerManager.get("page:addBlock").add("otherBlocks.multiApp",{name:"multiApp",title:i("Multi-app manager"),icon:o.jsx(C.AppstoreOutlined,{}),Component:w})})}}n.MultiAppManagerPlugin=D,n.default=D,n.formSchema=I,n.tableActionColumnSchema=k,Object.defineProperties(n,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ (function(r,e){typeof exports=="object"&&typeof module!="undefined"?e(exports,require("react/jsx-runtime"),require("@tachybase/client"),require("@ant-design/icons"),require("react"),require("antd"),require("@tachybase/schema"),require("react-i18next"),require("react-router-dom")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","@tachybase/client","@ant-design/icons","react","antd","@tachybase/schema","react-i18next","react-router-dom"],e):(r=typeof globalThis!="undefined"?globalThis:r||self,e(r["@tachybase/module-multi-app"]={},r.jsxRuntime,r["@tachybase/client"],r["@ant-design/icons"],r.react,r.antd,r["@tachybase/schema"],r["react-i18next"],r["react-router-dom"]))})(this,function(r,e,o,A,v,a,x,b,y){"use strict";var X=Object.defineProperty,Z=Object.defineProperties;var R=Object.getOwnPropertyDescriptors;var O=Object.getOwnPropertySymbols;var ee=Object.prototype.hasOwnProperty,te=Object.prototype.propertyIsEnumerable;var V=(r,e,o)=>e in r?X(r,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):r[e]=o,C=(r,e)=>{for(var o in e||(e={}))ee.call(e,o)&&V(r,o,e[o]);if(O)for(var o of O(e))te.call(e,o)&&V(r,o,e[o]);return r},I=(r,e)=>Z(r,R(e));var g=(r,e,o)=>new Promise((A,v)=>{var a=y=>{try{b(o.next(y))}catch(m){v(m)}},x=y=>{try{b(o.throw(y))}catch(m){v(m)}},b=y=>y.done?A(y.value):Promise.resolve(y.value).then(a,x);b((o=o.apply(r,e)).next())});const m="multi-app",z="subAppsChange",f="subAppsChange",S=()=>{const{t}=b.useTranslation([m,"core"]);return{t}},s=t=>`{{t("${t}", { ns: ["${m}", "client"] })}}`,N=()=>{const t=x.useForm(),n=x.useField(),c=o.useActionContext(),p=o.useDataBlockRequest(),i=o.useDataBlockResource();return{onClick(){return g(this,null,function*(){try{yield t.submit(),n.data=n.data||{},n.data.loading=!0,yield i.create({values:t.values}),c.setVisible(!1),yield t.reset(),n.data.loading=!1,p.refresh()}catch(u){n.data&&(n.data.loading=!1)}})}}},q=t=>{const n=x.useField(),c=x.useForm(),p=o.useActionContext(),i=o.useDataBlockRequest(),d=o.useDataBlockResource(),u=o.useCollectionRecordData(),h=u==null?void 0:u.name;return{onClick(){return g(this,null,function*(){var k;yield c.submit(),n.data=n.data||{},n.data.loading=!0;try{const l=yield d.update({filterByTk:h,values:c.values});p.setVisible(!1),yield c.reset(),i.refresh(),t==null||t(h,(k=l==null?void 0:l.data)==null?void 0:k.data)}catch(l){console.error(l)}finally{n.data.loading=!1}})}}},E=()=>{const t=o.useDataBlockResource(),{t:n}=S();return{onClick(){return g(this,null,function*(){var i,d;const p=yield t.startAll();a.notification.info({key:f,message:e.jsxs("span",{children:[n("Processing..."),"    ",e.jsx(a.Spin,{indicator:e.jsx(A.LoadingOutlined,{style:{fontSize:24},spin:!0})})]}),duration:0}),((d=(i=p==null?void 0:p.data)==null?void 0:i.data)==null?void 0:d.all)===0&&a.notification.info({key:f,message:`${n("Start count")}: 0/0!`})})}}},$=()=>{const t=o.useDataBlockResource(),{t:n}=S();return{onClick(){return g(this,null,function*(){var i,d;const p=yield t.stopAll();if(((d=(i=p==null?void 0:p.data)==null?void 0:i.data)==null?void 0:d.all)===0){a.notification.info({key:f,message:`${n("Stop count")}: 0/0!`});return}a.notification.info({key:f,message:e.jsxs("span",{children:[n("Processing..."),"    ",e.jsx(a.Spin,{indicator:e.jsx(A.LoadingOutlined,{style:{fontSize:24},spin:!0})})]}),duration:0})})}}},_={name:"applications",filterTargetKey:"name",targetKey:"name",fields:[{type:"uid",name:"name",primaryKey:!0,prefix:"a",interface:"input",uiSchema:{type:"string",title:s("App ID"),required:!0,"x-component":"Input","x-validator":"uid"}},{type:"string",name:"displayName",interface:"input",uiSchema:{type:"string",title:s("App display name"),required:!0,"x-component":"Input"}},{type:"string",name:"pinned",interface:"checkbox",uiSchema:{type:"boolean","x-content":s("Pin to menu"),"x-component":"Checkbox"}},{type:"string",name:"status",interface:"radioGroup",defaultValue:"pending",uiSchema:{type:"string",title:s("App status"),enum:[{label:"Initializing",value:"initializing"},{label:"Initialized",value:"initialized"},{label:"Running",value:"running"},{label:"Commanding",value:"commanding"},{label:"Stopped",value:"stopped"},{label:"Error",value:"error"},{label:"Not found",value:"not_found"}],"x-component":"Radio.Group"}},{type:"string",name:"isTemplate",interface:"checkbox",uiSchema:{type:"boolean","x-content":s("Is template"),"x-component":"Checkbox"}}]},T={type:"void","x-component":"div",properties:{displayName:{"x-component":"CollectionField","x-decorator":"FormItem"},name:{"x-component":"CollectionField","x-decorator":"FormItem","x-disabled":"{{ !createOnly }}","x-hidden":"{{ !admin }}"},"options.autoStart":{title:s("Start mode"),"x-component":"Radio.Group","x-decorator":"FormItem",default:!1,enum:[{label:s("Start on first visit"),value:!1},{label:s("Start with main application"),value:!0}],"x-hidden":"{{ !admin }}"},cnamePrefix:{title:s("Custom domain prefix"),"x-component":"Input","x-decorator":"FormItem","x-component-props":{addonAfter:`.${window.location.hostname}`},"x-reactions":{dependencies:["cname"],fulfill:{state:{value:'{{($deps[0] && $deps[0].replace(new RegExp("\\."+window.location.hostname+"$"), "")) || ""}}'}}}},cname:{"x-hidden":!0,"x-component":"Input","x-decorator":"FormItem","x-read-pretty":!0,"x-reactions":{dependencies:["cnamePrefix"],fulfill:{state:{value:`{{$deps[0] ? $deps[0] + ".${window.location.hostname}" : null}}`}}}},tmpl:{title:s("Template"),"x-component":"RemoteSelect","x-component-props":{fieldNames:{label:"displayName",value:"name"},service:{resource:"applications",params:{filter:{$or:[{isTemplate:!0},{createdById:"{{ userId }}"}]}}}},"x-decorator":"FormItem","x-disabled":"{{ !createOnly }}"},"options.startEnvs":{type:"string",title:s("Start environment variables"),"x-component":"Input.TextArea","x-decorator":"FormItem","x-hidden":!0},pinned:{"x-component":"CollectionField","x-decorator":"FormItem","x-hidden":"{{ !admin }}"},isTemplate:{"x-component":"CollectionField","x-decorator":"FormItem","x-hidden":"{{ !admin }}"}}},D={properties:{view:{type:"void","x-component":"AppVisitor","x-component-props":{admin:"{{ admin }}"}},update:{type:"void",title:'{{t("Edit")}}',"x-component":"Action.Link",properties:{drawer:{type:"void","x-component":"Action.Drawer","x-decorator":"Form","x-decorator-props":{useValues:"{{ cm.useValuesFromRecord }}"},title:'{{t("Edit")}}',properties:{formSchema:T,footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-use-component-props":"useCancelActionProps"},submit:{title:'{{t("Submit")}}',"x-action":"submit","x-component":"Action","x-use-component-props":"useMultiAppUpdateAction","x-component-props":{type:"primary"}}}}}}}},delete:{type:"void",title:'{{ t("Delete") }}',"x-component":"Action.Link","x-hidden":"{{ !admin }}","x-use-component-props":"useDestroyActionProps","x-component-props":{confirm:{title:"{{t('Delete')}}",content:"{{t('Are you sure you want to delete it?')}}"}}}}},L={type:"void",properties:{provider:{type:"void","x-decorator":"TableBlockProvider","x-decorator-props":{collection:_,action:"list",params:{pageSize:50,sort:["-createdAt"],appends:[],filter:{createdById:"{{ admin ? undefined : userId }}"}},rowKey:"name"},properties:{actions:{type:"void","x-component":"ActionBar","x-component-props":{style:{marginBottom:16}},properties:{refresh:{type:"void",title:'{{ t("Refresh") }}',"x-component":"Action","x-use-component-props":"useRefreshActionProps","x-component-props":{icon:"ReloadOutlined"}},delete:{type:"void",title:'{{ t("Delete") }}',"x-action":"destroy","x-component":"Action","x-decorator":"ACLActionProvider","x-use-component-props":"useBulkDestroyActionProps","x-component-props":{icon:"DeleteOutlined",confirm:{title:"{{t('Delete')}}",content:"{{t('Are you sure you want to delete it?')}}"}},"x-hidden":"{{ !admin }}"},startAll:{type:"void",title:'{{ t("Start all") }}',"x-component":"Action","x-use-component-props":"useStartAllAction","x-component-props":{icon:"FastForwardOutlined",danger:!0,confirm:{title:s("Start all"),content:s("Starting all sub-applications may cause lag. The more applications you have, the longer the waiting time")}},"x-hidden":"{{ !admin }}"},stopAll:{type:"void",title:'{{ t("Stop all") }}',"x-component":"Action","x-use-component-props":"useStopAllAction","x-component-props":{icon:"StopOutlined",danger:!0,confirm:{title:s("Stop all"),content:s("All sub-applications have stopped serving, unless you restart them")}},"x-hidden":"{{ !admin }}"},create:{type:"void",title:'{{t("Add new")}}',"x-decorator":t=>v.createElement(o.SchemaComponentOptions,I(C({},t),{scope:{createOnly:!0}})),"x-component":"Action","x-component-props":{type:"primary",icon:"PlusOutlined"},properties:{drawer:{type:"void","x-component":"Action.Drawer","x-decorator":"Form","x-decorator-props":{useValues(t){const n=o.useActionContext();return o.useRequest(()=>Promise.resolve({data:{name:`a_${x.uid()}`}}),I(C({},t),{refreshDeps:[n.visible]}))}},title:'{{t("Add new")}}',properties:{formSchema:T,footer:{type:"void","x-component":"Action.Drawer.Footer",properties:{cancel:{title:'{{t("Cancel")}}',"x-component":"Action","x-use-component-props":"useCancelActionProps"},submit:{title:'{{ t("Submit") }}',"x-component":"Action","x-use-component-props":"useCreateDatabaseConnectionAction","x-component-props":{type:"primary"}}}}}}}}}},table:{type:"array","x-uid":"input","x-component":"TableV2","x-use-component-props":"useTableBlockProps","x-component-props":{rowKey:"name",rowSelection:{type:"checkbox"}},properties:{displayName:{type:"void","x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{displayName:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},name:{type:"void","x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{name:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},pinned:{type:"void",title:s("Pin to menu"),"x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{pinned:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},isTemplate:{type:"void",title:s("Is template"),"x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{isTemplate:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},status:{type:"void","x-decorator":"TableV2.Column.Decorator","x-component":"TableV2.Column",properties:{status:{type:"string","x-component":"CollectionField","x-read-pretty":!0}}},actions:{type:"void",title:'{{t("Actions")}}',"x-component":"TableV2.Column",properties:{actions:C({type:"void","x-component":"Space","x-component-props":{split:"|"}},D)}}}}}}}},K=()=>{const t=o.useCollectionRecordData(),n=o.useApp();return t.cname?`//${t.cname}`:n.getRouteUrl(`/apps/${t.name}/admin/`)},U=()=>{const{t}=S(),n=K(),c=o.useCollectionRecordData(),p=o.useAPIClient(),{data:i,mutate:d,refresh:u}=o.useDataBlockRequest(),h=v.useMemo(()=>p.resource("applications"),[p]),Q=()=>{h.start({filterByTk:c.name}).then(()=>{a.notification.info({key:f,message:e.jsxs("span",{children:[t("Processing..."),"    ",e.jsx(a.Spin,{indicator:e.jsx(A.LoadingOutlined,{style:{fontSize:24},spin:!0})})]}),duration:0})})},k=()=>{h.stop({filterByTk:c.name}).then(()=>{a.notification.info({key:f,message:e.jsxs("span",{children:[t("Processing..."),"    ",e.jsx(a.Spin,{indicator:e.jsx(A.LoadingOutlined,{style:{fontSize:24},spin:!0})})]}),duration:0})})};return o.useNoticeSub(z,l=>{const W=a.notification[l.level]||a.notification.info;if(l.message?W({key:f,message:l.message}):l.status!=="commanding"&&a.notification.destroy(f),!(i!=null&&i.data)||l.refresh){u();return}if(!l.app&&!l.status||!i.data.some(w=>w.name===l.app))return;const B=[...i.data];B.find(w=>w.name===l.app).status=l.status,d({data:B})}),e.jsxs(a.Space,{split:e.jsx(a.Divider,{type:"horizontal"}),children:[e.jsx("a",{href:n,target:"_blank",rel:"noreferrer",children:t("View",{ns:m})}),e.jsx("a",{onClick:()=>Q(),children:t("Start",{ns:m})}),e.jsx("a",{onClick:()=>k(),children:t("Stop",{ns:m})})]})},P=t=>{var i,d;const{admin:n=!0}=t,c=o.useCurrentUserContext(),p=(d=(i=c==null?void 0:c.data)==null?void 0:i.data)==null?void 0:d.id;return e.jsx(a.Card,{bordered:!1,children:e.jsx(o.SchemaComponent,{schema:L,scope:{admin:n,userId:p,useCreateDatabaseConnectionAction:N,useMultiAppUpdateAction:q,useStartAllAction:E,useStopAllAction:$},components:{AppVisitor:U}})})},F=()=>{const{insert:t}=o.useSchemaInitializer();S();const n=o.useSchemaInitializerItem();return e.jsx(o.SchemaInitializerItem,I(C({},n),{onClick:()=>{t({type:"void","x-decorator-props":{},"x-component":"CardItem","x-toolbar":"BlockSchemaToolbar","x-settings":"blockSettings:table",properties:{app:{type:"void","x-component":"AppManager","x-component-props":{admin:!1}}}})}}))},j=t=>{const n=o.useApp(),c=t.value&&e.jsx("a",{target:"_blank",href:n.getRouteUrl(`/apps/${t.value}/admin`),rel:"noreferrer",children:t.value});return e.jsxs("div",{style:t.style,children:[t.addonBefore,t.prefix,c,t.suffix,t.addonAfter]})},G=x.connect(a.Input,x.mapReadPretty(j)),Y=o.createStyles(({token:t})=>({button:{color:t.colorTextHeaderMenu+" !important"}})),H=()=>{const{styles:t}=Y(),{data:n,run:c}=o.useRequest({resource:"applications",action:"listPinned"},{manual:!0}),{t:p}=S(),i=o.useApp(),d=[...((n==null?void 0:n.data)||[]).map(u=>{let h=i.getRouteUrl(`/apps/${u.name}/admin/`);return u.cname&&(h=`//${u.cname}`),{key:u.name,label:e.jsx("a",{href:h,target:"_blank",rel:"noopener noreferrer",children:u.displayName||u.name})}}),{key:".manager",label:e.jsx(y.Link,{to:i.systemSettingsManager.getRoutePath("system-services."+m),children:p("Manage applications")})}];return e.jsx(a.Dropdown,{onOpenChange:u=>{c()},menu:{items:d},children:e.jsx(a.Button,{className:t.button,title:"Apps",icon:e.jsx(o.Icon,{type:"AppstoreOutlined"})})})},J=t=>e.jsx(o.PinnedPluginListProvider,{items:{am:{order:201,component:"MultiAppManager",pin:!0,snippet:"pm.*",belongTo:"pinnedmenu"}},children:e.jsx(o.SchemaComponentOptions,{components:{MultiAppManager:H,AppNameInput:G,MultiAppBlockInitializer:F},children:t.children})});class M extends o.Plugin{load(){return g(this,null,function*(){this.app.addComponents({AppManager:P}),this.app.use(J),this.app.systemSettingsManager.add(`system-services.${m}`,{title:s("Multi-app manager"),icon:"AppstoreOutlined",Component:P,aclSnippet:"pm.multi-app-manager.applications"}),this.app.schemaInitializerManager.get("page:addBlock").add("otherBlocks.multiApp",{name:"multiApp",title:s("Multi-app manager"),icon:e.jsx(A.AppstoreOutlined,{}),Component:F})})}}r.MultiAppManagerPlugin=M,r.default=M,r.formSchema=T,r.tableActionColumnSchema=D,Object.defineProperties(r,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
@@ -1 +1,3 @@
1
1
  export declare const NAMESPACE = "multi-app";
2
+ export declare const NOTIFY_STATUS_EVENT_KEY = "subAppsChange";
3
+ export declare const NOTIFICATION_CLIENT_KEY = "subAppsChange";
package/dist/constants.js CHANGED
@@ -17,11 +17,17 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
  var constants_exports = {};
19
19
  __export(constants_exports, {
20
- NAMESPACE: () => NAMESPACE
20
+ NAMESPACE: () => NAMESPACE,
21
+ NOTIFICATION_CLIENT_KEY: () => NOTIFICATION_CLIENT_KEY,
22
+ NOTIFY_STATUS_EVENT_KEY: () => NOTIFY_STATUS_EVENT_KEY
21
23
  });
22
24
  module.exports = __toCommonJS(constants_exports);
23
25
  const NAMESPACE = "multi-app";
26
+ const NOTIFY_STATUS_EVENT_KEY = "subAppsChange";
27
+ const NOTIFICATION_CLIENT_KEY = "subAppsChange";
24
28
  // Annotate the CommonJS export names for ESM import in node:
25
29
  0 && (module.exports = {
26
- NAMESPACE
30
+ NAMESPACE,
31
+ NOTIFICATION_CLIENT_KEY,
32
+ NOTIFY_STATUS_EVENT_KEY
27
33
  });
@@ -1,16 +1,16 @@
1
1
  module.exports = {
2
2
  "react": "18.3.1",
3
- "@tachybase/client": "0.23.35",
4
- "antd": "5.22.5",
5
- "@tachybase/schema": "0.23.35",
3
+ "@tachybase/client": "0.23.41",
6
4
  "@ant-design/icons": "5.5.2",
5
+ "antd": "5.22.5",
6
+ "@tachybase/schema": "0.23.41",
7
7
  "react-router-dom": "6.28.1",
8
8
  "react-i18next": "15.2.0",
9
- "@tachybase/server": "0.23.35",
10
- "@tachybase/database": "0.23.35",
9
+ "@tachybase/server": "0.23.41",
10
+ "@tachybase/database": "0.23.41",
11
11
  "lodash": "4.17.21",
12
12
  "mysql2": "3.11.5",
13
13
  "pg": "8.13.1",
14
- "@tachybase/actions": "0.23.35",
15
- "@tachybase/utils": "0.23.35"
14
+ "@tachybase/actions": "0.23.41",
15
+ "@tachybase/utils": "0.23.41"
16
16
  };
@@ -1,4 +1,5 @@
1
1
  {
2
+ "All sub-applications have stopped serving, unless you reopen them": "All sub-applications have stopped serving, unless you reopen them",
2
3
  "App ID": "App ID",
3
4
  "App display name": "App display name",
4
5
  "App status": "App status",
@@ -14,11 +15,16 @@
14
15
  "Refresh": "Refresh",
15
16
  "Standalone deployment": "Standalone deployment",
16
17
  "Start": "Start",
18
+ "Start all": "Start all",
19
+ "Start count": "Start count",
17
20
  "Start environment variables": "Start environment variables",
18
21
  "Start mode": "Start mode",
19
22
  "Start on first visit": "Start on first visit",
20
23
  "Start with main application": "Start with main application",
24
+ "Starting all sub-applications may cause lag. The more applications you have, the longer the waiting time": "All sub-applications have stopped serving, unless you reopen them",
21
25
  "Stop": "Stop",
26
+ "Stop all": "Stop all",
27
+ "Stop count": "Stop count",
22
28
  "Template": "Template",
23
29
  "Template is in use": "Template is in use",
24
30
  "Template not exists": "模板不存在",
@@ -1,5 +1,8 @@
1
1
  {
2
+ "All sub-applications have stopped serving, unless you restart them": "所有子应用停止服务,除非你重新打开",
2
3
  "App ID": "应用标识",
4
+ "App already started": "应用已启动",
5
+ "App already stopped": "应用已关闭",
3
6
  "App display name": "应用名称",
4
7
  "App status": "应用状态",
5
8
  "Applications": "应用",
@@ -14,11 +17,16 @@
14
17
  "Refresh": "刷新",
15
18
  "Standalone deployment": "独立部署",
16
19
  "Start": "启动",
20
+ "Start all": "启动所有",
21
+ "Start count": "启动数量",
17
22
  "Start environment variables": "启动环境变量",
18
23
  "Start mode": "启动方式",
19
24
  "Start on first visit": "首次访问时启动",
20
25
  "Start with main application": "随主应用一同启动",
26
+ "Starting all sub-applications may cause lag. The more applications you have, the longer the waiting time": "启动所有子应用,可能会造成卡顿,你的应用越多等待时间越长",
21
27
  "Stop": "停止",
28
+ "Stop all": "关闭所有",
29
+ "Stop count": "关闭数量",
22
30
  "Template": "模板",
23
31
  "Template is in use": "模板正在使用",
24
32
  "Template not exists": "模板不存在",
@@ -1 +1 @@
1
- {"name":"mariadb","version":"2.5.6","description":"fast mariadb/mysql connector.","main":"promise.js","types":"types/index.d.ts","directories":{"lib":"lib","test":"test"},"private":false,"scripts":{"test":"npm run test:types-prettier && npm run test:prettier && npm run test:types && npm run test:lint && npm run test:base","test:base":"mocha --no-parallel --timeout 5000 \"test/**/*.js\" ","test:lint":"eslint \"{lib,test}/**/*.js\" ","test:types":"eslint \"types/*.ts\" ","test:types-prettier":"prettier --write \"types/*.ts\"","test:prettier":"prettier --write \"{tools,lib,test,benchmarks}/**/*.js\"","coverage":"npm run coverage:test && npm run coverage:report","coverage:test":"nyc mocha --no-parallel --timeout 5000 \"test/**/*.js\"","coverage:report":"nyc report --reporter=text-lcov > coverage.lcov && codecov","benchmark":"node ./benchmarks/benchmarks.js","generate":"node ./tools/generate-mariadb.js"},"repository":{"type":"git","url":"git+https://github.com/mariadb-corporation/mariadb-connector-nodejs.git"},"keywords":["mariadb","mysql","client","driver","connector"],"files":["lib","types/index.d.ts","promise.js","callback.js"],"engines":{"node":">= 10.13"},"author":"Diego Dupin <diego.dupin@mariadb.com>","license":"LGPL-2.1-or-later","dependencies":{"@types/geojson":"^7946.0.8","@types/node":"^17.0.10","denque":"^2.0.1","iconv-lite":"^0.6.3","long":"^5.2.0","moment-timezone":"^0.5.34","please-upgrade-node":"^3.2.0"},"devDependencies":{"@typescript-eslint/eslint-plugin":"^5.10.0","@typescript-eslint/parser":"^5.10.0","benchmark":"^2.1.4","chai":"^4.3.4","codecov":"^3.8.2","chalk":"^4.1.2","dom-parser":"^0.1.6","error-stack-parser":"^2.0.6","eslint":"^8.7.0","eslint-config-prettier":"^8.3.0","eslint-plugin-markdown":"^2.2.1","eslint-plugin-prettier":"^4.0.0","mocha":"^9.2.0","mocha-lcov-reporter":"^1.3.0","nyc":"^15.1.0","prettier":"^2.5.1","typescript":"^4.5.5"},"bugs":{"url":"https://jira.mariadb.org/projects/CONJS/"},"homepage":"https://github.com/mariadb-corporation/mariadb-connector-nodejs#readme","_lastModified":"2025-01-16T06:23:27.348Z"}
1
+ {"name":"mariadb","version":"2.5.6","description":"fast mariadb/mysql connector.","main":"promise.js","types":"types/index.d.ts","directories":{"lib":"lib","test":"test"},"private":false,"scripts":{"test":"npm run test:types-prettier && npm run test:prettier && npm run test:types && npm run test:lint && npm run test:base","test:base":"mocha --no-parallel --timeout 5000 \"test/**/*.js\" ","test:lint":"eslint \"{lib,test}/**/*.js\" ","test:types":"eslint \"types/*.ts\" ","test:types-prettier":"prettier --write \"types/*.ts\"","test:prettier":"prettier --write \"{tools,lib,test,benchmarks}/**/*.js\"","coverage":"npm run coverage:test && npm run coverage:report","coverage:test":"nyc mocha --no-parallel --timeout 5000 \"test/**/*.js\"","coverage:report":"nyc report --reporter=text-lcov > coverage.lcov && codecov","benchmark":"node ./benchmarks/benchmarks.js","generate":"node ./tools/generate-mariadb.js"},"repository":{"type":"git","url":"git+https://github.com/mariadb-corporation/mariadb-connector-nodejs.git"},"keywords":["mariadb","mysql","client","driver","connector"],"files":["lib","types/index.d.ts","promise.js","callback.js"],"engines":{"node":">= 10.13"},"author":"Diego Dupin <diego.dupin@mariadb.com>","license":"LGPL-2.1-or-later","dependencies":{"@types/geojson":"^7946.0.8","@types/node":"^17.0.10","denque":"^2.0.1","iconv-lite":"^0.6.3","long":"^5.2.0","moment-timezone":"^0.5.34","please-upgrade-node":"^3.2.0"},"devDependencies":{"@typescript-eslint/eslint-plugin":"^5.10.0","@typescript-eslint/parser":"^5.10.0","benchmark":"^2.1.4","chai":"^4.3.4","codecov":"^3.8.2","chalk":"^4.1.2","dom-parser":"^0.1.6","error-stack-parser":"^2.0.6","eslint":"^8.7.0","eslint-config-prettier":"^8.3.0","eslint-plugin-markdown":"^2.2.1","eslint-plugin-prettier":"^4.0.0","mocha":"^9.2.0","mocha-lcov-reporter":"^1.3.0","nyc":"^15.1.0","prettier":"^2.5.1","typescript":"^4.5.5"},"bugs":{"url":"https://jira.mariadb.org/projects/CONJS/"},"homepage":"https://github.com/mariadb-corporation/mariadb-connector-nodejs#readme","_lastModified":"2025-02-08T06:52:19.282Z"}
@@ -3,3 +3,5 @@ export declare function start(ctx: Context, next: Next): Promise<void>;
3
3
  export declare function stop(ctx: Context, next: Next): Promise<void>;
4
4
  export declare function listPinned(ctx: Context, next: Next): Promise<void>;
5
5
  export declare function create(ctx: Context, next: Next): Promise<void>;
6
+ export declare function startAll(ctx: Context, next: Next): Promise<void>;
7
+ export declare function stopAll(ctx: Context, next: Next): Promise<void>;
@@ -20,7 +20,9 @@ __export(apps_exports, {
20
20
  create: () => create,
21
21
  listPinned: () => listPinned,
22
22
  start: () => start,
23
- stop: () => stop
23
+ startAll: () => startAll,
24
+ stop: () => stop,
25
+ stopAll: () => stopAll
24
26
  });
25
27
  module.exports = __toCommonJS(apps_exports);
26
28
  var import_server = require("@tachybase/server");
@@ -30,7 +32,7 @@ async function start(ctx, next) {
30
32
  const appSupervisor = import_server.AppSupervisor.getInstance();
31
33
  if (!appSupervisor.hasApp(targetAppId)) {
32
34
  appSupervisor.blockApps.delete(targetAppId);
33
- await import_server.AppSupervisor.getInstance().getApp(targetAppId);
35
+ import_server.AppSupervisor.getInstance().getApp(targetAppId);
34
36
  ctx.body = "ok";
35
37
  await next();
36
38
  } else {
@@ -42,7 +44,7 @@ async function stop(ctx, next) {
42
44
  const appSupervisor = import_server.AppSupervisor.getInstance();
43
45
  if (appSupervisor.hasApp(targetAppId)) {
44
46
  appSupervisor.blockApps.add(targetAppId);
45
- await appSupervisor.removeApp(targetAppId);
47
+ appSupervisor.removeApp(targetAppId);
46
48
  ctx.body = "ok";
47
49
  await next();
48
50
  } else {
@@ -93,25 +95,84 @@ async function create(ctx, next) {
93
95
  ctx.throw(400, ctx.t("Template is in use", { ns: import_constants.NAMESPACE }));
94
96
  }
95
97
  }
96
- await ctx.db.getRepository("applications").create({
98
+ const app = await ctx.db.getRepository("applications").create({
97
99
  values: {
98
100
  ...params.values,
99
101
  createdBy: ctx.state.currentUser.id,
100
102
  updatedBy: ctx.state.currentUser.id
101
103
  }
102
104
  });
103
- const app = await ctx.db.getRepository("applications").find({
104
- filter: {
105
- name: ctx.request.body.name
106
- }
107
- });
108
105
  ctx.body = app;
109
106
  await next();
110
107
  }
108
+ async function startAll(ctx, next) {
109
+ const db = ctx.db;
110
+ const appSupervisor = import_server.AppSupervisor.getInstance();
111
+ const existNames = await appSupervisor.getAppsNames();
112
+ const applications = await db.getRepository("applications").find({
113
+ fields: ["name", "options"],
114
+ filter: {
115
+ name: {
116
+ $notIn: existNames
117
+ }
118
+ },
119
+ raw: true
120
+ });
121
+ let count = 0;
122
+ const all = applications.length;
123
+ appSupervisor.blockApps.clear();
124
+ if (all) {
125
+ const messageTitle = ctx.t("Start count", { ns: import_constants.NAMESPACE });
126
+ Promise.allSettled(
127
+ applications.map(async (app) => {
128
+ return appSupervisor.bootStrapApp(app.name, app.options).then(() => {
129
+ count++;
130
+ });
131
+ })
132
+ ).finally(() => {
133
+ const message = `${messageTitle}: ${count}/${all}`;
134
+ ctx.app.noticeManager.notify(import_constants.NOTIFY_STATUS_EVENT_KEY, { level: "info", message });
135
+ });
136
+ }
137
+ ctx.body = {
138
+ all
139
+ };
140
+ }
141
+ async function stopAll(ctx, next) {
142
+ const appSupervisor = import_server.AppSupervisor.getInstance();
143
+ const subApps = await appSupervisor.getAppsNames();
144
+ const promises = [];
145
+ let count = 0;
146
+ let all = 0;
147
+ const messageTitle = ctx.t("Stop count", { ns: import_constants.NAMESPACE });
148
+ for (const name of subApps) {
149
+ if (name === "main") {
150
+ continue;
151
+ }
152
+ all++;
153
+ promises.push(
154
+ appSupervisor.removeApp(name).then(() => {
155
+ appSupervisor.blockApps.add(name);
156
+ count++;
157
+ })
158
+ );
159
+ }
160
+ if (all) {
161
+ Promise.allSettled(promises).finally(() => {
162
+ const message = `${messageTitle}: ${count}/${all}`;
163
+ ctx.app.noticeManager.notify(import_constants.NOTIFY_STATUS_EVENT_KEY, { level: "info", message });
164
+ });
165
+ }
166
+ ctx.body = {
167
+ all
168
+ };
169
+ }
111
170
  // Annotate the CommonJS export names for ESM import in node:
112
171
  0 && (module.exports = {
113
172
  create,
114
173
  listPinned,
115
174
  start,
116
- stop
175
+ startAll,
176
+ stop,
177
+ stopAll
117
178
  });
@@ -16,4 +16,9 @@ export declare class PluginMultiAppManager extends Plugin {
16
16
  setAppDbCreator(appDbCreator: AppDbCreator): void;
17
17
  beforeLoad(): void;
18
18
  load(): Promise<void>;
19
+ notifyStatusChange({ appName, status, options }: {
20
+ appName: any;
21
+ status: any;
22
+ options: any;
23
+ }): void;
19
24
  }
@@ -34,6 +34,7 @@ var import_path = __toESM(require("path"));
34
34
  var import_database = require("@tachybase/database");
35
35
  var import_server = require("@tachybase/server");
36
36
  var import_lodash = __toESM(require("lodash"));
37
+ var import_constants = require("../constants");
37
38
  var import_server2 = require("../server");
38
39
  var actions = __toESM(require("./actions/apps"));
39
40
  var import_app_lifecycle = require("./app-lifecycle");
@@ -198,11 +199,13 @@ class PluginMultiAppManager extends import_server.Plugin {
198
199
  if ((_a = options == null ? void 0 : options.context) == null ? void 0 : _a.waitSubAppInstall) {
199
200
  await startPromise;
200
201
  }
202
+ this.app.noticeManager.notify(import_constants.NOTIFY_STATUS_EVENT_KEY, { level: "info", refresh: true });
201
203
  }
202
204
  }
203
205
  );
204
206
  this.db.on("applications.afterDestroy", async (model) => {
205
207
  await import_server.AppSupervisor.getInstance().removeApp(model.get("name"));
208
+ this.app.noticeManager.notify(import_constants.NOTIFY_STATUS_EVENT_KEY, { level: "info", refresh: true });
206
209
  });
207
210
  const self = this;
208
211
  import_server.AppSupervisor.getInstance().setAppBootstrapper((0, import_app_lifecycle.LazyLoadApplication)(self));
@@ -211,6 +214,11 @@ class PluginMultiAppManager extends import_server.Plugin {
211
214
  this.app.on("afterUpgrade", async (app, options) => {
212
215
  await this.subAppUpgradeHandler(app);
213
216
  });
217
+ const notifyStatusChange = this.notifyStatusChange.bind(this);
218
+ this.app.on("beforeStop", async (app) => {
219
+ import_server.AppSupervisor.getInstance().off("appStatusChanged", notifyStatusChange);
220
+ });
221
+ import_server.AppSupervisor.getInstance().on("appStatusChanged", notifyStatusChange);
214
222
  this.app.acl.allow("applications", "listPinned", "loggedIn");
215
223
  this.app.acl.allow("applications", "list", "loggedIn");
216
224
  this.app.acl.registerSnippet({
@@ -239,6 +247,19 @@ class PluginMultiAppManager extends import_server.Plugin {
239
247
  this.app.resourcer.registerActionHandler(`applications:${key}`, action);
240
248
  }
241
249
  }
250
+ notifyStatusChange({ appName, status, options }) {
251
+ var _a;
252
+ if (appName === "main") {
253
+ return;
254
+ }
255
+ const level = ["error", "not_found"].includes(status) ? "error" : "info";
256
+ this.app.noticeManager.notify(import_constants.NOTIFY_STATUS_EVENT_KEY, {
257
+ app: appName,
258
+ status,
259
+ level,
260
+ message: (_a = options.error) == null ? void 0 : _a.message
261
+ });
262
+ }
242
263
  }
243
264
  // Annotate the CommonJS export names for ESM import in node:
244
265
  0 && (module.exports = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tachybase/module-multi-app",
3
3
  "displayName": "Multi-app manager",
4
- "version": "0.23.35",
4
+ "version": "0.23.41",
5
5
  "description": "Dynamically create multiple apps without separate deployments.",
6
6
  "keywords": [
7
7
  "System management"
@@ -19,15 +19,15 @@
19
19
  "react": "~18.3.1",
20
20
  "react-i18next": "^15.2.0",
21
21
  "react-router-dom": "6.28.1",
22
- "@tachybase/schema": "0.23.35"
22
+ "@tachybase/schema": "0.23.41"
23
23
  },
24
24
  "peerDependencies": {
25
- "@tachybase/actions": "0.23.35",
26
- "@tachybase/server": "0.23.35",
27
- "@tachybase/test": "0.23.35",
28
- "@tachybase/utils": "0.23.35",
29
- "@tachybase/client": "0.23.35",
30
- "@tachybase/database": "0.23.35"
25
+ "@tachybase/actions": "0.23.41",
26
+ "@tachybase/client": "0.23.41",
27
+ "@tachybase/server": "0.23.41",
28
+ "@tachybase/database": "0.23.41",
29
+ "@tachybase/test": "0.23.41",
30
+ "@tachybase/utils": "0.23.41"
31
31
  },
32
32
  "description.zh-CN": "无需单独部署即可动态创建多个应用。",
33
33
  "displayName.zh-CN": "多应用管理器",