mirror of
https://github.com/documize/community.git
synced 2025-08-09 07:25:23 +02:00
new templates process
This commit is contained in:
parent
a815d27993
commit
01e5d59bad
10 changed files with 207 additions and 29 deletions
|
@ -22,6 +22,11 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
|||
description: ""
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
this.set('saveTemplate.name', this.get('document.name'));
|
||||
this.set('saveTemplate.description', this.get('document.excerpt'));
|
||||
},
|
||||
|
||||
didRender() {
|
||||
if (this.get('isEditor')) {
|
||||
this.addTooltip(document.getElementById("attachment-button"));
|
||||
|
@ -99,30 +104,21 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
|||
},
|
||||
|
||||
saveTemplate() {
|
||||
var templateName = this.get('saveTemplate.name');
|
||||
var templateDescription = this.get('saveTemplate.description');
|
||||
var name = this.get('saveTemplate.name');
|
||||
var excerpt = this.get('saveTemplate.description');
|
||||
|
||||
if (is.empty(templateName)) {
|
||||
if (is.empty(name)) {
|
||||
$("#new-template-name").addClass("error").focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is.empty(templateDescription)) {
|
||||
if (is.empty(excerpt)) {
|
||||
$("#new-template-desc").addClass("error").focus();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
let doc = this.get('document');
|
||||
doc.set('template', true);
|
||||
doc.set('name', templateName);
|
||||
doc.set('excerpt', templateDescription);
|
||||
|
||||
this.set('saveTemplate.name', "");
|
||||
this.set('saveTemplate.description', "");
|
||||
|
||||
this.showNotification('Templated');
|
||||
this.attrs.onSaveTemplate(doc);
|
||||
this.showNotification('Template saved');
|
||||
this.attrs.onSaveTemplate(name, excerpt);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
|
|
@ -3,6 +3,7 @@ import NotifierMixin from '../../../mixins/notifier';
|
|||
|
||||
export default Ember.Controller.extend(NotifierMixin, {
|
||||
documentService: Ember.inject.service('document'),
|
||||
templateService: Ember.inject.service('template'),
|
||||
|
||||
queryParams: ['page'],
|
||||
page: null,
|
||||
|
@ -170,6 +171,11 @@ export default Ember.Controller.extend(NotifierMixin, {
|
|||
}
|
||||
},
|
||||
|
||||
onSaveTemplate(name, desc) {
|
||||
this.get('templateService').saveAsTemplate(this.model.get('id'), name, desc).then(function() {
|
||||
});
|
||||
},
|
||||
|
||||
onDocumentChange(doc) {
|
||||
let self = this;
|
||||
this.get('documentService').save(doc).then(function() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{{header/message-box message=model.excerpt}}
|
||||
{{/header/page-navigation}}
|
||||
|
||||
{{document/document-toolbar document=model pages=pages meta=meta folder=folder isEditor=isEditor users=users owner=owner onSaveTemplate=(action 'onDocumentChange') onDocumentChange=(action 'onDocumentChange') onAttachmentUpload=(action
|
||||
{{document/document-toolbar document=model pages=pages meta=meta folder=folder isEditor=isEditor users=users owner=owner onSaveTemplate=(action 'onSaveTemplate') onDocumentChange=(action 'onDocumentChange') onAttachmentUpload=(action
|
||||
'onAttachmentUpload') onDocumentDelete=(action 'onDocumentDelete')}}
|
||||
|
||||
<div class="container-fluid background-color-white">
|
||||
|
|
|
@ -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(() => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -77,15 +77,15 @@
|
|||
<p>Are you sure you want to delete this document?</p>
|
||||
<p>There is no undo!</p>
|
||||
{{/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"}}
|
||||
<div>
|
||||
<div class="input-control">
|
||||
<label>Template Name</label>
|
||||
<div class="tip">Short title for this type of document</div>
|
||||
<label>Name</label>
|
||||
<div class="tip">Short name for this type of document</div>
|
||||
{{input type='text' id="new-template-name" value=saveTemplate.name}}
|
||||
</div>
|
||||
<div class="input-control">
|
||||
<label>Description</label>
|
||||
<label>Excerpt</label>
|
||||
<div class="tip">Explain use case for this template</div>
|
||||
{{textarea value=saveTemplate.description rows="3" id="new-template-desc"}}
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,14 @@
|
|||
<meta property="dbhash" content="{{.DBhash}}" />
|
||||
<meta name="author" content="Documize" />
|
||||
|
||||
<style>
|
||||
#ember-testing-container {
|
||||
/* Set position static to short-circuit Hubspot Tether's positioning */
|
||||
/* https://github.com/HubSpot/tether/pull/98/ */
|
||||
position: static !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
{{content-for "head"}}
|
||||
{{content-for "test-head"}}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue