mirror of
https://github.com/documize/community.git
synced 2025-07-20 13:49:42 +02:00
implemented delete reusable content block
This commit is contained in:
parent
2493a09ba9
commit
fc9127e165
12 changed files with 130 additions and 16 deletions
|
@ -106,6 +106,11 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
|
||||||
this.attrs.onInsertBlock(block);
|
this.attrs.onInsertBlock(block);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onDeleteBlock(id) {
|
||||||
|
this.set('blocks', this.get('blocks').filter((item) => item.get('id') !== id));
|
||||||
|
this.attrs.onDeleteBlock(id);
|
||||||
|
},
|
||||||
|
|
||||||
scrollTop() {
|
scrollTop() {
|
||||||
this.set('showScrollTool', false);
|
this.set('showScrollTool', false);
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,22 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
import NotifierMixin from '../../mixins/notifier';
|
||||||
|
|
||||||
|
const {
|
||||||
|
computed,
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
export default Ember.Component.extend(NotifierMixin, {
|
export default Ember.Component.extend(NotifierMixin, {
|
||||||
display: 'section', // which CSS to use
|
display: 'section', // which CSS to use
|
||||||
hasTemplates: false,
|
hasTemplates: false,
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this.set('hasBlocks', this.get('blocks.length') > 0);
|
let blocks = this.get('blocks');
|
||||||
|
|
||||||
|
this.set('hasBlocks', blocks.get('length') > 0);
|
||||||
|
|
||||||
|
blocks.forEach((b) => {
|
||||||
|
b.set('deleteId', `delete-block-button-${b.id}`);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
|
@ -42,6 +52,10 @@ export default Ember.Component.extend(NotifierMixin, {
|
||||||
this.attrs.onAddSection(section);
|
this.attrs.onAddSection(section);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onDeleteBlock(id) {
|
||||||
|
this.attrs.onDeleteBlock(id);
|
||||||
|
},
|
||||||
|
|
||||||
onInsertBlock(block) {
|
onInsertBlock(block) {
|
||||||
this.attrs.onInsertBlock(block);
|
this.attrs.onInsertBlock(block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,6 @@ export default Ember.Component.extend({
|
||||||
return is.not.undefined(this.get('page.excerpt'));
|
return is.not.undefined(this.get('page.excerpt'));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
|
||||||
this._super(...arguments);
|
|
||||||
},
|
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
let self = this;
|
let self = this;
|
||||||
Mousetrap.bind('esc', function () {
|
Mousetrap.bind('esc', function () {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import NotifierMixin from '../../mixins/notifier';
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
export default Ember.Controller.extend(NotifierMixin, {
|
||||||
documentService: Ember.inject.service('document'),
|
documentService: Ember.inject.service('document'),
|
||||||
templateService: Ember.inject.service('template'),
|
templateService: Ember.inject.service('template'),
|
||||||
|
sectionService: Ember.inject.service('section'),
|
||||||
page: null,
|
page: null,
|
||||||
folder: {},
|
folder: {},
|
||||||
pages: [],
|
pages: [],
|
||||||
|
@ -188,6 +189,14 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onDeleteBlock(blockId) {
|
||||||
|
this.get('sectionService').deleteBlock(blockId).then(() => {
|
||||||
|
this.audit.record("deleted-block");
|
||||||
|
this.send("showNotification", "Deleted");
|
||||||
|
this.transitionToRoute('document.index');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
onDocumentDelete() {
|
onDocumentDelete() {
|
||||||
this.get('documentService').deleteDocument(this.get('model.document.id')).then(() => {
|
this.get('documentService').deleteDocument(this.get('model.document.id')).then(() => {
|
||||||
this.audit.record("deleted-page");
|
this.audit.record("deleted-page");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{{#layout/zone-sidebar}}
|
{{#layout/zone-sidebar}}
|
||||||
{{document/document-sidebar document=model.document folder=model.folder pages=model.pages page=model.page isEditor=model.isEditor sections=model.sections
|
{{document/document-sidebar document=model.document folder=model.folder pages=model.pages page=model.page isEditor=model.isEditor sections=model.sections
|
||||||
onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock') changePageSequence=(action 'onPageSequenceChange') changePageLevel=(action 'onPageLevelChange') gotoPage=(action 'gotoPage')}}
|
onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock') onDeleteBlock=(action 'onDeleteBlock') changePageSequence=(action 'onPageSequenceChange') changePageLevel=(action 'onPageLevelChange') gotoPage=(action 'gotoPage')}}
|
||||||
{{/layout/zone-sidebar}}
|
{{/layout/zone-sidebar}}
|
||||||
|
|
||||||
{{#layout/zone-content}}
|
{{#layout/zone-content}}
|
||||||
|
|
|
@ -81,6 +81,9 @@ export default BaseService.extend({
|
||||||
return this.get('ajax').post(url, {
|
return this.get('ajax').post(url, {
|
||||||
data: JSON.stringify(payload),
|
data: JSON.stringify(payload),
|
||||||
contentType: 'json'
|
contentType: 'json'
|
||||||
|
}).then((response) => {
|
||||||
|
let data = this.get('store').normalize('block', response);
|
||||||
|
return this.get('store').push(data);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -116,5 +119,14 @@ export default BaseService.extend({
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
data: JSON.stringify(block)
|
data: JSON.stringify(block)
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Removes specified reusable content block.
|
||||||
|
deleteBlock: function (blockId) {
|
||||||
|
let url = `sections/blocks/${blockId}`;
|
||||||
|
|
||||||
|
return this.get('ajax').request(url, {
|
||||||
|
method: 'DELETE'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -83,18 +83,12 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
opacity: 0.3;
|
opacity: 0.4;
|
||||||
|
|
||||||
> .material-icons, a {
|
> .material-icons, a {
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,6 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if showSections}}
|
{{#if showSections}}
|
||||||
{{document/page-wizard display='section' document=document folder=folder sections=sections blocks=blocks
|
{{document/page-wizard display='section' document=document folder=folder sections=sections blocks=blocks
|
||||||
onCancel=(action 'onCancel') onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock')}}
|
onCancel=(action 'onCancel') onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock') onDeleteBlock=(action 'onDeleteBlock')}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -40,9 +40,15 @@
|
||||||
<i class="material-icons">mode_edit</i>
|
<i class="material-icons">mode_edit</i>
|
||||||
{{/link-to}}
|
{{/link-to}}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
<i class="material-icons">delete</i>
|
<i class="material-icons" id={{block.deleteId}}>delete</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="clearfix" />
|
<div class="clearfix" />
|
||||||
|
{{#dropdown-dialog target=block.deleteId position="top right" button="Delete" color="flat-red" onAction=(action 'onDeleteBlock' block.id)}}
|
||||||
|
<p>
|
||||||
|
Are you sure you want to delete block<br/>
|
||||||
|
<span class="bold">{{block.title}}?</span>
|
||||||
|
</p>
|
||||||
|
{{/dropdown-dialog}}
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -219,6 +219,7 @@ func init() {
|
||||||
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/space/{folderID}", []string{"GET", "OPTIONS"}, nil, GetBlocksForSpace))
|
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/space/{folderID}", []string{"GET", "OPTIONS"}, nil, GetBlocksForSpace))
|
||||||
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/{blockID}", []string{"GET", "OPTIONS"}, nil, GetBlock))
|
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/{blockID}", []string{"GET", "OPTIONS"}, nil, GetBlock))
|
||||||
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/{blockID}", []string{"PUT", "OPTIONS"}, nil, UpdateBlock))
|
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/{blockID}", []string{"PUT", "OPTIONS"}, nil, UpdateBlock))
|
||||||
|
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks/{blockID}", []string{"DELETE", "OPTIONS"}, nil, DeleteBlock))
|
||||||
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks", []string{"POST", "OPTIONS"}, nil, AddBlock))
|
log.IfErr(Add(RoutePrefixPrivate, "sections/blocks", []string{"POST", "OPTIONS"}, nil, AddBlock))
|
||||||
|
|
||||||
// Links
|
// Links
|
||||||
|
|
|
@ -226,7 +226,19 @@ func AddBlock(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
b, err = p.GetBlock(b.RefID)
|
||||||
|
if err != nil {
|
||||||
|
writeGeneralSQLError(w, method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
json, err := json.Marshal(b)
|
||||||
|
if err != nil {
|
||||||
|
writeJSONMarshalError(w, method, "block", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writeSuccessBytes(w, json)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlock returns requested reusable content block.
|
// GetBlock returns requested reusable content block.
|
||||||
|
@ -337,3 +349,43 @@ func UpdateBlock(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteBlock removes requested reusable content block.
|
||||||
|
func DeleteBlock(w http.ResponseWriter, r *http.Request) {
|
||||||
|
method := "DeleteBlock"
|
||||||
|
p := request.GetPersister(r)
|
||||||
|
|
||||||
|
params := mux.Vars(r)
|
||||||
|
blockID := params["blockID"]
|
||||||
|
|
||||||
|
if len(blockID) == 0 {
|
||||||
|
writeMissingDataError(w, method, "blockID")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := request.Db.Beginx()
|
||||||
|
if err != nil {
|
||||||
|
writeTransactionError(w, method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Context.Transaction = tx
|
||||||
|
|
||||||
|
_, err = p.DeleteBlock(blockID)
|
||||||
|
if err != nil {
|
||||||
|
log.IfErr(tx.Rollback())
|
||||||
|
writeGeneralSQLError(w, method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.RemoveBlockReference(blockID)
|
||||||
|
if err != nil {
|
||||||
|
log.IfErr(tx.Rollback())
|
||||||
|
writeGeneralSQLError(w, method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
|
writeSuccessEmptyJSON(w)
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
package request
|
package request
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -113,6 +114,30 @@ func (p *Persister) DecrementBlockUsage(id string) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveBlockReference clears page.blockid for given blockID.
|
||||||
|
func (p *Persister) RemoveBlockReference(id string) (err error) {
|
||||||
|
stmt, err := p.Context.Transaction.Preparex("UPDATE page SET blockid='', revised=? WHERE orgid=? AND blockid=?")
|
||||||
|
defer utility.Close(stmt)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(fmt.Sprintf("Unable to prepare update RemoveBlockReference id %s", id), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = stmt.Exec(time.Now().UTC(), p.Context.OrgID, id)
|
||||||
|
|
||||||
|
// skip no rows affected
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(fmt.Sprintf("Unable to execute RemoveBlockReference id %s", id), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateBlock updates existing reusable content block item.
|
// UpdateBlock updates existing reusable content block item.
|
||||||
func (p *Persister) UpdateBlock(b entity.Block) (err error) {
|
func (p *Persister) UpdateBlock(b entity.Block) (err error) {
|
||||||
b.Revised = time.Now().UTC()
|
b.Revised = time.Now().UTC()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue