1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-08-09 15:35:27 +02:00

Merge pull request #12 from documize/customer-improvements

Customer improvements
This commit is contained in:
Harvey Kandola 2016-06-22 10:51:06 -07:00 committed by GitHub
commit 6dbf074a50
19 changed files with 204 additions and 99 deletions

View file

@ -27,8 +27,11 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
this.addTooltip(document.getElementById("attachment-button")); this.addTooltip(document.getElementById("attachment-button"));
this.addTooltip(document.getElementById("save-template-button")); this.addTooltip(document.getElementById("save-template-button"));
this.addTooltip(document.getElementById("set-meta-button")); this.addTooltip(document.getElementById("set-meta-button"));
this.addTooltip(document.getElementById("delete-document-button"));
} }
this.addTooltip(document.getElementById("print-document-button"));
if (this.session.authenticated) { if (this.session.authenticated) {
this.addTooltip(document.getElementById("owner-avatar")); this.addTooltip(document.getElementById("owner-avatar"));
} }
@ -87,6 +90,14 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
}, },
actions: { actions: {
deleteDocument() {
this.attrs.onDocumentDelete();
},
printDocument() {
window.print();
},
saveTemplate() { saveTemplate() {
var templateName = this.get('saveTemplate.name'); var templateName = this.get('saveTemplate.name');
var templateDescription = this.get('saveTemplate.description'); var templateDescription = this.get('saveTemplate.description');

View file

@ -36,7 +36,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
}, },
noSections: Ember.computed('pages', function() { noSections: Ember.computed('pages', function() {
return this.get('pages.length') === 1; return this.get('pages.length') === 0;
}), }),
didInsertElement() { didInsertElement() {

View file

@ -188,6 +188,17 @@ export default Ember.Controller.extend(NotifierMixin, {
self.get('model.slug'), self.get('model.slug'),
newPage.id); newPage.id);
}); });
} },
onDocumentDelete() {
console.log("deleting " + this.get('model.id'));
let self = this;
this.get('documentService').deleteDocument(this.get('model.id')).then(function() {
self.audit.record("deleted-page");
self.send("showNotification", "Deleted");
self.transitionToRoute('folders.folder', self.get('folder.id'), self.get('folder.slug'));
});
}
} }
}); });

View file

@ -3,7 +3,7 @@
{{/header/page-navigation}} {{/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 'onDocumentChange') onDocumentChange=(action 'onDocumentChange') onAttachmentUpload=(action
'onAttachmentUpload')}} 'onAttachmentUpload') onDocumentDelete=(action 'onDocumentDelete')}}
<div class="container-fluid background-color-white"> <div class="container-fluid background-color-white">
<div class="row"> <div class="row">

View file

@ -29,6 +29,7 @@
@import "view/document/wizard.scss"; @import "view/document/wizard.scss";
@import "vendor.scss"; @import "vendor.scss";
@import "responsive.scss"; @import "responsive.scss";
@import "print.scss";
@import "section/trello.scss"; @import "section/trello.scss";
@import "section/gemini.scss"; @import "section/gemini.scss";

View file

@ -113,9 +113,9 @@ ul {
.clearfix:before, .clearfix:before,
.clearfix:after { .clearfix:after {
content: " "; content: " ";
display: table; display: table;
} }
.clearfix:after { .clearfix:after {
clear: both; clear: both;
} }

30
app/app/styles/print.scss Normal file
View file

@ -0,0 +1,30 @@
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
//
// 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 <sales@documize.com>.
//
// https://documize.com
@media print {
.header, .sidebar, .non-printable {
display: none !important;
}
.document-container {
> .content {
padding: 20px 0 !important;
.page-toolbar {
display: none !important;
}
.print-title, .non-printable-message, .document-summary, .attachment-zone {
display: block !important;
}
}
}
}

View file

@ -2,6 +2,22 @@
> .content { > .content {
padding: 40px 40px 40px 20px; padding: 40px 40px 40px 20px;
.print-title {
display: none;
font-size: 2.3em;
font-weight: bold;
color:$color-off-black;
margin-bottom: 20px;
margin-top: 0;
}
.non-printable-message {
display: none;
font-size: 1em;
font-style: italic;
color: $color-gray;
}
.attachment-zone { .attachment-zone {
margin: 20px 0 30px 0; margin: 20px 0 30px 0;
@ -15,7 +31,7 @@
padding: 0; padding: 0;
list-style-type: none; list-style-type: none;
border-bottom: 1px solid $color-gray2; border-bottom: 1px solid $color-gray2;
padding-bottom: 10px; padding-bottom: 10px;
> .icon { > .icon {
vertical-align: text-top; vertical-align: text-top;
@ -34,7 +50,6 @@
color: $color-stroke; color: $color-stroke;
} }
&:hover { &:hover {
.file { .file {
text-decoration: underline; text-decoration: underline;
@ -53,20 +68,17 @@
display: none; display: none;
} }
.document-tags {
margin: 10px 0;
}
.is-template { .is-template {
color: $color-green; color: $color-green;
font-weight: bold; font-weight: bold;
} }
> .pages { > .pages {
margin: 20px 0 50px 0;
> .wysiwyg { > .wysiwyg {
> .is-a-page { > .is-a-page {
.page-title { .page-title {
> .page-toolbar { > .page-toolbar {
opacity: 0.3; opacity: 0.3;
@extend .transition-all; @extend .transition-all;

View file

@ -27,7 +27,7 @@
color: $color-white; color: $color-white;
padding: 0.5em; padding: 0.5em;
font-size: 0.8em; font-size: 0.8em;
line-height: 1.0em; line-height: 1.1em;
&:before { &:before {
content: ""; content: "";
display: block; display: block;

View file

@ -38,7 +38,19 @@
{{/if}} {{/if}}
<div class="actions pull-right hidden-xs hidden-sm"> <div class="actions pull-right hidden-xs hidden-sm">
{{#link-to 'folders.folder' folder.id folder.slug}}
<div class="regular-button button-blue" id="add-section-button">
<i class="material-icons">arrow_back</i>
<div class="name">space</div>
</div>
{{/link-to}}
{{#if isEditor}} {{#if isEditor}}
<div class="button-gap"></div>
<div class="square-button button-gray" id="set-meta-button" data-tooltip="Set meta" data-tooltip-position="top center">
<i class="material-icons">settings</i>
</div>
<div class="button-gap"></div> <div class="button-gap"></div>
<div class="square-button button-gray" id="attachment-button" data-tooltip="Attach file" data-tooltip-position="top center"> <div class="square-button button-gray" id="attachment-button" data-tooltip="Attach file" data-tooltip-position="top center">
<i class="material-icons">attach_file</i> <i class="material-icons">attach_file</i>
@ -47,14 +59,25 @@
<div class="square-button button-gray" id="save-template-button" data-tooltip="Save as template" data-tooltip-position="top center"> <div class="square-button button-gray" id="save-template-button" data-tooltip="Save as template" data-tooltip-position="top center">
<i class="material-icons">content_copy</i> <i class="material-icons">content_copy</i>
</div> </div>
<div class="button-gap"></div>
<div class="square-button button-gray" id="set-meta-button" data-tooltip="Set owner & excerpt" data-tooltip-position="top center">
<i class="material-icons">person</i>
</div>
<div class="button-gap"></div>
{{/if}} {{/if}}
<div class="button-gap"></div>
<div class="square-button button-gray" id="print-document-button" data-tooltip="Print document" data-tooltip-position="top center" {{action 'printDocument'}}>
<i class="material-icons">print</i>
</div>
{{#if isEditor}} {{#if isEditor}}
<div class="button-gap"></div>
<div class="square-button button-red" id="delete-document-button" data-tooltip="Delete document" data-tooltip-position="top center">
<i class="material-icons">delete</i>
</div>
{{/if}}
{{#if isEditor}}
{{#dropdown-dialog target="delete-document-button" position="bottom right" button="Delete" color="flat-red" onAction=(action 'deleteDocument')}}
<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" color="flat-green" onAction=(action 'saveTemplate') focusOn="new-template-name"}}
<div> <div>
<div class="input-control"> <div class="input-control">
@ -69,7 +92,7 @@
</div> </div>
</div> </div>
{{/dropdown-dialog}} {{/dropdown-dialog}}
{{#dropdown-dialog target="set-meta-button" position="bottom right" button="Save" color="flat-blue" onAction=(action 'saveMeta') selectOn="meta-excerpt"}} {{#dropdown-dialog target="set-meta-button" position="bottom right" button="Save" color="flat-blue" onAction=(action 'saveMeta') selectOn="document-name"}}
<div> <div>
<div class="input-control"> <div class="input-control">
<label>Owner</label> <label>Owner</label>
@ -81,6 +104,11 @@
optionLabelPath="fullname" optionLabelPath="fullname"
selection=owner}} selection=owner}}
</div> </div>
<div class="input-control">
<label>Name</label>
<div class="tip">Short title for this document</div>
{{input type='text' id="document-name" value=document.name}}
</div>
<div class="input-control"> <div class="input-control">
<label>Excerpt</label> <label>Excerpt</label>
<div class="tip">Provide short summary of the document (max. 250)</div> <div class="tip">Provide short summary of the document (max. 250)</div>

View file

@ -1,42 +1,42 @@
<div class="document-container"> <div class="document-container">
<div class="content"> <div class="content">
<div class="document-summary">
{{document/tag-editor documentTags=document.tags isEditor=isEditor onChange=(action 'onTagChange')}}
</div>
<div class="print-title">
{{document.name}}
</div>
{{#if attachments}}
<div class="attachment-zone">
<ul class="list">
{{#each attachments key="id" as |a index|}}
<li class="item">
<img class="icon" src="assets/img/attachments/{{ document/file-icon a.extension }}" />
<a href="{{ session.appMeta.apiUrl }}api/public/attachments/{{ session.appMeta.orgId }}/{{ a.job }}/{{ a.fileId }}">
<span class="file">{{ a.filename }}</span>
</a>
{{#if isEditor}}
<div class="action round-button-mono">
<i class="material-icons delete-attachment-{{a.id}}" title="Delete" {{action 'confirmDeleteAttachment' a.id a.filename}}>delete</i>
</div>
{{/if}}
</li>
{{/each}}
</ul>
</div>
{{/if}}
<div class="pages"> <div class="pages">
{{#each pages key="id" as |page index|}} {{#each pages key="id" as |page index|}}
<div class="wysiwyg"> <div class="wysiwyg">
<div id="page-{{ page.id }}" class="is-a-page" data-id="{{ page.id }}" data-type="{{ page.contentType }}"> <div id="page-{{ page.id }}" class="is-a-page" data-id="{{ page.id }}" data-type="{{ page.contentType }}">
{{document/page-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor onDeletePage=(action 'onDeletePage') }} {{document/page-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor onDeletePage=(action 'onDeletePage') }}
{{#if page.firstPage }} {{#if page.firstPage }}
{{#if document.template}} {{#if document.template}}
<div class="is-template">TEMPLATE</div> <div class="is-template">TEMPLATE</div>
{{/if}} {{/if}}
<div class="document-summary">
{{document/tag-editor documentTags=document.tags isEditor=isEditor onChange=(action 'onTagChange')}}
{{#if attachments}}
<div class="attachment-zone">
<ul class="list">
{{#each attachments key="id" as |a index|}}
<li class="item">
<img class="icon" src="assets/img/attachments/{{ document/file-icon a.extension }}" />
<a href="{{ session.appMeta.apiUrl }}api/public/attachments/{{ session.appMeta.orgId }}/{{ a.job }}/{{ a.fileId }}">
<span class="file">{{ a.filename }}</span>
</a>
{{#if isEditor}}
<div class="action round-button-mono">
<i class="material-icons delete-attachment-{{a.id}}" title="Delete" {{action 'confirmDeleteAttachment' a.id a.filename}}>delete</i>
</div>
{{/if}}
</li>
{{/each}}
</ul>
</div>
{{/if}}
</div>
{{/if}} {{/if}}
{{section/base-renderer page=page}} {{section/base-renderer page=page}}
</div> </div>

View file

@ -708,7 +708,7 @@ func InviteToFolder(w http.ResponseWriter, r *http.Request) {
a.UserID = user.RefID a.UserID = user.RefID
a.OrgID = p.Context.OrgID a.OrgID = p.Context.OrgID
a.Admin = false a.Admin = false
a.Editor = true a.Editor = false
accountID := util.UniqueID() accountID := util.UniqueID()
a.RefID = accountID a.RefID = accountID
@ -808,7 +808,7 @@ func inviteNewUserToSharedFolder(p request.Persister, email string, invitedBy en
a.UserID = userID a.UserID = userID
a.OrgID = p.Context.OrgID a.OrgID = p.Context.OrgID
a.Admin = false a.Admin = false
a.Editor = true a.Editor = false
accountID := util.UniqueID() accountID := util.UniqueID()
a.RefID = accountID a.RefID = accountID

View file

@ -200,9 +200,8 @@ func GetDocumentPages(w http.ResponseWriter, r *http.Request) {
pages, err = p.GetPages(documentID) pages, err = p.GetPages(documentID)
} }
if err == sql.ErrNoRows { if len(pages) == 0 {
writeNotFoundError(w, method, documentID) pages = []entity.Page{}
return
} }
if err != nil { if err != nil {

View file

@ -30,7 +30,7 @@ const (
// AppVersion does what it says // AppVersion does what it says
// Versioning scheme major.minor where "minor" is optional // Versioning scheme major.minor where "minor" is optional
// e.g. 1, 2, 3, 4.1, 4.2, 5, 6, 7, 7.1, 8, 9, 10, ..... 127, 127.1, 128 // e.g. 1, 2, 3, 4.1, 4.2, 5, 6, 7, 7.1, 8, 9, 10, ..... 127, 127.1, 128
AppVersion = "12.6" AppVersion = "12.7"
) )
var port, certFile, keyFile, forcePort2SSL string var port, certFile, keyFile, forcePort2SSL string

View file

@ -181,21 +181,22 @@ func StartDocumentFromSavedTemplate(w http.ResponseWriter, r *http.Request) {
// Define an empty document just in case user wanted one. // Define an empty document just in case user wanted one.
var err error var err error
var d = entity.Document{} var d = entity.Document{}
d.Title = "Empty Document" d.Title = "New Document"
d.Location = fmt.Sprintf("template-%s", templateID) d.Location = fmt.Sprintf("template-%s", templateID)
d.Excerpt = "Created from template" d.Excerpt = "A new document"
d.Slug = utility.MakeSlug(d.Title) d.Slug = utility.MakeSlug(d.Title)
d.Tags = "" d.Tags = ""
d.LabelID = folderID d.LabelID = folderID
documentID := util.UniqueID() documentID := util.UniqueID()
d.RefID = documentID d.RefID = documentID
var pages = make([]entity.Page, 1, 1) var pages = []entity.Page{}
pages[0] = entity.Page{} //var pages = make([]entity.Page, 1, 1)
pages[0].Title = "Heading" //pages[0] = entity.Page{}
pages[0].Body = "<p>Some content here.</p>" //pages[0].Title = "Heading"
pages[0].Level = 1 //pages[0].Body = "<p>Some content here.</p>"
pages[0].Sequence = 1 //pages[0].Level = 1
//pages[0].Sequence = 1
var attachments = []entity.Attachment{} var attachments = []entity.Attachment{}

View file

@ -14,6 +14,7 @@ package entity
import ( import (
"fmt" "fmt"
"strings"
"time" "time"
) )
@ -152,6 +153,15 @@ type Document struct {
Template bool `json:"template"` Template bool `json:"template"`
} }
// SetDefaults ensures on blanks and cleans.
func (d *Document) SetDefaults() {
d.Title = strings.TrimSpace(d.Title)
if len(d.Title) == 0 {
d.Title = "Document"
}
}
// Attachment represents an attachment to a document. // Attachment represents an attachment to a document.
type Attachment struct { type Attachment struct {
BaseEntity BaseEntity
@ -183,6 +193,8 @@ func (p *Page) SetDefaults() {
if len(p.ContentType) == 0 { if len(p.ContentType) == 0 {
p.ContentType = "wysiwyg" p.ContentType = "wysiwyg"
} }
p.Title = strings.TrimSpace(p.Title)
} }
// PageMeta holds raw page data that is used to // PageMeta holds raw page data that is used to

View file

@ -255,35 +255,35 @@ func (p *Persister) UpdatePage(page entity.Page, refID, userID string, skipRevis
} }
} }
if page.Level == 1 { // may need to update the document name //if page.Level == 1 { // may need to update the document name
var doc entity.Document //var doc entity.Document
stmt4, err := p.Context.Transaction.Preparex("SELECT id, refid, orgid, labelid, job, location, title, excerpt, slug, tags, template, created, revised FROM document WHERE refid=?") //stmt4, err := p.Context.Transaction.Preparex("SELECT id, refid, orgid, labelid, job, location, title, excerpt, slug, tags, template, created, revised FROM document WHERE refid=?")
defer utility.Close(stmt4) //defer utility.Close(stmt4)
if err != nil { //if err != nil {
log.Error(fmt.Sprintf("Unable to prepare pagemanager doc query for Id %s", page.DocumentID), err) //log.Error(fmt.Sprintf("Unable to prepare pagemanager doc query for Id %s", page.DocumentID), err)
return err //return err
} //}
err = stmt4.Get(&doc, page.DocumentID) //err = stmt4.Get(&doc, page.DocumentID)
if err != nil { //if err != nil {
log.Error(fmt.Sprintf("Unable to execute pagemanager document query for Id %s", page.DocumentID), err) //log.Error(fmt.Sprintf("Unable to execute pagemanager document query for Id %s", page.DocumentID), err)
return err //return err
} //}
if doc.Title != page.Title { //if doc.Title != page.Title {
doc.Title = page.Title //doc.Title = page.Title
doc.Revised = page.Revised //doc.Revised = page.Revised
err = p.UpdateDocument(doc) //err = p.UpdateDocument(doc)
if err != nil { //if err != nil {
log.Error(fmt.Sprintf("Unable to update document when page 1 altered DocumentId %s", page.DocumentID), err) //log.Error(fmt.Sprintf("Unable to update document when page 1 altered DocumentId %s", page.DocumentID), err)
return err //return err
} //}
} //}
} //}
p.Base.Audit(p.Context, "update-page", page.DocumentID, page.RefID) p.Base.Audit(p.Context, "update-page", page.DocumentID, page.RefID)

View file

@ -14,7 +14,8 @@ package trello
import "strings" import "strings"
const renderTemplate = ` const renderTemplate = `
<div class="section-trello-render"> <p class="non-printable-message">Non-printable</p>
<div class="section-trello-render non-printable">
<p>There are {{ .CardCount }} cards across {{ .ListCount }} lists for board <a href="{{ .Board.URL }}">{{.Board.Name}}.</a></p> <p>There are {{ .CardCount }} cards across {{ .ListCount }} lists for board <a href="{{ .Board.URL }}">{{.Board.Name}}.</a></p>
<div class="trello-board" style="background-color: {{.Board.Prefs.BackgroundColor}}"> <div class="trello-board" style="background-color: {{.Board.Prefs.BackgroundColor}}">
<a href="{{ .Board.URL }}"><div class="trello-board-title">{{.Board.Name}}</div></a> <a href="{{ .Board.URL }}"><div class="trello-board-title">{{.Board.Name}}</div></a>

View file

@ -129,7 +129,6 @@ func (*Provider) Command(w http.ResponseWriter, r *http.Request) {
AppKey string `json:"appKey"` AppKey string `json:"appKey"`
} }
fmt.Println(appKey)
config.AppKey = appKey config.AppKey = appKey
provider.WriteJSON(w, config) provider.WriteJSON(w, config)
return return