1 parent
e37d583179
commit
5260c2828b
65 files changed
+8469
-380
No files matched your search
+68
-7
@@ -1,19 +1,71 @@
|
||||
// Visual data and binding editors. Only typed data is sent to the server; no user code is evaluated.
|
||||
function generationUi(){return {
|
||||
...generationMapUi(),
|
||||
transferMode:'export',transferText:'',transferExport:'',transferError:'',transferResult:null,transferLoading:false,transferSequence:0,transferBase:null,
|
||||
async openTransfer(){
|
||||
await this.run(async()=>{await this.saveSharedGeneration();this.transferSequence++;clearTimeout(this.transferTimer);this.transferBase={revision:this.workspace.revision,shared_revision:this.generationDraftVersion};this.transferMode='export';this.transferText='';this.transferExport='';this.transferError='';this.transferResult=null;this.modal='generation-transfer';await this.exportTransfer();});
|
||||
},
|
||||
async exportTransfer(){
|
||||
const workspace=this.workspace.id;this.transferLoading=true;this.transferError='';
|
||||
try{const result=await this.api(this.endpoint('/generation-export'),'POST',this.transferBase);if(this.modal==='generation-transfer' && this.workspace.id===workspace){this.transferExport=result.text;this.transferText=result.text;}}
|
||||
catch(e){if(this.modal==='generation-transfer')this.transferError=e.message;}
|
||||
finally{this.transferLoading=false;}
|
||||
},
|
||||
transferSwitch(mode){this.transferSequence++;clearTimeout(this.transferTimer);this.transferLoading=false;this.transferMode=mode;this.transferError='';if(mode==='import')this.transferChanged();},
|
||||
transferChanged(){this.transferSequence++;this.transferResult=null;this.transferError='';this.transferLoading=true;clearTimeout(this.transferTimer);this.transferTimer=setTimeout(()=>this.previewTransfer(),350);},
|
||||
async previewTransfer(){
|
||||
const seq=++this.transferSequence,text=this.transferText,workspace=this.workspace.id;
|
||||
if(this.modal!=='generation-transfer'||this.transferMode!=='import')return;
|
||||
try{const result=await this.api(this.endpoint('/generation-import-preview'),'POST',{...this.transferBase,text});if(seq===this.transferSequence&&this.modal==='generation-transfer'&&workspace===this.workspace.id)this.transferResult={...result,text};}
|
||||
catch(e){if(seq===this.transferSequence&&this.modal==='generation-transfer')this.transferError=e.message;}
|
||||
finally{if(seq===this.transferSequence)this.transferLoading=false;}
|
||||
},
|
||||
transferCanApply(){return this.transferMode==='import'&&!this.transferLoading&&!this.transferError&&this.transferResult?.text===this.transferText&&!this.transferResult?.preview.issues.length;},
|
||||
async applyTransfer(){
|
||||
if(!this.transferCanApply())return;
|
||||
await this.run(async()=>{const saved=await this.api(this.endpoint('/generation-import'),'POST',{...this.transferBase,text:this.transferText,review_id:this.transferResult.review_id});this.detail.generation_draft=saved;this.modal='';await this.loadWorkspace();this.loadGenerationDraft(true);},tr('transfer_applied'));
|
||||
},
|
||||
transferGuideSections(){return ['structure','variables','bindings','generators','schedules','escalations','routes','merge','example'].map(id=>({id,title:tr('transfer_guide_'+id+'_title'),body:tr('transfer_guide_'+id),code:id==='example'}));},
|
||||
transferGuideText(){return '# Meguri · meguri/v2\n\n'+this.transferGuideSections().map(s=>'## '+s.title+'\n\n'+(s.code?'```json\n'+s.body+'\n```':s.body)).join('\n\n');},
|
||||
async copyTransferGuide(){await this.run(()=>navigator.clipboard.writeText(this.transferGuideText()),tr('transfer_guide_copied'));},
|
||||
async copyTransfer(){await this.run(()=>navigator.clipboard.writeText(this.transferExport),tr('transfer_copied'));},
|
||||
downloadTransfer(){const url=URL.createObjectURL(new Blob([this.transferExport+'\n'],{type:'application/json'})),a=document.createElement('a');a.href=url;a.download='meguri-config.json';a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);},
|
||||
|
||||
generationSaveTask:null,generationSaveError:'',generationSavedKey:'',generationDraftVersion:0,generationSaving:false,
|
||||
generationDraft:null,generationWorkspace:'',generationResult:null,generationError:'',generationLoading:false,generationSequence:0,bindingEditor:null,bulkNode:null,bulkText:'',generationAll:false,dataAdvanced:false,dataExpanded:{},dataPersonTarget:null,dataPersonQuery:'',ruleAdvanced:false,rulePeopleTarget:null,rulePeopleQuery:'',generationIssuesOpen:false,editorScroll:0,editorOrigin:null,
|
||||
nodeKinds:['text','person','number','boolean','date','time','duration','list','dictionary'],
|
||||
newNode(kind='text',value=null,key=''){return {id:crypto.randomUUID(),kind,key,value:value??(kind==='boolean'?false:['number','duration'].includes(kind)?0:kind==='time'?'11:00':kind==='date'?this.today():''),entries:[]};},
|
||||
literal(value){return {kind:'literal',value,path:[],prefix:'',suffix:''};},
|
||||
generationContent(payload){return JSON.stringify({variables:payload?.variables||[],rules:payload?.rules||[],route_position:payload?.route_position||0});},
|
||||
generationDirty(){return !!this.generationDraft && this.generationContent(this.generationPayload())!==this.generationContent(this.doc?.generation);},
|
||||
generationUnsaved(){return !!this.generationDraft && this.generationContent(this.generationPayload())!==this.generationSavedKey;},
|
||||
publicationDirty(){return !!this.detail?.sync?.has_changes || this.generationDirty();},
|
||||
loadGenerationDraft(reset=false){
|
||||
if(!this.workspace)return;
|
||||
const clean=this.generationDraft && JSON.stringify(this.generationDraft.variables)===JSON.stringify(this.doc.generation.variables||[]) && JSON.stringify(this.generationDraft.rules)===JSON.stringify(this.doc.generation?.rules||[]) && this.generationDraft.route_position===(this.doc.generation?.route_position||0);
|
||||
if(reset || !this.generationDraft || this.generationWorkspace!==this.workspace.id || (clean && this.generationDraft.revision!==this.workspace.revision)){
|
||||
this.generationWorkspace=this.workspace.id;this.generationDraft={revision:this.workspace.revision,variables:copy(this.doc.generation.variables||[]),rules:copy(this.doc.generation?.rules||[]),route_position:this.doc.generation?.route_position||0};
|
||||
const shared=this.detail.generation_draft||{revision:0,payload:null};
|
||||
const localClean=!this.generationDraft || this.generationContent(this.generationPayload())===this.generationSavedKey;
|
||||
if(reset || !this.generationDraft || this.generationWorkspace!==this.workspace.id || (localClean && !this.modal && (this.generationDraftVersion!==shared.revision || this.generationDraft.revision!==this.workspace.revision))){
|
||||
const data=shared.payload || this.doc.generation;
|
||||
this.generationWorkspace=this.workspace.id;this.generationDraft={revision:this.workspace.revision,variables:copy(data.variables||[]),rules:copy(data.rules||[]),route_position:data.route_position||0};
|
||||
this.generationDraftVersion=shared.revision;this.generationSavedKey=this.generationContent(this.generationDraft);this.generationSaveError='';
|
||||
this.generationResult=null;this.generationAll=false;
|
||||
}
|
||||
if(this.can('edit_schedules'))this.generationChanged();
|
||||
},
|
||||
async reloadSharedGeneration(){await this.run(async()=>{await this.loadWorkspace();this.loadGenerationDraft(true);});},
|
||||
async saveSharedGeneration(){
|
||||
if(!this.can('edit_schedules') || !this.generationDraft)return;
|
||||
while(this.generationSaveTask)await this.generationSaveTask;
|
||||
if(this.generationSaveError)throw new Error(this.generationSaveError);
|
||||
const workspace=this.workspace.id,payload=this.generationPayload(),key=this.generationContent(payload);
|
||||
if(key===this.generationSavedKey)return;
|
||||
this.generationSaving=true;
|
||||
const task=this.api(this.endpoint('/generation-draft'),'PUT',{revision:this.generationDraftVersion,payload});
|
||||
this.generationSaveTask=task;
|
||||
try{const saved=await task;if(this.workspace?.id===workspace){this.generationDraftVersion=saved.revision;this.generationSavedKey=key;this.detail.generation_draft=saved;}}
|
||||
catch(e){if(this.workspace?.id===workspace)this.generationSaveError=e.message;throw e;}
|
||||
finally{if(this.generationSaveTask===task){this.generationSaveTask=null;this.generationSaving=false;}}
|
||||
},
|
||||
generationPayload(){
|
||||
if(!this.generationDraft)return null;
|
||||
const payload=copy(this.generationDraft);
|
||||
@@ -25,7 +77,7 @@ function generationUi(){return {
|
||||
async previewGeneration(){
|
||||
const sequence=++this.generationSequence,payload=this.generationPayload();
|
||||
if(!payload || !this.can('edit_schedules')){this.generationLoading=false;return;}
|
||||
try{const result=await this.api(this.endpoint('/generation-preview'),'POST',payload);if(sequence===this.generationSequence)this.generationResult={...result,key:JSON.stringify(payload)};}
|
||||
try{await this.saveSharedGeneration();if(sequence!==this.generationSequence)return;const result=await this.api(this.endpoint('/generation-preview'),'POST',payload);if(sequence===this.generationSequence)this.generationResult={...result,key:JSON.stringify(payload)};}
|
||||
catch(e){if(sequence===this.generationSequence)this.generationError=e.message;}
|
||||
finally{if(sequence===this.generationSequence)this.generationLoading=false;}
|
||||
},
|
||||
@@ -62,10 +114,19 @@ function generationUi(){return {
|
||||
requestAnimationFrame(()=>{const target=action.block?document.querySelector('[role="dialog"] [data-block-id="'+action.block+'"]'):null;if(target)target.scrollIntoView({block:'start'});});
|
||||
},
|
||||
generationCanApply(){return !this.generationLoading && this.generationResult && !this.generationResult.issues.length && this.generationResult.key===JSON.stringify(this.generationPayload());},
|
||||
generationChanges(){return this.generationResult?.changes||[];},
|
||||
generationChanges(){return this.modal?(this.generationResult?.changes||[]):(this.generationDirty()?(this.generationResult?.publication_changes||[]):(this.detail?.sync?.changes||[]));},
|
||||
generationVisibleChanges(){const changes=this.generationChanges();return this.generationAll?changes:changes.filter(c=>c.action!=='unchanged').slice(0,8);},
|
||||
generationCount(action){return this.generationChanges().filter(c=>c.action===action).length;},
|
||||
async applyGeneration(){if(!this.generationCanApply())return;await this.run(async()=>{await this.api(this.endpoint('/generation'),'POST',{...this.generationPayload(),review_id:this.generationResult.review_id});await this.loadWorkspaces();this.loadGenerationDraft(true);},tr('workspace_data_and_generated_schedules_saved_publica_e4ae3d'));},
|
||||
async stageGeneration(){
|
||||
await this.saveSharedGeneration();
|
||||
if(!this.generationDirty())return;
|
||||
const payload={...this.generationPayload(),shared_revision:this.generationDraftVersion};
|
||||
const review=await this.api(this.endpoint('/generation-preview'),'POST',payload);
|
||||
if(review.issues.length)throw new Error(review.issues.map(i=>i.message).join('; '));
|
||||
await this.api(this.endpoint('/generation'),'POST',{...payload,review_id:review.review_id});
|
||||
this.modal='';await this.loadWorkspace();this.loadGenerationDraft(true);
|
||||
},
|
||||
async applyGeneration(){await this.run(()=>this.stageGeneration(),tr('workspace_data_and_generated_schedules_saved_publica_e4ae3d'));},
|
||||
generated(id){return (this.doc?.generation?.managed||[]).some(m=>m.id===id);},
|
||||
moveGenerationRule(index,delta){const list=this.generationDraft.rules,to=index+delta;if(to<0||to>=list.length)return;[list[index],list[to]]=[list[to],list[index]];},
|
||||
sourceRuleName(id){const owner=this.doc?.generation?.managed?.find(m=>m.id===id);return this.doc?.generation?.rules?.find(r=>r.id===owner?.rule)?.name || this.generationDraft?.rules?.find(r=>r.id===owner?.rule)?.name || tr('generated_resource');},
|
||||
@@ -160,7 +221,7 @@ function generationUi(){return {
|
||||
const collection=this.modal==='variable'?'variables':'rules',list=this.generationDraft[collection],at=list.findIndex(v=>v.id===this.form.id);
|
||||
at<0?list.push(copy(this.form)):list.splice(at,1,copy(this.form));this.modal='';this.bindingEditor=null;this.generationChanged();
|
||||
},
|
||||
removeGenerationItem(collection,id){this.generationDraft[collection]=this.generationDraft[collection].filter(v=>v.id!==id);},
|
||||
removeGenerationItem(collection,id){const item=this.generationDraft[collection].find(v=>v.id===id);if(!item || !window.confirm(tr(collection==='variables'?'confirm_remove_variable':'confirm_remove_generation_rule',{name:item.name})))return;this.generationDraft[collection]=this.generationDraft[collection].filter(v=>v.id!==id);},
|
||||
nodeRows(root){const rows=[];const visit=(node,parent,depth,index)=>{rows.push({node,parent,depth,index});if(depth<9 && this.dataExpanded[node.id])node.entries.forEach((child,i)=>visit(child,node,depth+1,i));};visit(root,null,0,0);return rows;},
|
||||
setNodeKind(node,kind){const previous=node.kind;node.kind=kind;node.entries=[];if(['list','dictionary'].includes(kind))node.value=null;else if(kind==='boolean')node.value=false;else if(['number','duration'].includes(kind))node.value=0;else if(kind==='date')node.value=this.today();else if(kind==='time')node.value='11:00';else if(typeof node.value!=='string' || ['date','time'].includes(previous))node.value='';},
|
||||
toggleDataNode(node){this.dataExpanded[node.id]=!this.dataExpanded[node.id];},
|
||||
|
||||
Reference in new issue
Block a user