diff --git a/app/app/services/template.js b/app/app/services/template.js
index 86b48c9e..ec99a59b 100644
--- a/app/app/services/template.js
+++ b/app/app/services/template.js
@@ -62,5 +62,20 @@ export default Ember.Service.extend({
return this.get('ajax').request(url, {
method: 'GET'
});
- }
+ },
+
+ saveAsTemplate(documentId, name, excerpt) {
+ let url = this.get('sessionService').appMeta.getUrl("templates");
+ let payload = {
+ DocumentID: documentId,
+ Name: name,
+ Excerpt: excerpt
+ };
+
+ return this.get('ajax').request(url, {
+ method: 'POST',
+ data: JSON.stringify(payload)
+ }).then(() => {
+ });
+ }
});
diff --git a/app/app/styles/view/document/content.scss b/app/app/styles/view/document/content.scss
index a66bf2dc..a24d3f31 100644
--- a/app/app/styles/view/document/content.scss
+++ b/app/app/styles/view/document/content.scss
@@ -69,10 +69,12 @@
}
.is-template {
- color: $color-green;
+ color: $color-gray;
font-weight: bold;
- font-size: 1.3em;
- margin-bottom: 20px;
+ font-size: 1.5em;
+ margin-bottom: 50px;
+ padding-bottom: 5px;
+ @include border-bottom(1px);
}
> .pages {
diff --git a/app/app/templates/components/document/document-toolbar.hbs b/app/app/templates/components/document/document-toolbar.hbs
index 26ae373f..fedacb44 100644
--- a/app/app/templates/components/document/document-toolbar.hbs
+++ b/app/app/templates/components/document/document-toolbar.hbs
@@ -77,15 +77,15 @@
{{/dropdown-dialog}}
- {{#dropdown-dialog target="save-template-button" position="bottom right" button="Save" color="flat-green" onAction=(action 'saveTemplate') focusOn="new-template-name"}}
+ {{#dropdown-dialog target="save-template-button" position="bottom right" button="Save as Template" color="flat-green" onAction=(action 'saveTemplate') focusOn="new-template-name"}}
diff --git a/app/tests/index.html b/app/tests/index.html
index 87c5d442..a955841e 100644
--- a/app/tests/index.html
+++ b/app/tests/index.html
@@ -11,6 +11,14 @@
+
+
{{content-for "head"}}
{{content-for "test-head"}}
diff --git a/documize/api/endpoint/router.go b/documize/api/endpoint/router.go
index 9bb4d255..f050cff2 100644
--- a/documize/api/endpoint/router.go
+++ b/documize/api/endpoint/router.go
@@ -145,8 +145,8 @@ func buildSecureRoutes() *mux.Router {
router.HandleFunc("/api/documents/{documentID}", GetDocument).Methods("GET", "OPTIONS")
router.HandleFunc("/api/documents/{documentID}", UpdateDocument).Methods("PUT", "OPTIONS")
router.HandleFunc("/api/documents/{documentID}", DeleteDocument).Methods("DELETE", "OPTIONS")
- // Document Meta
+ // Document Meta
router.HandleFunc("/api/documents/{documentID}/meta", GetDocumentMeta).Methods("GET", "OPTIONS")
// Document Page
@@ -198,6 +198,7 @@ func buildSecureRoutes() *mux.Router {
router.HandleFunc("/api/search", SearchDocuments).Methods("GET", "OPTIONS")
// Templates
+ router.HandleFunc("/api/templates", SaveAsTemplate).Methods("POST", "OPTIONS")
router.HandleFunc("/api/templates", GetSavedTemplates).Methods("GET", "OPTIONS")
router.HandleFunc("/api/templates/stock", GetStockTemplates).Methods("GET", "OPTIONS")
router.HandleFunc("/api/templates/{templateID}/folder/{folderID}", StartDocumentFromStockTemplate).Methods("POST", "OPTIONS").Queries("type", "stock")
diff --git a/documize/api/endpoint/templates_endpoint.go b/documize/api/endpoint/templates_endpoint.go
index 78c6b05b..4974b235 100644
--- a/documize/api/endpoint/templates_endpoint.go
+++ b/documize/api/endpoint/templates_endpoint.go
@@ -34,6 +34,156 @@ import (
uuid "github.com/nu7hatch/gouuid"
)
+// SaveAsTemplate saves existing document as a template.
+func SaveAsTemplate(w http.ResponseWriter, r *http.Request) {
+ method := "SaveAsTemplate"
+ p := request.GetPersister(r)
+
+ var model struct {
+ DocumentID string
+ Name string
+ Excerpt string
+ }
+
+ defer utility.Close(r.Body)
+ body, err := ioutil.ReadAll(r.Body)
+
+ if err != nil {
+ writeBadRequestError(w, method, "Bad payload")
+ return
+ }
+
+ err = json.Unmarshal(body, &model)
+
+ if err != nil {
+ writePayloadError(w, method, err)
+ return
+ }
+
+ if !p.CanChangeDocument(model.DocumentID) {
+ writeForbiddenError(w)
+ return
+ }
+
+ // DB transaction
+ tx, err := request.Db.Beginx()
+
+ if err != nil {
+ writeTransactionError(w, method, err)
+ return
+ }
+
+ p.Context.Transaction = tx
+
+ // Duplicate document
+ doc, err := p.GetDocument(model.DocumentID)
+
+ if err != nil {
+ writeServerError(w, method, err)
+ return
+ }
+
+ docID := util.UniqueID()
+ doc.Template = true
+ doc.Title = model.Name
+ doc.Excerpt = model.Excerpt
+ doc.RefID = docID
+ doc.ID = 0
+ doc.Template = true
+
+ // Duplicate pages and associated meta
+ pages, err := p.GetPages(model.DocumentID)
+ var pageModel []models.PageModel
+
+ if err != nil {
+ writeServerError(w, method, err)
+ return
+ }
+
+ for _, page := range pages {
+ page.DocumentID = docID
+ page.ID = 0
+
+ meta, err2 := p.GetPageMeta(page.RefID)
+
+ if err2 != nil {
+ writeServerError(w, method, err2)
+ return
+ }
+
+ pageID := util.UniqueID()
+ page.RefID = pageID
+
+ meta.PageID = pageID
+ meta.DocumentID = docID
+
+ m := models.PageModel{}
+
+ m.Page = page
+ m.Meta = meta
+
+ pageModel = append(pageModel, m)
+ }
+
+ // Duplicate attachments
+ attachments, err := p.GetAttachments(model.DocumentID)
+
+ for i, a := range attachments {
+ a.DocumentID = docID
+ a.RefID = util.UniqueID()
+ a.ID = 0
+ attachments[i] = a
+ }
+
+ // Now create the template: document, attachments, pages and their meta
+ err = p.AddDocument(doc)
+
+ if err != nil {
+ log.IfErr(tx.Rollback())
+ writeGeneralSQLError(w, method, err)
+ return
+ }
+
+ for _, a := range attachments {
+ err = p.AddAttachment(a)
+
+ if err != nil {
+ log.IfErr(tx.Rollback())
+ writeGeneralSQLError(w, method, err)
+ return
+ }
+ }
+
+ for _, m := range pageModel {
+ err = p.AddPage(m)
+
+ if err != nil {
+ log.IfErr(tx.Rollback())
+ writeGeneralSQLError(w, method, err)
+ return
+ }
+ }
+
+ // Commit and return new document template
+ log.IfErr(tx.Commit())
+
+ doc, err = p.GetDocument(docID)
+
+ if err != nil {
+ writeGeneralSQLError(w, method, err)
+ return
+ }
+
+ d, err := json.Marshal(doc)
+
+ if err != nil {
+ writeJSONMarshalError(w, method, "document", err)
+ return
+ }
+
+ writeSuccessBytes(w, d)
+}
+
// GetSavedTemplates returns all templates saved by the user
func GetSavedTemplates(w http.ResponseWriter, r *http.Request) {
method := "GetSavedTemplates"
diff --git a/documize/api/request/document.go b/documize/api/request/document.go
index 761da709..dc95a25e 100644
--- a/documize/api/request/document.go
+++ b/documize/api/request/document.go
@@ -1,11 +1,11 @@
// Copyright 2016 Documize Inc.
. All rights reserved.
//
-// This software (Documize Community Edition) is licensed under
+// This software (Documize Community Edition) is licensed under
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
//
// You can operate outside the AGPL restrictions by purchasing
// Documize Enterprise Edition and obtaining a commercial license
-// by contacting .
+// by contacting .
//
// https://documize.com
@@ -29,7 +29,7 @@ func (p *Persister) AddDocument(document entity.Document) (err error) {
document.Created = time.Now().UTC()
document.Revised = document.Created // put same time in both fields
- stmt, err := p.Context.Transaction.Preparex("INSERT INTO document (refId, orgid, labelid, userid, job, location, title, excerpt, slug, tags, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+ stmt, err := p.Context.Transaction.Preparex("INSERT INTO document (refId, orgid, labelid, userid, job, location, title, excerpt, slug, tags, template, created, revised) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
defer utility.Close(stmt)
if err != nil {
@@ -37,7 +37,7 @@ func (p *Persister) AddDocument(document entity.Document) (err error) {
return
}
- _, err = stmt.Exec(document.RefID, document.OrgID, document.LabelID, document.UserID, document.Job, document.Location, document.Title, document.Excerpt, document.Slug, document.Tags, document.Created, document.Revised)
+ _, err = stmt.Exec(document.RefID, document.OrgID, document.LabelID, document.UserID, document.Job, document.Location, document.Title, document.Excerpt, document.Slug, document.Tags, document.Template, document.Created, document.Revised)
if err != nil {
log.Error("Unable to execute insert for document", err)