diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-page.js.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-page.js.template index cca3a69534c..ddd1462e940 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-page.js.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-page.js.template @@ -20,6 +20,10 @@ document.addEventListener('alpine:init', () => { ...basePage(), state: 'loading', mode: 'create', + // True when this session began as a NEW document (create route); stays true after the header is + // saved and `mode` flips to 'edit', so the create flow shows Finish and an existing document opened + // for editing shows Save (issue #7403). + createFlow: false, id: null, error: null, // The single header property a rejected save NAMED ("The 'Name' property is required"), else @@ -114,6 +118,7 @@ document.addEventListener('alpine:init', () => { const params = (window.PineconeRouter.context && window.PineconeRouter.context.params) || {}; this.id = params.id || null; this.mode = this.id ? 'edit' : 'create'; + this.createFlow = this.mode === 'create'; if (this.id) { try { const record = await App.services.api.get(this.apiPath + '/' + this.id); @@ -638,6 +643,17 @@ document.addEventListener('alpine:init', () => { // A document with unsaved header edits asks before it is abandoned (issue #7359); a clean one // leaves silently, as before. goBack() { this.guardExit(() => this.navigate('/my/${name}')); }, + + // "Finish" on a saved document (issue #7403). Line items persist as they are added, so the only + // thing still unsaved is a header edit: save it, and only leave if the save succeeded (a failure + // sets this.error and keeps the user on the page). A clean header just returns to the list. + async finish() { + if (this.isDirty()) { + await this.save(); + if (this.error) return; + } + this.goBack(); + }, #set($docChildren = []) #if($myChildren) #foreach($child in $myChildren) diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-view.html.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-view.html.template index faddadd42b0..70f615aa26c 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-view.html.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/my/my-document-view.html.template @@ -366,12 +366,28 @@
- + - + + + + #end diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-page.js.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-page.js.template index cb80256292d..454a085d79c 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-page.js.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-page.js.template @@ -20,6 +20,10 @@ document.addEventListener('alpine:init', () => { ...basePage(), state: 'loading', mode: 'create', + // True when this session began as a NEW document (create route); stays true after the header is + // saved and `mode` flips to 'edit', so the create flow shows Finish and an existing document opened + // for editing shows Save (issue #7403). + createFlow: false, id: null, error: null, // The single header property a rejected save NAMED ("The 'Name' property is required"), else @@ -105,6 +109,7 @@ document.addEventListener('alpine:init', () => { const params = (window.PineconeRouter.context && window.PineconeRouter.context.params) || {}; this.id = params.id || null; this.mode = this.id ? 'edit' : 'create'; + this.createFlow = this.mode === 'create'; if (this.id) { try { const record = await App.services.api.get(this.apiPath + '/' + this.id); @@ -524,5 +529,16 @@ document.addEventListener('alpine:init', () => { // A document with unsaved header edits asks before it is abandoned (issue #7359); a clean one // leaves silently, as before. goBack() { this.guardExit(() => this.navigate('/partner/${name}')); }, + + // "Finish" on a saved document (issue #7403). Line items persist as they are added, so the only + // thing still unsaved is a header edit: save it, and only leave if the save succeeded (a failure + // sets this.error and keeps the user on the page). A clean header just returns to the list. + async finish() { + if (this.isDirty()) { + await this.save(); + if (this.error) return; + } + this.goBack(); + }, })); }); diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-view.html.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-view.html.template index 09918455284..12a9779a6c1 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-view.html.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/partner/partner-document-view.html.template @@ -220,12 +220,28 @@
- + - + + + + diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template index c9cc9395c6d..bfd906cb0d5 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-page.js.template @@ -138,6 +138,10 @@ document.addEventListener('alpine:init', () => { state: 'ready', // empty-form | loading | ready | saving | validation-error | save-failure | load-failure mode: 'create', + // True when this session began as a NEW document (create route). Stays true after the header is + // saved and `mode` flips to 'edit' for adding line items, so the create flow shows Finish while an + // existing document opened for editing shows Save (issue #7403). + createFlow: false, id: null, record: {}, // the loaded master (drives the read-only totals footer + calculated header fields) @@ -337,6 +341,9 @@ document.addEventListener('alpine:init', () => { // Read the live hash to tell /preview from /edit (Pinecone's context can lag the hash). const routePath = (window.location.hash || '').split('?')[0]; this.mode = this.id == null ? 'create' : (routePath.endsWith('/preview') ? 'preview' : 'edit'); + // The create flow: either the /create route, or the /edit page the Create button just navigated to + // carrying ?created=1 (the header is saved, its line items are being added). Both show Finish. + this.createFlow = this.mode === 'create' || this.queryParam('created') === '1'; // The line-items child registered itself as a detail of this master; pick it by name. this.itemsDef = App.detailsFor('${name}').find(d => d.entity === '${documentItemsEntity}') || null; @@ -627,7 +634,9 @@ document.addEventListener('alpine:init', () => { // The write landed, so there is nothing left to protect: clear the guard before the page // navigates itself, or it would veto its own route change. this.clearPristine(); - window.PineconeRouter.navigate('/${name}/' + encodeURIComponent(newId) + '/edit'); + // ?created=1 marks this as the create flow across the route change, so the re-mounted page + // (now at /edit) still shows Finish while its line items are added, not Save (issue #7403). + window.PineconeRouter.navigate('/${name}/' + encodeURIComponent(newId) + '/edit?created=1'); await this.loadHeader(); await this.loadItems(); } @@ -1406,6 +1415,20 @@ document.addEventListener('alpine:init', () => { // being asked about (issue #7359). A clean one leaves silently, as before. backToList() { this.guardExit(() => window.PineconeRouter.navigate('/${name}')); }, + // "Finish" on a saved document (issue #7403). Line items persist as they are added, so the only + // thing that can still be unsaved is a header edit: save it first, and only leave if the save + // succeeded - a failed validation keeps the user on the page with the error, never navigating on + // failure. A clean header just returns to the list. Not offered on create (that is the Create + // button, which stays on the document so line items can be added). + async finish() { + if (this.isPreview) return; + if (this.isDirty()) { + await this.save(); + if (this.state !== 'ready') return; + } + window.PineconeRouter.navigate('/${name}'); + }, + // Preview -> the editable document for the same record. goEdit() { window.PineconeRouter.navigate('/${name}/' + encodeURIComponent(this.id) + '/edit'); }, })); diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template index ce1123dd0fc..8752d727437 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/document/document-view.html.template @@ -529,16 +529,13 @@ - +
-#if($hasProcess) - - -#end +
+ - - + + + +
diff --git a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/manage/form-view.html.template b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/manage/form-view.html.template index a0d607447ee..dcfb558bb39 100644 --- a/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/manage/form-view.html.template +++ b/components/template/template-application-ui-harmonia-java/src/main/resources/META-INF/dirigible/template-application-ui-harmonia-java/ui/perspective/manage/form-view.html.template @@ -457,17 +457,12 @@ + document view. Cancel + Save/Create on the RIGHT; workflow user-tasks live in the Process + Inbox, not here (issue #7403). Save is type=button @click=save() because it lives outside the + header
. -->
-#if($hasProcess) - - -#end +
#if($hasPrint == "true")