1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 13:19:43 +02:00

refactored base-editor-inline to support section and block editing

This commit is contained in:
Harvey Kandola 2017-03-05 19:11:01 +00:00
parent 81fcf0f5df
commit 7e7f63e6f4
15 changed files with 157 additions and 149 deletions

View file

@ -31,7 +31,7 @@ export default Ember.Component.extend(TooltipMixin, {
{ label: 'Attachment', selected: false }, { label: 'Attachment', selected: false },
{ label: 'Search', selected: false } { label: 'Search', selected: false }
], ],
buttonId: Ember.computed('page', function () { contentLinkerButtonId: Ember.computed('page', function () {
let page = this.get('page'); let page = this.get('page');
return `content-linker-button-${page.id}`; return `content-linker-button-${page.id}`;
}), }),

View file

@ -33,6 +33,14 @@ export default Ember.Component.extend({
let page = this.get('page'); let page = this.get('page');
return `discard-edits-dialog-${page.id}`; return `discard-edits-dialog-${page.id}`;
}), }),
contentLinkerButtonId: Ember.computed('page', function () {
let page = this.get('page');
return `content-linker-button-${page.id}`;
}),
previewButtonId: Ember.computed('page', function () {
let page = this.get('page');
return `content-preview-button-${page.id}`;
}),
didRender() { didRender() {
let self = this; let self = this;
@ -108,6 +116,14 @@ export default Ember.Component.extend({
discardEdits() { discardEdits() {
this.attrs.onCancel(); this.attrs.onCancel();
} },
onInsertLink(selection) {
return this.get('onInsertLink')(selection);
},
onPreview() {
return this.get('onPreview')();
},
} }
}); });

View file

@ -32,10 +32,6 @@ export default Ember.Component.extend(TooltipMixin, {
let page = this.get('page'); let page = this.get('page');
return `markdown-preview-${page.id}`; return `markdown-preview-${page.id}`;
}), }),
tooltipId: Ember.computed('page', function () {
let page = this.get('page');
return `markdown-tooltip-${page.id}`;
}),
init() { init() {
this._super(...arguments); this._super(...arguments);
@ -127,7 +123,7 @@ export default Ember.Component.extend(TooltipMixin, {
}, },
actions: { actions: {
toggleMode() { onPreview() {
this.set('editMode', !this.get('editMode')); this.set('editMode', !this.get('editMode'));
Ember.run.schedule('afterRender', () => { Ember.run.schedule('afterRender', () => {

View file

@ -16,31 +16,23 @@ export default Ember.Controller.extend({
actions: { actions: {
onCancel( /*page*/ ) { onCancel( /*page*/ ) {
this.transitionToRoute('document', { this.transitionToRoute('document');
queryParams: {
page: this.get('model.page.id')
}
});
}, },
onAction(page, meta) { onAction(page, meta) {
let self = this; let self = this;
let block = this.get('model.block'); let b = this.get('model.block');
block.set('title', page.get('title')); b.set('title', page.get('title'));
block.set('body', page.get('body')); b.set('body', page.get('body'));
block.set('excerpt', page.get('excerpt')); b.set('excerpt', page.get('excerpt'));
block.set('rawBody', meta.get('rawBody')); b.set('rawBody', meta.get('rawBody'));
block.set('config', meta.get('config')); b.set('config', meta.get('config'));
block.set('externalSource', meta.get('externalSource')); b.set('externalSource', meta.get('externalSource'));
this.get('sectionService').updateBlock(block).then(function () { this.get('sectionService').updateBlock(b).then(function () {
self.audit.record("edited-block"); self.audit.record("edited-block");
self.transitionToRoute('document', { self.transitionToRoute('document');
queryParams: {
page: page.get('id')
}
});
}); });
} }
} }

View file

@ -1,5 +1,5 @@
@import "activity.scss"; @import "activity.scss";
@import "edit-tools.scss"; @import "content-linker.scss";
@import "files.scss"; @import "files.scss";
@import "history.scss"; @import "history.scss";
@import "inline-editor.scss"; @import "inline-editor.scss";

View file

@ -1,20 +1,3 @@
.edit-tools {
position: absolute;
top: 18px;
right: 78px;
> .toolbar {
margin: 0;
padding: 0;
line-height: 0;
> li {
list-style: none;
list-style-type: none;
}
}
}
.content-counter-dialog { .content-counter-dialog {
width: 200px; width: 200px;
height: 200px; height: 200px;

View file

@ -1,6 +1,6 @@
.document-editor { .document-editor {
position: relative; position: relative;
> .toolbar { > .toolbar {
width: 100%; width: 100%;
padding: 0; padding: 0;
@ -11,7 +11,7 @@
> input { > input {
font-weight: bold; font-weight: bold;
font-size: 1.5rem; font-size: 1.5rem;
margin: 17px 0 0 0; margin: 16px 0 10px 0;
color: $color-wysiwyg; color: $color-wysiwyg;
} }
} }
@ -29,3 +29,13 @@
display: none; display: none;
} }
} }
.document-editor-full {
@extend .transition-all;
@include border-radius(2px);
@include ease-in();
position: relative;
padding: 25px 50px;
box-shadow: 0 0 0 0.75pt $color-stroke,0 0 3pt 0.75pt $color-stroke;
background-color: $color-white;
}

View file

@ -1,6 +1,4 @@
.zone-section-editor { .zone-section-editor {
// min-height: 500px; //ensure dropdowns render in viewport
// height: 100%;
margin-left: 60px; margin-left: 60px;
padding: 20px 60px; padding: 20px 60px;
z-index: 777; z-index: 777;

View file

@ -344,11 +344,6 @@
} }
} }
.empty-state-document {
margin-top: 150px;
text-align: center;
}
.dropdown-page-toolbar { .dropdown-page-toolbar {
width: 300px; width: 300px;
} }

View file

@ -1 +1 @@
{{component editorType document=document folder=folder page=page meta=meta onCancel=(action 'onCancel') onAction=(action 'onAction')}} {{component editorType document=document folder=folder page=page meta=meta blockMode=true onCancel=(action 'onCancel') onAction=(action 'onAction')}}

View file

@ -1,82 +1,72 @@
<div class="edit-tools"> {{#dropdown-dialog target=contentLinkerButtonId position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}}
<ul class="toolbar"> <div class="content-linker-dialog">
<li class="item"> <form>
<div class="round-button-mono" id={{buttonId}} data-tooltip="Reference link" data-tooltip-position="top center"> {{ui/ui-tab tabs=tabs onTabSelect=(action 'onTabSelect')}}
<i class="material-icons color-blue">link</i>
</div>
</li>
</ul>
{{#dropdown-dialog target=buttonId position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}} <div class="margin-top-40" />
<div class="content-linker-dialog">
<form>
{{ui/ui-tab tabs=tabs onTabSelect=(action 'onTabSelect')}}
<div class="margin-top-40" /> {{#if showSections}}
<ul class="link-list">
{{#each candidates.pages as |p|}}
<li class="link-item" {{ action 'setSelection' p }}>
{{#ui/ui-selection selected=p.selected}}
{{p.title}}
{{/ui/ui-selection}}
</li>
{{/each}}
</ul>
{{/if}}
{{#if showSections}} {{#if showAttachments}}
<ul class="link-list"> <ul class="link-list">
{{#each candidates.pages as |p|}} {{#each candidates.attachments as |a|}}
<li class="link-item" {{ action 'setSelection' p }}> <li class="link-item" {{ action 'setSelection' a }}>
{{#ui/ui-selection selected=p.selected}} {{#ui/ui-selection selected=a.selected}}
{{p.title}} <img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
{{/ui/ui-selection}} {{ a.title }}
</li> {{/ui/ui-selection}}
{{/each}} </li>
</ul> {{/each}}
{{/if}} </ul>
{{/if}}
{{#if showAttachments}} {{#if showSearch}}
<ul class="link-list"> <div class="input-control">
{{#each candidates.attachments as |a|}} <label>Search</label>
<li class="link-item" {{ action 'setSelection' a }}> <div class="tip">For content or attachments</div>
{{#ui/ui-selection selected=a.selected}} {{focus-input id="content-linker-search" type="input" value=keywords placeholder="keyword search" autocomplete="off"}}
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" /> </div>
{{ a.title }} {{#unless hasMatches}}
{{/ui/ui-selection}} Nothing found.
</li> {{/unless}}
{{/each}} <ul class="link-list">
</ul> {{#each matches.documents as |m|}}
{{/if}} <li class="link-item" {{ action 'setSelection' m }}>
{{#ui/ui-selection selected=m.selected}}
{{m.title}}
{{/ui/ui-selection}}
</li>
{{/each}}
{{#each matches.pages as |m|}}
<li class="link-item" {{ action 'setSelection' m }}>
{{#ui/ui-selection selected=m.selected}}
{{m.title}}<br/><span class="color-gray">{{m.context}}</span>
{{/ui/ui-selection}}
</li>
{{/each}}
{{#each matches.attachments as |a|}}
<li class="link-item" {{ action 'setSelection' a }}>
{{#ui/ui-selection selected=a.selected}}
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
{{ a.title }}
{{/ui/ui-selection}}
</li>
{{/each}}
</ul>
{{/if}}
{{#if showSearch}} <div class="hide regular-button button-blue pull-right" {{ action 'onInsertLink' }}>Insert</div>
<div class="input-control"> <div class="hide clearfix" />
<label>Search</label> </form>
<div class="tip">For content or attachments</div> </div>
{{focus-input id="content-linker-search" type="input" value=keywords placeholder="keyword search" autocomplete="off"}} {{/dropdown-dialog}}
</div>
{{#unless hasMatches}}
Nothing found.
{{/unless}}
<ul class="link-list">
{{#each matches.documents as |m|}}
<li class="link-item" {{ action 'setSelection' m }}>
{{#ui/ui-selection selected=m.selected}}
{{m.title}}
{{/ui/ui-selection}}
</li>
{{/each}}
{{#each matches.pages as |m|}}
<li class="link-item" {{ action 'setSelection' m }}>
{{#ui/ui-selection selected=m.selected}}
{{m.title}}<br/><span class="color-gray">{{m.context}}</span>
{{/ui/ui-selection}}
</li>
{{/each}}
{{#each matches.attachments as |a|}}
<li class="link-item" {{ action 'setSelection' a }}>
{{#ui/ui-selection selected=a.selected}}
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
{{ a.title }}
{{/ui/ui-selection}}
</li>
{{/each}}
</ul>
{{/if}}
<div class="hide regular-button button-blue pull-right" {{ action 'onInsertLink' }}>Insert</div>
<div class="hide clearfix" />
</form>
</div>
{{/dropdown-dialog}}
</div>

View file

@ -1,12 +1,23 @@
<div class="document-editor"> <div class="document-editor {{if blockMode 'document-editor-full'}}">
<div class="toolbar"> <div class="toolbar">
<div class="input-inline input-transparent edit-title pull-left">
{{focus-input type="text" id=pageId value=page.title class=(if hasNameError 'error-inline') placeholder="Name" class="mousetrap"}}
</div>
<div class="buttons pull-right"> <div class="buttons pull-right">
{{#if busy}} {{#if busy}}
<img src="/assets/img/busy-gray.gif" class="busy-indicator" /> <img src="/assets/img/busy-gray.gif" class="busy-indicator" />
{{/if}} {{/if}}
{{#if contentLinkerButton}}
{{document/edit-tools tagName="span" document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}}
<div class="round-button-mono" id={{contentLinkerButtonId}} data-tooltip="Reference link" data-tooltip-position="top center">
<i class="material-icons color-blue">link</i>
</div>
{{/if}}
{{#if previewButton}}
<div class="round-button-mono" {{action 'onPreview'}} id={{previewButtonId}} data-tooltip="Toggle Preview" data-tooltip-position="top center">
<i class="material-icons color-gray">visibility</i>
</div>
{{/if}}
<div class="round-button-mono" {{action 'onAction'}}> <div class="round-button-mono" {{action 'onAction'}}>
<i class="material-icons color-green">check</i> <i class="material-icons color-green">check</i>
</div> </div>
@ -14,7 +25,23 @@
<i class="material-icons color-gray">close</i> <i class="material-icons color-gray">close</i>
</div> </div>
</div> </div>
{{#if blockMode}}
<div class="clearfix"></div>
<div class="input-control">
<label>Name</label>
{{focus-input id="page-id-{{pageId}}" value=page.title class="mousetrap"}}
</div>
<div class="input-control">
<label>Description</label>
{{textarea id="page-excerpt-{{pageId}}" value=page.excerpt class="mousetrap" rows="3"}}
</div>
{{else}}
<div class="input-inline input-transparent edit-title pull-left">
{{focus-input type="text" id=pageId value=page.title class=(if hasNameError 'error-inline') placeholder="Name" class="mousetrap"}}
</div>
{{/if}}
<div class="clearfix"></div> <div class="clearfix"></div>
<div class="dropdown-dialog cancel-edits-dialog" id={{dialogId}}> <div class="dropdown-dialog cancel-edits-dialog" id={{dialogId}}>
<div class="content"> <div class="content">
<p>Do you want to cancel editing and lose unsaved changes?</p> <p>Do you want to cancel editing and lose unsaved changes?</p>

View file

@ -1,15 +1,7 @@
{{#section/base-editor-inline document=document folder=folder page=page tip="Concise name that describes code snippet" isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}} {{#section/base-editor-inline document=document folder=folder page=page blockMode=blockMode
<style> contentLinkerButton=true onInsertLink=(action 'onInsertLink')
.CodeMirror { previewButton=true onPreview=(action 'onPreview')
height: auto; isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}}
font-size: 17px;
}
</style>
<div class="section-markdown-preview-button round-button-mono" id={{tooltipId}} {{action 'toggleMode'}} data-tooltip="Toggle Preview" data-tooltip-position="top center">
<i class="material-icons color-gray">visibility</i>
</div>
{{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}}
<div class="section-code-editor"> <div class="section-code-editor">
{{#if editMode}} {{#if editMode}}

View file

@ -1,5 +1,6 @@
{{#section/base-editor-inline document=document folder=folder page=page isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}} {{#section/base-editor-inline document=document folder=folder page=page
{{document/edit-tools document=document folder=folder page=page onInsertLink=(action 'onInsertLink')}} blockMode=blockMode contentLinkerButton=true onInsertLink=(action 'onInsertLink')
isDirty=(action 'isDirty') onCancel=(action 'onCancel') onAction=(action 'onAction')}}
<div id={{editorId}} class="mousetrap wysiwyg wysiwyg-editor"> <div id={{editorId}} class="mousetrap wysiwyg wysiwyg-editor">
{{{pageBody}}} {{{pageBody}}}
</div> </div>

View file

@ -320,9 +320,15 @@ func UpdateBlock(w http.ResponseWriter, r *http.Request) {
method := "UpdateBlock" method := "UpdateBlock"
p := request.GetPersister(r) p := request.GetPersister(r)
params := mux.Vars(r)
blockID := params["blockID"]
if len(blockID) == 0 {
writeMissingDataError(w, method, "blockID")
return
}
defer utility.Close(r.Body) defer utility.Close(r.Body)
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
writeBadRequestError(w, method, "Bad payload") writeBadRequestError(w, method, "Bad payload")
return return
@ -335,6 +341,8 @@ func UpdateBlock(w http.ResponseWriter, r *http.Request) {
return return
} }
b.RefID = blockID
if !p.CanUploadDocument(b.LabelID) { if !p.CanUploadDocument(b.LabelID) {
writeForbiddenError(w) writeForbiddenError(w)
return return