mirror of
https://github.com/documize/community.git
synced 2025-08-04 21:15:24 +02:00
reusable content block editing completed
This commit is contained in:
parent
bbc2237ef7
commit
2493a09ba9
15 changed files with 307 additions and 23 deletions
53
app/app/components/document/block-editor.js
Normal file
53
app/app/components/document/block-editor.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
// 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
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
store: Ember.inject.service(),
|
||||
|
||||
didReceiveAttrs() {
|
||||
let p = this.get('store').createRecord('page');
|
||||
let m = this.get('store').createRecord('pageMeta');
|
||||
|
||||
p.set('id', this.get('block.id'));
|
||||
p.set('orgId', this.get('block.orgId'));
|
||||
p.set('documentId', this.get('document.id'));
|
||||
p.set('contentType', this.get('block.contentType'));
|
||||
p.set('pageType', this.get('block.pageType'));
|
||||
p.set('title', this.get('block.title'));
|
||||
p.set('body', this.get('block.body'));
|
||||
p.set('rawBody', this.get('block.rawBody'));
|
||||
p.set('excerpt', this.get('block.excerpt'));
|
||||
|
||||
m.set('pageId', this.get('block.id'));
|
||||
m.set('orgId', this.get('block.orgId'));
|
||||
m.set('documentId', this.get('document.id'));
|
||||
m.set('rawBody', this.get('block.rawBody'));
|
||||
m.set('config', this.get('block.config'));
|
||||
m.set('externalSource', this.get('block.externalSource'));
|
||||
|
||||
this.set('page', p);
|
||||
this.set('meta', m);
|
||||
|
||||
this.set('editorType', 'section/' + this.get('block.contentType') + '/type-editor');
|
||||
},
|
||||
|
||||
actions: {
|
||||
onCancel() {
|
||||
this.attrs.onCancel();
|
||||
},
|
||||
|
||||
onAction(page, meta) {
|
||||
this.attrs.onAction(page, meta);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -17,6 +17,13 @@ export default Ember.Component.extend({
|
|||
actionLabel: "Save",
|
||||
tip: "Short and concise title",
|
||||
busy: false,
|
||||
hasExcerpt: Ember.computed('page', function () {
|
||||
return is.not.undefined(this.get('page.excerpt'));
|
||||
}),
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
},
|
||||
|
||||
didRender() {
|
||||
let self = this;
|
||||
|
@ -30,10 +37,14 @@ export default Ember.Component.extend({
|
|||
});
|
||||
|
||||
$("#page-title").removeClass("error");
|
||||
$("#page-excerpt").removeClass("error");
|
||||
|
||||
$("#page-title").focus(function() {
|
||||
$(this).select();
|
||||
});
|
||||
$("#page-excerpt").focus(function() {
|
||||
$(this).select();
|
||||
});
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
|
@ -80,6 +91,11 @@ export default Ember.Component.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.get('hasExcerpt') && is.empty(this.get('page.excerpt'))) {
|
||||
$("#page-excerpt").addClass("error").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
this.attrs.onAction(this.get('page.title'));
|
||||
},
|
||||
|
||||
|
|
47
app/app/pods/document/block/controller.js
Normal file
47
app/app/pods/document/block/controller.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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
|
||||
|
||||
import Ember from 'ember';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
sectionService: Ember.inject.service('section'),
|
||||
|
||||
actions: {
|
||||
onCancel( /*page*/ ) {
|
||||
this.transitionToRoute('document', {
|
||||
queryParams: {
|
||||
page: this.get('model.page.id')
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onAction(page, meta) {
|
||||
let self = this;
|
||||
|
||||
let block = this.get('model.block');
|
||||
block.set('title', page.get('title'));
|
||||
block.set('body', page.get('body'));
|
||||
block.set('excerpt', page.get('excerpt'));
|
||||
block.set('rawBody', meta.get('rawBody'));
|
||||
block.set('config', meta.get('config'));
|
||||
block.set('externalSource', meta.get('externalSource'));
|
||||
|
||||
this.get('sectionService').updateBlock(block).then(function () {
|
||||
self.audit.record("edited-block");
|
||||
self.transitionToRoute('document', {
|
||||
queryParams: {
|
||||
page: page.get('id')
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
31
app/app/pods/document/block/route.js
Normal file
31
app/app/pods/document/block/route.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
// 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
|
||||
|
||||
import Ember from 'ember';
|
||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||
|
||||
export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||
documentService: Ember.inject.service('document'),
|
||||
folderService: Ember.inject.service('folder'),
|
||||
sectionService: Ember.inject.service('section'),
|
||||
|
||||
model(params) {
|
||||
let self = this;
|
||||
|
||||
this.audit.record("edited-block");
|
||||
|
||||
return Ember.RSVP.hash({
|
||||
folder: self.modelFor('document').folder,
|
||||
document: self.modelFor('document').document,
|
||||
block: self.get('sectionService').getBlock(params.block_id),
|
||||
});
|
||||
}
|
||||
});
|
1
app/app/pods/document/block/template.hbs
Normal file
1
app/app/pods/document/block/template.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{document/block-editor document=model.document folder=model.folder block=model.block onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
|
@ -50,6 +50,9 @@ export default Router.map(function () {
|
|||
this.route('history', {
|
||||
path: 'history'
|
||||
});
|
||||
this.route('block', {
|
||||
path: 'block/:block_id'
|
||||
});
|
||||
});
|
||||
|
||||
this.route('customize', {
|
||||
|
|
|
@ -84,9 +84,19 @@ export default BaseService.extend({
|
|||
});
|
||||
},
|
||||
|
||||
// Returns reusable content block.
|
||||
getBlock(blockId) {
|
||||
return this.get('ajax').request(`sections/blocks/${blockId}`, {
|
||||
method: 'GET'
|
||||
}).then((response) => {
|
||||
let data = this.get('store').normalize('block', response);
|
||||
return this.get('store').push(data);
|
||||
});
|
||||
},
|
||||
|
||||
// Returns all available reusable content block for section.
|
||||
getSpaceBlocks(folderId) {
|
||||
return this.get('ajax').request(`sections/blocks/${folderId}`, {
|
||||
return this.get('ajax').request(`sections/blocks/space/${folderId}`, {
|
||||
method: 'GET'
|
||||
}).then((response) => {
|
||||
let data = [];
|
||||
|
@ -98,5 +108,13 @@ export default BaseService.extend({
|
|||
|
||||
return data;
|
||||
});
|
||||
},
|
||||
|
||||
// Returns reusable content block.
|
||||
updateBlock(block) {
|
||||
return this.get('ajax').request(`sections/blocks/${block.id}`, {
|
||||
method: 'PUT',
|
||||
data: JSON.stringify(block)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
&:hover {
|
||||
@include ease-in();
|
||||
|
||||
> .actions {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
> .details {
|
||||
> .title {
|
||||
color: $color-primary;
|
||||
|
@ -72,6 +76,25 @@
|
|||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
> .actions {
|
||||
display: none;
|
||||
vertical-align: top;
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
margin-top: 5px;
|
||||
opacity: 0.3;
|
||||
|
||||
> .material-icons, a {
|
||||
color: $color-gray;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
color: $color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
app/app/templates/components/document/block-editor.hbs
Normal file
1
app/app/templates/components/document/block-editor.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
{{component editorType document=document folder=folder page=page meta=meta onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
|
@ -24,24 +24,31 @@
|
|||
<div class="template-caption">Reusable Content</div>
|
||||
<ul class="list">
|
||||
{{#each blocks as |block|}}
|
||||
<li class="item" {{action 'onInsertBlock' block}}>
|
||||
<div class="icon">
|
||||
<li class="item">
|
||||
<div class="icon" {{action 'onInsertBlock' block}}>
|
||||
<img class="img" src="/assets/img/section-saved.png" srcset="/assets/img/section-saved@2x.png" />
|
||||
</div>
|
||||
<div class="details">
|
||||
<div class="details" {{action 'onInsertBlock' block}}>
|
||||
<div class='title'>
|
||||
{{block.title}}
|
||||
</div>
|
||||
<div class='desc'>{{block.excerpt}}</div>
|
||||
<div class='desc'>By {{block.firstname}} {{block.lastname}}, {{time-ago block.created}} (used: {{ block.used }})</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
{{#link-to 'document.block' folder.id folder.slug document.id document.slug block.id}}
|
||||
<i class="material-icons">mode_edit</i>
|
||||
{{/link-to}}
|
||||
<div class="divider"></div>
|
||||
<i class="material-icons">delete</i>
|
||||
</div>
|
||||
<div class="clearfix" />
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<div class="divider"></div>
|
||||
<div class="template-caption">No reusable content</div>
|
||||
<div class="template-caption">Published, reusable sections appear below</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
<div class="tip">{{tip}}</div>
|
||||
{{focus-input type='text' id="page-title" value=page.title class="mousetrap"}}
|
||||
</div>
|
||||
{{#if hasExcerpt}}
|
||||
<div class="margin-top-30">
|
||||
<div class="input-control">
|
||||
<label>Excerpt</label>
|
||||
<div class="tip">Short description</div>
|
||||
{{textarea rows="3" id="page-excerpt" value=page.excerpt class="mousetrap"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="buttons pull-right">
|
||||
{{#if busy}}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue